ReactOS 0.4.15-dev-7918-g2a2556c
xmlschemas.c
Go to the documentation of this file.
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>
62#include <libxml/hash.h>
63#include <libxml/uri.h>
64#include <libxml/xmlschemas.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 */
126static const xmlChar *xmlSchemaNs = (const xmlChar *)
127 "http://www.w3.org/2001/XMLSchema";
128
129static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
130 "http://www.w3.org/2001/XMLSchema-instance";
131
132static 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
354typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
355typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
356
357typedef struct _xmlSchemaItemList xmlSchemaItemList;
358typedef xmlSchemaItemList *xmlSchemaItemListPtr;
359struct _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
368typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
369typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
370struct _xmlSchemaAbstractCtxt {
371 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
372 void *dummy; /* Fix alignment issues */
373};
374
375typedef struct _xmlSchemaBucket xmlSchemaBucket;
376typedef 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
388typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
389typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
390struct _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
400struct _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
424typedef struct _xmlSchemaImport xmlSchemaImport;
425typedef xmlSchemaImport *xmlSchemaImportPtr;
426struct _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*/
453typedef struct _xmlSchemaInclude xmlSchemaInclude;
454typedef xmlSchemaInclude *xmlSchemaIncludePtr;
455struct _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
479typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
480typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
481struct _xmlSchemaBasicItem {
482 xmlSchemaTypeType type;
483 void *dummy; /* Fix alignment issues */
484};
485
492typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
493typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
494struct _xmlSchemaAnnotItem {
495 xmlSchemaTypeType type;
496 xmlSchemaAnnotPtr annot;
497};
498
505typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
506typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
507struct _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
522typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
523typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
524struct _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;
536 int occurs; /* required, optional */
537 const xmlChar * defValue;
538 xmlSchemaValPtr defVal;
539};
540
547typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
548typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
549struct _xmlSchemaAttributeUseProhib {
550 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
552 const xmlChar *name;
553 const xmlChar *targetNamespace;
554 int isRef;
555};
556
560typedef struct _xmlSchemaRedef xmlSchemaRedef;
561typedef xmlSchemaRedef *xmlSchemaRedefPtr;
562struct _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
576typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
577typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
578struct _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
595struct _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;
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
650typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
651typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
652struct _xmlSchemaQNameRef {
653 xmlSchemaTypeType type;
654 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
655 xmlSchemaTypeType itemType;
656 const xmlChar *name;
657 const xmlChar *targetNamespace;
659};
660
667typedef struct _xmlSchemaParticle xmlSchemaParticle;
668typedef xmlSchemaParticle *xmlSchemaParticlePtr;
669struct _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;
679};
680
687typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
688typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
689struct _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") */
695};
696
697#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
698#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
705typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
706typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
707struct _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;
715 int flags;
716};
717
718typedef struct _xmlSchemaIDC xmlSchemaIDC;
719typedef xmlSchemaIDC *xmlSchemaIDCPtr;
720
727typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
728typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
729struct _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
744struct _xmlSchemaIDC {
745 xmlSchemaTypeType type;
746 xmlSchemaAnnotPtr annot;
747 xmlSchemaIDCPtr next;
749 const xmlChar *name;
750 const xmlChar *targetNamespace;
751 xmlSchemaIDCSelectPtr selector;
752 xmlSchemaIDCSelectPtr fields;
753 int nbFields;
754 xmlSchemaQNameRefPtr ref;
755};
756
762typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
763typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
764struct _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
776typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
777typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
778struct _xmlSchemaPSVIIDCKey {
779 xmlSchemaTypePtr type;
780 xmlSchemaValPtr val;
781};
782
788typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
789typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
790struct _xmlSchemaPSVIIDCNode {
792 xmlSchemaPSVIIDCKeyPtr *keys;
793 int nodeLine;
794 int nodeQNameID;
795
796};
797
803typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
804typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
805struct _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
821typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
822typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
823
829typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
830typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
831struct _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
851struct _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 xmlHashTablePtr htab;
864};
865
866/*
867* Element info flags.
868*/
869#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
870#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
871#define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
872#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
873
874#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
875#define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
876#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
877
878#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
879#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
880#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
881#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
882
888struct _xmlSchemaNodeInfo {
889 int nodeType;
891 int nodeLine;
892 const xmlChar *localName;
893 const xmlChar *nsName;
894 const xmlChar *value;
895 xmlSchemaValPtr val; /* the pre-computed value if any */
896 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
897
898 int flags; /* combination of node info flags */
899
900 int valNeeded;
901 int normVal;
902
903 xmlSchemaElementPtr decl; /* the element/attribute declaration */
904 int depth;
905 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
906 for the scope element*/
907 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
908 element */
909 xmlRegExecCtxtPtr regexCtxt;
910
911 const xmlChar **nsBindings; /* Namespace bindings on this element */
912 int nbNsBindings;
913 int sizeNsBindings;
914
915 int hasKeyrefs;
916 int appliedXPath; /* Indicates that an XPath has been applied. */
917};
918
919#define XML_SCHEMAS_ATTR_UNKNOWN 1
920#define XML_SCHEMAS_ATTR_ASSESSED 2
921#define XML_SCHEMAS_ATTR_PROHIBITED 3
922#define XML_SCHEMAS_ATTR_ERR_MISSING 4
923#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
924#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
925#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
926#define XML_SCHEMAS_ATTR_DEFAULT 8
927#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
928#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
929#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
930#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
931#define XML_SCHEMAS_ATTR_WILD_SKIP 13
932#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
933#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
934#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
935#define XML_SCHEMAS_ATTR_META 17
936/*
937* @metaType values of xmlSchemaAttrInfo.
938*/
939#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
940#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
941#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
942#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
943#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
944
945typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
946typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
947struct _xmlSchemaAttrInfo {
948 int nodeType;
950 int nodeLine;
951 const xmlChar *localName;
952 const xmlChar *nsName;
953 const xmlChar *value;
954 xmlSchemaValPtr val; /* the pre-computed value if any */
955 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
956 int flags; /* combination of node info flags */
957
958 xmlSchemaAttributePtr decl; /* the attribute declaration */
959 xmlSchemaAttributeUsePtr use; /* the attribute use */
960 int state;
961 int metaType;
962 const xmlChar *vcValue; /* the value constraint value */
963 xmlSchemaNodeInfoPtr parent;
964};
965
966
967#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
973struct _xmlSchemaValidCtxt {
974 int type;
975 void *errCtxt; /* user specific data block */
976 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
977 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
979
980 xmlSchemaPtr schema; /* The schema in use */
981 xmlDocPtr doc;
983 xmlCharEncoding enc;
985 xmlParserCtxtPtr parserCtxt;
986 void *user_data; /* TODO: What is this for? */
987 char *filename;
988
989 int err;
990 int nberrors;
991
994 /* xmlSchemaTypePtr type; */
995
996 xmlRegExecCtxtPtr regexp;
997 xmlSchemaValPtr value;
998
999 int valueWS;
1000 int options;
1001 xmlNodePtr validationRoot;
1002 xmlSchemaParserCtxtPtr pctxt;
1003 int xsiAssemble;
1004
1005 int depth;
1006 xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
1007 int sizeElemInfos;
1008 xmlSchemaNodeInfoPtr inode; /* the current element information */
1009
1010 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1011
1012 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1013 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1014 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1015
1016 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1017 int nbIdcNodes;
1018 int sizeIdcNodes;
1019
1020 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1021 int nbIdcKeys;
1022 int sizeIdcKeys;
1023
1024 int flags;
1025
1026 xmlDictPtr dict;
1027
1028#ifdef LIBXML_READER_ENABLED
1029 xmlTextReaderPtr reader;
1030#endif
1031
1032 xmlSchemaAttrInfoPtr *attrInfos;
1033 int nbAttrInfos;
1034 int sizeAttrInfos;
1035
1036 int skipDepth;
1037 xmlSchemaItemListPtr nodeQNames;
1038 int hasKeyrefs;
1039 int createIDCNodeTables;
1040 int psviExposeIDCNodeTables;
1041
1042 /* Locator for error reporting in streaming mode */
1043 xmlSchemaValidityLocatorFunc locFunc;
1044 void *locCtxt;
1045};
1046
1052typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1053typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1054struct _xmlSchemaSubstGroup {
1055 xmlSchemaElementPtr head;
1056 xmlSchemaItemListPtr members;
1057};
1058
1064typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1065typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1066struct _xmlIDCHashEntry {
1067 xmlIDCHashEntryPtr next; /* next item with same hash */
1068 int index; /* index into associated item list */
1069};
1070
1071/************************************************************************
1072 * *
1073 * Some predeclarations *
1074 * *
1075 ************************************************************************/
1076
1077static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1078 xmlSchemaPtr schema,
1080static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1081 xmlSchemaPtr schema,
1083static int
1084xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1085 xmlSchemaAbstractCtxtPtr ctxt);
1086static const xmlChar *
1087xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1088static int
1089xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1091static int
1092xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1093 xmlSchemaParserCtxtPtr ctxt);
1094static void
1095xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1096static xmlSchemaWhitespaceValueType
1097xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1098static xmlSchemaTreeItemPtr
1099xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1100 xmlNodePtr node, xmlSchemaTypeType type,
1101 int withParticle);
1102static const xmlChar *
1103xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1104static xmlSchemaTypeLinkPtr
1105xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1106static void
1107xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1108 const char *funcName,
1109 const char *message) LIBXML_ATTR_FORMAT(3,0);
1110static int
1111xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1112 xmlSchemaTypePtr type,
1113 xmlSchemaTypePtr baseType,
1114 int subset);
1115static void
1116xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1117 xmlSchemaParserCtxtPtr ctxt);
1118static void
1119xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1120static xmlSchemaQNameRefPtr
1121xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1122 xmlSchemaPtr schema,
1124
1125/************************************************************************
1126 * *
1127 * Helper functions *
1128 * *
1129 ************************************************************************/
1130
1137static const xmlChar *
1138xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1139{
1140 switch (type) {
1141 case XML_SCHEMA_TYPE_BASIC:
1142 return(BAD_CAST "simple type definition");
1143 case XML_SCHEMA_TYPE_SIMPLE:
1144 return(BAD_CAST "simple type definition");
1145 case XML_SCHEMA_TYPE_COMPLEX:
1146 return(BAD_CAST "complex type definition");
1147 case XML_SCHEMA_TYPE_ELEMENT:
1148 return(BAD_CAST "element declaration");
1149 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1150 return(BAD_CAST "attribute use");
1151 case XML_SCHEMA_TYPE_ATTRIBUTE:
1152 return(BAD_CAST "attribute declaration");
1153 case XML_SCHEMA_TYPE_GROUP:
1154 return(BAD_CAST "model group definition");
1155 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1156 return(BAD_CAST "attribute group definition");
1157 case XML_SCHEMA_TYPE_NOTATION:
1158 return(BAD_CAST "notation declaration");
1159 case XML_SCHEMA_TYPE_SEQUENCE:
1160 return(BAD_CAST "model group (sequence)");
1161 case XML_SCHEMA_TYPE_CHOICE:
1162 return(BAD_CAST "model group (choice)");
1163 case XML_SCHEMA_TYPE_ALL:
1164 return(BAD_CAST "model group (all)");
1165 case XML_SCHEMA_TYPE_PARTICLE:
1166 return(BAD_CAST "particle");
1167 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1168 return(BAD_CAST "unique identity-constraint");
1169 /* return(BAD_CAST "IDC (unique)"); */
1170 case XML_SCHEMA_TYPE_IDC_KEY:
1171 return(BAD_CAST "key identity-constraint");
1172 /* return(BAD_CAST "IDC (key)"); */
1173 case XML_SCHEMA_TYPE_IDC_KEYREF:
1174 return(BAD_CAST "keyref identity-constraint");
1175 /* return(BAD_CAST "IDC (keyref)"); */
1176 case XML_SCHEMA_TYPE_ANY:
1177 return(BAD_CAST "wildcard (any)");
1178 case XML_SCHEMA_EXTRA_QNAMEREF:
1179 return(BAD_CAST "[helper component] QName reference");
1180 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1181 return(BAD_CAST "[helper component] attribute use prohibition");
1182 default:
1183 return(BAD_CAST "Not a schema component");
1184 }
1185}
1186
1193static const xmlChar *
1194xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1195{
1196 switch (item->type) {
1197 case XML_SCHEMA_TYPE_BASIC:
1198 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1199 return(BAD_CAST "complex type definition");
1200 else
1201 return(BAD_CAST "simple type definition");
1202 default:
1203 return(xmlSchemaItemTypeToStr(item->type));
1204 }
1205}
1206
1217static xmlNodePtr
1218xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1219{
1220 switch (item->type) {
1221 case XML_SCHEMA_TYPE_ELEMENT:
1222 return (((xmlSchemaElementPtr) item)->node);
1223 case XML_SCHEMA_TYPE_ATTRIBUTE:
1224 return (((xmlSchemaAttributePtr) item)->node);
1225 case XML_SCHEMA_TYPE_COMPLEX:
1226 case XML_SCHEMA_TYPE_SIMPLE:
1227 return (((xmlSchemaTypePtr) item)->node);
1228 case XML_SCHEMA_TYPE_ANY:
1229 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1230 return (((xmlSchemaWildcardPtr) item)->node);
1231 case XML_SCHEMA_TYPE_PARTICLE:
1232 return (((xmlSchemaParticlePtr) item)->node);
1233 case XML_SCHEMA_TYPE_SEQUENCE:
1234 case XML_SCHEMA_TYPE_CHOICE:
1235 case XML_SCHEMA_TYPE_ALL:
1236 return (((xmlSchemaModelGroupPtr) item)->node);
1237 case XML_SCHEMA_TYPE_GROUP:
1238 return (((xmlSchemaModelGroupDefPtr) item)->node);
1239 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1240 return (((xmlSchemaAttributeGroupPtr) item)->node);
1241 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1242 case XML_SCHEMA_TYPE_IDC_KEY:
1243 case XML_SCHEMA_TYPE_IDC_KEYREF:
1244 return (((xmlSchemaIDCPtr) item)->node);
1245 case XML_SCHEMA_EXTRA_QNAMEREF:
1246 return(((xmlSchemaQNameRefPtr) item)->node);
1247 /* TODO: What to do with NOTATIONs?
1248 case XML_SCHEMA_TYPE_NOTATION:
1249 return (((xmlSchemaNotationPtr) item)->node);
1250 */
1251 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1252 return (((xmlSchemaAttributeUsePtr) item)->node);
1253 default:
1254 return (NULL);
1255 }
1256}
1257
1258#if 0
1265static xmlSchemaBasicItemPtr
1266xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1267{
1268 switch (item->type) {
1269 case XML_SCHEMA_TYPE_ELEMENT:
1270 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1271 case XML_SCHEMA_TYPE_ATTRIBUTE:
1272 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1273 case XML_SCHEMA_TYPE_COMPLEX:
1274 case XML_SCHEMA_TYPE_SIMPLE:
1275 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1276 case XML_SCHEMA_TYPE_ANY:
1277 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1278 return (NULL);
1279 case XML_SCHEMA_TYPE_PARTICLE:
1280 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1281 case XML_SCHEMA_TYPE_SEQUENCE:
1282 case XML_SCHEMA_TYPE_CHOICE:
1283 case XML_SCHEMA_TYPE_ALL:
1284 return (NULL);
1285 case XML_SCHEMA_TYPE_GROUP:
1286 return (NULL);
1287 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1288 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1289 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1290 case XML_SCHEMA_TYPE_IDC_KEY:
1291 case XML_SCHEMA_TYPE_IDC_KEYREF:
1292 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1293 default:
1294 return (NULL);
1295 }
1296}
1297#endif
1298
1299
1312static const xmlChar*
1313xmlSchemaFormatQName(xmlChar **buf,
1314 const xmlChar *namespaceName,
1315 const xmlChar *localName)
1316{
1317 FREE_AND_NULL(*buf)
1318 if (namespaceName != NULL) {
1319 *buf = xmlStrdup(BAD_CAST "{");
1320 *buf = xmlStrcat(*buf, namespaceName);
1321 *buf = xmlStrcat(*buf, BAD_CAST "}");
1322 }
1323 if (localName != NULL) {
1324 if (namespaceName == NULL)
1325 return(localName);
1326 *buf = xmlStrcat(*buf, localName);
1327 } else {
1328 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1329 }
1330 return ((const xmlChar *) *buf);
1331}
1332
1333static const xmlChar*
1334xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1335{
1336 if (ns != NULL)
1337 return (xmlSchemaFormatQName(buf, ns->href, localName));
1338 else
1339 return (xmlSchemaFormatQName(buf, NULL, localName));
1340}
1341
1342static const xmlChar *
1343xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1344{
1345 if (item == NULL) {
1346 return (NULL);
1347 }
1348 switch (item->type) {
1349 case XML_SCHEMA_TYPE_ELEMENT:
1350 return (((xmlSchemaElementPtr) item)->name);
1351 case XML_SCHEMA_TYPE_ATTRIBUTE:
1352 return (((xmlSchemaAttributePtr) item)->name);
1353 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1354 return (((xmlSchemaAttributeGroupPtr) item)->name);
1355 case XML_SCHEMA_TYPE_BASIC:
1356 case XML_SCHEMA_TYPE_SIMPLE:
1357 case XML_SCHEMA_TYPE_COMPLEX:
1358 return (((xmlSchemaTypePtr) item)->name);
1359 case XML_SCHEMA_TYPE_GROUP:
1360 return (((xmlSchemaModelGroupDefPtr) item)->name);
1361 case XML_SCHEMA_TYPE_IDC_KEY:
1362 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1363 case XML_SCHEMA_TYPE_IDC_KEYREF:
1364 return (((xmlSchemaIDCPtr) item)->name);
1365 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1366 if (WXS_ATTRUSE_DECL(item) != NULL) {
1367 return(xmlSchemaGetComponentName(
1368 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1369 } else
1370 return(NULL);
1371 case XML_SCHEMA_EXTRA_QNAMEREF:
1372 return (((xmlSchemaQNameRefPtr) item)->name);
1373 case XML_SCHEMA_TYPE_NOTATION:
1374 return (((xmlSchemaNotationPtr) item)->name);
1375 default:
1376 /*
1377 * Other components cannot have names.
1378 */
1379 break;
1380 }
1381 return (NULL);
1382}
1383
1384#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1385#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1386/*
1387static const xmlChar *
1388xmlSchemaGetQNameRefName(void *ref)
1389{
1390 return(((xmlSchemaQNameRefPtr) ref)->name);
1391}
1392
1393static const xmlChar *
1394xmlSchemaGetQNameRefTargetNs(void *ref)
1395{
1396 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1397}
1398*/
1399
1400static const xmlChar *
1401xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1402{
1403 if (item == NULL) {
1404 return (NULL);
1405 }
1406 switch (item->type) {
1407 case XML_SCHEMA_TYPE_ELEMENT:
1408 return (((xmlSchemaElementPtr) item)->targetNamespace);
1409 case XML_SCHEMA_TYPE_ATTRIBUTE:
1410 return (((xmlSchemaAttributePtr) item)->targetNamespace);
1411 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1412 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1413 case XML_SCHEMA_TYPE_BASIC:
1414 return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1415 case XML_SCHEMA_TYPE_SIMPLE:
1416 case XML_SCHEMA_TYPE_COMPLEX:
1417 return (((xmlSchemaTypePtr) item)->targetNamespace);
1418 case XML_SCHEMA_TYPE_GROUP:
1419 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1420 case XML_SCHEMA_TYPE_IDC_KEY:
1421 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1422 case XML_SCHEMA_TYPE_IDC_KEYREF:
1423 return (((xmlSchemaIDCPtr) item)->targetNamespace);
1424 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1425 if (WXS_ATTRUSE_DECL(item) != NULL) {
1426 return(xmlSchemaGetComponentTargetNs(
1427 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1428 }
1429 /* TODO: Will returning NULL break something? */
1430 break;
1431 case XML_SCHEMA_EXTRA_QNAMEREF:
1432 return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1433 case XML_SCHEMA_TYPE_NOTATION:
1434 return (((xmlSchemaNotationPtr) item)->targetNamespace);
1435 default:
1436 /*
1437 * Other components cannot have names.
1438 */
1439 break;
1440 }
1441 return (NULL);
1442}
1443
1444static const xmlChar*
1445xmlSchemaGetComponentQName(xmlChar **buf,
1446 void *item)
1447{
1448 return (xmlSchemaFormatQName(buf,
1449 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1450 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1451}
1452
1453static const xmlChar*
1454xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1455{
1456 xmlChar *str = NULL;
1457
1458 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1459 *buf = xmlStrcat(*buf, BAD_CAST " '");
1460 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1461 (xmlSchemaBasicItemPtr) item));
1462 *buf = xmlStrcat(*buf, BAD_CAST "'");
1463 FREE_AND_NULL(str);
1464 return(*buf);
1465}
1466
1467static const xmlChar*
1468xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1469{
1470 return(xmlSchemaGetComponentDesignation(buf, idc));
1471}
1472
1480static const xmlChar *
1481xmlSchemaWildcardPCToString(int pc)
1482{
1483 switch (pc) {
1484 case XML_SCHEMAS_ANY_SKIP:
1485 return (BAD_CAST "skip");
1486 case XML_SCHEMAS_ANY_LAX:
1487 return (BAD_CAST "lax");
1488 case XML_SCHEMAS_ANY_STRICT:
1489 return (BAD_CAST "strict");
1490 default:
1491 return (BAD_CAST "invalid process contents");
1492 }
1493}
1494
1508static int
1509xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1510 xmlSchemaWhitespaceValueType ws,
1511 xmlChar **retValue,
1512 int for_hash)
1513{
1514 int list;
1515 xmlSchemaValType valType;
1516 const xmlChar *value, *value2 = NULL;
1517
1518
1519 if ((retValue == NULL) || (val == NULL))
1520 return (-1);
1521 list = xmlSchemaValueGetNext(val) ? 1 : 0;
1522 *retValue = NULL;
1523 do {
1524 value = NULL;
1525 valType = xmlSchemaGetValType(val);
1526 switch (valType) {
1527 case XML_SCHEMAS_STRING:
1528 case XML_SCHEMAS_NORMSTRING:
1529 case XML_SCHEMAS_ANYSIMPLETYPE:
1530 value = xmlSchemaValueGetAsString(val);
1531 if (value != NULL) {
1532 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1533 value2 = xmlSchemaCollapseString(value);
1534 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1535 value2 = xmlSchemaWhiteSpaceReplace(value);
1536 if (value2 != NULL)
1537 value = value2;
1538 }
1539 break;
1540 default:
1541 if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1542 if (value2 != NULL)
1543 xmlFree((xmlChar *) value2);
1544 goto internal_error;
1545 }
1546 if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1547 /* We can mostly use the canonical value for hashing,
1548 except in the case of decimal. There the canonical
1549 representation requires a trailing '.0' even for
1550 non-fractional numbers, but for the derived integer
1551 types it forbids any decimal point. Nevertheless they
1552 compare equal if the value is equal. We need to generate
1553 the same hash value for this to work, and it's easiest
1554 to just cut off the useless '.0' suffix for the
1555 decimal type. */
1556 int len = xmlStrlen(value2);
1557 if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1558 ((xmlChar*)value2)[len-2] = 0;
1559 }
1560 value = value2;
1561 }
1562 if (*retValue == NULL)
1563 if (value == NULL) {
1564 if (! list)
1565 *retValue = xmlStrdup(BAD_CAST "");
1566 } else
1567 *retValue = xmlStrdup(value);
1568 else if (value != NULL) {
1569 /* List. */
1570 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1571 *retValue = xmlStrcat((xmlChar *) *retValue, value);
1572 }
1573 FREE_AND_NULL(value2)
1574 val = xmlSchemaValueGetNext(val);
1575 } while (val != NULL);
1576
1577 return (0);
1578internal_error:
1579 if (*retValue != NULL)
1580 xmlFree((xmlChar *) (*retValue));
1581 if (value2 != NULL)
1582 xmlFree((xmlChar *) value2);
1583 return (-1);
1584}
1585
1586static int
1587xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1588 xmlSchemaWhitespaceValueType ws,
1589 xmlChar **retValue)
1590{
1591 return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1592}
1593
1594static int
1595xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1596 xmlChar **retValue)
1597{
1598 return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1599 retValue, 1);
1600}
1601
1628static xmlChar*
1629xmlSchemaFormatItemForReport(xmlChar **buf,
1630 const xmlChar *itemDes,
1631 xmlSchemaBasicItemPtr item,
1632 xmlNodePtr itemNode)
1633{
1634 xmlChar *str = NULL;
1635 int named = 1;
1636
1637 if (*buf != NULL) {
1638 xmlFree(*buf);
1639 *buf = NULL;
1640 }
1641
1642 if (itemDes != NULL) {
1643 *buf = xmlStrdup(itemDes);
1644 } else if (item != NULL) {
1645 switch (item->type) {
1646 case XML_SCHEMA_TYPE_BASIC: {
1647 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1648
1649 if (WXS_IS_ATOMIC(type))
1650 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1651 else if (WXS_IS_LIST(type))
1652 *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1653 else if (WXS_IS_UNION(type))
1654 *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1655 else
1656 *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1657 *buf = xmlStrcat(*buf, type->name);
1658 *buf = xmlStrcat(*buf, BAD_CAST "'");
1659 }
1660 break;
1661 case XML_SCHEMA_TYPE_SIMPLE: {
1662 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1663
1664 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1665 *buf = xmlStrdup(BAD_CAST"");
1666 } else {
1667 *buf = xmlStrdup(BAD_CAST "local ");
1668 }
1669 if (WXS_IS_ATOMIC(type))
1670 *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1671 else if (WXS_IS_LIST(type))
1672 *buf = xmlStrcat(*buf, BAD_CAST "list type");
1673 else if (WXS_IS_UNION(type))
1674 *buf = xmlStrcat(*buf, BAD_CAST "union type");
1675 else
1676 *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1677 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1678 *buf = xmlStrcat(*buf, BAD_CAST " '");
1679 *buf = xmlStrcat(*buf, type->name);
1680 *buf = xmlStrcat(*buf, BAD_CAST "'");
1681 }
1682 }
1683 break;
1684 case XML_SCHEMA_TYPE_COMPLEX: {
1685 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1686
1687 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1688 *buf = xmlStrdup(BAD_CAST "");
1689 else
1690 *buf = xmlStrdup(BAD_CAST "local ");
1691 *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1692 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1693 *buf = xmlStrcat(*buf, BAD_CAST " '");
1694 *buf = xmlStrcat(*buf, type->name);
1695 *buf = xmlStrcat(*buf, BAD_CAST "'");
1696 }
1697 }
1698 break;
1699 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1700 xmlSchemaAttributeUsePtr ause;
1701
1702 ause = WXS_ATTR_USE_CAST item;
1703 *buf = xmlStrdup(BAD_CAST "attribute use ");
1704 if (WXS_ATTRUSE_DECL(ause) != NULL) {
1705 *buf = xmlStrcat(*buf, BAD_CAST "'");
1706 *buf = xmlStrcat(*buf,
1707 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1708 FREE_AND_NULL(str)
1709 *buf = xmlStrcat(*buf, BAD_CAST "'");
1710 } else {
1711 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1712 }
1713 }
1714 break;
1715 case XML_SCHEMA_TYPE_ATTRIBUTE: {
1716 xmlSchemaAttributePtr attr;
1717
1718 attr = (xmlSchemaAttributePtr) item;
1719 *buf = xmlStrdup(BAD_CAST "attribute decl.");
1720 *buf = xmlStrcat(*buf, BAD_CAST " '");
1721 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1722 attr->targetNamespace, attr->name));
1723 FREE_AND_NULL(str)
1724 *buf = xmlStrcat(*buf, BAD_CAST "'");
1725 }
1726 break;
1727 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1728 xmlSchemaGetComponentDesignation(buf, item);
1729 break;
1730 case XML_SCHEMA_TYPE_ELEMENT: {
1731 xmlSchemaElementPtr elem;
1732
1733 elem = (xmlSchemaElementPtr) item;
1734 *buf = xmlStrdup(BAD_CAST "element decl.");
1735 *buf = xmlStrcat(*buf, BAD_CAST " '");
1736 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1737 elem->targetNamespace, elem->name));
1738 *buf = xmlStrcat(*buf, BAD_CAST "'");
1739 }
1740 break;
1741 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1742 case XML_SCHEMA_TYPE_IDC_KEY:
1743 case XML_SCHEMA_TYPE_IDC_KEYREF:
1744 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1745 *buf = xmlStrdup(BAD_CAST "unique '");
1746 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1747 *buf = xmlStrdup(BAD_CAST "key '");
1748 else
1749 *buf = xmlStrdup(BAD_CAST "keyRef '");
1750 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1751 *buf = xmlStrcat(*buf, BAD_CAST "'");
1752 break;
1753 case XML_SCHEMA_TYPE_ANY:
1754 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1755 *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1756 ((xmlSchemaWildcardPtr) item)->processContents));
1757 *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1758 break;
1759 case XML_SCHEMA_FACET_MININCLUSIVE:
1760 case XML_SCHEMA_FACET_MINEXCLUSIVE:
1761 case XML_SCHEMA_FACET_MAXINCLUSIVE:
1762 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1763 case XML_SCHEMA_FACET_TOTALDIGITS:
1764 case XML_SCHEMA_FACET_FRACTIONDIGITS:
1765 case XML_SCHEMA_FACET_PATTERN:
1766 case XML_SCHEMA_FACET_ENUMERATION:
1767 case XML_SCHEMA_FACET_WHITESPACE:
1768 case XML_SCHEMA_FACET_LENGTH:
1769 case XML_SCHEMA_FACET_MAXLENGTH:
1770 case XML_SCHEMA_FACET_MINLENGTH:
1771 *buf = xmlStrdup(BAD_CAST "facet '");
1772 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1773 *buf = xmlStrcat(*buf, BAD_CAST "'");
1774 break;
1775 case XML_SCHEMA_TYPE_GROUP: {
1776 *buf = xmlStrdup(BAD_CAST "model group def.");
1777 *buf = xmlStrcat(*buf, BAD_CAST " '");
1778 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1779 *buf = xmlStrcat(*buf, BAD_CAST "'");
1780 FREE_AND_NULL(str)
1781 }
1782 break;
1783 case XML_SCHEMA_TYPE_SEQUENCE:
1784 case XML_SCHEMA_TYPE_CHOICE:
1785 case XML_SCHEMA_TYPE_ALL:
1786 case XML_SCHEMA_TYPE_PARTICLE:
1787 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1788 break;
1789 case XML_SCHEMA_TYPE_NOTATION: {
1790 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1791 *buf = xmlStrcat(*buf, BAD_CAST " '");
1792 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1793 *buf = xmlStrcat(*buf, BAD_CAST "'");
1794 FREE_AND_NULL(str);
1795 }
1796 /* Falls through. */
1797 default:
1798 named = 0;
1799 }
1800 } else
1801 named = 0;
1802
1803 if ((named == 0) && (itemNode != NULL)) {
1805
1806 if (itemNode->type == XML_ATTRIBUTE_NODE)
1807 elem = itemNode->parent;
1808 else
1809 elem = itemNode;
1810 *buf = xmlStrdup(BAD_CAST "Element '");
1811 if (elem->ns != NULL) {
1812 *buf = xmlStrcat(*buf,
1813 xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1814 FREE_AND_NULL(str)
1815 } else
1816 *buf = xmlStrcat(*buf, elem->name);
1817 *buf = xmlStrcat(*buf, BAD_CAST "'");
1818
1819 }
1820 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1821 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1822 if (itemNode->ns != NULL) {
1823 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1824 itemNode->ns->href, itemNode->name));
1825 FREE_AND_NULL(str)
1826 } else
1827 *buf = xmlStrcat(*buf, itemNode->name);
1828 *buf = xmlStrcat(*buf, BAD_CAST "'");
1829 }
1830 FREE_AND_NULL(str)
1831
1832 return (xmlEscapeFormatString(buf));
1833}
1834
1844static const xmlChar *
1845xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1846 xmlChar **buf, xmlSchemaTypePtr type)
1847{
1848 xmlSchemaFacetPtr facet;
1849 xmlSchemaWhitespaceValueType ws;
1850 xmlChar *value = NULL;
1851 int res, found = 0;
1852
1853 if (*buf != NULL)
1854 xmlFree(*buf);
1855 *buf = NULL;
1856
1857 do {
1858 /*
1859 * Use the whitespace type of the base type.
1860 */
1861 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1862 for (facet = type->facets; facet != NULL; facet = facet->next) {
1863 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1864 continue;
1865 found = 1;
1866 res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1867 ws, &value);
1868 if (res == -1) {
1869 xmlSchemaInternalErr(actxt,
1870 "xmlSchemaFormatFacetEnumSet",
1871 "compute the canonical lexical representation");
1872 if (*buf != NULL)
1873 xmlFree(*buf);
1874 *buf = NULL;
1875 return (NULL);
1876 }
1877 if (*buf == NULL)
1878 *buf = xmlStrdup(BAD_CAST "'");
1879 else
1880 *buf = xmlStrcat(*buf, BAD_CAST ", '");
1882 *buf = xmlStrcat(*buf, BAD_CAST "'");
1883 if (value != NULL) {
1884 xmlFree((xmlChar *)value);
1885 value = NULL;
1886 }
1887 }
1888 /*
1889 * The enumeration facet of a type restricts the enumeration
1890 * facet of the ancestor type; i.e., such restricted enumerations
1891 * do not belong to the set of the given type. Thus we break
1892 * on the first found enumeration.
1893 */
1894 if (found)
1895 break;
1896 type = type->baseType;
1897 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1898
1899 return ((const xmlChar *) *buf);
1900}
1901
1902/************************************************************************
1903 * *
1904 * Error functions *
1905 * *
1906 ************************************************************************/
1907
1908#if 0
1909static void
1910xmlSchemaErrMemory(const char *msg)
1911{
1912 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1913 msg);
1914}
1915#endif
1916
1917static void
1918xmlSchemaPSimpleErr(const char *msg)
1919{
1920 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1921 msg);
1922}
1923
1931static void
1932xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1933 const char *extra, xmlNodePtr node)
1934{
1935 if (ctxt != NULL)
1936 ctxt->nberrors++;
1937 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
1938 extra);
1939}
1940
1952static void LIBXML_ATTR_FORMAT(4,0)
1953xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1954 const char *msg, const xmlChar * str1, const xmlChar * str2)
1955{
1956 xmlGenericErrorFunc channel = NULL;
1957 xmlStructuredErrorFunc schannel = NULL;
1958 void *data = NULL;
1959
1960 if (ctxt != NULL) {
1961 ctxt->nberrors++;
1962 ctxt->err = error;
1963 channel = ctxt->error;
1964 data = ctxt->errCtxt;
1965 schannel = ctxt->serror;
1966 }
1967 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1969 (const char *) str1, (const char *) str2, NULL, 0, 0,
1970 msg, str1, str2);
1971}
1972
1985static void LIBXML_ATTR_FORMAT(5,0)
1986xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1987 xmlNodePtr child, int error,
1988 const char *msg, const xmlChar * str1, const xmlChar * str2)
1989{
1990 if (child != NULL)
1991 xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1992 else
1993 xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1994}
1995
1996
2014static void LIBXML_ATTR_FORMAT(7,0)
2015xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
2016 const xmlChar * strData1, const xmlChar * strData2,
2017 const xmlChar * strData3, const char *msg, const xmlChar * str1,
2018 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2019 const xmlChar * str5)
2020{
2021
2022 xmlGenericErrorFunc channel = NULL;
2023 xmlStructuredErrorFunc schannel = NULL;
2024 void *data = NULL;
2025
2026 if (ctxt != NULL) {
2027 ctxt->nberrors++;
2028 ctxt->err = error;
2029 channel = ctxt->error;
2030 data = ctxt->errCtxt;
2031 schannel = ctxt->serror;
2032 }
2033 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
2035 (const char *) strData1, (const char *) strData2,
2036 (const char *) strData3, 0, 0, msg, str1, str2,
2037 str3, str4, str5);
2038}
2039
2040/************************************************************************
2041 * *
2042 * Allround error functions *
2043 * *
2044 ************************************************************************/
2045
2053static void
2054xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
2055 const char *extra, xmlNodePtr node)
2056{
2057 if (ctxt != NULL) {
2058 ctxt->nberrors++;
2059 ctxt->err = XML_SCHEMAV_INTERNAL;
2060 }
2061 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
2062 extra);
2063}
2064
2065static void LIBXML_ATTR_FORMAT(2,0)
2066xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2067 const char *msg, const xmlChar *str)
2068{
2069 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2070 msg, (const char *) str);
2071}
2072
2073#define WXS_ERROR_TYPE_ERROR 1
2074#define WXS_ERROR_TYPE_WARNING 2
2090static void LIBXML_ATTR_FORMAT(6,0)
2091xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2092 xmlErrorLevel errorLevel,
2093 int error, xmlNodePtr node, int line, const char *msg,
2094 const xmlChar *str1, const xmlChar *str2,
2095 const xmlChar *str3, const xmlChar *str4)
2096{
2097 xmlStructuredErrorFunc schannel = NULL;
2098 xmlGenericErrorFunc channel = NULL;
2099 void *data = NULL;
2100
2101 if (ctxt != NULL) {
2102 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2103 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2104 const char *file = NULL;
2105 int col = 0;
2106 if (errorLevel != XML_ERR_WARNING) {
2107 vctxt->nberrors++;
2108 vctxt->err = error;
2109 channel = vctxt->error;
2110 } else {
2111 channel = vctxt->warning;
2112 }
2113 schannel = vctxt->serror;
2114 data = vctxt->errCtxt;
2115
2116 /*
2117 * Error node. If we specify a line number, then
2118 * do not channel any node to the error function.
2119 */
2120 if (line == 0) {
2121 if ((node == NULL) &&
2122 (vctxt->depth >= 0) &&
2123 (vctxt->inode != NULL)) {
2124 node = vctxt->inode->node;
2125 }
2126 /*
2127 * Get filename and line if no node-tree.
2128 */
2129 if ((node == NULL) &&
2130 (vctxt->parserCtxt != NULL) &&
2131 (vctxt->parserCtxt->input != NULL)) {
2132 file = vctxt->parserCtxt->input->filename;
2133 line = vctxt->parserCtxt->input->line;
2134 col = vctxt->parserCtxt->input->col;
2135 }
2136 } else {
2137 /*
2138 * Override the given node's (if any) position
2139 * and channel only the given line number.
2140 */
2141 node = NULL;
2142 /*
2143 * Get filename.
2144 */
2145 if (vctxt->doc != NULL)
2146 file = (const char *) vctxt->doc->URL;
2147 else if ((vctxt->parserCtxt != NULL) &&
2148 (vctxt->parserCtxt->input != NULL))
2149 file = vctxt->parserCtxt->input->filename;
2150 }
2151 if (vctxt->locFunc != NULL) {
2152 if ((file == NULL) || (line == 0)) {
2153 unsigned long l;
2154 const char *f;
2155 vctxt->locFunc(vctxt->locCtxt, &f, &l);
2156 if (file == NULL)
2157 file = f;
2158 if (line == 0)
2159 line = (int) l;
2160 }
2161 }
2162 if ((file == NULL) && (vctxt->filename != NULL))
2163 file = vctxt->filename;
2164
2165 __xmlRaiseError(schannel, channel, data, ctxt,
2167 error, errorLevel, file, line,
2168 (const char *) str1, (const char *) str2,
2169 (const char *) str3, 0, col, msg, str1, str2, str3, str4);
2170
2171 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2172 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2173 if (errorLevel != XML_ERR_WARNING) {
2174 pctxt->nberrors++;
2175 pctxt->err = error;
2176 channel = pctxt->error;
2177 } else {
2178 channel = pctxt->warning;
2179 }
2180 schannel = pctxt->serror;
2181 data = pctxt->errCtxt;
2182 __xmlRaiseError(schannel, channel, data, ctxt,
2184 errorLevel, NULL, 0,
2185 (const char *) str1, (const char *) str2,
2186 (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2187 } else {
2188 TODO
2189 }
2190 }
2191}
2192
2205static void LIBXML_ATTR_FORMAT(4,0)
2206xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2207 int error, xmlNodePtr node, const char *msg,
2208 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2209{
2210 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2211 msg, str1, str2, str3, NULL);
2212}
2213
2214static void LIBXML_ATTR_FORMAT(4,0)
2215xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2216 int error, xmlNodePtr node, const char *msg,
2217 const xmlChar *str1, const xmlChar *str2,
2218 const xmlChar *str3, const xmlChar *str4)
2219{
2220 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2221 msg, str1, str2, str3, str4);
2222}
2223
2224static void LIBXML_ATTR_FORMAT(4,0)
2225xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2226 int error, xmlNodePtr node, const char *msg,
2227 const xmlChar *str1, const xmlChar *str2)
2228{
2229 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2230}
2231
2232static xmlChar *
2233xmlSchemaFormatNodeForError(xmlChar ** msg,
2234 xmlSchemaAbstractCtxtPtr actxt,
2236{
2237 xmlChar *str = NULL;
2238
2239 *msg = NULL;
2240 if ((node != NULL) &&
2241 (node->type != XML_ELEMENT_NODE) &&
2242 (node->type != XML_ATTRIBUTE_NODE))
2243 {
2244 /*
2245 * Don't try to format other nodes than element and
2246 * attribute nodes.
2247 * Play safe and return an empty string.
2248 */
2249 *msg = xmlStrdup(BAD_CAST "");
2250 return(*msg);
2251 }
2252 if (node != NULL) {
2253 /*
2254 * Work on tree nodes.
2255 */
2256 if (node->type == XML_ATTRIBUTE_NODE) {
2257 xmlNodePtr elem = node->parent;
2258
2259 *msg = xmlStrdup(BAD_CAST "Element '");
2260 if (elem->ns != NULL)
2261 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2262 elem->ns->href, elem->name));
2263 else
2264 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2265 NULL, elem->name));
2266 FREE_AND_NULL(str);
2267 *msg = xmlStrcat(*msg, BAD_CAST "', ");
2268 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2269 } else {
2270 *msg = xmlStrdup(BAD_CAST "Element '");
2271 }
2272 if (node->ns != NULL)
2273 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2274 node->ns->href, node->name));
2275 else
2276 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2277 NULL, node->name));
2278 FREE_AND_NULL(str);
2279 *msg = xmlStrcat(*msg, BAD_CAST "': ");
2280 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2281 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2282 /*
2283 * Work on node infos.
2284 */
2285 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2286 xmlSchemaNodeInfoPtr ielem =
2287 vctxt->elemInfos[vctxt->depth];
2288
2289 *msg = xmlStrdup(BAD_CAST "Element '");
2290 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2291 ielem->nsName, ielem->localName));
2292 FREE_AND_NULL(str);
2293 *msg = xmlStrcat(*msg, BAD_CAST "', ");
2294 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2295 } else {
2296 *msg = xmlStrdup(BAD_CAST "Element '");
2297 }
2298 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2299 vctxt->inode->nsName, vctxt->inode->localName));
2300 FREE_AND_NULL(str);
2301 *msg = xmlStrcat(*msg, BAD_CAST "': ");
2302 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2303 /*
2304 * Hmm, no node while parsing?
2305 * Return an empty string, in case NULL will break something.
2306 */
2307 *msg = xmlStrdup(BAD_CAST "");
2308 } else {
2309 TODO
2310 return (NULL);
2311 }
2312
2313 /*
2314 * xmlSchemaFormatItemForReport() also returns an escaped format
2315 * string, so do this before calling it below (in the future).
2316 */
2318
2319 /*
2320 * VAL TODO: The output of the given schema component is currently
2321 * disabled.
2322 */
2323#if 0
2324 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2325 *msg = xmlStrcat(*msg, BAD_CAST " [");
2326 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2327 NULL, type, NULL, 0));
2328 FREE_AND_NULL(str)
2329 *msg = xmlStrcat(*msg, BAD_CAST "]");
2330 }
2331#endif
2332 return (*msg);
2333}
2334
2335static void LIBXML_ATTR_FORMAT(3,0)
2336xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2337 const char *funcName,
2338 const char *message,
2339 const xmlChar *str1,
2340 const xmlChar *str2)
2341{
2342 xmlChar *msg = NULL;
2343
2344 if (actxt == NULL)
2345 return;
2346 msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2348 msg = xmlStrcat(msg, BAD_CAST ".\n");
2349
2350 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2351 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2352 (const char *) msg, (const xmlChar *) funcName, str1, str2);
2353 else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2354 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2355 (const char *) msg, (const xmlChar *) funcName, str1, str2);
2356
2357 FREE_AND_NULL(msg)
2358}
2359
2360static void LIBXML_ATTR_FORMAT(3,0)
2361xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2362 const char *funcName,
2363 const char *message)
2364{
2365 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2366}
2367
2368#if 0
2369static void LIBXML_ATTR_FORMAT(3,0)
2370xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2371 const char *funcName,
2372 const char *message,
2373 const xmlChar *str1,
2374 const xmlChar *str2)
2375{
2376 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2377 str1, str2);
2378}
2379#endif
2380
2381static void LIBXML_ATTR_FORMAT(5,0)
2382xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2385 xmlSchemaBasicItemPtr item,
2386 const char *message,
2387 const xmlChar *str1, const xmlChar *str2,
2388 const xmlChar *str3, const xmlChar *str4)
2389{
2390 xmlChar *msg = NULL;
2391
2392 if ((node == NULL) && (item != NULL) &&
2393 (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2394 node = WXS_ITEM_NODE(item);
2395 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2396 msg = xmlStrcat(msg, BAD_CAST ": ");
2397 } else
2398 xmlSchemaFormatNodeForError(&msg, actxt, node);
2399 msg = xmlStrcat(msg, (const xmlChar *) message);
2400 msg = xmlStrcat(msg, BAD_CAST ".\n");
2401 xmlSchemaErr4(actxt, error, node,
2402 (const char *) msg, str1, str2, str3, str4);
2403 FREE_AND_NULL(msg)
2404}
2405
2406static void LIBXML_ATTR_FORMAT(5,0)
2407xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2410 xmlSchemaBasicItemPtr item,
2411 const char *message,
2412 const xmlChar *str1,
2413 const xmlChar *str2)
2414{
2415 xmlSchemaCustomErr4(actxt, error, node, item,
2416 message, str1, str2, NULL, NULL);
2417}
2418
2419
2420
2421static void LIBXML_ATTR_FORMAT(5,0)
2422xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2425 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2426 const char *message,
2427 const xmlChar *str1,
2428 const xmlChar *str2,
2429 const xmlChar *str3)
2430{
2431 xmlChar *msg = NULL;
2432
2433 xmlSchemaFormatNodeForError(&msg, actxt, node);
2434 msg = xmlStrcat(msg, (const xmlChar *) message);
2435 msg = xmlStrcat(msg, BAD_CAST ".\n");
2436
2437 /* URGENT TODO: Set the error code to something sane. */
2438 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2439 (const char *) msg, str1, str2, str3, NULL);
2440
2441 FREE_AND_NULL(msg)
2442}
2443
2444
2445
2446static void LIBXML_ATTR_FORMAT(5,0)
2447xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2449 xmlSchemaPSVIIDCNodePtr idcNode,
2450 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2451 const char *message,
2452 const xmlChar *str1,
2453 const xmlChar *str2)
2454{
2455 xmlChar *msg = NULL, *qname = NULL;
2456
2457 msg = xmlStrdup(BAD_CAST "Element '%s': ");
2458 msg = xmlStrcat(msg, (const xmlChar *) message);
2459 msg = xmlStrcat(msg, BAD_CAST ".\n");
2460 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2461 error, NULL, idcNode->nodeLine, (const char *) msg,
2462 xmlSchemaFormatQName(&qname,
2463 vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2464 vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2465 str1, str2, NULL);
2466 FREE_AND_NULL(qname);
2467 FREE_AND_NULL(msg);
2468}
2469
2470static int
2471xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2473{
2474 if (node != NULL)
2475 return (node->type);
2476 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2477 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2478 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2479 return (-1);
2480}
2481
2482static int
2483xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2484{
2485 switch (item->type) {
2486 case XML_SCHEMA_TYPE_COMPLEX:
2487 case XML_SCHEMA_TYPE_SIMPLE:
2488 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2489 return(1);
2490 break;
2491 case XML_SCHEMA_TYPE_GROUP:
2492 return (1);
2493 case XML_SCHEMA_TYPE_ELEMENT:
2494 if ( ((xmlSchemaElementPtr) item)->flags &
2495 XML_SCHEMAS_ELEM_GLOBAL)
2496 return(1);
2497 break;
2498 case XML_SCHEMA_TYPE_ATTRIBUTE:
2499 if ( ((xmlSchemaAttributePtr) item)->flags &
2500 XML_SCHEMAS_ATTR_GLOBAL)
2501 return(1);
2502 break;
2503 /* Note that attribute groups are always global. */
2504 default:
2505 return(1);
2506 }
2507 return (0);
2508}
2509
2510static void
2511xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2514 const xmlChar *value,
2515 xmlSchemaTypePtr type,
2516 int displayValue)
2517{
2518 xmlChar *msg = NULL;
2519
2520 xmlSchemaFormatNodeForError(&msg, actxt, node);
2521
2522 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2524 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2525 else
2526 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2527 "value of ");
2528
2529 if (! xmlSchemaIsGlobalItem(type))
2530 msg = xmlStrcat(msg, BAD_CAST "the local ");
2531 else
2532 msg = xmlStrcat(msg, BAD_CAST "the ");
2533
2534 if (WXS_IS_ATOMIC(type))
2535 msg = xmlStrcat(msg, BAD_CAST "atomic type");
2536 else if (WXS_IS_LIST(type))
2537 msg = xmlStrcat(msg, BAD_CAST "list type");
2538 else if (WXS_IS_UNION(type))
2539 msg = xmlStrcat(msg, BAD_CAST "union type");
2540
2541 if (xmlSchemaIsGlobalItem(type)) {
2542 xmlChar *str = NULL;
2543 msg = xmlStrcat(msg, BAD_CAST " '");
2544 if (type->builtInType != 0) {
2545 msg = xmlStrcat(msg, BAD_CAST "xs:");
2546 str = xmlStrdup(type->name);
2547 } else {
2548 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2549 if (!str)
2550 str = xmlStrdup(qName);
2551 }
2553 msg = xmlStrcat(msg, BAD_CAST "'");
2554 FREE_AND_NULL(str);
2555 }
2556 msg = xmlStrcat(msg, BAD_CAST ".\n");
2557 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2559 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2560 else
2561 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2562 FREE_AND_NULL(msg)
2563}
2564
2565static const xmlChar *
2566xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2567 xmlSchemaNodeInfoPtr ni,
2569{
2570 if (node != NULL) {
2571 if (node->ns != NULL)
2572 return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2573 else
2574 return (xmlSchemaFormatQName(str, NULL, node->name));
2575 } else if (ni != NULL)
2576 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2577 return (NULL);
2578}
2579
2580static void
2581xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2583 xmlSchemaAttrInfoPtr ni,
2585{
2586 xmlChar *msg = NULL, *str = NULL;
2587
2588 xmlSchemaFormatNodeForError(&msg, actxt, node);
2589 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2590 xmlSchemaErr(actxt, error, node, (const char *) msg,
2591 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2592 NULL);
2593 FREE_AND_NULL(str)
2594 FREE_AND_NULL(msg)
2595}
2596
2597static void LIBXML_ATTR_FORMAT(5,0)
2598xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2601 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2602 const char *message,
2603 int nbval,
2604 int nbneg,
2605 xmlChar **values)
2606{
2607 xmlChar *str = NULL, *msg = NULL;
2608 xmlChar *localName, *nsName;
2609 const xmlChar *cur, *end;
2610 int i;
2611
2612 xmlSchemaFormatNodeForError(&msg, actxt, node);
2613 msg = xmlStrcat(msg, (const xmlChar *) message);
2614 msg = xmlStrcat(msg, BAD_CAST ".");
2615 /*
2616 * Note that is does not make sense to report that we have a
2617 * wildcard here, since the wildcard might be unfolded into
2618 * multiple transitions.
2619 */
2620 if (nbval + nbneg > 0) {
2621 if (nbval + nbneg > 1) {
2622 str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2623 } else
2624 str = xmlStrdup(BAD_CAST " Expected is ( ");
2625 nsName = NULL;
2626
2627 for (i = 0; i < nbval + nbneg; i++) {
2628 cur = values[i];
2629 if (cur == NULL)
2630 continue;
2631 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2632 (cur[3] == ' ')) {
2633 cur += 4;
2634 str = xmlStrcat(str, BAD_CAST "##other");
2635 }
2636 /*
2637 * Get the local name.
2638 */
2639 localName = NULL;
2640
2641 end = cur;
2642 if (*end == '*') {
2643 localName = xmlStrdup(BAD_CAST "*");
2644 end++;
2645 } else {
2646 while ((*end != 0) && (*end != '|'))
2647 end++;
2648 localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2649 }
2650 if (*end != 0) {
2651 end++;
2652 /*
2653 * Skip "*|*" if they come with negated expressions, since
2654 * they represent the same negated wildcard.
2655 */
2656 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2657 /*
2658 * Get the namespace name.
2659 */
2660 cur = end;
2661 if (*end == '*') {
2662 nsName = xmlStrdup(BAD_CAST "{*}");
2663 } else {
2664 while (*end != 0)
2665 end++;
2666
2667 if (i >= nbval)
2668 nsName = xmlStrdup(BAD_CAST "{##other:");
2669 else
2670 nsName = xmlStrdup(BAD_CAST "{");
2671
2672 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2673 nsName = xmlStrcat(nsName, BAD_CAST "}");
2674 }
2675 str = xmlStrcat(str, BAD_CAST nsName);
2676 FREE_AND_NULL(nsName)
2677 } else {
2678 FREE_AND_NULL(localName);
2679 continue;
2680 }
2681 }
2682 str = xmlStrcat(str, BAD_CAST localName);
2683 FREE_AND_NULL(localName);
2684
2685 if (i < nbval + nbneg -1)
2686 str = xmlStrcat(str, BAD_CAST ", ");
2687 }
2688 str = xmlStrcat(str, BAD_CAST " ).\n");
2690 FREE_AND_NULL(str)
2691 } else
2692 msg = xmlStrcat(msg, BAD_CAST "\n");
2693 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2694 xmlFree(msg);
2695}
2696
2697static void LIBXML_ATTR_FORMAT(8,0)
2698xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2702 unsigned long length,
2703 xmlSchemaTypePtr type,
2704 xmlSchemaFacetPtr facet,
2705 const char *message,
2706 const xmlChar *str1,
2707 const xmlChar *str2)
2708{
2709 xmlChar *str = NULL, *msg = NULL;
2710 xmlSchemaTypeType facetType;
2711 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2712
2713 xmlSchemaFormatNodeForError(&msg, actxt, node);
2715 facetType = XML_SCHEMA_FACET_ENUMERATION;
2716 /*
2717 * If enumerations are validated, one must not expect the
2718 * facet to be given.
2719 */
2720 } else
2721 facetType = facet->type;
2722 msg = xmlStrcat(msg, BAD_CAST "[");
2723 msg = xmlStrcat(msg, BAD_CAST "facet '");
2724 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2725 msg = xmlStrcat(msg, BAD_CAST "'] ");
2726 if (message == NULL) {
2727 /*
2728 * Use a default message.
2729 */
2730 if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2731 (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2732 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2733
2734 char len[25], actLen[25];
2735
2736 /* FIXME, TODO: What is the max expected string length of the
2737 * this value?
2738 */
2739 if (nodeType == XML_ATTRIBUTE_NODE)
2740 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2741 else
2742 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2743
2744 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2745 snprintf(actLen, 24, "%lu", length);
2746
2747 if (facetType == XML_SCHEMA_FACET_LENGTH)
2748 msg = xmlStrcat(msg,
2749 BAD_CAST "this differs from the allowed length of '%s'.\n");
2750 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2751 msg = xmlStrcat(msg,
2752 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2753 else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2754 msg = xmlStrcat(msg,
2755 BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2756
2757 if (nodeType == XML_ATTRIBUTE_NODE)
2758 xmlSchemaErr3(actxt, error, node, (const char *) msg,
2759 value, (const xmlChar *) actLen, (const xmlChar *) len);
2760 else
2761 xmlSchemaErr(actxt, error, node, (const char *) msg,
2762 (const xmlChar *) actLen, (const xmlChar *) len);
2763
2764 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2765 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2766 "of the set {%s}.\n");
2767 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2768 xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2769 } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2770 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2771 "by the pattern '%s'.\n");
2772 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2773 facet->value);
2774 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2775 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2776 "minimum value allowed ('%s').\n");
2777 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2778 facet->value);
2779 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2780 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2781 "maximum value allowed ('%s').\n");
2782 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2783 facet->value);
2784 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2785 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2786 "'%s'.\n");
2787 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2788 facet->value);
2789 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2790 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2791 "'%s'.\n");
2792 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2793 facet->value);
2794 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2795 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2796 "digits than are allowed ('%s').\n");
2797 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2798 facet->value);
2799 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2800 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2801 "digits than are allowed ('%s').\n");
2802 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2803 facet->value);
2804 } else if (nodeType == XML_ATTRIBUTE_NODE) {
2805 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2806 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2807 } else {
2808 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2809 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2810 }
2811 } else {
2812 msg = xmlStrcat(msg, (const xmlChar *) message);
2813 msg = xmlStrcat(msg, BAD_CAST ".\n");
2814 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2815 }
2816 FREE_AND_NULL(str)
2817 xmlFree(msg);
2818}
2819
2820#define VERROR(err, type, msg) \
2821 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2822
2823#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2824
2825#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2826#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2827
2828#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2829
2830
2841static void
2842xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2844 xmlSchemaBasicItemPtr ownerItem,
2845 xmlNodePtr ownerElem,
2846 const char *name,
2847 const char *message)
2848{
2849 xmlChar *des = NULL;
2850
2851 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2852
2853 if (message != NULL)
2854 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2855 else
2856 xmlSchemaPErr(ctxt, ownerElem, error,
2857 "%s: The attribute '%s' is required but missing.\n",
2859 FREE_AND_NULL(des);
2860}
2861
2862
2877static void
2878xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2880 xmlSchemaBasicItemPtr ownerItem,
2881 xmlNodePtr ownerElem,
2882 const char *name,
2883 const xmlChar *refName,
2884 const xmlChar *refURI,
2885 xmlSchemaTypeType refType,
2886 const char *refTypeStr)
2887{
2888 xmlChar *des = NULL, *strA = NULL;
2889
2890 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2891 if (refTypeStr == NULL)
2892 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2893 xmlSchemaPErrExt(ctxt, ownerElem, error,
2894 NULL, NULL, NULL,
2895 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2896 "%s.\n", BAD_CAST des, BAD_CAST name,
2897 xmlSchemaFormatQName(&strA, refURI, refName),
2898 BAD_CAST refTypeStr, NULL);
2899 FREE_AND_NULL(des)
2900 FREE_AND_NULL(strA)
2901}
2902
2913static void
2914xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2916 xmlChar **ownerDes,
2917 xmlSchemaBasicItemPtr ownerItem,
2919 const char *msg)
2920{
2921 xmlChar *des = NULL;
2922
2923 if (ownerDes == NULL)
2924 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2925 else if (*ownerDes == NULL) {
2926 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2927 des = *ownerDes;
2928 } else
2929 des = *ownerDes;
2930 if (attr == NULL) {
2931 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2932 "%s, attribute '%s': %s.\n",
2933 BAD_CAST des, (const xmlChar *) "Unknown",
2934 (const xmlChar *) msg, NULL, NULL);
2935 } else {
2936 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2937 "%s, attribute '%s': %s.\n",
2938 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2939 }
2940 if (ownerDes == NULL)
2941 FREE_AND_NULL(des);
2942}
2943
2953static void
2954xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2956 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2958{
2959 xmlChar *strA = NULL, *strB = NULL;
2960
2961 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2962 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2963 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2964 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2965 NULL, NULL);
2966 FREE_AND_NULL(strA);
2967 FREE_AND_NULL(strB);
2968}
2969
2984static void LIBXML_ATTR_FORMAT(5,0)
2985xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2987 xmlSchemaBasicItemPtr item,
2988 xmlNodePtr itemElem,
2989 const char *message,
2990 const xmlChar *str1,
2991 const xmlChar *str2,
2992 const xmlChar *str3)
2993{
2994 xmlChar *des = NULL, *msg = NULL;
2995
2996 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
2997 msg = xmlStrdup(BAD_CAST "%s: ");
2998 msg = xmlStrcat(msg, (const xmlChar *) message);
2999 msg = xmlStrcat(msg, BAD_CAST ".\n");
3000 if ((itemElem == NULL) && (item != NULL))
3001 itemElem = WXS_ITEM_NODE(item);
3002 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3003 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3004 FREE_AND_NULL(des);
3005 FREE_AND_NULL(msg);
3006}
3007
3020static void LIBXML_ATTR_FORMAT(5,0)
3021xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3023 xmlSchemaBasicItemPtr item,
3024 xmlNodePtr itemElem,
3025 const char *message,
3026 const xmlChar *str1)
3027{
3028 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3029 str1, NULL, NULL);
3030}
3031
3045static void LIBXML_ATTR_FORMAT(6,0)
3046xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3049 xmlSchemaBasicItemPtr ownerItem,
3050 const xmlSchemaAttributeUsePtr attruse,
3051 const char *message,
3052 const xmlChar *str1, const xmlChar *str2,
3053 const xmlChar *str3,const xmlChar *str4)
3054{
3055 xmlChar *str = NULL, *msg = NULL;
3056
3057 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3058 msg = xmlStrcat(msg, BAD_CAST ", ");
3059 msg = xmlStrcat(msg,
3060 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3061 WXS_BASIC_CAST attruse, NULL));
3062 FREE_AND_NULL(str);
3063 msg = xmlStrcat(msg, BAD_CAST ": ");
3064 msg = xmlStrcat(msg, (const xmlChar *) message);
3065 msg = xmlStrcat(msg, BAD_CAST ".\n");
3066 xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3067 (const char *) msg, str1, str2, str3, str4);
3068 xmlFree(msg);
3069}
3070
3081static void
3082xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3084 xmlSchemaTypePtr type,
3085 xmlSchemaTypePtr baseType,
3086 xmlSchemaFacetPtr facet)
3087{
3088 xmlChar *des = NULL, *strT = NULL;
3089
3090 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3091 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3092 "%s: The facet '%s' is not allowed on types derived from the "
3093 "type %s.\n",
3094 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3095 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3096 NULL, NULL);
3097 FREE_AND_NULL(des);
3098 FREE_AND_NULL(strT);
3099}
3100
3111static void
3112xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3114 xmlSchemaTypePtr type,
3115 xmlSchemaFacetPtr facet)
3116{
3117 xmlChar *des = NULL;
3118
3119 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3120 type->node);
3121 xmlSchemaPErr(ctxt, type->node, error,
3122 "%s: The facet '%s' is not allowed.\n",
3123 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3124 FREE_AND_NULL(des);
3125}
3126
3137static void
3138xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3140 xmlSchemaBasicItemPtr ownerItem,
3142 const char *name1,
3143 const char *name2)
3144{
3145 xmlChar *des = NULL;
3146
3147 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3148 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3149 "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3151 FREE_AND_NULL(des);
3152}
3153
3166static void LIBXML_ATTR_FORMAT(8,0)
3167xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3169 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3171 xmlSchemaTypePtr type,
3172 const char *expected,
3174 const char *message,
3175 const xmlChar *str1,
3176 const xmlChar *str2)
3177{
3178 xmlChar *msg = NULL;
3179
3180 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3181 if (message == NULL) {
3182 /*
3183 * Use default messages.
3184 */
3185 if (type != NULL) {
3186 if (node->type == XML_ATTRIBUTE_NODE)
3187 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3188 else
3189 msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3190 "valid value of ");
3191 if (! xmlSchemaIsGlobalItem(type))
3192 msg = xmlStrcat(msg, BAD_CAST "the local ");
3193 else
3194 msg = xmlStrcat(msg, BAD_CAST "the ");
3195
3196 if (WXS_IS_ATOMIC(type))
3197 msg = xmlStrcat(msg, BAD_CAST "atomic type");
3198 else if (WXS_IS_LIST(type))
3199 msg = xmlStrcat(msg, BAD_CAST "list type");
3200 else if (WXS_IS_UNION(type))
3201 msg = xmlStrcat(msg, BAD_CAST "union type");
3202
3203 if (xmlSchemaIsGlobalItem(type)) {
3204 xmlChar *str = NULL;
3205 msg = xmlStrcat(msg, BAD_CAST " '");
3206 if (type->builtInType != 0) {
3207 msg = xmlStrcat(msg, BAD_CAST "xs:");
3208 str = xmlStrdup(type->name);
3209 } else {
3210 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3211 if (!str)
3212 str = xmlStrdup(qName);
3213 }
3215 msg = xmlStrcat(msg, BAD_CAST "'.");
3216 FREE_AND_NULL(str);
3217 }
3218 } else {
3219 if (node->type == XML_ATTRIBUTE_NODE)
3220 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3221 else
3222 msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3223 "valid.");
3224 }
3225 if (expected) {
3226 xmlChar *expectedEscaped = xmlCharStrdup(expected);
3227 msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3228 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3229 FREE_AND_NULL(expectedEscaped);
3230 msg = xmlStrcat(msg, BAD_CAST "'.\n");
3231 } else
3232 msg = xmlStrcat(msg, BAD_CAST "\n");
3233 if (node->type == XML_ATTRIBUTE_NODE)
3234 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3235 else
3236 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3237 } else {
3239 msg = xmlStrcat(msg, BAD_CAST ".\n");
3240 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3241 (const char*) msg, str1, str2, NULL, NULL, NULL);
3242 }
3243 /* Cleanup. */
3244 FREE_AND_NULL(msg)
3245}
3246
3259static void
3260xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3262 xmlSchemaBasicItemPtr ownerItem,
3263 xmlNodePtr ownerElem,
3265 const char *message,
3266 const char *content)
3267{
3268 xmlChar *des = NULL;
3269
3270 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3271 if (message != NULL)
3272 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3273 "%s: %s.\n",
3275 else {
3276 if (content != NULL) {
3277 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3278 "%s: The content is not valid. Expected is %s.\n",
3280 } else {
3281 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3282 "%s: The content is not valid.\n",
3283 BAD_CAST des, NULL);
3284 }
3285 }
3286 FREE_AND_NULL(des)
3287}
3288
3289/************************************************************************
3290 * *
3291 * Streamable error functions *
3292 * *
3293 ************************************************************************/
3294
3295
3296
3297
3298/************************************************************************
3299 * *
3300 * Validation helper functions *
3301 * *
3302 ************************************************************************/
3303
3304
3305/************************************************************************
3306 * *
3307 * Allocation functions *
3308 * *
3309 ************************************************************************/
3310
3319static xmlSchemaPtr
3320xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3321{
3322 xmlSchemaPtr ret;
3323
3324 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3325 if (ret == NULL) {
3326 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
3327 return (NULL);
3328 }
3329 memset(ret, 0, sizeof(xmlSchema));
3330 ret->dict = ctxt->dict;
3331 xmlDictReference(ret->dict);
3332
3333 return (ret);
3334}
3335
3343xmlSchemaFacetPtr
3344xmlSchemaNewFacet(void)
3345{
3346 xmlSchemaFacetPtr ret;
3347
3348 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3349 if (ret == NULL) {
3350 return (NULL);
3351 }
3352 memset(ret, 0, sizeof(xmlSchemaFacet));
3353
3354 return (ret);
3355}
3356
3366static xmlSchemaAnnotPtr
3367xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3368{
3369 xmlSchemaAnnotPtr ret;
3370
3371 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3372 if (ret == NULL) {
3373 xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3374 return (NULL);
3375 }
3376 memset(ret, 0, sizeof(xmlSchemaAnnot));
3377 ret->content = node;
3378 return (ret);
3379}
3380
3381static xmlSchemaItemListPtr
3382xmlSchemaItemListCreate(void)
3383{
3384 xmlSchemaItemListPtr ret;
3385
3386 ret = xmlMalloc(sizeof(xmlSchemaItemList));
3387 if (ret == NULL) {
3388 xmlSchemaPErrMemory(NULL,
3389 "allocating an item list structure", NULL);
3390 return (NULL);
3391 }
3392 memset(ret, 0, sizeof(xmlSchemaItemList));
3393 return (ret);
3394}
3395
3396static void
3397xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3398{
3399 if (list->items != NULL) {
3400 xmlFree(list->items);
3401 list->items = NULL;
3402 }
3403 list->nbItems = 0;
3404 list->sizeItems = 0;
3405}
3406
3407static int
3408xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3409{
3410 if (list->items == NULL) {
3411 list->items = (void **) xmlMalloc(
3412 20 * sizeof(void *));
3413 if (list->items == NULL) {
3414 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3415 return(-1);
3416 }
3417 list->sizeItems = 20;
3418 } else if (list->sizeItems <= list->nbItems) {
3419 list->sizeItems *= 2;
3420 list->items = (void **) xmlRealloc(list->items,
3421 list->sizeItems * sizeof(void *));
3422 if (list->items == NULL) {
3423 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3424 list->sizeItems = 0;
3425 return(-1);
3426 }
3427 }
3428 list->items[list->nbItems++] = item;
3429 return(0);
3430}
3431
3432static int
3433xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3434 int initialSize,
3435 void *item)
3436{
3437 if (list->items == NULL) {
3438 if (initialSize <= 0)
3439 initialSize = 1;
3440 list->items = (void **) xmlMalloc(
3441 initialSize * sizeof(void *));
3442 if (list->items == NULL) {
3443 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3444 return(-1);
3445 }
3446 list->sizeItems = initialSize;
3447 } else if (list->sizeItems <= list->nbItems) {
3448 list->sizeItems *= 2;
3449 list->items = (void **) xmlRealloc(list->items,
3450 list->sizeItems * sizeof(void *));
3451 if (list->items == NULL) {
3452 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3453 list->sizeItems = 0;
3454 return(-1);
3455 }
3456 }
3457 list->items[list->nbItems++] = item;
3458 return(0);
3459}
3460
3461static int
3462xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3463{
3464 if (list->items == NULL) {
3465 list->items = (void **) xmlMalloc(
3466 20 * sizeof(void *));
3467 if (list->items == NULL) {
3468 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3469 return(-1);
3470 }
3471 list->sizeItems = 20;
3472 } else if (list->sizeItems <= list->nbItems) {
3473 list->sizeItems *= 2;
3474 list->items = (void **) xmlRealloc(list->items,
3475 list->sizeItems * sizeof(void *));
3476 if (list->items == NULL) {
3477 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3478 list->sizeItems = 0;
3479 return(-1);
3480 }
3481 }
3482 /*
3483 * Just append if the index is greater/equal than the item count.
3484 */
3485 if (idx >= list->nbItems) {
3486 list->items[list->nbItems++] = item;
3487 } else {
3488 int i;
3489 for (i = list->nbItems; i > idx; i--)
3490 list->items[i] = list->items[i-1];
3491 list->items[idx] = item;
3492 list->nbItems++;
3493 }
3494 return(0);
3495}
3496
3497#if 0 /* enable if ever needed */
3498static int
3499xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3500 int initialSize,
3501 void *item,
3502 int idx)
3503{
3504 if (list->items == NULL) {
3505 if (initialSize <= 0)
3506 initialSize = 1;
3507 list->items = (void **) xmlMalloc(
3508 initialSize * sizeof(void *));
3509 if (list->items == NULL) {
3510 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3511 return(-1);
3512 }
3513 list->sizeItems = initialSize;
3514 } else if (list->sizeItems <= list->nbItems) {
3515 list->sizeItems *= 2;
3516 list->items = (void **) xmlRealloc(list->items,
3517 list->sizeItems * sizeof(void *));
3518 if (list->items == NULL) {
3519 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3520 list->sizeItems = 0;
3521 return(-1);
3522 }
3523 }
3524 /*
3525 * Just append if the index is greater/equal than the item count.
3526 */
3527 if (idx >= list->nbItems) {
3528 list->items[list->nbItems++] = item;
3529 } else {
3530 int i;
3531 for (i = list->nbItems; i > idx; i--)
3532 list->items[i] = list->items[i-1];
3533 list->items[idx] = item;
3534 list->nbItems++;
3535 }
3536 return(0);
3537}
3538#endif
3539
3540static int
3541xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3542{
3543 int i;
3544 if ((list->items == NULL) || (idx >= list->nbItems)) {
3545 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3546 "index error.\n");
3547 return(-1);
3548 }
3549
3550 if (list->nbItems == 1) {
3551 /* TODO: Really free the list? */
3552 xmlFree(list->items);
3553 list->items = NULL;
3554 list->nbItems = 0;
3555 list->sizeItems = 0;
3556 } else if (list->nbItems -1 == idx) {
3557 list->nbItems--;
3558 } else {
3559 for (i = idx; i < list->nbItems -1; i++)
3560 list->items[i] = list->items[i+1];
3561 list->nbItems--;
3562 }
3563 return(0);
3564}
3565
3572static void
3573xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3574{
3575 if (list == NULL)
3576 return;
3577 if (list->items != NULL)
3578 xmlFree(list->items);
3579 xmlFree(list);
3580}
3581
3582static void
3583xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3584{
3585 if (bucket == NULL)
3586 return;
3587 if (bucket->globals != NULL) {
3588 xmlSchemaComponentListFree(bucket->globals);
3589 xmlSchemaItemListFree(bucket->globals);
3590 }
3591 if (bucket->locals != NULL) {
3592 xmlSchemaComponentListFree(bucket->locals);
3593 xmlSchemaItemListFree(bucket->locals);
3594 }
3595 if (bucket->relations != NULL) {
3596 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3597 do {
3598 prev = cur;
3599 cur = cur->next;
3600 xmlFree(prev);
3601 } while (cur != NULL);
3602 }
3603 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3604 xmlFreeDoc(bucket->doc);
3605 }
3606 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3607 if (WXS_IMPBUCKET(bucket)->schema != NULL)
3608 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3609 }
3610 xmlFree(bucket);
3611}
3612
3613static void
3614xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3615{
3616 xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3617}
3618
3619static xmlSchemaBucketPtr
3620xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3621 int type, const xmlChar *targetNamespace)
3622{
3623 xmlSchemaBucketPtr ret;
3624 int size;
3625 xmlSchemaPtr mainSchema;
3626
3627 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3628 PERROR_INT("xmlSchemaBucketCreate",
3629 "no main schema on constructor");
3630 return(NULL);
3631 }
3632 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3633 /* Create the schema bucket. */
3634 if (WXS_IS_BUCKET_INCREDEF(type))
3635 size = sizeof(xmlSchemaInclude);
3636 else
3637 size = sizeof(xmlSchemaImport);
3638 ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3639 if (ret == NULL) {
3640 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
3641 return(NULL);
3642 }
3643 memset(ret, 0, size);
3644 ret->targetNamespace = targetNamespace;
3645 ret->type = type;
3646 ret->globals = xmlSchemaItemListCreate();
3647 if (ret->globals == NULL) {
3648 xmlFree(ret);
3649 return(NULL);
3650 }
3651 ret->locals = xmlSchemaItemListCreate();
3652 if (ret->locals == NULL) {
3653 xmlFree(ret);
3654 return(NULL);
3655 }
3656 /*
3657 * The following will assure that only the first bucket is marked as
3658 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3659 * For each following import buckets an xmlSchema will be created.
3660 * An xmlSchema will be created for every distinct targetNamespace.
3661 * We assign the targetNamespace to the schemata here.
3662 */
3663 if (! WXS_HAS_BUCKETS(pctxt)) {
3664 if (WXS_IS_BUCKET_INCREDEF(type)) {
3665 PERROR_INT("xmlSchemaBucketCreate",
3666 "first bucket but it's an include or redefine");
3667 xmlSchemaBucketFree(ret);
3668 return(NULL);
3669 }
3670 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3671 ret->type = XML_SCHEMA_SCHEMA_MAIN;
3672 /* Point to the *main* schema. */
3673 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3674 WXS_IMPBUCKET(ret)->schema = mainSchema;
3675 /*
3676 * Ensure that the main schema gets a targetNamespace.
3677 */
3678 mainSchema->targetNamespace = targetNamespace;
3679 } else {
3680 if (type == XML_SCHEMA_SCHEMA_MAIN) {
3681 PERROR_INT("xmlSchemaBucketCreate",
3682 "main bucket but it's not the first one");
3683 xmlSchemaBucketFree(ret);
3684 return(NULL);
3685 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3686 /*
3687 * Create a schema for imports and assign the
3688 * targetNamespace.
3689 */
3690 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3691 if (WXS_IMPBUCKET(ret)->schema == NULL) {
3692 xmlSchemaBucketFree(ret);
3693 return(NULL);
3694 }
3695 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3696 }
3697 }
3698 if (WXS_IS_BUCKET_IMPMAIN(type)) {
3699 int res;
3700 /*
3701 * Imports go into the "schemasImports" slot of the main *schema*.
3702 * Note that we create an import entry for the main schema as well; i.e.,
3703 * even if there's only one schema, we'll get an import.
3704 */
3705 if (mainSchema->schemasImports == NULL) {
3706 mainSchema->schemasImports = xmlHashCreateDict(5,
3707 WXS_CONSTRUCTOR(pctxt)->dict);
3708 if (mainSchema->schemasImports == NULL) {
3709 xmlSchemaBucketFree(ret);
3710 return(NULL);
3711 }
3712 }
3713 if (targetNamespace == NULL)
3714 res = xmlHashAddEntry(mainSchema->schemasImports,
3715 XML_SCHEMAS_NO_NAMESPACE, ret);
3716 else
3717 res = xmlHashAddEntry(mainSchema->schemasImports,
3718 targetNamespace, ret);
3719 if (res != 0) {
3720 PERROR_INT("xmlSchemaBucketCreate",
3721 "failed to add the schema bucket to the hash");
3722 xmlSchemaBucketFree(ret);
3723 return(NULL);
3724 }
3725 } else {
3726 /* Set the @ownerImport of an include bucket. */
3727 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3728 WXS_INCBUCKET(ret)->ownerImport =
3729 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3730 else
3731 WXS_INCBUCKET(ret)->ownerImport =
3732 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3733
3734 /* Includes got into the "includes" slot of the *main* schema. */
3735 if (mainSchema->includes == NULL) {
3736 mainSchema->includes = xmlSchemaItemListCreate();
3737 if (mainSchema->includes == NULL) {
3738 xmlSchemaBucketFree(ret);
3739 return(NULL);
3740 }
3741 }
3742 xmlSchemaItemListAdd(mainSchema->includes, ret);
3743 }
3744 /*
3745 * Add to list of all buckets; this is used for lookup
3746 * during schema construction time only.
3747 */
3748 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3749 return(NULL);
3750 return(ret);
3751}
3752
3753static int
3754xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3755{
3756 if (*list == NULL) {
3757 *list = xmlSchemaItemListCreate();
3758 if (*list == NULL)
3759 return(-1);
3760 }
3761 xmlSchemaItemListAddSize(*list, initialSize, item);
3762 return(0);
3763}
3764
3771static void
3772xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3773{
3774 if (annot == NULL)
3775 return;
3776 if (annot->next == NULL) {
3777 xmlFree(annot);
3778 } else {
3779 xmlSchemaAnnotPtr prev;
3780
3781 do {
3782 prev = annot;
3783 annot = annot->next;
3784 xmlFree(prev);
3785 } while (annot != NULL);
3786 }
3787}
3788
3795static void
3796xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3797{
3798 if (nota == NULL)
3799 return;
3800 xmlFree(nota);
3801}
3802
3809static void
3810xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3811{
3812 if (attr == NULL)
3813 return;
3814 if (attr->annot != NULL)
3815 xmlSchemaFreeAnnot(attr->annot);
3816 if (attr->defVal != NULL)
3817 xmlSchemaFreeValue(attr->defVal);
3818 xmlFree(attr);
3819}
3820
3827static void
3828xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3829{
3830 if (use == NULL)
3831 return;
3832 if (use->annot != NULL)
3833 xmlSchemaFreeAnnot(use->annot);
3834 if (use->defVal != NULL)
3835 xmlSchemaFreeValue(use->defVal);
3836 xmlFree(use);
3837}
3838
3845static void
3846xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3847{
3848 if (prohib == NULL)
3849 return;
3850 xmlFree(prohib);
3851}
3852
3859static void
3860xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3861{
3862 xmlSchemaWildcardNsPtr next;
3863
3864 while (set != NULL) {
3865 next = set->next;
3866 xmlFree(set);
3867 set = next;
3868 }
3869}
3870
3877void
3878xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3879{
3880 if (wildcard == NULL)
3881 return;
3882 if (wildcard->annot != NULL)
3883 xmlSchemaFreeAnnot(wildcard->annot);
3884 if (wildcard->nsSet != NULL)
3885 xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3886 if (wildcard->negNsSet != NULL)
3887 xmlFree(wildcard->negNsSet);
3888 xmlFree(wildcard);
3889}
3890
3897static void
3898xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3899{
3900 if (attrGr == NULL)
3901 return;
3902 if (attrGr->annot != NULL)
3903 xmlSchemaFreeAnnot(attrGr->annot);
3904 if (attrGr->attrUses != NULL)
3905 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3906 xmlFree(attrGr);
3907}
3908
3915static void
3916xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3917{
3918 xmlFree(item);
3919}
3920
3927static void
3928xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3929{
3930 xmlSchemaTypeLinkPtr next;
3931
3932 while (link != NULL) {
3933 next = link->next;
3934 xmlFree(link);
3935 link = next;
3936 }
3937}
3938
3939static void
3940xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3941{
3942 xmlSchemaIDCStateObjPtr next;
3943 while (sto != NULL) {
3944 next = sto->next;
3945 if (sto->history != NULL)
3946 xmlFree(sto->history);
3947 if (sto->xpathCtxt != NULL)
3948 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3949 xmlFree(sto);
3950 sto = next;
3951 }
3952}
3953
3960static void
3961xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3962{
3963 xmlSchemaIDCSelectPtr cur, prev;
3964
3965 if (idcDef == NULL)
3966 return;
3967 if (idcDef->annot != NULL)
3968 xmlSchemaFreeAnnot(idcDef->annot);
3969 /* Selector */
3970 if (idcDef->selector != NULL) {
3971 if (idcDef->selector->xpathComp != NULL)
3972 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3973 xmlFree(idcDef->selector);
3974 }
3975 /* Fields */
3976 if (idcDef->fields != NULL) {
3977 cur = idcDef->fields;
3978 do {
3979 prev = cur;
3980 cur = cur->next;
3981 if (prev->xpathComp != NULL)
3982 xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3983 xmlFree(prev);
3984 } while (cur != NULL);
3985 }
3986 xmlFree(idcDef);
3987}
3988
3995static void
3996xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3997{
3998 if (elem == NULL)
3999 return;
4000 if (elem->annot != NULL)
4001 xmlSchemaFreeAnnot(elem->annot);
4002 if (elem->contModel != NULL)
4003 xmlRegFreeRegexp(elem->contModel);
4004 if (elem->defVal != NULL)
4005 xmlSchemaFreeValue(elem->defVal);
4006 xmlFree(elem);
4007}
4008
4015void
4016xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4017{
4018 if (facet == NULL)
4019 return;
4020 if (facet->val != NULL)
4021 xmlSchemaFreeValue(facet->val);
4022 if (facet->regexp != NULL)
4023 xmlRegFreeRegexp(facet->regexp);
4024 if (facet->annot != NULL)
4025 xmlSchemaFreeAnnot(facet->annot);
4026 xmlFree(facet);
4027}
4028
4035void
4036xmlSchemaFreeType(xmlSchemaTypePtr type)
4037{
4038 if (type == NULL)
4039 return;
4040 if (type->annot != NULL)
4041 xmlSchemaFreeAnnot(type->annot);
4042 if (type->facets != NULL) {
4043 xmlSchemaFacetPtr facet, next;
4044
4045 facet = type->facets;
4046 while (facet != NULL) {
4047 next = facet->next;
4048 xmlSchemaFreeFacet(facet);
4049 facet = next;
4050 }
4051 }
4052 if (type->attrUses != NULL)
4053 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4054 if (type->memberTypes != NULL)
4055 xmlSchemaFreeTypeLinkList(type->memberTypes);
4056 if (type->facetSet != NULL) {
4057 xmlSchemaFacetLinkPtr next, link;
4058
4059 link = type->facetSet;
4060 do {
4061 next = link->next;
4062 xmlFree(link);
4063 link = next;
4064 } while (link != NULL);
4065 }
4066 if (type->contModel != NULL)
4067 xmlRegFreeRegexp(type->contModel);
4068 xmlFree(type);
4069}
4070
4077static void
4078xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4079{
4080 if (item->annot != NULL)
4081 xmlSchemaFreeAnnot(item->annot);
4082 xmlFree(item);
4083}
4084
4091static void
4092xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4093{
4094 if (item->annot != NULL)
4095 xmlSchemaFreeAnnot(item->annot);
4096 xmlFree(item);
4097}
4098
4099static void
4100xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4101{
4102 if ((list == NULL) || (list->nbItems == 0))
4103 return;
4104 {
4105 xmlSchemaTreeItemPtr item;
4106 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4107 int i;
4108
4109 for (i = 0; i < list->nbItems; i++) {
4110 item = items[i];
4111 if (item == NULL)
4112 continue;
4113 switch (item->type) {
4114 case XML_SCHEMA_TYPE_SIMPLE:
4115 case XML_SCHEMA_TYPE_COMPLEX:
4116 xmlSchemaFreeType((xmlSchemaTypePtr) item);
4117 break;
4118 case XML_SCHEMA_TYPE_ATTRIBUTE:
4119 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4120 break;
4121 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4122 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4123 break;
4124 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4125 xmlSchemaFreeAttributeUseProhib(
4126 (xmlSchemaAttributeUseProhibPtr) item);
4127 break;
4128 case XML_SCHEMA_TYPE_ELEMENT:
4129 xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4130 break;
4131 case XML_SCHEMA_TYPE_PARTICLE:
4132 if (item->annot != NULL)
4133 xmlSchemaFreeAnnot(item->annot);
4134 xmlFree(item);
4135 break;
4136 case XML_SCHEMA_TYPE_SEQUENCE:
4137 case XML_SCHEMA_TYPE_CHOICE:
4138 case XML_SCHEMA_TYPE_ALL:
4139 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4140 break;
4141 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4142 xmlSchemaFreeAttributeGroup(
4143 (xmlSchemaAttributeGroupPtr) item);
4144 break;
4145 case XML_SCHEMA_TYPE_GROUP:
4146 xmlSchemaFreeModelGroupDef(
4147 (xmlSchemaModelGroupDefPtr) item);
4148 break;
4149 case XML_SCHEMA_TYPE_ANY:
4150 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4151 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4152 break;
4153 case XML_SCHEMA_TYPE_IDC_KEY:
4154 case XML_SCHEMA_TYPE_IDC_UNIQUE:
4155 case XML_SCHEMA_TYPE_IDC_KEYREF:
4156 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4157 break;
4158 case XML_SCHEMA_TYPE_NOTATION:
4159 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4160 break;
4161 case XML_SCHEMA_EXTRA_QNAMEREF:
4162 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4163 break;
4164 default: {
4165 /* TODO: This should never be hit. */
4166 xmlSchemaPSimpleInternalErr(NULL,
4167 "Internal error: xmlSchemaComponentListFree, "
4168 "unexpected component type '%s'\n",
4169 (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
4170 }
4171 break;
4172 }
4173 }
4174 list->nbItems = 0;
4175 }
4176}
4177
4184void
4185xmlSchemaFree(xmlSchemaPtr schema)
4186{
4187 if (schema == NULL)
4188 return;
4189 /* @volatiles is not used anymore :-/ */
4190 if (schema->volatiles != NULL)
4191 TODO
4192 /*
4193 * Note that those slots are not responsible for freeing
4194 * schema components anymore; this will now be done by
4195 * the schema buckets.
4196 */
4197 if (schema->notaDecl != NULL)
4198 xmlHashFree(schema->notaDecl, NULL);
4199 if (schema->attrDecl != NULL)
4200 xmlHashFree(schema->attrDecl, NULL);
4201 if (schema->attrgrpDecl != NULL)
4202 xmlHashFree(schema->attrgrpDecl, NULL);
4203 if (schema->elemDecl != NULL)
4204 xmlHashFree(schema->elemDecl, NULL);
4205 if (schema->typeDecl != NULL)
4206 xmlHashFree(schema->typeDecl, NULL);
4207 if (schema->groupDecl != NULL)
4208 xmlHashFree(schema->groupDecl, NULL);
4209 if (schema->idcDef != NULL)
4210 xmlHashFree(schema->idcDef, NULL);
4211
4212 if (schema->schemasImports != NULL)
4213 xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4214 if (schema->includes != NULL) {
4215 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4216 int i;
4217 for (i = 0; i < list->nbItems; i++) {
4218 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4219 }
4220 xmlSchemaItemListFree(list);
4221 }
4222 if (schema->annot != NULL)
4223 xmlSchemaFreeAnnot(schema->annot);
4224 /* Never free the doc here, since this will be done by the buckets. */
4225
4226 xmlDictFree(schema->dict);
4227 xmlFree(schema);
4228}
4229
4230/************************************************************************
4231 * *
4232 * Debug functions *
4233 * *
4234 ************************************************************************/
4235
4236#ifdef LIBXML_OUTPUT_ENABLED
4237
4238static void
4239xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4240
4248static void
4249xmlSchemaElementDump(void *payload, void *data,
4251 const xmlChar * namespace ATTRIBUTE_UNUSED,
4253{
4254 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4255 FILE *output = (FILE *) data;
4256 if (elem == NULL)
4257 return;
4258
4259
4260 fprintf(output, "Element");
4261 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4262 fprintf(output, " (global)");
4263 fprintf(output, ": '%s' ", elem->name);
4264 if (namespace != NULL)
4265 fprintf(output, "ns '%s'", namespace);
4266 fprintf(output, "\n");
4267#if 0
4268 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4269 fprintf(output, " min %d ", elem->minOccurs);
4270 if (elem->maxOccurs >= UNBOUNDED)
4271 fprintf(output, "max: unbounded\n");
4272 else if (elem->maxOccurs != 1)
4273 fprintf(output, "max: %d\n", elem->maxOccurs);
4274 else
4275 fprintf(output, "\n");
4276 }
4277#endif
4278 /*
4279 * Misc other properties.
4280 */
4281 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4282 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4283 (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4284 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4285 fprintf(output, " props: ");
4286 if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4287 fprintf(output, "[fixed] ");
4288 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4289 fprintf(output, "[default] ");
4290 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4291 fprintf(output, "[abstract] ");
4292 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4293 fprintf(output, "[nillable] ");
4294 fprintf(output, "\n");
4295 }
4296 /*
4297 * Default/fixed value.
4298 */
4299 if (elem->value != NULL)
4300 fprintf(output, " value: '%s'\n", elem->value);
4301 /*
4302 * Type.
4303 */
4304 if (elem->namedType != NULL) {
4305 fprintf(output, " type: '%s' ", elem->namedType);
4306 if (elem->namedTypeNs != NULL)
4307 fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4308 else
4309 fprintf(output, "\n");
4310 } else if (elem->subtypes != NULL) {
4311 /*
4312 * Dump local types.
4313 */
4314 xmlSchemaTypeDump(elem->subtypes, output);
4315 }
4316 /*
4317 * Substitution group.
4318 */
4319 if (elem->substGroup != NULL) {
4320 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
4321 if (elem->substGroupNs != NULL)
4322 fprintf(output, "ns '%s'\n", elem->substGroupNs);
4323 else
4324 fprintf(output, "\n");
4325 }
4326}
4327
4335static void
4336xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4337{
4339
4340 if (annot == NULL)
4341 return;
4342
4343 content = xmlNodeGetContent(annot->content);
4344 if (content != NULL) {
4345 fprintf(output, " Annot: %s\n", content);
4347 } else
4348 fprintf(output, " Annot: empty\n");
4349}
4350
4359static void
4360xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4361{
4362 xmlChar *str = NULL;
4363 xmlSchemaTreeItemPtr term;
4364 char shift[100];
4365 int i;
4366
4367 if (particle == NULL)
4368 return;
4369 for (i = 0;((i < depth) && (i < 25));i++)
4370 shift[2 * i] = shift[2 * i + 1] = ' ';
4371 shift[2 * i] = shift[2 * i + 1] = 0;
4372 fprintf(output, "%s", shift);
4373 if (particle->children == NULL) {
4374 fprintf(output, "MISSING particle term\n");
4375 return;
4376 }
4377 term = particle->children;
4378 if (term == NULL) {
4379 fprintf(output, "(NULL)");
4380 } else {
4381 switch (term->type) {
4382 case XML_SCHEMA_TYPE_ELEMENT:
4383 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4384 ((xmlSchemaElementPtr)term)->targetNamespace,
4385 ((xmlSchemaElementPtr)term)->name));
4386 FREE_AND_NULL(str);
4387 break;
4388 case XML_SCHEMA_TYPE_SEQUENCE:
4389 fprintf(output, "SEQUENCE");
4390 break;
4391 case XML_SCHEMA_TYPE_CHOICE:
4392 fprintf(output, "CHOICE");
4393 break;
4394 case XML_SCHEMA_TYPE_ALL:
4395 fprintf(output, "ALL");
4396 break;
4397 case XML_SCHEMA_TYPE_ANY:
4398 fprintf(output, "ANY");
4399 break;
4400 default:
4401 fprintf(output, "UNKNOWN\n");
4402 return;
4403 }
4404 }
4405 if (particle->minOccurs != 1)
4406 fprintf(output, " min: %d", particle->minOccurs);
4407 if (particle->maxOccurs >= UNBOUNDED)
4408 fprintf(output, " max: unbounded");
4409 else if (particle->maxOccurs != 1)
4410 fprintf(output, " max: %d", particle->maxOccurs);
4411 fprintf(output, "\n");
4412 if (term &&
4413 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4414 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4415 (term->type == XML_SCHEMA_TYPE_ALL)) &&
4416 (term->children != NULL)) {
4417 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4418 output, depth +1);
4419 }
4420 if (particle->next != NULL)
4421 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4422 output, depth);
4423}
4424
4432static void
4433xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4434{
4435 xmlSchemaAttributeUsePtr use;
4436 xmlSchemaAttributeUseProhibPtr prohib;
4437 xmlSchemaQNameRefPtr ref;
4438 const xmlChar *name, *tns;
4439 xmlChar *str = NULL;
4440 int i;
4441
4442 if ((uses == NULL) || (uses->nbItems == 0))
4443 return;
4444
4445 fprintf(output, " attributes:\n");
4446 for (i = 0; i < uses->nbItems; i++) {
4447 use = uses->items[i];
4448 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4449 fprintf(output, " [prohibition] ");
4450 prohib = (xmlSchemaAttributeUseProhibPtr) use;
4451 name = prohib->name;
4452 tns = prohib->targetNamespace;
4453 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4454 fprintf(output, " [reference] ");
4455 ref = (xmlSchemaQNameRefPtr) use;
4456 name = ref->name;
4457 tns = ref->targetNamespace;
4458 } else {
4459 fprintf(output, " [use] ");
4460 name = WXS_ATTRUSE_DECL_NAME(use);
4461 tns = WXS_ATTRUSE_DECL_TNS(use);
4462 }
4463 fprintf(output, "'%s'\n",
4464 (const char *) xmlSchemaFormatQName(&str, tns, name));
4465 FREE_AND_NULL(str);
4466 }
4467}
4468
4476static void
4477xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4478{
4479 if (type == NULL) {
4480 fprintf(output, "Type: NULL\n");
4481 return;
4482 }
4483 fprintf(output, "Type: ");
4484 if (type->name != NULL)
4485 fprintf(output, "'%s' ", type->name);
4486 else
4487 fprintf(output, "(no name) ");
4488 if (type->targetNamespace != NULL)
4489 fprintf(output, "ns '%s' ", type->targetNamespace);
4490 switch (type->type) {
4491 case XML_SCHEMA_TYPE_BASIC:
4492 fprintf(output, "[basic] ");
4493 break;
4494 case XML_SCHEMA_TYPE_SIMPLE:
4495 fprintf(output, "[simple] ");
4496 break;
4497 case XML_SCHEMA_TYPE_COMPLEX:
4498 fprintf(output, "[complex] ");
4499 break;
4500 case XML_SCHEMA_TYPE_SEQUENCE:
4501 fprintf(output, "[sequence] ");
4502 break;
4503 case XML_SCHEMA_TYPE_CHOICE:
4504 fprintf(output, "[choice] ");
4505 break;
4506 case XML_SCHEMA_TYPE_ALL:
4507 fprintf(output, "[all] ");
4508 break;
4509 case XML_SCHEMA_TYPE_UR:
4510 fprintf(output, "[ur] ");
4511 break;
4512 case XML_SCHEMA_TYPE_RESTRICTION:
4513 fprintf(output, "[restriction] ");
4514 break;
4515 case XML_SCHEMA_TYPE_EXTENSION:
4516 fprintf(output, "[extension] ");
4517 break;
4518 default:
4519 fprintf(output, "[unknown type %d] ", type->type);
4520 break;
4521 }
4522 fprintf(output, "content: ");
4523 switch (type->contentType) {
4524 case XML_SCHEMA_CONTENT_UNKNOWN:
4525 fprintf(output, "[unknown] ");
4526 break;
4527 case XML_SCHEMA_CONTENT_EMPTY:
4528 fprintf(output, "[empty] ");
4529 break;
4530 case XML_SCHEMA_CONTENT_ELEMENTS:
4531 fprintf(output, "[element] ");
4532 break;
4533 case XML_SCHEMA_CONTENT_MIXED:
4534 fprintf(output, "[mixed] ");
4535 break;
4536 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4537 /* not used. */
4538 break;
4539 case XML_SCHEMA_CONTENT_BASIC:
4540 fprintf(output, "[basic] ");
4541 break;
4542 case XML_SCHEMA_CONTENT_SIMPLE:
4543 fprintf(output, "[simple] ");
4544 break;
4545 case XML_SCHEMA_CONTENT_ANY:
4546 fprintf(output, "[any] ");
4547 break;
4548 }
4549 fprintf(output, "\n");
4550 if (type->base != NULL) {
4551 fprintf(output, " base type: '%s'", type->base);
4552 if (type->baseNs != NULL)
4553 fprintf(output, " ns '%s'\n", type->baseNs);
4554 else
4555 fprintf(output, "\n");
4556 }
4557 if (type->attrUses != NULL)
4558 xmlSchemaAttrUsesDump(type->attrUses, output);
4559 if (type->annot != NULL)
4560 xmlSchemaAnnotDump(output, type->annot);
4561#ifdef DUMP_CONTENT_MODEL
4562 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4563 (type->subtypes != NULL)) {
4564 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4565 output, 1);
4566 }
4567#endif
4568}
4569
4570static void
4571xmlSchemaTypeDumpEntry(void *type, void *output,
4573{
4574 xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4575}
4576
4584void
4585xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4586{
4587 if (output == NULL)
4588 return;
4589 if (schema == NULL) {
4590 fprintf(output, "Schemas: NULL\n");
4591 return;
4592 }
4593 fprintf(output, "Schemas: ");
4594 if (schema->name != NULL)
4595 fprintf(output, "%s, ", schema->name);
4596 else
4597 fprintf(output, "no name, ");
4598 if (schema->targetNamespace != NULL)
4599 fprintf(output, "%s", (const char *) schema->targetNamespace);
4600 else
4601 fprintf(output, "no target namespace");
4602 fprintf(output, "\n");
4603 if (schema->annot != NULL)
4604 xmlSchemaAnnotDump(output, schema->annot);
4605 xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4606 xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4607}
4608
4609#ifdef DEBUG_IDC_NODE_TABLE
4616static void
4617xmlSchemaDebugDumpIDCTable(FILE * output,
4618 const xmlChar *namespaceName,
4619 const xmlChar *localName,
4620 xmlSchemaPSVIIDCBindingPtr bind)
4621{
4622 xmlChar *str = NULL;
4623 const xmlChar *value;
4624 xmlSchemaPSVIIDCNodePtr tab;
4625 xmlSchemaPSVIIDCKeyPtr key;
4626 int i, j, res;
4627
4628 fprintf(output, "IDC: TABLES on '%s'\n",
4629 xmlSchemaFormatQName(&str, namespaceName, localName));
4630 FREE_AND_NULL(str)
4631
4632 if (bind == NULL)
4633 return;
4634 do {
4635 fprintf(output, "IDC: BINDING '%s' (%d)\n",
4636 xmlSchemaGetComponentQName(&str,
4637 bind->definition), bind->nbNodes);
4638 FREE_AND_NULL(str)
4639 for (i = 0; i < bind->nbNodes; i++) {
4640 tab = bind->nodeTable[i];
4641 fprintf(output, " ( ");
4642 for (j = 0; j < bind->definition->nbFields; j++) {
4643 key = tab->keys[j];
4644 if ((key != NULL) && (key->val != NULL)) {
4645 res = xmlSchemaGetCanonValue(key->val, &value);
4646 if (res >= 0)
4647 fprintf(output, "'%s' ", value);
4648 else
4649 fprintf(output, "CANON-VALUE-FAILED ");
4650 if (res == 0)
4651 FREE_AND_NULL(value)
4652 } else if (key != NULL)
4653 fprintf(output, "(no val), ");
4654 else
4655 fprintf(output, "(key missing), ");
4656 }
4657 fprintf(output, ")\n");
4658 }
4659 if (bind->dupls && bind->dupls->nbItems) {
4660 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
4661 for (i = 0; i < bind->dupls->nbItems; i++) {
4662 tab = bind->dupls->items[i];
4663 fprintf(output, " ( ");
4664 for (j = 0; j < bind->definition->nbFields; j++) {
4665 key = tab->keys[j];
4666 if ((key != NULL) && (key->val != NULL)) {
4667 res = xmlSchemaGetCanonValue(key->val, &value);
4668 if (res >= 0)
4669 fprintf(output, "'%s' ", value);
4670 else
4671 fprintf(output, "CANON-VALUE-FAILED ");
4672 if (res == 0)
4673 FREE_AND_NULL(value)
4674 } else if (key != NULL)
4675 fprintf(output, "(no val), ");
4676 else
4677 fprintf(output, "(key missing), ");
4678 }
4679 fprintf(output, ")\n");
4680 }
4681 }
4682 bind = bind->next;
4683 } while (bind != NULL);
4684}
4685#endif /* DEBUG_IDC */
4686#endif /* LIBXML_OUTPUT_ENABLED */
4687
4688/************************************************************************
4689 * *
4690 * Utilities *
4691 * *
4692 ************************************************************************/
4693
4704static xmlAttrPtr
4705xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4706{
4707 xmlAttrPtr prop;
4708
4709 if ((node == NULL) || (name == NULL))
4710 return(NULL);
4711 prop = node->properties;
4712 while (prop != NULL) {
4713 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4714 return(prop);
4715 prop = prop->next;
4716 }
4717 return (NULL);
4718}
4719
4731static xmlAttrPtr
4732xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4733{
4734 xmlAttrPtr prop;
4735
4736 if ((node == NULL) || (name == NULL))
4737 return(NULL);
4738 prop = node->properties;
4739 while (prop != NULL) {
4740 if ((prop->ns != NULL) &&
4741 xmlStrEqual(prop->name, BAD_CAST name) &&
4742 xmlStrEqual(prop->ns->href, BAD_CAST uri))
4743 return(prop);
4744 prop = prop->next;
4745 }
4746 return (NULL);
4747}
4748
4749static const xmlChar *
4750xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4751{
4752 xmlChar *val;
4753 const xmlChar *ret;
4754
4756 if (val == NULL)
4757 val = xmlStrdup((xmlChar *)"");
4758 ret = xmlDictLookup(ctxt->dict, val, -1);
4759 xmlFree(val);
4760 return(ret);
4761}
4762
4763static const xmlChar *
4764xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4765{
4766 return((const xmlChar*) xmlNodeGetContent(node));
4767}
4768
4779static const xmlChar *
4780xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4781 const char *name)
4782{
4783 xmlChar *val;
4784 const xmlChar *ret;
4785
4787 if (val == NULL)
4788 return(NULL);
4789 ret = xmlDictLookup(ctxt->dict, val, -1);
4790 xmlFree(val);
4791 return(ret);
4792}
4793
4794/************************************************************************
4795 * *
4796 * Parsing functions *
4797 * *
4798 ************************************************************************/
4799
4800#define WXS_FIND_GLOBAL_ITEM(slot) \
4801 if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4802 ret = xmlHashLookup(schema->slot, name); \
4803 if (ret != NULL) goto exit; \
4804 } \
4805 if (xmlHashSize(schema->schemasImports) > 1) { \
4806 xmlSchemaImportPtr import; \
4807 if (nsName == NULL) \
4808 import = xmlHashLookup(schema->schemasImports, \
4809 XML_SCHEMAS_NO_NAMESPACE); \
4810 else \
4811 import = xmlHashLookup(schema->schemasImports, nsName); \
4812 if (import == NULL) \
4813 goto exit; \
4814 ret = xmlHashLookup(import->schema->slot, name); \
4815 }
4816
4827static xmlSchemaElementPtr
4828xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4829 const xmlChar * nsName)
4830{
4831 xmlSchemaElementPtr ret = NULL;
4832
4833 if ((name == NULL) || (schema == NULL))
4834 return(NULL);
4835 if (schema != NULL) {
4836 WXS_FIND_GLOBAL_ITEM(elemDecl)
4837 }
4838exit:
4839#ifdef DEBUG
4840 if (ret == NULL) {
4841 if (nsName == NULL)
4842 fprintf(stderr, "Unable to lookup element decl. %s", name);
4843 else
4844 fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
4845 nsName);
4846 }
4847#endif
4848 return (ret);
4849}
4850
4861static xmlSchemaTypePtr
4862xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4863 const xmlChar * nsName)
4864{
4865 xmlSchemaTypePtr ret = NULL;
4866
4867 if (name == NULL)
4868 return (NULL);
4869 /* First try the built-in types. */
4870 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4871 ret = xmlSchemaGetPredefinedType(name, nsName);
4872 if (ret != NULL)
4873 goto exit;
4874 /*
4875 * Note that we try the parsed schemas as well here
4876 * since one might have parsed the S4S, which contain more
4877 * than the built-in types.
4878 * TODO: Can we optimize this?
4879 */
4880 }
4881 if (schema != NULL) {
4882 WXS_FIND_GLOBAL_ITEM(typeDecl)
4883 }
4884exit:
4885
4886#ifdef DEBUG
4887 if (ret == NULL) {
4888 if (nsName == NULL)
4889 fprintf(stderr, "Unable to lookup type %s", name);
4890 else
4891 fprintf(stderr, "Unable to lookup type %s:%s", name,
4892 nsName);
4893 }
4894#endif
4895 return (ret);
4896}
4897
4908static xmlSchemaAttributePtr
4909xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4910 const xmlChar * nsName)
4911{
4912 xmlSchemaAttributePtr ret = NULL;
4913
4914 if ((name == NULL) || (schema == NULL))
4915 return (NULL);
4916 if (schema != NULL) {
4917 WXS_FIND_GLOBAL_ITEM(attrDecl)
4918 }
4919exit:
4920#ifdef DEBUG
4921 if (ret == NULL) {
4922 if (nsName == NULL)
4923 fprintf(stderr, "Unable to lookup attribute %s", name);
4924 else
4925 fprintf(stderr, "Unable to lookup attribute %s:%s", name,
4926 nsName);
4927 }
4928#endif
4929 return (ret);
4930}
4931
4942static xmlSchemaAttributeGroupPtr
4943xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4944 const xmlChar * nsName)
4945{
4946 xmlSchemaAttributeGroupPtr ret = NULL;
4947
4948 if ((name == NULL) || (schema == NULL))
4949 return (NULL);
4950 if (schema != NULL) {
4951 WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4952 }
4953exit:
4954 /* TODO:
4955 if ((ret != NULL) && (ret->redef != NULL)) {
4956 * Return the last redefinition. *
4957 ret = ret->redef;
4958 }
4959 */
4960#ifdef DEBUG
4961 if (ret == NULL) {
4962 if (nsName == NULL)
4963 fprintf(stderr, "Unable to lookup attribute group %s", name);
4964 else
4965 fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
4966 nsName);
4967 }
4968#endif
4969 return (ret);
4970}
4971
4982static xmlSchemaModelGroupDefPtr
4983xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4984 const xmlChar * nsName)
4985{
4986 xmlSchemaModelGroupDefPtr ret = NULL;
4987
4988 if ((name == NULL) || (schema == NULL))
4989 return (NULL);
4990 if (schema != NULL) {
4991 WXS_FIND_GLOBAL_ITEM(groupDecl)
4992 }
4993exit:
4994
4995#ifdef DEBUG
4996 if (ret == NULL) {
4997 if (nsName == NULL)
4998 fprintf(stderr, "Unable to lookup group %s", name);
4999 else
5000 fprintf(stderr, "Unable to lookup group %s:%s", name,
5001 nsName);
5002 }
5003#endif
5004 return (ret);
5005}
5006
5007static xmlSchemaNotationPtr
5008xmlSchemaGetNotation(xmlSchemaPtr schema,
5009 const xmlChar *name,
5010 const xmlChar *nsName)
5011{
5012 xmlSchemaNotationPtr ret = NULL;
5013
5014 if ((name == NULL) || (schema == NULL))
5015 return (NULL);
5016 if (schema != NULL) {
5017 WXS_FIND_GLOBAL_ITEM(notaDecl)
5018 }
5019exit:
5020 return (ret);
5021}
5022
5023static xmlSchemaIDCPtr
5024xmlSchemaGetIDC(xmlSchemaPtr schema,
5025 const xmlChar *name,
5026 const xmlChar *nsName)
5027{
5028 xmlSchemaIDCPtr ret = NULL;
5029
5030 if ((name == NULL) || (schema == NULL))
5031 return (NULL);
5032 if (schema != NULL) {
5033 WXS_FIND_GLOBAL_ITEM(idcDef)
5034 }
5035exit:
5036 return (ret);
5037}
5038
5049static xmlSchemaBasicItemPtr
5050xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
5051 xmlSchemaTypeType itemType,
5052 const xmlChar *name,
5053 const xmlChar *targetNs)
5054{
5055 switch (itemType) {
5056 case XML_SCHEMA_TYPE_GROUP:
5057 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
5058 name, targetNs));
5059 case XML_SCHEMA_TYPE_ELEMENT:
5060 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
5061 name, targetNs));
5062 default:
5063 TODO
5064 return (NULL);
5065 }
5066}
5067
5068/************************************************************************
5069 * *
5070 * Parsing functions *
5071 * *
5072 ************************************************************************/
5073
5074#define IS_BLANK_NODE(n) \
5075 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
5076
5086static int
5087xmlSchemaIsBlank(xmlChar * str, int len)
5088{
5089 if (str == NULL)
5090 return (1);
5091 if (len < 0) {
5092 while (*str != 0) {
5093 if (!(IS_BLANK_CH(*str)))
5094 return (0);
5095 str++;
5096 }
5097 } else while ((*str != 0) && (len != 0)) {
5098 if (!(IS_BLANK_CH(*str)))
5099 return (0);
5100 str++;
5101 len--;
5102 }
5103
5104 return (1);
5105}
5106
5107#define WXS_COMP_NAME(c, t) ((t) (c))->name
5108#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5109/*
5110* xmlSchemaFindRedefCompInGraph:
5111* ATTENTION TODO: This uses pointer comp. for strings.
5112*/
5113static xmlSchemaBasicItemPtr
5114xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5115 xmlSchemaTypeType type,
5116 const xmlChar *name,
5117 const xmlChar *nsName)
5118{
5119 xmlSchemaBasicItemPtr ret;
5120 int i;
5121
5122 if ((bucket == NULL) || (name == NULL))
5123 return(NULL);
5124 if ((bucket->globals == NULL) ||
5125 (bucket->globals->nbItems == 0))
5126 goto subschemas;
5127 /*
5128 * Search in global components.
5129 */
5130 for (i = 0; i < bucket->globals->nbItems; i++) {
5131 ret = bucket->globals->items[i];
5132 if (ret->type == type) {
5133 switch (type) {
5134 case XML_SCHEMA_TYPE_COMPLEX:
5135 case XML_SCHEMA_TYPE_SIMPLE:
5136 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5137 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5138 nsName))
5139 {
5140 return(ret);
5141 }
5142 break;
5143 case XML_SCHEMA_TYPE_GROUP:
5144 if ((WXS_COMP_NAME(ret,
5145 xmlSchemaModelGroupDefPtr) == name) &&
5146 (WXS_COMP_TNS(ret,
5147 xmlSchemaModelGroupDefPtr) == nsName))
5148 {
5149 return(ret);
5150 }
5151 break;
5152 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5153 if ((WXS_COMP_NAME(ret,
5154 xmlSchemaAttributeGroupPtr) == name) &&
5155 (WXS_COMP_TNS(ret,
5156 xmlSchemaAttributeGroupPtr) == nsName))
5157 {
5158 return(ret);
5159 }
5160 break;
5161 default:
5162 /* Should not be hit. */
5163 return(NULL);
5164 }
5165 }
5166 }
5167subschemas:
5168 /*
5169 * Process imported/included schemas.
5170 */
5171 if (bucket->relations != NULL) {
5172 xmlSchemaSchemaRelationPtr rel = bucket->relations;
5173
5174 /*
5175 * TODO: Marking the bucket will not avoid multiple searches
5176 * in the same schema, but avoids at least circularity.
5177 */
5178 bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5179 do {
5180 if ((rel->bucket != NULL) &&
5181 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5182 ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5183 type, name, nsName);
5184 if (ret != NULL)
5185 return(ret);
5186 }
5187 rel = rel->next;
5188 } while (rel != NULL);
5189 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5190 }
5191 return(NULL);
5192}
5193
5205static xmlSchemaNotationPtr
5206xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5207 const xmlChar *name, const xmlChar *nsName,
5209{
5210 xmlSchemaNotationPtr ret = NULL;
5211
5212 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5213 return (NULL);
5214
5215 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5216 if (ret == NULL) {
5217 xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
5218 return (NULL);
5219 }
5220 memset(ret, 0, sizeof(xmlSchemaNotation));
5221 ret->type = XML_SCHEMA_TYPE_NOTATION;
5222 ret->name = name;
5223 ret->targetNamespace = nsName;
5224 /* TODO: do we need the node to be set?
5225 * ret->node = node;*/
5226 WXS_ADD_GLOBAL(ctxt, ret);
5227 return (ret);
5228}
5229
5242static xmlSchemaAttributePtr
5243xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5244 const xmlChar * name, const xmlChar * nsName,
5245 xmlNodePtr node, int topLevel)
5246{
5247 xmlSchemaAttributePtr ret = NULL;
5248
5249 if ((ctxt == NULL) || (schema == NULL))
5250 return (NULL);
5251
5252 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5253 if (ret == NULL) {
5254 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
5255 return (NULL);
5256 }
5257 memset(ret, 0, sizeof(xmlSchemaAttribute));
5258 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5259 ret->node = node;
5260 ret->name = name;
5261 ret->targetNamespace = nsName;
5262
5263 if (topLevel)
5264 WXS_ADD_GLOBAL(ctxt, ret);
5265 else
5266 WXS_ADD_LOCAL(ctxt, ret);
5267 WXS_ADD_PENDING(ctxt, ret);
5268 return (ret);
5269}
5270
5283static xmlSchemaAttributeUsePtr
5284xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5286{
5287 xmlSchemaAttributeUsePtr ret = NULL;
5288
5289 if (pctxt == NULL)
5290 return (NULL);
5291
5292 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5293 if (ret == NULL) {
5294 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
5295 return (NULL);
5296 }
5297 memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5298 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5299 ret->node = node;
5300
5301 WXS_ADD_LOCAL(pctxt, ret);
5302 return (ret);
5303}
5304
5305/*
5306* xmlSchemaAddRedef:
5307*
5308* Adds a redefinition information. This is used at a later stage to:
5309* resolve references to the redefined components and to check constraints.
5310*/
5311static xmlSchemaRedefPtr
5312xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5313 xmlSchemaBucketPtr targetBucket,
5314 void *item,
5315 const xmlChar *refName,
5316 const xmlChar *refTargetNs)
5317{
5318 xmlSchemaRedefPtr ret;
5319
5320 ret = (xmlSchemaRedefPtr)
5321 xmlMalloc(sizeof(xmlSchemaRedef));
5322 if (ret == NULL) {
5323 xmlSchemaPErrMemory(pctxt,
5324 "allocating redefinition info", NULL);
5325 return (NULL);
5326 }
5327 memset(ret, 0, sizeof(xmlSchemaRedef));
5328 ret->item = item;
5329 ret->targetBucket = targetBucket;
5330 ret->refName = refName;
5331 ret->refTargetNs = refTargetNs;
5332 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5333 WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5334 else
5335 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5336 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5337
5338 return (ret);
5339}
5340
5353static xmlSchemaAttributeGroupPtr
5354xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5355 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5356 const xmlChar *name,
5357 const xmlChar *nsName,
5359{
5360 xmlSchemaAttributeGroupPtr ret = NULL;
5361
5362 if ((pctxt == NULL) || (name == NULL))
5363 return (NULL);
5364
5365 ret = (xmlSchemaAttributeGroupPtr)
5366 xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5367 if (ret == NULL) {
5368 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
5369 return (NULL);
5370 }
5371 memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5372 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5373 ret->name = name;
5374 ret->targetNamespace = nsName;
5375 ret->node = node;
5376
5377 /* TODO: Remove the flag. */
5378 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5379 if (pctxt->isRedefine) {
5380 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5381 ret, name, nsName);
5382 if (pctxt->redef == NULL) {
5383 xmlFree(ret);
5384 return(NULL);
5385 }
5386 pctxt->redefCounter = 0;
5387 }
5388 WXS_ADD_GLOBAL(pctxt, ret);
5389 WXS_ADD_PENDING(pctxt, ret);
5390 return (ret);
5391}
5392
5405static xmlSchemaElementPtr
5406xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5407 const xmlChar * name, const xmlChar * nsName,
5408 xmlNodePtr node, int topLevel)
5409{
5410 xmlSchemaElementPtr ret = NULL;
5411
5412 if ((ctxt == NULL) || (name == NULL))
5413 return (NULL);
5414
5415 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5416 if (ret == NULL) {
5417 xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
5418 return (NULL);
5419 }
5420 memset(ret, 0, sizeof(xmlSchemaElement));
5421 ret->type = XML_SCHEMA_TYPE_ELEMENT;
5422 ret->name = name;
5423 ret->targetNamespace = nsName;
5424 ret->node = node;
5425
5426 if (topLevel)
5427 WXS_ADD_GLOBAL(ctxt, ret);
5428 else
5429 WXS_ADD_LOCAL(ctxt, ret);
5430 WXS_ADD_PENDING(ctxt, ret);
5431 return (ret);
5432}
5433
5446static xmlSchemaTypePtr
5447xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5448 xmlSchemaTypeType type,
5449 const xmlChar * name, const xmlChar * nsName,
5450 xmlNodePtr node, int topLevel)
5451{
5452 xmlSchemaTypePtr ret = NULL;
5453
5454 if ((ctxt == NULL) || (schema == NULL))
5455 return (NULL);
5456
5457 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5458 if (ret == NULL) {
5459 xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
5460 return (NULL);
5461 }
5462 memset(ret, 0, sizeof(xmlSchemaType));
5463 ret->type = type;
5464 ret->name = name;
5465 ret->targetNamespace = nsName;
5466 ret->node = node;
5467 if (topLevel) {
5468 if (ctxt->isRedefine) {
5469 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5470 ret, name, nsName);
5471 if (ctxt->redef == NULL) {
5472 xmlFree(ret);
5473 return(NULL);
5474 }
5475 ctxt->redefCounter = 0;
5476 }
5477 WXS_ADD_GLOBAL(ctxt, ret);
5478 } else
5479 WXS_ADD_LOCAL(ctxt, ret);
5480 WXS_ADD_PENDING(ctxt, ret);
5481 return (ret);
5482}
5483
5484static xmlSchemaQNameRefPtr
5485xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5486 xmlSchemaTypeType refType,
5487 const xmlChar *refName,
5488 const xmlChar *refNs)
5489{
5490 xmlSchemaQNameRefPtr ret;
5491
5492 ret = (xmlSchemaQNameRefPtr)
5493 xmlMalloc(sizeof(xmlSchemaQNameRef));
5494 if (ret == NULL) {
5495 xmlSchemaPErrMemory(pctxt,
5496 "allocating QName reference item", NULL);
5497 return (NULL);
5498 }
5499 ret->node = NULL;
5500 ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5501 ret->name = refName;
5502 ret->targetNamespace = refNs;
5503 ret->item = NULL;
5504 ret->itemType = refType;
5505 /*
5506 * Store the reference item in the schema.
5507 */
5508 WXS_ADD_LOCAL(pctxt, ret);
5509 return (ret);
5510}
5511
5512static xmlSchemaAttributeUseProhibPtr
5513xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5514{
5515 xmlSchemaAttributeUseProhibPtr ret;
5516
5517 ret = (xmlSchemaAttributeUseProhibPtr)
5518 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5519 if (ret == NULL) {
5520 xmlSchemaPErrMemory(pctxt,
5521 "allocating attribute use prohibition", NULL);
5522 return (NULL);
5523 }
5524 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5525 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5526 WXS_ADD_LOCAL(pctxt, ret);
5527 return (ret);
5528}
5529
5530
5543static xmlSchemaModelGroupPtr
5544xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5545 xmlSchemaPtr schema,
5546 xmlSchemaTypeType type,
5548{
5549 xmlSchemaModelGroupPtr ret = NULL;
5550
5551 if ((ctxt == NULL) || (schema == NULL))
5552 return (NULL);
5553
5554 ret = (xmlSchemaModelGroupPtr)
5555 xmlMalloc(sizeof(xmlSchemaModelGroup));
5556 if (ret == NULL) {
5557 xmlSchemaPErrMemory(ctxt, "allocating model group component",
5558 NULL);
5559 return (NULL);
5560 }
5561 memset(ret, 0, sizeof(xmlSchemaModelGroup));
5562 ret->type = type;
5563 ret->node = node;
5564 WXS_ADD_LOCAL(ctxt, ret);
5565 if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5566 (type == XML_SCHEMA_TYPE_CHOICE))
5567 WXS_ADD_PENDING(ctxt, ret);
5568 return (ret);
5569}
5570
5571
5585static xmlSchemaParticlePtr
5586xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5587 xmlNodePtr node, int min, int max)
5588{
5589 xmlSchemaParticlePtr ret = NULL;
5590 if (ctxt == NULL)
5591 return (NULL);
5592
5593#ifdef DEBUG
5594 fprintf(stderr, "Adding particle component\n");
5595#endif
5596 ret = (xmlSchemaParticlePtr)
5597 xmlMalloc(sizeof(xmlSchemaParticle));
5598 if (ret == NULL) {
5599 xmlSchemaPErrMemory(ctxt, "allocating particle component",
5600 NULL);
5601 return (NULL);
5602 }
5603 ret->type = XML_SCHEMA_TYPE_PARTICLE;
5604 ret->annot = NULL;
5605 ret->node = node;
5606 ret->minOccurs = min;
5607 ret->maxOccurs = max;
5608 ret->next = NULL;
5609 ret->children = NULL;
5610
5611 WXS_ADD_LOCAL(ctxt, ret);
5612 /*
5613 * Note that addition to pending components will be done locally
5614 * to the specific parsing function, since the most particles
5615 * need not to be fixed up (i.e. the reference to be resolved).
5616 * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5617 */
5618 return (ret);
5619}
5620
5631static xmlSchemaModelGroupDefPtr
5632xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5633 xmlSchemaPtr schema,
5634 const xmlChar *name,
5635 const xmlChar *nsName,
5637{
5638 xmlSchemaModelGroupDefPtr ret = NULL;
5639
5640 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5641 return (NULL);
5642
5643 ret = (xmlSchemaModelGroupDefPtr)
5644 xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5645 if (ret == NULL) {
5646 xmlSchemaPErrMemory(ctxt, "adding group", NULL);
5647 return (NULL);
5648 }
5649 memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5650 ret->name = name;
5651 ret->type = XML_SCHEMA_TYPE_GROUP;
5652 ret->node = node;
5653 ret->targetNamespace = nsName;
5654
5655 if (ctxt->isRedefine) {
5656 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5657 ret, name, nsName);
5658 if (ctxt->redef == NULL) {
5659 xmlFree(ret);
5660 return(NULL);
5661 }
5662 ctxt->redefCounter = 0;
5663 }
5664 WXS_ADD_GLOBAL(ctxt, ret);
5665 WXS_ADD_PENDING(ctxt, ret);
5666 return (ret);
5667}
5668
5677static xmlSchemaWildcardNsPtr
5678xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5679{
5680 xmlSchemaWildcardNsPtr ret;
5681
5682 ret = (xmlSchemaWildcardNsPtr)
5683 xmlMalloc(sizeof(xmlSchemaWildcardNs));
5684 if (ret == NULL) {
5685 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
5686 return (NULL);
5687 }
5688 ret->value = NULL;
5689 ret->next = NULL;
5690 return (ret);
5691}
5692
5693static xmlSchemaIDCPtr
5694xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5695 const xmlChar *name, const xmlChar *nsName,
5697{
5698 xmlSchemaIDCPtr ret = NULL;
5699
5700 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5701 return (NULL);
5702
5703 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5704 if (ret == NULL) {
5705 xmlSchemaPErrMemory(ctxt,
5706 "allocating an identity-constraint definition", NULL);
5707 return (NULL);
5708 }
5709 memset(ret, 0, sizeof(xmlSchemaIDC));
5710 /* The target namespace of the parent element declaration. */
5711 ret->targetNamespace = nsName;
5712 ret->name = name;
5713 ret->type = category;
5714 ret->node = node;
5715
5716 WXS_ADD_GLOBAL(ctxt, ret);
5717 /*
5718 * Only keyrefs need to be fixup up.
5719 */
5720 if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5721 WXS_ADD_PENDING(ctxt, ret);
5722 return (ret);
5723}
5724
5735static xmlSchemaWildcardPtr
5736xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5737 xmlSchemaTypeType type, xmlNodePtr node)
5738{
5739 xmlSchemaWildcardPtr ret = NULL;
5740
5741 if ((ctxt == NULL) || (schema == NULL))
5742 return (NULL);
5743
5744 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5745 if (ret == NULL) {
5746 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
5747 return (NULL);
5748 }
5749 memset(ret, 0, sizeof(xmlSchemaWildcard));
5750 ret->type = type;
5751 ret->node = node;
5752 WXS_ADD_LOCAL(ctxt, ret);
5753 return (ret);
5754}
5755
5756static void
5757xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5758{
5759 if (group == NULL)
5760 return;
5761 if (group->members != NULL)
5762 xmlSchemaItemListFree(group->members);
5763 xmlFree(group);
5764}
5765
5766static void
5767xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5768{
5769 xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5770}
5771
5772static xmlSchemaSubstGroupPtr
5773xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5774 xmlSchemaElementPtr head)
5775{
5776 xmlSchemaSubstGroupPtr ret;
5777
5778 /* Init subst group hash. */
5779 if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5780 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5781 if (WXS_SUBST_GROUPS(pctxt) == NULL)
5782 return(NULL);
5783 }
5784 /* Create a new substitution group. */
5785 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5786 if (ret == NULL) {
5787 xmlSchemaPErrMemory(NULL,
5788 "allocating a substitution group container", NULL);
5789 return(NULL);
5790 }
5791 memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5792 ret->head = head;
5793 /* Create list of members. */
5794 ret->members = xmlSchemaItemListCreate();
5795 if (ret->members == NULL) {
5796 xmlSchemaSubstGroupFree(ret);
5797 return(NULL);
5798 }
5799 /* Add subst group to hash. */
5800 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5801 head->name, head->targetNamespace, ret) != 0) {
5802 PERROR_INT("xmlSchemaSubstGroupAdd",
5803 "failed to add a new substitution container");
5804 xmlSchemaSubstGroupFree(ret);
5805 return(NULL);
5806 }
5807 return(ret);
5808}
5809
5810static xmlSchemaSubstGroupPtr
5811xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5812 xmlSchemaElementPtr head)
5813{
5814 if (WXS_SUBST_GROUPS(pctxt) == NULL)
5815 return(NULL);
5816 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5817 head->name, head->targetNamespace));
5818
5819}
5820
5831static int
5832xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5833 xmlSchemaElementPtr head,
5834 xmlSchemaElementPtr member)
5835{
5836 xmlSchemaSubstGroupPtr substGroup = NULL;
5837
5838 if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5839 return (-1);
5840
5841 substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5842 if (substGroup == NULL)
5843 substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5844 if (substGroup == NULL)
5845 return(-1);
5846 if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5847 return(-1);
5848 return(0);
5849}
5850
5851/************************************************************************
5852 * *
5853 * Utilities for parsing *
5854 * *
5855 ************************************************************************/
5856
5873static int
5874xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5875 xmlSchemaPtr schema,
5876 xmlSchemaBasicItemPtr ownerItem,
5878 const xmlChar *value,
5879 const xmlChar **uri,
5880 const xmlChar **local)
5881{
5882 const xmlChar *pref;
5883 xmlNsPtr ns;
5884 int len, ret;
5885
5886 *uri = NULL;
5887 *local = NULL;
5888 ret = xmlValidateQName(value, 1);
5889 if (ret > 0) {
5890 xmlSchemaPSimpleTypeErr(ctxt,
5892 ownerItem, (xmlNodePtr) attr,
5893 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5894 NULL, value, NULL, NULL, NULL);
5895 *local = value;
5896 return (ctxt->err);
5897 } else if (ret < 0)
5898 return (-1);
5899
5900 if (!strchr((char *) value, ':')) {
5901 ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5902 if (ns && ns->href && ns->href[0])
5903 *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5904 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5905 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5906 * parser context. */
5907 /*
5908 * This one takes care of included schemas with no
5909 * target namespace.
5910 */
5911 *uri = ctxt->targetNamespace;
5912 }
5913 *local = xmlDictLookup(ctxt->dict, value, -1);
5914 return (0);
5915 }
5916 /*
5917 * At this point xmlSplitQName3 has to return a local name.
5918 */
5920 *local = xmlDictLookup(ctxt->dict, *local, -1);
5921 pref = xmlDictLookup(ctxt->dict, value, len);
5922 ns = xmlSearchNs(attr->doc, attr->parent, pref);
5923 if (ns == NULL) {
5924 xmlSchemaPSimpleTypeErr(ctxt,
5926 ownerItem, (xmlNodePtr) attr,
5927 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5928 "The value '%s' of simple type 'xs:QName' has no "
5929 "corresponding namespace declaration in scope", value, NULL);
5930 return (ctxt->err);
5931 } else {
5932 *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5933 }
5934 return (0);
5935}
5936
5953static int
5954xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5955 xmlSchemaPtr schema,
5956 xmlSchemaBasicItemPtr ownerItem,
5958 const xmlChar **uri,
5959 const xmlChar **local)
5960{
5961 const xmlChar *value;
5962
5963 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5964 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5965 ownerItem, attr, value, uri, local));
5966}
5967
5983static int
5984xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5985 xmlSchemaPtr schema,
5986 xmlSchemaBasicItemPtr ownerItem,
5987 xmlNodePtr ownerElem,
5988 const char *name,
5989 const xmlChar **uri,
5990 const xmlChar **local)
5991{
5993
5994 attr = xmlSchemaGetPropNode(ownerElem, name);
5995 if (attr == NULL) {
5996 *local = NULL;
5997 *uri = NULL;
5998 return (0);
5999 }
6000 return (xmlSchemaPValAttrNodeQName(ctxt, schema,
6001 ownerItem, attr, uri, local));
6002}
6003
6013static int
6014xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
6015{
6016 int ret;
6017 const xmlChar *value;
6018
6019 if (attr == NULL)
6020 return(0);
6021 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
6022 ret = xmlValidateNCName(value, 1);
6023 if (ret == 0) {
6024 /*
6025 * NOTE: the IDness might have already be declared in the DTD
6026 */
6027 if (attr->atype != XML_ATTRIBUTE_ID) {
6028 xmlIDPtr res;
6029 xmlChar *strip;
6030
6031 /*
6032 * TODO: Use xmlSchemaStrip here; it's not exported at this
6033 * moment.
6034 */
6035 strip = xmlSchemaCollapseString(value);
6036 if (strip != NULL) {
6037 xmlFree((xmlChar *) value);
6038 value = strip;
6039 }
6040 res = xmlAddID(NULL, attr->doc, value, attr);
6041 if (res == NULL) {
6043 xmlSchemaPSimpleTypeErr(ctxt,
6045 NULL, (xmlNodePtr) attr,
6046 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
6047 NULL, NULL, "Duplicate value '%s' of simple "
6048 "type 'xs:ID'", value, NULL);
6049 } else
6050 attr->atype = XML_ATTRIBUTE_ID;
6051 }
6052 } else if (ret > 0) {
6054 xmlSchemaPSimpleTypeErr(ctxt,
6056 NULL, (xmlNodePtr) attr,
6057 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
6058 NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
6059 "not a valid 'xs:NCName'",
6060 value, NULL);
6061 }
6062 if (value != NULL)
6063 xmlFree((xmlChar *)value);
6064
6065 return (ret);
6066}
6067
6068static int
6069xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
6070 xmlNodePtr ownerElem,
6071 const xmlChar *name)
6072{
6074
6075 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
6076 if (attr == NULL)
6077 return(0);
6078 return(xmlSchemaPValAttrNodeID(ctxt, attr));
6079
6080}
6081
6091static int
6092xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6093 int min, int max, int def, const char *expected)
6094{
6095 const xmlChar *val, *cur;
6096 int ret = 0;
6098
6099 attr = xmlSchemaGetPropNode(node, "maxOccurs");
6100 if (attr == NULL)
6101 return (def);
6102 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6103
6104 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
6105 if (max != UNBOUNDED) {
6106 xmlSchemaPSimpleTypeErr(ctxt,
6108 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6110 val, NULL, NULL, NULL);
6111 return (def);
6112 } else
6113 return (UNBOUNDED); /* encoding it with -1 might be another option */
6114 }
6115
6116 cur = val;
6117 while (IS_BLANK_CH(*cur))
6118 cur++;
6119 if (*cur == 0) {
6120 xmlSchemaPSimpleTypeErr(ctxt,
6122 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6124 val, NULL, NULL, NULL);
6125 return (def);
6126 }
6127 while ((*cur >= '0') && (*cur <= '9')) {
6128 if (ret > INT_MAX / 10) {
6129 ret = INT_MAX;
6130 } else {
6131 int digit = *cur - '0';
6132 ret *= 10;
6133 if (ret > INT_MAX - digit)
6134 ret = INT_MAX;
6135 else
6136 ret += digit;
6137 }
6138 cur++;
6139 }
6140 while (IS_BLANK_CH(*cur))
6141 cur++;
6142 /*
6143 * TODO: Restrict the maximal value to Integer.
6144 */
6145 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6146 xmlSchemaPSimpleTypeErr(ctxt,
6148 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6150 val, NULL, NULL, NULL);
6151 return (def);
6152 }
6153 return (ret);
6154}
6155
6165static int
6166xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6167 int min, int max, int def, const char *expected)
6168{
6169 const xmlChar *val, *cur;
6170 int ret = 0;
6172
6173 attr = xmlSchemaGetPropNode(node, "minOccurs");
6174 if (attr == NULL)
6175 return (def);
6176 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6177 cur = val;
6178 while (IS_BLANK_CH(*cur))
6179 cur++;
6180 if (*cur == 0) {
6181 xmlSchemaPSimpleTypeErr(ctxt,
6183 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6185 val, NULL, NULL, NULL);
6186 return (def);
6187 }
6188 while ((*cur >= '0') && (*cur <= '9')) {
6189 if (ret > INT_MAX / 10) {
6190 ret = INT_MAX;
6191 } else {
6192 int digit = *cur - '0';
6193 ret *= 10;
6194 if (ret > INT_MAX - digit)
6195 ret = INT_MAX;
6196 else
6197 ret += digit;
6198 }
6199 cur++;
6200 }
6201 while (IS_BLANK_CH(*cur))
6202 cur++;
6203 /*
6204 * TODO: Restrict the maximal value to Integer.
6205 */
6206 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6207 xmlSchemaPSimpleTypeErr(ctxt,
6209 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6211 val, NULL, NULL, NULL);
6212 return (def);
6213 }
6214 return (ret);
6215}
6216
6227static int
6228xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6229 xmlSchemaBasicItemPtr ownerItem,
6231{
6232 xmlChar *value = NULL;
6233 int res = 0;
6234
6236 /*
6237 * 3.2.2.1 Lexical representation
6238 * An instance of a datatype that is defined as `boolean`
6239 * can have the following legal literals {true, false, 1, 0}.
6240 */
6241 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6242 res = 1;
6243 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6244 res = 0;
6245 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6246 res = 1;
6247 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6248 res = 0;
6249 else {
6250 xmlSchemaPSimpleTypeErr(ctxt,
6252 ownerItem, node,
6253 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6255 NULL, NULL, NULL);
6256 }
6257 if (value != NULL)
6258 xmlFree(value);
6259 return (res);
6260}
6261
6274static int
6275xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6277 const char *name, int def)
6278{
6279 const xmlChar *val;
6280
6281 val = xmlSchemaGetProp(ctxt, node, name);
6282 if (val == NULL)
6283 return (def);
6284 /*
6285 * 3.2.2.1 Lexical representation
6286 * An instance of a datatype that is defined as `boolean`
6287 * can have the following legal literals {true, false, 1, 0}.
6288 */
6289 if (xmlStrEqual(val, BAD_CAST "true"))
6290 def = 1;
6291 else if (xmlStrEqual(val, BAD_CAST "false"))
6292 def = 0;
6293 else if (xmlStrEqual(val, BAD_CAST "1"))
6294 def = 1;
6295 else if (xmlStrEqual(val, BAD_CAST "0"))
6296 def = 0;
6297 else {
6298 xmlSchemaPSimpleTypeErr(ctxt,
6300 NULL,
6301 (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6302 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6303 NULL, val, NULL, NULL, NULL);
6304 }
6305 return (def);
6306}
6307
6308/************************************************************************
6309 * *
6310 * Schema extraction from an Infoset *
6311 * *
6312 ************************************************************************/
6313static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6314 ctxt, xmlSchemaPtr schema,
6316 int topLevel);
6317static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6318 ctxt,
6319 xmlSchemaPtr schema,
6321 int topLevel);
6322static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6323 ctxt,
6324 xmlSchemaPtr schema,
6326 xmlSchemaTypeType parentType);
6327static xmlSchemaBasicItemPtr
6328xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6329 xmlSchemaPtr schema,
6331 xmlSchemaItemListPtr uses,
6332 int parentType);
6333static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6334 xmlSchemaPtr schema,
6336static xmlSchemaWildcardPtr
6337xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6338 xmlSchemaPtr schema, xmlNodePtr node);
6339
6356static int
6357xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6358 xmlSchemaBasicItemPtr ownerItem,
6360 const xmlChar *value,
6361 xmlSchemaTypePtr type)
6362{
6363
6364 int ret = 0;
6365
6366 /*
6367 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6368 * one is really meant to be used internally, so better not.
6369 */
6370 if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6371 return (-1);
6372 if (type->type != XML_SCHEMA_TYPE_BASIC) {
6373 PERROR_INT("xmlSchemaPValAttrNodeValue",
6374 "the given type is not a built-in type");
6375 return (-1);
6376 }
6377 switch (type->builtInType) {
6378 case XML_SCHEMAS_NCNAME:
6379 case XML_SCHEMAS_QNAME:
6380 case XML_SCHEMAS_ANYURI:
6381 case XML_SCHEMAS_TOKEN:
6382 case XML_SCHEMAS_LANGUAGE:
6383 ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6384 (xmlNodePtr) attr);
6385 break;
6386 default: {
6387 PERROR_INT("xmlSchemaPValAttrNodeValue",
6388 "validation using the given type is not supported while "
6389 "parsing a schema");
6390 return (-1);
6391 }
6392 }
6393 /*
6394 * TODO: Should we use the S4S error codes instead?
6395 */
6396 if (ret < 0) {
6397 PERROR_INT("xmlSchemaPValAttrNodeValue",
6398 "failed to validate a schema attribute value");
6399 return (-1);
6400 } else if (ret > 0) {
6401 if (WXS_IS_LIST(type))
6403 else
6405 xmlSchemaPSimpleTypeErr(pctxt,
6406 ret, ownerItem, (xmlNodePtr) attr,
6407 type, NULL, value, NULL, NULL, NULL);
6408 }
6409 return (ret);
6410}
6411
6428static int
6429xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6430 xmlSchemaBasicItemPtr ownerItem,
6432 xmlSchemaTypePtr type,
6433 const xmlChar **value)
6434{
6435 const xmlChar *val;
6436
6437 if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6438 return (-1);
6439
6440 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6441 if (value != NULL)
6442 *value = val;
6443
6444 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6445 val, type));
6446}
6447
6466static int
6467xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6468 xmlSchemaBasicItemPtr ownerItem,
6469 xmlNodePtr ownerElem,
6470 const char *name,
6471 xmlSchemaTypePtr type,
6472 const xmlChar **value)
6473{
6475
6476 if ((ctxt == NULL) || (type == NULL)) {
6477 if (value != NULL)
6478 *value = NULL;
6479 return (-1);
6480 }
6481 if (type->type != XML_SCHEMA_TYPE_BASIC) {
6482 if (value != NULL)
6483 *value = NULL;
6484 xmlSchemaPErr(ctxt, ownerElem,
6486 "Internal error: xmlSchemaPValAttr, the given "
6487 "type '%s' is not a built-in type.\n",
6488 type->name, NULL);
6489 return (-1);
6490 }
6491 attr = xmlSchemaGetPropNode(ownerElem, name);
6492 if (attr == NULL) {
6493 if (value != NULL)
6494 *value = NULL;
6495 return (0);
6496 }
6497 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6498 type, value));
6499}
6500
6501static int
6502xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6503 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6506 const xmlChar *namespaceName)
6507{
6508 /* TODO: Pointer comparison instead? */
6509 if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6510 return (0);
6511 if (xmlStrEqual(xmlSchemaNs, namespaceName))
6512 return (0);
6513 /*
6514 * Check if the referenced namespace was <import>ed.
6515 */
6516 if (WXS_BUCKET(pctxt)->relations != NULL) {
6517 xmlSchemaSchemaRelationPtr rel;
6518
6519 rel = WXS_BUCKET(pctxt)->relations;
6520 do {
6521 if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6522 xmlStrEqual(namespaceName, rel->importNamespace))
6523 return (0);
6524 rel = rel->next;
6525 } while (rel != NULL);
6526 }
6527 /*
6528 * No matching <import>ed namespace found.
6529 */
6530 {
6531 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6532
6533 if (namespaceName == NULL)
6534 xmlSchemaCustomErr(ACTXT_CAST pctxt,
6536 "References from this schema to components in no "
6537 "namespace are not allowed, since not indicated by an "
6538 "import statement", NULL, NULL);
6539 else
6540 xmlSchemaCustomErr(ACTXT_CAST pctxt,
6542 "References from this schema to components in the "
6543 "namespace '%s' are not allowed, since not indicated by an "
6544 "import statement", namespaceName, NULL);
6545 }
6546 return (XML_SCHEMAP_SRC_RESOLVE);
6547}
6548
6559static int
6560xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6561 xmlNodePtr *child, xmlSchemaItemListPtr *list,
6562 int parentType, int *hasRefs)
6563{
6564 void *item;
6565
6566 while ((IS_SCHEMA((*child), "attribute")) ||
6567 (IS_SCHEMA((*child), "attributeGroup"))) {
6568 if (IS_SCHEMA((*child), "attribute")) {
6569 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6570 *list, parentType);
6571 } else {
6572 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6573 if ((item != NULL) && (hasRefs != NULL))
6574 *hasRefs = 1;
6575 }
6576 if (item != NULL) {
6577 if (*list == NULL) {
6578 /* TODO: Customize grow factor. */
6579 *list = xmlSchemaItemListCreate();
6580 if (*list == NULL)
6581 return(-1);
6582 }
6583 if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6584 return(-1);
6585 }
6586 *child = (*child)->next;
6587 }
6588 return (0);
6589}
6590
6603static xmlSchemaAnnotPtr
6604xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6605{
6606 xmlSchemaAnnotPtr ret;
6609 int barked = 0;
6610
6611 /*
6612 * INFO: S4S completed.
6613 */
6614 /*
6615 * id = ID
6616 * {any attributes with non-schema namespace . . .}>
6617 * Content: (appinfo | documentation)*
6618 */
6619 if ((ctxt == NULL) || (node == NULL))
6620 return (NULL);
6621 if (needed)
6622 ret = xmlSchemaNewAnnot(ctxt, node);
6623 else
6624 ret = NULL;
6625 attr = node->properties;
6626 while (attr != NULL) {
6627 if (((attr->ns == NULL) &&
6628 (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6629 ((attr->ns != NULL) &&
6630 xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6631
6632 xmlSchemaPIllegalAttrErr(ctxt,
6634 }
6635 attr = attr->next;
6636 }
6637 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6638 /*
6639 * And now for the children...
6640 */
6641 child = node->children;
6642 while (child != NULL) {
6643 if (IS_SCHEMA(child, "appinfo")) {
6644 /* TODO: make available the content of "appinfo". */
6645 /*
6646 * source = anyURI
6647 * {any attributes with non-schema namespace . . .}>
6648 * Content: ({any})*
6649 */
6650 attr = child->properties;
6651 while (attr != NULL) {
6652 if (((attr->ns == NULL) &&
6653 (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6654 ((attr->ns != NULL) &&
6655 xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6656
6657 xmlSchemaPIllegalAttrErr(ctxt,
6659 }
6660 attr = attr->next;
6661 }
6662 xmlSchemaPValAttr(ctxt, NULL, child, "source",
6663 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6664 child = child->next;
6665 } else if (IS_SCHEMA(child, "documentation")) {
6666 /* TODO: make available the content of "documentation". */
6667 /*
6668 * source = anyURI
6669 * {any attributes with non-schema namespace . . .}>
6670 * Content: ({any})*
6671 */
6672 attr = child->properties;
6673 while (attr != NULL) {
6674 if (attr->ns == NULL) {
6675 if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6676 xmlSchemaPIllegalAttrErr(ctxt,
6678 }
6679 } else {
6680 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6681 (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6682 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6683
6684 xmlSchemaPIllegalAttrErr(ctxt,
6686 }
6687 }
6688 attr = attr->next;
6689 }
6690 /*
6691 * Attribute "xml:lang".
6692 */
6693 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6694 if (attr != NULL)
6695 xmlSchemaPValAttrNode(ctxt, NULL, attr,
6696 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6697 child = child->next;
6698 } else {
6699 if (!barked)
6700 xmlSchemaPContentErr(ctxt,
6702 NULL, node, child, NULL, "(appinfo | documentation)*");
6703 barked = 1;
6704 child = child->next;
6705 }
6706 }
6707
6708 return (ret);
6709}
6710
6722static xmlSchemaFacetPtr
6723xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6725{
6726 xmlSchemaFacetPtr facet;
6728 const xmlChar *value;
6729
6730 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6731 return (NULL);
6732
6733 facet = xmlSchemaNewFacet();
6734 if (facet == NULL) {
6735 xmlSchemaPErrMemory(ctxt, "allocating facet", node);
6736 return (NULL);
6737 }
6738 facet->node = node;
6739 value = xmlSchemaGetProp(ctxt, node, "value");
6740 if (value == NULL) {
6741 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6742 "Facet %s has no value\n", node->name, NULL);
6743 xmlSchemaFreeFacet(facet);
6744 return (NULL);
6745 }
6746 if (IS_SCHEMA(node, "minInclusive")) {
6747 facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6748 } else if (IS_SCHEMA(node, "minExclusive")) {
6749 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6750 } else if (IS_SCHEMA(node, "maxInclusive")) {
6751 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6752 } else if (IS_SCHEMA(node, "maxExclusive")) {
6753 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6754 } else if (IS_SCHEMA(node, "totalDigits")) {
6755 facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6756 } else if (IS_SCHEMA(node, "fractionDigits")) {
6757 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6758 } else if (IS_SCHEMA(node, "pattern")) {
6759 facet->type = XML_SCHEMA_FACET_PATTERN;
6760 } else if (IS_SCHEMA(node, "enumeration")) {
6761 facet->type = XML_SCHEMA_FACET_ENUMERATION;
6762 } else if (IS_SCHEMA(node, "whiteSpace")) {
6763 facet->type = XML_SCHEMA_FACET_WHITESPACE;
6764 } else if (IS_SCHEMA(node, "length")) {
6765 facet->type = XML_SCHEMA_FACET_LENGTH;
6766 } else if (IS_SCHEMA(node, "maxLength")) {
6767 facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6768 } else if (IS_SCHEMA(node, "minLength")) {
6769 facet->type = XML_SCHEMA_FACET_MINLENGTH;
6770 } else {
6771 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6772 "Unknown facet type %s\n", node->name, NULL);
6773 xmlSchemaFreeFacet(facet);
6774 return (NULL);
6775 }
6776 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6777 facet->value = value;
6778 if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6779 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6780 const xmlChar *fixed;
6781
6782 fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6783 if (fixed != NULL) {
6784 if (xmlStrEqual(fixed, BAD_CAST "true"))
6785 facet->fixed = 1;
6786 }
6787 }
6788 child = node->children;
6789
6790 if (IS_SCHEMA(child, "annotation")) {
6791 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6792 child = child->next;
6793 }
6794 if (child != NULL) {
6795 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6796 "Facet %s has unexpected child content\n",
6797 node->name, NULL);
6798 }
6799 return (facet);
6800}
6801
6815static int
6816xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6817 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6818 xmlSchemaWildcardPtr wildc,
6820{
6821 const xmlChar *pc, *ns, *dictnsItem;
6822 int ret = 0;
6823 xmlChar *nsItem;
6824 xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6826
6827 pc = xmlSchemaGetProp(ctxt, node, "processContents");
6828 if ((pc == NULL)
6829 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6830 wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6831 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6832 wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6833 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6834 wildc->processContents = XML_SCHEMAS_ANY_LAX;
6835 } else {
6836 xmlSchemaPSimpleTypeErr(ctxt,
6838 NULL, node,
6839 NULL, "(strict | skip | lax)", pc,
6840 NULL, NULL, NULL);
6841 wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6843 }
6844 /*
6845 * Build the namespace constraints.
6846 */
6847 attr = xmlSchemaGetPropNode(node, "namespace");
6848 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6849 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6850 wildc->any = 1;
6851 else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6852 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6853 if (wildc->negNsSet == NULL) {
6854 return (-1);
6855 }
6856 wildc->negNsSet->value = ctxt->targetNamespace;
6857 } else {
6858 const xmlChar *end, *cur;
6859
6860 cur = ns;
6861 do {
6862 while (IS_BLANK_CH(*cur))
6863 cur++;
6864 end = cur;
6865 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6866 end++;
6867 if (end == cur)
6868 break;
6869 nsItem = xmlStrndup(cur, end - cur);
6870 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6871 (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6872 xmlSchemaPSimpleTypeErr(ctxt,
6874 NULL, (xmlNodePtr) attr,
6875 NULL,
6876 "((##any | ##other) | List of (xs:anyURI | "
6877 "(##targetNamespace | ##local)))",
6878 nsItem, NULL, NULL, NULL);
6880 } else {
6881 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6882 dictnsItem = ctxt->targetNamespace;
6883 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6884 dictnsItem = NULL;
6885 } else {
6886 /*
6887 * Validate the item (anyURI).
6888 */
6889 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6890 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6891 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6892 }
6893 /*
6894 * Avoid duplicate namespaces.
6895 */
6896 tmp = wildc->nsSet;
6897 while (tmp != NULL) {
6898 if (dictnsItem == tmp->value)
6899 break;
6900 tmp = tmp->next;
6901 }
6902 if (tmp == NULL) {
6903 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6904 if (tmp == NULL) {
6905 xmlFree(nsItem);
6906 return (-1);
6907 }
6908 tmp->value = dictnsItem;
6909 tmp->next = NULL;
6910 if (wildc->nsSet == NULL)
6911 wildc->nsSet = tmp;
6912 else if (lastNs != NULL)
6913 lastNs->next = tmp;
6914 lastNs = tmp;
6915 }
6916
6917 }
6918 xmlFree(nsItem);
6919 cur = end;
6920 } while (*cur != 0);
6921 }
6922 return (ret);
6923}
6924
6925static int
6926xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6927 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6929 int minOccurs,
6930 int maxOccurs) {
6931
6932 if ((maxOccurs == 0) && ( minOccurs == 0))
6933 return (0);
6934 if (maxOccurs != UNBOUNDED) {
6935 /*
6936 * TODO: Maybe we should better not create the particle,
6937 * if min/max is invalid, since it could confuse the build of the
6938 * content model.
6939 */
6940 /*
6941 * 3.9.6 Schema Component Constraint: Particle Correct
6942 *
6943 */
6944 if (maxOccurs < 1) {
6945 /*
6946 * 2.2 {max occurs} must be greater than or equal to 1.
6947 */
6948 xmlSchemaPCustomAttrErr(ctxt,
6950 NULL, NULL,
6951 xmlSchemaGetPropNode(node, "maxOccurs"),
6952 "The value must be greater than or equal to 1");
6954 } else if (minOccurs > maxOccurs) {
6955 /*
6956 * 2.1 {min occurs} must not be greater than {max occurs}.
6957 */
6958 xmlSchemaPCustomAttrErr(ctxt,
6960 NULL, NULL,
6961 xmlSchemaGetPropNode(node, "minOccurs"),
6962 "The value must not be greater than the value of 'maxOccurs'");
6964 }
6965 }
6966 return (0);
6967}
6968
6982static xmlSchemaParticlePtr
6983xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6985{
6986 xmlSchemaParticlePtr particle;
6988 xmlSchemaWildcardPtr wild;
6989 int min, max;
6991 xmlSchemaAnnotPtr annot = NULL;
6992
6993 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6994 return (NULL);
6995 /*
6996 * Check for illegal attributes.
6997 */
6998 attr = node->properties;
6999 while (attr != NULL) {
7000 if (attr->ns == NULL) {
7001 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7002 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
7003 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
7004 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7005 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7006 xmlSchemaPIllegalAttrErr(ctxt,
7008 }
7009 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7010 xmlSchemaPIllegalAttrErr(ctxt,
7012 }
7013 attr = attr->next;
7014 }
7015 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7016 /*
7017 * minOccurs/maxOccurs.
7018 */
7019 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
7020 "(xs:nonNegativeInteger | unbounded)");
7021 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
7022 "xs:nonNegativeInteger");
7023 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
7024 /*
7025 * Create & parse the wildcard.
7026 */
7027 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
7028 if (wild == NULL)
7029 return (NULL);
7030 xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
7031 /*
7032 * And now for the children...
7033 */
7034 child = node->children;
7035 if (IS_SCHEMA(child, "annotation")) {
7036 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7037 child = child->next;
7038 }
7039 if (child != NULL) {
7040 xmlSchemaPContentErr(ctxt,
7042 NULL, node, child,
7043 NULL, "(annotation?)");
7044 }
7045 /*
7046 * No component if minOccurs==maxOccurs==0.
7047 */
7048 if ((min == 0) && (max == 0)) {
7049 /* Don't free the wildcard, since it's already on the list. */
7050 return (NULL);
7051 }
7052 /*
7053 * Create the particle.
7054 */
7055 particle = xmlSchemaAddParticle(ctxt, node, min, max);
7056 if (particle == NULL)
7057 return (NULL);
7058 particle->annot = annot;
7059 particle->children = (xmlSchemaTreeItemPtr) wild;
7060
7061 return (particle);
7062}
7063
7074static xmlSchemaNotationPtr
7075xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
7077{
7078 const xmlChar *name;
7079 xmlSchemaNotationPtr ret;
7081
7082 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7083 return (NULL);
7084 name = xmlSchemaGetProp(ctxt, node, "name");
7085 if (name == NULL) {
7086 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
7087 "Notation has no name\n", NULL, NULL);
7088 return (NULL);
7089 }
7090 ret = xmlSchemaAddNotation(ctxt, schema, name,
7091 ctxt->targetNamespace, node);
7092 if (ret == NULL)
7093 return (NULL);
7094 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
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,
7104 NULL, node, child,
7105 NULL, "(annotation?)");
7106 }
7107
7108 return (ret);
7109}
7110
7122static xmlSchemaWildcardPtr
7123xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7124 xmlSchemaPtr schema, xmlNodePtr node)
7125{
7126 xmlSchemaWildcardPtr ret;
7129
7130 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7131 return (NULL);
7132
7133 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7134 node);
7135 if (ret == NULL) {
7136 return (NULL);
7137 }
7138 /*
7139 * Check for illegal attributes.
7140 */
7141 attr = node->properties;
7142 while (attr != NULL) {
7143 if (attr->ns == NULL) {
7144 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7145 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7146 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7147 xmlSchemaPIllegalAttrErr(ctxt,
7149 }
7150 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7151 xmlSchemaPIllegalAttrErr(ctxt,
7153 }
7154 attr = attr->next;
7155 }
7156 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7157 /*
7158 * Parse the namespace list.
7159 */
7160 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7161 return (NULL);
7162 /*
7163 * And now for the children...
7164 */
7165 child = node->children;
7166 if (IS_SCHEMA(child, "annotation")) {
7167 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7168 child = child->next;
7169 }
7170 if (child != NULL) {
7171 xmlSchemaPContentErr(ctxt,
7173 NULL, node, child,
7174 NULL, "(annotation?)");
7175 }
7176
7177 return (ret);
7178}
7179
7180
7192static xmlSchemaBasicItemPtr
7193xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7194 xmlSchemaPtr schema,
7196 xmlSchemaItemListPtr uses,
7197 int parentType)
7198{
7199 const xmlChar *attrValue, *name = NULL, *ns = NULL;
7200 xmlSchemaAttributeUsePtr use = NULL;
7203 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7204 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7205 int nberrors, hasForm = 0, defValueType = 0;
7206
7207#define WXS_ATTR_DEF_VAL_DEFAULT 1
7208#define WXS_ATTR_DEF_VAL_FIXED 2
7209
7210 /*
7211 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7212 */
7213
7214 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7215 return (NULL);
7216 attr = xmlSchemaGetPropNode(node, "ref");
7217 if (attr != NULL) {
7218 if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7219 NULL, attr, &tmpNs, &tmpName) != 0) {
7220 return (NULL);
7221 }
7222 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7223 return(NULL);
7224 isRef = 1;
7225 }
7226 nberrors = pctxt->nberrors;
7227 /*
7228 * Check for illegal attributes.
7229 */
7230 attr = node->properties;
7231 while (attr != NULL) {
7232 if (attr->ns == NULL) {
7233 if (isRef) {
7234 if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7235 xmlSchemaPValAttrNodeID(pctxt, attr);
7236 goto attr_next;
7237 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7238 goto attr_next;
7239 }
7240 } else {
7241 if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7242 goto attr_next;
7243 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7244 xmlSchemaPValAttrNodeID(pctxt, attr);
7245 goto attr_next;
7246 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7247 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7248 attr, &tmpNs, &tmpName);
7249 goto attr_next;
7250 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7251 /*
7252 * Evaluate the target namespace
7253 */
7254 hasForm = 1;
7255 attrValue = xmlSchemaGetNodeContent(pctxt,
7256 (xmlNodePtr) attr);
7257 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7258 ns = pctxt->targetNamespace;
7259 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7260 {
7261 xmlSchemaPSimpleTypeErr(pctxt,
7263 NULL, (xmlNodePtr) attr,
7264 NULL, "(qualified | unqualified)",
7265 attrValue, NULL, NULL, NULL);
7266 }
7267 goto attr_next;
7268 }
7269 }
7270 if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7271
7272 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7273 /* TODO: Maybe we need to normalize the value beforehand. */
7274 if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7275 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7276 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7277 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7278 else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7279 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7280 else {
7281 xmlSchemaPSimpleTypeErr(pctxt,
7283 NULL, (xmlNodePtr) attr,
7284 NULL, "(optional | prohibited | required)",
7285 attrValue, NULL, NULL, NULL);
7286 }
7287 goto attr_next;
7288 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7289 /*
7290 * 3.2.3 : 1
7291 * default and fixed must not both be present.
7292 */
7293 if (defValue) {
7294 xmlSchemaPMutualExclAttrErr(pctxt,
7296 NULL, attr, "default", "fixed");
7297 } else {
7298 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7299 defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7300 }
7301 goto attr_next;
7302 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7303 /*
7304 * 3.2.3 : 1
7305 * default and fixed must not both be present.
7306 */
7307 if (defValue) {
7308 xmlSchemaPMutualExclAttrErr(pctxt,
7310 NULL, attr, "default", "fixed");
7311 } else {
7312 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7313 defValueType = WXS_ATTR_DEF_VAL_FIXED;
7314 }
7315 goto attr_next;
7316 }
7317 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7318 goto attr_next;
7319
7320 xmlSchemaPIllegalAttrErr(pctxt,
7322
7323attr_next:
7324 attr = attr->next;
7325 }
7326 /*
7327 * 3.2.3 : 2
7328 * If default and use are both present, use must have
7329 * the actual value optional.
7330 */
7331 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7332 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7333 xmlSchemaPSimpleTypeErr(pctxt,
7335 NULL, node, NULL,
7336 "(optional | prohibited | required)", NULL,
7337 "The value of the attribute 'use' must be 'optional' "
7338 "if the attribute 'default' is present",
7339 NULL, NULL);
7340 }
7341 /*
7342 * We want correct attributes.
7343 */
7344 if (nberrors != pctxt->nberrors)
7345 return(NULL);
7346 if (! isRef) {
7347 xmlSchemaAttributePtr attrDecl;
7348
7349 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7350 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7351 ns = pctxt->targetNamespace;
7352 /*
7353 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7354 * TODO: Move this to the component layer.
7355 */
7356 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7357 xmlSchemaCustomErr(ACTXT_CAST pctxt,
7359 node, NULL,
7360 "The target namespace must not match '%s'",
7361 xmlSchemaInstanceNs, NULL);
7362 }
7363 attr = xmlSchemaGetPropNode(node, "name");
7364 if (attr == NULL) {
7365 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7366 NULL, node, "name", NULL);
7367 return (NULL);
7368 }
7369 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7370 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7371 return (NULL);
7372 }
7373 /*
7374 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7375 * TODO: Move this to the component layer.
7376 */
7377 if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7378 xmlSchemaPSimpleTypeErr(pctxt,
7380 NULL, (xmlNodePtr) attr,
7381 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7382 "The value of the attribute must not match 'xmlns'",
7383 NULL, NULL);
7384 return (NULL);
7385 }
7386 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7387 goto check_children;
7388 /*
7389 * Create the attribute use component.
7390 */
7391 use = xmlSchemaAddAttributeUse(pctxt, node);
7392 if (use == NULL)
7393 return(NULL);
7394 use->occurs = occurs;
7395 /*
7396 * Create the attribute declaration.
7397 */
7398 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7399 if (attrDecl == NULL)
7400 return (NULL);
7401 if (tmpName != NULL) {
7402 attrDecl->typeName = tmpName;
7403 attrDecl->typeNs = tmpNs;
7404 }
7405 use->attrDecl = attrDecl;
7406 /*
7407 * Value constraint.
7408 */
7409 if (defValue != NULL) {
7410 attrDecl->defValue = defValue;
7411 if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7412 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7413 }
7414 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7415 xmlSchemaQNameRefPtr ref;
7416
7417 /*
7418 * Create the attribute use component.
7419 */
7420 use = xmlSchemaAddAttributeUse(pctxt, node);
7421 if (use == NULL)
7422 return(NULL);
7423 /*
7424 * We need to resolve the reference at later stage.
7425 */
7426 WXS_ADD_PENDING(pctxt, use);
7427 use->occurs = occurs;
7428 /*
7429 * Create a QName reference to the attribute declaration.
7430 */
7431 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7432 tmpName, tmpNs);
7433 if (ref == NULL)
7434 return(NULL);
7435 /*
7436 * Assign the reference. This will be substituted for the
7437 * referenced attribute declaration when the QName is resolved.
7438 */
7439 use->attrDecl = WXS_ATTR_CAST ref;
7440 /*
7441 * Value constraint.
7442 */
7443 if (defValue != NULL)
7444 use->defValue = defValue;
7445 if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7446 use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7447 }
7448
7449check_children:
7450 /*
7451 * And now for the children...
7452 */
7453 child = node->children;
7454 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7455 xmlSchemaAttributeUseProhibPtr prohib;
7456
7457 if (IS_SCHEMA(child, "annotation")) {
7458 xmlSchemaParseAnnotation(pctxt, child, 0);
7459 child = child->next;
7460 }
7461 if (child != NULL) {
7462 xmlSchemaPContentErr(pctxt,
7464 NULL, node, child, NULL,
7465 "(annotation?)");
7466 }
7467 /*
7468 * Check for pointlessness of attribute prohibitions.
7469 */
7470 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7471 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7473 node, NULL,
7474 "Skipping attribute use prohibition, since it is "
7475 "pointless inside an <attributeGroup>",
7476 NULL, NULL, NULL);
7477 return(NULL);
7478 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7479 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7481 node, NULL,
7482 "Skipping attribute use prohibition, since it is "
7483 "pointless when extending a type",
7484 NULL, NULL, NULL);
7485 return(NULL);
7486 }
7487 if (! isRef) {
7488 tmpName = name;
7489 tmpNs = ns;
7490 }
7491 /*
7492 * Check for duplicate attribute prohibitions.
7493 */
7494 if (uses) {
7495 int i;
7496
7497 for (i = 0; i < uses->nbItems; i++) {
7498 use = uses->items[i];
7499 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7500 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7501 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7502 {
7503 xmlChar *str = NULL;
7504
7505 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7507 node, NULL,
7508 "Skipping duplicate attribute use prohibition '%s'",
7509 xmlSchemaFormatQName(&str, tmpNs, tmpName),
7510 NULL, NULL);
7511 FREE_AND_NULL(str)
7512 return(NULL);
7513 }
7514 }
7515 }
7516 /*
7517 * Create the attribute prohibition helper component.
7518 */
7519 prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7520 if (prohib == NULL)
7521 return(NULL);
7522 prohib->node = node;
7523 prohib->name = tmpName;
7524 prohib->targetNamespace = tmpNs;
7525 if (isRef) {
7526 /*
7527 * We need at least to resolve to the attribute declaration.
7528 */
7529 WXS_ADD_PENDING(pctxt, prohib);
7530 }
7531 return(WXS_BASIC_CAST prohib);
7532 } else {
7533 if (IS_SCHEMA(child, "annotation")) {
7534 /*
7535 * TODO: Should this go into the attr decl?
7536 */
7537 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7538 child = child->next;
7539 }
7540 if (isRef) {
7541 if (child != NULL) {
7542 if (IS_SCHEMA(child, "simpleType"))
7543 /*
7544 * 3.2.3 : 3.2
7545 * If ref is present, then all of <simpleType>,
7546 * form and type must be absent.
7547 */
7548 xmlSchemaPContentErr(pctxt,
7550 NULL, node, child, NULL,
7551 "(annotation?)");
7552 else
7553 xmlSchemaPContentErr(pctxt,
7555 NULL, node, child, NULL,
7556 "(annotation?)");
7557 }
7558 } else {
7559 if (IS_SCHEMA(child, "simpleType")) {
7560 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7561 /*
7562 * 3.2.3 : 4
7563 * type and <simpleType> must not both be present.
7564 */
7565 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7566 NULL, node, child,
7567 "The attribute 'type' and the <simpleType> child "
7568 "are mutually exclusive", NULL);
7569 } else
7570 WXS_ATTRUSE_TYPEDEF(use) =
7571 xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7572 child = child->next;
7573 }
7574 if (child != NULL)
7575 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7576 NULL, node, child, NULL,
7577 "(annotation?, simpleType?)");
7578 }
7579 }
7580 return (WXS_BASIC_CAST use);
7581}
7582
7583
7584static xmlSchemaAttributePtr
7585xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7586 xmlSchemaPtr schema,
7588{
7589 const xmlChar *attrValue;
7590 xmlSchemaAttributePtr ret;
7593
7594 /*
7595 * Note that the w3c spec assumes the schema to be validated with schema
7596 * for schemas beforehand.
7597 *
7598 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7599 */
7600 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7601 return (NULL);
7602 /*
7603 * 3.2.3 : 3.1
7604 * One of ref or name must be present, but not both
7605 */
7606 attr = xmlSchemaGetPropNode(node, "name");
7607 if (attr == NULL) {
7608 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7609 NULL, node, "name", NULL);
7610 return (NULL);
7611 }
7612 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7613 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7614 return (NULL);
7615 }
7616 /*
7617 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7618 * TODO: Move this to the component layer.
7619 */
7620 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7621 xmlSchemaPSimpleTypeErr(pctxt,
7623 NULL, (xmlNodePtr) attr,
7624 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7625 "The value of the attribute must not match 'xmlns'",
7626 NULL, NULL);
7627 return (NULL);
7628 }
7629 /*
7630 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7631 * TODO: Move this to the component layer.
7632 * Or better leave it here and add it to the component layer
7633 * if we have a schema construction API.
7634 */
7635 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7636 xmlSchemaCustomErr(ACTXT_CAST pctxt,
7638 "The target namespace must not match '%s'",
7639 xmlSchemaInstanceNs, NULL);
7640 }
7641
7642 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7643 pctxt->targetNamespace, node, 1);
7644 if (ret == NULL)
7645 return (NULL);
7646 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7647
7648 /*
7649 * Check for illegal attributes.
7650 */
7651 attr = node->properties;
7652 while (attr != NULL) {
7653 if (attr->ns == NULL) {
7654 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7655 (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7656 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7657 (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7658 (!xmlStrEqual(attr->name, BAD_CAST "type")))
7659 {
7660 xmlSchemaPIllegalAttrErr(pctxt,
7662 }
7663 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7664 xmlSchemaPIllegalAttrErr(pctxt,
7666 }
7667 attr = attr->next;
7668 }
7669 xmlSchemaPValAttrQName(pctxt, schema, NULL,
7670 node, "type", &ret->typeNs, &ret->typeName);
7671
7672 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7673 /*
7674 * Attribute "fixed".
7675 */
7676 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7677 if (ret->defValue != NULL)
7678 ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7679 /*
7680 * Attribute "default".
7681 */
7682 attr = xmlSchemaGetPropNode(node, "default");
7683 if (attr != NULL) {
7684 /*
7685 * 3.2.3 : 1
7686 * default and fixed must not both be present.
7687 */
7688 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7689 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7690 WXS_BASIC_CAST ret, attr, "default", "fixed");
7691 } else
7692 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7693 }
7694 /*
7695 * And now for the children...
7696 */
7697 child = node->children;
7698 if (IS_SCHEMA(child, "annotation")) {
7699 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7700 child = child->next;
7701 }
7702 if (IS_SCHEMA(child, "simpleType")) {
7703 if (ret->typeName != NULL) {
7704 /*
7705 * 3.2.3 : 4
7706 * type and <simpleType> must not both be present.
7707 */
7708 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7709 NULL, node, child,
7710 "The attribute 'type' and the <simpleType> child "
7711 "are mutually exclusive", NULL);
7712 } else
7713 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7714 child = child->next;
7715 }
7716 if (child != NULL)
7717 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7718 NULL, node, child, NULL,
7719 "(annotation?, simpleType?)");
7720
7721 return (ret);
7722}
7723
7737static xmlSchemaQNameRefPtr
7738xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7739 xmlSchemaPtr schema,
7741{
7742 xmlSchemaQNameRefPtr ret;
7745 const xmlChar *refNs = NULL, *ref = NULL;
7746
7747 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7748 return (NULL);
7749
7750 attr = xmlSchemaGetPropNode(node, "ref");
7751 if (attr == NULL) {
7752 xmlSchemaPMissingAttrErr(pctxt,
7754 NULL, node, "ref", NULL);
7755 return (NULL);
7756 }
7757 xmlSchemaPValAttrNodeQName(pctxt, schema,
7758 NULL, attr, &refNs, &ref);
7759 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7760 return(NULL);
7761
7762 /*
7763 * Check for illegal attributes.
7764 */
7765 attr = node->properties;
7766 while (attr != NULL) {
7767 if (attr->ns == NULL) {
7768 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7769 (!xmlStrEqual(attr->name, BAD_CAST "id")))
7770 {
7771 xmlSchemaPIllegalAttrErr(pctxt,
7773 }
7774 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7775 xmlSchemaPIllegalAttrErr(pctxt,
7777 }
7778 attr = attr->next;
7779 }
7780 /* Attribute ID */
7781 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7782
7783 /*
7784 * And now for the children...
7785 */
7786 child = node->children;
7787 if (IS_SCHEMA(child, "annotation")) {
7788 /*
7789 * TODO: We do not have a place to store the annotation, do we?
7790 */
7791 xmlSchemaParseAnnotation(pctxt, child, 0);
7792 child = child->next;
7793 }
7794 if (child != NULL) {
7795 xmlSchemaPContentErr(pctxt,
7797 NULL, node, child, NULL,
7798 "(annotation?)");
7799 }
7800
7801 /*
7802 * Handle attribute group redefinitions.
7803 */
7804 if (pctxt->isRedefine && pctxt->redef &&
7805 (pctxt->redef->item->type ==
7806 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7807 (ref == pctxt->redef->refName) &&
7808 (refNs == pctxt->redef->refTargetNs))
7809 {
7810 /*
7811 * SPEC src-redefine:
7812 * (7.1) "If it has an <attributeGroup> among its contents
7813 * the `actual value` of whose ref [attribute] is the same
7814 * as the `actual value` of its own name attribute plus
7815 * target namespace, then it must have exactly one such group."
7816 */
7817 if (pctxt->redefCounter != 0) {
7818 xmlChar *str = NULL;
7819
7820 xmlSchemaCustomErr(ACTXT_CAST pctxt,
7822 "The redefining attribute group definition "
7823 "'%s' must not contain more than one "
7824 "reference to the redefined definition",
7825 xmlSchemaFormatQName(&str, refNs, ref), NULL);
7826 FREE_AND_NULL(str);
7827 return(NULL);
7828 }
7829 pctxt->redefCounter++;
7830 /*
7831 * URGENT TODO: How to ensure that the reference will not be
7832 * handled by the normal component resolution mechanism?
7833 */
7834 ret = xmlSchemaNewQNameRef(pctxt,
7835 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7836 if (ret == NULL)
7837 return(NULL);
7838 ret->node = node;
7839 pctxt->redef->reference = WXS_BASIC_CAST ret;
7840 } else {
7841 /*
7842 * Create a QName-reference helper component. We will substitute this
7843 * component for the attribute uses of the referenced attribute group
7844 * definition.
7845 */
7846 ret = xmlSchemaNewQNameRef(pctxt,
7847 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7848 if (ret == NULL)
7849 return(NULL);
7850 ret->node = node;
7851 /* Add to pending items, to be able to resolve the reference. */
7852 WXS_ADD_PENDING(pctxt, ret);
7853 }
7854 return (ret);
7855}
7856
7868static xmlSchemaAttributeGroupPtr
7869xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7870 xmlSchemaPtr schema,
7872{
7873 const xmlChar *name;
7874 xmlSchemaAttributeGroupPtr ret;
7877 int hasRefs = 0;
7878
7879 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7880 return (NULL);
7881
7882 attr = xmlSchemaGetPropNode(node, "name");
7883 if (attr == NULL) {
7884 xmlSchemaPMissingAttrErr(pctxt,
7886 NULL, node, "name", NULL);
7887 return (NULL);
7888 }
7889 /*
7890 * The name is crucial, exit if invalid.
7891 */
7892 if (xmlSchemaPValAttrNode(pctxt,
7893 NULL, attr,
7894 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7895 return (NULL);
7896 }
7897 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7898 name, pctxt->targetNamespace, node);
7899 if (ret == NULL)
7900 return (NULL);
7901 /*
7902 * Check for illegal attributes.
7903 */
7904 attr = node->properties;
7905 while (attr != NULL) {
7906 if (attr->ns == NULL) {
7907 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7908 (!xmlStrEqual(attr->name, BAD_CAST "id")))
7909 {
7910 xmlSchemaPIllegalAttrErr(pctxt,
7912 }
7913 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7914 xmlSchemaPIllegalAttrErr(pctxt,
7916 }
7917 attr = attr->next;
7918 }
7919 /* Attribute ID */
7920 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7921 /*
7922 * And now for the children...
7923 */
7924 child = node->children;
7925 if (IS_SCHEMA(child, "annotation")) {
7926 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7927 child = child->next;
7928 }
7929 /*
7930 * Parse contained attribute decls/refs.
7931 */
7932 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7933 (xmlSchemaItemListPtr *) &(ret->attrUses),
7934 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7935 return(NULL);
7936 if (hasRefs)
7937 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7938 /*
7939 * Parse the attribute wildcard.
7940 */
7941 if (IS_SCHEMA(child, "anyAttribute")) {
7942 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7943 schema, child);
7944 child = child->next;
7945 }
7946 if (child != NULL) {
7947 xmlSchemaPContentErr(pctxt,
7949 NULL, node, child, NULL,
7950 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7951 }
7952 return (ret);
7953}
7954
7963static int
7964xmlSchemaPValAttrFormDefault(const xmlChar *value,
7965 int *flags,
7966 int flagQualified)
7967{
7968 if (xmlStrEqual(value, BAD_CAST "qualified")) {
7969 if ((*flags & flagQualified) == 0)
7970 *flags |= flagQualified;
7971 } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7972 return (1);
7973
7974 return (0);
7975}
7976
7994static int
7995xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7996 int *flags,
7997 int flagAll,
7998 int flagExtension,
7999 int flagRestriction,
8000 int flagSubstitution,
8001 int flagList,
8002 int flagUnion)
8003{
8004 int ret = 0;
8005
8006 /*
8007 * TODO: This does not check for duplicate entries.
8008 */
8009 if ((flags == NULL) || (value == NULL))
8010 return (-1);
8011 if (value[0] == 0)
8012 return (0);
8013 if (xmlStrEqual(value, BAD_CAST "#all")) {
8014 if (flagAll != -1)
8015 *flags |= flagAll;
8016 else {
8017 if (flagExtension != -1)
8018 *flags |= flagExtension;
8019 if (flagRestriction != -1)
8020 *flags |= flagRestriction;
8021 if (flagSubstitution != -1)
8022 *flags |= flagSubstitution;
8023 if (flagList != -1)
8024 *flags |= flagList;
8025 if (flagUnion != -1)
8026 *flags |= flagUnion;
8027 }
8028 } else {
8029 const xmlChar *end, *cur = value;
8030 xmlChar *item;
8031
8032 do {
8033 while (IS_BLANK_CH(*cur))
8034 cur++;
8035 end = cur;
8036 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8037 end++;
8038 if (end == cur)
8039 break;
8040 item = xmlStrndup(cur, end - cur);
8041 if (xmlStrEqual(item, BAD_CAST "extension")) {
8042 if (flagExtension != -1) {
8043 if ((*flags & flagExtension) == 0)
8044 *flags |= flagExtension;
8045 } else
8046 ret = 1;
8047 } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
8048 if (flagRestriction != -1) {
8049 if ((*flags & flagRestriction) == 0)
8050 *flags |= flagRestriction;
8051 } else
8052 ret = 1;
8053 } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
8054 if (flagSubstitution != -1) {
8055 if ((*flags & flagSubstitution) == 0)
8056 *flags |= flagSubstitution;
8057 } else
8058 ret = 1;
8059 } else if (xmlStrEqual(item, BAD_CAST "list")) {
8060 if (flagList != -1) {
8061 if ((*flags & flagList) == 0)
8062 *flags |= flagList;
8063 } else
8064 ret = 1;
8065 } else if (xmlStrEqual(item, BAD_CAST "union")) {
8066 if (flagUnion != -1) {
8067 if ((*flags & flagUnion) == 0)
8068 *flags |= flagUnion;
8069 } else
8070 ret = 1;
8071 } else
8072 ret = 1;
8073 if (item != NULL)
8074 xmlFree(item);
8075 cur = end;
8076 } while ((ret == 0) && (*cur != 0));
8077 }
8078
8079 return (ret);
8080}
8081
8082static int
8083xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
8084 xmlSchemaIDCPtr idc,
8085 xmlSchemaIDCSelectPtr selector,
8087 int isField)
8088{
8090
8091 /*
8092 * c-selector-xpath:
8093 * Schema Component Constraint: Selector Value OK
8094 *
8095 * TODO: 1 The {selector} must be a valid XPath expression, as defined
8096 * in [XPath].
8097 */
8098 if (selector == NULL) {
8099 xmlSchemaPErr(ctxt, idc->node,
8101 "Internal error: xmlSchemaCheckCSelectorXPath, "
8102 "the selector is not specified.\n", NULL, NULL);
8103 return (-1);
8104 }
8105 if (attr == NULL)
8106 node = idc->node;
8107 else
8108 node = (xmlNodePtr) attr;
8109 if (selector->xpath == NULL) {
8110 xmlSchemaPCustomErr(ctxt,
8111 /* TODO: Adjust error code. */
8113 NULL, node,
8114 "The XPath expression of the selector is not valid", NULL);
8116 } else {
8117 const xmlChar **nsArray = NULL;
8118 xmlNsPtr *nsList = NULL;
8119 /*
8120 * Compile the XPath expression.
8121 */
8122 /*
8123 * TODO: We need the array of in-scope namespaces for compilation.
8124 * TODO: Call xmlPatterncompile with different options for selector/
8125 * field.
8126 */
8127 if (attr == NULL)
8128 nsList = NULL;
8129 else
8130 nsList = xmlGetNsList(attr->doc, attr->parent);
8131 /*
8132 * Build an array of prefixes and namespaces.
8133 */
8134 if (nsList != NULL) {
8135 int i, count = 0;
8136
8137 for (i = 0; nsList[i] != NULL; i++)
8138 count++;
8139
8140 nsArray = (const xmlChar **) xmlMalloc(
8141 (count * 2 + 1) * sizeof(const xmlChar *));
8142 if (nsArray == NULL) {
8143 xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
8144 NULL);
8145 xmlFree(nsList);
8146 return (-1);
8147 }
8148 for (i = 0; i < count; i++) {
8149 nsArray[2 * i] = nsList[i]->href;
8150 nsArray[2 * i + 1] = nsList[i]->prefix;
8151 }
8152 nsArray[count * 2] = NULL;
8153 xmlFree(nsList);
8154 }
8155 /*
8156 * TODO: Differentiate between "selector" and "field".
8157 */
8158 if (isField)
8159 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8160 NULL, XML_PATTERN_XSFIELD, nsArray);
8161 else
8162 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8163 NULL, XML_PATTERN_XSSEL, nsArray);
8164 if (nsArray != NULL)
8165 xmlFree((xmlChar **) nsArray);
8166
8167 if (selector->xpathComp == NULL) {
8168 xmlSchemaPCustomErr(ctxt,
8169 /* TODO: Adjust error code? */
8171 NULL, node,
8172 "The XPath expression '%s' could not be "
8173 "compiled", selector->xpath);
8175 }
8176 }
8177 return (0);
8178}
8179
8180#define ADD_ANNOTATION(annot) \
8181 xmlSchemaAnnotPtr cur = item->annot; \
8182 if (item->annot == NULL) { \
8183 item->annot = annot; \
8184 return (annot); \
8185 } \
8186 cur = item->annot; \
8187 if (cur->next != NULL) { \
8188 cur = cur->next; \
8189 } \
8190 cur->next = annot;
8191
8201static xmlSchemaAnnotPtr
8202xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8203 xmlSchemaAnnotPtr annot)
8204{
8205 if ((annItem == NULL) || (annot == NULL))
8206 return (NULL);
8207 switch (annItem->type) {
8208 case XML_SCHEMA_TYPE_ELEMENT: {
8209 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8210 ADD_ANNOTATION(annot)
8211 }
8212 break;
8213 case XML_SCHEMA_TYPE_ATTRIBUTE: {
8214 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8215 ADD_ANNOTATION(annot)
8216 }
8217 break;
8218 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8219 case XML_SCHEMA_TYPE_ANY: {
8220 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8221 ADD_ANNOTATION(annot)
8222 }
8223 break;
8224 case XML_SCHEMA_TYPE_PARTICLE:
8225 case XML_SCHEMA_TYPE_IDC_KEY:
8226 case XML_SCHEMA_TYPE_IDC_KEYREF:
8227 case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8228 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8229 ADD_ANNOTATION(annot)
8230 }
8231 break;
8232 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8233 xmlSchemaAttributeGroupPtr item =
8234 (xmlSchemaAttributeGroupPtr) annItem;
8235 ADD_ANNOTATION(annot)
8236 }
8237 break;
8238 case XML_SCHEMA_TYPE_NOTATION: {
8239 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8240 ADD_ANNOTATION(annot)
8241 }
8242 break;
8243 case XML_SCHEMA_FACET_MININCLUSIVE:
8244 case XML_SCHEMA_FACET_MINEXCLUSIVE:
8245 case XML_SCHEMA_FACET_MAXINCLUSIVE:
8246 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8247 case XML_SCHEMA_FACET_TOTALDIGITS:
8248 case XML_SCHEMA_FACET_FRACTIONDIGITS:
8249 case XML_SCHEMA_FACET_PATTERN:
8250 case XML_SCHEMA_FACET_ENUMERATION:
8251 case XML_SCHEMA_FACET_WHITESPACE:
8252 case XML_SCHEMA_FACET_LENGTH:
8253 case XML_SCHEMA_FACET_MAXLENGTH:
8254 case XML_SCHEMA_FACET_MINLENGTH: {
8255 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8256 ADD_ANNOTATION(annot)
8257 }
8258 break;
8259 case XML_SCHEMA_TYPE_SIMPLE:
8260 case XML_SCHEMA_TYPE_COMPLEX: {
8261 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8262 ADD_ANNOTATION(annot)
8263 }
8264 break;
8265 case XML_SCHEMA_TYPE_GROUP: {
8266 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8267 ADD_ANNOTATION(annot)
8268 }
8269 break;
8270 case XML_SCHEMA_TYPE_SEQUENCE:
8271 case XML_SCHEMA_TYPE_CHOICE:
8272 case XML_SCHEMA_TYPE_ALL: {
8273 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8274 ADD_ANNOTATION(annot)
8275 }
8276 break;
8277 default:
8278 xmlSchemaPCustomErr(NULL,
8280 NULL, NULL,
8281 "Internal error: xmlSchemaAddAnnotation, "
8282 "The item is not a annotated schema component", NULL);
8283 break;
8284 }
8285 return (annot);
8286}
8287
8299static xmlSchemaIDCSelectPtr
8300xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8301 xmlSchemaIDCPtr idc,
8303 int isField)
8304{
8305 xmlSchemaIDCSelectPtr item;
8308
8309 /*
8310 * Check for illegal attributes.
8311 */
8312 attr = node->properties;
8313 while (attr != NULL) {
8314 if (attr->ns == NULL) {
8315 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8316 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8317 xmlSchemaPIllegalAttrErr(ctxt,
8319 }
8320 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8321 xmlSchemaPIllegalAttrErr(ctxt,
8323 }
8324 attr = attr->next;
8325 }
8326 /*
8327 * Create the item.
8328 */
8329 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8330 if (item == NULL) {
8331 xmlSchemaPErrMemory(ctxt,
8332 "allocating a 'selector' of an identity-constraint definition",
8333 NULL);
8334 return (NULL);
8335 }
8336 memset(item, 0, sizeof(xmlSchemaIDCSelect));
8337 /*
8338 * Attribute "xpath" (mandatory).
8339 */
8340 attr = xmlSchemaGetPropNode(node, "xpath");
8341 if (attr == NULL) {
8342 xmlSchemaPMissingAttrErr(ctxt,
8344 NULL, node,
8345 "name", NULL);
8346 } else {
8347 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8348 /*
8349 * URGENT TODO: "field"s have an other syntax than "selector"s.
8350 */
8351
8352 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8353 isField) == -1) {
8354 xmlSchemaPErr(ctxt,
8355 (xmlNodePtr) attr,
8357 "Internal error: xmlSchemaParseIDCSelectorAndField, "
8358 "validating the XPath expression of a IDC selector.\n",
8359 NULL, NULL);
8360 }
8361
8362 }
8363 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8364 /*
8365 * And now for the children...
8366 */
8367 child = node->children;
8368 if (IS_SCHEMA(child, "annotation")) {
8369 /*
8370 * Add the annotation to the parent IDC.
8371 */
8372 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8373 xmlSchemaParseAnnotation(ctxt, child, 1));
8374 child = child->next;
8375 }
8376 if (child != NULL) {
8377 xmlSchemaPContentErr(ctxt,
8379 NULL, node, child,
8380 NULL, "(annotation?)");
8381 }
8382
8383 return (item);
8384}
8385
8396static xmlSchemaIDCPtr
8397xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8398 xmlSchemaPtr schema,
8400 xmlSchemaTypeType idcCategory,
8401 const xmlChar *targetNamespace)
8402{
8403 xmlSchemaIDCPtr item = NULL;
8406 const xmlChar *name = NULL;
8407 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8408
8409 /*
8410 * Check for illegal attributes.
8411 */
8412 attr = node->properties;
8413 while (attr != NULL) {
8414 if (attr->ns == NULL) {
8415 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8416 (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8417 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8418 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8419 xmlSchemaPIllegalAttrErr(ctxt,
8421 }
8422 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8423 xmlSchemaPIllegalAttrErr(ctxt,
8425 }
8426 attr = attr->next;
8427 }
8428 /*
8429 * Attribute "name" (mandatory).
8430 */
8431 attr = xmlSchemaGetPropNode(node, "name");
8432 if (attr == NULL) {
8433 xmlSchemaPMissingAttrErr(ctxt,
8435 NULL, node,
8436 "name", NULL);
8437 return (NULL);
8438 } else if (xmlSchemaPValAttrNode(ctxt,
8439 NULL, attr,
8440 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8441 return (NULL);
8442 }
8443 /* Create the component. */
8444 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8445 idcCategory, node);
8446 if (item == NULL)
8447 return(NULL);
8448
8449 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8450 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8451 /*
8452 * Attribute "refer" (mandatory).
8453 */
8454 attr = xmlSchemaGetPropNode(node, "refer");
8455 if (attr == NULL) {
8456 xmlSchemaPMissingAttrErr(ctxt,
8458 NULL, node,
8459 "refer", NULL);
8460 } else {
8461 /*
8462 * Create a reference item.
8463 */
8464 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8465 NULL, NULL);
8466 if (item->ref == NULL)
8467 return (NULL);
8468 xmlSchemaPValAttrNodeQName(ctxt, schema,
8469 NULL, attr,
8470 &(item->ref->targetNamespace),
8471 &(item->ref->name));
8472 xmlSchemaCheckReference(ctxt, schema, node, attr,
8473 item->ref->targetNamespace);
8474 }
8475 }
8476 /*
8477 * And now for the children...
8478 */
8479 child = node->children;
8480 if (IS_SCHEMA(child, "annotation")) {
8481 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8482 child = child->next;
8483 }
8484 if (child == NULL) {
8485 xmlSchemaPContentErr(ctxt,
8487 NULL, node, child,
8488 "A child element is missing",
8489 "(annotation?, (selector, field+))");
8490 }
8491 /*
8492 * Child element <selector>.
8493 */
8494 if (IS_SCHEMA(child, "selector")) {
8495 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8496 item, child, 0);
8497 child = child->next;
8498 /*
8499 * Child elements <field>.
8500 */
8501 if (IS_SCHEMA(child, "field")) {
8502 do {
8503 field = xmlSchemaParseIDCSelectorAndField(ctxt,
8504 item, child, 1);
8505 if (field != NULL) {
8506 field->index = item->nbFields;
8507 item->nbFields++;
8508 if (lastField != NULL)
8509 lastField->next = field;
8510 else
8511 item->fields = field;
8512 lastField = field;
8513 }
8514 child = child->next;
8515 } while (IS_SCHEMA(child, "field"));
8516 } else {
8517 xmlSchemaPContentErr(ctxt,
8519 NULL, node, child,
8520 NULL, "(annotation?, (selector, field+))");
8521 }
8522 }
8523 if (child != NULL) {
8524 xmlSchemaPContentErr(ctxt,
8526 NULL, node, child,
8527 NULL, "(annotation?, (selector, field+))");
8528 }
8529
8530 return (item);
8531}
8532
8546static xmlSchemaBasicItemPtr
8547xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8548 xmlNodePtr node, int *isElemRef, int topLevel)
8549{
8550 xmlSchemaElementPtr decl = NULL;
8551 xmlSchemaParticlePtr particle = NULL;
8552 xmlSchemaAnnotPtr annot = NULL;
8554 xmlAttrPtr attr, nameAttr;
8555 int min, max, isRef = 0;
8556 xmlChar *des = NULL;
8557
8558 /* 3.3.3 Constraints on XML Representations of Element Declarations */
8559 /* TODO: Complete implementation of 3.3.6 */
8560
8561 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8562 return (NULL);
8563
8564 if (isElemRef != NULL)
8565 *isElemRef = 0;
8566 /*
8567 * If we get a "ref" attribute on a local <element> we will assume it's
8568 * a reference - even if there's a "name" attribute; this seems to be more
8569 * robust.
8570 */
8571 nameAttr = xmlSchemaGetPropNode(node, "name");
8572 attr = xmlSchemaGetPropNode(node, "ref");
8573 if ((topLevel) || (attr == NULL)) {
8574 if (nameAttr == NULL) {
8575 xmlSchemaPMissingAttrErr(ctxt,
8577 NULL, node, "name", NULL);
8578 return (NULL);
8579 }
8580 } else
8581 isRef = 1;
8582
8583 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8584 child = node->children;
8585 if (IS_SCHEMA(child, "annotation")) {
8586 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8587 child = child->next;
8588 }
8589 /*
8590 * Skip particle part if a global declaration.
8591 */
8592 if (topLevel)
8593 goto declaration_part;
8594 /*
8595 * The particle part ==================================================
8596 */
8597 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8598 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8599 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8600 particle = xmlSchemaAddParticle(ctxt, node, min, max);
8601 if (particle == NULL)
8602 goto return_null;
8603
8604 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8605
8606 if (isRef) {
8607 const xmlChar *refNs = NULL, *ref = NULL;
8608 xmlSchemaQNameRefPtr refer = NULL;
8609 /*
8610 * The reference part =============================================
8611 */
8612 if (isElemRef != NULL)
8613 *isElemRef = 1;
8614
8615 xmlSchemaPValAttrNodeQName(ctxt, schema,
8616 NULL, attr, &refNs, &ref);
8617 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8618 /*
8619 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8620 */
8621 if (nameAttr != NULL) {
8622 xmlSchemaPMutualExclAttrErr(ctxt,
8623 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8624 }
8625 /*
8626 * Check for illegal attributes.
8627 */
8628 attr = node->properties;
8629 while (attr != NULL) {
8630 if (attr->ns == NULL) {
8631 if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8632 xmlStrEqual(attr->name, BAD_CAST "name") ||
8633 xmlStrEqual(attr->name, BAD_CAST "id") ||
8634 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8635 xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8636 {
8637 attr = attr->next;
8638 continue;
8639 } else {
8640 /* SPEC (3.3.3 : 2.2) */
8641 xmlSchemaPCustomAttrErr(ctxt,
8643 NULL, NULL, attr,
8644 "Only the attributes 'minOccurs', 'maxOccurs' and "
8645 "'id' are allowed in addition to 'ref'");
8646 break;
8647 }
8648 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8649 xmlSchemaPIllegalAttrErr(ctxt,
8651 }
8652 attr = attr->next;
8653 }
8654 /*
8655 * No children except <annotation> expected.
8656 */
8657 if (child != NULL) {
8658 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8659 NULL, node, child, NULL, "(annotation?)");
8660 }
8661 if ((min == 0) && (max == 0))
8662 goto return_null;
8663 /*
8664 * Create the reference item and attach it to the particle.
8665 */
8666 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8667 ref, refNs);
8668 if (refer == NULL)
8669 goto return_null;
8670 particle->children = (xmlSchemaTreeItemPtr) refer;
8671 particle->annot = annot;
8672 /*
8673 * Add the particle to pending components, since the reference
8674 * need to be resolved.
8675 */
8676 WXS_ADD_PENDING(ctxt, particle);
8677 return ((xmlSchemaBasicItemPtr) particle);
8678 }
8679 /*
8680 * The declaration part ===============================================
8681 */
8682declaration_part:
8683 {
8684 const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8685 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8686
8687 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8688 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8689 goto return_null;
8690 /*
8691 * Evaluate the target namespace.
8692 */
8693 if (topLevel) {
8694 ns = ctxt->targetNamespace;
8695 } else {
8696 attr = xmlSchemaGetPropNode(node, "form");
8697 if (attr != NULL) {
8698 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8699 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8700 ns = ctxt->targetNamespace;
8701 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8702 xmlSchemaPSimpleTypeErr(ctxt,
8704 NULL, (xmlNodePtr) attr,
8705 NULL, "(qualified | unqualified)",
8706 attrValue, NULL, NULL, NULL);
8707 }
8708 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8709 ns = ctxt->targetNamespace;
8710 }
8711 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8712 if (decl == NULL) {
8713 goto return_null;
8714 }
8715 /*
8716 * Check for illegal attributes.
8717 */
8718 attr = node->properties;
8719 while (attr != NULL) {
8720 if (attr->ns == NULL) {
8721 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8722 (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8723 (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8724 (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8725 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8726 (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8727 (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8728 {
8729 if (topLevel == 0) {
8730 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8731 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8732 (!xmlStrEqual(attr->name, BAD_CAST "form")))
8733 {
8734 xmlSchemaPIllegalAttrErr(ctxt,
8736 }
8737 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8738 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8739 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8740
8741 xmlSchemaPIllegalAttrErr(ctxt,
8743 }
8744 }
8745 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8746
8747 xmlSchemaPIllegalAttrErr(ctxt,
8749 }
8750 attr = attr->next;
8751 }
8752 /*
8753 * Extract/validate attributes.
8754 */
8755 if (topLevel) {
8756 /*
8757 * Process top attributes of global element declarations here.
8758 */
8759 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8760 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8761 xmlSchemaPValAttrQName(ctxt, schema,
8762 NULL, node, "substitutionGroup",
8763 &(decl->substGroupNs), &(decl->substGroup));
8764 if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8765 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8766 /*
8767 * Attribute "final".
8768 */
8769 attr = xmlSchemaGetPropNode(node, "final");
8770 if (attr == NULL) {
8771 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8772 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8773 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8774 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8775 } else {
8776 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8777 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8778 -1,
8779 XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8780 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8781 xmlSchemaPSimpleTypeErr(ctxt,
8783 NULL, (xmlNodePtr) attr,
8784 NULL, "(#all | List of (extension | restriction))",
8785 attrValue, NULL, NULL, NULL);
8786 }
8787 }
8788 }
8789 /*
8790 * Attribute "block".
8791 */
8792 attr = xmlSchemaGetPropNode(node, "block");
8793 if (attr == NULL) {
8794 /*
8795 * Apply default "block" values.
8796 */
8797 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8798 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8799 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8800 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8801 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8802 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8803 } else {
8804 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8805 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8806 -1,
8807 XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8808 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8809 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8810 xmlSchemaPSimpleTypeErr(ctxt,
8812 NULL, (xmlNodePtr) attr,
8813 NULL, "(#all | List of (extension | "
8814 "restriction | substitution))", attrValue,
8815 NULL, NULL, NULL);
8816 }
8817 }
8818 if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8819 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8820
8821 attr = xmlSchemaGetPropNode(node, "type");
8822 if (attr != NULL) {
8823 xmlSchemaPValAttrNodeQName(ctxt, schema,
8824 NULL, attr,
8825 &(decl->namedTypeNs), &(decl->namedType));
8826 xmlSchemaCheckReference(ctxt, schema, node,
8827 attr, decl->namedTypeNs);
8828 }
8829 decl->value = xmlSchemaGetProp(ctxt, node, "default");
8830 attr = xmlSchemaGetPropNode(node, "fixed");
8831 if (attr != NULL) {
8832 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8833 if (decl->value != NULL) {
8834 /*
8835 * 3.3.3 : 1
8836 * default and fixed must not both be present.
8837 */
8838 xmlSchemaPMutualExclAttrErr(ctxt,
8840 NULL, attr, "default", "fixed");
8841 } else {
8842 decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8843 decl->value = fixed;
8844 }
8845 }
8846 /*
8847 * And now for the children...
8848 */
8849 if (IS_SCHEMA(child, "complexType")) {
8850 /*
8851 * 3.3.3 : 3
8852 * "type" and either <simpleType> or <complexType> are mutually
8853 * exclusive
8854 */
8855 if (decl->namedType != NULL) {
8856 xmlSchemaPContentErr(ctxt,
8858 NULL, node, child,
8859 "The attribute 'type' and the <complexType> child are "
8860 "mutually exclusive", NULL);
8861 } else
8862 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8863 child = child->next;
8864 } else if (IS_SCHEMA(child, "simpleType")) {
8865 /*
8866 * 3.3.3 : 3
8867 * "type" and either <simpleType> or <complexType> are
8868 * mutually exclusive
8869 */
8870 if (decl->namedType != NULL) {
8871 xmlSchemaPContentErr(ctxt,
8873 NULL, node, child,
8874 "The attribute 'type' and the <simpleType> child are "
8875 "mutually exclusive", NULL);
8876 } else
8877 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8878 child = child->next;
8879 }
8880 while ((IS_SCHEMA(child, "unique")) ||
8881 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8882 if (IS_SCHEMA(child, "unique")) {
8883 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8884 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8885 } else if (IS_SCHEMA(child, "key")) {
8886 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8887 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8888 } else if (IS_SCHEMA(child, "keyref")) {
8889 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8890 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8891 }
8892 if (lastIDC != NULL)
8893 lastIDC->next = curIDC;
8894 else
8895 decl->idcs = (void *) curIDC;
8896 lastIDC = curIDC;
8897 child = child->next;
8898 }
8899 if (child != NULL) {
8900 xmlSchemaPContentErr(ctxt,
8902 NULL, node, child,
8903 NULL, "(annotation?, ((simpleType | complexType)?, "
8904 "(unique | key | keyref)*))");
8905 }
8906 decl->annot = annot;
8907 }
8908 /*
8909 * NOTE: Element Declaration Representation OK 4. will be checked at a
8910 * different layer.
8911 */
8912 FREE_AND_NULL(des)
8913 if (topLevel)
8914 return ((xmlSchemaBasicItemPtr) decl);
8915 else {
8916 particle->children = (xmlSchemaTreeItemPtr) decl;
8917 return ((xmlSchemaBasicItemPtr) particle);
8918 }
8919
8921 FREE_AND_NULL(des);
8922 if (annot != NULL) {
8923 if (particle != NULL)
8924 particle->annot = NULL;
8925 if (decl != NULL)
8926 decl->annot = NULL;
8927 xmlSchemaFreeAnnot(annot);
8928 }
8929 return (NULL);
8930}
8931
8944static int
8945xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8947{
8948 xmlSchemaTypePtr type;
8951 const xmlChar *cur = NULL;
8952
8953 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8954 return (-1);
8955 /* Not a component, don't create it. */
8956 type = ctxt->ctxtType;
8957 /*
8958 * Mark the simple type as being of variety "union".
8959 */
8960 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8961 /*
8962 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8963 * then the `simple ur-type definition`."
8964 */
8965 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8966 /*
8967 * Check for illegal attributes.
8968 */
8969 attr = node->properties;
8970 while (attr != NULL) {
8971 if (attr->ns == NULL) {
8972 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8973 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8974 xmlSchemaPIllegalAttrErr(ctxt,
8976 }
8977 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8978 xmlSchemaPIllegalAttrErr(ctxt,
8980 }
8981 attr = attr->next;
8982 }
8983 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8984 /*
8985 * Attribute "memberTypes". This is a list of QNames.
8986 * TODO: Check the value to contain anything.
8987 */
8988 attr = xmlSchemaGetPropNode(node, "memberTypes");
8989 if (attr != NULL) {
8990 const xmlChar *end;
8991 xmlChar *tmp;
8992 const xmlChar *localName, *nsName;
8993 xmlSchemaTypeLinkPtr link, lastLink = NULL;
8994 xmlSchemaQNameRefPtr ref;
8995
8996 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8997 type->base = cur;
8998 do {
8999 while (IS_BLANK_CH(*cur))
9000 cur++;
9001 end = cur;
9002 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
9003 end++;
9004 if (end == cur)
9005 break;
9006 tmp = xmlStrndup(cur, end - cur);
9007 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
9008 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
9009 /*
9010 * Create the member type link.
9011 */
9012 link = (xmlSchemaTypeLinkPtr)
9013 xmlMalloc(sizeof(xmlSchemaTypeLink));
9014 if (link == NULL) {
9015 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
9016 "allocating a type link", NULL);
9017 return (-1);
9018 }
9019 link->type = NULL;
9020 link->next = NULL;
9021 if (lastLink == NULL)
9022 type->memberTypes = link;
9023 else
9024 lastLink->next = link;
9025 lastLink = link;
9026 /*
9027 * Create a reference item.
9028 */
9029 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
9030 localName, nsName);
9031 if (ref == NULL) {
9032 FREE_AND_NULL(tmp)
9033 return (-1);
9034 }
9035 /*
9036 * Assign the reference to the link, it will be resolved
9037 * later during fixup of the union simple type.
9038 */
9039 link->type = (xmlSchemaTypePtr) ref;
9040 }
9041 FREE_AND_NULL(tmp)
9042 cur = end;
9043 } while (*cur != 0);
9044
9045 }
9046 /*
9047 * And now for the children...
9048 */
9049 child = node->children;
9050 if (IS_SCHEMA(child, "annotation")) {
9051 /*
9052 * Add the annotation to the simple type ancestor.
9053 */
9054 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9055 xmlSchemaParseAnnotation(ctxt, child, 1));
9056 child = child->next;
9057 }
9058 if (IS_SCHEMA(child, "simpleType")) {
9059 xmlSchemaTypePtr subtype, last = NULL;
9060
9061 /*
9062 * Anchor the member types in the "subtypes" field of the
9063 * simple type.
9064 */
9065 while (IS_SCHEMA(child, "simpleType")) {
9066 subtype = (xmlSchemaTypePtr)
9067 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9068 if (subtype != NULL) {
9069 if (last == NULL) {
9070 type->subtypes = subtype;
9071 last = subtype;
9072 } else {
9073 last->next = subtype;
9074 last = subtype;
9075 }
9076 last->next = NULL;
9077 }
9078 child = child->next;
9079 }
9080 }
9081 if (child != NULL) {
9082 xmlSchemaPContentErr(ctxt,
9084 NULL, node, child, NULL, "(annotation?, simpleType*)");
9085 }
9086 if ((attr == NULL) && (type->subtypes == NULL)) {
9087 /*
9088 * src-union-memberTypes-or-simpleTypes
9089 * Either the memberTypes [attribute] of the <union> element must
9090 * be non-empty or there must be at least one simpleType [child].
9091 */
9092 xmlSchemaPCustomErr(ctxt,
9094 NULL, node,
9095 "Either the attribute 'memberTypes' or "
9096 "at least one <simpleType> child must be present", NULL);
9097 }
9098 return (0);
9099}
9100
9113static xmlSchemaTypePtr
9114xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9116{
9117 xmlSchemaTypePtr type;
9120
9121 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9122 return (NULL);
9123 /* Not a component, don't create it. */
9124 type = ctxt->ctxtType;
9125 /*
9126 * Mark the type as being of variety "list".
9127 */
9128 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9129 /*
9130 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9131 * then the `simple ur-type definition`."
9132 */
9133 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9134 /*
9135 * Check for illegal attributes.
9136 */
9137 attr = node->properties;
9138 while (attr != NULL) {
9139 if (attr->ns == NULL) {
9140 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9141 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
9142 xmlSchemaPIllegalAttrErr(ctxt,
9144 }
9145 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9146 xmlSchemaPIllegalAttrErr(ctxt,
9148 }
9149 attr = attr->next;
9150 }
9151
9152 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9153
9154 /*
9155 * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9156 * fields for holding the reference to the itemType.
9157 *
9158 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9159 * the "ref" fields.
9160 */
9161 xmlSchemaPValAttrQName(ctxt, schema, NULL,
9162 node, "itemType", &(type->baseNs), &(type->base));
9163 /*
9164 * And now for the children...
9165 */
9166 child = node->children;
9167 if (IS_SCHEMA(child, "annotation")) {
9168 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9169 xmlSchemaParseAnnotation(ctxt, child, 1));
9170 child = child->next;
9171 }
9172 if (IS_SCHEMA(child, "simpleType")) {
9173 /*
9174 * src-list-itemType-or-simpleType
9175 * Either the itemType [attribute] or the <simpleType> [child] of
9176 * the <list> element must be present, but not both.
9177 */
9178 if (type->base != NULL) {
9179 xmlSchemaPCustomErr(ctxt,
9181 NULL, node,
9182 "The attribute 'itemType' and the <simpleType> child "
9183 "are mutually exclusive", NULL);
9184 } else {
9185 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9186 }
9187 child = child->next;
9188 } else if (type->base == NULL) {
9189 xmlSchemaPCustomErr(ctxt,
9191 NULL, node,
9192 "Either the attribute 'itemType' or the <simpleType> child "
9193 "must be present", NULL);
9194 }
9195 if (child != NULL) {
9196 xmlSchemaPContentErr(ctxt,
9198 NULL, node, child, NULL, "(annotation?, simpleType?)");
9199 }
9200 if ((type->base == NULL) &&
9201 (type->subtypes == NULL) &&
9202 (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9203 xmlSchemaPCustomErr(ctxt,
9205 NULL, node,
9206 "Either the attribute 'itemType' or the <simpleType> child "
9207 "must be present", NULL);
9208 }
9209 return (NULL);
9210}
9211
9224static xmlSchemaTypePtr
9225xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9226 xmlNodePtr node, int topLevel)
9227{
9228 xmlSchemaTypePtr type, oldCtxtType;
9230 const xmlChar *attrValue = NULL;
9232 int hasRestriction = 0;
9233
9234 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9235 return (NULL);
9236
9237 if (topLevel) {
9238 attr = xmlSchemaGetPropNode(node, "name");
9239 if (attr == NULL) {
9240 xmlSchemaPMissingAttrErr(ctxt,
9242 NULL, node,
9243 "name", NULL);
9244 return (NULL);
9245 } else {
9246 if (xmlSchemaPValAttrNode(ctxt,
9247 NULL, attr,
9248 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9249 return (NULL);
9250 /*
9251 * Skip built-in types.
9252 */
9253 if (ctxt->isS4S) {
9254 xmlSchemaTypePtr biType;
9255
9256 if (ctxt->isRedefine) {
9257 /*
9258 * REDEFINE: Disallow redefinition of built-in-types.
9259 * TODO: It seems that the spec does not say anything
9260 * about this case.
9261 */
9262 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9263 NULL, node,
9264 "Redefinition of built-in simple types is not "
9265 "supported", NULL);
9266 return(NULL);
9267 }
9268 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9269 if (biType != NULL)
9270 return (biType);
9271 }
9272 }
9273 }
9274 /*
9275 * TargetNamespace:
9276 * SPEC "The `actual value` of the targetNamespace [attribute]
9277 * of the <schema> ancestor element information item if present,
9278 * otherwise `absent`.
9279 */
9280 if (topLevel == 0) {
9281#ifdef ENABLE_NAMED_LOCALS
9282 char buf[40];
9283#endif
9284 /*
9285 * Parse as local simple type definition.
9286 */
9287#ifdef ENABLE_NAMED_LOCALS
9288 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9289 type = xmlSchemaAddType(ctxt, schema,
9290 XML_SCHEMA_TYPE_SIMPLE,
9291 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9292 ctxt->targetNamespace, node, 0);
9293#else
9294 type = xmlSchemaAddType(ctxt, schema,
9295 XML_SCHEMA_TYPE_SIMPLE,
9296 NULL, ctxt->targetNamespace, node, 0);
9297#endif
9298 if (type == NULL)
9299 return (NULL);
9300 type->type = XML_SCHEMA_TYPE_SIMPLE;
9301 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9302 /*
9303 * Check for illegal attributes.
9304 */
9305 attr = node->properties;
9306 while (attr != NULL) {
9307 if (attr->ns == NULL) {
9308 if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9309 xmlSchemaPIllegalAttrErr(ctxt,
9311 }
9312 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9313 xmlSchemaPIllegalAttrErr(ctxt,
9315 }
9316 attr = attr->next;
9317 }
9318 } else {
9319 /*
9320 * Parse as global simple type definition.
9321 *
9322 * Note that attrValue is the value of the attribute "name" here.
9323 */
9324 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9325 attrValue, ctxt->targetNamespace, node, 1);
9326 if (type == NULL)
9327 return (NULL);
9328 type->type = XML_SCHEMA_TYPE_SIMPLE;
9329 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9330 type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9331 /*
9332 * Check for illegal attributes.
9333 */
9334 attr = node->properties;
9335 while (attr != NULL) {
9336 if (attr->ns == NULL) {
9337 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9338 (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9339 (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9340 xmlSchemaPIllegalAttrErr(ctxt,
9342 }
9343 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9344 xmlSchemaPIllegalAttrErr(ctxt,
9346 }
9347 attr = attr->next;
9348 }
9349 /*
9350 * Attribute "final".
9351 */
9352 attr = xmlSchemaGetPropNode(node, "final");
9353 if (attr == NULL) {
9354 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9355 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9356 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9357 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9358 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9359 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9360 } else {
9361 attrValue = xmlSchemaGetProp(ctxt, node, "final");
9362 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9363 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9364 XML_SCHEMAS_TYPE_FINAL_LIST,
9365 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9366
9367 xmlSchemaPSimpleTypeErr(ctxt,
9369 WXS_BASIC_CAST type, (xmlNodePtr) attr,
9370 NULL, "(#all | List of (list | union | restriction)",
9371 attrValue, NULL, NULL, NULL);
9372 }
9373 }
9374 }
9375 type->targetNamespace = ctxt->targetNamespace;
9376 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9377 /*
9378 * And now for the children...
9379 */
9380 oldCtxtType = ctxt->ctxtType;
9381
9382 ctxt->ctxtType = type;
9383
9384 child = node->children;
9385 if (IS_SCHEMA(child, "annotation")) {
9386 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9387 child = child->next;
9388 }
9389 if (child == NULL) {
9390 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9391 NULL, node, child, NULL,
9392 "(annotation?, (restriction | list | union))");
9393 } else if (IS_SCHEMA(child, "restriction")) {
9394 xmlSchemaParseRestriction(ctxt, schema, child,
9395 XML_SCHEMA_TYPE_SIMPLE);
9396 hasRestriction = 1;
9397 child = child->next;
9398 } else if (IS_SCHEMA(child, "list")) {
9399 xmlSchemaParseList(ctxt, schema, child);
9400 child = child->next;
9401 } else if (IS_SCHEMA(child, "union")) {
9402 xmlSchemaParseUnion(ctxt, schema, child);
9403 child = child->next;
9404 }
9405 if (child != NULL) {
9406 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9407 NULL, node, child, NULL,
9408 "(annotation?, (restriction | list | union))");
9409 }
9410 /*
9411 * REDEFINE: SPEC src-redefine (5)
9412 * "Within the [children], each <simpleType> must have a
9413 * <restriction> among its [children] ... the `actual value` of whose
9414 * base [attribute] must be the same as the `actual value` of its own
9415 * name attribute plus target namespace;"
9416 */
9417 if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9418 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9419 NULL, node, "This is a redefinition, thus the "
9420 "<simpleType> must have a <restriction> child", NULL);
9421 }
9422
9423 ctxt->ctxtType = oldCtxtType;
9424 return (type);
9425}
9426
9438static xmlSchemaTreeItemPtr
9439xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9440 xmlSchemaPtr schema,
9442{
9443 xmlSchemaParticlePtr item;
9446 const xmlChar *ref = NULL, *refNs = NULL;
9447 int min, max;
9448
9449 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9450 return (NULL);
9451
9452 attr = xmlSchemaGetPropNode(node, "ref");
9453 if (attr == NULL) {
9454 xmlSchemaPMissingAttrErr(ctxt,
9456 NULL, node, "ref", NULL);
9457 return (NULL);
9458 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9459 attr, &refNs, &ref) != 0) {
9460 return (NULL);
9461 }
9462 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9463 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9464 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9465 "(xs:nonNegativeInteger | unbounded)");
9466 /*
9467 * Check for illegal attributes.
9468 */
9469 attr = node->properties;
9470 while (attr != NULL) {
9471 if (attr->ns == NULL) {
9472 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9473 (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9474 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9475 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9476 xmlSchemaPIllegalAttrErr(ctxt,
9478 }
9479 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9480 xmlSchemaPIllegalAttrErr(ctxt,
9482 }
9483 attr = attr->next;
9484 }
9485 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9486 item = xmlSchemaAddParticle(ctxt, node, min, max);
9487 if (item == NULL)
9488 return (NULL);
9489 /*
9490 * Create a qname-reference and set as the term; it will be substituted
9491 * for the model group after the reference has been resolved.
9492 */
9493 item->children = (xmlSchemaTreeItemPtr)
9494 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9495 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9496 /*
9497 * And now for the children...
9498 */
9499 child = node->children;
9500 /* TODO: Is annotation even allowed for a model group reference? */
9501 if (IS_SCHEMA(child, "annotation")) {
9502 /*
9503 * TODO: What to do exactly with the annotation?
9504 */
9505 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9506 child = child->next;
9507 }
9508 if (child != NULL) {
9509 xmlSchemaPContentErr(ctxt,
9511 NULL, node, child, NULL,
9512 "(annotation?)");
9513 }
9514 /*
9515 * Corresponds to no component at all if minOccurs==maxOccurs==0.
9516 */
9517 if ((min == 0) && (max == 0))
9518 return (NULL);
9519
9520 return ((xmlSchemaTreeItemPtr) item);
9521}
9522
9540static xmlSchemaModelGroupDefPtr
9541xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9542 xmlSchemaPtr schema,
9544{
9545 xmlSchemaModelGroupDefPtr item;
9548 const xmlChar *name;
9549
9550 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9551 return (NULL);
9552
9553 attr = xmlSchemaGetPropNode(node, "name");
9554 if (attr == NULL) {
9555 xmlSchemaPMissingAttrErr(ctxt,
9557 NULL, node,
9558 "name", NULL);
9559 return (NULL);
9560 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9561 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9562 return (NULL);
9563 }
9564 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9565 ctxt->targetNamespace, node);
9566 if (item == NULL)
9567 return (NULL);
9568 /*
9569 * Check for illegal attributes.
9570 */
9571 attr = node->properties;
9572 while (attr != NULL) {
9573 if (attr->ns == NULL) {
9574 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9575 (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9576 xmlSchemaPIllegalAttrErr(ctxt,
9578 }
9579 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9580 xmlSchemaPIllegalAttrErr(ctxt,
9582 }
9583 attr = attr->next;
9584 }
9585 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9586 /*
9587 * And now for the children...
9588 */
9589 child = node->children;
9590 if (IS_SCHEMA(child, "annotation")) {
9591 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9592 child = child->next;
9593 }
9594 if (IS_SCHEMA(child, "all")) {
9595 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9596 XML_SCHEMA_TYPE_ALL, 0);
9597 child = child->next;
9598 } else if (IS_SCHEMA(child, "choice")) {
9599 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9600 XML_SCHEMA_TYPE_CHOICE, 0);
9601 child = child->next;
9602 } else if (IS_SCHEMA(child, "sequence")) {
9603 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9604 XML_SCHEMA_TYPE_SEQUENCE, 0);
9605 child = child->next;
9606 }
9607
9608
9609
9610 if (child != NULL) {
9611 xmlSchemaPContentErr(ctxt,
9613 NULL, node, child, NULL,
9614 "(annotation?, (all | choice | sequence)?)");
9615 }
9616 return (item);
9617}
9618
9626static void
9627xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9628{
9629 xmlNodePtr delete, cur;
9630
9631 if ((ctxt == NULL) || (root == NULL)) return;
9632
9633 /*
9634 * Remove all the blank text nodes
9635 */
9636 delete = NULL;
9637 cur = root;
9638 while (cur != NULL) {
9639 if (delete != NULL) {
9640 xmlUnlinkNode(delete);
9641 xmlFreeNode(delete);
9642 delete = NULL;
9643 }
9644 if (cur->type == XML_TEXT_NODE) {
9645 if (IS_BLANK_NODE(cur)) {
9646 if (xmlNodeGetSpacePreserve(cur) != 1) {
9647 delete = cur;
9648 }
9649 }
9650 } else if ((cur->type != XML_ELEMENT_NODE) &&
9651 (cur->type != XML_CDATA_SECTION_NODE)) {
9652 delete = cur;
9653 goto skip_children;
9654 }
9655
9656 /*
9657 * Skip to next node
9658 */
9659 if (cur->children != NULL) {
9660 if ((cur->children->type != XML_ENTITY_DECL) &&
9661 (cur->children->type != XML_ENTITY_REF_NODE) &&
9662 (cur->children->type != XML_ENTITY_NODE)) {
9663 cur = cur->children;
9664 continue;
9665 }
9666 }
9667 skip_children:
9668 if (cur->next != NULL) {
9669 cur = cur->next;
9670 continue;
9671 }
9672
9673 do {
9674 cur = cur->parent;
9675 if (cur == NULL)
9676 break;
9677 if (cur == root) {
9678 cur = NULL;
9679 break;
9680 }
9681 if (cur->next != NULL) {
9682 cur = cur->next;
9683 break;
9684 }
9685 } while (cur != NULL);
9686 }
9687 if (delete != NULL) {
9688 xmlUnlinkNode(delete);
9689 xmlFreeNode(delete);
9690 delete = NULL;
9691 }
9692}
9693
9694
9695static void
9696xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9697{
9698 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9699 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9700
9701 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9702 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9703
9704 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9705 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9706 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9707 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9708 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9709 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9710 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9711 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9712
9713 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9714 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9715 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9716 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9717 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9718 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9719}
9720
9721static int
9722xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9723 xmlSchemaPtr schema,
9725{
9727 const xmlChar *val;
9728 int res = 0, oldErrs = ctxt->nberrors;
9729
9730 /*
9731 * Those flags should be moved to the parser context flags,
9732 * since they are not visible at the component level. I.e.
9733 * they are used if processing schema *documents* only.
9734 */
9735 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9736 HFAILURE;
9737
9738 /*
9739 * Since the version is of type xs:token, we won't bother to
9740 * check it.
9741 */
9742 /* REMOVED:
9743 attr = xmlSchemaGetPropNode(node, "version");
9744 if (attr != NULL) {
9745 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9746 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9747 HFAILURE;
9748 }
9749 */
9750 attr = xmlSchemaGetPropNode(node, "targetNamespace");
9751 if (attr != NULL) {
9752 res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9753 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9754 HFAILURE;
9755 if (res != 0) {
9757 goto exit;
9758 }
9759 }
9760 attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9761 if (attr != NULL) {
9762 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9763 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9764 XML_SCHEMAS_QUALIF_ELEM);
9765 HFAILURE;
9766 if (res != 0) {
9767 xmlSchemaPSimpleTypeErr(ctxt,
9770 "(qualified | unqualified)", val, NULL, NULL, NULL);
9771 }
9772 }
9773 attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9774 if (attr != NULL) {
9775 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9776 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9777 XML_SCHEMAS_QUALIF_ATTR);
9778 HFAILURE;
9779 if (res != 0) {
9780 xmlSchemaPSimpleTypeErr(ctxt,
9783 "(qualified | unqualified)", val, NULL, NULL, NULL);
9784 }
9785 }
9786 attr = xmlSchemaGetPropNode(node, "finalDefault");
9787 if (attr != NULL) {
9788 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9789 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9790 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9791 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9792 -1,
9793 XML_SCHEMAS_FINAL_DEFAULT_LIST,
9794 XML_SCHEMAS_FINAL_DEFAULT_UNION);
9795 HFAILURE;
9796 if (res != 0) {
9797 xmlSchemaPSimpleTypeErr(ctxt,
9800 "(#all | List of (extension | restriction | list | union))",
9801 val, NULL, NULL, NULL);
9802 }
9803 }
9804 attr = xmlSchemaGetPropNode(node, "blockDefault");
9805 if (attr != NULL) {
9806 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9807 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9808 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9809 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9810 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9811 HFAILURE;
9812 if (res != 0) {
9813 xmlSchemaPSimpleTypeErr(ctxt,
9816 "(#all | List of (extension | restriction | substitution))",
9817 val, NULL, NULL, NULL);
9818 }
9819 }
9820
9821exit:
9822 if (oldErrs != ctxt->nberrors)
9823 res = ctxt->err;
9824 return(res);
9825exit_failure:
9826 return(-1);
9827}
9828
9838static int
9839xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9840 xmlSchemaPtr schema, xmlNodePtr nodes)
9841{
9843 xmlSchemaAnnotPtr annot;
9844 int res = 0, oldErrs, tmpOldErrs;
9845
9846 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9847 return(-1);
9848
9849 oldErrs = ctxt->nberrors;
9850 child = nodes;
9851 while ((IS_SCHEMA(child, "include")) ||
9852 (IS_SCHEMA(child, "import")) ||
9853 (IS_SCHEMA(child, "redefine")) ||
9854 (IS_SCHEMA(child, "annotation"))) {
9855 if (IS_SCHEMA(child, "annotation")) {
9856 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9857 if (schema->annot == NULL)
9858 schema->annot = annot;
9859 else
9860 xmlSchemaFreeAnnot(annot);
9861 } else if (IS_SCHEMA(child, "import")) {
9862 tmpOldErrs = ctxt->nberrors;
9863 res = xmlSchemaParseImport(ctxt, schema, child);
9864 HFAILURE;
9865 HSTOP(ctxt);
9866 if (tmpOldErrs != ctxt->nberrors)
9867 goto exit;
9868 } else if (IS_SCHEMA(child, "include")) {
9869 tmpOldErrs = ctxt->nberrors;
9870 res = xmlSchemaParseInclude(ctxt, schema, child);
9871 HFAILURE;
9872 HSTOP(ctxt);
9873 if (tmpOldErrs != ctxt->nberrors)
9874 goto exit;
9875 } else if (IS_SCHEMA(child, "redefine")) {
9876 tmpOldErrs = ctxt->nberrors;
9877 res = xmlSchemaParseRedefine(ctxt, schema, child);
9878 HFAILURE;
9879 HSTOP(ctxt);
9880 if (tmpOldErrs != ctxt->nberrors)
9881 goto exit;
9882 }
9883 child = child->next;
9884 }
9885 /*
9886 * URGENT TODO: Change the functions to return int results.
9887 * We need especially to catch internal errors.
9888 */
9889 while (child != NULL) {
9890 if (IS_SCHEMA(child, "complexType")) {
9891 xmlSchemaParseComplexType(ctxt, schema, child, 1);
9892 child = child->next;
9893 } else if (IS_SCHEMA(child, "simpleType")) {
9894 xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9895 child = child->next;
9896 } else if (IS_SCHEMA(child, "element")) {
9897 xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9898 child = child->next;
9899 } else if (IS_SCHEMA(child, "attribute")) {
9900 xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9901 child = child->next;
9902 } else if (IS_SCHEMA(child, "attributeGroup")) {
9903 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9904 child = child->next;
9905 } else if (IS_SCHEMA(child, "group")) {
9906 xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9907 child = child->next;
9908 } else if (IS_SCHEMA(child, "notation")) {
9909 xmlSchemaParseNotation(ctxt, schema, child);
9910 child = child->next;
9911 } else {
9912 xmlSchemaPContentErr(ctxt,
9914 NULL, child->parent, child,
9915 NULL, "((include | import | redefine | annotation)*, "
9916 "(((simpleType | complexType | group | attributeGroup) "
9917 "| element | attribute | notation), annotation*)*)");
9918 child = child->next;
9919 }
9920 while (IS_SCHEMA(child, "annotation")) {
9921 /*
9922 * TODO: We should add all annotations.
9923 */
9924 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9925 if (schema->annot == NULL)
9926 schema->annot = annot;
9927 else
9928 xmlSchemaFreeAnnot(annot);
9929 child = child->next;
9930 }
9931 }
9932exit:
9933 ctxt->ctxtType = NULL;
9934 if (oldErrs != ctxt->nberrors)
9935 res = ctxt->err;
9936 return(res);
9937exit_failure:
9938 return(-1);
9939}
9940
9941static xmlSchemaSchemaRelationPtr
9942xmlSchemaSchemaRelationCreate(void)
9943{
9944 xmlSchemaSchemaRelationPtr ret;
9945
9946 ret = (xmlSchemaSchemaRelationPtr)
9947 xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9948 if (ret == NULL) {
9949 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
9950 return(NULL);
9951 }
9952 memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9953 return(ret);
9954}
9955
9956#if 0
9957static void
9958xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9959{
9960 xmlFree(rel);
9961}
9962#endif
9963
9964static void
9965xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9966{
9967 xmlSchemaRedefPtr prev;
9968
9969 while (redef != NULL) {
9970 prev = redef;
9971 redef = redef->next;
9972 xmlFree(prev);
9973 }
9974}
9975
9976static void
9977xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9978{
9979 /*
9980 * After the construction context has been freed, there will be
9981 * no schema graph available any more. Only the schema buckets
9982 * will stay alive, which are put into the "schemasImports" and
9983 * "includes" slots of the xmlSchema.
9984 */
9985 if (con->buckets != NULL)
9986 xmlSchemaItemListFree(con->buckets);
9987 if (con->pending != NULL)
9988 xmlSchemaItemListFree(con->pending);
9989 if (con->substGroups != NULL)
9990 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9991 if (con->redefs != NULL)
9992 xmlSchemaRedefListFree(con->redefs);
9993 if (con->dict != NULL)
9994 xmlDictFree(con->dict);
9995 xmlFree(con);
9996}
9997
9998static xmlSchemaConstructionCtxtPtr
9999xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
10000{
10001 xmlSchemaConstructionCtxtPtr ret;
10002
10003 ret = (xmlSchemaConstructionCtxtPtr)
10004 xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
10005 if (ret == NULL) {
10006 xmlSchemaPErrMemory(NULL,
10007 "allocating schema construction context", NULL);
10008 return (NULL);
10009 }
10010 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
10011
10012 ret->buckets = xmlSchemaItemListCreate();
10013 if (ret->buckets == NULL) {
10014 xmlSchemaPErrMemory(NULL,
10015 "allocating list of schema buckets", NULL);
10016 xmlFree(ret);
10017 return (NULL);
10018 }
10019 ret->pending = xmlSchemaItemListCreate();
10020 if (ret->pending == NULL) {
10021 xmlSchemaPErrMemory(NULL,
10022 "allocating list of pending global components", NULL);
10023 xmlSchemaConstructionCtxtFree(ret);
10024 return (NULL);
10025 }
10026 ret->dict = dict;
10027 xmlDictReference(dict);
10028 return(ret);
10029}
10030
10031static xmlSchemaParserCtxtPtr
10032xmlSchemaParserCtxtCreate(void)
10033{
10034 xmlSchemaParserCtxtPtr ret;
10035
10036 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
10037 if (ret == NULL) {
10038 xmlSchemaPErrMemory(NULL, "allocating schema parser context",
10039 NULL);
10040 return (NULL);
10041 }
10042 memset(ret, 0, sizeof(xmlSchemaParserCtxt));
10043 ret->type = XML_SCHEMA_CTXT_PARSER;
10044 ret->attrProhibs = xmlSchemaItemListCreate();
10045 if (ret->attrProhibs == NULL) {
10046 xmlFree(ret);
10047 return(NULL);
10048 }
10049 return(ret);
10050}
10051
10062static xmlSchemaParserCtxtPtr
10063xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
10064{
10065 xmlSchemaParserCtxtPtr ret;
10066
10067 ret = xmlSchemaParserCtxtCreate();
10068 if (ret == NULL)
10069 return (NULL);
10070 ret->dict = dict;
10071 xmlDictReference(dict);
10072 if (URL != NULL)
10073 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
10074 return (ret);
10075}
10076
10077static int
10078xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
10079{
10080 if (vctxt->pctxt == NULL) {
10081 if (vctxt->schema != NULL)
10082 vctxt->pctxt =
10083 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
10084 else
10085 vctxt->pctxt = xmlSchemaNewParserCtxt("*");
10086 if (vctxt->pctxt == NULL) {
10087 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
10088 "failed to create a temp. parser context");
10089 return (-1);
10090 }
10091 /* TODO: Pass user data. */
10092 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
10093 vctxt->warning, vctxt->errCtxt);
10094 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
10095 vctxt->errCtxt);
10096 }
10097 return (0);
10098}
10099
10110static xmlSchemaBucketPtr
10111xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10112 const xmlChar *schemaLocation)
10113{
10114 xmlSchemaBucketPtr cur;
10115 xmlSchemaItemListPtr list;
10116
10117 list = pctxt->constructor->buckets;
10118 if (list->nbItems == 0)
10119 return(NULL);
10120 else {
10121 int i;
10122 for (i = 0; i < list->nbItems; i++) {
10123 cur = (xmlSchemaBucketPtr) list->items[i];
10124 /* Pointer comparison! */
10125 if (cur->schemaLocation == schemaLocation)
10126 return(cur);
10127 }
10128 }
10129 return(NULL);
10130}
10131
10132static xmlSchemaBucketPtr
10133xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10134 const xmlChar *schemaLocation,
10135 const xmlChar *targetNamespace)
10136{
10137 xmlSchemaBucketPtr cur;
10138 xmlSchemaItemListPtr list;
10139
10140 list = pctxt->constructor->buckets;
10141 if (list->nbItems == 0)
10142 return(NULL);
10143 else {
10144 int i;
10145 for (i = 0; i < list->nbItems; i++) {
10146 cur = (xmlSchemaBucketPtr) list->items[i];
10147 /* Pointer comparison! */
10148 if ((cur->origTargetNamespace == NULL) &&
10149 (cur->schemaLocation == schemaLocation) &&
10150 (cur->targetNamespace == targetNamespace))
10151 return(cur);
10152 }
10153 }
10154 return(NULL);
10155}
10156
10157
10158#define IS_BAD_SCHEMA_DOC(b) \
10159 (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10160
10161static xmlSchemaBucketPtr
10162xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10163 const xmlChar *targetNamespace,
10164 int imported)
10165{
10166 xmlSchemaBucketPtr cur;
10167 xmlSchemaItemListPtr list;
10168
10169 list = pctxt->constructor->buckets;
10170 if (list->nbItems == 0)
10171 return(NULL);
10172 else {
10173 int i;
10174 for (i = 0; i < list->nbItems; i++) {
10175 cur = (xmlSchemaBucketPtr) list->items[i];
10176 if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10177 (cur->origTargetNamespace == targetNamespace) &&
10178 ((imported && cur->imported) ||
10179 ((!imported) && (!cur->imported))))
10180 return(cur);
10181 }
10182 }
10183 return(NULL);
10184}
10185
10186static int
10187xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10188 xmlSchemaPtr schema,
10189 xmlSchemaBucketPtr bucket)
10190{
10191 int oldFlags;
10192 xmlDocPtr oldDoc;
10194 int ret, oldErrs;
10195 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10196
10197 /*
10198 * Save old values; reset the *main* schema.
10199 * URGENT TODO: This is not good; move the per-document information
10200 * to the parser. Get rid of passing the main schema to the
10201 * parsing functions.
10202 */
10203 oldFlags = schema->flags;
10204 oldDoc = schema->doc;
10205 if (schema->flags != 0)
10206 xmlSchemaClearSchemaDefaults(schema);
10207 schema->doc = bucket->doc;
10208 pctxt->schema = schema;
10209 /*
10210 * Keep the current target namespace on the parser *not* on the
10211 * main schema.
10212 */
10213 pctxt->targetNamespace = bucket->targetNamespace;
10214 WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10215
10216 if ((bucket->targetNamespace != NULL) &&
10217 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10218 /*
10219 * We are parsing the schema for schemas!
10220 */
10221 pctxt->isS4S = 1;
10222 }
10223 /* Mark it as parsed, even if parsing fails. */
10224 bucket->parsed++;
10225 /* Compile the schema doc. */
10226 node = xmlDocGetRootElement(bucket->doc);
10227 ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10228 if (ret != 0)
10229 goto exit;
10230 /* An empty schema; just get out. */
10231 if (node->children == NULL)
10232 goto exit;
10233 oldErrs = pctxt->nberrors;
10234 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10235 if (ret != 0)
10236 goto exit;
10237 /*
10238 * TODO: Not nice, but I'm not 100% sure we will get always an error
10239 * as a result of the above functions; so better rely on pctxt->err
10240 * as well.
10241 */
10242 if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10243 ret = pctxt->err;
10244 goto exit;
10245 }
10246
10247exit:
10248 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10249 /* Restore schema values. */
10250 schema->doc = oldDoc;
10251 schema->flags = oldFlags;
10252 return(ret);
10253}
10254
10255static int
10256xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10257 xmlSchemaPtr schema,
10258 xmlSchemaBucketPtr bucket)
10259{
10260 xmlSchemaParserCtxtPtr newpctxt;
10261 int res = 0;
10262
10263 if (bucket == NULL)
10264 return(0);
10265 if (bucket->parsed) {
10266 PERROR_INT("xmlSchemaParseNewDoc",
10267 "reparsing a schema doc");
10268 return(-1);
10269 }
10270 if (bucket->doc == NULL) {
10271 PERROR_INT("xmlSchemaParseNewDoc",
10272 "parsing a schema doc, but there's no doc");
10273 return(-1);
10274 }
10275 if (pctxt->constructor == NULL) {
10276 PERROR_INT("xmlSchemaParseNewDoc",
10277 "no constructor");
10278 return(-1);
10279 }
10280 /* Create and init the temporary parser context. */
10281 newpctxt = xmlSchemaNewParserCtxtUseDict(
10282 (const char *) bucket->schemaLocation, pctxt->dict);
10283 if (newpctxt == NULL)
10284 return(-1);
10285 newpctxt->constructor = pctxt->constructor;
10286 /*
10287 * TODO: Can we avoid that the parser knows about the main schema?
10288 * It would be better if he knows about the current schema bucket
10289 * only.
10290 */
10291 newpctxt->schema = schema;
10292 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10293 pctxt->errCtxt);
10294 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10295 pctxt->errCtxt);
10296 newpctxt->counter = pctxt->counter;
10297
10298
10299 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10300
10301 /* Channel back errors and cleanup the temporary parser context. */
10302 if (res != 0)
10303 pctxt->err = res;
10304 pctxt->nberrors += newpctxt->nberrors;
10305 pctxt->counter = newpctxt->counter;
10306 newpctxt->constructor = NULL;
10307 /* Free the parser context. */
10308 xmlSchemaFreeParserCtxt(newpctxt);
10309 return(res);
10310}
10311
10312static void
10313xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10314 xmlSchemaSchemaRelationPtr rel)
10315{
10316 xmlSchemaSchemaRelationPtr cur = bucket->relations;
10317
10318 if (cur == NULL) {
10319 bucket->relations = rel;
10320 return;
10321 }
10322 while (cur->next != NULL)
10323 cur = cur->next;
10324 cur->next = rel;
10325}
10326
10327
10328static const xmlChar *
10329xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10330 xmlNodePtr ctxtNode)
10331{
10332 /*
10333 * Build an absolute location URI.
10334 */
10335 if (location != NULL) {
10336 if (ctxtNode == NULL)
10337 return(location);
10338 else {
10339 xmlChar *base, *URI;
10340 const xmlChar *ret = NULL;
10341
10342 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10343 if (base == NULL) {
10344 URI = xmlBuildURI(location, ctxtNode->doc->URL);
10345 } else {
10346 URI = xmlBuildURI(location, base);
10347 xmlFree(base);
10348 }
10349 if (URI != NULL) {
10350 ret = xmlDictLookup(dict, URI, -1);
10351 xmlFree(URI);
10352 return(ret);
10353 }
10354 }
10355 }
10356 return(NULL);
10357}
10358
10359
10360
10373static int
10374xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10375 int type, /* import or include or redefine */
10376 const xmlChar *schemaLocation,
10377 xmlDocPtr schemaDoc,
10378 const char *schemaBuffer,
10379 int schemaBufferLen,
10380 xmlNodePtr invokingNode,
10381 const xmlChar *sourceTargetNamespace,
10382 const xmlChar *importNamespace,
10383 xmlSchemaBucketPtr *bucket)
10384{
10385 const xmlChar *targetNamespace = NULL;
10386 xmlSchemaSchemaRelationPtr relation = NULL;
10387 xmlDocPtr doc = NULL;
10388 int res = 0, err = 0, located = 0, preserveDoc = 0;
10389 xmlSchemaBucketPtr bkt = NULL;
10390
10391 if (bucket != NULL)
10392 *bucket = NULL;
10393
10394 switch (type) {
10395 case XML_SCHEMA_SCHEMA_IMPORT:
10396 case XML_SCHEMA_SCHEMA_MAIN:
10398 break;
10399 case XML_SCHEMA_SCHEMA_INCLUDE:
10401 break;
10402 case XML_SCHEMA_SCHEMA_REDEFINE:
10404 break;
10405 }
10406
10407
10408 /* Special handling for the main schema:
10409 * skip the location and relation logic and just parse the doc.
10410 * We need just a bucket to be returned in this case.
10411 */
10412 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10413 goto doc_load;
10414
10415 /* Note that we expect the location to be an absolute URI. */
10416 if (schemaLocation != NULL) {
10417 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10418 if ((bkt != NULL) &&
10419 (pctxt->constructor->bucket == bkt)) {
10420 /* Report self-imports/inclusions/redefinitions. */
10421
10422 xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10423 invokingNode, NULL,
10424 "The schema must not import/include/redefine itself",
10425 NULL, NULL);
10426 goto exit;
10427 }
10428 }
10429 /*
10430 * Create a relation for the graph of schemas.
10431 */
10432 relation = xmlSchemaSchemaRelationCreate();
10433 if (relation == NULL)
10434 return(-1);
10435 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10436 relation);
10437 relation->type = type;
10438
10439 /*
10440 * Save the namespace import information.
10441 */
10442 if (WXS_IS_BUCKET_IMPMAIN(type)) {
10443 relation->importNamespace = importNamespace;
10444 if (schemaLocation == NULL) {
10445 /*
10446 * No location; this is just an import of the namespace.
10447 * Note that we don't assign a bucket to the relation
10448 * in this case.
10449 */
10450 goto exit;
10451 }
10452 targetNamespace = importNamespace;
10453 }
10454
10455 /* Did we already fetch the doc? */
10456 if (bkt != NULL) {
10457 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10458 /*
10459 * We included/redefined and then try to import a schema,
10460 * but the new location provided for import was different.
10461 */
10462 if (schemaLocation == NULL)
10463 schemaLocation = BAD_CAST "in_memory_buffer";
10464 if (!xmlStrEqual(schemaLocation,
10465 bkt->schemaLocation)) {
10466 xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10467 invokingNode, NULL,
10468 "The schema document '%s' cannot be imported, since "
10469 "it was already included or redefined",
10470 schemaLocation, NULL);
10471 goto exit;
10472 }
10473 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10474 /*
10475 * We imported and then try to include/redefine a schema,
10476 * but the new location provided for the include/redefine
10477 * was different.
10478 */
10479 if (schemaLocation == NULL)
10480 schemaLocation = BAD_CAST "in_memory_buffer";
10481 if (!xmlStrEqual(schemaLocation,
10482 bkt->schemaLocation)) {
10483 xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10484 invokingNode, NULL,
10485 "The schema document '%s' cannot be included or "
10486 "redefined, since it was already imported",
10487 schemaLocation, NULL);
10488 goto exit;
10489 }
10490 }
10491 }
10492
10493 if (WXS_IS_BUCKET_IMPMAIN(type)) {
10494 /*
10495 * Given that the schemaLocation [attribute] is only a hint, it is open
10496 * to applications to ignore all but the first <import> for a given
10497 * namespace, regardless of the `actual value` of schemaLocation, but
10498 * such a strategy risks missing useful information when new
10499 * schemaLocations are offered.
10500 *
10501 * We will use the first <import> that comes with a location.
10502 * Further <import>s *with* a location, will result in an error.
10503 * TODO: Better would be to just report a warning here, but
10504 * we'll try it this way until someone complains.
10505 *
10506 * Schema Document Location Strategy:
10507 * 3 Based on the namespace name, identify an existing schema document,
10508 * either as a resource which is an XML document or a <schema> element
10509 * information item, in some local schema repository;
10510 * 5 Attempt to resolve the namespace name to locate such a resource.
10511 *
10512 * NOTE: (3) and (5) are not supported.
10513 */
10514 if (bkt != NULL) {
10515 relation->bucket = bkt;
10516 goto exit;
10517 }
10518 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10519 importNamespace, 1);
10520
10521 if (bkt != NULL) {
10522 relation->bucket = bkt;
10523 if (bkt->schemaLocation == NULL) {
10524 /* First given location of the schema; load the doc. */
10525 bkt->schemaLocation = schemaLocation;
10526 } else {
10527 if (!xmlStrEqual(schemaLocation,
10528 bkt->schemaLocation)) {
10529 /*
10530 * Additional location given; just skip it.
10531 * URGENT TODO: We should report a warning here.
10532 * res = XML_SCHEMAP_SRC_IMPORT;
10533 */
10534 if (schemaLocation == NULL)
10535 schemaLocation = BAD_CAST "in_memory_buffer";
10536
10537 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10539 invokingNode, NULL,
10540 "Skipping import of schema located at '%s' for the "
10541 "namespace '%s', since this namespace was already "
10542 "imported with the schema located at '%s'",
10543 schemaLocation, importNamespace, bkt->schemaLocation);
10544 }
10545 goto exit;
10546 }
10547 }
10548 /*
10549 * No bucket + first location: load the doc and create a
10550 * bucket.
10551 */
10552 } else {
10553 /* <include> and <redefine> */
10554 if (bkt != NULL) {
10555
10556 if ((bkt->origTargetNamespace == NULL) &&
10557 (bkt->targetNamespace != sourceTargetNamespace)) {
10558 xmlSchemaBucketPtr chamel;
10559
10560 /*
10561 * Chameleon include/redefine: skip loading only if it was
10562 * already build for the targetNamespace of the including
10563 * schema.
10564 */
10565 /*
10566 * URGENT TODO: If the schema is a chameleon-include then copy
10567 * the components into the including schema and modify the
10568 * targetNamespace of those components, do nothing otherwise.
10569 * NOTE: This is currently worked-around by compiling the
10570 * chameleon for every distinct including targetNamespace; thus
10571 * not performant at the moment.
10572 * TODO: Check when the namespace in wildcards for chameleons
10573 * needs to be converted: before we built wildcard intersections
10574 * or after.
10575 * Answer: after!
10576 */
10577 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10578 schemaLocation, sourceTargetNamespace);
10579 if (chamel != NULL) {
10580 /* A fitting chameleon was already parsed; NOP. */
10581 relation->bucket = chamel;
10582 goto exit;
10583 }
10584 /*
10585 * We need to parse the chameleon again for a different
10586 * targetNamespace.
10587 * CHAMELEON TODO: Optimize this by only parsing the
10588 * chameleon once, and then copying the components to
10589 * the new targetNamespace.
10590 */
10591 bkt = NULL;
10592 } else {
10593 relation->bucket = bkt;
10594 goto exit;
10595 }
10596 }
10597 }
10598 if ((bkt != NULL) && (bkt->doc != NULL)) {
10599 PERROR_INT("xmlSchemaAddSchemaDoc",
10600 "trying to load a schema doc, but a doc is already "
10601 "assigned to the schema bucket");
10602 goto exit_failure;
10603 }
10604
10605doc_load:
10606 /*
10607 * Load the document.
10608 */
10609 if (schemaDoc != NULL) {
10610 doc = schemaDoc;
10611 /* Don' free this one, since it was provided by the caller. */
10612 preserveDoc = 1;
10613 /* TODO: Does the context or the doc hold the location? */
10614 if (schemaDoc->URL != NULL)
10615 schemaLocation = xmlDictLookup(pctxt->dict,
10616 schemaDoc->URL, -1);
10617 else
10618 schemaLocation = BAD_CAST "in_memory_buffer";
10619 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10620 xmlParserCtxtPtr parserCtxt;
10621
10622 parserCtxt = xmlNewParserCtxt();
10623 if (parserCtxt == NULL) {
10624 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10625 "allocating a parser context", NULL);
10626 goto exit_failure;
10627 }
10628 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10629 /*
10630 * TODO: Do we have to burden the schema parser dict with all
10631 * the content of the schema doc?
10632 */
10633 xmlDictFree(parserCtxt->dict);
10634 parserCtxt->dict = pctxt->dict;
10635 xmlDictReference(parserCtxt->dict);
10636 }
10637 if (schemaLocation != NULL) {
10638 /* Parse from file. */
10639 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10640 NULL, SCHEMAS_PARSE_OPTIONS);
10641 } else if (schemaBuffer != NULL) {
10642 /* Parse from memory buffer. */
10643 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10644 NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10645 schemaLocation = BAD_CAST "in_memory_buffer";
10646 if (doc != NULL)
10647 doc->URL = xmlStrdup(schemaLocation);
10648 }
10649 /*
10650 * For <import>:
10651 * 2.1 The referent is (a fragment of) a resource which is an
10652 * XML document (see clause 1.1), which in turn corresponds to
10653 * a <schema> element information item in a well-formed information
10654 * set, which in turn corresponds to a valid schema.
10655 * TODO: (2.1) fragments of XML documents are not supported.
10656 *
10657 * 2.2 The referent is a <schema> element information item in
10658 * a well-formed information set, which in turn corresponds
10659 * to a valid schema.
10660 * TODO: (2.2) is not supported.
10661 */
10662 if (doc == NULL) {
10663 xmlErrorPtr lerr;
10664 lerr = xmlGetLastError();
10665 /*
10666 * Check if this a parser error, or if the document could
10667 * just not be located.
10668 * TODO: Try to find specific error codes to react only on
10669 * localisation failures.
10670 */
10671 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10672 /*
10673 * We assume a parser error here.
10674 */
10675 located = 1;
10676 /* TODO: Error code ?? */
10678 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10679 invokingNode, NULL,
10680 "Failed to parse the XML resource '%s'",
10681 schemaLocation, NULL);
10682 }
10683 }
10684 xmlFreeParserCtxt(parserCtxt);
10685 if ((doc == NULL) && located)
10686 goto exit_error;
10687 } else {
10688 xmlSchemaPErr(pctxt, NULL,
10690 "No information for parsing was provided with the "
10691 "given schema parser context.\n",
10692 NULL, NULL);
10693 goto exit_failure;
10694 }
10695 /*
10696 * Preprocess the document.
10697 */
10698 if (doc != NULL) {
10699 xmlNodePtr docElem = NULL;
10700
10701 located = 1;
10702 docElem = xmlDocGetRootElement(doc);
10703 if (docElem == NULL) {
10704 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10705 invokingNode, NULL,
10706 "The document '%s' has no document element",
10707 schemaLocation, NULL);
10708 goto exit_error;
10709 }
10710 /*
10711 * Remove all the blank text nodes.
10712 */
10713 xmlSchemaCleanupDoc(pctxt, docElem);
10714 /*
10715 * Check the schema's top level element.
10716 */
10717 if (!IS_SCHEMA(docElem, "schema")) {
10718 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10719 invokingNode, NULL,
10720 "The XML document '%s' is not a schema document",
10721 schemaLocation, NULL);
10722 goto exit_error;
10723 }
10724 /*
10725 * Note that we don't apply a type check for the
10726 * targetNamespace value here.
10727 */
10728 targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10729 "targetNamespace");
10730 }
10731
10732/* after_doc_loading: */
10733 if ((bkt == NULL) && located) {
10734 /* Only create a bucket if the schema was located. */
10735 bkt = xmlSchemaBucketCreate(pctxt, type,
10736 targetNamespace);
10737 if (bkt == NULL)
10738 goto exit_failure;
10739 }
10740 if (bkt != NULL) {
10741 bkt->schemaLocation = schemaLocation;
10742 bkt->located = located;
10743 if (doc != NULL) {
10744 bkt->doc = doc;
10745 bkt->targetNamespace = targetNamespace;
10746 bkt->origTargetNamespace = targetNamespace;
10747 if (preserveDoc)
10748 bkt->preserveDoc = 1;
10749 }
10750 if (WXS_IS_BUCKET_IMPMAIN(type))
10751 bkt->imported++;
10752 /*
10753 * Add it to the graph of schemas.
10754 */
10755 if (relation != NULL)
10756 relation->bucket = bkt;
10757 }
10758
10759exit:
10760 /*
10761 * Return the bucket explicitly; this is needed for the
10762 * main schema.
10763 */
10764 if (bucket != NULL)
10765 *bucket = bkt;
10766 return (0);
10767
10768exit_error:
10769 if ((doc != NULL) && (! preserveDoc)) {
10770 xmlFreeDoc(doc);
10771 if (bkt != NULL)
10772 bkt->doc = NULL;
10773 }
10774 return(pctxt->err);
10775
10776exit_failure:
10777 if ((doc != NULL) && (! preserveDoc)) {
10778 xmlFreeDoc(doc);
10779 if (bkt != NULL)
10780 bkt->doc = NULL;
10781 }
10782 return (-1);
10783}
10784
10797static int
10798xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10800{
10802 const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10803 const xmlChar *thisTargetNamespace;
10805 int ret = 0;
10806 xmlSchemaBucketPtr bucket = NULL;
10807
10808 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10809 return (-1);
10810
10811 /*
10812 * Check for illegal attributes.
10813 */
10814 attr = node->properties;
10815 while (attr != NULL) {
10816 if (attr->ns == NULL) {
10817 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10818 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10819 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10820 xmlSchemaPIllegalAttrErr(pctxt,
10822 }
10823 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10824 xmlSchemaPIllegalAttrErr(pctxt,
10826 }
10827 attr = attr->next;
10828 }
10829 /*
10830 * Extract and validate attributes.
10831 */
10832 if (xmlSchemaPValAttr(pctxt, NULL, node,
10833 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10834 &namespaceName) != 0) {
10835 xmlSchemaPSimpleTypeErr(pctxt,
10837 NULL, node,
10838 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10839 NULL, namespaceName, NULL, NULL, NULL);
10840 return (pctxt->err);
10841 }
10842
10843 if (xmlSchemaPValAttr(pctxt, NULL, node,
10844 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10845 &schemaLocation) != 0) {
10846 xmlSchemaPSimpleTypeErr(pctxt,
10848 NULL, node,
10849 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10850 NULL, schemaLocation, NULL, NULL, NULL);
10851 return (pctxt->err);
10852 }
10853 /*
10854 * And now for the children...
10855 */
10856 child = node->children;
10857 if (IS_SCHEMA(child, "annotation")) {
10858 /*
10859 * the annotation here is simply discarded ...
10860 * TODO: really?
10861 */
10862 child = child->next;
10863 }
10864 if (child != NULL) {
10865 xmlSchemaPContentErr(pctxt,
10867 NULL, node, child, NULL,
10868 "(annotation?)");
10869 }
10870 /*
10871 * Apply additional constraints.
10872 *
10873 * Note that it is important to use the original @targetNamespace
10874 * (or none at all), to rule out imports of schemas _with_ a
10875 * @targetNamespace if the importing schema is a chameleon schema
10876 * (with no @targetNamespace).
10877 */
10878 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10879 if (namespaceName != NULL) {
10880 /*
10881 * 1.1 If the namespace [attribute] is present, then its `actual value`
10882 * must not match the `actual value` of the enclosing <schema>'s
10883 * targetNamespace [attribute].
10884 */
10885 if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10886 xmlSchemaPCustomErr(pctxt,
10888 NULL, node,
10889 "The value of the attribute 'namespace' must not match "
10890 "the target namespace '%s' of the importing schema",
10891 thisTargetNamespace);
10892 return (pctxt->err);
10893 }
10894 } else {
10895 /*
10896 * 1.2 If the namespace [attribute] is not present, then the enclosing
10897 * <schema> must have a targetNamespace [attribute].
10898 */
10899 if (thisTargetNamespace == NULL) {
10900 xmlSchemaPCustomErr(pctxt,
10902 NULL, node,
10903 "The attribute 'namespace' must be existent if "
10904 "the importing schema has no target namespace",
10905 NULL);
10906 return (pctxt->err);
10907 }
10908 }
10909 /*
10910 * Locate and acquire the schema document.
10911 */
10912 if (schemaLocation != NULL)
10913 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10914 schemaLocation, node);
10915 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10916 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10917 namespaceName, &bucket);
10918
10919 if (ret != 0)
10920 return(ret);
10921
10922 /*
10923 * For <import>: "It is *not* an error for the application
10924 * schema reference strategy to fail."
10925 * So just don't parse if no schema document was found.
10926 * Note that we will get no bucket if the schema could not be
10927 * located or if there was no schemaLocation.
10928 */
10929 if ((bucket == NULL) && (schemaLocation != NULL)) {
10930 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10932 node, NULL,
10933 "Failed to locate a schema at location '%s'. "
10934 "Skipping the import", schemaLocation, NULL, NULL);
10935 }
10936
10937 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10938 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10939 }
10940
10941 return (ret);
10942}
10943
10944static int
10945xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10946 xmlSchemaPtr schema,
10948 xmlChar **schemaLocation,
10949 int type)
10950{
10952
10953 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10954 (schemaLocation == NULL))
10955 return (-1);
10956
10957 *schemaLocation = NULL;
10958 /*
10959 * Check for illegal attributes.
10960 * Applies for both <include> and <redefine>.
10961 */
10962 attr = node->properties;
10963 while (attr != NULL) {
10964 if (attr->ns == NULL) {
10965 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10966 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10967 xmlSchemaPIllegalAttrErr(pctxt,
10969 }
10970 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10971 xmlSchemaPIllegalAttrErr(pctxt,
10973 }
10974 attr = attr->next;
10975 }
10976 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10977 /*
10978 * Preliminary step, extract the URI-Reference and make an URI
10979 * from the base.
10980 */
10981 /*
10982 * Attribute "schemaLocation" is mandatory.
10983 */
10984 attr = xmlSchemaGetPropNode(node, "schemaLocation");
10985 if (attr != NULL) {
10986 xmlChar *base = NULL;
10987 xmlChar *uri = NULL;
10988
10989 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10990 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10991 (const xmlChar **) schemaLocation) != 0)
10992 goto exit_error;
10993 base = xmlNodeGetBase(node->doc, node);
10994 if (base == NULL) {
10995 uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10996 } else {
10997 uri = xmlBuildURI(*schemaLocation, base);
10998 xmlFree(base);
10999 }
11000 if (uri == NULL) {
11001 PERROR_INT("xmlSchemaParseIncludeOrRedefine",
11002 "could not build an URI from the schemaLocation")
11003 goto exit_failure;
11004 }
11005 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
11006 xmlFree(uri);
11007 } else {
11008 xmlSchemaPMissingAttrErr(pctxt,
11010 NULL, node, "schemaLocation", NULL);
11011 goto exit_error;
11012 }
11013 /*
11014 * Report self-inclusion and self-redefinition.
11015 */
11016 if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
11017 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11018 xmlSchemaPCustomErr(pctxt,
11020 NULL, node,
11021 "The schema document '%s' cannot redefine itself.",
11022 *schemaLocation);
11023 } else {
11024 xmlSchemaPCustomErr(pctxt,
11026 NULL, node,
11027 "The schema document '%s' cannot include itself.",
11028 *schemaLocation);
11029 }
11030 goto exit_error;
11031 }
11032
11033 return(0);
11034exit_error:
11035 return(pctxt->err);
11036exit_failure:
11037 return(-1);
11038}
11039
11040static int
11041xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
11042 xmlSchemaPtr schema,
11044 int type)
11045{
11047 const xmlChar *schemaLocation = NULL;
11048 int res = 0; /* hasRedefinitions = 0 */
11049 int isChameleon = 0, wasChameleon = 0;
11050 xmlSchemaBucketPtr bucket = NULL;
11051
11052 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
11053 return (-1);
11054
11055 /*
11056 * Parse attributes. Note that the returned schemaLocation will
11057 * be already converted to an absolute URI.
11058 */
11059 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
11060 node, (xmlChar **) (&schemaLocation), type);
11061 if (res != 0)
11062 return(res);
11063 /*
11064 * Load and add the schema document.
11065 */
11066 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
11067 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
11068 if (res != 0)
11069 return(res);
11070 /*
11071 * If we get no schema bucket back, then this means that the schema
11072 * document could not be located or was broken XML or was not
11073 * a schema document.
11074 */
11075 if ((bucket == NULL) || (bucket->doc == NULL)) {
11076 if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
11077 /*
11078 * WARNING for <include>:
11079 * We will raise an error if the schema cannot be located
11080 * for inclusions, since the that was the feedback from the
11081 * schema people. I.e. the following spec piece will *not* be
11082 * satisfied:
11083 * SPEC src-include: "It is not an error for the `actual value` of the
11084 * schemaLocation [attribute] to fail to resolve it all, in which
11085 * case no corresponding inclusion is performed.
11086 * So do we need a warning report here?"
11087 */
11089 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
11090 node, NULL,
11091 "Failed to load the document '%s' for inclusion",
11092 schemaLocation, NULL);
11093 } else {
11094 /*
11095 * NOTE: This was changed to raise an error even if no redefinitions
11096 * are specified.
11097 *
11098 * SPEC src-redefine (1)
11099 * "If there are any element information items among the [children]
11100 * other than <annotation> then the `actual value` of the
11101 * schemaLocation [attribute] must successfully resolve."
11102 * TODO: Ask the WG if a the location has always to resolve
11103 * here as well!
11104 */
11106 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
11107 node, NULL,
11108 "Failed to load the document '%s' for redefinition",
11109 schemaLocation, NULL);
11110 }
11111 } else {
11112 /*
11113 * Check targetNamespace sanity before parsing the new schema.
11114 * TODO: Note that we won't check further content if the
11115 * targetNamespace was bad.
11116 */
11117 if (bucket->origTargetNamespace != NULL) {
11118 /*
11119 * SPEC src-include (2.1)
11120 * "SII has a targetNamespace [attribute], and its `actual
11121 * value` is identical to the `actual value` of the targetNamespace
11122 * [attribute] of SII' (which must have such an [attribute])."
11123 */
11124 if (pctxt->targetNamespace == NULL) {
11125 xmlSchemaCustomErr(ACTXT_CAST pctxt,
11127 node, NULL,
11128 "The target namespace of the included/redefined schema "
11129 "'%s' has to be absent, since the including/redefining "
11130 "schema has no target namespace",
11131 schemaLocation, NULL);
11132 goto exit_error;
11133 } else if (!xmlStrEqual(bucket->origTargetNamespace,
11134 pctxt->targetNamespace)) {
11135 /* TODO: Change error function. */
11136 xmlSchemaPCustomErrExt(pctxt,
11138 NULL, node,
11139 "The target namespace '%s' of the included/redefined "
11140 "schema '%s' differs from '%s' of the "
11141 "including/redefining schema",
11142 bucket->origTargetNamespace, schemaLocation,
11143 pctxt->targetNamespace);
11144 goto exit_error;
11145 }
11146 } else if (pctxt->targetNamespace != NULL) {
11147 /*
11148 * Chameleons: the original target namespace will
11149 * differ from the resulting namespace.
11150 */
11151 isChameleon = 1;
11152 if (bucket->parsed &&
11153 bucket->origTargetNamespace != NULL) {
11154 xmlSchemaCustomErr(ACTXT_CAST pctxt,
11156 node, NULL,
11157 "The target namespace of the included/redefined schema "
11158 "'%s' has to be absent or the same as the "
11159 "including/redefining schema's target namespace",
11160 schemaLocation, NULL);
11161 goto exit_error;
11162 }
11163 bucket->targetNamespace = pctxt->targetNamespace;
11164 }
11165 }
11166 /*
11167 * Parse the schema.
11168 */
11169 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11170 if (isChameleon) {
11171 /* TODO: Get rid of this flag on the schema itself. */
11172 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11173 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11174 } else
11175 wasChameleon = 1;
11176 }
11177 xmlSchemaParseNewDoc(pctxt, schema, bucket);
11178 /* Restore chameleon flag. */
11179 if (isChameleon && (!wasChameleon))
11180 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11181 }
11182 /*
11183 * And now for the children...
11184 */
11185 child = node->children;
11186 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11187 /*
11188 * Parse (simpleType | complexType | group | attributeGroup))*
11189 */
11190 pctxt->redefined = bucket;
11191 /*
11192 * How to proceed if the redefined schema was not located?
11193 */
11194 pctxt->isRedefine = 1;
11195 while (IS_SCHEMA(child, "annotation") ||
11196 IS_SCHEMA(child, "simpleType") ||
11197 IS_SCHEMA(child, "complexType") ||
11198 IS_SCHEMA(child, "group") ||
11199 IS_SCHEMA(child, "attributeGroup")) {
11200 if (IS_SCHEMA(child, "annotation")) {
11201 /*
11202 * TODO: discard or not?
11203 */
11204 } else if (IS_SCHEMA(child, "simpleType")) {
11205 xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11206 } else if (IS_SCHEMA(child, "complexType")) {
11207 xmlSchemaParseComplexType(pctxt, schema, child, 1);
11208 /* hasRedefinitions = 1; */
11209 } else if (IS_SCHEMA(child, "group")) {
11210 /* hasRedefinitions = 1; */
11211 xmlSchemaParseModelGroupDefinition(pctxt,
11212 schema, child);
11213 } else if (IS_SCHEMA(child, "attributeGroup")) {
11214 /* hasRedefinitions = 1; */
11215 xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11216 child);
11217 }
11218 child = child->next;
11219 }
11220 pctxt->redefined = NULL;
11221 pctxt->isRedefine = 0;
11222 } else {
11223 if (IS_SCHEMA(child, "annotation")) {
11224 /*
11225 * TODO: discard or not?
11226 */
11227 child = child->next;
11228 }
11229 }
11230 if (child != NULL) {
11232 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11233 xmlSchemaPContentErr(pctxt, res,
11234 NULL, node, child, NULL,
11235 "(annotation | (simpleType | complexType | group | attributeGroup))*");
11236 } else {
11237 xmlSchemaPContentErr(pctxt, res,
11238 NULL, node, child, NULL,
11239 "(annotation?)");
11240 }
11241 }
11242 return(res);
11243
11244exit_error:
11245 return(pctxt->err);
11246}
11247
11248static int
11249xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11251{
11252 int res;
11253#ifndef ENABLE_REDEFINE
11254 TODO
11255 return(0);
11256#endif
11257 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11258 XML_SCHEMA_SCHEMA_REDEFINE);
11259 if (res != 0)
11260 return(res);
11261 return(0);
11262}
11263
11264static int
11265xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11267{
11268 int res;
11269
11270 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11271 XML_SCHEMA_SCHEMA_INCLUDE);
11272 if (res != 0)
11273 return(res);
11274 return(0);
11275}
11276
11302static xmlSchemaTreeItemPtr
11303xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11304 xmlNodePtr node, xmlSchemaTypeType type,
11305 int withParticle)
11306{
11307 xmlSchemaModelGroupPtr item;
11308 xmlSchemaParticlePtr particle = NULL;
11311 int min = 1, max = 1, isElemRef, hasRefs = 0;
11312
11313 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11314 return (NULL);
11315 /*
11316 * Create a model group with the given compositor.
11317 */
11318 item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11319 if (item == NULL)
11320 return (NULL);
11321
11322 if (withParticle) {
11323 if (type == XML_SCHEMA_TYPE_ALL) {
11324 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11325 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11326 } else {
11327 /* choice + sequence */
11328 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11329 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11330 "(xs:nonNegativeInteger | unbounded)");
11331 }
11332 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11333 /*
11334 * Create a particle
11335 */
11336 particle = xmlSchemaAddParticle(ctxt, node, min, max);
11337 if (particle == NULL)
11338 return (NULL);
11339 particle->children = (xmlSchemaTreeItemPtr) item;
11340 /*
11341 * Check for illegal attributes.
11342 */
11343 attr = node->properties;
11344 while (attr != NULL) {
11345 if (attr->ns == NULL) {
11346 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11347 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11348 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11349 xmlSchemaPIllegalAttrErr(ctxt,
11351 }
11352 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11353 xmlSchemaPIllegalAttrErr(ctxt,
11355 }
11356 attr = attr->next;
11357 }
11358 } else {
11359 /*
11360 * Check for illegal attributes.
11361 */
11362 attr = node->properties;
11363 while (attr != NULL) {
11364 if (attr->ns == NULL) {
11365 if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11366 xmlSchemaPIllegalAttrErr(ctxt,
11368 }
11369 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11370 xmlSchemaPIllegalAttrErr(ctxt,
11372 }
11373 attr = attr->next;
11374 }
11375 }
11376
11377 /*
11378 * Extract and validate attributes.
11379 */
11380 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11381 /*
11382 * And now for the children...
11383 */
11384 child = node->children;
11385 if (IS_SCHEMA(child, "annotation")) {
11386 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11387 child = child->next;
11388 }
11389 if (type == XML_SCHEMA_TYPE_ALL) {
11390 xmlSchemaParticlePtr part, last = NULL;
11391
11392 while (IS_SCHEMA(child, "element")) {
11393 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11394 schema, child, &isElemRef, 0);
11395 /*
11396 * SPEC cos-all-limited (2)
11397 * "The {max occurs} of all the particles in the {particles}
11398 * of the ('all') group must be 0 or 1.
11399 */
11400 if (part != NULL) {
11401 if (isElemRef)
11402 hasRefs++;
11403 if (part->minOccurs > 1) {
11404 xmlSchemaPCustomErr(ctxt,
11406 NULL, child,
11407 "Invalid value for minOccurs (must be 0 or 1)",
11408 NULL);
11409 /* Reset to 1. */
11410 part->minOccurs = 1;
11411 }
11412 if (part->maxOccurs > 1) {
11413 xmlSchemaPCustomErr(ctxt,
11415 NULL, child,
11416 "Invalid value for maxOccurs (must be 0 or 1)",
11417 NULL);
11418 /* Reset to 1. */
11419 part->maxOccurs = 1;
11420 }
11421 if (last == NULL)
11422 item->children = (xmlSchemaTreeItemPtr) part;
11423 else
11424 last->next = (xmlSchemaTreeItemPtr) part;
11425 last = part;
11426 }
11427 child = child->next;
11428 }
11429 if (child != NULL) {
11430 xmlSchemaPContentErr(ctxt,
11432 NULL, node, child, NULL,
11433 "(annotation?, (annotation?, element*)");
11434 }
11435 } else {
11436 /* choice + sequence */
11437 xmlSchemaTreeItemPtr part = NULL, last = NULL;
11438
11439 while ((IS_SCHEMA(child, "element")) ||
11440 (IS_SCHEMA(child, "group")) ||
11441 (IS_SCHEMA(child, "any")) ||
11442 (IS_SCHEMA(child, "choice")) ||
11443 (IS_SCHEMA(child, "sequence"))) {
11444
11445 if (IS_SCHEMA(child, "element")) {
11446 part = (xmlSchemaTreeItemPtr)
11447 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11448 if (part && isElemRef)
11449 hasRefs++;
11450 } else if (IS_SCHEMA(child, "group")) {
11451 part =
11452 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11453 if (part != NULL)
11454 hasRefs++;
11455 /*
11456 * Handle redefinitions.
11457 */
11458 if (ctxt->isRedefine && ctxt->redef &&
11459 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11460 part && part->children)
11461 {
11462 if ((xmlSchemaGetQNameRefName(part->children) ==
11463 ctxt->redef->refName) &&
11464 (xmlSchemaGetQNameRefTargetNs(part->children) ==
11465 ctxt->redef->refTargetNs))
11466 {
11467 /*
11468 * SPEC src-redefine:
11469 * (6.1) "If it has a <group> among its contents at
11470 * some level the `actual value` of whose ref
11471 * [attribute] is the same as the `actual value` of
11472 * its own name attribute plus target namespace, then
11473 * all of the following must be true:"
11474 * (6.1.1) "It must have exactly one such group."
11475 */
11476 if (ctxt->redefCounter != 0) {
11477 xmlChar *str = NULL;
11478
11479 xmlSchemaCustomErr(ACTXT_CAST ctxt,
11481 "The redefining model group definition "
11482 "'%s' must not contain more than one "
11483 "reference to the redefined definition",
11484 xmlSchemaFormatQName(&str,
11485 ctxt->redef->refTargetNs,
11486 ctxt->redef->refName),
11487 NULL);
11488 FREE_AND_NULL(str)
11489 part = NULL;
11490 } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11491 ((WXS_PARTICLE(part))->maxOccurs != 1))
11492 {
11493 xmlChar *str = NULL;
11494 /*
11495 * SPEC src-redefine:
11496 * (6.1.2) "The `actual value` of both that
11497 * group's minOccurs and maxOccurs [attribute]
11498 * must be 1 (or `absent`).
11499 */
11500 xmlSchemaCustomErr(ACTXT_CAST ctxt,
11502 "The redefining model group definition "
11503 "'%s' must not contain a reference to the "
11504 "redefined definition with a "
11505 "maxOccurs/minOccurs other than 1",
11506 xmlSchemaFormatQName(&str,
11507 ctxt->redef->refTargetNs,
11508 ctxt->redef->refName),
11509 NULL);
11510 FREE_AND_NULL(str)
11511 part = NULL;
11512 }
11513 ctxt->redef->reference = WXS_BASIC_CAST part;
11514 ctxt->redefCounter++;
11515 }
11516 }
11517 } else if (IS_SCHEMA(child, "any")) {
11518 part = (xmlSchemaTreeItemPtr)
11519 xmlSchemaParseAny(ctxt, schema, child);
11520 } else if (IS_SCHEMA(child, "choice")) {
11521 part = xmlSchemaParseModelGroup(ctxt, schema, child,
11522 XML_SCHEMA_TYPE_CHOICE, 1);
11523 } else if (IS_SCHEMA(child, "sequence")) {
11524 part = xmlSchemaParseModelGroup(ctxt, schema, child,
11525 XML_SCHEMA_TYPE_SEQUENCE, 1);
11526 }
11527 if (part != NULL) {
11528 if (last == NULL)
11529 item->children = part;
11530 else
11531 last->next = part;
11532 last = part;
11533 }
11534 child = child->next;
11535 }
11536 if (child != NULL) {
11537 xmlSchemaPContentErr(ctxt,
11539 NULL, node, child, NULL,
11540 "(annotation?, (element | group | choice | sequence | any)*)");
11541 }
11542 }
11543 if ((max == 0) && (min == 0))
11544 return (NULL);
11545 if (hasRefs) {
11546 /*
11547 * We need to resolve references.
11548 */
11549 WXS_ADD_PENDING(ctxt, item);
11550 }
11551 if (withParticle)
11552 return ((xmlSchemaTreeItemPtr) particle);
11553 else
11554 return ((xmlSchemaTreeItemPtr) item);
11555}
11556
11568static xmlSchemaTypePtr
11569xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11570 xmlNodePtr node, xmlSchemaTypeType parentType)
11571{
11572 xmlSchemaTypePtr type;
11575
11576 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11577 return (NULL);
11578 /* Not a component, don't create it. */
11579 type = ctxt->ctxtType;
11580 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11581
11582 /*
11583 * Check for illegal attributes.
11584 */
11585 attr = node->properties;
11586 while (attr != NULL) {
11587 if (attr->ns == NULL) {
11588 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11589 (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11590 xmlSchemaPIllegalAttrErr(ctxt,
11592 }
11593 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11594 xmlSchemaPIllegalAttrErr(ctxt,
11596 }
11597 attr = attr->next;
11598 }
11599 /*
11600 * Extract and validate attributes.
11601 */
11602 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11603 /*
11604 * Attribute
11605 */
11606 /*
11607 * Extract the base type. The "base" attribute is mandatory if inside
11608 * a complex type or if redefining.
11609 *
11610 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11611 * among its [children]), the simple type definition which is
11612 * the {content type} of the type definition `resolved` to by
11613 * the `actual value` of the base [attribute]"
11614 */
11615 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11616 &(type->baseNs), &(type->base)) == 0)
11617 {
11618 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11619 xmlSchemaPMissingAttrErr(ctxt,
11621 NULL, node, "base", NULL);
11622 } else if ((ctxt->isRedefine) &&
11623 (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11624 {
11625 if (type->base == NULL) {
11626 xmlSchemaPMissingAttrErr(ctxt,
11628 NULL, node, "base", NULL);
11629 } else if ((! xmlStrEqual(type->base, type->name)) ||
11630 (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11631 {
11632 xmlChar *str1 = NULL, *str2 = NULL;
11633 /*
11634 * REDEFINE: SPEC src-redefine (5)
11635 * "Within the [children], each <simpleType> must have a
11636 * <restriction> among its [children] ... the `actual value` of
11637 * whose base [attribute] must be the same as the `actual value`
11638 * of its own name attribute plus target namespace;"
11639 */
11640 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11641 NULL, node, "This is a redefinition, but the QName "
11642 "value '%s' of the 'base' attribute does not match the "
11643 "type's designation '%s'",
11644 xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11645 xmlSchemaFormatQName(&str2, type->targetNamespace,
11646 type->name), NULL);
11647 FREE_AND_NULL(str1);
11648 FREE_AND_NULL(str2);
11649 /* Avoid confusion and erase the values. */
11650 type->base = NULL;
11651 type->baseNs = NULL;
11652 }
11653 }
11654 }
11655 /*
11656 * And now for the children...
11657 */
11658 child = node->children;
11659 if (IS_SCHEMA(child, "annotation")) {
11660 /*
11661 * Add the annotation to the simple type ancestor.
11662 */
11663 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11664 xmlSchemaParseAnnotation(ctxt, child, 1));
11665 child = child->next;
11666 }
11667 if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11668 /*
11669 * Corresponds to <simpleType><restriction><simpleType>.
11670 */
11671 if (IS_SCHEMA(child, "simpleType")) {
11672 if (type->base != NULL) {
11673 /*
11674 * src-restriction-base-or-simpleType
11675 * Either the base [attribute] or the simpleType [child] of the
11676 * <restriction> element must be present, but not both.
11677 */
11678 xmlSchemaPContentErr(ctxt,
11680 NULL, node, child,
11681 "The attribute 'base' and the <simpleType> child are "
11682 "mutually exclusive", NULL);
11683 } else {
11684 type->baseType = (xmlSchemaTypePtr)
11685 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11686 }
11687 child = child->next;
11688 } else if (type->base == NULL) {
11689 xmlSchemaPContentErr(ctxt,
11691 NULL, node, child,
11692 "Either the attribute 'base' or a <simpleType> child "
11693 "must be present", NULL);
11694 }
11695 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11696 /*
11697 * Corresponds to <complexType><complexContent><restriction>...
11698 * followed by:
11699 *
11700 * Model groups <all>, <choice> and <sequence>.
11701 */
11702 if (IS_SCHEMA(child, "all")) {
11703 type->subtypes = (xmlSchemaTypePtr)
11704 xmlSchemaParseModelGroup(ctxt, schema, child,
11705 XML_SCHEMA_TYPE_ALL, 1);
11706 child = child->next;
11707 } else if (IS_SCHEMA(child, "choice")) {
11708 type->subtypes = (xmlSchemaTypePtr)
11709 xmlSchemaParseModelGroup(ctxt,
11710 schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11711 child = child->next;
11712 } else if (IS_SCHEMA(child, "sequence")) {
11713 type->subtypes = (xmlSchemaTypePtr)
11714 xmlSchemaParseModelGroup(ctxt, schema, child,
11715 XML_SCHEMA_TYPE_SEQUENCE, 1);
11716 child = child->next;
11717 /*
11718 * Model group reference <group>.
11719 */
11720 } else if (IS_SCHEMA(child, "group")) {
11721 type->subtypes = (xmlSchemaTypePtr)
11722 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11723 /*
11724 * Note that the reference will be resolved in
11725 * xmlSchemaResolveTypeReferences();
11726 */
11727 child = child->next;
11728 }
11729 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11730 /*
11731 * Corresponds to <complexType><simpleContent><restriction>...
11732 *
11733 * "1.1 the simple type definition corresponding to the <simpleType>
11734 * among the [children] of <restriction> if there is one;"
11735 */
11736 if (IS_SCHEMA(child, "simpleType")) {
11737 /*
11738 * We will store the to-be-restricted simple type in
11739 * type->contentTypeDef *temporarily*.
11740 */
11741 type->contentTypeDef = (xmlSchemaTypePtr)
11742 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11743 if ( type->contentTypeDef == NULL)
11744 return (NULL);
11745 child = child->next;
11746 }
11747 }
11748
11749 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11750 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11751 xmlSchemaFacetPtr facet, lastfacet = NULL;
11752 /*
11753 * Corresponds to <complexType><simpleContent><restriction>...
11754 * <simpleType><restriction>...
11755 */
11756
11757 /*
11758 * Add the facets to the simple type ancestor.
11759 */
11760 /*
11761 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11762 * Simple Type Definition Schema Representation Constraint:
11763 * *Single Facet Value*
11764 */
11765 while ((IS_SCHEMA(child, "minInclusive")) ||
11766 (IS_SCHEMA(child, "minExclusive")) ||
11767 (IS_SCHEMA(child, "maxInclusive")) ||
11768 (IS_SCHEMA(child, "maxExclusive")) ||
11769 (IS_SCHEMA(child, "totalDigits")) ||
11770 (IS_SCHEMA(child, "fractionDigits")) ||
11771 (IS_SCHEMA(child, "pattern")) ||
11772 (IS_SCHEMA(child, "enumeration")) ||
11773 (IS_SCHEMA(child, "whiteSpace")) ||
11774 (IS_SCHEMA(child, "length")) ||
11775 (IS_SCHEMA(child, "maxLength")) ||
11776 (IS_SCHEMA(child, "minLength"))) {
11777 facet = xmlSchemaParseFacet(ctxt, schema, child);
11778 if (facet != NULL) {
11779 if (lastfacet == NULL)
11780 type->facets = facet;
11781 else
11782 lastfacet->next = facet;
11783 lastfacet = facet;
11784 lastfacet->next = NULL;
11785 }
11786 child = child->next;
11787 }
11788 /*
11789 * Create links for derivation and validation.
11790 */
11791 if (type->facets != NULL) {
11792 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11793
11794 facet = type->facets;
11795 do {
11796 facetLink = (xmlSchemaFacetLinkPtr)
11797 xmlMalloc(sizeof(xmlSchemaFacetLink));
11798 if (facetLink == NULL) {
11799 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11800 xmlFree(facetLink);
11801 return (NULL);
11802 }
11803 facetLink->facet = facet;
11804 facetLink->next = NULL;
11805 if (lastFacetLink == NULL)
11806 type->facetSet = facetLink;
11807 else
11808 lastFacetLink->next = facetLink;
11809 lastFacetLink = facetLink;
11810 facet = facet->next;
11811 } while (facet != NULL);
11812 }
11813 }
11814 if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11815 /*
11816 * Attribute uses/declarations.
11817 */
11818 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11819 (xmlSchemaItemListPtr *) &(type->attrUses),
11820 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11821 return(NULL);
11822 /*
11823 * Attribute wildcard.
11824 */
11825 if (IS_SCHEMA(child, "anyAttribute")) {
11826 type->attributeWildcard =
11827 xmlSchemaParseAnyAttribute(ctxt, schema, child);
11828 child = child->next;
11829 }
11830 }
11831 if (child != NULL) {
11832 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11833 xmlSchemaPContentErr(ctxt,
11835 NULL, node, child, NULL,
11836 "annotation?, (group | all | choice | sequence)?, "
11837 "((attribute | attributeGroup)*, anyAttribute?))");
11838 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11839 xmlSchemaPContentErr(ctxt,
11841 NULL, node, child, NULL,
11842 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11843 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11844 "length | minLength | maxLength | enumeration | whiteSpace | "
11845 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11846 } else {
11847 /* Simple type */
11848 xmlSchemaPContentErr(ctxt,
11850 NULL, node, child, NULL,
11851 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11852 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11853 "length | minLength | maxLength | enumeration | whiteSpace | "
11854 "pattern)*))");
11855 }
11856 }
11857 return (NULL);
11858}
11859
11872static xmlSchemaTypePtr
11873xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11874 xmlNodePtr node, xmlSchemaTypeType parentType)
11875{
11876 xmlSchemaTypePtr type;
11879
11880 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11881 return (NULL);
11882 /* Not a component, don't create it. */
11883 type = ctxt->ctxtType;
11884 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11885
11886 /*
11887 * Check for illegal attributes.
11888 */
11889 attr = node->properties;
11890 while (attr != NULL) {
11891 if (attr->ns == NULL) {
11892 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11893 (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11894 xmlSchemaPIllegalAttrErr(ctxt,
11896 }
11897 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11898 xmlSchemaPIllegalAttrErr(ctxt,
11900 }
11901 attr = attr->next;
11902 }
11903
11904 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11905
11906 /*
11907 * Attribute "base" - mandatory.
11908 */
11909 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11910 "base", &(type->baseNs), &(type->base)) == 0) &&
11911 (type->base == NULL)) {
11912 xmlSchemaPMissingAttrErr(ctxt,
11914 NULL, node, "base", NULL);
11915 }
11916 /*
11917 * And now for the children...
11918 */
11919 child = node->children;
11920 if (IS_SCHEMA(child, "annotation")) {
11921 /*
11922 * Add the annotation to the type ancestor.
11923 */
11924 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11925 xmlSchemaParseAnnotation(ctxt, child, 1));
11926 child = child->next;
11927 }
11928 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11929 /*
11930 * Corresponds to <complexType><complexContent><extension>... and:
11931 *
11932 * Model groups <all>, <choice>, <sequence> and <group>.
11933 */
11934 if (IS_SCHEMA(child, "all")) {
11935 type->subtypes = (xmlSchemaTypePtr)
11936 xmlSchemaParseModelGroup(ctxt, schema,
11937 child, XML_SCHEMA_TYPE_ALL, 1);
11938 child = child->next;
11939 } else if (IS_SCHEMA(child, "choice")) {
11940 type->subtypes = (xmlSchemaTypePtr)
11941 xmlSchemaParseModelGroup(ctxt, schema,
11942 child, XML_SCHEMA_TYPE_CHOICE, 1);
11943 child = child->next;
11944 } else if (IS_SCHEMA(child, "sequence")) {
11945 type->subtypes = (xmlSchemaTypePtr)
11946 xmlSchemaParseModelGroup(ctxt, schema,
11947 child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11948 child = child->next;
11949 } else if (IS_SCHEMA(child, "group")) {
11950 type->subtypes = (xmlSchemaTypePtr)
11951 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11952 /*
11953 * Note that the reference will be resolved in
11954 * xmlSchemaResolveTypeReferences();
11955 */
11956 child = child->next;
11957 }
11958 }
11959 if (child != NULL) {
11960 /*
11961 * Attribute uses/declarations.
11962 */
11963 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11964 (xmlSchemaItemListPtr *) &(type->attrUses),
11965 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11966 return(NULL);
11967 /*
11968 * Attribute wildcard.
11969 */
11970 if (IS_SCHEMA(child, "anyAttribute")) {
11971 ctxt->ctxtType->attributeWildcard =
11972 xmlSchemaParseAnyAttribute(ctxt, schema, child);
11973 child = child->next;
11974 }
11975 }
11976 if (child != NULL) {
11977 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11978 /* Complex content extension. */
11979 xmlSchemaPContentErr(ctxt,
11981 NULL, node, child, NULL,
11982 "(annotation?, ((group | all | choice | sequence)?, "
11983 "((attribute | attributeGroup)*, anyAttribute?)))");
11984 } else {
11985 /* Simple content extension. */
11986 xmlSchemaPContentErr(ctxt,
11988 NULL, node, child, NULL,
11989 "(annotation?, ((attribute | attributeGroup)*, "
11990 "anyAttribute?))");
11991 }
11992 }
11993 return (NULL);
11994}
11995
12007static int
12008xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
12009 xmlSchemaPtr schema, xmlNodePtr node,
12010 int *hasRestrictionOrExtension)
12011{
12012 xmlSchemaTypePtr type;
12015
12016 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
12017 (hasRestrictionOrExtension == NULL))
12018 return (-1);
12019 *hasRestrictionOrExtension = 0;
12020 /* Not a component, don't create it. */
12021 type = ctxt->ctxtType;
12022 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
12023 /*
12024 * Check for illegal attributes.
12025 */
12026 attr = node->properties;
12027 while (attr != NULL) {
12028 if (attr->ns == NULL) {
12029 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
12030 xmlSchemaPIllegalAttrErr(ctxt,
12032 }
12033 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12034 xmlSchemaPIllegalAttrErr(ctxt,
12036 }
12037 attr = attr->next;
12038 }
12039
12040 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12041
12042 /*
12043 * And now for the children...
12044 */
12045 child = node->children;
12046 if (IS_SCHEMA(child, "annotation")) {
12047 /*
12048 * Add the annotation to the complex type ancestor.
12049 */
12050 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12051 xmlSchemaParseAnnotation(ctxt, child, 1));
12052 child = child->next;
12053 }
12054 if (child == NULL) {
12055 xmlSchemaPContentErr(ctxt,
12057 NULL, node, NULL, NULL,
12058 "(annotation?, (restriction | extension))");
12059 }
12060 if (child == NULL) {
12061 xmlSchemaPContentErr(ctxt,
12063 NULL, node, NULL, NULL,
12064 "(annotation?, (restriction | extension))");
12065 }
12066 if (IS_SCHEMA(child, "restriction")) {
12067 xmlSchemaParseRestriction(ctxt, schema, child,
12068 XML_SCHEMA_TYPE_SIMPLE_CONTENT);
12069 (*hasRestrictionOrExtension) = 1;
12070 child = child->next;
12071 } else if (IS_SCHEMA(child, "extension")) {
12072 xmlSchemaParseExtension(ctxt, schema, child,
12073 XML_SCHEMA_TYPE_SIMPLE_CONTENT);
12074 (*hasRestrictionOrExtension) = 1;
12075 child = child->next;
12076 }
12077 if (child != NULL) {
12078 xmlSchemaPContentErr(ctxt,
12080 NULL, node, child, NULL,
12081 "(annotation?, (restriction | extension))");
12082 }
12083 return (0);
12084}
12085
12097static int
12098xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
12099 xmlSchemaPtr schema, xmlNodePtr node,
12100 int *hasRestrictionOrExtension)
12101{
12102 xmlSchemaTypePtr type;
12105
12106 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
12107 (hasRestrictionOrExtension == NULL))
12108 return (-1);
12109 *hasRestrictionOrExtension = 0;
12110 /* Not a component, don't create it. */
12111 type = ctxt->ctxtType;
12112 /*
12113 * Check for illegal attributes.
12114 */
12115 attr = node->properties;
12116 while (attr != NULL) {
12117 if (attr->ns == NULL) {
12118 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
12119 (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
12120 {
12121 xmlSchemaPIllegalAttrErr(ctxt,
12123 }
12124 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12125 xmlSchemaPIllegalAttrErr(ctxt,
12127 }
12128 attr = attr->next;
12129 }
12130
12131 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12132
12133 /*
12134 * Set the 'mixed' on the complex type ancestor.
12135 */
12136 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
12137 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12138 type->flags |= XML_SCHEMAS_TYPE_MIXED;
12139 }
12140 child = node->children;
12141 if (IS_SCHEMA(child, "annotation")) {
12142 /*
12143 * Add the annotation to the complex type ancestor.
12144 */
12145 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12146 xmlSchemaParseAnnotation(ctxt, child, 1));
12147 child = child->next;
12148 }
12149 if (child == NULL) {
12150 xmlSchemaPContentErr(ctxt,
12152 NULL, node, NULL,
12153 NULL, "(annotation?, (restriction | extension))");
12154 }
12155 if (child == NULL) {
12156 xmlSchemaPContentErr(ctxt,
12158 NULL, node, NULL,
12159 NULL, "(annotation?, (restriction | extension))");
12160 }
12161 if (IS_SCHEMA(child, "restriction")) {
12162 xmlSchemaParseRestriction(ctxt, schema, child,
12163 XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12164 (*hasRestrictionOrExtension) = 1;
12165 child = child->next;
12166 } else if (IS_SCHEMA(child, "extension")) {
12167 xmlSchemaParseExtension(ctxt, schema, child,
12168 XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12169 (*hasRestrictionOrExtension) = 1;
12170 child = child->next;
12171 }
12172 if (child != NULL) {
12173 xmlSchemaPContentErr(ctxt,
12175 NULL, node, child,
12176 NULL, "(annotation?, (restriction | extension))");
12177 }
12178 return (0);
12179}
12180
12192static xmlSchemaTypePtr
12193xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12194 xmlNodePtr node, int topLevel)
12195{
12196 xmlSchemaTypePtr type, ctxtType;
12198 const xmlChar *name = NULL;
12200 const xmlChar *attrValue;
12201#ifdef ENABLE_NAMED_LOCALS
12202 char buf[40];
12203#endif
12204 int final = 0, block = 0, hasRestrictionOrExtension = 0;
12205
12206
12207 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12208 return (NULL);
12209
12210 ctxtType = ctxt->ctxtType;
12211
12212 if (topLevel) {
12213 attr = xmlSchemaGetPropNode(node, "name");
12214 if (attr == NULL) {
12215 xmlSchemaPMissingAttrErr(ctxt,
12217 return (NULL);
12218 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12219 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12220 return (NULL);
12221 }
12222 }
12223
12224 if (topLevel == 0) {
12225 /*
12226 * Parse as local complex type definition.
12227 */
12228#ifdef ENABLE_NAMED_LOCALS
12229 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12230 type = xmlSchemaAddType(ctxt, schema,
12231 XML_SCHEMA_TYPE_COMPLEX,
12232 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12233 ctxt->targetNamespace, node, 0);
12234#else
12235 type = xmlSchemaAddType(ctxt, schema,
12236 XML_SCHEMA_TYPE_COMPLEX,
12237 NULL, ctxt->targetNamespace, node, 0);
12238#endif
12239 if (type == NULL)
12240 return (NULL);
12241 name = type->name;
12242 type->node = node;
12243 type->type = XML_SCHEMA_TYPE_COMPLEX;
12244 /*
12245 * TODO: We need the target namespace.
12246 */
12247 } else {
12248 /*
12249 * Parse as global complex type definition.
12250 */
12251 type = xmlSchemaAddType(ctxt, schema,
12252 XML_SCHEMA_TYPE_COMPLEX,
12253 name, ctxt->targetNamespace, node, 1);
12254 if (type == NULL)
12255 return (NULL);
12256 type->node = node;
12257 type->type = XML_SCHEMA_TYPE_COMPLEX;
12258 type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12259 }
12260 type->targetNamespace = ctxt->targetNamespace;
12261 /*
12262 * Handle attributes.
12263 */
12264 attr = node->properties;
12265 while (attr != NULL) {
12266 if (attr->ns == NULL) {
12267 if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12268 /*
12269 * Attribute "id".
12270 */
12271 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12272 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12273 /*
12274 * Attribute "mixed".
12275 */
12276 if (xmlSchemaPGetBoolNodeValue(ctxt,
12277 NULL, (xmlNodePtr) attr))
12278 type->flags |= XML_SCHEMAS_TYPE_MIXED;
12279 } else if (topLevel) {
12280 /*
12281 * Attributes of global complex type definitions.
12282 */
12283 if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12284 /* Pass. */
12285 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12286 /*
12287 * Attribute "abstract".
12288 */
12289 if (xmlSchemaPGetBoolNodeValue(ctxt,
12290 NULL, (xmlNodePtr) attr))
12291 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12292 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12293 /*
12294 * Attribute "final".
12295 */
12296 attrValue = xmlSchemaGetNodeContent(ctxt,
12297 (xmlNodePtr) attr);
12298 if (xmlSchemaPValAttrBlockFinal(attrValue,
12299 &(type->flags),
12300 -1,
12301 XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12302 XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12303 -1, -1, -1) != 0)
12304 {
12305 xmlSchemaPSimpleTypeErr(ctxt,
12308 "(#all | List of (extension | restriction))",
12309 attrValue, NULL, NULL, NULL);
12310 } else
12311 final = 1;
12312 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12313 /*
12314 * Attribute "block".
12315 */
12316 attrValue = xmlSchemaGetNodeContent(ctxt,
12317 (xmlNodePtr) attr);
12318 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12319 -1,
12320 XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12321 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12322 -1, -1, -1) != 0) {
12323 xmlSchemaPSimpleTypeErr(ctxt,
12326 "(#all | List of (extension | restriction)) ",
12327 attrValue, NULL, NULL, NULL);
12328 } else
12329 block = 1;
12330 } else {
12331 xmlSchemaPIllegalAttrErr(ctxt,
12333 }
12334 } else {
12335 xmlSchemaPIllegalAttrErr(ctxt,
12337 }
12338 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12339 xmlSchemaPIllegalAttrErr(ctxt,
12341 }
12342 attr = attr->next;
12343 }
12344 if (! block) {
12345 /*
12346 * Apply default "block" values.
12347 */
12348 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12349 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12350 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12351 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12352 }
12353 if (! final) {
12354 /*
12355 * Apply default "block" values.
12356 */
12357 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12358 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12359 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12360 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12361 }
12362 /*
12363 * And now for the children...
12364 */
12365 child = node->children;
12366 if (IS_SCHEMA(child, "annotation")) {
12367 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12368 child = child->next;
12369 }
12370 ctxt->ctxtType = type;
12371 if (IS_SCHEMA(child, "simpleContent")) {
12372 /*
12373 * <complexType><simpleContent>...
12374 * 3.4.3 : 2.2
12375 * Specifying mixed='true' when the <simpleContent>
12376 * alternative is chosen has no effect
12377 */
12378 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12379 type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12380 xmlSchemaParseSimpleContent(ctxt, schema, child,
12381 &hasRestrictionOrExtension);
12382 child = child->next;
12383 } else if (IS_SCHEMA(child, "complexContent")) {
12384 /*
12385 * <complexType><complexContent>...
12386 */
12387 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12388 xmlSchemaParseComplexContent(ctxt, schema, child,
12389 &hasRestrictionOrExtension);
12390 child = child->next;
12391 } else {
12392 /*
12393 * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12394 *
12395 * SPEC
12396 * "...the third alternative (neither <simpleContent> nor
12397 * <complexContent>) is chosen. This case is understood as shorthand
12398 * for complex content restricting the `ur-type definition`, and the
12399 * details of the mappings should be modified as necessary.
12400 */
12401 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12402 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12403 /*
12404 * Parse model groups.
12405 */
12406 if (IS_SCHEMA(child, "all")) {
12407 type->subtypes = (xmlSchemaTypePtr)
12408 xmlSchemaParseModelGroup(ctxt, schema, child,
12409 XML_SCHEMA_TYPE_ALL, 1);
12410 child = child->next;
12411 } else if (IS_SCHEMA(child, "choice")) {
12412 type->subtypes = (xmlSchemaTypePtr)
12413 xmlSchemaParseModelGroup(ctxt, schema, child,
12414 XML_SCHEMA_TYPE_CHOICE, 1);
12415 child = child->next;
12416 } else if (IS_SCHEMA(child, "sequence")) {
12417 type->subtypes = (xmlSchemaTypePtr)
12418 xmlSchemaParseModelGroup(ctxt, schema, child,
12419 XML_SCHEMA_TYPE_SEQUENCE, 1);
12420 child = child->next;
12421 } else if (IS_SCHEMA(child, "group")) {
12422 type->subtypes = (xmlSchemaTypePtr)
12423 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12424 /*
12425 * Note that the reference will be resolved in
12426 * xmlSchemaResolveTypeReferences();
12427 */
12428 child = child->next;
12429 }
12430 /*
12431 * Parse attribute decls/refs.
12432 */
12433 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12434 (xmlSchemaItemListPtr *) &(type->attrUses),
12435 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12436 return(NULL);
12437 /*
12438 * Parse attribute wildcard.
12439 */
12440 if (IS_SCHEMA(child, "anyAttribute")) {
12441 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12442 child = child->next;
12443 }
12444 }
12445 if (child != NULL) {
12446 xmlSchemaPContentErr(ctxt,
12448 NULL, node, child,
12449 NULL, "(annotation?, (simpleContent | complexContent | "
12450 "((group | all | choice | sequence)?, ((attribute | "
12451 "attributeGroup)*, anyAttribute?))))");
12452 }
12453 /*
12454 * REDEFINE: SPEC src-redefine (5)
12455 */
12456 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12457 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12458 NULL, node, "This is a redefinition, thus the "
12459 "<complexType> must have a <restriction> or <extension> "
12460 "grand-child", NULL);
12461 }
12462 ctxt->ctxtType = ctxtType;
12463 return (type);
12464}
12465
12466/************************************************************************
12467 * *
12468 * Validating using Schemas *
12469 * *
12470 ************************************************************************/
12471
12472/************************************************************************
12473 * *
12474 * Reading/Writing Schemas *
12475 * *
12476 ************************************************************************/
12477
12478#if 0 /* Will be enabled if it is clear what options are needed. */
12489static int
12490xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12491 int options)
12492
12493{
12494 int i;
12495
12496 if (ctxt == NULL)
12497 return (-1);
12498 /*
12499 * WARNING: Change the start value if adding to the
12500 * xmlSchemaParseOption.
12501 */
12502 for (i = 1; i < (int) sizeof(int) * 8; i++) {
12503 if (options & 1<<i) {
12504 return (-1);
12505 }
12506 }
12507 ctxt->options = options;
12508 return (0);
12509}
12510
12517static int
12518xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12519
12520{
12521 if (ctxt == NULL)
12522 return (-1);
12523 else
12524 return (ctxt->options);
12525}
12526#endif
12527
12537xmlSchemaParserCtxtPtr
12538xmlSchemaNewParserCtxt(const char *URL)
12539{
12540 xmlSchemaParserCtxtPtr ret;
12541
12542 if (URL == NULL)
12543 return (NULL);
12544
12545 ret = xmlSchemaParserCtxtCreate();
12546 if (ret == NULL)
12547 return(NULL);
12548 ret->dict = xmlDictCreate();
12549 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12550 return (ret);
12551}
12552
12563xmlSchemaParserCtxtPtr
12564xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12565{
12566 xmlSchemaParserCtxtPtr ret;
12567
12568 if ((buffer == NULL) || (size <= 0))
12569 return (NULL);
12570 ret = xmlSchemaParserCtxtCreate();
12571 if (ret == NULL)
12572 return(NULL);
12573 ret->buffer = buffer;
12574 ret->size = size;
12575 ret->dict = xmlDictCreate();
12576 return (ret);
12577}
12578
12588xmlSchemaParserCtxtPtr
12589xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12590{
12591 xmlSchemaParserCtxtPtr ret;
12592
12593 if (doc == NULL)
12594 return (NULL);
12595 ret = xmlSchemaParserCtxtCreate();
12596 if (ret == NULL)
12597 return(NULL);
12598 ret->doc = doc;
12599 ret->dict = xmlDictCreate();
12600 /* The application has responsibility for the document */
12601 ret->preserve = 1;
12602
12603 return (ret);
12604}
12605
12612void
12613xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12614{
12615 if (ctxt == NULL)
12616 return;
12617 if (ctxt->doc != NULL && !ctxt->preserve)
12618 xmlFreeDoc(ctxt->doc);
12619 if (ctxt->vctxt != NULL) {
12620 xmlSchemaFreeValidCtxt(ctxt->vctxt);
12621 }
12622 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12623 xmlSchemaConstructionCtxtFree(ctxt->constructor);
12624 ctxt->constructor = NULL;
12625 ctxt->ownsConstructor = 0;
12626 }
12627 if (ctxt->attrProhibs != NULL)
12628 xmlSchemaItemListFree(ctxt->attrProhibs);
12629 xmlDictFree(ctxt->dict);
12630 xmlFree(ctxt);
12631}
12632
12633/************************************************************************
12634 * *
12635 * Building the content models *
12636 * *
12637 ************************************************************************/
12638
12644static int
12645xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12646 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12647{
12648 xmlAutomataStatePtr start, tmp;
12649 xmlSchemaElementPtr elemDecl, member;
12650 xmlSchemaSubstGroupPtr substGroup;
12651 int i;
12652 int ret = 0;
12653
12654 elemDecl = (xmlSchemaElementPtr) particle->children;
12655 /*
12656 * Wrap the substitution group with a CHOICE.
12657 */
12658 start = pctxt->state;
12659 if (end == NULL)
12660 end = xmlAutomataNewState(pctxt->am);
12661 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12662 if (substGroup == NULL) {
12663 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12665 "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12666 "declaration is marked having a subst. group but none "
12667 "available.\n", elemDecl->name, NULL);
12668 return(0);
12669 }
12670 if (counter >= 0) {
12671 /*
12672 * NOTE that we put the declaration in, even if it's abstract.
12673 * However, an error will be raised during *validation* if an element
12674 * information item shall be validated against an abstract element
12675 * declaration.
12676 */
12677 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12678 xmlAutomataNewTransition2(pctxt->am, tmp, end,
12679 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12680 /*
12681 * Add subst. group members.
12682 */
12683 for (i = 0; i < substGroup->members->nbItems; i++) {
12684 member = (xmlSchemaElementPtr) substGroup->members->items[i];
12685 xmlAutomataNewTransition2(pctxt->am, tmp, end,
12686 member->name, member->targetNamespace, member);
12687 }
12688 } else if (particle->maxOccurs == 1) {
12689 /*
12690 * NOTE that we put the declaration in, even if it's abstract,
12691 */
12692 xmlAutomataNewEpsilon(pctxt->am,
12693 xmlAutomataNewTransition2(pctxt->am,
12694 start, NULL,
12695 elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12696 /*
12697 * Add subst. group members.
12698 */
12699 for (i = 0; i < substGroup->members->nbItems; i++) {
12700 member = (xmlSchemaElementPtr) substGroup->members->items[i];
12701 /*
12702 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12703 * was incorrectly used instead of xmlAutomataNewTransition2()
12704 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12705 * section in xmlSchemaBuildAContentModel() ).
12706 * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12707 * intended for the above "counter" section originally. I.e.,
12708 * check xs:all with subst-groups.
12709 *
12710 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12711 * member->name, member->targetNamespace,
12712 * 1, 1, member);
12713 */
12714 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12715 member->name, member->targetNamespace, member);
12716 xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12717 }
12718 } else {
12719 xmlAutomataStatePtr hop;
12720 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12721 UNBOUNDED : particle->maxOccurs - 1;
12722 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12723
12724 counter =
12725 xmlAutomataNewCounter(pctxt->am, minOccurs,
12726 maxOccurs);
12727 hop = xmlAutomataNewState(pctxt->am);
12728
12729 xmlAutomataNewEpsilon(pctxt->am,
12730 xmlAutomataNewTransition2(pctxt->am,
12731 start, NULL,
12732 elemDecl->name, elemDecl->targetNamespace, elemDecl),
12733 hop);
12734 /*
12735 * Add subst. group members.
12736 */
12737 for (i = 0; i < substGroup->members->nbItems; i++) {
12738 member = (xmlSchemaElementPtr) substGroup->members->items[i];
12739 xmlAutomataNewEpsilon(pctxt->am,
12740 xmlAutomataNewTransition2(pctxt->am,
12741 start, NULL,
12742 member->name, member->targetNamespace, member),
12743 hop);
12744 }
12745 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12746 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12747 }
12748 if (particle->minOccurs == 0) {
12749 xmlAutomataNewEpsilon(pctxt->am, start, end);
12750 ret = 1;
12751 }
12752 pctxt->state = end;
12753 return(ret);
12754}
12755
12761static int
12762xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12763 xmlSchemaParticlePtr particle)
12764{
12765 int ret = 0;
12766
12767 if (((xmlSchemaElementPtr) particle->children)->flags &
12768 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12769 /*
12770 * Substitution groups.
12771 */
12772 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12773 } else {
12774 xmlSchemaElementPtr elemDecl;
12775 xmlAutomataStatePtr start;
12776
12777 elemDecl = (xmlSchemaElementPtr) particle->children;
12778
12779 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12780 return(0);
12781 if (particle->maxOccurs == 1) {
12782 start = ctxt->state;
12783 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12784 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12785 } else if ((particle->maxOccurs >= UNBOUNDED) &&
12786 (particle->minOccurs < 2)) {
12787 /* Special case. */
12788 start = ctxt->state;
12789 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12790 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12791 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12792 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12793 } else {
12794 int counter;
12795 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12796 UNBOUNDED : particle->maxOccurs - 1;
12797 int minOccurs = particle->minOccurs < 1 ?
12798 0 : particle->minOccurs - 1;
12799
12800 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12801 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12802 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12803 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12804 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12805 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12806 NULL, counter);
12807 }
12808 if (particle->minOccurs == 0) {
12809 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12810 ret = 1;
12811 }
12812 }
12813 return(ret);
12814}
12815
12826static int
12827xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12828 xmlSchemaParticlePtr particle)
12829{
12830 int ret = 0, tmp2;
12831
12832 if (particle == NULL) {
12833 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12834 return(1);
12835 }
12836 if (particle->children == NULL) {
12837 /*
12838 * Just return in this case. A missing "term" of the particle
12839 * might arise due to an invalid "term" component.
12840 */
12841 return(1);
12842 }
12843
12844 switch (particle->children->type) {
12845 case XML_SCHEMA_TYPE_ANY: {
12846 xmlAutomataStatePtr start, end;
12847 xmlSchemaWildcardPtr wild;
12848 xmlSchemaWildcardNsPtr ns;
12849
12850 wild = (xmlSchemaWildcardPtr) particle->children;
12851
12852 start = pctxt->state;
12853 end = xmlAutomataNewState(pctxt->am);
12854
12855 if (particle->maxOccurs == 1) {
12856 if (wild->any == 1) {
12857 /*
12858 * We need to add both transitions:
12859 *
12860 * 1. the {"*", "*"} for elements in a namespace.
12861 */
12862 pctxt->state =
12863 xmlAutomataNewTransition2(pctxt->am,
12864 start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12865 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12866 /*
12867 * 2. the {"*"} for elements in no namespace.
12868 */
12869 pctxt->state =
12870 xmlAutomataNewTransition2(pctxt->am,
12871 start, NULL, BAD_CAST "*", NULL, wild);
12872 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12873
12874 } else if (wild->nsSet != NULL) {
12875 ns = wild->nsSet;
12876 do {
12877 pctxt->state = start;
12878 pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12879 pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12880 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12881 ns = ns->next;
12882 } while (ns != NULL);
12883
12884 } else if (wild->negNsSet != NULL) {
12885 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12886 start, end, BAD_CAST "*", wild->negNsSet->value,
12887 wild);
12888 }
12889 } else {
12890 int counter;
12891 xmlAutomataStatePtr hop;
12892 int maxOccurs =
12893 particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12894 particle->maxOccurs - 1;
12895 int minOccurs =
12896 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12897
12898 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12899 hop = xmlAutomataNewState(pctxt->am);
12900 if (wild->any == 1) {
12901 pctxt->state =
12902 xmlAutomataNewTransition2(pctxt->am,
12903 start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12904 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12905 pctxt->state =
12906 xmlAutomataNewTransition2(pctxt->am,
12907 start, NULL, BAD_CAST "*", NULL, wild);
12908 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12909 } else if (wild->nsSet != NULL) {
12910 ns = wild->nsSet;
12911 do {
12912 pctxt->state =
12913 xmlAutomataNewTransition2(pctxt->am,
12914 start, NULL, BAD_CAST "*", ns->value, wild);
12915 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12916 ns = ns->next;
12917 } while (ns != NULL);
12918
12919 } else if (wild->negNsSet != NULL) {
12920 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12921 start, hop, BAD_CAST "*", wild->negNsSet->value,
12922 wild);
12923 }
12924 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12925 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12926 }
12927 if (particle->minOccurs == 0) {
12928 xmlAutomataNewEpsilon(pctxt->am, start, end);
12929 ret = 1;
12930 }
12931 pctxt->state = end;
12932 break;
12933 }
12934 case XML_SCHEMA_TYPE_ELEMENT:
12935 ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12936 break;
12937 case XML_SCHEMA_TYPE_SEQUENCE:{
12938 xmlSchemaTreeItemPtr sub;
12939
12940 ret = 1;
12941 /*
12942 * If max and min occurrences are default (1) then
12943 * simply iterate over the particles of the <sequence>.
12944 */
12945 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12946 sub = particle->children->children;
12947
12948 while (sub != NULL) {
12949 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12950 (xmlSchemaParticlePtr) sub);
12951 if (tmp2 != 1) ret = 0;
12952 sub = sub->next;
12953 }
12954 } else {
12955 xmlAutomataStatePtr oldstate = pctxt->state;
12956
12957 if (particle->maxOccurs >= UNBOUNDED) {
12958 if (particle->minOccurs > 1) {
12959 xmlAutomataStatePtr tmp;
12960 int counter;
12961
12962 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12963 oldstate, NULL);
12964 oldstate = pctxt->state;
12965
12966 counter = xmlAutomataNewCounter(pctxt->am,
12967 particle->minOccurs - 1, UNBOUNDED);
12968
12969 sub = particle->children->children;
12970 while (sub != NULL) {
12971 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12972 (xmlSchemaParticlePtr) sub);
12973 if (tmp2 != 1) ret = 0;
12974 sub = sub->next;
12975 }
12976 tmp = pctxt->state;
12977 xmlAutomataNewCountedTrans(pctxt->am, tmp,
12978 oldstate, counter);
12979 pctxt->state =
12980 xmlAutomataNewCounterTrans(pctxt->am, tmp,
12981 NULL, counter);
12982 if (ret == 1)
12983 xmlAutomataNewEpsilon(pctxt->am,
12984 oldstate, pctxt->state);
12985
12986 } else {
12987 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12988 oldstate, NULL);
12989 oldstate = pctxt->state;
12990
12991 sub = particle->children->children;
12992 while (sub != NULL) {
12993 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12994 (xmlSchemaParticlePtr) sub);
12995 if (tmp2 != 1) ret = 0;
12996 sub = sub->next;
12997 }
12998 xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12999 oldstate);
13000 /*
13001 * epsilon needed to block previous trans from
13002 * being allowed to enter back from another
13003 * construct
13004 */
13005 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13006 pctxt->state, NULL);
13007 if (particle->minOccurs == 0) {
13008 xmlAutomataNewEpsilon(pctxt->am,
13009 oldstate, pctxt->state);
13010 ret = 1;
13011 }
13012 }
13013 } else if ((particle->maxOccurs > 1)
13014 || (particle->minOccurs > 1)) {
13015 xmlAutomataStatePtr tmp;
13016 int counter;
13017
13018 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13019 oldstate, NULL);
13020 oldstate = pctxt->state;
13021
13022 counter = xmlAutomataNewCounter(pctxt->am,
13023 particle->minOccurs - 1,
13024 particle->maxOccurs - 1);
13025
13026 sub = particle->children->children;
13027 while (sub != NULL) {
13028 tmp2 = xmlSchemaBuildAContentModel(pctxt,
13029 (xmlSchemaParticlePtr) sub);
13030 if (tmp2 != 1) ret = 0;
13031 sub = sub->next;
13032 }
13033 tmp = pctxt->state;
13034 xmlAutomataNewCountedTrans(pctxt->am,
13035 tmp, oldstate, counter);
13036 pctxt->state =
13037 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
13038 counter);
13039 if ((particle->minOccurs == 0) || (ret == 1)) {
13040 xmlAutomataNewEpsilon(pctxt->am,
13041 oldstate, pctxt->state);
13042 ret = 1;
13043 }
13044 } else {
13045 sub = particle->children->children;
13046 while (sub != NULL) {
13047 tmp2 = xmlSchemaBuildAContentModel(pctxt,
13048 (xmlSchemaParticlePtr) sub);
13049 if (tmp2 != 1) ret = 0;
13050 sub = sub->next;
13051 }
13052
13053 /*
13054 * epsilon needed to block previous trans from
13055 * being allowed to enter back from another
13056 * construct
13057 */
13058 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13059 pctxt->state, NULL);
13060
13061 if (particle->minOccurs == 0) {
13062 xmlAutomataNewEpsilon(pctxt->am, oldstate,
13063 pctxt->state);
13064 ret = 1;
13065 }
13066 }
13067 }
13068 break;
13069 }
13070 case XML_SCHEMA_TYPE_CHOICE:{
13071 xmlSchemaTreeItemPtr sub;
13072 xmlAutomataStatePtr start, end;
13073
13074 ret = 0;
13075 start = pctxt->state;
13076 end = xmlAutomataNewState(pctxt->am);
13077
13078 /*
13079 * iterate over the subtypes and remerge the end with an
13080 * epsilon transition
13081 */
13082 if (particle->maxOccurs == 1) {
13083 sub = particle->children->children;
13084 while (sub != NULL) {
13085 pctxt->state = start;
13086 tmp2 = xmlSchemaBuildAContentModel(pctxt,
13087 (xmlSchemaParticlePtr) sub);
13088 if (tmp2 == 1) ret = 1;
13089 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
13090 sub = sub->next;
13091 }
13092 } else {
13093 int counter;
13094 xmlAutomataStatePtr hop, base;
13095 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
13096 UNBOUNDED : particle->maxOccurs - 1;
13097 int minOccurs =
13098 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
13099
13100 /*
13101 * use a counter to keep track of the number of transitions
13102 * which went through the choice.
13103 */
13104 counter =
13105 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
13106 hop = xmlAutomataNewState(pctxt->am);
13107 base = xmlAutomataNewState(pctxt->am);
13108
13109 sub = particle->children->children;
13110 while (sub != NULL) {
13111 pctxt->state = base;
13112 tmp2 = xmlSchemaBuildAContentModel(pctxt,
13113 (xmlSchemaParticlePtr) sub);
13114 if (tmp2 == 1) ret = 1;
13115 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
13116 sub = sub->next;
13117 }
13118 xmlAutomataNewEpsilon(pctxt->am, start, base);
13119 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
13120 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
13121 if (ret == 1)
13122 xmlAutomataNewEpsilon(pctxt->am, base, end);
13123 }
13124 if (particle->minOccurs == 0) {
13125 xmlAutomataNewEpsilon(pctxt->am, start, end);
13126 ret = 1;
13127 }
13128 pctxt->state = end;
13129 break;
13130 }
13131 case XML_SCHEMA_TYPE_ALL:{
13132 xmlAutomataStatePtr start, tmp;
13133 xmlSchemaParticlePtr sub;
13134 xmlSchemaElementPtr elemDecl;
13135
13136 ret = 1;
13137
13138 sub = (xmlSchemaParticlePtr) particle->children->children;
13139 if (sub == NULL)
13140 break;
13141
13142 ret = 0;
13143
13144 start = pctxt->state;
13145 tmp = xmlAutomataNewState(pctxt->am);
13146 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13147 pctxt->state = tmp;
13148 while (sub != NULL) {
13149 pctxt->state = tmp;
13150
13151 elemDecl = (xmlSchemaElementPtr) sub->children;
13152 if (elemDecl == NULL) {
13153 PERROR_INT("xmlSchemaBuildAContentModel",
13154 "<element> particle has no term");
13155 return(ret);
13156 };
13157 /*
13158 * NOTE: The {max occurs} of all the particles in the
13159 * {particles} of the group must be 0 or 1; this is
13160 * already ensured during the parse of the content of
13161 * <all>.
13162 */
13163 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13164 int counter;
13165
13166 /*
13167 * This is an abstract group, we need to share
13168 * the same counter for all the element transitions
13169 * derived from the group
13170 */
13171 counter = xmlAutomataNewCounter(pctxt->am,
13172 sub->minOccurs, sub->maxOccurs);
13173 xmlSchemaBuildContentModelForSubstGroup(pctxt,
13174 sub, counter, pctxt->state);
13175 } else {
13176 if ((sub->minOccurs == 1) &&
13177 (sub->maxOccurs == 1)) {
13178 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13179 pctxt->state,
13180 elemDecl->name,
13181 elemDecl->targetNamespace,
13182 1, 1, elemDecl);
13183 } else if ((sub->minOccurs == 0) &&
13184 (sub->maxOccurs == 1)) {
13185
13186 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13187 pctxt->state,
13188 elemDecl->name,
13189 elemDecl->targetNamespace,
13190 0,
13191 1,
13192 elemDecl);
13193 }
13194 }
13195 sub = (xmlSchemaParticlePtr) sub->next;
13196 }
13197 pctxt->state =
13198 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13199 if (particle->minOccurs == 0) {
13200 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13201 ret = 1;
13202 }
13203 break;
13204 }
13205 case XML_SCHEMA_TYPE_GROUP:
13206 /*
13207 * If we hit a model group definition, then this means that
13208 * it was empty, thus was not substituted for the containing
13209 * model group. Just do nothing in this case.
13210 * TODO: But the group should be substituted and not occur at
13211 * all in the content model at this point. Fix this.
13212 */
13213 ret = 1;
13214 break;
13215 default:
13216 xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13217 "xmlSchemaBuildAContentModel",
13218 "found unexpected term of type '%s' in content model",
13219 WXS_ITEM_TYPE_NAME(particle->children), NULL);
13220 return(ret);
13221 }
13222 return(ret);
13223}
13224
13233static void
13234xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13235 xmlSchemaParserCtxtPtr ctxt)
13236{
13237 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13238 (type->contModel != NULL) ||
13239 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13240 (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13241 return;
13242
13243#ifdef DEBUG_CONTENT
13245 "Building content model for %s\n", name);
13246#endif
13247 ctxt->am = NULL;
13248 ctxt->am = xmlNewAutomata();
13249 if (ctxt->am == NULL) {
13251 "Cannot create automata for complex type %s\n", type->name);
13252 return;
13253 }
13254 ctxt->state = xmlAutomataGetInitState(ctxt->am);
13255 /*
13256 * Build the automaton.
13257 */
13258 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13259 xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13260 type->contModel = xmlAutomataCompile(ctxt->am);
13261 if (type->contModel == NULL) {
13262 xmlSchemaPCustomErr(ctxt,
13264 WXS_BASIC_CAST type, type->node,
13265 "Failed to compile the content model", NULL);
13266 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13267 xmlSchemaPCustomErr(ctxt,
13269 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13270 WXS_BASIC_CAST type, type->node,
13271 "The content model is not determinist", NULL);
13272 } else {
13273#ifdef DEBUG_CONTENT_REGEXP
13275 "Content model of %s:\n", type->name);
13276 xmlRegexpPrint(stderr, type->contModel);
13277#endif
13278 }
13279 ctxt->state = NULL;
13280 xmlFreeAutomata(ctxt->am);
13281 ctxt->am = NULL;
13282}
13283
13293static void
13294xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13295 xmlSchemaParserCtxtPtr ctxt)
13296{
13297 if ((ctxt == NULL) || (elemDecl == NULL) ||
13298 ((elemDecl != NULL) &&
13299 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13300 return;
13301 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13302
13303 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13304 xmlSchemaTypePtr type;
13305
13306 /* (type definition) ... otherwise the type definition `resolved`
13307 * to by the `actual value` of the type [attribute] ...
13308 */
13309 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13310 elemDecl->namedTypeNs);
13311 if (type == NULL) {
13312 xmlSchemaPResCompAttrErr(ctxt,
13314 WXS_BASIC_CAST elemDecl, elemDecl->node,
13315 "type", elemDecl->namedType, elemDecl->namedTypeNs,
13316 XML_SCHEMA_TYPE_BASIC, "type definition");
13317 } else
13318 elemDecl->subtypes = type;
13319 }
13320 if (elemDecl->substGroup != NULL) {
13321 xmlSchemaElementPtr substHead;
13322
13323 /*
13324 * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13325 * substitutionGroup?
13326 */
13327 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13328 elemDecl->substGroupNs);
13329 if (substHead == NULL) {
13330 xmlSchemaPResCompAttrErr(ctxt,
13332 WXS_BASIC_CAST elemDecl, NULL,
13333 "substitutionGroup", elemDecl->substGroup,
13334 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13335 } else {
13336 xmlSchemaResolveElementReferences(substHead, ctxt);
13337 /*
13338 * Set the "substitution group affiliation".
13339 * NOTE that now we use the "refDecl" field for this.
13340 */
13341 WXS_SUBST_HEAD(elemDecl) = substHead;
13342 /*
13343 * The type definitions is set to:
13344 * SPEC "...the {type definition} of the element
13345 * declaration `resolved` to by the `actual value`
13346 * of the substitutionGroup [attribute], if present"
13347 */
13348 if (elemDecl->subtypes == NULL)
13349 elemDecl->subtypes = substHead->subtypes;
13350 }
13351 }
13352 /*
13353 * SPEC "The definition of anyType serves as the default type definition
13354 * for element declarations whose XML representation does not specify one."
13355 */
13356 if ((elemDecl->subtypes == NULL) &&
13357 (elemDecl->namedType == NULL) &&
13358 (elemDecl->substGroup == NULL))
13359 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13360}
13361
13373static int
13374xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13375 xmlSchemaTypePtr type)
13376{
13377
13378 xmlSchemaTypeLinkPtr link, lastLink, newLink;
13379 xmlSchemaTypePtr memberType;
13380
13381 /*
13382 * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13383 * define the explicit members as the type definitions `resolved`
13384 * to by the items in the `actual value` of the memberTypes [attribute],
13385 * if any, followed by the type definitions corresponding to the
13386 * <simpleType>s among the [children] of <union>, if any."
13387 */
13388 /*
13389 * Resolve references.
13390 */
13391 link = type->memberTypes;
13392 lastLink = NULL;
13393 while (link != NULL) {
13394 const xmlChar *name, *nsName;
13395
13396 name = ((xmlSchemaQNameRefPtr) link->type)->name;
13397 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13398
13399 memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13400 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13401 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13402 WXS_BASIC_CAST type, type->node, "memberTypes",
13403 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13404 /*
13405 * Remove the member type link.
13406 */
13407 if (lastLink == NULL)
13408 type->memberTypes = link->next;
13409 else
13410 lastLink->next = link->next;
13411 newLink = link;
13412 link = link->next;
13413 xmlFree(newLink);
13414 } else {
13415 link->type = memberType;
13416 lastLink = link;
13417 link = link->next;
13418 }
13419 }
13420 /*
13421 * Add local simple types,
13422 */
13423 memberType = type->subtypes;
13424 while (memberType != NULL) {
13425 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13426 if (link == NULL) {
13427 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
13428 return (-1);
13429 }
13430 link->type = memberType;
13431 link->next = NULL;
13432 if (lastLink == NULL)
13433 type->memberTypes = link;
13434 else
13435 lastLink->next = link;
13436 lastLink = link;
13437 memberType = memberType->next;
13438 }
13439 return (0);
13440}
13441
13452static int
13453xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13454{
13455 if (type == NULL)
13456 return (0);
13457 if (WXS_IS_COMPLEX(type))
13458 return (0);
13459 if (type->type == XML_SCHEMA_TYPE_BASIC) {
13460 if (type->builtInType == valType)
13461 return(1);
13462 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13463 (type->builtInType == XML_SCHEMAS_ANYTYPE))
13464 return (0);
13465 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13466 }
13467 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13468}
13469
13470#if 0
13481static int
13482xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13483{
13484 if (type == NULL)
13485 return (0);
13486 if (WXS_IS_COMPLEX(type))
13487 return (0);
13488 if (type->type == XML_SCHEMA_TYPE_BASIC) {
13489 if (type->builtInType == valType)
13490 return(1);
13491 return (0);
13492 } else
13493 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13494
13495 return (0);
13496}
13497
13498static xmlSchemaTypePtr
13499xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13500{
13501 if (type == NULL)
13502 return (NULL);
13503 if (WXS_IS_COMPLEX(type))
13504 return (NULL);
13505 if (type->type == XML_SCHEMA_TYPE_BASIC)
13506 return(type);
13507 return(xmlSchemaQueryBuiltInType(type->subtypes));
13508}
13509#endif
13510
13518static xmlSchemaTypePtr
13519xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13520{
13521
13522 while (type != NULL) {
13523 /*
13524 * Note that anySimpleType is actually not a primitive type
13525 * but we need that here.
13526 */
13527 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13528 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13529 return (type);
13530 type = type->baseType;
13531 }
13532
13533 return (NULL);
13534}
13535
13536#if 0
13544static xmlSchemaTypePtr
13545xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13546{
13547 if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13548 return (0);
13549 while (type != NULL) {
13550 if (type->type == XML_SCHEMA_TYPE_BASIC)
13551 return (type);
13552 type = type->baseType;
13553 }
13554
13555 return (NULL);
13556}
13557#endif
13558
13569static int
13570xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13571 xmlSchemaWildcardPtr dest,
13572 xmlSchemaWildcardPtr source)
13573{
13574 xmlSchemaWildcardNsPtr cur, tmp, last;
13575
13576 if ((source == NULL) || (dest == NULL))
13577 return(-1);
13578 dest->any = source->any;
13579 cur = source->nsSet;
13580 last = NULL;
13581 while (cur != NULL) {
13582 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13583 if (tmp == NULL)
13584 return(-1);
13585 tmp->value = cur->value;
13586 if (last == NULL)
13587 dest->nsSet = tmp;
13588 else
13589 last->next = tmp;
13590 last = tmp;
13591 cur = cur->next;
13592 }
13593 if (dest->negNsSet != NULL)
13594 xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13595 if (source->negNsSet != NULL) {
13596 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13597 if (dest->negNsSet == NULL)
13598 return(-1);
13599 dest->negNsSet->value = source->negNsSet->value;
13600 } else
13601 dest->negNsSet = NULL;
13602 return(0);
13603}
13604
13616static int
13617xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13618 xmlSchemaWildcardPtr completeWild,
13619 xmlSchemaWildcardPtr curWild)
13620{
13621 xmlSchemaWildcardNsPtr cur, curB, tmp;
13622
13623 /*
13624 * 1 If O1 and O2 are the same value, then that value must be the
13625 * value.
13626 */
13627 if ((completeWild->any == curWild->any) &&
13628 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13629 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13630
13631 if ((completeWild->negNsSet == NULL) ||
13632 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13633
13634 if (completeWild->nsSet != NULL) {
13635 int found = 0;
13636
13637 /*
13638 * Check equality of sets.
13639 */
13640 cur = completeWild->nsSet;
13641 while (cur != NULL) {
13642 found = 0;
13643 curB = curWild->nsSet;
13644 while (curB != NULL) {
13645 if (cur->value == curB->value) {
13646 found = 1;
13647 break;
13648 }
13649 curB = curB->next;
13650 }
13651 if (!found)
13652 break;
13653 cur = cur->next;
13654 }
13655 if (found)
13656 return(0);
13657 } else
13658 return(0);
13659 }
13660 }
13661 /*
13662 * 2 If either O1 or O2 is any, then any must be the value
13663 */
13664 if (completeWild->any != curWild->any) {
13665 if (completeWild->any == 0) {
13666 completeWild->any = 1;
13667 if (completeWild->nsSet != NULL) {
13668 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13669 completeWild->nsSet = NULL;
13670 }
13671 if (completeWild->negNsSet != NULL) {
13672 xmlFree(completeWild->negNsSet);
13673 completeWild->negNsSet = NULL;
13674 }
13675 }
13676 return (0);
13677 }
13678 /*
13679 * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13680 * then the union of those sets must be the value.
13681 */
13682 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13683 int found;
13684 xmlSchemaWildcardNsPtr start;
13685
13686 cur = curWild->nsSet;
13687 start = completeWild->nsSet;
13688 while (cur != NULL) {
13689 found = 0;
13690 curB = start;
13691 while (curB != NULL) {
13692 if (cur->value == curB->value) {
13693 found = 1;
13694 break;
13695 }
13696 curB = curB->next;
13697 }
13698 if (!found) {
13699 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13700 if (tmp == NULL)
13701 return (-1);
13702 tmp->value = cur->value;
13703 tmp->next = completeWild->nsSet;
13704 completeWild->nsSet = tmp;
13705 }
13706 cur = cur->next;
13707 }
13708
13709 return(0);
13710 }
13711 /*
13712 * 4 If the two are negations of different values (namespace names
13713 * or `absent`), then a pair of not and `absent` must be the value.
13714 */
13715 if ((completeWild->negNsSet != NULL) &&
13716 (curWild->negNsSet != NULL) &&
13717 (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13718 completeWild->negNsSet->value = NULL;
13719
13720 return(0);
13721 }
13722 /*
13723 * 5.
13724 */
13725 if (((completeWild->negNsSet != NULL) &&
13726 (completeWild->negNsSet->value != NULL) &&
13727 (curWild->nsSet != NULL)) ||
13728 ((curWild->negNsSet != NULL) &&
13729 (curWild->negNsSet->value != NULL) &&
13730 (completeWild->nsSet != NULL))) {
13731
13732 int nsFound, absentFound = 0;
13733
13734 if (completeWild->nsSet != NULL) {
13735 cur = completeWild->nsSet;
13736 curB = curWild->negNsSet;
13737 } else {
13738 cur = curWild->nsSet;
13739 curB = completeWild->negNsSet;
13740 }
13741 nsFound = 0;
13742 while (cur != NULL) {
13743 if (cur->value == NULL)
13744 absentFound = 1;
13745 else if (cur->value == curB->value)
13746 nsFound = 1;
13747 if (nsFound && absentFound)
13748 break;
13749 cur = cur->next;
13750 }
13751
13752 if (nsFound && absentFound) {
13753 /*
13754 * 5.1 If the set S includes both the negated namespace
13755 * name and `absent`, then any must be the value.
13756 */
13757 completeWild->any = 1;
13758 if (completeWild->nsSet != NULL) {
13759 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13760 completeWild->nsSet = NULL;
13761 }
13762 if (completeWild->negNsSet != NULL) {
13763 xmlFree(completeWild->negNsSet);
13764 completeWild->negNsSet = NULL;
13765 }
13766 } else if (nsFound && (!absentFound)) {
13767 /*
13768 * 5.2 If the set S includes the negated namespace name
13769 * but not `absent`, then a pair of not and `absent` must
13770 * be the value.
13771 */
13772 if (completeWild->nsSet != NULL) {
13773 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13774 completeWild->nsSet = NULL;
13775 }
13776 if (completeWild->negNsSet == NULL) {
13777 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13778 if (completeWild->negNsSet == NULL)
13779 return (-1);
13780 }
13781 completeWild->negNsSet->value = NULL;
13782 } else if ((!nsFound) && absentFound) {
13783 /*
13784 * 5.3 If the set S includes `absent` but not the negated
13785 * namespace name, then the union is not expressible.
13786 */
13787 xmlSchemaPErr(ctxt, completeWild->node,
13789 "The union of the wildcard is not expressible.\n",
13790 NULL, NULL);
13792 } else if ((!nsFound) && (!absentFound)) {
13793 /*
13794 * 5.4 If the set S does not include either the negated namespace
13795 * name or `absent`, then whichever of O1 or O2 is a pair of not
13796 * and a namespace name must be the value.
13797 */
13798 if (completeWild->negNsSet == NULL) {
13799 if (completeWild->nsSet != NULL) {
13800 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13801 completeWild->nsSet = NULL;
13802 }
13803 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13804 if (completeWild->negNsSet == NULL)
13805 return (-1);
13806 completeWild->negNsSet->value = curWild->negNsSet->value;
13807 }
13808 }
13809 return (0);
13810 }
13811 /*
13812 * 6.
13813 */
13814 if (((completeWild->negNsSet != NULL) &&
13815 (completeWild->negNsSet->value == NULL) &&
13816 (curWild->nsSet != NULL)) ||
13817 ((curWild->negNsSet != NULL) &&
13818 (curWild->negNsSet->value == NULL) &&
13819 (completeWild->nsSet != NULL))) {
13820
13821 if (completeWild->nsSet != NULL) {
13822 cur = completeWild->nsSet;
13823 } else {
13824 cur = curWild->nsSet;
13825 }
13826 while (cur != NULL) {
13827 if (cur->value == NULL) {
13828 /*
13829 * 6.1 If the set S includes `absent`, then any must be the
13830 * value.
13831 */
13832 completeWild->any = 1;
13833 if (completeWild->nsSet != NULL) {
13834 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13835 completeWild->nsSet = NULL;
13836 }
13837 if (completeWild->negNsSet != NULL) {
13838 xmlFree(completeWild->negNsSet);
13839 completeWild->negNsSet = NULL;
13840 }
13841 return (0);
13842 }
13843 cur = cur->next;
13844 }
13845 if (completeWild->negNsSet == NULL) {
13846 /*
13847 * 6.2 If the set S does not include `absent`, then a pair of not
13848 * and `absent` must be the value.
13849 */
13850 if (completeWild->nsSet != NULL) {
13851 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13852 completeWild->nsSet = NULL;
13853 }
13854 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13855 if (completeWild->negNsSet == NULL)
13856 return (-1);
13857 completeWild->negNsSet->value = NULL;
13858 }
13859 return (0);
13860 }
13861 return (0);
13862
13863}
13864
13876static int
13877xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13878 xmlSchemaWildcardPtr completeWild,
13879 xmlSchemaWildcardPtr curWild)
13880{
13881 xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
13882
13883 /*
13884 * 1 If O1 and O2 are the same value, then that value must be the
13885 * value.
13886 */
13887 if ((completeWild->any == curWild->any) &&
13888 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13889 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13890
13891 if ((completeWild->negNsSet == NULL) ||
13892 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13893
13894 if (completeWild->nsSet != NULL) {
13895 int found = 0;
13896
13897 /*
13898 * Check equality of sets.
13899 */
13900 cur = completeWild->nsSet;
13901 while (cur != NULL) {
13902 found = 0;
13903 curB = curWild->nsSet;
13904 while (curB != NULL) {
13905 if (cur->value == curB->value) {
13906 found = 1;
13907 break;
13908 }
13909 curB = curB->next;
13910 }
13911 if (!found)
13912 break;
13913 cur = cur->next;
13914 }
13915 if (found)
13916 return(0);
13917 } else
13918 return(0);
13919 }
13920 }
13921 /*
13922 * 2 If either O1 or O2 is any, then the other must be the value.
13923 */
13924 if ((completeWild->any != curWild->any) && (completeWild->any)) {
13925 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13926 return(-1);
13927 return(0);
13928 }
13929 /*
13930 * 3 If either O1 or O2 is a pair of not and a value (a namespace
13931 * name or `absent`) and the other is a set of (namespace names or
13932 * `absent`), then that set, minus the negated value if it was in
13933 * the set, minus `absent` if it was in the set, must be the value.
13934 */
13935 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13936 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13937 const xmlChar *neg;
13938
13939 if (completeWild->nsSet == NULL) {
13940 neg = completeWild->negNsSet->value;
13941 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13942 return(-1);
13943 } else
13944 neg = curWild->negNsSet->value;
13945 /*
13946 * Remove absent and negated.
13947 */
13948 prev = NULL;
13949 cur = completeWild->nsSet;
13950 while (cur != NULL) {
13951 if (cur->value == NULL) {
13952 if (prev == NULL)
13953 completeWild->nsSet = cur->next;
13954 else
13955 prev->next = cur->next;
13956 xmlFree(cur);
13957 break;
13958 }
13959 prev = cur;
13960 cur = cur->next;
13961 }
13962 if (neg != NULL) {
13963 prev = NULL;
13964 cur = completeWild->nsSet;
13965 while (cur != NULL) {
13966 if (cur->value == neg) {
13967 if (prev == NULL)
13968 completeWild->nsSet = cur->next;
13969 else
13970 prev->next = cur->next;
13971 xmlFree(cur);
13972 break;
13973 }
13974 prev = cur;
13975 cur = cur->next;
13976 }
13977 }
13978
13979 return(0);
13980 }
13981 /*
13982 * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13983 * then the intersection of those sets must be the value.
13984 */
13985 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13986 int found;
13987
13988 cur = completeWild->nsSet;
13989 prev = NULL;
13990 while (cur != NULL) {
13991 found = 0;
13992 curB = curWild->nsSet;
13993 while (curB != NULL) {
13994 if (cur->value == curB->value) {
13995 found = 1;
13996 break;
13997 }
13998 curB = curB->next;
13999 }
14000 if (!found) {
14001 if (prev == NULL)
14002 completeWild->nsSet = cur->next;
14003 else
14004 prev->next = cur->next;
14005 tmp = cur->next;
14006 xmlFree(cur);
14007 cur = tmp;
14008 continue;
14009 }
14010 prev = cur;
14011 cur = cur->next;
14012 }
14013
14014 return(0);
14015 }
14016 /* 5 If the two are negations of different namespace names,
14017 * then the intersection is not expressible
14018 */
14019 if ((completeWild->negNsSet != NULL) &&
14020 (curWild->negNsSet != NULL) &&
14021 (completeWild->negNsSet->value != curWild->negNsSet->value) &&
14022 (completeWild->negNsSet->value != NULL) &&
14023 (curWild->negNsSet->value != NULL)) {
14024
14025 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
14026 "The intersection of the wildcard is not expressible.\n",
14027 NULL, NULL);
14029 }
14030 /*
14031 * 6 If the one is a negation of a namespace name and the other
14032 * is a negation of `absent`, then the one which is the negation
14033 * of a namespace name must be the value.
14034 */
14035 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
14036 (completeWild->negNsSet->value != curWild->negNsSet->value) &&
14037 (completeWild->negNsSet->value == NULL)) {
14038 completeWild->negNsSet->value = curWild->negNsSet->value;
14039 }
14040 return(0);
14041}
14042
14054static int
14055xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
14056 xmlSchemaWildcardPtr super)
14057{
14058 /*
14059 * 1 super must be any.
14060 */
14061 if (super->any)
14062 return (0);
14063 /*
14064 * 2.1 sub must be a pair of not and a namespace name or `absent`.
14065 * 2.2 super must be a pair of not and the same value.
14066 */
14067 if ((sub->negNsSet != NULL) &&
14068 (super->negNsSet != NULL) &&
14069 (sub->negNsSet->value == super->negNsSet->value))
14070 return (0);
14071 /*
14072 * 3.1 sub must be a set whose members are either namespace names or `absent`.
14073 */
14074 if (sub->nsSet != NULL) {
14075 /*
14076 * 3.2.1 super must be the same set or a superset thereof.
14077 */
14078 if (super->nsSet != NULL) {
14079 xmlSchemaWildcardNsPtr cur, curB;
14080 int found = 0;
14081
14082 cur = sub->nsSet;
14083 while (cur != NULL) {
14084 found = 0;
14085 curB = super->nsSet;
14086 while (curB != NULL) {
14087 if (cur->value == curB->value) {
14088 found = 1;
14089 break;
14090 }
14091 curB = curB->next;
14092 }
14093 if (!found)
14094 return (1);
14095 cur = cur->next;
14096 }
14097 if (found)
14098 return (0);
14099 } else if (super->negNsSet != NULL) {
14100 xmlSchemaWildcardNsPtr cur;
14101 /*
14102 * 3.2.2 super must be a pair of not and a namespace name or
14103 * `absent` and that value must not be in sub's set.
14104 */
14105 cur = sub->nsSet;
14106 while (cur != NULL) {
14107 if (cur->value == super->negNsSet->value)
14108 return (1);
14109 cur = cur->next;
14110 }
14111 return (0);
14112 }
14113 }
14114 return (1);
14115}
14116
14117static int
14118xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
14119 int *fixed,
14120 const xmlChar **value,
14121 xmlSchemaValPtr *val)
14122{
14123 *fixed = 0;
14124 *value = NULL;
14125 if (val != 0)
14126 *val = NULL;
14127
14128 if (attruse->defValue != NULL) {
14129 *value = attruse->defValue;
14130 if (val != NULL)
14131 *val = attruse->defVal;
14132 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14133 *fixed = 1;
14134 return(1);
14135 } else if ((attruse->attrDecl != NULL) &&
14136 (attruse->attrDecl->defValue != NULL)) {
14137 *value = attruse->attrDecl->defValue;
14138 if (val != NULL)
14139 *val = attruse->attrDecl->defVal;
14140 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14141 *fixed = 1;
14142 return(1);
14143 }
14144 return(0);
14145}
14157static int
14158xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14159 const xmlChar* ns)
14160{
14161 if (wild == NULL)
14162 return(-1);
14163
14164 if (wild->any)
14165 return(0);
14166 else if (wild->nsSet != NULL) {
14167 xmlSchemaWildcardNsPtr cur;
14168
14169 cur = wild->nsSet;
14170 while (cur != NULL) {
14171 if (xmlStrEqual(cur->value, ns))
14172 return(0);
14173 cur = cur->next;
14174 }
14175 } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14176 (!xmlStrEqual(wild->negNsSet->value, ns)))
14177 return(0);
14178
14179 return(1);
14180}
14181
14182#define XML_SCHEMA_ACTION_DERIVE 0
14183#define XML_SCHEMA_ACTION_REDEFINE 1
14184
14185#define WXS_ACTION_STR(a) \
14186((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14187
14188/*
14189* Schema Component Constraint:
14190* Derivation Valid (Restriction, Complex)
14191* derivation-ok-restriction (2) - (4)
14192*
14193* ATTENTION:
14194* In XML Schema 1.1 this will be:
14195* Validation Rule:
14196* Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14197*
14198*/
14199static int
14200xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14201 int action,
14202 xmlSchemaBasicItemPtr item,
14203 xmlSchemaBasicItemPtr baseItem,
14204 xmlSchemaItemListPtr uses,
14205 xmlSchemaItemListPtr baseUses,
14206 xmlSchemaWildcardPtr wild,
14207 xmlSchemaWildcardPtr baseWild)
14208{
14209 xmlSchemaAttributeUsePtr cur = NULL, bcur;
14210 int i, j, found; /* err = 0; */
14211 const xmlChar *bEffValue;
14212 int effFixed;
14213
14214 if (uses != NULL) {
14215 for (i = 0; i < uses->nbItems; i++) {
14216 cur = uses->items[i];
14217 found = 0;
14218 if (baseUses == NULL)
14219 goto not_found;
14220 for (j = 0; j < baseUses->nbItems; j++) {
14221 bcur = baseUses->items[j];
14222 if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14223 WXS_ATTRUSE_DECL_NAME(bcur)) &&
14224 (WXS_ATTRUSE_DECL_TNS(cur) ==
14225 WXS_ATTRUSE_DECL_TNS(bcur)))
14226 {
14227 /*
14228 * (2.1) "If there is an attribute use in the {attribute
14229 * uses} of the {base type definition} (call this B) whose
14230 * {attribute declaration} has the same {name} and {target
14231 * namespace}, then all of the following must be true:"
14232 */
14233 found = 1;
14234
14235 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14236 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14237 {
14238 xmlChar *str = NULL;
14239 /*
14240 * (2.1.1) "one of the following must be true:"
14241 * (2.1.1.1) "B's {required} is false."
14242 * (2.1.1.2) "R's {required} is true."
14243 */
14244 xmlSchemaPAttrUseErr4(pctxt,
14246 WXS_ITEM_NODE(item), item, cur,
14247 "The 'optional' attribute use is inconsistent "
14248 "with the corresponding 'required' attribute use of "
14249 "the %s %s",
14250 WXS_ACTION_STR(action),
14251 xmlSchemaGetComponentDesignation(&str, baseItem),
14252 NULL, NULL);
14253 FREE_AND_NULL(str);
14254 /* err = pctxt->err; */
14255 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14256 WXS_ATTRUSE_TYPEDEF(cur),
14257 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14258 {
14259 xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14260
14261 /*
14262 * SPEC (2.1.2) "R's {attribute declaration}'s
14263 * {type definition} must be validly derived from
14264 * B's {type definition} given the empty set as
14265 * defined in Type Derivation OK (Simple) ($3.14.6)."
14266 */
14267 xmlSchemaPAttrUseErr4(pctxt,
14269 WXS_ITEM_NODE(item), item, cur,
14270 "The attribute declaration's %s "
14271 "is not validly derived from "
14272 "the corresponding %s of the "
14273 "attribute declaration in the %s %s",
14274 xmlSchemaGetComponentDesignation(&strA,
14275 WXS_ATTRUSE_TYPEDEF(cur)),
14276 xmlSchemaGetComponentDesignation(&strB,
14277 WXS_ATTRUSE_TYPEDEF(bcur)),
14278 WXS_ACTION_STR(action),
14279 xmlSchemaGetComponentDesignation(&strC, baseItem));
14280 /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14281 FREE_AND_NULL(strA);
14282 FREE_AND_NULL(strB);
14283 FREE_AND_NULL(strC);
14284 /* err = pctxt->err; */
14285 } else {
14286 /*
14287 * 2.1.3 [Definition:] Let the effective value
14288 * constraint of an attribute use be its {value
14289 * constraint}, if present, otherwise its {attribute
14290 * declaration}'s {value constraint} .
14291 */
14292 xmlSchemaGetEffectiveValueConstraint(bcur,
14293 &effFixed, &bEffValue, NULL);
14294 /*
14295 * 2.1.3 ... one of the following must be true
14296 *
14297 * 2.1.3.1 B's `effective value constraint` is
14298 * `absent` or default.
14299 */
14300 if ((bEffValue != NULL) &&
14301 (effFixed == 1)) {
14302 const xmlChar *rEffValue = NULL;
14303
14304 xmlSchemaGetEffectiveValueConstraint(bcur,
14305 &effFixed, &rEffValue, NULL);
14306 /*
14307 * 2.1.3.2 R's `effective value constraint` is
14308 * fixed with the same string as B's.
14309 * MAYBE TODO: Compare the computed values.
14310 * Hmm, it says "same string" so
14311 * string-equality might really be sufficient.
14312 */
14313 if ((effFixed == 0) ||
14314 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14315 {
14316 xmlChar *str = NULL;
14317
14318 xmlSchemaPAttrUseErr4(pctxt,
14320 WXS_ITEM_NODE(item), item, cur,
14321 "The effective value constraint of the "
14322 "attribute use is inconsistent with "
14323 "its correspondent in the %s %s",
14324 WXS_ACTION_STR(action),
14325 xmlSchemaGetComponentDesignation(&str,
14326 baseItem),
14327 NULL, NULL);
14328 FREE_AND_NULL(str);
14329 /* err = pctxt->err; */
14330 }
14331 }
14332 }
14333 break;
14334 }
14335 }
14336not_found:
14337 if (!found) {
14338 /*
14339 * (2.2) "otherwise the {base type definition} must have an
14340 * {attribute wildcard} and the {target namespace} of the
14341 * R's {attribute declaration} must be `valid` with respect
14342 * to that wildcard, as defined in Wildcard allows Namespace
14343 * Name ($3.10.4)."
14344 */
14345 if ((baseWild == NULL) ||
14346 (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14347 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14348 {
14349 xmlChar *str = NULL;
14350
14351 xmlSchemaPAttrUseErr4(pctxt,
14353 WXS_ITEM_NODE(item), item, cur,
14354 "Neither a matching attribute use, "
14355 "nor a matching wildcard exists in the %s %s",
14356 WXS_ACTION_STR(action),
14357 xmlSchemaGetComponentDesignation(&str, baseItem),
14358 NULL, NULL);
14359 FREE_AND_NULL(str);
14360 /* err = pctxt->err; */
14361 }
14362 }
14363 }
14364 }
14365 /*
14366 * SPEC derivation-ok-restriction (3):
14367 * (3) "For each attribute use in the {attribute uses} of the {base type
14368 * definition} whose {required} is true, there must be an attribute
14369 * use with an {attribute declaration} with the same {name} and
14370 * {target namespace} as its {attribute declaration} in the {attribute
14371 * uses} of the complex type definition itself whose {required} is true.
14372 */
14373 if (baseUses != NULL) {
14374 for (j = 0; j < baseUses->nbItems; j++) {
14375 bcur = baseUses->items[j];
14376 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14377 continue;
14378 found = 0;
14379 if (uses != NULL) {
14380 for (i = 0; i < uses->nbItems; i++) {
14381 cur = uses->items[i];
14382 if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14383 WXS_ATTRUSE_DECL_NAME(bcur)) &&
14384 (WXS_ATTRUSE_DECL_TNS(cur) ==
14385 WXS_ATTRUSE_DECL_TNS(bcur))) {
14386 found = 1;
14387 break;
14388 }
14389 }
14390 }
14391 if (!found) {
14392 xmlChar *strA = NULL, *strB = NULL;
14393
14394 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14396 NULL, item,
14397 "A matching attribute use for the "
14398 "'required' %s of the %s %s is missing",
14399 xmlSchemaGetComponentDesignation(&strA, bcur),
14400 WXS_ACTION_STR(action),
14401 xmlSchemaGetComponentDesignation(&strB, baseItem),
14402 NULL);
14403 FREE_AND_NULL(strA);
14404 FREE_AND_NULL(strB);
14405 }
14406 }
14407 }
14408 /*
14409 * derivation-ok-restriction (4)
14410 */
14411 if (wild != NULL) {
14412 /*
14413 * (4) "If there is an {attribute wildcard}, all of the
14414 * following must be true:"
14415 */
14416 if (baseWild == NULL) {
14417 xmlChar *str = NULL;
14418
14419 /*
14420 * (4.1) "The {base type definition} must also have one."
14421 */
14422 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14424 NULL, item,
14425 "The %s has an attribute wildcard, "
14426 "but the %s %s '%s' does not have one",
14427 WXS_ITEM_TYPE_NAME(item),
14428 WXS_ACTION_STR(action),
14429 WXS_ITEM_TYPE_NAME(baseItem),
14430 xmlSchemaGetComponentQName(&str, baseItem));
14431 FREE_AND_NULL(str);
14432 return(pctxt->err);
14433 } else if ((baseWild->any == 0) &&
14434 xmlSchemaCheckCOSNSSubset(wild, baseWild))
14435 {
14436 xmlChar *str = NULL;
14437 /*
14438 * (4.2) "The complex type definition's {attribute wildcard}'s
14439 * {namespace constraint} must be a subset of the {base type
14440 * definition}'s {attribute wildcard}'s {namespace constraint},
14441 * as defined by Wildcard Subset ($3.10.6)."
14442 */
14443 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14445 NULL, item,
14446 "The attribute wildcard is not a valid "
14447 "subset of the wildcard in the %s %s '%s'",
14448 WXS_ACTION_STR(action),
14449 WXS_ITEM_TYPE_NAME(baseItem),
14450 xmlSchemaGetComponentQName(&str, baseItem),
14451 NULL);
14452 FREE_AND_NULL(str);
14453 return(pctxt->err);
14454 }
14455 /* 4.3 Unless the {base type definition} is the `ur-type
14456 * definition`, the complex type definition's {attribute
14457 * wildcard}'s {process contents} must be identical to or
14458 * stronger than the {base type definition}'s {attribute
14459 * wildcard}'s {process contents}, where strict is stronger
14460 * than lax is stronger than skip.
14461 */
14462 if ((! WXS_IS_ANYTYPE(baseItem)) &&
14463 (wild->processContents < baseWild->processContents)) {
14464 xmlChar *str = NULL;
14465 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14467 NULL, baseItem,
14468 "The {process contents} of the attribute wildcard is "
14469 "weaker than the one in the %s %s '%s'",
14470 WXS_ACTION_STR(action),
14471 WXS_ITEM_TYPE_NAME(baseItem),
14472 xmlSchemaGetComponentQName(&str, baseItem),
14473 NULL);
14474 FREE_AND_NULL(str)
14475 return(pctxt->err);
14476 }
14477 }
14478 return(0);
14479}
14480
14481
14482static int
14483xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14484 xmlSchemaBasicItemPtr item,
14485 xmlSchemaWildcardPtr *completeWild,
14486 xmlSchemaItemListPtr list,
14487 xmlSchemaItemListPtr prohibs);
14502static int
14503xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14504 xmlSchemaTypePtr type)
14505{
14506 xmlSchemaTypePtr baseType = NULL;
14507 xmlSchemaAttributeUsePtr use;
14508 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14509
14510 if (type->baseType == NULL) {
14511 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14512 "no base type");
14513 return (-1);
14514 }
14515 baseType = type->baseType;
14516 if (WXS_IS_TYPE_NOT_FIXED(baseType))
14517 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14518 return(-1);
14519
14520 uses = type->attrUses;
14521 baseUses = baseType->attrUses;
14522 /*
14523 * Expand attribute group references. And build the 'complete'
14524 * wildcard, i.e. intersect multiple wildcards.
14525 * Move attribute prohibitions into a separate list.
14526 */
14527 if (uses != NULL) {
14528 if (WXS_IS_RESTRICTION(type)) {
14529 /*
14530 * This one will transfer all attr. prohibitions
14531 * into pctxt->attrProhibs.
14532 */
14533 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14534 WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14535 pctxt->attrProhibs) == -1)
14536 {
14537 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14538 "failed to expand attributes");
14539 }
14540 if (pctxt->attrProhibs->nbItems != 0)
14541 prohibs = pctxt->attrProhibs;
14542 } else {
14543 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14544 WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14545 NULL) == -1)
14546 {
14547 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14548 "failed to expand attributes");
14549 }
14550 }
14551 }
14552 /*
14553 * Inherit the attribute uses of the base type.
14554 */
14555 if (baseUses != NULL) {
14556 int i, j;
14557 xmlSchemaAttributeUseProhibPtr pro;
14558
14559 if (WXS_IS_RESTRICTION(type)) {
14560 int usesCount;
14561 xmlSchemaAttributeUsePtr tmp;
14562
14563 if (uses != NULL)
14564 usesCount = uses->nbItems;
14565 else
14566 usesCount = 0;
14567
14568 /* Restriction. */
14569 for (i = 0; i < baseUses->nbItems; i++) {
14570 use = baseUses->items[i];
14571 if (prohibs) {
14572 /*
14573 * Filter out prohibited uses.
14574 */
14575 for (j = 0; j < prohibs->nbItems; j++) {
14576 pro = prohibs->items[j];
14577 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14578 (WXS_ATTRUSE_DECL_TNS(use) ==
14579 pro->targetNamespace))
14580 {
14581 goto inherit_next;
14582 }
14583 }
14584 }
14585 if (usesCount) {
14586 /*
14587 * Filter out existing uses.
14588 */
14589 for (j = 0; j < usesCount; j++) {
14590 tmp = uses->items[j];
14591 if ((WXS_ATTRUSE_DECL_NAME(use) ==
14592 WXS_ATTRUSE_DECL_NAME(tmp)) &&
14593 (WXS_ATTRUSE_DECL_TNS(use) ==
14594 WXS_ATTRUSE_DECL_TNS(tmp)))
14595 {
14596 goto inherit_next;
14597 }
14598 }
14599 }
14600 if (uses == NULL) {
14601 type->attrUses = xmlSchemaItemListCreate();
14602 if (type->attrUses == NULL)
14603 goto exit_failure;
14604 uses = type->attrUses;
14605 }
14606 xmlSchemaItemListAddSize(uses, 2, use);
14607inherit_next: {}
14608 }
14609 } else {
14610 /* Extension. */
14611 for (i = 0; i < baseUses->nbItems; i++) {
14612 use = baseUses->items[i];
14613 if (uses == NULL) {
14614 type->attrUses = xmlSchemaItemListCreate();
14615 if (type->attrUses == NULL)
14616 goto exit_failure;
14617 uses = type->attrUses;
14618 }
14619 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14620 }
14621 }
14622 }
14623 /*
14624 * Shrink attr. uses.
14625 */
14626 if (uses) {
14627 if (uses->nbItems == 0) {
14628 xmlSchemaItemListFree(uses);
14629 type->attrUses = NULL;
14630 }
14631 /*
14632 * TODO: We could shrink the size of the array
14633 * to fit the actual number of items.
14634 */
14635 }
14636 /*
14637 * Compute the complete wildcard.
14638 */
14639 if (WXS_IS_EXTENSION(type)) {
14640 if (baseType->attributeWildcard != NULL) {
14641 /*
14642 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14643 * the appropriate case among the following:"
14644 */
14645 if (type->attributeWildcard != NULL) {
14646 /*
14647 * Union the complete wildcard with the base wildcard.
14648 * SPEC {attribute wildcard}
14649 * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14650 * and {annotation} are those of the `complete wildcard`,
14651 * and whose {namespace constraint} is the intensional union
14652 * of the {namespace constraint} of the `complete wildcard`
14653 * and of the `base wildcard`, as defined in Attribute
14654 * Wildcard Union ($3.10.6)."
14655 */
14656 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14657 baseType->attributeWildcard) == -1)
14658 goto exit_failure;
14659 } else {
14660 /*
14661 * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14662 * then the `base wildcard`."
14663 */
14664 type->attributeWildcard = baseType->attributeWildcard;
14665 }
14666 } else {
14667 /*
14668 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14669 * `complete wildcard`"
14670 * NOOP
14671 */
14672 }
14673 } else {
14674 /*
14675 * SPEC {attribute wildcard}
14676 * (3.1) "If the <restriction> alternative is chosen, then the
14677 * `complete wildcard`;"
14678 * NOOP
14679 */
14680 }
14681
14682 return (0);
14683
14684exit_failure:
14685 return(-1);
14686}
14687
14700static int
14701xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14702{
14703 if (type == NULL)
14704 return (0);
14705 if (type->flags & final)
14706 return (1);
14707 else
14708 return (0);
14709}
14710
14718static xmlSchemaTypeLinkPtr
14719xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14720{
14721 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14722 if (type->memberTypes != NULL)
14723 return (type->memberTypes);
14724 else
14725 type = type->baseType;
14726 }
14727 return (NULL);
14728}
14729
14730#if 0
14740static int
14741xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14742{
14743 if ((particle->children == NULL) ||
14744 (particle->minOccurs == 0))
14745 return (0);
14746 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14747 int min = -1, cur;
14748 xmlSchemaParticlePtr part =
14749 (xmlSchemaParticlePtr) particle->children->children;
14750
14751 if (part == NULL)
14752 return (0);
14753 while (part != NULL) {
14754 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14755 (part->children->type == XML_SCHEMA_TYPE_ANY))
14756 cur = part->minOccurs;
14757 else
14758 cur = xmlSchemaGetParticleTotalRangeMin(part);
14759 if (cur == 0)
14760 return (0);
14761 if ((min > cur) || (min == -1))
14762 min = cur;
14763 part = (xmlSchemaParticlePtr) part->next;
14764 }
14765 return (particle->minOccurs * min);
14766 } else {
14767 /* <all> and <sequence> */
14768 int sum = 0;
14769 xmlSchemaParticlePtr part =
14770 (xmlSchemaParticlePtr) particle->children->children;
14771
14772 if (part == NULL)
14773 return (0);
14774 do {
14775 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14776 (part->children->type == XML_SCHEMA_TYPE_ANY))
14777 sum += part->minOccurs;
14778 else
14779 sum += xmlSchemaGetParticleTotalRangeMin(part);
14780 part = (xmlSchemaParticlePtr) part->next;
14781 } while (part != NULL);
14782 return (particle->minOccurs * sum);
14783 }
14784}
14785
14795static int
14796xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14797{
14798 if ((particle->children == NULL) ||
14799 (particle->children->children == NULL))
14800 return (0);
14801 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14802 int max = -1, cur;
14803 xmlSchemaParticlePtr part =
14804 (xmlSchemaParticlePtr) particle->children->children;
14805
14806 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14807 if (part->children == NULL)
14808 continue;
14809 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14810 (part->children->type == XML_SCHEMA_TYPE_ANY))
14811 cur = part->maxOccurs;
14812 else
14813 cur = xmlSchemaGetParticleTotalRangeMax(part);
14814 if (cur == UNBOUNDED)
14815 return (UNBOUNDED);
14816 if ((max < cur) || (max == -1))
14817 max = cur;
14818 }
14819 /* TODO: Handle overflows? */
14820 return (particle->maxOccurs * max);
14821 } else {
14822 /* <all> and <sequence> */
14823 int sum = 0, cur;
14824 xmlSchemaParticlePtr part =
14825 (xmlSchemaParticlePtr) particle->children->children;
14826
14827 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14828 if (part->children == NULL)
14829 continue;
14830 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14831 (part->children->type == XML_SCHEMA_TYPE_ANY))
14832 cur = part->maxOccurs;
14833 else
14834 cur = xmlSchemaGetParticleTotalRangeMax(part);
14835 if (cur == UNBOUNDED)
14836 return (UNBOUNDED);
14837 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14838 return (UNBOUNDED);
14839 sum += cur;
14840 }
14841 /* TODO: Handle overflows? */
14842 return (particle->maxOccurs * sum);
14843 }
14844}
14845#endif
14846
14853static int
14854xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14855{
14856 xmlSchemaParticlePtr part;
14857 int emptiable;
14858
14859 if ((particle->children == NULL) || (particle->minOccurs == 0))
14860 return (1);
14861
14862 part = (xmlSchemaParticlePtr) particle->children->children;
14863 if (part == NULL)
14864 return (1);
14865
14866 while (part != NULL) {
14867 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14868 (part->children->type == XML_SCHEMA_TYPE_ANY))
14869 emptiable = (part->minOccurs == 0);
14870 else
14871 emptiable = xmlSchemaGetParticleEmptiable(part);
14872 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14873 if (emptiable)
14874 return (1);
14875 } else {
14876 /* <all> and <sequence> */
14877 if (!emptiable)
14878 return (0);
14879 }
14880 part = (xmlSchemaParticlePtr) part->next;
14881 }
14882
14883 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14884 return (0);
14885 else
14886 return (1);
14887}
14888
14898static int
14899xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14900{
14901 /*
14902 * SPEC (1) "Its {min occurs} is 0."
14903 */
14904 if ((particle == NULL) || (particle->minOccurs == 0) ||
14905 (particle->children == NULL))
14906 return (1);
14907 /*
14908 * SPEC (2) "Its {term} is a group and the minimum part of the
14909 * effective total range of that group, [...] is 0."
14910 */
14911 if (WXS_IS_MODEL_GROUP(particle->children))
14912 return (xmlSchemaGetParticleEmptiable(particle));
14913 return (0);
14914}
14915
14931static int
14932xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14933 xmlSchemaTypePtr type,
14934 xmlSchemaTypePtr baseType,
14935 int subset)
14936{
14937 /*
14938 * 1 They are the same type definition.
14939 * TODO: The identity check might have to be more complex than this.
14940 */
14941 if (type == baseType)
14942 return (0);
14943 /*
14944 * 2.1 restriction is not in the subset, or in the {final}
14945 * of its own {base type definition};
14946 *
14947 * NOTE that this will be used also via "xsi:type".
14948 *
14949 * TODO: Revise this, it looks strange. How can the "type"
14950 * not be fixed or *in* fixing?
14951 */
14952 if (WXS_IS_TYPE_NOT_FIXED(type))
14953 if (xmlSchemaTypeFixup(type, actxt) == -1)
14954 return(-1);
14955 if (WXS_IS_TYPE_NOT_FIXED(baseType))
14956 if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14957 return(-1);
14958 if ((subset & SUBSET_RESTRICTION) ||
14959 (xmlSchemaTypeFinalContains(type->baseType,
14960 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14962 }
14963 /* 2.2 */
14964 if (type->baseType == baseType) {
14965 /*
14966 * 2.2.1 D's `base type definition` is B.
14967 */
14968 return (0);
14969 }
14970 /*
14971 * 2.2.2 D's `base type definition` is not the `ur-type definition`
14972 * and is validly derived from B given the subset, as defined by this
14973 * constraint.
14974 */
14975 if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14976 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14977 baseType, subset) == 0)) {
14978 return (0);
14979 }
14980 /*
14981 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14982 * definition`.
14983 */
14984 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14985 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14986 return (0);
14987 }
14988 /*
14989 * 2.2.4 B's {variety} is union and D is validly derived from a type
14990 * definition in B's {member type definitions} given the subset, as
14991 * defined by this constraint.
14992 *
14993 * NOTE: This seems not to involve built-in types, since there is no
14994 * built-in Union Simple Type.
14995 */
14996 if (WXS_IS_UNION(baseType)) {
14997 xmlSchemaTypeLinkPtr cur;
14998
14999 cur = baseType->memberTypes;
15000 while (cur != NULL) {
15001 if (WXS_IS_TYPE_NOT_FIXED(cur->type))
15002 if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
15003 return(-1);
15004 if (xmlSchemaCheckCOSSTDerivedOK(actxt,
15005 type, cur->type, subset) == 0)
15006 {
15007 /*
15008 * It just has to be validly derived from at least one
15009 * member-type.
15010 */
15011 return (0);
15012 }
15013 cur = cur->next;
15014 }
15015 }
15017}
15018
15031static int
15032xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
15033 xmlSchemaTypePtr ctxtType,
15034 xmlSchemaTypePtr ancestor)
15035{
15036 int ret;
15037
15038 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
15039 return (0);
15040
15041 if (ctxtType == ancestor) {
15042 xmlSchemaPCustomErr(pctxt,
15044 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
15045 "The definition is circular", NULL);
15047 }
15048 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
15049 /*
15050 * Avoid infinite recursion on circular types not yet checked.
15051 */
15052 return (0);
15053 }
15054 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
15055 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
15056 ancestor->baseType);
15057 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
15058 return (ret);
15059}
15060
15069static void
15070xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
15071 xmlSchemaParserCtxtPtr ctxt)
15072{
15073 if ((item == NULL) ||
15074 (item->type == XML_SCHEMA_TYPE_BASIC) ||
15075 (item->baseType == NULL))
15076 return;
15077 xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
15078 item->baseType);
15079}
15080
15081/*
15082* Simple Type Definition Representation OK (src-simple-type) 4
15083*
15084* "4 Circular union type definition is disallowed. That is, if the
15085* <union> alternative is chosen, there must not be any entries in the
15086* memberTypes [attribute] at any depth which resolve to the component
15087* corresponding to the <simpleType>."
15088*
15089* Note that this should work on the *representation* of a component,
15090* thus assumes any union types in the member types not being yet
15091* substituted. At this stage we need the variety of the types
15092* to be already computed.
15093*/
15094static int
15095xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
15096 xmlSchemaTypePtr ctxType,
15097 xmlSchemaTypeLinkPtr members)
15098{
15099 xmlSchemaTypeLinkPtr member;
15100 xmlSchemaTypePtr memberType;
15101
15102 member = members;
15103 while (member != NULL) {
15104 memberType = member->type;
15105 while ((memberType != NULL) &&
15106 (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
15107 if (memberType == ctxType) {
15108 xmlSchemaPCustomErr(pctxt,
15110 WXS_BASIC_CAST ctxType, NULL,
15111 "The union type definition is circular", NULL);
15113 }
15114 if ((WXS_IS_UNION(memberType)) &&
15115 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
15116 {
15117 int res;
15118 memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
15119 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
15120 ctxType,
15121 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
15122 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
15123 if (res != 0)
15124 return(res);
15125 }
15126 memberType = memberType->baseType;
15127 }
15128 member = member->next;
15129 }
15130 return(0);
15131}
15132
15133static int
15134xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15135 xmlSchemaTypePtr type)
15136{
15137 if (! WXS_IS_UNION(type))
15138 return(0);
15139 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15140 type->memberTypes));
15141}
15142
15151static void
15152xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15153 xmlSchemaParserCtxtPtr ctxt)
15154{
15155 if (typeDef == NULL)
15156 return;
15157
15158 /*
15159 * Resolve the base type.
15160 */
15161 if (typeDef->baseType == NULL) {
15162 typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15163 typeDef->base, typeDef->baseNs);
15164 if (typeDef->baseType == NULL) {
15165 xmlSchemaPResCompAttrErr(ctxt,
15167 WXS_BASIC_CAST typeDef, typeDef->node,
15168 "base", typeDef->base, typeDef->baseNs,
15169 XML_SCHEMA_TYPE_SIMPLE, NULL);
15170 return;
15171 }
15172 }
15173 if (WXS_IS_SIMPLE(typeDef)) {
15174 if (WXS_IS_UNION(typeDef)) {
15175 /*
15176 * Resolve the memberTypes.
15177 */
15178 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15179 return;
15180 } else if (WXS_IS_LIST(typeDef)) {
15181 /*
15182 * Resolve the itemType.
15183 */
15184 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15185
15186 typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15187 typeDef->base, typeDef->baseNs);
15188
15189 if ((typeDef->subtypes == NULL) ||
15190 (! WXS_IS_SIMPLE(typeDef->subtypes)))
15191 {
15192 typeDef->subtypes = NULL;
15193 xmlSchemaPResCompAttrErr(ctxt,
15195 WXS_BASIC_CAST typeDef, typeDef->node,
15196 "itemType", typeDef->base, typeDef->baseNs,
15197 XML_SCHEMA_TYPE_SIMPLE, NULL);
15198 }
15199 }
15200 return;
15201 }
15202 }
15203 /*
15204 * The ball of letters below means, that if we have a particle
15205 * which has a QName-helper component as its {term}, we want
15206 * to resolve it...
15207 */
15208 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15209 ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15210 XML_SCHEMA_TYPE_PARTICLE) &&
15211 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15212 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15213 XML_SCHEMA_EXTRA_QNAMEREF))
15214 {
15215 xmlSchemaQNameRefPtr ref =
15216 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15217 xmlSchemaModelGroupDefPtr groupDef;
15218
15219 /*
15220 * URGENT TODO: Test this.
15221 */
15222 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15223 /*
15224 * Resolve the MG definition reference.
15225 */
15226 groupDef =
15227 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15228 ref->itemType, ref->name, ref->targetNamespace);
15229 if (groupDef == NULL) {
15230 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15231 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15232 "ref", ref->name, ref->targetNamespace, ref->itemType,
15233 NULL);
15234 /* Remove the particle. */
15235 WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15236 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15237 /* Remove the particle. */
15238 WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15239 else {
15240 /*
15241 * Assign the MG definition's {model group} to the
15242 * particle's {term}.
15243 */
15244 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15245
15246 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15247 /*
15248 * SPEC cos-all-limited (1.2)
15249 * "1.2 the {term} property of a particle with
15250 * {max occurs}=1 which is part of a pair which constitutes
15251 * the {content type} of a complex type definition."
15252 */
15253 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15254 xmlSchemaCustomErr(ACTXT_CAST ctxt,
15255 /* TODO: error code */
15257 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15258 "The particle's {max occurs} must be 1, since the "
15259 "reference resolves to an 'all' model group",
15260 NULL, NULL);
15261 }
15262 }
15263 }
15264 }
15265}
15266
15267
15268
15280static int
15281xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15282 xmlSchemaTypePtr type)
15283{
15284 xmlSchemaTypePtr baseType = type->baseType;
15285 xmlChar *str = NULL;
15286
15287 /* STATE: error funcs converted. */
15288 /*
15289 * Schema Component Constraint: Simple Type Definition Properties Correct
15290 *
15291 * NOTE: This is somehow redundant, since we actually built a simple type
15292 * to have all the needed information; this acts as an self test.
15293 */
15294 /* Base type: If the datatype has been `derived` by `restriction`
15295 * then the Simple Type Definition component from which it is `derived`,
15296 * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15297 */
15298 if (baseType == NULL) {
15299 /*
15300 * TODO: Think about: "modulo the impact of Missing
15301 * Sub-components ($5.3)."
15302 */
15303 xmlSchemaPCustomErr(ctxt,
15305 WXS_BASIC_CAST type, NULL,
15306 "No base type existent", NULL);
15308
15309 }
15310 if (! WXS_IS_SIMPLE(baseType)) {
15311 xmlSchemaPCustomErr(ctxt,
15313 WXS_BASIC_CAST type, NULL,
15314 "The base type '%s' is not a simple type",
15315 xmlSchemaGetComponentQName(&str, baseType));
15316 FREE_AND_NULL(str)
15318 }
15319 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15320 (WXS_IS_RESTRICTION(type) == 0) &&
15321 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15322 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15323 xmlSchemaPCustomErr(ctxt,
15325 WXS_BASIC_CAST type, NULL,
15326 "A type, derived by list or union, must have "
15327 "the simple ur-type definition as base type, not '%s'",
15328 xmlSchemaGetComponentQName(&str, baseType));
15329 FREE_AND_NULL(str)
15331 }
15332 /*
15333 * Variety: One of {atomic, list, union}.
15334 */
15335 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15336 (! WXS_IS_LIST(type))) {
15337 xmlSchemaPCustomErr(ctxt,
15339 WXS_BASIC_CAST type, NULL,
15340 "The variety is absent", NULL);
15342 }
15343 /* TODO: Finish this. Hmm, is this finished? */
15344
15345 /*
15346 * 3 The {final} of the {base type definition} must not contain restriction.
15347 */
15348 if (xmlSchemaTypeFinalContains(baseType,
15349 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15350 xmlSchemaPCustomErr(ctxt,
15352 WXS_BASIC_CAST type, NULL,
15353 "The 'final' of its base type '%s' must not contain "
15354 "'restriction'",
15355 xmlSchemaGetComponentQName(&str, baseType));
15356 FREE_AND_NULL(str)
15358 }
15359
15360 /*
15361 * 2 All simple type definitions must be derived ultimately from the `simple
15362 * ur-type definition` (so circular definitions are disallowed). That is, it
15363 * must be possible to reach a built-in primitive datatype or the `simple
15364 * ur-type definition` by repeatedly following the {base type definition}.
15365 *
15366 * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15367 */
15368 return (0);
15369}
15370
15385static int
15386xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15387 xmlSchemaTypePtr type)
15388{
15389 xmlChar *str = NULL;
15390
15391 if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15392 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15393 "given type is not a user-derived simpleType");
15394 return (-1);
15395 }
15396
15397 if (WXS_IS_ATOMIC(type)) {
15398 xmlSchemaTypePtr primitive;
15399 /*
15400 * 1.1 The {base type definition} must be an atomic simple
15401 * type definition or a built-in primitive datatype.
15402 */
15403 if (! WXS_IS_ATOMIC(type->baseType)) {
15404 xmlSchemaPCustomErr(pctxt,
15406 WXS_BASIC_CAST type, NULL,
15407 "The base type '%s' is not an atomic simple type",
15408 xmlSchemaGetComponentQName(&str, type->baseType));
15409 FREE_AND_NULL(str)
15411 }
15412 /* 1.2 The {final} of the {base type definition} must not contain
15413 * restriction.
15414 */
15415 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15416 if (xmlSchemaTypeFinalContains(type->baseType,
15417 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15418 xmlSchemaPCustomErr(pctxt,
15420 WXS_BASIC_CAST type, NULL,
15421 "The final of its base type '%s' must not contain 'restriction'",
15422 xmlSchemaGetComponentQName(&str, type->baseType));
15423 FREE_AND_NULL(str)
15425 }
15426
15427 /*
15428 * 1.3.1 DF must be an allowed constraining facet for the {primitive
15429 * type definition}, as specified in the appropriate subsection of 3.2
15430 * Primitive datatypes.
15431 */
15432 if (type->facets != NULL) {
15433 xmlSchemaFacetPtr facet;
15434 int ok = 1;
15435
15436 primitive = xmlSchemaGetPrimitiveType(type);
15437 if (primitive == NULL) {
15438 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15439 "failed to get primitive type");
15440 return (-1);
15441 }
15442 facet = type->facets;
15443 do {
15444 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15445 ok = 0;
15446 xmlSchemaPIllegalFacetAtomicErr(pctxt,
15448 type, primitive, facet);
15449 }
15450 facet = facet->next;
15451 } while (facet != NULL);
15452 if (ok == 0)
15454 }
15455 /*
15456 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15457 * of the {base type definition} (call this BF),then the DF's {value}
15458 * must be a valid restriction of BF's {value} as defined in
15459 * [XML Schemas: Datatypes]."
15460 *
15461 * NOTE (1.3.2) Facet derivation constraints are currently handled in
15462 * xmlSchemaDeriveAndValidateFacets()
15463 */
15464 } else if (WXS_IS_LIST(type)) {
15465 xmlSchemaTypePtr itemType = NULL;
15466
15467 itemType = type->subtypes;
15468 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15469 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15470 "failed to evaluate the item type");
15471 return (-1);
15472 }
15473 if (WXS_IS_TYPE_NOT_FIXED(itemType))
15474 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15475 /*
15476 * 2.1 The {item type definition} must have a {variety} of atomic or
15477 * union (in which case all the {member type definitions}
15478 * must be atomic).
15479 */
15480 if ((! WXS_IS_ATOMIC(itemType)) &&
15481 (! WXS_IS_UNION(itemType))) {
15482 xmlSchemaPCustomErr(pctxt,
15484 WXS_BASIC_CAST type, NULL,
15485 "The item type '%s' does not have a variety of atomic or union",
15486 xmlSchemaGetComponentQName(&str, itemType));
15487 FREE_AND_NULL(str)
15489 } else if (WXS_IS_UNION(itemType)) {
15490 xmlSchemaTypeLinkPtr member;
15491
15492 member = itemType->memberTypes;
15493 while (member != NULL) {
15494 if (! WXS_IS_ATOMIC(member->type)) {
15495 xmlSchemaPCustomErr(pctxt,
15497 WXS_BASIC_CAST type, NULL,
15498 "The item type is a union type, but the "
15499 "member type '%s' of this item type is not atomic",
15500 xmlSchemaGetComponentQName(&str, member->type));
15501 FREE_AND_NULL(str)
15503 }
15504 member = member->next;
15505 }
15506 }
15507
15508 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15509 xmlSchemaFacetPtr facet;
15510 /*
15511 * This is the case if we have: <simpleType><list ..
15512 */
15513 /*
15514 * 2.3.1
15515 * 2.3.1.1 The {final} of the {item type definition} must not
15516 * contain list.
15517 */
15518 if (xmlSchemaTypeFinalContains(itemType,
15519 XML_SCHEMAS_TYPE_FINAL_LIST)) {
15520 xmlSchemaPCustomErr(pctxt,
15522 WXS_BASIC_CAST type, NULL,
15523 "The final of its item type '%s' must not contain 'list'",
15524 xmlSchemaGetComponentQName(&str, itemType));
15525 FREE_AND_NULL(str)
15527 }
15528 /*
15529 * 2.3.1.2 The {facets} must only contain the whiteSpace
15530 * facet component.
15531 * OPTIMIZE TODO: the S4S already disallows any facet
15532 * to be specified.
15533 */
15534 if (type->facets != NULL) {
15535 facet = type->facets;
15536 do {
15537 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15538 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15540 type, facet);
15542 }
15543 facet = facet->next;
15544 } while (facet != NULL);
15545 }
15546 /*
15547 * MAYBE TODO: (Hmm, not really) Datatypes states:
15548 * A `list` datatype can be `derived` from an `atomic` datatype
15549 * whose `lexical space` allows space (such as string or anyURI)or
15550 * a `union` datatype any of whose {member type definitions}'s
15551 * `lexical space` allows space.
15552 */
15553 } else {
15554 /*
15555 * This is the case if we have: <simpleType><restriction ...
15556 * I.e. the variety of "list" is inherited.
15557 */
15558 /*
15559 * 2.3.2
15560 * 2.3.2.1 The {base type definition} must have a {variety} of list.
15561 */
15562 if (! WXS_IS_LIST(type->baseType)) {
15563 xmlSchemaPCustomErr(pctxt,
15565 WXS_BASIC_CAST type, NULL,
15566 "The base type '%s' must be a list type",
15567 xmlSchemaGetComponentQName(&str, type->baseType));
15568 FREE_AND_NULL(str)
15570 }
15571 /*
15572 * 2.3.2.2 The {final} of the {base type definition} must not
15573 * contain restriction.
15574 */
15575 if (xmlSchemaTypeFinalContains(type->baseType,
15576 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15577 xmlSchemaPCustomErr(pctxt,
15579 WXS_BASIC_CAST type, NULL,
15580 "The 'final' of the base type '%s' must not contain 'restriction'",
15581 xmlSchemaGetComponentQName(&str, type->baseType));
15582 FREE_AND_NULL(str)
15584 }
15585 /*
15586 * 2.3.2.3 The {item type definition} must be validly derived
15587 * from the {base type definition}'s {item type definition} given
15588 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15589 */
15590 {
15591 xmlSchemaTypePtr baseItemType;
15592
15593 baseItemType = type->baseType->subtypes;
15594 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15595 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15596 "failed to eval the item type of a base type");
15597 return (-1);
15598 }
15599 if ((itemType != baseItemType) &&
15600 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15601 baseItemType, 0) != 0)) {
15602 xmlChar *strBIT = NULL, *strBT = NULL;
15603 xmlSchemaPCustomErrExt(pctxt,
15605 WXS_BASIC_CAST type, NULL,
15606 "The item type '%s' is not validly derived from "
15607 "the item type '%s' of the base type '%s'",
15608 xmlSchemaGetComponentQName(&str, itemType),
15609 xmlSchemaGetComponentQName(&strBIT, baseItemType),
15610 xmlSchemaGetComponentQName(&strBT, type->baseType));
15611
15612 FREE_AND_NULL(str)
15613 FREE_AND_NULL(strBIT)
15614 FREE_AND_NULL(strBT)
15616 }
15617 }
15618
15619 if (type->facets != NULL) {
15620 xmlSchemaFacetPtr facet;
15621 int ok = 1;
15622 /*
15623 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15624 * and enumeration facet components are allowed among the {facets}.
15625 */
15626 facet = type->facets;
15627 do {
15628 switch (facet->type) {
15629 case XML_SCHEMA_FACET_LENGTH:
15630 case XML_SCHEMA_FACET_MINLENGTH:
15631 case XML_SCHEMA_FACET_MAXLENGTH:
15632 case XML_SCHEMA_FACET_WHITESPACE:
15633 /*
15634 * TODO: 2.5.1.2 List datatypes
15635 * The value of `whiteSpace` is fixed to the value collapse.
15636 */
15637 case XML_SCHEMA_FACET_PATTERN:
15638 case XML_SCHEMA_FACET_ENUMERATION:
15639 break;
15640 default: {
15641 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15643 type, facet);
15644 /*
15645 * We could return, but it's nicer to report all
15646 * invalid facets.
15647 */
15648 ok = 0;
15649 }
15650 }
15651 facet = facet->next;
15652 } while (facet != NULL);
15653 if (ok == 0)
15655 /*
15656 * SPEC (2.3.2.5) (same as 1.3.2)
15657 *
15658 * NOTE (2.3.2.5) This is currently done in
15659 * xmlSchemaDeriveAndValidateFacets()
15660 */
15661 }
15662 }
15663 } else if (WXS_IS_UNION(type)) {
15664 /*
15665 * 3.1 The {member type definitions} must all have {variety} of
15666 * atomic or list.
15667 */
15668 xmlSchemaTypeLinkPtr member;
15669
15670 member = type->memberTypes;
15671 while (member != NULL) {
15672 if (WXS_IS_TYPE_NOT_FIXED(member->type))
15673 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15674
15675 if ((! WXS_IS_ATOMIC(member->type)) &&
15676 (! WXS_IS_LIST(member->type))) {
15677 xmlSchemaPCustomErr(pctxt,
15679 WXS_BASIC_CAST type, NULL,
15680 "The member type '%s' is neither an atomic, nor a list type",
15681 xmlSchemaGetComponentQName(&str, member->type));
15682 FREE_AND_NULL(str)
15684 }
15685 member = member->next;
15686 }
15687 /*
15688 * 3.3.1 If the {base type definition} is the `simple ur-type
15689 * definition`
15690 */
15691 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15692 /*
15693 * 3.3.1.1 All of the {member type definitions} must have a
15694 * {final} which does not contain union.
15695 */
15696 member = type->memberTypes;
15697 while (member != NULL) {
15698 if (xmlSchemaTypeFinalContains(member->type,
15699 XML_SCHEMAS_TYPE_FINAL_UNION)) {
15700 xmlSchemaPCustomErr(pctxt,
15702 WXS_BASIC_CAST type, NULL,
15703 "The 'final' of member type '%s' contains 'union'",
15704 xmlSchemaGetComponentQName(&str, member->type));
15705 FREE_AND_NULL(str)
15707 }
15708 member = member->next;
15709 }
15710 /*
15711 * 3.3.1.2 The {facets} must be empty.
15712 */
15713 if (type->facetSet != NULL) {
15714 xmlSchemaPCustomErr(pctxt,
15716 WXS_BASIC_CAST type, NULL,
15717 "No facets allowed", NULL);
15719 }
15720 } else {
15721 /*
15722 * 3.3.2.1 The {base type definition} must have a {variety} of union.
15723 * I.e. the variety of "list" is inherited.
15724 */
15725 if (! WXS_IS_UNION(type->baseType)) {
15726 xmlSchemaPCustomErr(pctxt,
15728 WXS_BASIC_CAST type, NULL,
15729 "The base type '%s' is not a union type",
15730 xmlSchemaGetComponentQName(&str, type->baseType));
15731 FREE_AND_NULL(str)
15733 }
15734 /*
15735 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15736 */
15737 if (xmlSchemaTypeFinalContains(type->baseType,
15738 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15739 xmlSchemaPCustomErr(pctxt,
15741 WXS_BASIC_CAST type, NULL,
15742 "The 'final' of its base type '%s' must not contain 'restriction'",
15743 xmlSchemaGetComponentQName(&str, type->baseType));
15744 FREE_AND_NULL(str)
15746 }
15747 /*
15748 * 3.3.2.3 The {member type definitions}, in order, must be validly
15749 * derived from the corresponding type definitions in the {base
15750 * type definition}'s {member type definitions} given the empty set,
15751 * as defined in Type Derivation OK (Simple) ($3.14.6).
15752 */
15753 {
15754 xmlSchemaTypeLinkPtr baseMember;
15755
15756 /*
15757 * OPTIMIZE: if the type is restricting, it has no local defined
15758 * member types and inherits the member types of the base type;
15759 * thus a check for equality can be skipped.
15760 */
15761 /*
15762 * Even worse: I cannot see a scenario where a restricting
15763 * union simple type can have other member types as the member
15764 * types of it's base type. This check seems not necessary with
15765 * respect to the derivation process in libxml2.
15766 * But necessary if constructing types with an API.
15767 */
15768 if (type->memberTypes != NULL) {
15769 member = type->memberTypes;
15770 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15771 if ((member == NULL) && (baseMember != NULL)) {
15772 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15773 "different number of member types in base");
15774 }
15775 while (member != NULL) {
15776 if (baseMember == NULL) {
15777 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15778 "different number of member types in base");
15779 } else if ((member->type != baseMember->type) &&
15780 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15781 member->type, baseMember->type, 0) != 0)) {
15782 xmlChar *strBMT = NULL, *strBT = NULL;
15783
15784 xmlSchemaPCustomErrExt(pctxt,
15786 WXS_BASIC_CAST type, NULL,
15787 "The member type %s is not validly "
15788 "derived from its corresponding member "
15789 "type %s of the base type %s",
15790 xmlSchemaGetComponentQName(&str, member->type),
15791 xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15792 xmlSchemaGetComponentQName(&strBT, type->baseType));
15793 FREE_AND_NULL(str)
15794 FREE_AND_NULL(strBMT)
15795 FREE_AND_NULL(strBT)
15797 }
15798 member = member->next;
15799 if (baseMember != NULL)
15800 baseMember = baseMember->next;
15801 }
15802 }
15803 }
15804 /*
15805 * 3.3.2.4 Only pattern and enumeration facet components are
15806 * allowed among the {facets}.
15807 */
15808 if (type->facets != NULL) {
15809 xmlSchemaFacetPtr facet;
15810 int ok = 1;
15811
15812 facet = type->facets;
15813 do {
15814 if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15815 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15816 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15818 type, facet);
15819 ok = 0;
15820 }
15821 facet = facet->next;
15822 } while (facet != NULL);
15823 if (ok == 0)
15825
15826 }
15827 /*
15828 * SPEC (3.3.2.5) (same as 1.3.2)
15829 *
15830 * NOTE (3.3.2.5) This is currently done in
15831 * xmlSchemaDeriveAndValidateFacets()
15832 */
15833 }
15834 }
15835
15836 return (0);
15837}
15838
15850#if 0
15851static int
15852xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15853 xmlSchemaTypePtr type)
15854{
15855 /*
15856 * src-simple-type.1 The corresponding simple type definition, if any,
15857 * must satisfy the conditions set out in Constraints on Simple Type
15858 * Definition Schema Components ($3.14.6).
15859 */
15860 if (WXS_IS_RESTRICTION(type)) {
15861 /*
15862 * src-simple-type.2 "If the <restriction> alternative is chosen,
15863 * either it must have a base [attribute] or a <simpleType> among its
15864 * [children], but not both."
15865 * NOTE: This is checked in the parse function of <restriction>.
15866 */
15867 /*
15868 *
15869 */
15870 } else if (WXS_IS_LIST(type)) {
15871 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15872 * an itemType [attribute] or a <simpleType> among its [children],
15873 * but not both."
15874 *
15875 * NOTE: This is checked in the parse function of <list>.
15876 */
15877 } else if (WXS_IS_UNION(type)) {
15878 /*
15879 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15880 */
15881 }
15882 return (0);
15883}
15884#endif
15885
15886static int
15887xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15888{
15889 if (ctxt->vctxt == NULL) {
15890 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15891 if (ctxt->vctxt == NULL) {
15892 xmlSchemaPErr(ctxt, NULL,
15894 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15895 "failed to create a temp. validation context.\n",
15896 NULL, NULL);
15897 return (-1);
15898 }
15899 /* TODO: Pass user data. */
15900 xmlSchemaSetValidErrors(ctxt->vctxt,
15901 ctxt->error, ctxt->warning, ctxt->errCtxt);
15902 xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15903 ctxt->serror, ctxt->errCtxt);
15904 }
15905 return (0);
15906}
15907
15908static int
15909xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15911 xmlSchemaTypePtr type,
15912 const xmlChar *value,
15913 xmlSchemaValPtr *retVal,
15914 int fireErrors,
15915 int normalize,
15916 int isNormalized);
15917
15934static int
15935xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15937 xmlSchemaTypePtr type,
15938 const xmlChar *value,
15939 xmlSchemaValPtr *val)
15940{
15941 int ret = 0;
15942
15943 /*
15944 * cos-valid-default:
15945 * Schema Component Constraint: Element Default Valid (Immediate)
15946 * For a string to be a valid default with respect to a type
15947 * definition the appropriate case among the following must be true:
15948 */
15949 if WXS_IS_COMPLEX(type) {
15950 /*
15951 * Complex type.
15952 *
15953 * SPEC (2.1) "its {content type} must be a simple type definition
15954 * or mixed."
15955 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15956 * type}'s particle must be `emptiable` as defined by
15957 * Particle Emptiable ($3.9.6)."
15958 */
15959 if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15960 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15961 /* NOTE that this covers (2.2.2) as well. */
15962 xmlSchemaPCustomErr(pctxt,
15964 WXS_BASIC_CAST type, type->node,
15965 "For a string to be a valid default, the type definition "
15966 "must be a simple type or a complex type with mixed content "
15967 "and a particle emptiable", NULL);
15969 }
15970 }
15971 /*
15972 * 1 If the type definition is a simple type definition, then the string
15973 * must be `valid` with respect to that definition as defined by String
15974 * Valid ($3.14.4).
15975 *
15976 * AND
15977 *
15978 * 2.2.1 If the {content type} is a simple type definition, then the
15979 * string must be `valid` with respect to that simple type definition
15980 * as defined by String Valid ($3.14.4).
15981 */
15982 if (WXS_IS_SIMPLE(type))
15983 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15984 type, value, val, 1, 1, 0);
15985 else if (WXS_HAS_SIMPLE_CONTENT(type))
15986 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15987 type->contentTypeDef, value, val, 1, 1, 0);
15988 else
15989 return (ret);
15990
15991 if (ret < 0) {
15992 PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15993 "calling xmlSchemaVCheckCVCSimpleType()");
15994 }
15995
15996 return (ret);
15997}
15998
16012static int
16013xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
16014 xmlSchemaTypePtr type)
16015{
16016 /*
16017 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
16018 *
16019 * SPEC (1) "The values of the properties of a complex type definition must
16020 * be as described in the property tableau in The Complex Type Definition
16021 * Schema Component ($3.4.1), modulo the impact of Missing
16022 * Sub-components ($5.3)."
16023 */
16024 if ((type->baseType != NULL) &&
16025 (WXS_IS_SIMPLE(type->baseType)) &&
16026 (WXS_IS_EXTENSION(type) == 0)) {
16027 /*
16028 * SPEC (2) "If the {base type definition} is a simple type definition,
16029 * the {derivation method} must be extension."
16030 */
16031 xmlSchemaCustomErr(ACTXT_CAST pctxt,
16033 NULL, WXS_BASIC_CAST type,
16034 "If the base type is a simple type, the derivation method must be "
16035 "'extension'", NULL, NULL);
16036 return (XML_SCHEMAP_SRC_CT_1);
16037 }
16038 /*
16039 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
16040 * definition`. That is, it must be possible to reach the `ur-type
16041 * definition` by repeatedly following the {base type definition}."
16042 *
16043 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
16044 */
16045 /*
16046 * NOTE that (4) and (5) need the following:
16047 * - attribute uses need to be already inherited (apply attr. prohibitions)
16048 * - attribute group references need to be expanded already
16049 * - simple types need to be typefixed already
16050 */
16051 if (type->attrUses &&
16052 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
16053 {
16054 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
16055 xmlSchemaAttributeUsePtr use, tmp;
16056 int i, j, hasId = 0;
16057
16058 for (i = uses->nbItems -1; i >= 0; i--) {
16059 use = uses->items[i];
16060
16061 /*
16062 * SPEC ct-props-correct
16063 * (4) "Two distinct attribute declarations in the
16064 * {attribute uses} must not have identical {name}s and
16065 * {target namespace}s."
16066 */
16067 if (i > 0) {
16068 for (j = i -1; j >= 0; j--) {
16069 tmp = uses->items[j];
16070 if ((WXS_ATTRUSE_DECL_NAME(use) ==
16071 WXS_ATTRUSE_DECL_NAME(tmp)) &&
16072 (WXS_ATTRUSE_DECL_TNS(use) ==
16073 WXS_ATTRUSE_DECL_TNS(tmp)))
16074 {
16075 xmlChar *str = NULL;
16076
16077 xmlSchemaCustomErr(ACTXT_CAST pctxt,
16079 NULL, WXS_BASIC_CAST type,
16080 "Duplicate %s",
16081 xmlSchemaGetComponentDesignation(&str, use),
16082 NULL);
16083 FREE_AND_NULL(str);
16084 /*
16085 * Remove the duplicate.
16086 */
16087 if (xmlSchemaItemListRemove(uses, i) == -1)
16088 goto exit_failure;
16089 goto next_use;
16090 }
16091 }
16092 }
16093 /*
16094 * SPEC ct-props-correct
16095 * (5) "Two distinct attribute declarations in the
16096 * {attribute uses} must not have {type definition}s which
16097 * are or are derived from ID."
16098 */
16099 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
16100 if (xmlSchemaIsDerivedFromBuiltInType(
16101 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
16102 {
16103 if (hasId) {
16104 xmlChar *str = NULL;
16105
16106 xmlSchemaCustomErr(ACTXT_CAST pctxt,
16108 NULL, WXS_BASIC_CAST type,
16109 "There must not exist more than one attribute "
16110 "declaration of type 'xs:ID' "
16111 "(or derived from 'xs:ID'). The %s violates this "
16112 "constraint",
16113 xmlSchemaGetComponentDesignation(&str, use),
16114 NULL);
16115 FREE_AND_NULL(str);
16116 if (xmlSchemaItemListRemove(uses, i) == -1)
16117 goto exit_failure;
16118 }
16119
16120 hasId = 1;
16121 }
16122 }
16123next_use: {}
16124 }
16125 }
16126 return (0);
16127exit_failure:
16128 return(-1);
16129}
16130
16131static int
16132xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16133 xmlSchemaTypePtr typeB)
16134{
16135 /*
16136 * TODO: This should implement component-identity
16137 * in the future.
16138 */
16139 if ((typeA == NULL) || (typeB == NULL))
16140 return (0);
16141 return (typeA == typeB);
16142}
16143
16159static int
16160xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16161 xmlSchemaTypePtr type,
16162 xmlSchemaTypePtr baseType,
16163 int set)
16164{
16165 int equal = xmlSchemaAreEqualTypes(type, baseType);
16166 /* TODO: Error codes. */
16167 /*
16168 * SPEC "For a complex type definition (call it D, for derived)
16169 * to be validly derived from a type definition (call this
16170 * B, for base) given a subset of {extension, restriction}
16171 * all of the following must be true:"
16172 */
16173 if (! equal) {
16174 /*
16175 * SPEC (1) "If B and D are not the same type definition, then the
16176 * {derivation method} of D must not be in the subset."
16177 */
16178 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16179 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16180 return (1);
16181 } else {
16182 /*
16183 * SPEC (2.1) "B and D must be the same type definition."
16184 */
16185 return (0);
16186 }
16187 /*
16188 * SPEC (2.2) "B must be D's {base type definition}."
16189 */
16190 if (type->baseType == baseType)
16191 return (0);
16192 /*
16193 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16194 * definition`."
16195 */
16196 if (WXS_IS_ANYTYPE(type->baseType))
16197 return (1);
16198
16199 if (WXS_IS_COMPLEX(type->baseType)) {
16200 /*
16201 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16202 * must be validly derived from B given the subset as defined by this
16203 * constraint."
16204 */
16205 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16206 baseType, set));
16207 } else {
16208 /*
16209 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16210 * must be validly derived from B given the subset as defined in Type
16211 * Derivation OK (Simple) ($3.14.6).
16212 */
16213 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16214 baseType, set));
16215 }
16216}
16217
16230static int
16231xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16232 xmlSchemaTypePtr type,
16233 xmlSchemaTypePtr baseType,
16234 int set)
16235{
16236 if (WXS_IS_SIMPLE(type))
16237 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16238 else
16239 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16240}
16241
16259static int
16260xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16261 xmlSchemaTypePtr type)
16262{
16263 xmlSchemaTypePtr base = type->baseType;
16264 /*
16265 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16266 * temporarily only.
16267 */
16268 /*
16269 * SPEC (1) "If the {base type definition} is a complex type definition,
16270 * then all of the following must be true:"
16271 */
16272 if (WXS_IS_COMPLEX(base)) {
16273 /*
16274 * SPEC (1.1) "The {final} of the {base type definition} must not
16275 * contain extension."
16276 */
16277 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16278 xmlSchemaPCustomErr(ctxt,
16280 WXS_BASIC_CAST type, NULL,
16281 "The 'final' of the base type definition "
16282 "contains 'extension'", NULL);
16284 }
16285
16286 /*
16287 * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16288 * since they are automatically satisfied through the
16289 * inheriting mechanism.
16290 * Note that even if redefining components, the inheriting mechanism
16291 * is used.
16292 */
16293#if 0
16294 /*
16295 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16296 * uses}
16297 * of the complex type definition itself, that is, for every attribute
16298 * use in the {attribute uses} of the {base type definition}, there
16299 * must be an attribute use in the {attribute uses} of the complex
16300 * type definition itself whose {attribute declaration} has the same
16301 * {name}, {target namespace} and {type definition} as its attribute
16302 * declaration"
16303 */
16304 if (base->attrUses != NULL) {
16305 int i, j, found;
16306 xmlSchemaAttributeUsePtr use, buse;
16307
16308 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16309 buse = (WXS_LIST_CAST base->attrUses)->items[i];
16310 found = 0;
16311 if (type->attrUses != NULL) {
16312 use = (WXS_LIST_CAST type->attrUses)->items[j];
16313 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16314 {
16315 if ((WXS_ATTRUSE_DECL_NAME(use) ==
16316 WXS_ATTRUSE_DECL_NAME(buse)) &&
16317 (WXS_ATTRUSE_DECL_TNS(use) ==
16318 WXS_ATTRUSE_DECL_TNS(buse)) &&
16319 (WXS_ATTRUSE_TYPEDEF(use) ==
16320 WXS_ATTRUSE_TYPEDEF(buse))
16321 {
16322 found = 1;
16323 break;
16324 }
16325 }
16326 }
16327 if (! found) {
16328 xmlChar *str = NULL;
16329
16330 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16332 NULL, WXS_BASIC_CAST type,
16333 /*
16334 * TODO: The report does not indicate that also the
16335 * type needs to be the same.
16336 */
16337 "This type is missing a matching correspondent "
16338 "for its {base type}'s %s in its {attribute uses}",
16339 xmlSchemaGetComponentDesignation(&str,
16340 buse->children),
16341 NULL);
16342 FREE_AND_NULL(str)
16343 }
16344 }
16345 }
16346 /*
16347 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16348 * definition must also have one, and the base type definition's
16349 * {attribute wildcard}'s {namespace constraint} must be a subset
16350 * of the complex type definition's {attribute wildcard}'s {namespace
16351 * constraint}, as defined by Wildcard Subset ($3.10.6)."
16352 */
16353
16354 /*
16355 * MAYBE TODO: Enable if ever needed. But this will be needed only
16356 * if created the type via a schema construction API.
16357 */
16358 if (base->attributeWildcard != NULL) {
16359 if (type->attributeWildcard == NULL) {
16360 xmlChar *str = NULL;
16361
16362 xmlSchemaCustomErr(ACTXT_CAST pctxt,
16364 NULL, type,
16365 "The base %s has an attribute wildcard, "
16366 "but this type is missing an attribute wildcard",
16367 xmlSchemaGetComponentDesignation(&str, base));
16368 FREE_AND_NULL(str)
16369
16370 } else if (xmlSchemaCheckCOSNSSubset(
16371 base->attributeWildcard, type->attributeWildcard))
16372 {
16373 xmlChar *str = NULL;
16374
16375 xmlSchemaCustomErr(ACTXT_CAST pctxt,
16377 NULL, type,
16378 "The attribute wildcard is not a valid "
16379 "superset of the one in the base %s",
16380 xmlSchemaGetComponentDesignation(&str, base));
16381 FREE_AND_NULL(str)
16382 }
16383 }
16384#endif
16385 /*
16386 * SPEC (1.4) "One of the following must be true:"
16387 */
16388 if ((type->contentTypeDef != NULL) &&
16389 (type->contentTypeDef == base->contentTypeDef)) {
16390 /*
16391 * SPEC (1.4.1) "The {content type} of the {base type definition}
16392 * and the {content type} of the complex type definition itself
16393 * must be the same simple type definition"
16394 * PASS
16395 */
16396 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16397 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16398 /*
16399 * SPEC (1.4.2) "The {content type} of both the {base type
16400 * definition} and the complex type definition itself must
16401 * be empty."
16402 * PASS
16403 */
16404 } else {
16405 /*
16406 * SPEC (1.4.3) "All of the following must be true:"
16407 */
16408 if (type->subtypes == NULL) {
16409 /*
16410 * SPEC 1.4.3.1 The {content type} of the complex type
16411 * definition itself must specify a particle.
16412 */
16413 xmlSchemaPCustomErr(ctxt,
16415 WXS_BASIC_CAST type, NULL,
16416 "The content type must specify a particle", NULL);
16418 }
16419 /*
16420 * SPEC (1.4.3.2) "One of the following must be true:"
16421 */
16422 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16423 /*
16424 * SPEC (1.4.3.2.1) "The {content type} of the {base type
16425 * definition} must be empty.
16426 * PASS
16427 */
16428 } else {
16429 /*
16430 * SPEC (1.4.3.2.2) "All of the following must be true:"
16431 */
16432 if ((type->contentType != base->contentType) ||
16433 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16434 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16435 /*
16436 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16437 * or both must be element-only."
16438 */
16439 xmlSchemaPCustomErr(ctxt,
16441 WXS_BASIC_CAST type, NULL,
16442 "The content type of both, the type and its base "
16443 "type, must either 'mixed' or 'element-only'", NULL);
16445 }
16446 /*
16447 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16448 * complex type definition must be a `valid extension`
16449 * of the {base type definition}'s particle, as defined
16450 * in Particle Valid (Extension) ($3.9.6)."
16451 *
16452 * NOTE that we won't check "Particle Valid (Extension)",
16453 * since it is ensured by the derivation process in
16454 * xmlSchemaTypeFixup(). We need to implement this when heading
16455 * for a construction API
16456 * TODO: !! This is needed to be checked if redefining a type !!
16457 */
16458 }
16459 /*
16460 * URGENT TODO (1.5)
16461 */
16462 }
16463 } else {
16464 /*
16465 * SPEC (2) "If the {base type definition} is a simple type definition,
16466 * then all of the following must be true:"
16467 */
16468 if (type->contentTypeDef != base) {
16469 /*
16470 * SPEC (2.1) "The {content type} must be the same simple type
16471 * definition."
16472 */
16473 xmlSchemaPCustomErr(ctxt,
16475 WXS_BASIC_CAST type, NULL,
16476 "The content type must be the simple base type", NULL);
16478 }
16479 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16480 /*
16481 * SPEC (2.2) "The {final} of the {base type definition} must not
16482 * contain extension"
16483 * NOTE that this is the same as (1.1).
16484 */
16485 xmlSchemaPCustomErr(ctxt,
16487 WXS_BASIC_CAST type, NULL,
16488 "The 'final' of the base type definition "
16489 "contains 'extension'", NULL);
16491 }
16492 }
16493 return (0);
16494}
16495
16516static int
16517xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16518 xmlSchemaTypePtr type)
16519{
16520 xmlSchemaTypePtr base;
16521
16522 /*
16523 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16524 * temporarily only.
16525 */
16526 base = type->baseType;
16527 if (! WXS_IS_COMPLEX(base)) {
16528 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16530 type->node, WXS_BASIC_CAST type,
16531 "The base type must be a complex type", NULL, NULL);
16532 return(ctxt->err);
16533 }
16534 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16535 /*
16536 * SPEC (1) "The {base type definition} must be a complex type
16537 * definition whose {final} does not contain restriction."
16538 */
16539 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16541 type->node, WXS_BASIC_CAST type,
16542 "The 'final' of the base type definition "
16543 "contains 'restriction'", NULL, NULL);
16544 return (ctxt->err);
16545 }
16546 /*
16547 * SPEC (2), (3) and (4)
16548 * Those are handled in a separate function, since the
16549 * same constraints are needed for redefinition of
16550 * attribute groups as well.
16551 */
16552 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16553 XML_SCHEMA_ACTION_DERIVE,
16554 WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16555 type->attrUses, base->attrUses,
16556 type->attributeWildcard,
16557 base->attributeWildcard) == -1)
16558 {
16559 return(-1);
16560 }
16561 /*
16562 * SPEC (5) "One of the following must be true:"
16563 */
16564 if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16565 /*
16566 * SPEC (5.1) "The {base type definition} must be the
16567 * `ur-type definition`."
16568 * PASS
16569 */
16570 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16571 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16572 /*
16573 * SPEC (5.2.1) "The {content type} of the complex type definition
16574 * must be a simple type definition"
16575 *
16576 * SPEC (5.2.2) "One of the following must be true:"
16577 */
16578 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16579 (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16580 {
16581 int err;
16582 /*
16583 * SPEC (5.2.2.1) "The {content type} of the {base type
16584 * definition} must be a simple type definition from which
16585 * the {content type} is validly derived given the empty
16586 * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16587 *
16588 * ATTENTION TODO: This seems not needed if the type implicitly
16589 * derived from the base type.
16590 *
16591 */
16592 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16593 type->contentTypeDef, base->contentTypeDef, 0);
16594 if (err != 0) {
16595 xmlChar *strA = NULL, *strB = NULL;
16596
16597 if (err == -1)
16598 return(-1);
16599 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16601 NULL, WXS_BASIC_CAST type,
16602 "The {content type} %s is not validly derived from the "
16603 "base type's {content type} %s",
16604 xmlSchemaGetComponentDesignation(&strA,
16605 type->contentTypeDef),
16606 xmlSchemaGetComponentDesignation(&strB,
16607 base->contentTypeDef));
16608 FREE_AND_NULL(strA);
16609 FREE_AND_NULL(strB);
16610 return(ctxt->err);
16611 }
16612 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16613 (xmlSchemaIsParticleEmptiable(
16614 (xmlSchemaParticlePtr) base->subtypes))) {
16615 /*
16616 * SPEC (5.2.2.2) "The {base type definition} must be mixed
16617 * and have a particle which is `emptiable` as defined in
16618 * Particle Emptiable ($3.9.6)."
16619 * PASS
16620 */
16621 } else {
16622 xmlSchemaPCustomErr(ctxt,
16624 WXS_BASIC_CAST type, NULL,
16625 "The content type of the base type must be either "
16626 "a simple type or 'mixed' and an emptiable particle", NULL);
16627 return (ctxt->err);
16628 }
16629 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16630 /*
16631 * SPEC (5.3.1) "The {content type} of the complex type itself must
16632 * be empty"
16633 */
16634 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16635 /*
16636 * SPEC (5.3.2.1) "The {content type} of the {base type
16637 * definition} must also be empty."
16638 * PASS
16639 */
16640 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16641 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16642 xmlSchemaIsParticleEmptiable(
16643 (xmlSchemaParticlePtr) base->subtypes)) {
16644 /*
16645 * SPEC (5.3.2.2) "The {content type} of the {base type
16646 * definition} must be elementOnly or mixed and have a particle
16647 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16648 * PASS
16649 */
16650 } else {
16651 xmlSchemaPCustomErr(ctxt,
16653 WXS_BASIC_CAST type, NULL,
16654 "The content type of the base type must be either "
16655 "empty or 'mixed' (or 'elements-only') and an emptiable "
16656 "particle", NULL);
16657 return (ctxt->err);
16658 }
16659 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16660 WXS_HAS_MIXED_CONTENT(type)) {
16661 /*
16662 * SPEC (5.4.1.1) "The {content type} of the complex type definition
16663 * itself must be element-only"
16664 */
16665 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16666 /*
16667 * SPEC (5.4.1.2) "The {content type} of the complex type
16668 * definition itself and of the {base type definition} must be
16669 * mixed"
16670 */
16671 xmlSchemaPCustomErr(ctxt,
16673 WXS_BASIC_CAST type, NULL,
16674 "If the content type is 'mixed', then the content type of the "
16675 "base type must also be 'mixed'", NULL);
16676 return (ctxt->err);
16677 }
16678 /*
16679 * SPEC (5.4.2) "The particle of the complex type definition itself
16680 * must be a `valid restriction` of the particle of the {content
16681 * type} of the {base type definition} as defined in Particle Valid
16682 * (Restriction) ($3.9.6).
16683 *
16684 * URGENT TODO: (5.4.2)
16685 */
16686 } else {
16687 xmlSchemaPCustomErr(ctxt,
16689 WXS_BASIC_CAST type, NULL,
16690 "The type is not a valid restriction of its base type", NULL);
16691 return (ctxt->err);
16692 }
16693 return (0);
16694}
16695
16706static int
16707xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16708 xmlSchemaTypePtr type)
16709{
16710 int ret;
16711 /*
16712 * Complex Type Definition Properties Correct
16713 */
16714 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16715 if (ret != 0)
16716 return (ret);
16717 if (WXS_IS_EXTENSION(type))
16718 ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16719 else
16720 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16721 return (ret);
16722}
16723
16736static int
16737xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16738 xmlSchemaTypePtr type)
16739{
16740 xmlSchemaTypePtr base;
16741 int ret = 0;
16742
16743 /*
16744 * TODO: Adjust the error codes here, as I used
16745 * XML_SCHEMAP_SRC_CT_1 only yet.
16746 */
16747 base = type->baseType;
16748 if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16749 /*
16750 * 1 If the <complexContent> alternative is chosen, the type definition
16751 * `resolved` to by the `actual value` of the base [attribute]
16752 * must be a complex type definition;
16753 */
16754 if (! WXS_IS_COMPLEX(base)) {
16755 xmlChar *str = NULL;
16756 xmlSchemaPCustomErr(ctxt,
16758 WXS_BASIC_CAST type, type->node,
16759 "If using <complexContent>, the base type is expected to be "
16760 "a complex type. The base type '%s' is a simple type",
16761 xmlSchemaFormatQName(&str, base->targetNamespace,
16762 base->name));
16763 FREE_AND_NULL(str)
16764 return (XML_SCHEMAP_SRC_CT_1);
16765 }
16766 } else {
16767 /*
16768 * SPEC
16769 * 2 If the <simpleContent> alternative is chosen, all of the
16770 * following must be true:
16771 * 2.1 The type definition `resolved` to by the `actual value` of the
16772 * base [attribute] must be one of the following:
16773 */
16774 if (WXS_IS_SIMPLE(base)) {
16775 if (WXS_IS_EXTENSION(type) == 0) {
16776 xmlChar *str = NULL;
16777 /*
16778 * 2.1.3 only if the <extension> alternative is also
16779 * chosen, a simple type definition.
16780 */
16781 /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16782 xmlSchemaPCustomErr(ctxt,
16784 WXS_BASIC_CAST type, NULL,
16785 "If using <simpleContent> and <restriction>, the base "
16786 "type must be a complex type. The base type '%s' is "
16787 "a simple type",
16788 xmlSchemaFormatQName(&str, base->targetNamespace,
16789 base->name));
16790 FREE_AND_NULL(str)
16791 return (XML_SCHEMAP_SRC_CT_1);
16792 }
16793 } else {
16794 /* Base type is a complex type. */
16795 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16796 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16797 /*
16798 * 2.1.1 a complex type definition whose {content type} is a
16799 * simple type definition;
16800 * PASS
16801 */
16802 if (base->contentTypeDef == NULL) {
16803 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16804 WXS_BASIC_CAST type, NULL,
16805 "Internal error: xmlSchemaCheckSRCCT, "
16806 "'%s', base type has no content type",
16807 type->name);
16808 return (-1);
16809 }
16810 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16811 (WXS_IS_RESTRICTION(type))) {
16812
16813 /*
16814 * 2.1.2 only if the <restriction> alternative is also
16815 * chosen, a complex type definition whose {content type}
16816 * is mixed and a particle emptiable.
16817 */
16818 if (! xmlSchemaIsParticleEmptiable(
16819 (xmlSchemaParticlePtr) base->subtypes)) {
16821 } else
16822 /*
16823 * Attention: at this point the <simpleType> child is in
16824 * ->contentTypeDef (put there during parsing).
16825 */
16826 if (type->contentTypeDef == NULL) {
16827 xmlChar *str = NULL;
16828 /*
16829 * 2.2 If clause 2.1.2 above is satisfied, then there
16830 * must be a <simpleType> among the [children] of
16831 * <restriction>.
16832 */
16833 /* TODO: Change error code to ..._SRC_CT_2_2. */
16834 xmlSchemaPCustomErr(ctxt,
16836 WXS_BASIC_CAST type, NULL,
16837 "A <simpleType> is expected among the children "
16838 "of <restriction>, if <simpleContent> is used and "
16839 "the base type '%s' is a complex type",
16840 xmlSchemaFormatQName(&str, base->targetNamespace,
16841 base->name));
16842 FREE_AND_NULL(str)
16843 return (XML_SCHEMAP_SRC_CT_1);
16844 }
16845 } else {
16847 }
16848 }
16849 if (ret > 0) {
16850 xmlChar *str = NULL;
16851 if (WXS_IS_RESTRICTION(type)) {
16852 xmlSchemaPCustomErr(ctxt,
16854 WXS_BASIC_CAST type, NULL,
16855 "If <simpleContent> and <restriction> is used, the "
16856 "base type must be a simple type or a complex type with "
16857 "mixed content and particle emptiable. The base type "
16858 "'%s' is none of those",
16859 xmlSchemaFormatQName(&str, base->targetNamespace,
16860 base->name));
16861 } else {
16862 xmlSchemaPCustomErr(ctxt,
16864 WXS_BASIC_CAST type, NULL,
16865 "If <simpleContent> and <extension> is used, the "
16866 "base type must be a simple type. The base type '%s' "
16867 "is a complex type",
16868 xmlSchemaFormatQName(&str, base->targetNamespace,
16869 base->name));
16870 }
16871 FREE_AND_NULL(str)
16872 }
16873 }
16874 /*
16875 * SPEC (3) "The corresponding complex type definition component must
16876 * satisfy the conditions set out in Constraints on Complex Type
16877 * Definition Schema Components ($3.4.6);"
16878 * NOTE (3) will be done in xmlSchemaTypeFixup().
16879 */
16880 /*
16881 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16882 * above for {attribute wildcard} is satisfied, the intensional
16883 * intersection must be expressible, as defined in Attribute Wildcard
16884 * Intersection ($3.10.6).
16885 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16886 */
16887 return (ret);
16888}
16889
16890#ifdef ENABLE_PARTICLE_RESTRICTION
16905static int
16906xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16907 int bmin, int bmax)
16908{
16909 if (rmin < bmin)
16910 return (1);
16911 if ((bmax != UNBOUNDED) &&
16912 (rmax > bmax))
16913 return (1);
16914 return (0);
16915}
16916
16935static int
16936xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16937 xmlSchemaParticlePtr r,
16938 xmlSchemaParticlePtr b)
16939{
16940 xmlSchemaElementPtr elemR, elemB;
16941
16942 /* TODO: Error codes (rcase-NameAndTypeOK). */
16943 elemR = (xmlSchemaElementPtr) r->children;
16944 elemB = (xmlSchemaElementPtr) b->children;
16945 /*
16946 * SPEC (1) "The declarations' {name}s and {target namespace}s are
16947 * the same."
16948 */
16949 if ((elemR != elemB) &&
16950 ((! xmlStrEqual(elemR->name, elemB->name)) ||
16951 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16952 return (1);
16953 /*
16954 * SPEC (2) "R's occurrence range is a valid restriction of B's
16955 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16956 */
16957 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16958 b->minOccurs, b->maxOccurs) != 0)
16959 return (1);
16960 /*
16961 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16962 * {scope} are global."
16963 */
16964 if (elemR == elemB)
16965 return (0);
16966 /*
16967 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16968 */
16969 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16970 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16971 return (1);
16972 /*
16973 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16974 * or is not fixed, or R's declaration's {value constraint} is fixed
16975 * with the same value."
16976 */
16977 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16978 ((elemR->value == NULL) ||
16979 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16980 /* TODO: Equality of the initial value or normalized or canonical? */
16981 (! xmlStrEqual(elemR->value, elemB->value))))
16982 return (1);
16983 /*
16984 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16985 * definitions} is a subset of B's declaration's {identity-constraint
16986 * definitions}, if any."
16987 */
16988 if (elemB->idcs != NULL) {
16989 /* TODO */
16990 }
16991 /*
16992 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16993 * superset of B's declaration's {disallowed substitutions}."
16994 */
16995 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16996 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16997 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16998 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16999 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
17000 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
17001 return (1);
17002 /*
17003 * SPEC (3.2.5) "R's {type definition} is validly derived given
17004 * {extension, list, union} from B's {type definition}"
17005 *
17006 * BADSPEC TODO: What's the point of adding "list" and "union" to the
17007 * set, if the corresponding constraints handle "restriction" and
17008 * "extension" only?
17009 *
17010 */
17011 {
17012 int set = 0;
17013
17014 set |= SUBSET_EXTENSION;
17015 set |= SUBSET_LIST;
17016 set |= SUBSET_UNION;
17017 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
17018 elemB->subtypes, set) != 0)
17019 return (1);
17020 }
17021 return (0);
17022}
17023
17040static int
17041xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
17042 xmlSchemaParticlePtr r,
17043 xmlSchemaParticlePtr b)
17044{
17045 /* TODO:Error codes (rcase-NSCompat). */
17046 /*
17047 * SPEC "For an element declaration particle to be a `valid restriction`
17048 * of a wildcard particle all of the following must be true:"
17049 *
17050 * SPEC (1) "The element declaration's {target namespace} is `valid`
17051 * with respect to the wildcard's {namespace constraint} as defined by
17052 * Wildcard allows Namespace Name ($3.10.4)."
17053 */
17054 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
17055 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
17056 return (1);
17057 /*
17058 * SPEC (2) "R's occurrence range is a valid restriction of B's
17059 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17060 */
17061 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17062 b->minOccurs, b->maxOccurs) != 0)
17063 return (1);
17064
17065 return (0);
17066}
17067
17084static int
17085xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
17086 xmlSchemaParticlePtr r,
17087 xmlSchemaParticlePtr b)
17088{
17089 /* TODO: Error codes (rcase-RecurseAsIfGroup). */
17090 TODO
17091 return (0);
17092}
17093
17110static int
17111xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
17112 xmlSchemaParticlePtr r,
17113 xmlSchemaParticlePtr b,
17114 int isAnyTypeBase)
17115{
17116 /* TODO: Error codes (rcase-NSSubset). */
17117 /*
17118 * SPEC (1) "R's occurrence range is a valid restriction of B's
17119 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17120 */
17121 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17122 b->minOccurs, b->maxOccurs))
17123 return (1);
17124 /*
17125 * SPEC (2) "R's {namespace constraint} must be an intensional subset
17126 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17127 */
17128 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
17129 (xmlSchemaWildcardPtr) b->children))
17130 return (1);
17131 /*
17132 * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17133 * definition`, R's {process contents} must be identical to or stronger
17134 * than B's {process contents}, where strict is stronger than lax is
17135 * stronger than skip."
17136 */
17137 if (! isAnyTypeBase) {
17138 if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17139 ((xmlSchemaWildcardPtr) b->children)->processContents)
17140 return (1);
17141 }
17142
17143 return (0);
17144}
17145
17160static int
17161xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17162 xmlSchemaParticlePtr r,
17163 xmlSchemaParticlePtr b)
17164{
17165 int ret = 0;
17166
17167 /*part = WXS_TYPE_PARTICLE(type);
17168 basePart = WXS_TYPE_PARTICLE(base);
17169 */
17170
17171 TODO
17172
17173 /*
17174 * SPEC (1) "They are the same particle."
17175 */
17176 if (r == b)
17177 return (0);
17178
17179
17180 return (0);
17181}
17182
17183#if 0
17201static int
17202xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17203 xmlSchemaParticlePtr r,
17204 xmlSchemaParticlePtr b)
17205{
17206 xmlSchemaParticlePtr part;
17207 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17208 if ((r->children == NULL) || (r->children->children == NULL))
17209 return (-1);
17210 /*
17211 * SPEC "For a group particle to be a `valid restriction` of a
17212 * wildcard particle..."
17213 *
17214 * SPEC (1) "Every member of the {particles} of the group is a `valid
17215 * restriction` of the wildcard as defined by
17216 * Particle Valid (Restriction) ($3.9.6)."
17217 */
17218 part = (xmlSchemaParticlePtr) r->children->children;
17219 do {
17220 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17221 return (1);
17222 part = (xmlSchemaParticlePtr) part->next;
17223 } while (part != NULL);
17224 /*
17225 * SPEC (2) "The effective total range of the group [...] is a
17226 * valid restriction of B's occurrence range as defined by
17227 * Occurrence Range OK ($3.9.6)."
17228 */
17229 if (xmlSchemaCheckParticleRangeOK(
17230 xmlSchemaGetParticleTotalRangeMin(r),
17231 xmlSchemaGetParticleTotalRangeMax(r),
17232 b->minOccurs, b->maxOccurs) != 0)
17233 return (1);
17234 return (0);
17235}
17236#endif
17237
17256static int
17257xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17258 xmlSchemaParticlePtr r,
17259 xmlSchemaParticlePtr b)
17260{
17261 /* xmlSchemaParticlePtr part; */
17262 /* TODO: Error codes (rcase-Recurse). */
17263 if ((r->children == NULL) || (b->children == NULL) ||
17264 (r->children->type != b->children->type))
17265 return (-1);
17266 /*
17267 * SPEC "For an all or sequence group particle to be a `valid
17268 * restriction` of another group particle with the same {compositor}..."
17269 *
17270 * SPEC (1) "R's occurrence range is a valid restriction of B's
17271 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17272 */
17273 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17274 b->minOccurs, b->maxOccurs))
17275 return (1);
17276
17277
17278 return (0);
17279}
17280
17281#endif
17282
17283#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17284 xmlSchemaPCustomErrExt(pctxt, \
17285 XML_SCHEMAP_INVALID_FACET_VALUE, \
17286 WXS_BASIC_CAST fac1, fac1->node, \
17287 "It is an error for both '%s' and '%s' to be specified on the "\
17288 "same type definition", \
17289 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17290 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17291
17292#define FACET_RESTR_ERR(fac1, msg) \
17293 xmlSchemaPCustomErr(pctxt, \
17294 XML_SCHEMAP_INVALID_FACET_VALUE, \
17295 WXS_BASIC_CAST fac1, fac1->node, \
17296 msg, NULL);
17297
17298#define FACET_RESTR_FIXED_ERR(fac) \
17299 xmlSchemaPCustomErr(pctxt, \
17300 XML_SCHEMAP_INVALID_FACET_VALUE, \
17301 WXS_BASIC_CAST fac, fac->node, \
17302 "The base type's facet is 'fixed', thus the value must not " \
17303 "differ", NULL);
17304
17305static void
17306xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17307 xmlSchemaFacetPtr facet1,
17308 xmlSchemaFacetPtr facet2,
17309 int lessGreater,
17310 int orEqual,
17311 int ofBase)
17312{
17313 xmlChar *msg = NULL;
17314
17315 msg = xmlStrdup(BAD_CAST "'");
17316 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17317 msg = xmlStrcat(msg, BAD_CAST "' has to be");
17318 if (lessGreater == 0)
17319 msg = xmlStrcat(msg, BAD_CAST " equal to");
17320 if (lessGreater == 1)
17321 msg = xmlStrcat(msg, BAD_CAST " greater than");
17322 else
17323 msg = xmlStrcat(msg, BAD_CAST " less than");
17324
17325 if (orEqual)
17326 msg = xmlStrcat(msg, BAD_CAST " or equal to");
17327 msg = xmlStrcat(msg, BAD_CAST " '");
17328 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17329 if (ofBase)
17330 msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17331 else
17332 msg = xmlStrcat(msg, BAD_CAST "'");
17333
17334 xmlSchemaPCustomErr(pctxt,
17336 WXS_BASIC_CAST facet1, NULL,
17337 (const char *) msg, NULL);
17338
17339 if (msg != NULL)
17340 xmlFree(msg);
17341}
17342
17343/*
17344* xmlSchemaDeriveAndValidateFacets:
17345*
17346* Schema Component Constraint: Simple Type Restriction (Facets)
17347* (st-restrict-facets)
17348*/
17349static int
17350xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17351 xmlSchemaTypePtr type)
17352{
17353 xmlSchemaTypePtr base = type->baseType;
17354 xmlSchemaFacetLinkPtr link, cur, last = NULL;
17355 xmlSchemaFacetPtr facet, bfacet,
17356 flength = NULL, ftotdig = NULL, ffracdig = NULL,
17357 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17358 fmininc = NULL, fmaxinc = NULL,
17359 fminexc = NULL, fmaxexc = NULL,
17360 bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17361 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17362 bfmininc = NULL, bfmaxinc = NULL,
17363 bfminexc = NULL, bfmaxexc = NULL;
17364 int res; /* err = 0, fixedErr; */
17365
17366 /*
17367 * SPEC st-restrict-facets 1:
17368 * "The {variety} of R is the same as that of B."
17369 */
17370 /*
17371 * SPEC st-restrict-facets 2:
17372 * "If {variety} is atomic, the {primitive type definition}
17373 * of R is the same as that of B."
17374 *
17375 * NOTE: we leave 1 & 2 out for now, since this will be
17376 * satisfied by the derivation process.
17377 * CONSTRUCTION TODO: Maybe needed if using a construction API.
17378 */
17379 /*
17380 * SPEC st-restrict-facets 3:
17381 * "The {facets} of R are the union of S and the {facets}
17382 * of B, eliminating duplicates. To eliminate duplicates,
17383 * when a facet of the same kind occurs in both S and the
17384 * {facets} of B, the one in the {facets} of B is not
17385 * included, with the exception of enumeration and pattern
17386 * facets, for which multiple occurrences with distinct values
17387 * are allowed."
17388 */
17389
17390 if ((type->facetSet == NULL) && (base->facetSet == NULL))
17391 return (0);
17392
17393 last = type->facetSet;
17394 if (last != NULL)
17395 while (last->next != NULL)
17396 last = last->next;
17397
17398 for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17399 facet = cur->facet;
17400 switch (facet->type) {
17401 case XML_SCHEMA_FACET_LENGTH:
17402 flength = facet; break;
17403 case XML_SCHEMA_FACET_MINLENGTH:
17404 fminlen = facet; break;
17405 case XML_SCHEMA_FACET_MININCLUSIVE:
17406 fmininc = facet; break;
17407 case XML_SCHEMA_FACET_MINEXCLUSIVE:
17408 fminexc = facet; break;
17409 case XML_SCHEMA_FACET_MAXLENGTH:
17410 fmaxlen = facet; break;
17411 case XML_SCHEMA_FACET_MAXINCLUSIVE:
17412 fmaxinc = facet; break;
17413 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17414 fmaxexc = facet; break;
17415 case XML_SCHEMA_FACET_TOTALDIGITS:
17416 ftotdig = facet; break;
17417 case XML_SCHEMA_FACET_FRACTIONDIGITS:
17418 ffracdig = facet; break;
17419 default:
17420 break;
17421 }
17422 }
17423 for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17424 facet = cur->facet;
17425 switch (facet->type) {
17426 case XML_SCHEMA_FACET_LENGTH:
17427 bflength = facet; break;
17428 case XML_SCHEMA_FACET_MINLENGTH:
17429 bfminlen = facet; break;
17430 case XML_SCHEMA_FACET_MININCLUSIVE:
17431 bfmininc = facet; break;
17432 case XML_SCHEMA_FACET_MINEXCLUSIVE:
17433 bfminexc = facet; break;
17434 case XML_SCHEMA_FACET_MAXLENGTH:
17435 bfmaxlen = facet; break;
17436 case XML_SCHEMA_FACET_MAXINCLUSIVE:
17437 bfmaxinc = facet; break;
17438 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17439 bfmaxexc = facet; break;
17440 case XML_SCHEMA_FACET_TOTALDIGITS:
17441 bftotdig = facet; break;
17442 case XML_SCHEMA_FACET_FRACTIONDIGITS:
17443 bffracdig = facet; break;
17444 default:
17445 break;
17446 }
17447 }
17448 /*
17449 * length and minLength or maxLength (2.2) + (3.2)
17450 */
17451 if (flength && (fminlen || fmaxlen)) {
17452 FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17453 "either of 'minLength' or 'maxLength' to be specified on "
17454 "the same type definition")
17455 }
17456 /*
17457 * Mutual exclusions in the same derivation step.
17458 */
17459 if ((fmaxinc) && (fmaxexc)) {
17460 /*
17461 * SCC "maxInclusive and maxExclusive"
17462 */
17463 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17464 }
17465 if ((fmininc) && (fminexc)) {
17466 /*
17467 * SCC "minInclusive and minExclusive"
17468 */
17469 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17470 }
17471
17472 if (flength && bflength) {
17473 /*
17474 * SCC "length valid restriction"
17475 * The values have to be equal.
17476 */
17477 res = xmlSchemaCompareValues(flength->val, bflength->val);
17478 if (res == -2)
17479 goto internal_error;
17480 if (res != 0)
17481 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17482 if ((res != 0) && (bflength->fixed)) {
17483 FACET_RESTR_FIXED_ERR(flength)
17484 }
17485
17486 }
17487 if (fminlen && bfminlen) {
17488 /*
17489 * SCC "minLength valid restriction"
17490 * minLength >= BASE minLength
17491 */
17492 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17493 if (res == -2)
17494 goto internal_error;
17495 if (res == -1)
17496 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17497 if ((res != 0) && (bfminlen->fixed)) {
17498 FACET_RESTR_FIXED_ERR(fminlen)
17499 }
17500 }
17501 if (fmaxlen && bfmaxlen) {
17502 /*
17503 * SCC "maxLength valid restriction"
17504 * maxLength <= BASE minLength
17505 */
17506 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17507 if (res == -2)
17508 goto internal_error;
17509 if (res == 1)
17510 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17511 if ((res != 0) && (bfmaxlen->fixed)) {
17512 FACET_RESTR_FIXED_ERR(fmaxlen)
17513 }
17514 }
17515 /*
17516 * SCC "length and minLength or maxLength"
17517 */
17518 if (! flength)
17519 flength = bflength;
17520 if (flength) {
17521 if (! fminlen)
17522 fminlen = bfminlen;
17523 if (fminlen) {
17524 /* (1.1) length >= minLength */
17525 res = xmlSchemaCompareValues(flength->val, fminlen->val);
17526 if (res == -2)
17527 goto internal_error;
17528 if (res == -1)
17529 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17530 }
17531 if (! fmaxlen)
17532 fmaxlen = bfmaxlen;
17533 if (fmaxlen) {
17534 /* (2.1) length <= maxLength */
17535 res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17536 if (res == -2)
17537 goto internal_error;
17538 if (res == 1)
17539 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17540 }
17541 }
17542 if (fmaxinc) {
17543 /*
17544 * "maxInclusive"
17545 */
17546 if (fmininc) {
17547 /* SCC "maxInclusive >= minInclusive" */
17548 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17549 if (res == -2)
17550 goto internal_error;
17551 if (res == -1) {
17552 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17553 }
17554 }
17555 /*
17556 * SCC "maxInclusive valid restriction"
17557 */
17558 if (bfmaxinc) {
17559 /* maxInclusive <= BASE maxInclusive */
17560 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17561 if (res == -2)
17562 goto internal_error;
17563 if (res == 1)
17564 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17565 if ((res != 0) && (bfmaxinc->fixed)) {
17566 FACET_RESTR_FIXED_ERR(fmaxinc)
17567 }
17568 }
17569 if (bfmaxexc) {
17570 /* maxInclusive < BASE maxExclusive */
17571 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17572 if (res == -2)
17573 goto internal_error;
17574 if (res != -1) {
17575 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17576 }
17577 }
17578 if (bfmininc) {
17579 /* maxInclusive >= BASE minInclusive */
17580 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17581 if (res == -2)
17582 goto internal_error;
17583 if (res == -1) {
17584 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17585 }
17586 }
17587 if (bfminexc) {
17588 /* maxInclusive > BASE minExclusive */
17589 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17590 if (res == -2)
17591 goto internal_error;
17592 if (res != 1) {
17593 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17594 }
17595 }
17596 }
17597 if (fmaxexc) {
17598 /*
17599 * "maxExclusive >= minExclusive"
17600 */
17601 if (fminexc) {
17602 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17603 if (res == -2)
17604 goto internal_error;
17605 if (res == -1) {
17606 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17607 }
17608 }
17609 /*
17610 * "maxExclusive valid restriction"
17611 */
17612 if (bfmaxexc) {
17613 /* maxExclusive <= BASE maxExclusive */
17614 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17615 if (res == -2)
17616 goto internal_error;
17617 if (res == 1) {
17618 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17619 }
17620 if ((res != 0) && (bfmaxexc->fixed)) {
17621 FACET_RESTR_FIXED_ERR(fmaxexc)
17622 }
17623 }
17624 if (bfmaxinc) {
17625 /* maxExclusive <= BASE maxInclusive */
17626 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17627 if (res == -2)
17628 goto internal_error;
17629 if (res == 1) {
17630 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17631 }
17632 }
17633 if (bfmininc) {
17634 /* maxExclusive > BASE minInclusive */
17635 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17636 if (res == -2)
17637 goto internal_error;
17638 if (res != 1) {
17639 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17640 }
17641 }
17642 if (bfminexc) {
17643 /* maxExclusive > BASE minExclusive */
17644 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17645 if (res == -2)
17646 goto internal_error;
17647 if (res != 1) {
17648 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17649 }
17650 }
17651 }
17652 if (fminexc) {
17653 /*
17654 * "minExclusive < maxInclusive"
17655 */
17656 if (fmaxinc) {
17657 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17658 if (res == -2)
17659 goto internal_error;
17660 if (res != -1) {
17661 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17662 }
17663 }
17664 /*
17665 * "minExclusive valid restriction"
17666 */
17667 if (bfminexc) {
17668 /* minExclusive >= BASE minExclusive */
17669 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17670 if (res == -2)
17671 goto internal_error;
17672 if (res == -1) {
17673 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17674 }
17675 if ((res != 0) && (bfminexc->fixed)) {
17676 FACET_RESTR_FIXED_ERR(fminexc)
17677 }
17678 }
17679 if (bfmaxinc) {
17680 /* minExclusive <= BASE maxInclusive */
17681 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17682 if (res == -2)
17683 goto internal_error;
17684 if (res == 1) {
17685 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17686 }
17687 }
17688 if (bfmininc) {
17689 /* minExclusive >= BASE minInclusive */
17690 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17691 if (res == -2)
17692 goto internal_error;
17693 if (res == -1) {
17694 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17695 }
17696 }
17697 if (bfmaxexc) {
17698 /* minExclusive < BASE maxExclusive */
17699 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17700 if (res == -2)
17701 goto internal_error;
17702 if (res != -1) {
17703 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17704 }
17705 }
17706 }
17707 if (fmininc) {
17708 /*
17709 * "minInclusive < maxExclusive"
17710 */
17711 if (fmaxexc) {
17712 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17713 if (res == -2)
17714 goto internal_error;
17715 if (res != -1) {
17716 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17717 }
17718 }
17719 /*
17720 * "minExclusive valid restriction"
17721 */
17722 if (bfmininc) {
17723 /* minInclusive >= BASE minInclusive */
17724 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17725 if (res == -2)
17726 goto internal_error;
17727 if (res == -1) {
17728 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17729 }
17730 if ((res != 0) && (bfmininc->fixed)) {
17731 FACET_RESTR_FIXED_ERR(fmininc)
17732 }
17733 }
17734 if (bfmaxinc) {
17735 /* minInclusive <= BASE maxInclusive */
17736 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17737 if (res == -2)
17738 goto internal_error;
17739 if (res == 1) {
17740 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17741 }
17742 }
17743 if (bfminexc) {
17744 /* minInclusive > BASE minExclusive */
17745 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17746 if (res == -2)
17747 goto internal_error;
17748 if (res != 1)
17749 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17750 }
17751 if (bfmaxexc) {
17752 /* minInclusive < BASE maxExclusive */
17753 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17754 if (res == -2)
17755 goto internal_error;
17756 if (res != -1)
17757 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17758 }
17759 }
17760 if (ftotdig && bftotdig) {
17761 /*
17762 * SCC " totalDigits valid restriction"
17763 * totalDigits <= BASE totalDigits
17764 */
17765 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17766 if (res == -2)
17767 goto internal_error;
17768 if (res == 1)
17769 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17770 -1, 1, 1);
17771 if ((res != 0) && (bftotdig->fixed)) {
17772 FACET_RESTR_FIXED_ERR(ftotdig)
17773 }
17774 }
17775 if (ffracdig && bffracdig) {
17776 /*
17777 * SCC "fractionDigits valid restriction"
17778 * fractionDigits <= BASE fractionDigits
17779 */
17780 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17781 if (res == -2)
17782 goto internal_error;
17783 if (res == 1)
17784 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17785 -1, 1, 1);
17786 if ((res != 0) && (bffracdig->fixed)) {
17787 FACET_RESTR_FIXED_ERR(ffracdig)
17788 }
17789 }
17790 /*
17791 * SCC "fractionDigits less than or equal to totalDigits"
17792 */
17793 if (! ftotdig)
17794 ftotdig = bftotdig;
17795 if (! ffracdig)
17796 ffracdig = bffracdig;
17797 if (ftotdig && ffracdig) {
17798 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17799 if (res == -2)
17800 goto internal_error;
17801 if (res == 1)
17802 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17803 -1, 1, 0);
17804 }
17805 /*
17806 * *Enumerations* won' be added here, since only the first set
17807 * of enumerations in the ancestor-or-self axis is used
17808 * for validation, plus we need to use the base type of those
17809 * enumerations for whitespace.
17810 *
17811 * *Patterns*: won't be add here, since they are ORed at
17812 * type level and ANDed at ancestor level. This will
17813 * happen during validation by walking the base axis
17814 * of the type.
17815 */
17816 for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17817 bfacet = cur->facet;
17818 /*
17819 * Special handling of enumerations and patterns.
17820 * TODO: hmm, they should not appear in the set, so remove this.
17821 */
17822 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17823 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17824 continue;
17825 /*
17826 * Search for a duplicate facet in the current type.
17827 */
17828 link = type->facetSet;
17829 /* err = 0; */
17830 /* fixedErr = 0; */
17831 while (link != NULL) {
17832 facet = link->facet;
17833 if (facet->type == bfacet->type) {
17834 switch (facet->type) {
17835 case XML_SCHEMA_FACET_WHITESPACE:
17836 /*
17837 * The whitespace must be stronger.
17838 */
17839 if (facet->whitespace < bfacet->whitespace) {
17840 FACET_RESTR_ERR(facet,
17841 "The 'whitespace' value has to be equal to "
17842 "or stronger than the 'whitespace' value of "
17843 "the base type")
17844 }
17845 if ((bfacet->fixed) &&
17846 (facet->whitespace != bfacet->whitespace)) {
17847 FACET_RESTR_FIXED_ERR(facet)
17848 }
17849 break;
17850 default:
17851 break;
17852 }
17853 /* Duplicate found. */
17854 break;
17855 }
17856 link = link->next;
17857 }
17858 /*
17859 * If no duplicate was found: add the base types's facet
17860 * to the set.
17861 */
17862 if (link == NULL) {
17863 link = (xmlSchemaFacetLinkPtr)
17864 xmlMalloc(sizeof(xmlSchemaFacetLink));
17865 if (link == NULL) {
17866 xmlSchemaPErrMemory(pctxt,
17867 "deriving facets, creating a facet link", NULL);
17868 return (-1);
17869 }
17870 link->facet = cur->facet;
17871 link->next = NULL;
17872 if (last == NULL)
17873 type->facetSet = link;
17874 else
17875 last->next = link;
17876 last = link;
17877 }
17878
17879 }
17880
17881 return (0);
17882internal_error:
17883 PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17884 "an error occurred");
17885 return (-1);
17886}
17887
17888static int
17889xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17890 xmlSchemaTypePtr type)
17891{
17892 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17893 /*
17894 * The actual value is then formed by replacing any union type
17895 * definition in the `explicit members` with the members of their
17896 * {member type definitions}, in order.
17897 *
17898 * TODO: There's a bug entry at
17899 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17900 * which indicates that we'll keep the union types the future.
17901 */
17902 link = type->memberTypes;
17903 while (link != NULL) {
17904
17905 if (WXS_IS_TYPE_NOT_FIXED(link->type))
17906 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17907
17908 if (WXS_IS_UNION(link->type)) {
17909 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17910 if (subLink != NULL) {
17911 link->type = subLink->type;
17912 if (subLink->next != NULL) {
17913 lastLink = link->next;
17914 subLink = subLink->next;
17915 prevLink = link;
17916 while (subLink != NULL) {
17917 newLink = (xmlSchemaTypeLinkPtr)
17918 xmlMalloc(sizeof(xmlSchemaTypeLink));
17919 if (newLink == NULL) {
17920 xmlSchemaPErrMemory(pctxt, "allocating a type link",
17921 NULL);
17922 return (-1);
17923 }
17924 newLink->type = subLink->type;
17925 prevLink->next = newLink;
17926 prevLink = newLink;
17927 newLink->next = lastLink;
17928
17929 subLink = subLink->next;
17930 }
17931 }
17932 }
17933 }
17934 link = link->next;
17935 }
17936 return (0);
17937}
17938
17939static void
17940xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17941{
17942 int has = 0, needVal = 0, normVal = 0;
17943
17944 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17945 if (has) {
17946 needVal = (type->baseType->flags &
17947 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17948 normVal = (type->baseType->flags &
17949 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17950 }
17951 if (type->facets != NULL) {
17952 xmlSchemaFacetPtr fac;
17953
17954 for (fac = type->facets; fac != NULL; fac = fac->next) {
17955 switch (fac->type) {
17956 case XML_SCHEMA_FACET_WHITESPACE:
17957 break;
17958 case XML_SCHEMA_FACET_PATTERN:
17959 normVal = 1;
17960 has = 1;
17961 break;
17962 case XML_SCHEMA_FACET_ENUMERATION:
17963 needVal = 1;
17964 normVal = 1;
17965 has = 1;
17966 break;
17967 default:
17968 has = 1;
17969 break;
17970 }
17971 }
17972 }
17973 if (normVal)
17974 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17975 if (needVal)
17976 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17977 if (has)
17978 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17979
17980 if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17981 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17982 /*
17983 * OPTIMIZE VAL TODO: Some facets need a computed value.
17984 */
17985 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17986 (prim->builtInType != XML_SCHEMAS_STRING)) {
17987 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17988 }
17989 }
17990}
17991
17992static int
17993xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17994{
17995
17996
17997 /*
17998 * Evaluate the whitespace-facet value.
17999 */
18000 if (WXS_IS_LIST(type)) {
18001 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18002 return (0);
18003 } else if (WXS_IS_UNION(type))
18004 return (0);
18005
18006 if (type->facetSet != NULL) {
18007 xmlSchemaFacetLinkPtr lin;
18008
18009 for (lin = type->facetSet; lin != NULL; lin = lin->next) {
18010 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
18011 switch (lin->facet->whitespace) {
18012 case XML_SCHEMAS_FACET_PRESERVE:
18013 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
18014 break;
18015 case XML_SCHEMAS_FACET_REPLACE:
18016 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
18017 break;
18018 case XML_SCHEMAS_FACET_COLLAPSE:
18019 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18020 break;
18021 default:
18022 return (-1);
18023 }
18024 return (0);
18025 }
18026 }
18027 }
18028 /*
18029 * For all `atomic` datatypes other than string (and types `derived`
18030 * by `restriction` from it) the value of whiteSpace is fixed to
18031 * collapse
18032 */
18033 {
18034 xmlSchemaTypePtr anc;
18035
18036 for (anc = type->baseType; anc != NULL &&
18037 anc->builtInType != XML_SCHEMAS_ANYTYPE;
18038 anc = anc->baseType) {
18039
18040 if (anc->type == XML_SCHEMA_TYPE_BASIC) {
18041 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
18042 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
18043
18044 } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
18045 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
18046 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
18047
18048 } else
18049 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18050 break;
18051 }
18052 }
18053 }
18054 return (0);
18055}
18056
18057static int
18058xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
18059 xmlSchemaTypePtr type)
18060{
18061 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18062 return(0);
18063 if (! WXS_IS_TYPE_NOT_FIXED_1(type))
18064 return(0);
18065 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
18066
18067 if (WXS_IS_LIST(type)) {
18068 /*
18069 * Corresponds to <simpleType><list>...
18070 */
18071 if (type->subtypes == NULL) {
18072 /*
18073 * This one is really needed, so get out.
18074 */
18075 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18076 "list type has no item-type assigned");
18077 return(-1);
18078 }
18079 } else if (WXS_IS_UNION(type)) {
18080 /*
18081 * Corresponds to <simpleType><union>...
18082 */
18083 if (type->memberTypes == NULL) {
18084 /*
18085 * This one is really needed, so get out.
18086 */
18087 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18088 "union type has no member-types assigned");
18089 return(-1);
18090 }
18091 } else {
18092 /*
18093 * Corresponds to <simpleType><restriction>...
18094 */
18095 if (type->baseType == NULL) {
18096 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18097 "type has no base-type assigned");
18098 return(-1);
18099 }
18100 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
18101 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
18102 return(-1);
18103 /*
18104 * Variety
18105 * If the <restriction> alternative is chosen, then the
18106 * {variety} of the {base type definition}.
18107 */
18108 if (WXS_IS_ATOMIC(type->baseType))
18109 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
18110 else if (WXS_IS_LIST(type->baseType)) {
18111 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
18112 /*
18113 * Inherit the itemType.
18114 */
18115 type->subtypes = type->baseType->subtypes;
18116 } else if (WXS_IS_UNION(type->baseType)) {
18117 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
18118 /*
18119 * NOTE that we won't assign the memberTypes of the base,
18120 * since this will make trouble when freeing them; we will
18121 * use a lookup function to access them instead.
18122 */
18123 }
18124 }
18125 return(0);
18126}
18127
18128#ifdef DEBUG_TYPE
18129static void
18130xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
18131 xmlSchemaTypePtr type)
18132{
18133 if (type->node != NULL) {
18135 "Type of %s : %s:%d :", name,
18136 type->node->doc->URL,
18137 xmlGetLineNo(type->node));
18138 } else {
18140 }
18141 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
18142 switch (type->contentType) {
18143 case XML_SCHEMA_CONTENT_SIMPLE:
18145 break;
18146 case XML_SCHEMA_CONTENT_ELEMENTS:
18148 break;
18149 case XML_SCHEMA_CONTENT_UNKNOWN:
18150 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
18151 break;
18152 case XML_SCHEMA_CONTENT_EMPTY:
18154 break;
18155 case XML_SCHEMA_CONTENT_MIXED:
18156 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
18157 type->subtypes))
18159 "mixed as emptiable particle\n");
18160 else
18162 break;
18163 /* Removed, since not used. */
18164 /*
18165 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18166 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18167 break;
18168 */
18169 case XML_SCHEMA_CONTENT_BASIC:
18171 break;
18172 default:
18174 "not registered !!!\n");
18175 break;
18176 }
18177 }
18178}
18179#endif
18180
18181/*
18182* 3.14.6 Constraints on Simple Type Definition Schema Components
18183*/
18184static int
18185xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18186 xmlSchemaTypePtr type)
18187{
18188 int res, olderrs = pctxt->nberrors;
18189
18190 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18191 return(-1);
18192
18193 if (! WXS_IS_TYPE_NOT_FIXED(type))
18194 return(0);
18195
18196 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18197 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18198
18199 if (type->baseType == NULL) {
18200 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18201 "missing baseType");
18202 goto exit_failure;
18203 }
18204 if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18205 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18206 /*
18207 * If a member type of a union is a union itself, we need to substitute
18208 * that member type for its member types.
18209 * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18210 * types in WXS 1.1.
18211 */
18212 if ((type->memberTypes != NULL) &&
18213 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18214 return(-1);
18215 /*
18216 * SPEC src-simple-type 1
18217 * "The corresponding simple type definition, if any, must satisfy
18218 * the conditions set out in Constraints on Simple Type Definition
18219 * Schema Components ($3.14.6)."
18220 */
18221 /*
18222 * Schema Component Constraint: Simple Type Definition Properties Correct
18223 * (st-props-correct)
18224 */
18225 res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18226 HFAILURE HERROR
18227 /*
18228 * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18229 * (cos-st-restricts)
18230 */
18231 res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18232 HFAILURE HERROR
18233 /*
18234 * TODO: Removed the error report, since it got annoying to get an
18235 * extra error report, if anything failed until now.
18236 * Enable this if needed.
18237 *
18238 * xmlSchemaPErr(ctxt, type->node,
18239 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18240 * "Simple type '%s' does not satisfy the constraints "
18241 * "on simple type definitions.\n",
18242 * type->name, NULL);
18243 */
18244 /*
18245 * Schema Component Constraint: Simple Type Restriction (Facets)
18246 * (st-restrict-facets)
18247 */
18248 res = xmlSchemaCheckFacetValues(type, pctxt);
18249 HFAILURE HERROR
18250 if ((type->facetSet != NULL) ||
18251 (type->baseType->facetSet != NULL)) {
18252 res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18253 HFAILURE HERROR
18254 }
18255 /*
18256 * Whitespace value.
18257 */
18258 res = xmlSchemaTypeFixupWhitespace(type);
18259 HFAILURE HERROR
18260 xmlSchemaTypeFixupOptimFacets(type);
18261
18262exit_error:
18263#ifdef DEBUG_TYPE
18264 xmlSchemaDebugFixedType(pctxt, type);
18265#endif
18266 if (olderrs != pctxt->nberrors)
18267 return(pctxt->err);
18268 return(0);
18269
18270exit_failure:
18271#ifdef DEBUG_TYPE
18272 xmlSchemaDebugFixedType(pctxt, type);
18273#endif
18274 return(-1);
18275}
18276
18277static int
18278xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18279 xmlSchemaTypePtr type)
18280{
18281 int res = 0, olderrs = pctxt->nberrors;
18282 xmlSchemaTypePtr baseType = type->baseType;
18283
18284 if (! WXS_IS_TYPE_NOT_FIXED(type))
18285 return(0);
18286 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18287 if (baseType == NULL) {
18288 PERROR_INT("xmlSchemaFixupComplexType",
18289 "missing baseType");
18290 goto exit_failure;
18291 }
18292 /*
18293 * Fixup the base type.
18294 */
18295 if (WXS_IS_TYPE_NOT_FIXED(baseType))
18296 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18297 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18298 /*
18299 * Skip fixup if the base type is invalid.
18300 * TODO: Generate a warning!
18301 */
18302 return(0);
18303 }
18304 /*
18305 * This basically checks if the base type can be derived.
18306 */
18307 res = xmlSchemaCheckSRCCT(pctxt, type);
18308 HFAILURE HERROR
18309 /*
18310 * Fixup the content type.
18311 */
18312 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18313 /*
18314 * Corresponds to <complexType><simpleContent>...
18315 */
18316 if ((WXS_IS_COMPLEX(baseType)) &&
18317 (baseType->contentTypeDef != NULL) &&
18318 (WXS_IS_RESTRICTION(type))) {
18319 xmlSchemaTypePtr contentBase, content;
18320#ifdef ENABLE_NAMED_LOCALS
18321 char buf[30];
18322 const xmlChar *tmpname;
18323#endif
18324 /*
18325 * SPEC (1) If <restriction> + base type is <complexType>,
18326 * "whose own {content type} is a simple type..."
18327 */
18328 if (type->contentTypeDef != NULL) {
18329 /*
18330 * SPEC (1.1) "the simple type definition corresponding to the
18331 * <simpleType> among the [children] of <restriction> if there
18332 * is one;"
18333 * Note that this "<simpleType> among the [children]" was put
18334 * into ->contentTypeDef during parsing.
18335 */
18336 contentBase = type->contentTypeDef;
18337 type->contentTypeDef = NULL;
18338 } else {
18339 /*
18340 * (1.2) "...otherwise (<restriction> has no <simpleType>
18341 * among its [children]), the simple type definition which
18342 * is the {content type} of the ... base type."
18343 */
18344 contentBase = baseType->contentTypeDef;
18345 }
18346 /*
18347 * SPEC
18348 * "... a simple type definition which restricts the simple
18349 * type definition identified in clause 1.1 or clause 1.2
18350 * with a set of facet components"
18351 *
18352 * Create the anonymous simple type, which will be the content
18353 * type of the complex type.
18354 */
18355#ifdef ENABLE_NAMED_LOCALS
18356 snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18357 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18358 content = xmlSchemaAddType(pctxt, pctxt->schema,
18359 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18360 type->node, 0);
18361#else
18362 content = xmlSchemaAddType(pctxt, pctxt->schema,
18363 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18364 type->node, 0);
18365#endif
18366 if (content == NULL)
18367 goto exit_failure;
18368 /*
18369 * We will use the same node as for the <complexType>
18370 * to have it somehow anchored in the schema doc.
18371 */
18372 content->type = XML_SCHEMA_TYPE_SIMPLE;
18373 content->baseType = contentBase;
18374 /*
18375 * Move the facets, previously anchored on the
18376 * complexType during parsing.
18377 */
18378 content->facets = type->facets;
18379 type->facets = NULL;
18380 content->facetSet = type->facetSet;
18381 type->facetSet = NULL;
18382
18383 type->contentTypeDef = content;
18384 if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18385 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18386 /*
18387 * Fixup the newly created type. We don't need to check
18388 * for circularity here.
18389 */
18390 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18391 HFAILURE HERROR
18392 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18393 HFAILURE HERROR
18394
18395 } else if ((WXS_IS_COMPLEX(baseType)) &&
18396 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18397 (WXS_IS_RESTRICTION(type))) {
18398 /*
18399 * SPEC (2) If <restriction> + base is a mixed <complexType> with
18400 * an emptiable particle, then a simple type definition which
18401 * restricts the <restriction>'s <simpleType> child.
18402 */
18403 if ((type->contentTypeDef == NULL) ||
18404 (type->contentTypeDef->baseType == NULL)) {
18405 /*
18406 * TODO: Check if this ever happens.
18407 */
18408 xmlSchemaPCustomErr(pctxt,
18410 WXS_BASIC_CAST type, NULL,
18411 "Internal error: xmlSchemaTypeFixup, "
18412 "complex type '%s': the <simpleContent><restriction> "
18413 "is missing a <simpleType> child, but was not caught "
18414 "by xmlSchemaCheckSRCCT()", type->name);
18415 goto exit_failure;
18416 }
18417 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18418 /*
18419 * SPEC (3) If <extension> + base is <complexType> with
18420 * <simpleType> content, "...then the {content type} of that
18421 * complex type definition"
18422 */
18423 if (baseType->contentTypeDef == NULL) {
18424 /*
18425 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18426 * should have caught this already.
18427 */
18428 xmlSchemaPCustomErr(pctxt,
18430 WXS_BASIC_CAST type, NULL,
18431 "Internal error: xmlSchemaTypeFixup, "
18432 "complex type '%s': the <extension>ed base type is "
18433 "a complex type with no simple content type",
18434 type->name);
18435 goto exit_failure;
18436 }
18437 type->contentTypeDef = baseType->contentTypeDef;
18438 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18439 /*
18440 * SPEC (4) <extension> + base is <simpleType>
18441 * "... then that simple type definition"
18442 */
18443 type->contentTypeDef = baseType;
18444 } else {
18445 /*
18446 * TODO: Check if this ever happens.
18447 */
18448 xmlSchemaPCustomErr(pctxt,
18450 WXS_BASIC_CAST type, NULL,
18451 "Internal error: xmlSchemaTypeFixup, "
18452 "complex type '%s' with <simpleContent>: unhandled "
18453 "derivation case", type->name);
18454 goto exit_failure;
18455 }
18456 } else {
18457 int dummySequence = 0;
18458 xmlSchemaParticlePtr particle =
18459 (xmlSchemaParticlePtr) type->subtypes;
18460 /*
18461 * Corresponds to <complexType><complexContent>...
18462 *
18463 * NOTE that the effective mixed was already set during parsing of
18464 * <complexType> and <complexContent>; its flag value is
18465 * XML_SCHEMAS_TYPE_MIXED.
18466 *
18467 * Compute the "effective content":
18468 * (2.1.1) + (2.1.2) + (2.1.3)
18469 */
18470 if ((particle == NULL) ||
18471 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18472 ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18473 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18474 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18475 (particle->minOccurs == 0))) &&
18476 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18477 if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18478 /*
18479 * SPEC (2.1.4) "If the `effective mixed` is true, then
18480 * a particle whose properties are as follows:..."
18481 *
18482 * Empty sequence model group with
18483 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18484 * NOTE that we sill assign it the <complexType> node to
18485 * somehow anchor it in the doc.
18486 */
18487 if ((particle == NULL) ||
18488 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18489 /*
18490 * Create the particle.
18491 */
18492 particle = xmlSchemaAddParticle(pctxt,
18493 type->node, 1, 1);
18494 if (particle == NULL)
18495 goto exit_failure;
18496 /*
18497 * Create the model group.
18498 */ /* URGENT TODO: avoid adding to pending items. */
18499 particle->children = (xmlSchemaTreeItemPtr)
18500 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18501 XML_SCHEMA_TYPE_SEQUENCE, type->node);
18502 if (particle->children == NULL)
18503 goto exit_failure;
18504
18505 type->subtypes = (xmlSchemaTypePtr) particle;
18506 }
18507 dummySequence = 1;
18508 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18509 } else {
18510 /*
18511 * SPEC (2.1.5) "otherwise empty"
18512 */
18513 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18514 }
18515 } else {
18516 /*
18517 * SPEC (2.2) "otherwise the particle corresponding to the
18518 * <all>, <choice>, <group> or <sequence> among the
18519 * [children]."
18520 */
18521 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18522 }
18523 /*
18524 * Compute the "content type".
18525 */
18526 if (WXS_IS_RESTRICTION(type)) {
18527 /*
18528 * SPEC (3.1) "If <restriction>..."
18529 * (3.1.1) + (3.1.2) */
18530 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18531 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18532 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18533 }
18534 } else {
18535 /*
18536 * SPEC (3.2) "If <extension>..."
18537 */
18538 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18539 /*
18540 * SPEC (3.2.1)
18541 * "If the `effective content` is empty, then the
18542 * {content type} of the [...] base ..."
18543 */
18544 type->contentType = baseType->contentType;
18545 type->subtypes = baseType->subtypes;
18546 /*
18547 * Fixes bug #347316:
18548 * This is the case when the base type has a simple
18549 * type definition as content.
18550 */
18551 type->contentTypeDef = baseType->contentTypeDef;
18552 /*
18553 * NOTE that the effective mixed is ignored here.
18554 */
18555 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18556 /*
18557 * SPEC (3.2.2)
18558 */
18559 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18560 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18561 } else {
18562 /*
18563 * SPEC (3.2.3)
18564 */
18565 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18566 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18567 /*
18568 * "A model group whose {compositor} is sequence and whose
18569 * {particles} are..."
18570 */
18571 if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18572 (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18573 ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18574 XML_SCHEMA_TYPE_ALL))
18575 {
18576 /*
18577 * SPEC cos-all-limited (1)
18578 */
18579 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18580 /* TODO: error code */
18582 WXS_ITEM_NODE(type), NULL,
18583 "The type has an 'all' model group in its "
18584 "{content type} and thus cannot be derived from "
18585 "a non-empty type, since this would produce a "
18586 "'sequence' model group containing the 'all' "
18587 "model group; 'all' model groups are not "
18588 "allowed to appear inside other model groups",
18589 NULL, NULL);
18590
18591 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18592 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18593 ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18594 XML_SCHEMA_TYPE_ALL))
18595 {
18596 /*
18597 * SPEC cos-all-limited (1)
18598 */
18599 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18600 /* TODO: error code */
18602 WXS_ITEM_NODE(type), NULL,
18603 "A type cannot be derived by extension from a type "
18604 "which has an 'all' model group in its "
18605 "{content type}, since this would produce a "
18606 "'sequence' model group containing the 'all' "
18607 "model group; 'all' model groups are not "
18608 "allowed to appear inside other model groups",
18609 NULL, NULL);
18610
18611 } else if (! dummySequence) {
18612 xmlSchemaTreeItemPtr effectiveContent =
18613 (xmlSchemaTreeItemPtr) type->subtypes;
18614 /*
18615 * Create the particle.
18616 */
18617 particle = xmlSchemaAddParticle(pctxt,
18618 type->node, 1, 1);
18619 if (particle == NULL)
18620 goto exit_failure;
18621 /*
18622 * Create the "sequence" model group.
18623 */
18624 particle->children = (xmlSchemaTreeItemPtr)
18625 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18626 XML_SCHEMA_TYPE_SEQUENCE, type->node);
18627 if (particle->children == NULL)
18628 goto exit_failure;
18629 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18630 /*
18631 * SPEC "the particle of the {content type} of
18632 * the ... base ..."
18633 * Create a duplicate of the base type's particle
18634 * and assign its "term" to it.
18635 */
18636 particle->children->children =
18637 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18638 type->node,
18639 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18640 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18641 if (particle->children->children == NULL)
18642 goto exit_failure;
18643 particle = (xmlSchemaParticlePtr)
18644 particle->children->children;
18645 particle->children =
18646 ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18647 /*
18648 * SPEC "followed by the `effective content`."
18649 */
18650 particle->next = effectiveContent;
18651 /*
18652 * This all will result in:
18653 * new-particle
18654 * --> new-sequence(
18655 * new-particle
18656 * --> base-model,
18657 * this-particle
18658 * --> this-model
18659 * )
18660 */
18661 } else {
18662 /*
18663 * This is the case when there is already an empty
18664 * <sequence> with minOccurs==maxOccurs==1.
18665 * Just add the base types's content type.
18666 * NOTE that, although we miss to add an intermediate
18667 * <sequence>, this should produce no difference to
18668 * neither the regex compilation of the content model,
18669 * nor to the complex type constraints.
18670 */
18671 particle->children->children =
18672 (xmlSchemaTreeItemPtr) baseType->subtypes;
18673 }
18674 }
18675 }
18676 }
18677 /*
18678 * Now fixup attribute uses:
18679 * - expand attr. group references
18680 * - intersect attribute wildcards
18681 * - inherit attribute uses of the base type
18682 * - inherit or union attr. wildcards if extending
18683 * - apply attr. use prohibitions if restricting
18684 */
18685 res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18686 HFAILURE HERROR
18687 /*
18688 * Apply the complex type component constraints; this will not
18689 * check attributes, since this is done in
18690 * xmlSchemaFixupTypeAttributeUses().
18691 */
18692 res = xmlSchemaCheckCTComponent(pctxt, type);
18693 HFAILURE HERROR
18694
18695#ifdef DEBUG_TYPE
18696 xmlSchemaDebugFixedType(pctxt, type);
18697#endif
18698 if (olderrs != pctxt->nberrors)
18699 return(pctxt->err);
18700 else
18701 return(0);
18702
18703exit_error:
18704 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18705#ifdef DEBUG_TYPE
18706 xmlSchemaDebugFixedType(pctxt, type);
18707#endif
18708 return(pctxt->err);
18709
18710exit_failure:
18711 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18712#ifdef DEBUG_TYPE
18713 xmlSchemaDebugFixedType(pctxt, type);
18714#endif
18715 return(-1);
18716}
18717
18718
18727static int
18728xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18729 xmlSchemaAbstractCtxtPtr actxt)
18730{
18731 if (type == NULL)
18732 return(0);
18733 if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18734 AERROR_INT("xmlSchemaTypeFixup",
18735 "this function needs a parser context");
18736 return(-1);
18737 }
18738 if (! WXS_IS_TYPE_NOT_FIXED(type))
18739 return(0);
18740 if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18741 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18742 else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18743 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18744 return(0);
18745}
18746
18759int
18760xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18761 xmlSchemaTypePtr typeDecl,
18762 xmlSchemaParserCtxtPtr pctxt,
18764{
18765 int ret = 0, ctxtGiven;
18766
18767 if ((facet == NULL) || (typeDecl == NULL))
18768 return(-1);
18769 /*
18770 * TODO: will the parser context be given if used from
18771 * the relaxNG module?
18772 */
18773 if (pctxt == NULL)
18774 ctxtGiven = 0;
18775 else
18776 ctxtGiven = 1;
18777
18778 switch (facet->type) {
18779 case XML_SCHEMA_FACET_MININCLUSIVE:
18780 case XML_SCHEMA_FACET_MINEXCLUSIVE:
18781 case XML_SCHEMA_FACET_MAXINCLUSIVE:
18782 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18783 case XML_SCHEMA_FACET_ENUMERATION: {
18784 /*
18785 * Okay we need to validate the value
18786 * at that point.
18787 */
18788 xmlSchemaTypePtr base;
18789
18790 /* 4.3.5.5 Constraints on enumeration Schema Components
18791 * Schema Component Constraint: enumeration valid restriction
18792 * It is an `error` if any member of {value} is not in the
18793 * `value space` of {base type definition}.
18794 *
18795 * minInclusive, maxInclusive, minExclusive, maxExclusive:
18796 * The value `must` be in the
18797 * `value space` of the `base type`.
18798 */
18799 /*
18800 * This function is intended to deliver a compiled value
18801 * on the facet. In this implementation of XML Schemata the
18802 * type holding a facet, won't be a built-in type.
18803 * Thus to ensure that other API
18804 * calls (relaxng) do work, if the given type is a built-in
18805 * type, we will assume that the given built-in type *is
18806 * already* the base type.
18807 */
18808 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18809 base = typeDecl->baseType;
18810 if (base == NULL) {
18811 PERROR_INT("xmlSchemaCheckFacet",
18812 "a type user derived type has no base type");
18813 return (-1);
18814 }
18815 } else
18816 base = typeDecl;
18817
18818 if (! ctxtGiven) {
18819 /*
18820 * A context is needed if called from RelaxNG.
18821 */
18822 pctxt = xmlSchemaNewParserCtxt("*");
18823 if (pctxt == NULL)
18824 return (-1);
18825 }
18826 /*
18827 * NOTE: This call does not check the content nodes,
18828 * since they are not available:
18829 * facet->node is just the node holding the facet
18830 * definition, *not* the attribute holding the *value*
18831 * of the facet.
18832 */
18833 ret = xmlSchemaVCheckCVCSimpleType(
18834 ACTXT_CAST pctxt, facet->node, base,
18835 facet->value, &(facet->val), 1, 1, 0);
18836 if (ret != 0) {
18837 if (ret < 0) {
18838 /* No error message for RelaxNG. */
18839 if (ctxtGiven) {
18840 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18841 XML_SCHEMAP_INTERNAL, facet->node, NULL,
18842 "Internal error: xmlSchemaCheckFacet, "
18843 "failed to validate the value '%s' of the "
18844 "facet '%s' against the base type",
18845 facet->value, xmlSchemaFacetTypeToString(facet->type));
18846 }
18847 goto internal_error;
18848 }
18850 /* No error message for RelaxNG. */
18851 if (ctxtGiven) {
18852 xmlChar *str = NULL;
18853
18854 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18855 ret, facet->node, WXS_BASIC_CAST facet,
18856 "The value '%s' of the facet does not validate "
18857 "against the base type '%s'",
18858 facet->value,
18859 xmlSchemaFormatQName(&str,
18860 base->targetNamespace, base->name));
18861 FREE_AND_NULL(str);
18862 }
18863 goto exit;
18864 } else if (facet->val == NULL) {
18865 if (ctxtGiven) {
18866 PERROR_INT("xmlSchemaCheckFacet",
18867 "value was not computed");
18868 }
18869 TODO
18870 }
18871 break;
18872 }
18873 case XML_SCHEMA_FACET_PATTERN:
18874 facet->regexp = xmlRegexpCompile(facet->value);
18875 if (facet->regexp == NULL) {
18877 /* No error message for RelaxNG. */
18878 if (ctxtGiven) {
18879 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18880 ret, facet->node, WXS_BASIC_CAST typeDecl,
18881 "The value '%s' of the facet 'pattern' is not a "
18882 "valid regular expression",
18883 facet->value, NULL);
18884 }
18885 }
18886 break;
18887 case XML_SCHEMA_FACET_TOTALDIGITS:
18888 case XML_SCHEMA_FACET_FRACTIONDIGITS:
18889 case XML_SCHEMA_FACET_LENGTH:
18890 case XML_SCHEMA_FACET_MAXLENGTH:
18891 case XML_SCHEMA_FACET_MINLENGTH:
18892
18893 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18894 ret = xmlSchemaValidatePredefinedType(
18895 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18896 facet->value, &(facet->val));
18897 } else {
18898 ret = xmlSchemaValidatePredefinedType(
18899 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18900 facet->value, &(facet->val));
18901 }
18902 if (ret != 0) {
18903 if (ret < 0) {
18904 /* No error message for RelaxNG. */
18905 if (ctxtGiven) {
18906 PERROR_INT("xmlSchemaCheckFacet",
18907 "validating facet value");
18908 }
18909 goto internal_error;
18910 }
18912 /* No error message for RelaxNG. */
18913 if (ctxtGiven) {
18914 /* error code */
18915 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18916 ret, facet->node, WXS_BASIC_CAST typeDecl,
18917 "The value '%s' of the facet '%s' is not a valid '%s'",
18918 facet->value,
18919 xmlSchemaFacetTypeToString(facet->type),
18920 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18921 BAD_CAST "nonNegativeInteger" :
18922 BAD_CAST "positiveInteger",
18923 NULL);
18924 }
18925 }
18926 break;
18927
18928 case XML_SCHEMA_FACET_WHITESPACE:{
18929 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18930 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18931 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18932 facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18933 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18934 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18935 } else {
18937 /* No error message for RelaxNG. */
18938 if (ctxtGiven) {
18939 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18940 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18941 ret, facet->node, WXS_BASIC_CAST typeDecl,
18942 "The value '%s' of the facet 'whitespace' is not "
18943 "valid", facet->value, NULL);
18944 }
18945 }
18946 }
18947 default:
18948 break;
18949 }
18950exit:
18951 if ((! ctxtGiven) && (pctxt != NULL))
18952 xmlSchemaFreeParserCtxt(pctxt);
18953 return (ret);
18954internal_error:
18955 if ((! ctxtGiven) && (pctxt != NULL))
18956 xmlSchemaFreeParserCtxt(pctxt);
18957 return (-1);
18958}
18959
18967static int
18968xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18969 xmlSchemaParserCtxtPtr pctxt)
18970{
18971 int res, olderrs = pctxt->nberrors;
18972 const xmlChar *name = typeDecl->name;
18973 /*
18974 * NOTE: It is intended to use the facets list, instead
18975 * of facetSet.
18976 */
18977 if (typeDecl->facets != NULL) {
18978 xmlSchemaFacetPtr facet = typeDecl->facets;
18979
18980 /*
18981 * Temporarily assign the "schema" to the validation context
18982 * of the parser context. This is needed for NOTATION validation.
18983 */
18984 if (pctxt->vctxt == NULL) {
18985 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18986 return(-1);
18987 }
18988 pctxt->vctxt->schema = pctxt->schema;
18989 while (facet != NULL) {
18990 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18991 HFAILURE
18992 facet = facet->next;
18993 }
18994 pctxt->vctxt->schema = NULL;
18995 }
18996 if (olderrs != pctxt->nberrors)
18997 return(pctxt->err);
18998 return(0);
18999exit_failure:
19000 return(-1);
19001}
19002
19015static xmlSchemaTreeItemPtr
19016xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
19017 xmlSchemaTreeItemPtr particle)
19018{
19019 xmlSchemaTreeItemPtr circ = NULL;
19020 xmlSchemaTreeItemPtr term;
19021 xmlSchemaModelGroupDefPtr gdef;
19022
19023 for (; particle != NULL; particle = particle->next) {
19024 term = particle->children;
19025 if (term == NULL)
19026 continue;
19027 switch (term->type) {
19028 case XML_SCHEMA_TYPE_GROUP:
19029 gdef = (xmlSchemaModelGroupDefPtr) term;
19030 if (gdef == groupDef)
19031 return (particle);
19032 /*
19033 * Mark this model group definition to avoid infinite
19034 * recursion on circular references not yet examined.
19035 */
19036 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
19037 continue;
19038 if (gdef->children != NULL) {
19039 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
19040 circ = xmlSchemaGetCircModelGrDefRef(groupDef,
19041 gdef->children->children);
19042 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
19043 if (circ != NULL)
19044 return (circ);
19045 }
19046 break;
19047 case XML_SCHEMA_TYPE_SEQUENCE:
19048 case XML_SCHEMA_TYPE_CHOICE:
19049 case XML_SCHEMA_TYPE_ALL:
19050 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
19051 if (circ != NULL)
19052 return (circ);
19053 break;
19054 default:
19055 break;
19056 }
19057 }
19058 return (NULL);
19059}
19060
19069static void
19070xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
19071 xmlSchemaParserCtxtPtr ctxt)
19072{
19073 /*
19074 * Schema Component Constraint: Model Group Correct
19075 * 2 Circular groups are disallowed. That is, within the {particles}
19076 * of a group there must not be at any depth a particle whose {term}
19077 * is the group itself.
19078 */
19079 if ((item == NULL) ||
19080 (item->type != XML_SCHEMA_TYPE_GROUP) ||
19081 (item->children == NULL))
19082 return;
19083 {
19084 xmlSchemaTreeItemPtr circ;
19085
19086 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
19087 if (circ != NULL) {
19088 xmlChar *str = NULL;
19089 /*
19090 * TODO: The error report is not adequate: this constraint
19091 * is defined for model groups but not definitions, but since
19092 * there cannot be any circular model groups without a model group
19093 * definition (if not using a construction API), we check those
19094 * definitions only.
19095 */
19096 xmlSchemaPCustomErr(ctxt,
19098 NULL, WXS_ITEM_NODE(circ),
19099 "Circular reference to the model group definition '%s' "
19100 "defined", xmlSchemaFormatQName(&str,
19101 item->targetNamespace, item->name));
19102 FREE_AND_NULL(str)
19103 /*
19104 * NOTE: We will cut the reference to avoid further
19105 * confusion of the processor. This is a fatal error.
19106 */
19107 circ->children = NULL;
19108 }
19109 }
19110}
19111
19126static void
19127xmlSchemaModelGroupToModelGroupDefFixup(
19128 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
19129 xmlSchemaModelGroupPtr mg)
19130{
19131 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19132
19133 while (particle != NULL) {
19134 if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19135 ((WXS_PARTICLE_TERM(particle))->type !=
19136 XML_SCHEMA_TYPE_GROUP))
19137 {
19138 particle = WXS_PTC_CAST particle->next;
19139 continue;
19140 }
19141 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
19142 /*
19143 * TODO: Remove the particle.
19144 */
19145 WXS_PARTICLE_TERM(particle) = NULL;
19146 particle = WXS_PTC_CAST particle->next;
19147 continue;
19148 }
19149 /*
19150 * Assign the model group to the {term} of the particle.
19151 */
19152 WXS_PARTICLE_TERM(particle) =
19153 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
19154
19155 particle = WXS_PTC_CAST particle->next;
19156 }
19157}
19158
19169static xmlSchemaQNameRefPtr
19170xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
19171 xmlSchemaItemListPtr list)
19172{
19173 xmlSchemaAttributeGroupPtr gr;
19174 xmlSchemaQNameRefPtr ref, circ;
19175 int i;
19176 /*
19177 * We will search for an attribute group reference which
19178 * references the context attribute group.
19179 */
19180 for (i = 0; i < list->nbItems; i++) {
19181 ref = list->items[i];
19182 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19183 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
19184 (ref->item != NULL))
19185 {
19186 gr = WXS_ATTR_GROUP_CAST ref->item;
19187 if (gr == ctxtGr)
19188 return(ref);
19189 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19190 continue;
19191 /*
19192 * Mark as visited to avoid infinite recursion on
19193 * circular references not yet examined.
19194 */
19195 if ((gr->attrUses) &&
19196 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19197 {
19198 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19199 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19200 (xmlSchemaItemListPtr) gr->attrUses);
19201 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19202 if (circ != NULL)
19203 return (circ);
19204 }
19205
19206 }
19207 }
19208 return (NULL);
19209}
19210
19219static int
19220xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19221 xmlSchemaParserCtxtPtr ctxt)
19222{
19223 /*
19224 * Schema Representation Constraint:
19225 * Attribute Group Definition Representation OK
19226 * 3 Circular group reference is disallowed outside <redefine>.
19227 * That is, unless this element information item's parent is
19228 * <redefine>, then among the [children], if any, there must
19229 * not be an <attributeGroup> with ref [attribute] which resolves
19230 * to the component corresponding to this <attributeGroup>. Indirect
19231 * circularity is also ruled out. That is, when QName resolution
19232 * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19233 * any <attributeGroup>s with a ref [attribute] among the [children],
19234 * it must not be the case that a `QName` is encountered at any depth
19235 * which resolves to the component corresponding to this <attributeGroup>.
19236 */
19237 if (attrGr->attrUses == NULL)
19238 return(0);
19239 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19240 return(0);
19241 else {
19242 xmlSchemaQNameRefPtr circ;
19243
19244 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19245 (xmlSchemaItemListPtr) attrGr->attrUses);
19246 if (circ != NULL) {
19247 xmlChar *str = NULL;
19248 /*
19249 * TODO: Report the referenced attr group as QName.
19250 */
19251 xmlSchemaPCustomErr(ctxt,
19253 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19254 "Circular reference to the attribute group '%s' "
19255 "defined", xmlSchemaGetComponentQName(&str, attrGr));
19256 FREE_AND_NULL(str);
19257 /*
19258 * NOTE: We will cut the reference to avoid further
19259 * confusion of the processor.
19260 * BADSPEC TODO: The spec should define how to process in this case.
19261 */
19262 circ->item = NULL;
19263 return(ctxt->err);
19264 }
19265 }
19266 return(0);
19267}
19268
19269static int
19270xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19271 xmlSchemaAttributeGroupPtr attrGr);
19272
19287static int
19288xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19289 xmlSchemaBasicItemPtr item,
19290 xmlSchemaWildcardPtr *completeWild,
19291 xmlSchemaItemListPtr list,
19292 xmlSchemaItemListPtr prohibs)
19293{
19294 xmlSchemaAttributeGroupPtr gr;
19295 xmlSchemaAttributeUsePtr use;
19296 xmlSchemaItemListPtr sublist;
19297 int i, j;
19298 int created = (*completeWild == NULL) ? 0 : 1;
19299
19300 if (prohibs)
19301 prohibs->nbItems = 0;
19302
19303 for (i = 0; i < list->nbItems; i++) {
19304 use = list->items[i];
19305
19306 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19307 if (prohibs == NULL) {
19308 PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19309 "unexpected attr prohibition found");
19310 return(-1);
19311 }
19312 /*
19313 * Remove from attribute uses.
19314 */
19315 if (xmlSchemaItemListRemove(list, i) == -1)
19316 return(-1);
19317 i--;
19318 /*
19319 * Note that duplicate prohibitions were already
19320 * handled at parsing time.
19321 */
19322 /*
19323 * Add to list of prohibitions.
19324 */
19325 xmlSchemaItemListAddSize(prohibs, 2, use);
19326 continue;
19327 }
19328 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19329 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19330 {
19331 if ((WXS_QNAME_CAST use)->item == NULL)
19332 return(-1);
19333 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19334 /*
19335 * Expand the referenced attr. group.
19336 * TODO: remove this, this is done in a previous step, so
19337 * already done here.
19338 */
19339 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19340 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19341 return(-1);
19342 }
19343 /*
19344 * Build the 'complete' wildcard; i.e. intersect multiple
19345 * wildcards.
19346 */
19347 if (gr->attributeWildcard != NULL) {
19348 if (*completeWild == NULL) {
19349 *completeWild = gr->attributeWildcard;
19350 } else {
19351 if (! created) {
19352 xmlSchemaWildcardPtr tmpWild;
19353
19354 /*
19355 * Copy the first encountered wildcard as context,
19356 * except for the annotation.
19357 *
19358 * Although the complete wildcard might not correspond
19359 * to any node in the schema, we will anchor it on
19360 * the node of the owner component.
19361 */
19362 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
19363 XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19364 WXS_ITEM_NODE(item));
19365 if (tmpWild == NULL)
19366 return(-1);
19367 if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19368 tmpWild, *completeWild) == -1)
19369 return (-1);
19370 tmpWild->processContents = (*completeWild)->processContents;
19371 *completeWild = tmpWild;
19372 created = 1;
19373 }
19374
19375 if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19376 gr->attributeWildcard) == -1)
19377 return(-1);
19378 }
19379 }
19380 /*
19381 * Just remove the reference if the referenced group does not
19382 * contain any attribute uses.
19383 */
19384 sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19385 if ((sublist == NULL) || sublist->nbItems == 0) {
19386 if (xmlSchemaItemListRemove(list, i) == -1)
19387 return(-1);
19388 i--;
19389 continue;
19390 }
19391 /*
19392 * Add the attribute uses.
19393 */
19394 list->items[i] = sublist->items[0];
19395 if (sublist->nbItems != 1) {
19396 for (j = 1; j < sublist->nbItems; j++) {
19397 i++;
19398 if (xmlSchemaItemListInsert(list,
19399 sublist->items[j], i) == -1)
19400 return(-1);
19401 }
19402 }
19403 }
19404
19405 }
19406 /*
19407 * Handle pointless prohibitions of declared attributes.
19408 */
19409 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19410 xmlSchemaAttributeUseProhibPtr prohib;
19411
19412 for (i = prohibs->nbItems -1; i >= 0; i--) {
19413 prohib = prohibs->items[i];
19414 for (j = 0; j < list->nbItems; j++) {
19415 use = list->items[j];
19416
19417 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19418 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19419 {
19420 xmlChar *str = NULL;
19421
19422 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19424 prohib->node, NULL,
19425 "Skipping pointless attribute use prohibition "
19426 "'%s', since a corresponding attribute use "
19427 "exists already in the type definition",
19428 xmlSchemaFormatQName(&str,
19429 prohib->targetNamespace, prohib->name),
19430 NULL, NULL);
19431 FREE_AND_NULL(str);
19432 /*
19433 * Remove the prohibition.
19434 */
19435 if (xmlSchemaItemListRemove(prohibs, i) == -1)
19436 return(-1);
19437 break;
19438 }
19439 }
19440 }
19441 }
19442 return(0);
19443}
19444
19457static int
19458xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19459 xmlSchemaAttributeGroupPtr attrGr)
19460{
19461 if ((attrGr->attrUses == NULL) ||
19462 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19463 return(0);
19464
19465 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19466 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19467 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19468 return(-1);
19469 return(0);
19470}
19471
19483static int
19484xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19485 xmlSchemaAttributeGroupPtr attrGr)
19486{
19487 /*
19488 * SPEC ag-props-correct
19489 * (1) "The values of the properties of an attribute group definition
19490 * must be as described in the property tableau in The Attribute
19491 * Group Definition Schema Component ($3.6.1), modulo the impact of
19492 * Missing Sub-components ($5.3);"
19493 */
19494
19495 if ((attrGr->attrUses != NULL) &&
19496 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19497 {
19498 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19499 xmlSchemaAttributeUsePtr use, tmp;
19500 int i, j, hasId = 0;
19501
19502 for (i = uses->nbItems -1; i >= 0; i--) {
19503 use = uses->items[i];
19504 /*
19505 * SPEC ag-props-correct
19506 * (2) "Two distinct members of the {attribute uses} must not have
19507 * {attribute declaration}s both of whose {name}s match and whose
19508 * {target namespace}s are identical."
19509 */
19510 if (i > 0) {
19511 for (j = i -1; j >= 0; j--) {
19512 tmp = uses->items[j];
19513 if ((WXS_ATTRUSE_DECL_NAME(use) ==
19514 WXS_ATTRUSE_DECL_NAME(tmp)) &&
19515 (WXS_ATTRUSE_DECL_TNS(use) ==
19516 WXS_ATTRUSE_DECL_TNS(tmp)))
19517 {
19518 xmlChar *str = NULL;
19519
19520 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19522 attrGr->node, WXS_BASIC_CAST attrGr,
19523 "Duplicate %s",
19524 xmlSchemaGetComponentDesignation(&str, use),
19525 NULL);
19526 FREE_AND_NULL(str);
19527 /*
19528 * Remove the duplicate.
19529 */
19530 if (xmlSchemaItemListRemove(uses, i) == -1)
19531 return(-1);
19532 goto next_use;
19533 }
19534 }
19535 }
19536 /*
19537 * SPEC ag-props-correct
19538 * (3) "Two distinct members of the {attribute uses} must not have
19539 * {attribute declaration}s both of whose {type definition}s are or
19540 * are derived from ID."
19541 * TODO: Does 'derived' include member-types of unions?
19542 */
19543 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19544 if (xmlSchemaIsDerivedFromBuiltInType(
19545 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19546 {
19547 if (hasId) {
19548 xmlChar *str = NULL;
19549
19550 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19552 attrGr->node, WXS_BASIC_CAST attrGr,
19553 "There must not exist more than one attribute "
19554 "declaration of type 'xs:ID' "
19555 "(or derived from 'xs:ID'). The %s violates this "
19556 "constraint",
19557 xmlSchemaGetComponentDesignation(&str, use),
19558 NULL);
19559 FREE_AND_NULL(str);
19560 if (xmlSchemaItemListRemove(uses, i) == -1)
19561 return(-1);
19562 }
19563 hasId = 1;
19564 }
19565 }
19566next_use: {}
19567 }
19568 }
19569 return(0);
19570}
19571
19580static int
19581xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19582 xmlSchemaParserCtxtPtr ctxt)
19583{
19584 xmlSchemaAttributeGroupPtr group;
19585
19586 if (ref->item != NULL)
19587 return(0);
19588 group = xmlSchemaGetAttributeGroup(ctxt->schema,
19589 ref->name,
19590 ref->targetNamespace);
19591 if (group == NULL) {
19592 xmlSchemaPResCompAttrErr(ctxt,
19594 NULL, ref->node,
19595 "ref", ref->name, ref->targetNamespace,
19596 ref->itemType, NULL);
19597 return(ctxt->err);
19598 }
19599 ref->item = WXS_BASIC_CAST group;
19600 return(0);
19601}
19602
19617static int
19618xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19619 xmlSchemaAttributePtr attr)
19620{
19621
19622 /*
19623 * SPEC a-props-correct (1)
19624 * "The values of the properties of an attribute declaration must
19625 * be as described in the property tableau in The Attribute
19626 * Declaration Schema Component ($3.2.1), modulo the impact of
19627 * Missing Sub-components ($5.3)."
19628 */
19629
19630 if (WXS_ATTR_TYPEDEF(attr) == NULL)
19631 return(0);
19632
19633 if (attr->defValue != NULL) {
19634 int ret;
19635
19636 /*
19637 * SPEC a-props-correct (3)
19638 * "If the {type definition} is or is derived from ID then there
19639 * must not be a {value constraint}."
19640 */
19641 if (xmlSchemaIsDerivedFromBuiltInType(
19642 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19643 {
19644 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19646 NULL, WXS_BASIC_CAST attr,
19647 "Value constraints are not allowed if the type definition "
19648 "is or is derived from xs:ID",
19649 NULL, NULL);
19650 return(pctxt->err);
19651 }
19652 /*
19653 * SPEC a-props-correct (2)
19654 * "if there is a {value constraint}, the canonical lexical
19655 * representation of its value must be `valid` with respect
19656 * to the {type definition} as defined in String Valid ($3.14.4)."
19657 * TODO: Don't care about the *canonical* stuff here, this requirement
19658 * will be removed in WXS 1.1 anyway.
19659 */
19660 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19661 attr->node, WXS_ATTR_TYPEDEF(attr),
19662 attr->defValue, &(attr->defVal),
19663 1, 1, 0);
19664 if (ret != 0) {
19665 if (ret < 0) {
19666 PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19667 "calling xmlSchemaVCheckCVCSimpleType()");
19668 return(-1);
19669 }
19670 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19672 NULL, WXS_BASIC_CAST attr,
19673 "The value of the value constraint is not valid",
19674 NULL, NULL);
19675 return(pctxt->err);
19676 }
19677 }
19678
19679 return(0);
19680}
19681
19682static xmlSchemaElementPtr
19683xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19684 xmlSchemaElementPtr ancestor)
19685{
19686 xmlSchemaElementPtr ret;
19687
19688 if (WXS_SUBST_HEAD(ancestor) == NULL)
19689 return (NULL);
19690 if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19691 return (ancestor);
19692
19693 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19694 return (NULL);
19695 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19696 ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19697 WXS_SUBST_HEAD(ancestor));
19698 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19699
19700 return (ret);
19701}
19702
19715static int
19716xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19717 xmlSchemaElementPtr elemDecl)
19718{
19719 int ret = 0;
19720 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19721 /*
19722 * SPEC (1) "The values of the properties of an element declaration
19723 * must be as described in the property tableau in The Element
19724 * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19725 * Sub-components ($5.3)."
19726 */
19727 if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19728 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19729
19730 xmlSchemaCheckElementDeclComponent(head, pctxt);
19731 /*
19732 * SPEC (3) "If there is a non-`absent` {substitution group
19733 * affiliation}, then {scope} must be global."
19734 */
19735 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19736 xmlSchemaPCustomErr(pctxt,
19738 WXS_BASIC_CAST elemDecl, NULL,
19739 "Only global element declarations can have a "
19740 "substitution group affiliation", NULL);
19742 }
19743 /*
19744 * TODO: SPEC (6) "Circular substitution groups are disallowed.
19745 * That is, it must not be possible to return to an element declaration
19746 * by repeatedly following the {substitution group affiliation}
19747 * property."
19748 */
19749 if (head == elemDecl)
19750 circ = head;
19751 else if (WXS_SUBST_HEAD(head) != NULL)
19752 circ = xmlSchemaCheckSubstGroupCircular(head, head);
19753 else
19754 circ = NULL;
19755 if (circ != NULL) {
19756 xmlChar *strA = NULL, *strB = NULL;
19757
19758 xmlSchemaPCustomErrExt(pctxt,
19760 WXS_BASIC_CAST circ, NULL,
19761 "The element declaration '%s' defines a circular "
19762 "substitution group to element declaration '%s'",
19763 xmlSchemaGetComponentQName(&strA, circ),
19764 xmlSchemaGetComponentQName(&strB, head),
19765 NULL);
19766 FREE_AND_NULL(strA)
19767 FREE_AND_NULL(strB)
19769 }
19770 /*
19771 * SPEC (4) "If there is a {substitution group affiliation},
19772 * the {type definition}
19773 * of the element declaration must be validly derived from the {type
19774 * definition} of the {substitution group affiliation}, given the value
19775 * of the {substitution group exclusions} of the {substitution group
19776 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19777 * (if the {type definition} is complex) or as defined in
19778 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19779 * simple)."
19780 *
19781 * NOTE: {substitution group exclusions} means the values of the
19782 * attribute "final".
19783 */
19784
19785 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19786 int set = 0;
19787
19788 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19789 set |= SUBSET_EXTENSION;
19790 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19791 set |= SUBSET_RESTRICTION;
19792
19793 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19794 WXS_ELEM_TYPEDEF(head), set) != 0) {
19795 xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19796
19798 xmlSchemaPCustomErrExt(pctxt,
19800 WXS_BASIC_CAST elemDecl, NULL,
19801 "The type definition '%s' was "
19802 "either rejected by the substitution group "
19803 "affiliation '%s', or not validly derived from its type "
19804 "definition '%s'",
19805 xmlSchemaGetComponentQName(&strA, typeDef),
19806 xmlSchemaGetComponentQName(&strB, head),
19807 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19808 FREE_AND_NULL(strA)
19809 FREE_AND_NULL(strB)
19810 FREE_AND_NULL(strC)
19811 }
19812 }
19813 }
19814 /*
19815 * SPEC (5) "If the {type definition} or {type definition}'s
19816 * {content type}
19817 * is or is derived from ID then there must not be a {value constraint}.
19818 * Note: The use of ID as a type definition for elements goes beyond
19819 * XML 1.0, and should be avoided if backwards compatibility is desired"
19820 */
19821 if ((elemDecl->value != NULL) &&
19822 ((WXS_IS_SIMPLE(typeDef) &&
19823 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19824 (WXS_IS_COMPLEX(typeDef) &&
19825 WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19826 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19827 XML_SCHEMAS_ID)))) {
19828
19830 xmlSchemaPCustomErr(pctxt,
19832 WXS_BASIC_CAST elemDecl, NULL,
19833 "The type definition (or type definition's content type) is or "
19834 "is derived from ID; value constraints are not allowed in "
19835 "conjunction with such a type definition", NULL);
19836 } else if (elemDecl->value != NULL) {
19837 int vcret;
19839
19840 /*
19841 * SPEC (2) "If there is a {value constraint}, the canonical lexical
19842 * representation of its value must be `valid` with respect to the
19843 * {type definition} as defined in Element Default Valid (Immediate)
19844 * ($3.3.6)."
19845 */
19846 if (typeDef == NULL) {
19847 xmlSchemaPErr(pctxt, elemDecl->node,
19849 "Internal error: xmlSchemaCheckElemPropsCorrect, "
19850 "type is missing... skipping validation of "
19851 "the value constraint", NULL, NULL);
19852 return (-1);
19853 }
19854 if (elemDecl->node != NULL) {
19855 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19856 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19857 BAD_CAST "fixed");
19858 else
19859 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19860 BAD_CAST "default");
19861 }
19862 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19863 typeDef, elemDecl->value, &(elemDecl->defVal));
19864 if (vcret != 0) {
19865 if (vcret < 0) {
19866 PERROR_INT("xmlSchemaElemCheckValConstr",
19867 "failed to validate the value constraint of an "
19868 "element declaration");
19869 return (-1);
19870 }
19871 return (vcret);
19872 }
19873 }
19874
19875 return (ret);
19876}
19877
19897static void
19898xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19899 xmlSchemaElementPtr elemDecl)
19900{
19901 if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19902 /* SPEC (1) "Its {abstract} is false." */
19903 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19904 return;
19905 {
19906 xmlSchemaElementPtr head;
19907 xmlSchemaTypePtr headType, type;
19908 int set, methSet;
19909 /*
19910 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19911 * {disallowed substitutions} as the blocking constraint, as defined in
19912 * Substitution Group OK (Transitive) ($3.3.6)."
19913 */
19914 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19915 head = WXS_SUBST_HEAD(head)) {
19916 set = 0;
19917 methSet = 0;
19918 /*
19919 * The blocking constraints.
19920 */
19921 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19922 continue;
19923 headType = head->subtypes;
19924 type = elemDecl->subtypes;
19925 if (headType == type)
19926 goto add_member;
19927 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19928 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19929 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19930 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19931 /*
19932 * SPEC: Substitution Group OK (Transitive) (2.3)
19933 * "The set of all {derivation method}s involved in the
19934 * derivation of D's {type definition} from C's {type definition}
19935 * does not intersect with the union of the blocking constraint,
19936 * C's {prohibited substitutions} (if C is complex, otherwise the
19937 * empty set) and the {prohibited substitutions} (respectively the
19938 * empty set) of any intermediate {type definition}s in the
19939 * derivation of D's {type definition} from C's {type definition}."
19940 */
19941 /*
19942 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19943 * subst.head axis, the methSet does not need to be computed for
19944 * the full depth over and over.
19945 */
19946 /*
19947 * The set of all {derivation method}s involved in the derivation
19948 */
19949 while ((type != NULL) && (type != headType)) {
19950 if ((WXS_IS_EXTENSION(type)) &&
19951 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19952 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19953
19954 if (WXS_IS_RESTRICTION(type) &&
19955 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19956 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19957
19958 type = type->baseType;
19959 }
19960 /*
19961 * The {prohibited substitutions} of all intermediate types +
19962 * the head's type.
19963 */
19964 type = elemDecl->subtypes->baseType;
19965 while (type != NULL) {
19966 if (WXS_IS_COMPLEX(type)) {
19967 if ((type->flags &
19968 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19969 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19970 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19971 if ((type->flags &
19972 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19973 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19974 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19975 } else
19976 break;
19977 if (type == headType)
19978 break;
19979 type = type->baseType;
19980 }
19981 if ((set != 0) &&
19982 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19983 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19984 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19985 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19986 continue;
19987 }
19988add_member:
19989 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19990 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19991 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19992 }
19993 }
19994}
19995
19996#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
20006static int
20007xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
20008 xmlSchemaBasicItemPtr ctxtComponent,
20009 xmlSchemaParticlePtr ctxtParticle,
20010 xmlSchemaParticlePtr searchParticle,
20011 xmlSchemaParticlePtr curParticle,
20012 int search)
20013{
20014 return(0);
20015
20016 int ret = 0;
20017 xmlSchemaParticlePtr cur = curParticle;
20018 if (curParticle == NULL) {
20019 return(0);
20020 }
20021 if (WXS_PARTICLE_TERM(curParticle) == NULL) {
20022 /*
20023 * Just return in this case. A missing "term" of the particle
20024 * might arise due to an invalid "term" component.
20025 */
20026 return(0);
20027 }
20028 while (cur != NULL) {
20029 switch (WXS_PARTICLE_TERM(cur)->type) {
20030 case XML_SCHEMA_TYPE_ANY:
20031 break;
20032 case XML_SCHEMA_TYPE_ELEMENT:
20033 if (search == 0) {
20034 ret = xmlSchemaCheckElementDeclConsistent(pctxt,
20035 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
20036 if (ret != 0)
20037 return(ret);
20038 } else {
20039 xmlSchemaElementPtr elem =
20040 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
20041 /*
20042 * SPEC Element Declarations Consistent:
20043 * "If the {particles} contains, either directly,
20044 * indirectly (that is, within the {particles} of a
20045 * contained model group, recursively) or `implicitly`
20046 * two or more element declaration particles with
20047 * the same {name} and {target namespace}, then
20048 * all their type definitions must be the same
20049 * top-level definition [...]"
20050 */
20051 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
20052 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
20053 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
20054 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
20055 {
20056 xmlChar *strA = NULL, *strB = NULL;
20057
20058 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20059 /* TODO: error code */
20060 XML_SCHEMAP_COS_NONAMBIG,
20061 WXS_ITEM_NODE(cur), NULL,
20062 "In the content model of %s, there are multiple "
20063 "element declarations for '%s' with different "
20064 "type definitions",
20065 xmlSchemaGetComponentDesignation(&strA,
20066 ctxtComponent),
20067 xmlSchemaFormatQName(&strB,
20068 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
20069 WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
20070 FREE_AND_NULL(strA);
20071 FREE_AND_NULL(strB);
20072 return(XML_SCHEMAP_COS_NONAMBIG);
20073 }
20074 }
20075 break;
20076 case XML_SCHEMA_TYPE_SEQUENCE: {
20077 break;
20078 }
20079 case XML_SCHEMA_TYPE_CHOICE:{
20080 /*
20081 xmlSchemaTreeItemPtr sub;
20082
20083 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
20084 while (sub != NULL) {
20085 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
20086 ctxtParticle, ctxtElem);
20087 if (ret != 0)
20088 return(ret);
20089 sub = sub->next;
20090 }
20091 */
20092 break;
20093 }
20094 case XML_SCHEMA_TYPE_ALL:
20095 break;
20096 case XML_SCHEMA_TYPE_GROUP:
20097 break;
20098 default:
20099 xmlSchemaInternalErr2(ACTXT_CAST pctxt,
20100 "xmlSchemaCheckElementDeclConsistent",
20101 "found unexpected term of type '%s' in content model",
20102 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
20103 return(-1);
20104 }
20105 cur = (xmlSchemaParticlePtr) cur->next;
20106 }
20107
20108exit:
20109 return(ret);
20110}
20111#endif
20112
20122static void
20123xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
20124 xmlSchemaParserCtxtPtr ctxt)
20125{
20126 if (elemDecl == NULL)
20127 return;
20128 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
20129 return;
20130 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
20131 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
20132 /*
20133 * Adds substitution group members.
20134 */
20135 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
20136 }
20137}
20138
20147static void
20148xmlSchemaResolveModelGroupParticleReferences(
20149 xmlSchemaParserCtxtPtr ctxt,
20150 xmlSchemaModelGroupPtr mg)
20151{
20152 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
20153 xmlSchemaQNameRefPtr ref;
20154 xmlSchemaBasicItemPtr refItem;
20155
20156 /*
20157 * URGENT TODO: Test this.
20158 */
20159 while (particle != NULL) {
20160 if ((WXS_PARTICLE_TERM(particle) == NULL) ||
20161 ((WXS_PARTICLE_TERM(particle))->type !=
20162 XML_SCHEMA_EXTRA_QNAMEREF))
20163 {
20164 goto next_particle;
20165 }
20166 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
20167 /*
20168 * Resolve the reference.
20169 * NULL the {term} by default.
20170 */
20171 particle->children = NULL;
20172
20173 refItem = xmlSchemaGetNamedComponent(ctxt->schema,
20174 ref->itemType, ref->name, ref->targetNamespace);
20175 if (refItem == NULL) {
20176 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
20177 NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
20178 ref->targetNamespace, ref->itemType, NULL);
20179 /* TODO: remove the particle. */
20180 goto next_particle;
20181 }
20182 if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
20183 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
20184 /* TODO: remove the particle. */
20185 goto next_particle;
20186 /*
20187 * NOTE that we will assign the model group definition
20188 * itself to the "term" of the particle. This will ease
20189 * the check for circular model group definitions. After
20190 * that the "term" will be assigned the model group of the
20191 * model group definition.
20192 */
20193 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20194 XML_SCHEMA_TYPE_ALL) {
20195 /*
20196 * SPEC cos-all-limited (1)
20197 * SPEC cos-all-limited (1.2)
20198 * "It appears only as the value of one or both of the
20199 * following properties:"
20200 * (1.1) "the {model group} property of a model group
20201 * definition."
20202 * (1.2) "the {term} property of a particle [... of] the "
20203 * {content type} of a complex type definition."
20204 */
20205 xmlSchemaCustomErr(ACTXT_CAST ctxt,
20206 /* TODO: error code */
20208 WXS_ITEM_NODE(particle), NULL,
20209 "A model group definition is referenced, but "
20210 "it contains an 'all' model group, which "
20211 "cannot be contained by model groups",
20212 NULL, NULL);
20213 /* TODO: remove the particle. */
20214 goto next_particle;
20215 }
20216 particle->children = (xmlSchemaTreeItemPtr) refItem;
20217 } else {
20218 /*
20219 * TODO: Are referenced element declarations the only
20220 * other components we expect here?
20221 */
20222 particle->children = (xmlSchemaTreeItemPtr) refItem;
20223 }
20224next_particle:
20225 particle = WXS_PTC_CAST particle->next;
20226 }
20227}
20228
20229static int
20230xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20231 xmlSchemaValPtr y)
20232{
20233 xmlSchemaTypePtr tx, ty, ptx, pty;
20234 int ret;
20235
20236 while (x != NULL) {
20237 /* Same types. */
20238 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20239 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20240 ptx = xmlSchemaGetPrimitiveType(tx);
20241 pty = xmlSchemaGetPrimitiveType(ty);
20242 /*
20243 * (1) if a datatype T' is `derived` by `restriction` from an
20244 * atomic datatype T then the `value space` of T' is a subset of
20245 * the `value space` of T. */
20246 /*
20247 * (2) if datatypes T' and T'' are `derived` by `restriction`
20248 * from a common atomic ancestor T then the `value space`s of T'
20249 * and T'' may overlap.
20250 */
20251 if (ptx != pty)
20252 return(0);
20253 /*
20254 * We assume computed values to be normalized, so do a fast
20255 * string comparison for string based types.
20256 */
20257 if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20258 WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20259 if (! xmlStrEqual(
20260 xmlSchemaValueGetAsString(x),
20261 xmlSchemaValueGetAsString(y)))
20262 return (0);
20263 } else {
20264 ret = xmlSchemaCompareValuesWhtsp(
20265 x, XML_SCHEMA_WHITESPACE_PRESERVE,
20266 y, XML_SCHEMA_WHITESPACE_PRESERVE);
20267 if (ret == -2)
20268 return(-1);
20269 if (ret != 0)
20270 return(0);
20271 }
20272 /*
20273 * Lists.
20274 */
20275 x = xmlSchemaValueGetNext(x);
20276 if (x != NULL) {
20277 y = xmlSchemaValueGetNext(y);
20278 if (y == NULL)
20279 return (0);
20280 } else if (xmlSchemaValueGetNext(y) != NULL)
20281 return (0);
20282 else
20283 return (1);
20284 }
20285 return (0);
20286}
20287
20295static int
20296xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20297 xmlSchemaParserCtxtPtr ctxt)
20298{
20299 if ((ctxt == NULL) || (ause == NULL))
20300 return(-1);
20301 if ((ause->attrDecl == NULL) ||
20302 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20303 return(0);
20304
20305 {
20306 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20307
20308 /*
20309 * TODO: Evaluate, what errors could occur if the declaration is not
20310 * found.
20311 */
20312 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20313 ref->name, ref->targetNamespace);
20314 if (ause->attrDecl == NULL) {
20315 xmlSchemaPResCompAttrErr(ctxt,
20317 WXS_BASIC_CAST ause, ause->node,
20318 "ref", ref->name, ref->targetNamespace,
20319 XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20320 return(ctxt->err);;
20321 }
20322 }
20323 return(0);
20324}
20325
20335static int
20336xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20337 xmlSchemaAttributeUsePtr use)
20338{
20339 if ((ctxt == NULL) || (use == NULL))
20340 return(-1);
20341 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20342 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20343 return(0);
20344
20345 /*
20346 * SPEC au-props-correct (1)
20347 * "The values of the properties of an attribute use must be as
20348 * described in the property tableau in The Attribute Use Schema
20349 * Component ($3.5.1), modulo the impact of Missing
20350 * Sub-components ($5.3)."
20351 */
20352
20353 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20354 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20355 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20356 {
20357 xmlSchemaPCustomErr(ctxt,
20359 WXS_BASIC_CAST use, NULL,
20360 "The attribute declaration has a 'fixed' value constraint "
20361 ", thus the attribute use must also have a 'fixed' value "
20362 "constraint",
20363 NULL);
20364 return(ctxt->err);
20365 }
20366 /*
20367 * Compute and check the value constraint's value.
20368 */
20369 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20370 int ret;
20371 /*
20372 * TODO: The spec seems to be missing a check of the
20373 * value constraint of the attribute use. We will do it here.
20374 */
20375 /*
20376 * SPEC a-props-correct (3)
20377 */
20378 if (xmlSchemaIsDerivedFromBuiltInType(
20379 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20380 {
20381 xmlSchemaCustomErr(ACTXT_CAST ctxt,
20383 NULL, WXS_BASIC_CAST use,
20384 "Value constraints are not allowed if the type definition "
20385 "is or is derived from xs:ID",
20386 NULL, NULL);
20387 return(ctxt->err);
20388 }
20389
20390 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20391 use->node, WXS_ATTRUSE_TYPEDEF(use),
20392 use->defValue, &(use->defVal),
20393 1, 1, 0);
20394 if (ret != 0) {
20395 if (ret < 0) {
20396 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20397 "calling xmlSchemaVCheckCVCSimpleType()");
20398 return(-1);
20399 }
20400 xmlSchemaCustomErr(ACTXT_CAST ctxt,
20402 NULL, WXS_BASIC_CAST use,
20403 "The value of the value constraint is not valid",
20404 NULL, NULL);
20405 return(ctxt->err);
20406 }
20407 }
20408 /*
20409 * SPEC au-props-correct (2)
20410 * "If the {attribute declaration} has a fixed
20411 * {value constraint}, then if the attribute use itself has a
20412 * {value constraint}, it must also be fixed and its value must match
20413 * that of the {attribute declaration}'s {value constraint}."
20414 */
20415 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20416 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20417 {
20418 if (! xmlSchemaAreValuesEqual(use->defVal,
20419 (WXS_ATTRUSE_DECL(use))->defVal))
20420 {
20421 xmlSchemaPCustomErr(ctxt,
20423 WXS_BASIC_CAST use, NULL,
20424 "The 'fixed' value constraint of the attribute use "
20425 "must match the attribute declaration's value "
20426 "constraint '%s'",
20427 (WXS_ATTRUSE_DECL(use))->defValue);
20428 }
20429 return(ctxt->err);
20430 }
20431 return(0);
20432}
20433
20434
20435
20436
20444static int
20445xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20446 xmlSchemaParserCtxtPtr ctxt)
20447{
20448 /*
20449 * The simple type definition corresponding to the <simpleType> element
20450 * information item in the [children], if present, otherwise the simple
20451 * type definition `resolved` to by the `actual value` of the type
20452 * [attribute], if present, otherwise the `simple ur-type definition`.
20453 */
20454 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20455 return(0);
20456 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20457 if (item->subtypes != NULL)
20458 return(0);
20459 if (item->typeName != NULL) {
20460 xmlSchemaTypePtr type;
20461
20462 type = xmlSchemaGetType(ctxt->schema, item->typeName,
20463 item->typeNs);
20464 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20465 xmlSchemaPResCompAttrErr(ctxt,
20467 WXS_BASIC_CAST item, item->node,
20468 "type", item->typeName, item->typeNs,
20469 XML_SCHEMA_TYPE_SIMPLE, NULL);
20470 return(ctxt->err);
20471 } else
20472 item->subtypes = type;
20473
20474 } else {
20475 /*
20476 * The type defaults to the xs:anySimpleType.
20477 */
20478 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20479 }
20480 return(0);
20481}
20482
20493static int
20494xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20495 xmlSchemaParserCtxtPtr pctxt)
20496{
20497 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20498 return(0);
20499 if (idc->ref->name != NULL) {
20500 idc->ref->item = (xmlSchemaBasicItemPtr)
20501 xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20502 idc->ref->targetNamespace);
20503 if (idc->ref->item == NULL) {
20504 /*
20505 * TODO: It is actually not an error to fail to resolve
20506 * at this stage. BUT we need to be that strict!
20507 */
20508 xmlSchemaPResCompAttrErr(pctxt,
20510 WXS_BASIC_CAST idc, idc->node,
20511 "refer", idc->ref->name,
20512 idc->ref->targetNamespace,
20513 XML_SCHEMA_TYPE_IDC_KEY, NULL);
20514 return(pctxt->err);
20515 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20516 /*
20517 * SPEC c-props-correct (1)
20518 */
20519 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20521 NULL, WXS_BASIC_CAST idc,
20522 "The keyref references a keyref",
20523 NULL, NULL);
20524 idc->ref->item = NULL;
20525 return(pctxt->err);
20526 } else {
20527 if (idc->nbFields !=
20528 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20529 xmlChar *str = NULL;
20530 xmlSchemaIDCPtr refer;
20531
20532 refer = (xmlSchemaIDCPtr) idc->ref->item;
20533 /*
20534 * SPEC c-props-correct(2)
20535 * "If the {identity-constraint category} is keyref,
20536 * the cardinality of the {fields} must equal that of
20537 * the {fields} of the {referenced key}.
20538 */
20539 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20541 NULL, WXS_BASIC_CAST idc,
20542 "The cardinality of the keyref differs from the "
20543 "cardinality of the referenced key/unique '%s'",
20544 xmlSchemaFormatQName(&str, refer->targetNamespace,
20545 refer->name),
20546 NULL);
20547 FREE_AND_NULL(str)
20548 return(pctxt->err);
20549 }
20550 }
20551 }
20552 return(0);
20553}
20554
20555static int
20556xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20557 xmlSchemaParserCtxtPtr pctxt)
20558{
20559 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20560 prohib->targetNamespace) == NULL) {
20561
20562 xmlSchemaPResCompAttrErr(pctxt,
20564 NULL, prohib->node,
20565 "ref", prohib->name, prohib->targetNamespace,
20566 XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20568 }
20569 return(0);
20570}
20571
20572#define WXS_REDEFINED_TYPE(c) \
20573(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20574
20575#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20576(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20577
20578#define WXS_REDEFINED_ATTR_GROUP(c) \
20579(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20580
20581static int
20582xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20583{
20584 int err = 0;
20585 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20586 xmlSchemaBasicItemPtr prev, item;
20587 int wasRedefined;
20588
20589 if (redef == NULL)
20590 return(0);
20591
20592 do {
20593 item = redef->item;
20594 /*
20595 * First try to locate the redefined component in the
20596 * schema graph starting with the redefined schema.
20597 * NOTE: According to this schema bug entry:
20598 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20599 * it's not clear if the referenced component needs to originate
20600 * from the <redefine>d schema _document_ or the schema; the latter
20601 * would include all imported and included sub-schemas of the
20602 * <redefine>d schema. Currently the latter approach is used.
20603 * SUPPLEMENT: It seems that the WG moves towards the latter
20604 * approach, so we are doing it right.
20605 *
20606 */
20607 prev = xmlSchemaFindRedefCompInGraph(
20608 redef->targetBucket, item->type,
20609 redef->refName, redef->refTargetNs);
20610 if (prev == NULL) {
20611 xmlChar *str = NULL;
20613
20614 /*
20615 * SPEC src-redefine:
20616 * (6.2.1) "The `actual value` of its own name attribute plus
20617 * target namespace must successfully `resolve` to a model
20618 * group definition in I."
20619 * (7.2.1) "The `actual value` of its own name attribute plus
20620 * target namespace must successfully `resolve` to an attribute
20621 * group definition in I."
20622
20623 *
20624 * Note that, if we are redefining with the use of references
20625 * to components, the spec assumes the src-resolve to be used;
20626 * but this won't assure that we search only *inside* the
20627 * redefined schema.
20628 */
20629 if (redef->reference)
20630 node = WXS_ITEM_NODE(redef->reference);
20631 else
20632 node = WXS_ITEM_NODE(item);
20633 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20634 /*
20635 * TODO: error code.
20636 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20637 * reference kind.
20638 */
20640 "The %s '%s' to be redefined could not be found in "
20641 "the redefined schema",
20642 WXS_ITEM_TYPE_NAME(item),
20643 xmlSchemaFormatQName(&str, redef->refTargetNs,
20644 redef->refName));
20645 FREE_AND_NULL(str);
20646 err = pctxt->err;
20647 redef = redef->next;
20648 continue;
20649 }
20650 /*
20651 * TODO: Obtaining and setting the redefinition state is really
20652 * clumsy.
20653 */
20654 wasRedefined = 0;
20655 switch (item->type) {
20656 case XML_SCHEMA_TYPE_COMPLEX:
20657 case XML_SCHEMA_TYPE_SIMPLE:
20658 if ((WXS_TYPE_CAST prev)->flags &
20659 XML_SCHEMAS_TYPE_REDEFINED)
20660 {
20661 wasRedefined = 1;
20662 break;
20663 }
20664 /* Mark it as redefined. */
20665 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20666 /*
20667 * Assign the redefined type to the
20668 * base type of the redefining type.
20669 * TODO: How
20670 */
20671 ((xmlSchemaTypePtr) item)->baseType =
20672 (xmlSchemaTypePtr) prev;
20673 break;
20674 case XML_SCHEMA_TYPE_GROUP:
20675 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20676 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20677 {
20678 wasRedefined = 1;
20679 break;
20680 }
20681 /* Mark it as redefined. */
20682 (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20683 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20684 if (redef->reference != NULL) {
20685 /*
20686 * Overwrite the QName-reference with the
20687 * referenced model group def.
20688 */
20689 (WXS_PTC_CAST redef->reference)->children =
20690 WXS_TREE_CAST prev;
20691 }
20692 redef->target = prev;
20693 break;
20694 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20695 if ((WXS_ATTR_GROUP_CAST prev)->flags &
20696 XML_SCHEMAS_ATTRGROUP_REDEFINED)
20697 {
20698 wasRedefined = 1;
20699 break;
20700 }
20701 (WXS_ATTR_GROUP_CAST prev)->flags |=
20702 XML_SCHEMAS_ATTRGROUP_REDEFINED;
20703 if (redef->reference != NULL) {
20704 /*
20705 * Assign the redefined attribute group to the
20706 * QName-reference component.
20707 * This is the easy case, since we will just
20708 * expand the redefined group.
20709 */
20710 (WXS_QNAME_CAST redef->reference)->item = prev;
20711 redef->target = NULL;
20712 } else {
20713 /*
20714 * This is the complicated case: we need
20715 * to apply src-redefine (7.2.2) at a later
20716 * stage, i.e. when attribute group references
20717 * have been expanded and simple types have
20718 * been fixed.
20719 */
20720 redef->target = prev;
20721 }
20722 break;
20723 default:
20724 PERROR_INT("xmlSchemaResolveRedefReferences",
20725 "Unexpected redefined component type");
20726 return(-1);
20727 }
20728 if (wasRedefined) {
20729 xmlChar *str = NULL;
20731
20732 if (redef->reference)
20733 node = WXS_ITEM_NODE(redef->reference);
20734 else
20735 node = WXS_ITEM_NODE(redef->item);
20736
20737 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20738 /* TODO: error code. */
20740 node, NULL,
20741 "The referenced %s was already redefined. Multiple "
20742 "redefinition of the same component is not supported",
20743 xmlSchemaGetComponentDesignation(&str, prev),
20744 NULL);
20745 FREE_AND_NULL(str)
20746 err = pctxt->err;
20747 redef = redef->next;
20748 continue;
20749 }
20750 redef = redef->next;
20751 } while (redef != NULL);
20752
20753 return(err);
20754}
20755
20756static int
20757xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20758{
20759 int err = 0;
20760 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20761 xmlSchemaBasicItemPtr item;
20762
20763 if (redef == NULL)
20764 return(0);
20765
20766 do {
20767 if (redef->target == NULL) {
20768 redef = redef->next;
20769 continue;
20770 }
20771 item = redef->item;
20772
20773 switch (item->type) {
20774 case XML_SCHEMA_TYPE_SIMPLE:
20775 case XML_SCHEMA_TYPE_COMPLEX:
20776 /*
20777 * Since the spec wants the {name} of the redefined
20778 * type to be 'absent', we'll NULL it.
20779 */
20780 (WXS_TYPE_CAST redef->target)->name = NULL;
20781
20782 /*
20783 * TODO: Seems like there's nothing more to do. The normal
20784 * inheritance mechanism is used. But not 100% sure.
20785 */
20786 break;
20787 case XML_SCHEMA_TYPE_GROUP:
20788 /*
20789 * URGENT TODO:
20790 * SPEC src-redefine:
20791 * (6.2.2) "The {model group} of the model group definition
20792 * which corresponds to it per XML Representation of Model
20793 * Group Definition Schema Components ($3.7.2) must be a
20794 * `valid restriction` of the {model group} of that model
20795 * group definition in I, as defined in Particle Valid
20796 * (Restriction) ($3.9.6)."
20797 */
20798 break;
20799 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20800 /*
20801 * SPEC src-redefine:
20802 * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20803 * the attribute group definition which corresponds to it
20804 * per XML Representation of Attribute Group Definition Schema
20805 * Components ($3.6.2) must be `valid restrictions` of the
20806 * {attribute uses} and {attribute wildcard} of that attribute
20807 * group definition in I, as defined in clause 2, clause 3 and
20808 * clause 4 of Derivation Valid (Restriction, Complex)
20809 * ($3.4.6) (where references to the base type definition are
20810 * understood as references to the attribute group definition
20811 * in I)."
20812 */
20813 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20814 XML_SCHEMA_ACTION_REDEFINE,
20815 item, redef->target,
20816 (WXS_ATTR_GROUP_CAST item)->attrUses,
20817 (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20818 (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20819 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20820 if (err == -1)
20821 return(-1);
20822 break;
20823 default:
20824 break;
20825 }
20826 redef = redef->next;
20827 } while (redef != NULL);
20828 return(0);
20829}
20830
20831
20832static int
20833xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20834 xmlSchemaBucketPtr bucket)
20835{
20836 xmlSchemaBasicItemPtr item;
20837 int err;
20839 const xmlChar *name;
20840 int i;
20841
20842#define WXS_GET_GLOBAL_HASH(c, slot) { \
20843 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20844 table = &(WXS_IMPBUCKET((c))->schema->slot); \
20845 else \
20846 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20847
20848 /*
20849 * Add global components to the schema's hash tables.
20850 * This is the place where duplicate components will be
20851 * detected.
20852 * TODO: I think normally we should support imports of the
20853 * same namespace from multiple locations. We don't do currently,
20854 * but if we do then according to:
20855 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20856 * we would need, if imported directly, to import redefined
20857 * components as well to be able to catch clashing components.
20858 * (I hope I'll still know what this means after some months :-()
20859 */
20860 if (bucket == NULL)
20861 return(-1);
20862 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20863 return(0);
20864 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20865
20866 for (i = 0; i < bucket->globals->nbItems; i++) {
20867 item = bucket->globals->items[i];
20868 table = NULL;
20869 switch (item->type) {
20870 case XML_SCHEMA_TYPE_COMPLEX:
20871 case XML_SCHEMA_TYPE_SIMPLE:
20872 if (WXS_REDEFINED_TYPE(item))
20873 continue;
20874 name = (WXS_TYPE_CAST item)->name;
20875 WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20876 break;
20877 case XML_SCHEMA_TYPE_ELEMENT:
20878 name = (WXS_ELEM_CAST item)->name;
20879 WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20880 break;
20881 case XML_SCHEMA_TYPE_ATTRIBUTE:
20882 name = (WXS_ATTR_CAST item)->name;
20883 WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20884 break;
20885 case XML_SCHEMA_TYPE_GROUP:
20886 if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20887 continue;
20888 name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20889 WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20890 break;
20891 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20892 if (WXS_REDEFINED_ATTR_GROUP(item))
20893 continue;
20894 name = (WXS_ATTR_GROUP_CAST item)->name;
20895 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20896 break;
20897 case XML_SCHEMA_TYPE_IDC_KEY:
20898 case XML_SCHEMA_TYPE_IDC_UNIQUE:
20899 case XML_SCHEMA_TYPE_IDC_KEYREF:
20900 name = (WXS_IDC_CAST item)->name;
20901 WXS_GET_GLOBAL_HASH(bucket, idcDef)
20902 break;
20903 case XML_SCHEMA_TYPE_NOTATION:
20904 name = ((xmlSchemaNotationPtr) item)->name;
20905 WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20906 break;
20907 default:
20908 PERROR_INT("xmlSchemaAddComponents",
20909 "Unexpected global component type");
20910 continue;
20911 }
20912 if (*table == NULL) {
20913 *table = xmlHashCreateDict(10, pctxt->dict);
20914 if (*table == NULL) {
20915 PERROR_INT("xmlSchemaAddComponents",
20916 "failed to create a component hash table");
20917 return(-1);
20918 }
20919 }
20921 if (err != 0) {
20922 xmlChar *str = NULL;
20923
20924 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20926 WXS_ITEM_NODE(item),
20927 WXS_BASIC_CAST item,
20928 "A global %s '%s' does already exist",
20929 WXS_ITEM_TYPE_NAME(item),
20930 xmlSchemaGetComponentQName(&str, item));
20931 FREE_AND_NULL(str);
20932 }
20933 }
20934 /*
20935 * Process imported/included schemas.
20936 */
20937 if (bucket->relations != NULL) {
20938 xmlSchemaSchemaRelationPtr rel = bucket->relations;
20939 do {
20940 if ((rel->bucket != NULL) &&
20941 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20942 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20943 return(-1);
20944 }
20945 rel = rel->next;
20946 } while (rel != NULL);
20947 }
20948 return(0);
20949}
20950
20951static int
20952xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20953 xmlSchemaBucketPtr rootBucket)
20954{
20955 xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20956 xmlSchemaTreeItemPtr item, *items;
20957 int nbItems, i, ret = 0;
20958 xmlSchemaBucketPtr oldbucket = con->bucket;
20959 xmlSchemaElementPtr elemDecl;
20960
20961#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20962
20963 if ((con->pending == NULL) ||
20964 (con->pending->nbItems == 0))
20965 return(0);
20966
20967 /*
20968 * Since xmlSchemaFixupComplexType() will create new particles
20969 * (local components), and those particle components need a bucket
20970 * on the constructor, we'll assure here that the constructor has
20971 * a bucket.
20972 * TODO: Think about storing locals _only_ on the main bucket.
20973 */
20974 if (con->bucket == NULL)
20975 con->bucket = rootBucket;
20976
20977 /* TODO:
20978 * SPEC (src-redefine):
20979 * (6.2) "If it has no such self-reference, then all of the
20980 * following must be true:"
20981
20982 * (6.2.2) The {model group} of the model group definition which
20983 * corresponds to it per XML Representation of Model Group
20984 * Definition Schema Components ($3.7.2) must be a `valid
20985 * restriction` of the {model group} of that model group definition
20986 * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20987 */
20988 xmlSchemaCheckSRCRedefineFirst(pctxt);
20989
20990 /*
20991 * Add global components to the schemata's hash tables.
20992 */
20993 xmlSchemaAddComponents(pctxt, rootBucket);
20994
20995 pctxt->ctxtType = NULL;
20996 items = (xmlSchemaTreeItemPtr *) con->pending->items;
20997 nbItems = con->pending->nbItems;
20998 /*
20999 * Now that we have parsed *all* the schema document(s) and converted
21000 * them to schema components, we can resolve references, apply component
21001 * constraints, create the FSA from the content model, etc.
21002 */
21003 /*
21004 * Resolve references of..
21005 *
21006 * 1. element declarations:
21007 * - the type definition
21008 * - the substitution group affiliation
21009 * 2. simple/complex types:
21010 * - the base type definition
21011 * - the memberTypes of union types
21012 * - the itemType of list types
21013 * 3. attributes declarations and attribute uses:
21014 * - the type definition
21015 * - if an attribute use, then the attribute declaration
21016 * 4. attribute group references:
21017 * - the attribute group definition
21018 * 5. particles:
21019 * - the term of the particle (e.g. a model group)
21020 * 6. IDC key-references:
21021 * - the referenced IDC 'key' or 'unique' definition
21022 * 7. Attribute prohibitions which had a "ref" attribute.
21023 */
21024 for (i = 0; i < nbItems; i++) {
21025 item = items[i];
21026 switch (item->type) {
21027 case XML_SCHEMA_TYPE_ELEMENT:
21028 xmlSchemaResolveElementReferences(
21029 (xmlSchemaElementPtr) item, pctxt);
21030 FIXHFAILURE;
21031 break;
21032 case XML_SCHEMA_TYPE_COMPLEX:
21033 case XML_SCHEMA_TYPE_SIMPLE:
21034 xmlSchemaResolveTypeReferences(
21035 (xmlSchemaTypePtr) item, pctxt);
21036 FIXHFAILURE;
21037 break;
21038 case XML_SCHEMA_TYPE_ATTRIBUTE:
21039 xmlSchemaResolveAttrTypeReferences(
21040 (xmlSchemaAttributePtr) item, pctxt);
21041 FIXHFAILURE;
21042 break;
21043 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21044 xmlSchemaResolveAttrUseReferences(
21045 (xmlSchemaAttributeUsePtr) item, pctxt);
21046 FIXHFAILURE;
21047 break;
21048 case XML_SCHEMA_EXTRA_QNAMEREF:
21049 if ((WXS_QNAME_CAST item)->itemType ==
21050 XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
21051 {
21052 xmlSchemaResolveAttrGroupReferences(
21053 WXS_QNAME_CAST item, pctxt);
21054 }
21055 FIXHFAILURE;
21056 break;
21057 case XML_SCHEMA_TYPE_SEQUENCE:
21058 case XML_SCHEMA_TYPE_CHOICE:
21059 case XML_SCHEMA_TYPE_ALL:
21060 xmlSchemaResolveModelGroupParticleReferences(pctxt,
21061 WXS_MODEL_GROUP_CAST item);
21062 FIXHFAILURE;
21063 break;
21064 case XML_SCHEMA_TYPE_IDC_KEY:
21065 case XML_SCHEMA_TYPE_IDC_UNIQUE:
21066 case XML_SCHEMA_TYPE_IDC_KEYREF:
21067 xmlSchemaResolveIDCKeyReferences(
21068 (xmlSchemaIDCPtr) item, pctxt);
21069 FIXHFAILURE;
21070 break;
21071 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
21072 /*
21073 * Handle attribute prohibition which had a
21074 * "ref" attribute.
21075 */
21076 xmlSchemaResolveAttrUseProhibReferences(
21077 WXS_ATTR_PROHIB_CAST item, pctxt);
21078 FIXHFAILURE;
21079 break;
21080 default:
21081 break;
21082 }
21083 }
21084 if (pctxt->nberrors != 0)
21085 goto exit_error;
21086
21087 /*
21088 * Now that all references are resolved we
21089 * can check for circularity of...
21090 * 1. the base axis of type definitions
21091 * 2. nested model group definitions
21092 * 3. nested attribute group definitions
21093 * TODO: check for circular substitution groups.
21094 */
21095 for (i = 0; i < nbItems; i++) {
21096 item = items[i];
21097 /*
21098 * Let's better stop on the first error here.
21099 */
21100 switch (item->type) {
21101 case XML_SCHEMA_TYPE_COMPLEX:
21102 case XML_SCHEMA_TYPE_SIMPLE:
21103 xmlSchemaCheckTypeDefCircular(
21104 (xmlSchemaTypePtr) item, pctxt);
21105 FIXHFAILURE;
21106 if (pctxt->nberrors != 0)
21107 goto exit_error;
21108 break;
21109 case XML_SCHEMA_TYPE_GROUP:
21110 xmlSchemaCheckGroupDefCircular(
21111 (xmlSchemaModelGroupDefPtr) item, pctxt);
21112 FIXHFAILURE;
21113 if (pctxt->nberrors != 0)
21114 goto exit_error;
21115 break;
21116 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21117 xmlSchemaCheckAttrGroupCircular(
21118 (xmlSchemaAttributeGroupPtr) item, pctxt);
21119 FIXHFAILURE;
21120 if (pctxt->nberrors != 0)
21121 goto exit_error;
21122 break;
21123 default:
21124 break;
21125 }
21126 }
21127 if (pctxt->nberrors != 0)
21128 goto exit_error;
21129 /*
21130 * Model group definition references:
21131 * Such a reference is reflected by a particle at the component
21132 * level. Until now the 'term' of such particles pointed
21133 * to the model group definition; this was done, in order to
21134 * ease circularity checks. Now we need to set the 'term' of
21135 * such particles to the model group of the model group definition.
21136 */
21137 for (i = 0; i < nbItems; i++) {
21138 item = items[i];
21139 switch (item->type) {
21140 case XML_SCHEMA_TYPE_SEQUENCE:
21141 case XML_SCHEMA_TYPE_CHOICE:
21142 xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
21143 WXS_MODEL_GROUP_CAST item);
21144 break;
21145 default:
21146 break;
21147 }
21148 }
21149 if (pctxt->nberrors != 0)
21150 goto exit_error;
21151 /*
21152 * Expand attribute group references of attribute group definitions.
21153 */
21154 for (i = 0; i < nbItems; i++) {
21155 item = items[i];
21156 switch (item->type) {
21157 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21158 if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
21159 WXS_ATTR_GROUP_HAS_REFS(item))
21160 {
21161 xmlSchemaAttributeGroupExpandRefs(pctxt,
21162 WXS_ATTR_GROUP_CAST item);
21163 FIXHFAILURE;
21164 }
21165 break;
21166 default:
21167 break;
21168 }
21169 }
21170 if (pctxt->nberrors != 0)
21171 goto exit_error;
21172 /*
21173 * First compute the variety of simple types. This is needed as
21174 * a separate step, since otherwise we won't be able to detect
21175 * circular union types in all cases.
21176 */
21177 for (i = 0; i < nbItems; i++) {
21178 item = items[i];
21179 switch (item->type) {
21180 case XML_SCHEMA_TYPE_SIMPLE:
21181 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
21182 xmlSchemaFixupSimpleTypeStageOne(pctxt,
21183 (xmlSchemaTypePtr) item);
21184 FIXHFAILURE;
21185 }
21186 break;
21187 default:
21188 break;
21189 }
21190 }
21191 if (pctxt->nberrors != 0)
21192 goto exit_error;
21193 /*
21194 * Detect circular union types. Note that this needs the variety to
21195 * be already computed.
21196 */
21197 for (i = 0; i < nbItems; i++) {
21198 item = items[i];
21199 switch (item->type) {
21200 case XML_SCHEMA_TYPE_SIMPLE:
21201 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21202 xmlSchemaCheckUnionTypeDefCircular(pctxt,
21203 (xmlSchemaTypePtr) item);
21204 FIXHFAILURE;
21205 }
21206 break;
21207 default:
21208 break;
21209 }
21210 }
21211 if (pctxt->nberrors != 0)
21212 goto exit_error;
21213
21214 /*
21215 * Do the complete type fixup for simple types.
21216 */
21217 for (i = 0; i < nbItems; i++) {
21218 item = items[i];
21219 switch (item->type) {
21220 case XML_SCHEMA_TYPE_SIMPLE:
21221 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21222 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21223 FIXHFAILURE;
21224 }
21225 break;
21226 default:
21227 break;
21228 }
21229 }
21230 if (pctxt->nberrors != 0)
21231 goto exit_error;
21232 /*
21233 * At this point we need build and check all simple types.
21234 */
21235 /*
21236 * Apply constraints for attribute declarations.
21237 */
21238 for (i = 0; i < nbItems; i++) {
21239 item = items[i];
21240 switch (item->type) {
21241 case XML_SCHEMA_TYPE_ATTRIBUTE:
21242 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21243 FIXHFAILURE;
21244 break;
21245 default:
21246 break;
21247 }
21248 }
21249 if (pctxt->nberrors != 0)
21250 goto exit_error;
21251 /*
21252 * Apply constraints for attribute uses.
21253 */
21254 for (i = 0; i < nbItems; i++) {
21255 item = items[i];
21256 switch (item->type) {
21257 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21258 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21259 xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21260 WXS_ATTR_USE_CAST item);
21261 FIXHFAILURE;
21262 }
21263 break;
21264 default:
21265 break;
21266 }
21267 }
21268 if (pctxt->nberrors != 0)
21269 goto exit_error;
21270
21271 /*
21272 * Apply constraints for attribute group definitions.
21273 */
21274 for (i = 0; i < nbItems; i++) {
21275 item = items[i];
21276 switch (item->type) {
21277 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21278 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21279 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21280 {
21281 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21282 FIXHFAILURE;
21283 }
21284 break;
21285 default:
21286 break;
21287 }
21288 }
21289 if (pctxt->nberrors != 0)
21290 goto exit_error;
21291
21292 /*
21293 * Apply constraints for redefinitions.
21294 */
21295 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21296 xmlSchemaCheckSRCRedefineSecond(pctxt);
21297 if (pctxt->nberrors != 0)
21298 goto exit_error;
21299
21300 /*
21301 * Complex types are built and checked.
21302 */
21303 for (i = 0; i < nbItems; i++) {
21304 item = con->pending->items[i];
21305 switch (item->type) {
21306 case XML_SCHEMA_TYPE_COMPLEX:
21307 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21308 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21309 FIXHFAILURE;
21310 }
21311 break;
21312 default:
21313 break;
21314 }
21315 }
21316 if (pctxt->nberrors != 0)
21317 goto exit_error;
21318
21319 /*
21320 * The list could have changed, since xmlSchemaFixupComplexType()
21321 * will create particles and model groups in some cases.
21322 */
21323 items = (xmlSchemaTreeItemPtr *) con->pending->items;
21324 nbItems = con->pending->nbItems;
21325
21326 /*
21327 * Apply some constraints for element declarations.
21328 */
21329 for (i = 0; i < nbItems; i++) {
21330 item = items[i];
21331 switch (item->type) {
21332 case XML_SCHEMA_TYPE_ELEMENT:
21333 elemDecl = (xmlSchemaElementPtr) item;
21334
21335 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21336 {
21337 xmlSchemaCheckElementDeclComponent(
21338 (xmlSchemaElementPtr) elemDecl, pctxt);
21339 FIXHFAILURE;
21340 }
21341
21342#ifdef WXS_ELEM_DECL_CONS_ENABLED
21343 /*
21344 * Schema Component Constraint: Element Declarations Consistent
21345 * Apply this constraint to local types of element declarations.
21346 */
21347 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21348 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21349 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21350 {
21351 xmlSchemaCheckElementDeclConsistent(pctxt,
21352 WXS_BASIC_CAST elemDecl,
21353 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21354 NULL, NULL, 0);
21355 }
21356#endif
21357 break;
21358 default:
21359 break;
21360 }
21361 }
21362 if (pctxt->nberrors != 0)
21363 goto exit_error;
21364
21365 /*
21366 * Finally we can build the automaton from the content model of
21367 * complex types.
21368 */
21369
21370 for (i = 0; i < nbItems; i++) {
21371 item = items[i];
21372 switch (item->type) {
21373 case XML_SCHEMA_TYPE_COMPLEX:
21374 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21375 /* FIXHFAILURE; */
21376 break;
21377 default:
21378 break;
21379 }
21380 }
21381 if (pctxt->nberrors != 0)
21382 goto exit_error;
21383 /*
21384 * URGENT TODO: cos-element-consistent
21385 */
21386 goto exit;
21387
21388exit_error:
21389 ret = pctxt->err;
21390 goto exit;
21391
21392exit_failure:
21393 ret = -1;
21394
21395exit:
21396 /*
21397 * Reset the constructor. This is needed for XSI acquisition, since
21398 * those items will be processed over and over again for every XSI
21399 * if not cleared here.
21400 */
21401 con->bucket = oldbucket;
21402 con->pending->nbItems = 0;
21403 if (con->substGroups != NULL) {
21404 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21405 con->substGroups = NULL;
21406 }
21407 if (con->redefs != NULL) {
21408 xmlSchemaRedefListFree(con->redefs);
21409 con->redefs = NULL;
21410 }
21411 return(ret);
21412}
21423xmlSchemaPtr
21424xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21425{
21426 xmlSchemaPtr mainSchema = NULL;
21427 xmlSchemaBucketPtr bucket = NULL;
21428 int res;
21429
21430 /*
21431 * This one is used if the schema to be parsed was specified via
21432 * the API; i.e. not automatically by the validated instance document.
21433 */
21434
21435 xmlSchemaInitTypes();
21436
21437 if (ctxt == NULL)
21438 return (NULL);
21439
21440 /* TODO: Init the context. Is this all we need?*/
21441 ctxt->nberrors = 0;
21442 ctxt->err = 0;
21443 ctxt->counter = 0;
21444
21445 /* Create the *main* schema. */
21446 mainSchema = xmlSchemaNewSchema(ctxt);
21447 if (mainSchema == NULL)
21448 goto exit_failure;
21449 /*
21450 * Create the schema constructor.
21451 */
21452 if (ctxt->constructor == NULL) {
21453 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21454 if (ctxt->constructor == NULL)
21455 return(NULL);
21456 /* Take ownership of the constructor to be able to free it. */
21457 ctxt->ownsConstructor = 1;
21458 }
21459 ctxt->constructor->mainSchema = mainSchema;
21460 /*
21461 * Locate and add the schema document.
21462 */
21463 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21464 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21465 NULL, NULL, &bucket);
21466 if (res == -1)
21467 goto exit_failure;
21468 if (res != 0)
21469 goto exit;
21470
21471 if (bucket == NULL) {
21472 /* TODO: Error code, actually we failed to *locate* the schema. */
21473 if (ctxt->URL)
21474 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21475 NULL, NULL,
21476 "Failed to locate the main schema resource at '%s'",
21477 ctxt->URL, NULL);
21478 else
21479 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21480 NULL, NULL,
21481 "Failed to locate the main schema resource",
21482 NULL, NULL);
21483 goto exit;
21484 }
21485 /* Then do the parsing for good. */
21486 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21487 goto exit_failure;
21488 if (ctxt->nberrors != 0)
21489 goto exit;
21490
21491 mainSchema->doc = bucket->doc;
21492 mainSchema->preserve = ctxt->preserve;
21493
21494 ctxt->schema = mainSchema;
21495
21496 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21497 goto exit_failure;
21498
21499 /*
21500 * TODO: This is not nice, since we cannot distinguish from the
21501 * result if there was an internal error or not.
21502 */
21503exit:
21504 if (ctxt->nberrors != 0) {
21505 if (mainSchema) {
21506 xmlSchemaFree(mainSchema);
21507 mainSchema = NULL;
21508 }
21509 if (ctxt->constructor) {
21510 xmlSchemaConstructionCtxtFree(ctxt->constructor);
21511 ctxt->constructor = NULL;
21512 ctxt->ownsConstructor = 0;
21513 }
21514 }
21515 ctxt->schema = NULL;
21516 return(mainSchema);
21517exit_failure:
21518 /*
21519 * Quite verbose, but should catch internal errors, which were
21520 * not communicated.
21521 */
21522 if (mainSchema) {
21523 xmlSchemaFree(mainSchema);
21524 mainSchema = NULL;
21525 }
21526 if (ctxt->constructor) {
21527 xmlSchemaConstructionCtxtFree(ctxt->constructor);
21528 ctxt->constructor = NULL;
21529 ctxt->ownsConstructor = 0;
21530 }
21531 PERROR_INT2("xmlSchemaParse",
21532 "An internal error occurred");
21533 ctxt->schema = NULL;
21534 return(NULL);
21535}
21536
21546void
21547xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21548 xmlSchemaValidityErrorFunc err,
21549 xmlSchemaValidityWarningFunc warn, void *ctx)
21550{
21551 if (ctxt == NULL)
21552 return;
21553 ctxt->error = err;
21554 ctxt->warning = warn;
21555 ctxt->errCtxt = ctx;
21556 if (ctxt->vctxt != NULL)
21557 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21558}
21559
21568void
21569xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21571 void *ctx)
21572{
21573 if (ctxt == NULL)
21574 return;
21575 ctxt->serror = serror;
21576 ctxt->errCtxt = ctx;
21577 if (ctxt->vctxt != NULL)
21578 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21579}
21580
21592int
21593xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21594 xmlSchemaValidityErrorFunc * err,
21595 xmlSchemaValidityWarningFunc * warn, void **ctx)
21596{
21597 if (ctxt == NULL)
21598 return(-1);
21599 if (err != NULL)
21600 *err = ctxt->error;
21601 if (warn != NULL)
21602 *warn = ctxt->warning;
21603 if (ctx != NULL)
21604 *ctx = ctxt->errCtxt;
21605 return(0);
21606}
21607
21617static const xmlChar *
21618xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21619{
21620 switch (type) {
21621 case XML_SCHEMA_FACET_PATTERN:
21622 return (BAD_CAST "pattern");
21623 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21624 return (BAD_CAST "maxExclusive");
21625 case XML_SCHEMA_FACET_MAXINCLUSIVE:
21626 return (BAD_CAST "maxInclusive");
21627 case XML_SCHEMA_FACET_MINEXCLUSIVE:
21628 return (BAD_CAST "minExclusive");
21629 case XML_SCHEMA_FACET_MININCLUSIVE:
21630 return (BAD_CAST "minInclusive");
21631 case XML_SCHEMA_FACET_WHITESPACE:
21632 return (BAD_CAST "whiteSpace");
21633 case XML_SCHEMA_FACET_ENUMERATION:
21634 return (BAD_CAST "enumeration");
21635 case XML_SCHEMA_FACET_LENGTH:
21636 return (BAD_CAST "length");
21637 case XML_SCHEMA_FACET_MAXLENGTH:
21638 return (BAD_CAST "maxLength");
21639 case XML_SCHEMA_FACET_MINLENGTH:
21640 return (BAD_CAST "minLength");
21641 case XML_SCHEMA_FACET_TOTALDIGITS:
21642 return (BAD_CAST "totalDigits");
21643 case XML_SCHEMA_FACET_FRACTIONDIGITS:
21644 return (BAD_CAST "fractionDigits");
21645 default:
21646 break;
21647 }
21648 return (BAD_CAST "Internal Error");
21649}
21650
21651static xmlSchemaWhitespaceValueType
21652xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21653{
21654 /*
21655 * The normalization type can be changed only for types which are derived
21656 * from xsd:string.
21657 */
21658 if (type->type == XML_SCHEMA_TYPE_BASIC) {
21659 /*
21660 * Note that we assume a whitespace of preserve for anySimpleType.
21661 */
21662 if ((type->builtInType == XML_SCHEMAS_STRING) ||
21663 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21664 return(XML_SCHEMA_WHITESPACE_PRESERVE);
21665 else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21666 return(XML_SCHEMA_WHITESPACE_REPLACE);
21667 else {
21668 /*
21669 * For all `atomic` datatypes other than string (and types `derived`
21670 * by `restriction` from it) the value of whiteSpace is fixed to
21671 * collapse
21672 * Note that this includes built-in list datatypes.
21673 */
21674 return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21675 }
21676 } else if (WXS_IS_LIST(type)) {
21677 /*
21678 * For list types the facet "whiteSpace" is fixed to "collapse".
21679 */
21680 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21681 } else if (WXS_IS_UNION(type)) {
21682 return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21683 } else if (WXS_IS_ATOMIC(type)) {
21684 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21685 return (XML_SCHEMA_WHITESPACE_PRESERVE);
21686 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21687 return (XML_SCHEMA_WHITESPACE_REPLACE);
21688 else
21689 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21690 }
21691 return (-1);
21692}
21693
21694/************************************************************************
21695 * *
21696 * Simple type validation *
21697 * *
21698 ************************************************************************/
21699
21700
21701/************************************************************************
21702 * *
21703 * DOM Validation code *
21704 * *
21705 ************************************************************************/
21706
21721static int
21722xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21723 xmlSchemaPtr schema,
21725 const xmlChar *nsName,
21726 const xmlChar *location)
21727{
21728 int ret = 0;
21729 xmlSchemaParserCtxtPtr pctxt;
21730 xmlSchemaBucketPtr bucket = NULL;
21731
21732 if ((vctxt == NULL) || (schema == NULL))
21733 return (-1);
21734
21735 if (vctxt->pctxt == NULL) {
21736 VERROR_INT("xmlSchemaAssembleByLocation",
21737 "no parser context available");
21738 return(-1);
21739 }
21740 pctxt = vctxt->pctxt;
21741 if (pctxt->constructor == NULL) {
21742 PERROR_INT("xmlSchemaAssembleByLocation",
21743 "no constructor");
21744 return(-1);
21745 }
21746 /*
21747 * Acquire the schema document.
21748 */
21749 location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21750 location, node);
21751 /*
21752 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21753 * the process will automatically change this to
21754 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21755 */
21756 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21757 location, NULL, NULL, 0, node, NULL, nsName,
21758 &bucket);
21759 if (ret != 0)
21760 return(ret);
21761 if (bucket == NULL) {
21762 /*
21763 * Generate a warning that the document could not be located.
21764 */
21765 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21766 node, NULL,
21767 "The document at location '%s' could not be acquired",
21768 location, NULL, NULL);
21769 return(ret);
21770 }
21771 /*
21772 * The first located schema will be handled as if all other
21773 * schemas imported by XSI were imported by this first schema.
21774 */
21775 if ((bucket != NULL) &&
21776 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21777 WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21778 /*
21779 * TODO: Is this handled like an import? I.e. is it not an error
21780 * if the schema cannot be located?
21781 */
21782 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21783 return(0);
21784 /*
21785 * We will reuse the parser context for every schema imported
21786 * directly via XSI. So reset the context.
21787 */
21788 pctxt->nberrors = 0;
21789 pctxt->err = 0;
21790 pctxt->doc = bucket->doc;
21791
21792 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21793 if (ret == -1) {
21794 pctxt->doc = NULL;
21795 goto exit_failure;
21796 }
21797 /* Paranoid error channelling. */
21798 if ((ret == 0) && (pctxt->nberrors != 0))
21799 ret = pctxt->err;
21800 if (pctxt->nberrors == 0) {
21801 /*
21802 * Only bother to fixup pending components, if there was
21803 * no error yet.
21804 * For every XSI acquired schema (and its sub-schemata) we will
21805 * fixup the components.
21806 */
21807 xmlSchemaFixupComponents(pctxt, bucket);
21808 ret = pctxt->err;
21809 /*
21810 * Not nice, but we need somehow to channel the schema parser
21811 * error to the validation context.
21812 */
21813 if ((ret != 0) && (vctxt->err == 0))
21814 vctxt->err = ret;
21815 vctxt->nberrors += pctxt->nberrors;
21816 } else {
21817 /* Add to validation error sum. */
21818 vctxt->nberrors += pctxt->nberrors;
21819 }
21820 pctxt->doc = NULL;
21821 return(ret);
21822exit_failure:
21823 pctxt->doc = NULL;
21824 return (-1);
21825}
21826
21827static xmlSchemaAttrInfoPtr
21828xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21829 int metaType)
21830{
21831 if (vctxt->nbAttrInfos == 0)
21832 return (NULL);
21833 {
21834 int i;
21835 xmlSchemaAttrInfoPtr iattr;
21836
21837 for (i = 0; i < vctxt->nbAttrInfos; i++) {
21838 iattr = vctxt->attrInfos[i];
21839 if (iattr->metaType == metaType)
21840 return (iattr);
21841 }
21842
21843 }
21844 return (NULL);
21845}
21846
21859static int
21860xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21861{
21862 const xmlChar *cur, *end;
21863 const xmlChar *nsname = NULL, *location;
21864 int count = 0;
21865 int ret = 0;
21866 xmlSchemaAttrInfoPtr iattr;
21867
21868 /*
21869 * Parse the value; we will assume an even number of values
21870 * to be given (this is how Xerces and XSV work).
21871 *
21872 * URGENT TODO: !! This needs to work for both
21873 * @noNamespaceSchemaLocation AND @schemaLocation on the same
21874 * element !!
21875 */
21876 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21877 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21878 if (iattr == NULL)
21879 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21880 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21881 if (iattr == NULL)
21882 return (0);
21883 cur = iattr->value;
21884 do {
21885 /*
21886 * TODO: Move the string parsing mechanism away from here.
21887 */
21888 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21889 /*
21890 * Get the namespace name.
21891 */
21892 while (IS_BLANK_CH(*cur))
21893 cur++;
21894 end = cur;
21895 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21896 end++;
21897 if (end == cur)
21898 break;
21899 count++; /* TODO: Don't use the schema's dict. */
21900 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21901 cur = end;
21902 }
21903 /*
21904 * Get the URI.
21905 */
21906 while (IS_BLANK_CH(*cur))
21907 cur++;
21908 end = cur;
21909 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21910 end++;
21911 if (end == cur) {
21912 if (iattr->metaType ==
21913 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21914 {
21915 /*
21916 * If using @schemaLocation then tuples are expected.
21917 * I.e. the namespace name *and* the document's URI.
21918 */
21919 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21920 iattr->node, NULL,
21921 "The value must consist of tuples: the target namespace "
21922 "name and the document's URI", NULL, NULL, NULL);
21923 }
21924 break;
21925 }
21926 count++; /* TODO: Don't use the schema's dict. */
21927 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21928 cur = end;
21929 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21930 iattr->node, nsname, location);
21931 if (ret == -1) {
21932 VERROR_INT("xmlSchemaAssembleByXSI",
21933 "assembling schemata");
21934 return (-1);
21935 }
21936 } while (*cur != 0);
21937 return (ret);
21938}
21939
21940static const xmlChar *
21941xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21942 const xmlChar *prefix)
21943{
21944 if (vctxt->sax != NULL) {
21945 int i, j;
21946 xmlSchemaNodeInfoPtr inode;
21947
21948 for (i = vctxt->depth; i >= 0; i--) {
21949 if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21950 inode = vctxt->elemInfos[i];
21951 for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21952 if (((prefix == NULL) &&
21953 (inode->nsBindings[j] == NULL)) ||
21954 ((prefix != NULL) && xmlStrEqual(prefix,
21955 inode->nsBindings[j]))) {
21956
21957 /*
21958 * Note that the namespace bindings are already
21959 * in a string dict.
21960 */
21961 return (inode->nsBindings[j+1]);
21962 }
21963 }
21964 }
21965 }
21966 return (NULL);
21967#ifdef LIBXML_READER_ENABLED
21968 } else if (vctxt->reader != NULL) {
21969 xmlChar *nsName;
21970
21971 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21972 if (nsName != NULL) {
21973 const xmlChar *ret;
21974
21975 ret = xmlDictLookup(vctxt->dict, nsName, -1);
21976 xmlFree(nsName);
21977 return (ret);
21978 } else
21979 return (NULL);
21980#endif
21981 } else {
21982 xmlNsPtr ns;
21983
21984 if ((vctxt->inode->node == NULL) ||
21985 (vctxt->inode->node->doc == NULL)) {
21986 VERROR_INT("xmlSchemaLookupNamespace",
21987 "no node or node's doc available");
21988 return (NULL);
21989 }
21990 ns = xmlSearchNs(vctxt->inode->node->doc,
21991 vctxt->inode->node, prefix);
21992 if (ns != NULL)
21993 return (ns->href);
21994 return (NULL);
21995 }
21996}
21997
21998/*
21999* This one works on the schema of the validation context.
22000*/
22001static int
22002xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
22003 xmlSchemaPtr schema,
22005 const xmlChar *value,
22006 xmlSchemaValPtr *val,
22007 int valNeeded)
22008{
22009 int ret;
22010
22011 if (vctxt && (vctxt->schema == NULL)) {
22012 VERROR_INT("xmlSchemaValidateNotation",
22013 "a schema is needed on the validation context");
22014 return (-1);
22015 }
22016 ret = xmlValidateQName(value, 1);
22017 if (ret != 0)
22018 return (ret);
22019 {
22020 xmlChar *localName = NULL;
22021 xmlChar *prefix = NULL;
22022
22023 localName = xmlSplitQName2(value, &prefix);
22024 if (prefix != NULL) {
22025 const xmlChar *nsName = NULL;
22026
22027 if (vctxt != NULL)
22028 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
22029 else if (node != NULL) {
22030 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
22031 if (ns != NULL)
22032 nsName = ns->href;
22033 } else {
22034 xmlFree(prefix);
22035 xmlFree(localName);
22036 return (1);
22037 }
22038 if (nsName == NULL) {
22039 xmlFree(prefix);
22040 xmlFree(localName);
22041 return (1);
22042 }
22043 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
22044 if ((valNeeded) && (val != NULL)) {
22045 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
22046 xmlStrdup(nsName));
22047 if (*val == NULL)
22048 ret = -1;
22049 }
22050 } else
22051 ret = 1;
22052 xmlFree(prefix);
22053 xmlFree(localName);
22054 } else {
22055 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
22056 if (valNeeded && (val != NULL)) {
22057 (*val) = xmlSchemaNewNOTATIONValue(
22059 if (*val == NULL)
22060 ret = -1;
22061 }
22062 } else
22063 return (1);
22064 }
22065 }
22066 return (ret);
22067}
22068
22069static int
22070xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
22071 const xmlChar* lname,
22072 const xmlChar* nsname)
22073{
22074 int i;
22075
22076 lname = xmlDictLookup(vctxt->dict, lname, -1);
22077 if (lname == NULL)
22078 return(-1);
22079 if (nsname != NULL) {
22080 nsname = xmlDictLookup(vctxt->dict, nsname, -1);
22081 if (nsname == NULL)
22082 return(-1);
22083 }
22084 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
22085 if ((vctxt->nodeQNames->items [i] == lname) &&
22086 (vctxt->nodeQNames->items[i +1] == nsname))
22087 /* Already there */
22088 return(i);
22089 }
22090 /* Add new entry. */
22091 i = vctxt->nodeQNames->nbItems;
22092 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
22093 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
22094 return(i);
22095}
22096
22097/************************************************************************
22098 * *
22099 * Validation of identity-constraints (IDC) *
22100 * *
22101 ************************************************************************/
22102
22111static void
22112xmlSchemaAugmentIDC(void *payload, void *data,
22114{
22115 xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
22116 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
22117 xmlSchemaIDCAugPtr aidc;
22118
22119 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
22120 if (aidc == NULL) {
22121 xmlSchemaVErrMemory(vctxt,
22122 "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
22123 NULL);
22124 return;
22125 }
22126 aidc->keyrefDepth = -1;
22127 aidc->def = idcDef;
22128 aidc->next = NULL;
22129 if (vctxt->aidcs == NULL)
22130 vctxt->aidcs = aidc;
22131 else {
22132 aidc->next = vctxt->aidcs;
22133 vctxt->aidcs = aidc;
22134 }
22135 /*
22136 * Save if we have keyrefs at all.
22137 */
22138 if ((vctxt->hasKeyrefs == 0) &&
22139 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
22140 vctxt->hasKeyrefs = 1;
22141}
22142
22149static void
22150xmlSchemaAugmentImportedIDC(void *payload, void *data,
22151 const xmlChar *name ATTRIBUTE_UNUSED) {
22152 xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
22153 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
22154 if (imported->schema->idcDef != NULL) {
22155 xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
22156 }
22157}
22158
22167static xmlSchemaPSVIIDCBindingPtr
22168xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22169{
22170 xmlSchemaPSVIIDCBindingPtr ret;
22171
22172 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22173 sizeof(xmlSchemaPSVIIDCBinding));
22174 if (ret == NULL) {
22175 xmlSchemaVErrMemory(NULL,
22176 "allocating a PSVI IDC binding item", NULL);
22177 return (NULL);
22178 }
22179 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22180 ret->definition = idcDef;
22181 return (ret);
22182}
22183
22195static int
22196xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22197 xmlSchemaPSVIIDCNodePtr item)
22198{
22199 /*
22200 * Add to global list.
22201 */
22202 if (vctxt->idcNodes == NULL) {
22203 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22204 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22205 if (vctxt->idcNodes == NULL) {
22206 xmlSchemaVErrMemory(vctxt,
22207 "allocating the IDC node table item list", NULL);
22208 return (-1);
22209 }
22210 vctxt->sizeIdcNodes = 20;
22211 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22212 vctxt->sizeIdcNodes *= 2;
22213 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22214 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22215 sizeof(xmlSchemaPSVIIDCNodePtr));
22216 if (vctxt->idcNodes == NULL) {
22217 xmlSchemaVErrMemory(vctxt,
22218 "re-allocating the IDC node table item list", NULL);
22219 return (-1);
22220 }
22221 }
22222 vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22223
22224 return (0);
22225}
22226
22236static int
22237xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22238 xmlSchemaPSVIIDCKeyPtr key)
22239{
22240 /*
22241 * Add to global list.
22242 */
22243 if (vctxt->idcKeys == NULL) {
22244 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22245 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22246 if (vctxt->idcKeys == NULL) {
22247 xmlSchemaVErrMemory(vctxt,
22248 "allocating the IDC key storage list", NULL);
22249 return (-1);
22250 }
22251 vctxt->sizeIdcKeys = 40;
22252 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22253 vctxt->sizeIdcKeys *= 2;
22254 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22255 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22256 sizeof(xmlSchemaPSVIIDCKeyPtr));
22257 if (vctxt->idcKeys == NULL) {
22258 xmlSchemaVErrMemory(vctxt,
22259 "re-allocating the IDC key storage list", NULL);
22260 return (-1);
22261 }
22262 }
22263 vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22264
22265 return (0);
22266}
22267
22277static int
22278xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22279 xmlSchemaPSVIIDCNodePtr ntItem)
22280{
22281 if (bind->nodeTable == NULL) {
22282 bind->sizeNodes = 10;
22283 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22284 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22285 if (bind->nodeTable == NULL) {
22286 xmlSchemaVErrMemory(NULL,
22287 "allocating an array of IDC node-table items", NULL);
22288 return(-1);
22289 }
22290 } else if (bind->sizeNodes <= bind->nbNodes) {
22291 bind->sizeNodes *= 2;
22292 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22293 xmlRealloc(bind->nodeTable, bind->sizeNodes *
22294 sizeof(xmlSchemaPSVIIDCNodePtr));
22295 if (bind->nodeTable == NULL) {
22296 xmlSchemaVErrMemory(NULL,
22297 "re-allocating an array of IDC node-table items", NULL);
22298 return(-1);
22299 }
22300 }
22301 bind->nodeTable[bind->nbNodes++] = ntItem;
22302 return(0);
22303}
22304
22316static xmlSchemaPSVIIDCBindingPtr
22317xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22318 xmlSchemaIDCMatcherPtr matcher)
22319{
22320 xmlSchemaNodeInfoPtr ielem;
22321
22322 ielem = vctxt->elemInfos[matcher->depth];
22323
22324 if (ielem->idcTable == NULL) {
22325 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22326 if (ielem->idcTable == NULL)
22327 return (NULL);
22328 return(ielem->idcTable);
22329 } else {
22330 xmlSchemaPSVIIDCBindingPtr bind = NULL;
22331
22332 bind = ielem->idcTable;
22333 do {
22334 if (bind->definition == matcher->aidc->def)
22335 return(bind);
22336 if (bind->next == NULL) {
22337 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22338 if (bind->next == NULL)
22339 return (NULL);
22340 return(bind->next);
22341 }
22342 bind = bind->next;
22343 } while (bind != NULL);
22344 }
22345 return (NULL);
22346}
22347
22348static xmlSchemaItemListPtr
22349xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22350 xmlSchemaIDCMatcherPtr matcher)
22351{
22352 if (matcher->targets == NULL)
22353 matcher->targets = xmlSchemaItemListCreate();
22354 return(matcher->targets);
22355}
22356
22363static void
22364xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22365{
22366 if (key->val != NULL)
22367 xmlSchemaFreeValue(key->val);
22368 xmlFree(key);
22369}
22370
22377static void
22378xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22379{
22380 if (bind->nodeTable != NULL)
22381 xmlFree(bind->nodeTable);
22382 if (bind->dupls != NULL)
22383 xmlSchemaItemListFree(bind->dupls);
22384 xmlFree(bind);
22385}
22386
22393static void
22394xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22395{
22396 xmlSchemaPSVIIDCBindingPtr prev;
22397
22398 while (bind != NULL) {
22399 prev = bind;
22400 bind = bind->next;
22401 xmlSchemaIDCFreeBinding(prev);
22402 }
22403}
22404
22405static void
22406xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
22407{
22408 xmlIDCHashEntryPtr e = payload, n;
22409 while (e) {
22410 n = e->next;
22411 xmlFree(e);
22412 e = n;
22413 }
22414}
22415
22422static void
22423xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22424{
22425 xmlSchemaIDCMatcherPtr next;
22426
22427 while (matcher != NULL) {
22428 next = matcher->next;
22429 if (matcher->keySeqs != NULL) {
22430 int i;
22431 for (i = 0; i < matcher->sizeKeySeqs; i++)
22432 if (matcher->keySeqs[i] != NULL)
22433 xmlFree(matcher->keySeqs[i]);
22434 xmlFree(matcher->keySeqs);
22435 }
22436 if (matcher->targets != NULL) {
22437 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22438 int i;
22439 xmlSchemaPSVIIDCNodePtr idcNode;
22440 /*
22441 * Node-table items for keyrefs are not stored globally
22442 * to the validation context, since they are not bubbled.
22443 * We need to free them here.
22444 */
22445 for (i = 0; i < matcher->targets->nbItems; i++) {
22446 idcNode =
22447 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22448 xmlFree(idcNode->keys);
22449 xmlFree(idcNode);
22450 }
22451 }
22452 xmlSchemaItemListFree(matcher->targets);
22453 }
22454 if (matcher->htab != NULL)
22455 xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22456 xmlFree(matcher);
22457 matcher = next;
22458 }
22459}
22460
22468static void
22469xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22470 xmlSchemaIDCMatcherPtr matcher)
22471{
22472 xmlSchemaIDCMatcherPtr next;
22473
22474 while (matcher != NULL) {
22475 next = matcher->next;
22476 if (matcher->keySeqs != NULL) {
22477 int i;
22478 /*
22479 * Don't free the array, but only the content.
22480 */
22481 for (i = 0; i < matcher->sizeKeySeqs; i++)
22482 if (matcher->keySeqs[i] != NULL) {
22483 xmlFree(matcher->keySeqs[i]);
22484 matcher->keySeqs[i] = NULL;
22485 }
22486 }
22487 if (matcher->targets) {
22488 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22489 int i;
22490 xmlSchemaPSVIIDCNodePtr idcNode;
22491 /*
22492 * Node-table items for keyrefs are not stored globally
22493 * to the validation context, since they are not bubbled.
22494 * We need to free them here.
22495 */
22496 for (i = 0; i < matcher->targets->nbItems; i++) {
22497 idcNode =
22498 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22499 xmlFree(idcNode->keys);
22500 xmlFree(idcNode);
22501 }
22502 }
22503 xmlSchemaItemListFree(matcher->targets);
22504 matcher->targets = NULL;
22505 }
22506 if (matcher->htab != NULL) {
22507 xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22508 matcher->htab = NULL;
22509 }
22510 matcher->next = NULL;
22511 /*
22512 * Cache the matcher.
22513 */
22514 if (vctxt->idcMatcherCache != NULL)
22515 matcher->nextCached = vctxt->idcMatcherCache;
22516 vctxt->idcMatcherCache = matcher;
22517
22518 matcher = next;
22519 }
22520}
22521
22536static int
22537xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22538 xmlSchemaIDCMatcherPtr matcher,
22539 xmlSchemaIDCSelectPtr sel,
22540 int type)
22541{
22542 xmlSchemaIDCStateObjPtr sto;
22543
22544 /*
22545 * Reuse the state objects from the pool.
22546 */
22547 if (vctxt->xpathStatePool != NULL) {
22548 sto = vctxt->xpathStatePool;
22549 vctxt->xpathStatePool = sto->next;
22550 sto->next = NULL;
22551 } else {
22552 /*
22553 * Create a new state object.
22554 */
22555 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22556 if (sto == NULL) {
22557 xmlSchemaVErrMemory(NULL,
22558 "allocating an IDC state object", NULL);
22559 return (-1);
22560 }
22561 memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22562 }
22563 /*
22564 * Add to global list.
22565 */
22566 if (vctxt->xpathStates != NULL)
22567 sto->next = vctxt->xpathStates;
22568 vctxt->xpathStates = sto;
22569
22570 /*
22571 * Free the old xpath validation context.
22572 */
22573 if (sto->xpathCtxt != NULL)
22574 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22575
22576 /*
22577 * Create a new XPath (pattern) validation context.
22578 */
22579 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22580 (xmlPatternPtr) sel->xpathComp);
22581 if (sto->xpathCtxt == NULL) {
22582 VERROR_INT("xmlSchemaIDCAddStateObject",
22583 "failed to create an XPath validation context");
22584 return (-1);
22585 }
22586 sto->type = type;
22587 sto->depth = vctxt->depth;
22588 sto->matcher = matcher;
22589 sto->sel = sel;
22590 sto->nbHistory = 0;
22591
22592#ifdef DEBUG_IDC
22593 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
22594 sto->sel->xpath);
22595#endif
22596 return (0);
22597}
22598
22609static int
22610xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22611 xmlElementType nodeType)
22612{
22613 xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22614 int res, resolved = 0, depth = vctxt->depth;
22615
22616 if (vctxt->xpathStates == NULL)
22617 return (0);
22618
22619 if (nodeType == XML_ATTRIBUTE_NODE)
22620 depth++;
22621#ifdef DEBUG_IDC
22622 {
22623 xmlChar *str = NULL;
22625 "IDC: EVAL on %s, depth %d, type %d\n",
22626 xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22627 vctxt->inode->localName), depth, nodeType);
22628 FREE_AND_NULL(str)
22629 }
22630#endif
22631 /*
22632 * Process all active XPath state objects.
22633 */
22634 first = vctxt->xpathStates;
22635 sto = first;
22636 while (sto != head) {
22637#ifdef DEBUG_IDC
22638 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22639 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
22640 sto->matcher->aidc->def->name, sto->sel->xpath);
22641 else
22642 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
22643 sto->matcher->aidc->def->name, sto->sel->xpath);
22644#endif
22645 if (nodeType == XML_ELEMENT_NODE)
22646 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22647 vctxt->inode->localName, vctxt->inode->nsName);
22648 else
22649 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22650 vctxt->inode->localName, vctxt->inode->nsName);
22651
22652 if (res == -1) {
22653 VERROR_INT("xmlSchemaXPathEvaluate",
22654 "calling xmlStreamPush()");
22655 return (-1);
22656 }
22657 if (res == 0)
22658 goto next_sto;
22659 /*
22660 * Full match.
22661 */
22662#ifdef DEBUG_IDC
22664 "MATCH\n");
22665#endif
22666 /*
22667 * Register a match in the state object history.
22668 */
22669 if (sto->history == NULL) {
22670 sto->history = (int *) xmlMalloc(5 * sizeof(int));
22671 if (sto->history == NULL) {
22672 xmlSchemaVErrMemory(NULL,
22673 "allocating the state object history", NULL);
22674 return(-1);
22675 }
22676 sto->sizeHistory = 5;
22677 } else if (sto->sizeHistory <= sto->nbHistory) {
22678 sto->sizeHistory *= 2;
22679 sto->history = (int *) xmlRealloc(sto->history,
22680 sto->sizeHistory * sizeof(int));
22681 if (sto->history == NULL) {
22682 xmlSchemaVErrMemory(NULL,
22683 "re-allocating the state object history", NULL);
22684 return(-1);
22685 }
22686 }
22687 sto->history[sto->nbHistory++] = depth;
22688
22689#ifdef DEBUG_IDC
22690 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
22691 vctxt->depth);
22692#endif
22693
22694 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22695 xmlSchemaIDCSelectPtr sel;
22696 /*
22697 * Activate state objects for the IDC fields of
22698 * the IDC selector.
22699 */
22700#ifdef DEBUG_IDC
22702 "activating field states\n");
22703#endif
22704 sel = sto->matcher->aidc->def->fields;
22705 while (sel != NULL) {
22706 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22707 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22708 return (-1);
22709 sel = sel->next;
22710 }
22711 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22712 /*
22713 * An IDC key node was found by the IDC field.
22714 */
22715#ifdef DEBUG_IDC
22717 "IDC: key found\n");
22718#endif
22719 /*
22720 * Notify that the character value of this node is
22721 * needed.
22722 */
22723 if (resolved == 0) {
22724 if ((vctxt->inode->flags &
22725 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22726 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22727 }
22728 resolved++;
22729 }
22730next_sto:
22731 if (sto->next == NULL) {
22732 /*
22733 * Evaluate field state objects created on this node as well.
22734 */
22735 head = first;
22736 sto = vctxt->xpathStates;
22737 } else
22738 sto = sto->next;
22739 }
22740 return (resolved);
22741}
22742
22743static const xmlChar *
22744xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22745 xmlChar **buf,
22746 xmlSchemaPSVIIDCKeyPtr *seq,
22747 int count, int for_hash)
22748{
22749 int i, res;
22750 xmlChar *value = NULL;
22751
22752 *buf = xmlStrdup(BAD_CAST "[");
22753 for (i = 0; i < count; i++) {
22754 *buf = xmlStrcat(*buf, BAD_CAST "'");
22755 if (!for_hash)
22756 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22757 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22758 &value);
22759 else {
22760 res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22761 }
22762 if (res == 0)
22764 else {
22765 VERROR_INT("xmlSchemaFormatIDCKeySequence",
22766 "failed to compute a canonical value");
22767 *buf = xmlStrcat(*buf, BAD_CAST "???");
22768 }
22769 if (i < count -1)
22770 *buf = xmlStrcat(*buf, BAD_CAST "', ");
22771 else
22772 *buf = xmlStrcat(*buf, BAD_CAST "'");
22773 if (value != NULL) {
22774 xmlFree(value);
22775 value = NULL;
22776 }
22777 }
22778 *buf = xmlStrcat(*buf, BAD_CAST "]");
22779
22780 return (BAD_CAST *buf);
22781}
22782
22783static const xmlChar *
22784xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22785 xmlChar **buf,
22786 xmlSchemaPSVIIDCKeyPtr *seq,
22787 int count)
22788{
22789 return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22790}
22791
22792static const xmlChar *
22793xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22794 xmlChar **buf,
22795 xmlSchemaPSVIIDCKeyPtr *seq,
22796 int count)
22797{
22798 return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22799}
22800
22809static int
22810xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22811{
22812 xmlSchemaIDCStateObjPtr sto;
22813 int res;
22814
22815 if (vctxt->xpathStates == NULL)
22816 return(0);
22817 sto = vctxt->xpathStates;
22818 do {
22819 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22820 if (res == -1)
22821 return (-1);
22822 sto = sto->next;
22823 } while (sto != NULL);
22824 return(0);
22825}
22826
22838static int
22839xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22840 int depth)
22841{
22842 xmlSchemaIDCStateObjPtr sto, nextsto;
22843 int res, matchDepth;
22844 xmlSchemaPSVIIDCKeyPtr key = NULL;
22845 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22846
22847 if (vctxt->xpathStates == NULL)
22848 return (0);
22849 sto = vctxt->xpathStates;
22850
22851#ifdef DEBUG_IDC
22852 {
22853 xmlChar *str = NULL;
22855 "IDC: BACK on %s, depth %d\n",
22856 xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22857 vctxt->inode->localName), vctxt->depth);
22858 FREE_AND_NULL(str)
22859 }
22860#endif
22861 /*
22862 * Evaluate the state objects.
22863 */
22864 while (sto != NULL) {
22865 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22866 if (res == -1) {
22867 VERROR_INT("xmlSchemaXPathProcessHistory",
22868 "calling xmlStreamPop()");
22869 return (-1);
22870 }
22871#ifdef DEBUG_IDC
22872 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
22873 sto->sel->xpath);
22874#endif
22875 if (sto->nbHistory == 0)
22876 goto deregister_check;
22877
22878 matchDepth = sto->history[sto->nbHistory -1];
22879
22880 /*
22881 * Only matches at the current depth are of interest.
22882 */
22883 if (matchDepth != depth) {
22884 sto = sto->next;
22885 continue;
22886 }
22887 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22888 /*
22889 * NOTE: According to
22890 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22891 * ... the simple-content of complex types is also allowed.
22892 */
22893
22894 if (WXS_IS_COMPLEX(type)) {
22895 if (WXS_HAS_SIMPLE_CONTENT(type)) {
22896 /*
22897 * Sanity check for complex types with simple content.
22898 */
22899 simpleType = type->contentTypeDef;
22900 if (simpleType == NULL) {
22901 VERROR_INT("xmlSchemaXPathProcessHistory",
22902 "field resolves to a CT with simple content "
22903 "but the CT is missing the ST definition");
22904 return (-1);
22905 }
22906 } else
22907 simpleType = NULL;
22908 } else
22909 simpleType = type;
22910 if (simpleType == NULL) {
22911 xmlChar *str = NULL;
22912
22913 /*
22914 * Not qualified if the field resolves to a node of non
22915 * simple type.
22916 */
22917 xmlSchemaCustomErr(ACTXT_CAST vctxt,
22919 WXS_BASIC_CAST sto->matcher->aidc->def,
22920 "The XPath '%s' of a field of %s does evaluate to a node of "
22921 "non-simple type",
22922 sto->sel->xpath,
22923 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22924 FREE_AND_NULL(str);
22925 sto->nbHistory--;
22926 goto deregister_check;
22927 }
22928
22929 if ((key == NULL) && (vctxt->inode->val == NULL)) {
22930 /*
22931 * Failed to provide the normalized value; maybe
22932 * the value was invalid.
22933 */
22934 VERROR(XML_SCHEMAV_CVC_IDC,
22935 WXS_BASIC_CAST sto->matcher->aidc->def,
22936 "Warning: No precomputed value available, the value "
22937 "was either invalid or something strange happened");
22938 sto->nbHistory--;
22939 goto deregister_check;
22940 } else {
22941 xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22942 xmlSchemaPSVIIDCKeyPtr *keySeq;
22943 int pos, idx;
22944
22945 /*
22946 * The key will be anchored on the matcher's list of
22947 * key-sequences. The position in this list is determined
22948 * by the target node's depth relative to the matcher's
22949 * depth of creation (i.e. the depth of the scope element).
22950 *
22951 * Element Depth Pos List-entries
22952 * <scope> 0 NULL
22953 * <bar> 1 NULL
22954 * <target/> 2 2 target
22955 * <bar>
22956 * </scope>
22957 *
22958 * The size of the list is only dependent on the depth of
22959 * the tree.
22960 * An entry will be NULLed in selector_leave, i.e. when
22961 * we hit the target's
22962 */
22963 pos = sto->depth - matcher->depth;
22964 idx = sto->sel->index;
22965
22966 /*
22967 * Create/grow the array of key-sequences.
22968 */
22969 if (matcher->keySeqs == NULL) {
22970 if (pos > 9)
22971 matcher->sizeKeySeqs = pos * 2;
22972 else
22973 matcher->sizeKeySeqs = 10;
22974 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22975 xmlMalloc(matcher->sizeKeySeqs *
22976 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22977 if (matcher->keySeqs == NULL) {
22978 xmlSchemaVErrMemory(NULL,
22979 "allocating an array of key-sequences",
22980 NULL);
22981 return(-1);
22982 }
22983 memset(matcher->keySeqs, 0,
22984 matcher->sizeKeySeqs *
22985 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22986 } else if (pos >= matcher->sizeKeySeqs) {
22987 int i = matcher->sizeKeySeqs;
22988
22989 matcher->sizeKeySeqs *= 2;
22990 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22991 xmlRealloc(matcher->keySeqs,
22992 matcher->sizeKeySeqs *
22993 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22994 if (matcher->keySeqs == NULL) {
22995 xmlSchemaVErrMemory(NULL,
22996 "reallocating an array of key-sequences",
22997 NULL);
22998 return (-1);
22999 }
23000 /*
23001 * The array needs to be NULLed.
23002 * TODO: Use memset?
23003 */
23004 for (; i < matcher->sizeKeySeqs; i++)
23005 matcher->keySeqs[i] = NULL;
23006 }
23007
23008 /*
23009 * Get/create the key-sequence.
23010 */
23011 keySeq = matcher->keySeqs[pos];
23012 if (keySeq == NULL) {
23013 goto create_sequence;
23014 } else if (keySeq[idx] != NULL) {
23015 xmlChar *str = NULL;
23016 /*
23017 * cvc-identity-constraint:
23018 * 3 For each node in the `target node set` all
23019 * of the {fields}, with that node as the context
23020 * node, evaluate to either an empty node-set or
23021 * a node-set with exactly one member, which must
23022 * have a simple type.
23023 *
23024 * The key was already set; report an error.
23025 */
23026 xmlSchemaCustomErr(ACTXT_CAST vctxt,
23028 WXS_BASIC_CAST matcher->aidc->def,
23029 "The XPath '%s' of a field of %s evaluates to a "
23030 "node-set with more than one member",
23031 sto->sel->xpath,
23032 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
23033 FREE_AND_NULL(str);
23034 sto->nbHistory--;
23035 goto deregister_check;
23036 } else
23037 goto create_key;
23038
23039create_sequence:
23040 /*
23041 * Create a key-sequence.
23042 */
23043 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
23044 matcher->aidc->def->nbFields *
23045 sizeof(xmlSchemaPSVIIDCKeyPtr));
23046 if (keySeq == NULL) {
23047 xmlSchemaVErrMemory(NULL,
23048 "allocating an IDC key-sequence", NULL);
23049 return(-1);
23050 }
23051 memset(keySeq, 0, matcher->aidc->def->nbFields *
23052 sizeof(xmlSchemaPSVIIDCKeyPtr));
23053 matcher->keySeqs[pos] = keySeq;
23055 /*
23056 * Create a key once per node only.
23057 */
23058 if (key == NULL) {
23059 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
23060 sizeof(xmlSchemaPSVIIDCKey));
23061 if (key == NULL) {
23062 xmlSchemaVErrMemory(NULL,
23063 "allocating a IDC key", NULL);
23064 xmlFree(keySeq);
23065 matcher->keySeqs[pos] = NULL;
23066 return(-1);
23067 }
23068 /*
23069 * Consume the compiled value.
23070 */
23071 key->type = simpleType;
23072 key->val = vctxt->inode->val;
23073 vctxt->inode->val = NULL;
23074 /*
23075 * Store the key in a global list.
23076 */
23077 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
23078 xmlSchemaIDCFreeKey(key);
23079 return (-1);
23080 }
23081 }
23082 keySeq[idx] = key;
23083 }
23084 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
23085
23086 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
23087 /* xmlSchemaPSVIIDCBindingPtr bind; */
23088 xmlSchemaPSVIIDCNodePtr ntItem;
23089 xmlSchemaIDCMatcherPtr matcher;
23090 xmlSchemaIDCPtr idc;
23091 xmlSchemaItemListPtr targets;
23092 int pos, i, j, nbKeys;
23093 /*
23094 * Here we have the following scenario:
23095 * An IDC 'selector' state object resolved to a target node,
23096 * during the time this target node was in the
23097 * ancestor-or-self axis, the 'field' state object(s) looked
23098 * out for matching nodes to create a key-sequence for this
23099 * target node. Now we are back to this target node and need
23100 * to put the key-sequence, together with the target node
23101 * itself, into the node-table of the corresponding IDC
23102 * binding.
23103 */
23104 matcher = sto->matcher;
23105 idc = matcher->aidc->def;
23106 nbKeys = idc->nbFields;
23107 pos = depth - matcher->depth;
23108 /*
23109 * Check if the matcher has any key-sequences at all, plus
23110 * if it has a key-sequence for the current target node.
23111 */
23112 if ((matcher->keySeqs == NULL) ||
23113 (matcher->sizeKeySeqs <= pos)) {
23114 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
23115 goto selector_key_error;
23116 else
23117 goto selector_leave;
23118 }
23119
23120 keySeq = &(matcher->keySeqs[pos]);
23121 if (*keySeq == NULL) {
23122 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
23123 goto selector_key_error;
23124 else
23125 goto selector_leave;
23126 }
23127
23128 for (i = 0; i < nbKeys; i++) {
23129 if ((*keySeq)[i] == NULL) {
23130 /*
23131 * Not qualified, if not all fields did resolve.
23132 */
23133 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
23134 /*
23135 * All fields of a "key" IDC must resolve.
23136 */
23137 goto selector_key_error;
23138 }
23139 goto selector_leave;
23140 }
23141 }
23142 /*
23143 * All fields did resolve.
23144 */
23145
23146 /*
23147 * 4.1 If the {identity-constraint category} is unique(/key),
23148 * then no two members of the `qualified node set` have
23149 * `key-sequences` whose members are pairwise equal, as
23150 * defined by Equal in [XML Schemas: Datatypes].
23151 *
23152 * Get the IDC binding from the matcher and check for
23153 * duplicate key-sequences.
23154 */
23155#if 0
23156 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23157#endif
23158 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
23159 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
23160 (targets->nbItems != 0)) {
23161 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
23162 xmlIDCHashEntryPtr e;
23163
23164 res = 0;
23165
23166 if (!matcher->htab)
23167 e = NULL;
23168 else {
23169 xmlChar *value = NULL;
23170 xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
23171 e = xmlHashLookup(matcher->htab, value);
23172 FREE_AND_NULL(value);
23173 }
23174
23175 /*
23176 * Compare the key-sequences, key by key.
23177 */
23178 for (;e; e = e->next) {
23179 bkeySeq =
23180 ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
23181 for (j = 0; j < nbKeys; j++) {
23182 ckey = (*keySeq)[j];
23183 bkey = bkeySeq[j];
23184 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
23185 if (res == -1) {
23186 return (-1);
23187 } else if (res == 0) {
23188 /*
23189 * One of the keys differs, so the key-sequence
23190 * won't be equal; get out.
23191 */
23192 break;
23193 }
23194 }
23195 if (res == 1) {
23196 /*
23197 * Duplicate key-sequence found.
23198 */
23199 break;
23200 }
23201 }
23202 if (e) {
23203 xmlChar *str = NULL, *strB = NULL;
23204 /*
23205 * TODO: Try to report the key-sequence.
23206 */
23207 xmlSchemaCustomErr(ACTXT_CAST vctxt,
23209 WXS_BASIC_CAST idc,
23210 "Duplicate key-sequence %s in %s",
23211 xmlSchemaFormatIDCKeySequence(vctxt, &str,
23212 (*keySeq), nbKeys),
23213 xmlSchemaGetIDCDesignation(&strB, idc));
23214 FREE_AND_NULL(str);
23215 FREE_AND_NULL(strB);
23216 goto selector_leave;
23217 }
23218 }
23219 /*
23220 * Add a node-table item to the IDC binding.
23221 */
23222 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
23223 sizeof(xmlSchemaPSVIIDCNode));
23224 if (ntItem == NULL) {
23225 xmlSchemaVErrMemory(NULL,
23226 "allocating an IDC node-table item", NULL);
23227 xmlFree(*keySeq);
23228 *keySeq = NULL;
23229 return(-1);
23230 }
23231 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
23232
23233 /*
23234 * Store the node-table item in a global list.
23235 */
23236 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23237 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
23238 xmlFree(ntItem);
23239 xmlFree(*keySeq);
23240 *keySeq = NULL;
23241 return (-1);
23242 }
23243 ntItem->nodeQNameID = -1;
23244 } else {
23245 /*
23246 * Save a cached QName for this node on the IDC node, to be
23247 * able to report it, even if the node is not saved.
23248 */
23249 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23250 vctxt->inode->localName, vctxt->inode->nsName);
23251 if (ntItem->nodeQNameID == -1) {
23252 xmlFree(ntItem);
23253 xmlFree(*keySeq);
23254 *keySeq = NULL;
23255 return (-1);
23256 }
23257 }
23258 /*
23259 * Init the node-table item: Save the node, position and
23260 * consume the key-sequence.
23261 */
23262 ntItem->node = vctxt->node;
23263 ntItem->nodeLine = vctxt->inode->nodeLine;
23264 ntItem->keys = *keySeq;
23265 *keySeq = NULL;
23266#if 0
23267 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23268#endif
23269 if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23270 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23271 /*
23272 * Free the item, since keyref items won't be
23273 * put on a global list.
23274 */
23275 xmlFree(ntItem->keys);
23276 xmlFree(ntItem);
23277 }
23278 return (-1);
23279 }
23280 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23281 xmlChar *value = NULL;
23282 xmlIDCHashEntryPtr r, e;
23283 if (!matcher->htab)
23284 matcher->htab = xmlHashCreate(4);
23285 xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23286 e = xmlMalloc(sizeof *e);
23287 e->index = targets->nbItems - 1;
23288 r = xmlHashLookup(matcher->htab, value);
23289 if (r) {
23290 e->next = r->next;
23291 r->next = e;
23292 } else {
23293 e->next = NULL;
23294 xmlHashAddEntry(matcher->htab, value, e);
23295 }
23296 FREE_AND_NULL(value);
23297 }
23298
23299 goto selector_leave;
23300selector_key_error:
23301 {
23302 xmlChar *str = NULL;
23303 /*
23304 * 4.2.1 (KEY) The `target node set` and the
23305 * `qualified node set` are equal, that is, every
23306 * member of the `target node set` is also a member
23307 * of the `qualified node set` and vice versa.
23308 */
23309 xmlSchemaCustomErr(ACTXT_CAST vctxt,
23311 WXS_BASIC_CAST idc,
23312 "Not all fields of %s evaluate to a node",
23313 xmlSchemaGetIDCDesignation(&str, idc), NULL);
23314 FREE_AND_NULL(str);
23315 }
23316selector_leave:
23317 /*
23318 * Free the key-sequence if not added to the IDC table.
23319 */
23320 if ((keySeq != NULL) && (*keySeq != NULL)) {
23321 xmlFree(*keySeq);
23322 *keySeq = NULL;
23323 }
23324 } /* if selector */
23325
23326 sto->nbHistory--;
23327
23328deregister_check:
23329 /*
23330 * Deregister state objects if they reach the depth of creation.
23331 */
23332 if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23333#ifdef DEBUG_IDC
23334 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
23335 sto->sel->xpath);
23336#endif
23337 if (vctxt->xpathStates != sto) {
23338 VERROR_INT("xmlSchemaXPathProcessHistory",
23339 "The state object to be removed is not the first "
23340 "in the list");
23341 }
23342 nextsto = sto->next;
23343 /*
23344 * Unlink from the list of active XPath state objects.
23345 */
23346 vctxt->xpathStates = sto->next;
23347 sto->next = vctxt->xpathStatePool;
23348 /*
23349 * Link it to the pool of reusable state objects.
23350 */
23351 vctxt->xpathStatePool = sto;
23352 sto = nextsto;
23353 } else
23354 sto = sto->next;
23355 } /* while (sto != NULL) */
23356 return (0);
23357}
23358
23369static int
23370xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23371 xmlSchemaElementPtr elemDecl)
23372{
23373 xmlSchemaIDCMatcherPtr matcher, last = NULL;
23374 xmlSchemaIDCPtr idc, refIdc;
23375 xmlSchemaIDCAugPtr aidc;
23376
23377 idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23378 if (idc == NULL)
23379 return (0);
23380
23381#ifdef DEBUG_IDC
23382 {
23383 xmlChar *str = NULL;
23385 "IDC: REGISTER on %s, depth %d\n",
23386 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23387 vctxt->inode->localName), vctxt->depth);
23388 FREE_AND_NULL(str)
23389 }
23390#endif
23391 if (vctxt->inode->idcMatchers != NULL) {
23392 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23393 "The chain of IDC matchers is expected to be empty");
23394 return (-1);
23395 }
23396 do {
23397 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23398 /*
23399 * Since IDCs bubbles are expensive we need to know the
23400 * depth at which the bubbles should stop; this will be
23401 * the depth of the top-most keyref IDC. If no keyref
23402 * references a key/unique IDC, the keyrefDepth will
23403 * be -1, indicating that no bubbles are needed.
23404 */
23405 refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23406 if (refIdc != NULL) {
23407 /*
23408 * Remember that we have keyrefs on this node.
23409 */
23410 vctxt->inode->hasKeyrefs = 1;
23411 /*
23412 * Lookup the referenced augmented IDC info.
23413 */
23414 aidc = vctxt->aidcs;
23415 while (aidc != NULL) {
23416 if (aidc->def == refIdc)
23417 break;
23418 aidc = aidc->next;
23419 }
23420 if (aidc == NULL) {
23421 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23422 "Could not find an augmented IDC item for an IDC "
23423 "definition");
23424 return (-1);
23425 }
23426 if ((aidc->keyrefDepth == -1) ||
23427 (vctxt->depth < aidc->keyrefDepth))
23428 aidc->keyrefDepth = vctxt->depth;
23429 }
23430 }
23431 /*
23432 * Lookup the augmented IDC item for the IDC definition.
23433 */
23434 aidc = vctxt->aidcs;
23435 while (aidc != NULL) {
23436 if (aidc->def == idc)
23437 break;
23438 aidc = aidc->next;
23439 }
23440 if (aidc == NULL) {
23441 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23442 "Could not find an augmented IDC item for an IDC definition");
23443 return (-1);
23444 }
23445 /*
23446 * Create an IDC matcher for every IDC definition.
23447 */
23448 if (vctxt->idcMatcherCache != NULL) {
23449 /*
23450 * Reuse a cached matcher.
23451 */
23452 matcher = vctxt->idcMatcherCache;
23453 vctxt->idcMatcherCache = matcher->nextCached;
23454 matcher->nextCached = NULL;
23455 } else {
23456 matcher = (xmlSchemaIDCMatcherPtr)
23457 xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23458 if (matcher == NULL) {
23459 xmlSchemaVErrMemory(vctxt,
23460 "allocating an IDC matcher", NULL);
23461 return (-1);
23462 }
23463 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23464 }
23465 if (last == NULL)
23466 vctxt->inode->idcMatchers = matcher;
23467 else
23468 last->next = matcher;
23469 last = matcher;
23470
23471 matcher->type = IDC_MATCHER;
23472 matcher->depth = vctxt->depth;
23473 matcher->aidc = aidc;
23474 matcher->idcType = aidc->def->type;
23475#ifdef DEBUG_IDC
23476 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
23477#endif
23478 /*
23479 * Init the automaton state object.
23480 */
23481 if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23482 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23483 return (-1);
23484
23485 idc = idc->next;
23486 } while (idc != NULL);
23487 return (0);
23488}
23489
23490static int
23491xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23492 xmlSchemaNodeInfoPtr ielem)
23493{
23494 xmlSchemaPSVIIDCBindingPtr bind;
23495 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23496 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23497 xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23498
23499 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23500 /* vctxt->createIDCNodeTables */
23501 while (matcher != NULL) {
23502 /*
23503 * Skip keyref IDCs and empty IDC target-lists.
23504 */
23505 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23506 WXS_ILIST_IS_EMPTY(matcher->targets))
23507 {
23508 matcher = matcher->next;
23509 continue;
23510 }
23511 /*
23512 * If we _want_ the IDC node-table to be created in any case
23513 * then do so. Otherwise create them only if keyrefs need them.
23514 */
23515 if ((! vctxt->createIDCNodeTables) &&
23516 ((matcher->aidc->keyrefDepth == -1) ||
23517 (matcher->aidc->keyrefDepth > vctxt->depth)))
23518 {
23519 matcher = matcher->next;
23520 continue;
23521 }
23522 /*
23523 * Get/create the IDC binding on this element for the IDC definition.
23524 */
23525 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23526 if (bind == NULL)
23527 goto internal_error;
23528
23529 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23530 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23531 nbDupls = bind->dupls->nbItems;
23532 } else {
23533 dupls = NULL;
23534 nbDupls = 0;
23535 }
23536 if (bind->nodeTable != NULL) {
23537 nbNodeTable = bind->nbNodes;
23538 } else {
23539 nbNodeTable = 0;
23540 }
23541
23542 if ((nbNodeTable == 0) && (nbDupls == 0)) {
23543 /*
23544 * Transfer all IDC target-nodes to the IDC node-table.
23545 */
23546 bind->nodeTable =
23547 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23548 bind->sizeNodes = matcher->targets->sizeItems;
23549 bind->nbNodes = matcher->targets->nbItems;
23550
23551 matcher->targets->items = NULL;
23552 matcher->targets->sizeItems = 0;
23553 matcher->targets->nbItems = 0;
23554 if (matcher->htab) {
23555 xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23556 matcher->htab = NULL;
23557 }
23558 } else {
23559 /*
23560 * Compare the key-sequences and add to the IDC node-table.
23561 */
23562 nbTargets = matcher->targets->nbItems;
23563 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23564 nbFields = matcher->aidc->def->nbFields;
23565 i = 0;
23566 do {
23567 keys = targets[i]->keys;
23568 if (nbDupls) {
23569 /*
23570 * Search in already found duplicates first.
23571 */
23572 j = 0;
23573 do {
23574 if (nbFields == 1) {
23575 res = xmlSchemaAreValuesEqual(keys[0]->val,
23576 dupls[j]->keys[0]->val);
23577 if (res == -1)
23578 goto internal_error;
23579 if (res == 1) {
23580 /*
23581 * Equal key-sequence.
23582 */
23583 goto next_target;
23584 }
23585 } else {
23586 res = 0;
23587 ntkeys = dupls[j]->keys;
23588 for (k = 0; k < nbFields; k++) {
23589 res = xmlSchemaAreValuesEqual(keys[k]->val,
23590 ntkeys[k]->val);
23591 if (res == -1)
23592 goto internal_error;
23593 if (res == 0) {
23594 /*
23595 * One of the keys differs.
23596 */
23597 break;
23598 }
23599 }
23600 if (res == 1) {
23601 /*
23602 * Equal key-sequence found.
23603 */
23604 goto next_target;
23605 }
23606 }
23607 j++;
23608 } while (j < nbDupls);
23609 }
23610 if (nbNodeTable) {
23611 j = 0;
23612 do {
23613 if (nbFields == 1) {
23614 res = xmlSchemaAreValuesEqual(keys[0]->val,
23615 bind->nodeTable[j]->keys[0]->val);
23616 if (res == -1)
23617 goto internal_error;
23618 if (res == 0) {
23619 /*
23620 * The key-sequence differs.
23621 */
23622 goto next_node_table_entry;
23623 }
23624 } else {
23625 res = 0;
23626 ntkeys = bind->nodeTable[j]->keys;
23627 for (k = 0; k < nbFields; k++) {
23628 res = xmlSchemaAreValuesEqual(keys[k]->val,
23629 ntkeys[k]->val);
23630 if (res == -1)
23631 goto internal_error;
23632 if (res == 0) {
23633 /*
23634 * One of the keys differs.
23635 */
23636 goto next_node_table_entry;
23637 }
23638 }
23639 }
23640 /*
23641 * Add the duplicate to the list of duplicates.
23642 */
23643 if (bind->dupls == NULL) {
23644 bind->dupls = xmlSchemaItemListCreate();
23645 if (bind->dupls == NULL)
23646 goto internal_error;
23647 }
23648 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23649 goto internal_error;
23650 /*
23651 * Remove the duplicate entry from the IDC node-table.
23652 */
23653 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23654 bind->nbNodes--;
23655
23656 goto next_target;
23657
23658next_node_table_entry:
23659 j++;
23660 } while (j < nbNodeTable);
23661 }
23662 /*
23663 * If everything is fine, then add the IDC target-node to
23664 * the IDC node-table.
23665 */
23666 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23667 goto internal_error;
23668
23669next_target:
23670 i++;
23671 } while (i < nbTargets);
23672 }
23673 matcher = matcher->next;
23674 }
23675 return(0);
23676
23677internal_error:
23678 return(-1);
23679}
23680
23692static int
23693xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23694{
23695 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23696 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23697 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23698 xmlSchemaIDCAugPtr aidc;
23699 int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23700
23701 bind = vctxt->inode->idcTable;
23702 if (bind == NULL) {
23703 /* Fine, no table, no bubbles. */
23704 return (0);
23705 }
23706
23707 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23708 /*
23709 * Walk all bindings; create new or add to existing bindings.
23710 * Remove duplicate key-sequences.
23711 */
23712 while (bind != NULL) {
23713
23714 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23715 goto next_binding;
23716 /*
23717 * Check if the key/unique IDC table needs to be bubbled.
23718 */
23719 if (! vctxt->createIDCNodeTables) {
23720 aidc = vctxt->aidcs;
23721 do {
23722 if (aidc->def == bind->definition) {
23723 if ((aidc->keyrefDepth == -1) ||
23724 (aidc->keyrefDepth >= vctxt->depth)) {
23725 goto next_binding;
23726 }
23727 break;
23728 }
23729 aidc = aidc->next;
23730 } while (aidc != NULL);
23731 }
23732
23733 if (parTable != NULL)
23734 parBind = *parTable;
23735 /*
23736 * Search a matching parent binding for the
23737 * IDC definition.
23738 */
23739 while (parBind != NULL) {
23740 if (parBind->definition == bind->definition)
23741 break;
23742 parBind = parBind->next;
23743 }
23744
23745 if (parBind != NULL) {
23746 /*
23747 * Compare every node-table entry of the child node,
23748 * i.e. the key-sequence within, ...
23749 */
23750 oldNum = parBind->nbNodes; /* Skip newly added items. */
23751
23752 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23753 oldDupls = parBind->dupls->nbItems;
23754 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23755 } else {
23756 dupls = NULL;
23757 oldDupls = 0;
23758 }
23759
23760 parNodes = parBind->nodeTable;
23761 nbFields = bind->definition->nbFields;
23762
23763 for (i = 0; i < bind->nbNodes; i++) {
23764 node = bind->nodeTable[i];
23765 if (node == NULL)
23766 continue;
23767 /*
23768 * ...with every key-sequence of the parent node, already
23769 * evaluated to be a duplicate key-sequence.
23770 */
23771 if (oldDupls) {
23772 j = 0;
23773 while (j < oldDupls) {
23774 if (nbFields == 1) {
23775 ret = xmlSchemaAreValuesEqual(
23776 node->keys[0]->val,
23777 dupls[j]->keys[0]->val);
23778 if (ret == -1)
23779 goto internal_error;
23780 if (ret == 0) {
23781 j++;
23782 continue;
23783 }
23784 } else {
23785 parNode = dupls[j];
23786 for (k = 0; k < nbFields; k++) {
23787 ret = xmlSchemaAreValuesEqual(
23788 node->keys[k]->val,
23789 parNode->keys[k]->val);
23790 if (ret == -1)
23791 goto internal_error;
23792 if (ret == 0)
23793 break;
23794 }
23795 }
23796 if (ret == 1)
23797 /* Duplicate found. */
23798 break;
23799 j++;
23800 }
23801 if (j != oldDupls) {
23802 /* Duplicate found. Skip this entry. */
23803 continue;
23804 }
23805 }
23806 /*
23807 * ... and with every key-sequence of the parent node.
23808 */
23809 if (oldNum) {
23810 j = 0;
23811 while (j < oldNum) {
23812 parNode = parNodes[j];
23813 if (nbFields == 1) {
23814 ret = xmlSchemaAreValuesEqual(
23815 node->keys[0]->val,
23816 parNode->keys[0]->val);
23817 if (ret == -1)
23818 goto internal_error;
23819 if (ret == 0) {
23820 j++;
23821 continue;
23822 }
23823 } else {
23824 for (k = 0; k < nbFields; k++) {
23825 ret = xmlSchemaAreValuesEqual(
23826 node->keys[k]->val,
23827 parNode->keys[k]->val);
23828 if (ret == -1)
23829 goto internal_error;
23830 if (ret == 0)
23831 break;
23832 }
23833 }
23834 if (ret == 1)
23835 /* Duplicate found. */
23836 break;
23837 j++;
23838 }
23839 if (j != oldNum) {
23840 /*
23841 * Handle duplicates. Move the duplicate in
23842 * the parent's node-table to the list of
23843 * duplicates.
23844 */
23845 oldNum--;
23846 parBind->nbNodes--;
23847 /*
23848 * Move last old item to pos of duplicate.
23849 */
23850 parNodes[j] = parNodes[oldNum];
23851
23852 if (parBind->nbNodes != oldNum) {
23853 /*
23854 * If new items exist, move last new item to
23855 * last of old items.
23856 */
23857 parNodes[oldNum] =
23858 parNodes[parBind->nbNodes];
23859 }
23860 if (parBind->dupls == NULL) {
23861 parBind->dupls = xmlSchemaItemListCreate();
23862 if (parBind->dupls == NULL)
23863 goto internal_error;
23864 }
23865 xmlSchemaItemListAdd(parBind->dupls, parNode);
23866 } else {
23867 /*
23868 * Add the node-table entry (node and key-sequence) of
23869 * the child node to the node table of the parent node.
23870 */
23871 if (parBind->nodeTable == NULL) {
23872 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23873 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23874 if (parBind->nodeTable == NULL) {
23875 xmlSchemaVErrMemory(NULL,
23876 "allocating IDC list of node-table items", NULL);
23877 goto internal_error;
23878 }
23879 parBind->sizeNodes = 1;
23880 } else if (parBind->nbNodes >= parBind->sizeNodes) {
23881 parBind->sizeNodes *= 2;
23882 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23883 xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23884 sizeof(xmlSchemaPSVIIDCNodePtr));
23885 if (parBind->nodeTable == NULL) {
23886 xmlSchemaVErrMemory(NULL,
23887 "re-allocating IDC list of node-table items", NULL);
23888 goto internal_error;
23889 }
23890 }
23891 parNodes = parBind->nodeTable;
23892 /*
23893 * Append the new node-table entry to the 'new node-table
23894 * entries' section.
23895 */
23896 parNodes[parBind->nbNodes++] = node;
23897 }
23898
23899 }
23900
23901 }
23902 } else {
23903 /*
23904 * No binding for the IDC was found: create a new one and
23905 * copy all node-tables.
23906 */
23907 parBind = xmlSchemaIDCNewBinding(bind->definition);
23908 if (parBind == NULL)
23909 goto internal_error;
23910
23911 /*
23912 * TODO: Hmm, how to optimize the initial number of
23913 * allocated entries?
23914 */
23915 if (bind->nbNodes != 0) {
23916 /*
23917 * Add all IDC node-table entries.
23918 */
23919 if (! vctxt->psviExposeIDCNodeTables) {
23920 /*
23921 * Just move the entries.
23922 * NOTE: this is quite save here, since
23923 * all the keyref lookups have already been
23924 * performed.
23925 */
23926 parBind->nodeTable = bind->nodeTable;
23927 bind->nodeTable = NULL;
23928 parBind->sizeNodes = bind->sizeNodes;
23929 bind->sizeNodes = 0;
23930 parBind->nbNodes = bind->nbNodes;
23931 bind->nbNodes = 0;
23932 } else {
23933 /*
23934 * Copy the entries.
23935 */
23936 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23937 xmlMalloc(bind->nbNodes *
23938 sizeof(xmlSchemaPSVIIDCNodePtr));
23939 if (parBind->nodeTable == NULL) {
23940 xmlSchemaVErrMemory(NULL,
23941 "allocating an array of IDC node-table "
23942 "items", NULL);
23943 xmlSchemaIDCFreeBinding(parBind);
23944 goto internal_error;
23945 }
23946 parBind->sizeNodes = bind->nbNodes;
23947 parBind->nbNodes = bind->nbNodes;
23948 memcpy(parBind->nodeTable, bind->nodeTable,
23949 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23950 }
23951 }
23952 if (bind->dupls) {
23953 /*
23954 * Move the duplicates.
23955 */
23956 if (parBind->dupls != NULL)
23957 xmlSchemaItemListFree(parBind->dupls);
23958 parBind->dupls = bind->dupls;
23959 bind->dupls = NULL;
23960 }
23961 if (parTable != NULL) {
23962 if (*parTable == NULL)
23963 *parTable = parBind;
23964 else {
23965 parBind->next = *parTable;
23966 *parTable = parBind;
23967 }
23968 }
23969 }
23970
23971next_binding:
23972 bind = bind->next;
23973 }
23974 return (0);
23975
23976internal_error:
23977 return(-1);
23978}
23979
23987static int
23988xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23989{
23990 xmlSchemaIDCMatcherPtr matcher;
23991 xmlSchemaPSVIIDCBindingPtr bind;
23992
23993 matcher = vctxt->inode->idcMatchers;
23994 /*
23995 * Find a keyref.
23996 */
23997 while (matcher != NULL) {
23998 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23999 matcher->targets &&
24000 matcher->targets->nbItems)
24001 {
24002 int i, j, k, res, nbFields, hasDupls;
24003 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
24004 xmlSchemaPSVIIDCNodePtr refNode = NULL;
24006
24007 nbFields = matcher->aidc->def->nbFields;
24008
24009 /*
24010 * Find the IDC node-table for the referenced IDC key/unique.
24011 */
24012 bind = vctxt->inode->idcTable;
24013 while (bind != NULL) {
24014 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
24015 bind->definition)
24016 break;
24017 bind = bind->next;
24018 }
24019 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
24020 /*
24021 * Search for a matching key-sequences.
24022 */
24023 if (bind) {
24024 table = xmlHashCreate(bind->nbNodes * 2);
24025 for (j = 0; j < bind->nbNodes; j++) {
24026 xmlChar *value;
24027 xmlIDCHashEntryPtr r, e;
24028 keys = bind->nodeTable[j]->keys;
24029 xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
24030 e = xmlMalloc(sizeof *e);
24031 e->index = j;
24033 if (r) {
24034 e->next = r->next;
24035 r->next = e;
24036 } else {
24037 e->next = NULL;
24039 }
24040 FREE_AND_NULL(value);
24041 }
24042 }
24043 for (i = 0; i < matcher->targets->nbItems; i++) {
24044 res = 0;
24045 refNode = matcher->targets->items[i];
24046 if (bind != NULL) {
24047 xmlChar *value;
24048 xmlIDCHashEntryPtr e;
24049 refKeys = refNode->keys;
24050 xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
24052 FREE_AND_NULL(value);
24053 res = 0;
24054 for (;e; e = e->next) {
24055 keys = bind->nodeTable[e->index]->keys;
24056 for (k = 0; k < nbFields; k++) {
24057 res = xmlSchemaAreValuesEqual(keys[k]->val,
24058 refKeys[k]->val);
24059 if (res == 0)
24060 break;
24061 else if (res == -1) {
24062 return (-1);
24063 }
24064 }
24065 if (res == 1) {
24066 /*
24067 * Match found.
24068 */
24069 break;
24070 }
24071 }
24072 if ((res == 0) && hasDupls) {
24073 /*
24074 * Search in duplicates
24075 */
24076 for (j = 0; j < bind->dupls->nbItems; j++) {
24077 keys = ((xmlSchemaPSVIIDCNodePtr)
24078 bind->dupls->items[j])->keys;
24079 for (k = 0; k < nbFields; k++) {
24080 res = xmlSchemaAreValuesEqual(keys[k]->val,
24081 refKeys[k]->val);
24082 if (res == 0)
24083 break;
24084 else if (res == -1) {
24085 return (-1);
24086 }
24087 }
24088 if (res == 1) {
24089 /*
24090 * Match in duplicates found.
24091 */
24092 xmlChar *str = NULL, *strB = NULL;
24093 xmlSchemaKeyrefErr(vctxt,
24094 XML_SCHEMAV_CVC_IDC, refNode,
24095 (xmlSchemaTypePtr) matcher->aidc->def,
24096 "More than one match found for "
24097 "key-sequence %s of keyref '%s'",
24098 xmlSchemaFormatIDCKeySequence(vctxt, &str,
24099 refNode->keys, nbFields),
24100 xmlSchemaGetComponentQName(&strB,
24101 matcher->aidc->def));
24102 FREE_AND_NULL(str);
24103 FREE_AND_NULL(strB);
24104 break;
24105 }
24106 }
24107 }
24108 }
24109
24110 if (res == 0) {
24111 xmlChar *str = NULL, *strB = NULL;
24112 xmlSchemaKeyrefErr(vctxt,
24113 XML_SCHEMAV_CVC_IDC, refNode,
24114 (xmlSchemaTypePtr) matcher->aidc->def,
24115 "No match found for key-sequence %s of keyref '%s'",
24116 xmlSchemaFormatIDCKeySequence(vctxt, &str,
24117 refNode->keys, nbFields),
24118 xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
24119 FREE_AND_NULL(str);
24120 FREE_AND_NULL(strB);
24121 }
24122 }
24123 if (table) {
24124 xmlHashFree(table, xmlFreeIDCHashEntry);
24125 }
24126 }
24127 matcher = matcher->next;
24128 }
24129 /* TODO: Return an error if any error encountered. */
24130 return (0);
24131}
24132
24133/************************************************************************
24134 * *
24135 * XML Reader validation code *
24136 * *
24137 ************************************************************************/
24138
24139static xmlSchemaAttrInfoPtr
24140xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
24141{
24142 xmlSchemaAttrInfoPtr iattr;
24143 /*
24144 * Grow/create list of attribute infos.
24145 */
24146 if (vctxt->attrInfos == NULL) {
24147 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
24148 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
24149 vctxt->sizeAttrInfos = 1;
24150 if (vctxt->attrInfos == NULL) {
24151 xmlSchemaVErrMemory(vctxt,
24152 "allocating attribute info list", NULL);
24153 return (NULL);
24154 }
24155 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
24156 vctxt->sizeAttrInfos++;
24157 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
24158 xmlRealloc(vctxt->attrInfos,
24159 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
24160 if (vctxt->attrInfos == NULL) {
24161 xmlSchemaVErrMemory(vctxt,
24162 "re-allocating attribute info list", NULL);
24163 return (NULL);
24164 }
24165 } else {
24166 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
24167 if (iattr->localName != NULL) {
24168 VERROR_INT("xmlSchemaGetFreshAttrInfo",
24169 "attr info not cleared");
24170 return (NULL);
24171 }
24172 iattr->nodeType = XML_ATTRIBUTE_NODE;
24173 return (iattr);
24174 }
24175 /*
24176 * Create an attribute info.
24177 */
24178 iattr = (xmlSchemaAttrInfoPtr)
24179 xmlMalloc(sizeof(xmlSchemaAttrInfo));
24180 if (iattr == NULL) {
24181 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
24182 return (NULL);
24183 }
24184 memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
24185 iattr->nodeType = XML_ATTRIBUTE_NODE;
24186 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
24187
24188 return (iattr);
24189}
24190
24191static int
24192xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
24193 xmlNodePtr attrNode,
24194 int nodeLine,
24195 const xmlChar *localName,
24196 const xmlChar *nsName,
24197 int ownedNames,
24198 xmlChar *value,
24199 int ownedValue)
24200{
24201 xmlSchemaAttrInfoPtr attr;
24202
24203 attr = xmlSchemaGetFreshAttrInfo(vctxt);
24204 if (attr == NULL) {
24205 VERROR_INT("xmlSchemaPushAttribute",
24206 "calling xmlSchemaGetFreshAttrInfo()");
24207 return (-1);
24208 }
24209 attr->node = attrNode;
24210 attr->nodeLine = nodeLine;
24211 attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
24212 attr->localName = localName;
24213 attr->nsName = nsName;
24214 if (ownedNames)
24215 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
24216 /*
24217 * Evaluate if it's an XSI attribute.
24218 */
24219 if (nsName != NULL) {
24220 if (xmlStrEqual(localName, BAD_CAST "nil")) {
24221 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24222 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
24223 }
24224 } else if (xmlStrEqual(localName, BAD_CAST "type")) {
24225 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24226 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
24227 }
24228 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
24229 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24230 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
24231 }
24232 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
24233 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24234 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
24235 }
24236 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
24237 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
24238 }
24239 }
24240 attr->value = value;
24241 if (ownedValue)
24242 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
24243 if (attr->metaType != 0)
24244 attr->state = XML_SCHEMAS_ATTR_META;
24245 return (0);
24246}
24247
24253static void
24254xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
24255 xmlSchemaNodeInfoPtr ielem)
24256{
24257 ielem->hasKeyrefs = 0;
24258 ielem->appliedXPath = 0;
24259 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
24260 FREE_AND_NULL(ielem->localName);
24261 FREE_AND_NULL(ielem->nsName);
24262 } else {
24263 ielem->localName = NULL;
24264 ielem->nsName = NULL;
24265 }
24266 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24267 FREE_AND_NULL(ielem->value);
24268 } else {
24269 ielem->value = NULL;
24270 }
24271 if (ielem->val != NULL) {
24272 /*
24273 * PSVI TODO: Be careful not to free it when the value is
24274 * exposed via PSVI.
24275 */
24276 xmlSchemaFreeValue(ielem->val);
24277 ielem->val = NULL;
24278 }
24279 if (ielem->idcMatchers != NULL) {
24280 /*
24281 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24282 * Does it work?
24283 */
24284 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24285#if 0
24286 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24287#endif
24288 ielem->idcMatchers = NULL;
24289 }
24290 if (ielem->idcTable != NULL) {
24291 /*
24292 * OPTIMIZE TODO: Use a pool of IDC tables??.
24293 */
24294 xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24295 ielem->idcTable = NULL;
24296 }
24297 if (ielem->regexCtxt != NULL) {
24298 xmlRegFreeExecCtxt(ielem->regexCtxt);
24299 ielem->regexCtxt = NULL;
24300 }
24301 if (ielem->nsBindings != NULL) {
24302 xmlFree((xmlChar **)ielem->nsBindings);
24303 ielem->nsBindings = NULL;
24304 ielem->nbNsBindings = 0;
24305 ielem->sizeNsBindings = 0;
24306 }
24307}
24308
24318static xmlSchemaNodeInfoPtr
24319xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24320{
24321 xmlSchemaNodeInfoPtr info = NULL;
24322
24323 if (vctxt->depth > vctxt->sizeElemInfos) {
24324 VERROR_INT("xmlSchemaGetFreshElemInfo",
24325 "inconsistent depth encountered");
24326 return (NULL);
24327 }
24328 if (vctxt->elemInfos == NULL) {
24329 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24330 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24331 if (vctxt->elemInfos == NULL) {
24332 xmlSchemaVErrMemory(vctxt,
24333 "allocating the element info array", NULL);
24334 return (NULL);
24335 }
24336 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24337 vctxt->sizeElemInfos = 10;
24338 } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24339 int i = vctxt->sizeElemInfos;
24340
24341 vctxt->sizeElemInfos *= 2;
24342 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24343 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24344 sizeof(xmlSchemaNodeInfoPtr));
24345 if (vctxt->elemInfos == NULL) {
24346 xmlSchemaVErrMemory(vctxt,
24347 "re-allocating the element info array", NULL);
24348 return (NULL);
24349 }
24350 /*
24351 * We need the new memory to be NULLed.
24352 * TODO: Use memset instead?
24353 */
24354 for (; i < vctxt->sizeElemInfos; i++)
24355 vctxt->elemInfos[i] = NULL;
24356 } else
24357 info = vctxt->elemInfos[vctxt->depth];
24358
24359 if (info == NULL) {
24360 info = (xmlSchemaNodeInfoPtr)
24361 xmlMalloc(sizeof(xmlSchemaNodeInfo));
24362 if (info == NULL) {
24363 xmlSchemaVErrMemory(vctxt,
24364 "allocating an element info", NULL);
24365 return (NULL);
24366 }
24367 vctxt->elemInfos[vctxt->depth] = info;
24368 } else {
24369 if (info->localName != NULL) {
24370 VERROR_INT("xmlSchemaGetFreshElemInfo",
24371 "elem info has not been cleared");
24372 return (NULL);
24373 }
24374 }
24375 memset(info, 0, sizeof(xmlSchemaNodeInfo));
24376 info->nodeType = XML_ELEMENT_NODE;
24377 info->depth = vctxt->depth;
24378
24379 return (info);
24380}
24381
24382#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24383#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24384#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24385
24386static int
24387xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24389 xmlSchemaTypePtr type,
24390 xmlSchemaValType valType,
24391 const xmlChar * value,
24392 xmlSchemaValPtr val,
24393 unsigned long length,
24394 int fireErrors)
24395{
24396 int ret, error = 0, found;
24397
24398 xmlSchemaTypePtr tmpType;
24399 xmlSchemaFacetLinkPtr facetLink;
24400 xmlSchemaFacetPtr facet;
24401 unsigned long len = 0;
24402 xmlSchemaWhitespaceValueType ws;
24403
24404 /*
24405 * In Libxml2, derived built-in types have currently no explicit facets.
24406 */
24407 if (type->type == XML_SCHEMA_TYPE_BASIC)
24408 return (0);
24409
24410 /*
24411 * NOTE: Do not jump away, if the facetSet of the given type is
24412 * empty: until now, "pattern" and "enumeration" facets of the
24413 * *base types* need to be checked as well.
24414 */
24415 if (type->facetSet == NULL)
24416 goto pattern_and_enum;
24417
24418 if (! WXS_IS_ATOMIC(type)) {
24419 if (WXS_IS_LIST(type))
24420 goto WXS_IS_LIST;
24421 else
24422 goto pattern_and_enum;
24423 }
24424
24425 /*
24426 * Whitespace handling is only of importance for string-based
24427 * types.
24428 */
24429 tmpType = xmlSchemaGetPrimitiveType(type);
24430 if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24431 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24432 ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24433 } else
24434 ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24435
24436 /*
24437 * If the value was not computed (for string or
24438 * anySimpleType based types), then use the provided
24439 * type.
24440 */
24441 if (val != NULL)
24442 valType = xmlSchemaGetValType(val);
24443
24444 ret = 0;
24445 for (facetLink = type->facetSet; facetLink != NULL;
24446 facetLink = facetLink->next) {
24447 /*
24448 * Skip the pattern "whiteSpace": it is used to
24449 * format the character content beforehand.
24450 */
24451 switch (facetLink->facet->type) {
24452 case XML_SCHEMA_FACET_WHITESPACE:
24453 case XML_SCHEMA_FACET_PATTERN:
24454 case XML_SCHEMA_FACET_ENUMERATION:
24455 continue;
24456 case XML_SCHEMA_FACET_LENGTH:
24457 case XML_SCHEMA_FACET_MINLENGTH:
24458 case XML_SCHEMA_FACET_MAXLENGTH:
24459 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24460 valType, value, val, &len, ws);
24461 break;
24462 default:
24463 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24464 valType, value, val, ws);
24465 break;
24466 }
24467 if (ret < 0) {
24468 AERROR_INT("xmlSchemaValidateFacets",
24469 "validating against a atomic type facet");
24470 return (-1);
24471 } else if (ret > 0) {
24472 if (fireErrors)
24473 xmlSchemaFacetErr(actxt, ret, node,
24474 value, len, type, facetLink->facet, NULL, NULL, NULL);
24475 else
24476 return (ret);
24477 if (error == 0)
24478 error = ret;
24479 }
24480 ret = 0;
24481 }
24482
24483WXS_IS_LIST:
24484 if (! WXS_IS_LIST(type))
24485 goto pattern_and_enum;
24486 /*
24487 * "length", "minLength" and "maxLength" of list types.
24488 */
24489 ret = 0;
24490 for (facetLink = type->facetSet; facetLink != NULL;
24491 facetLink = facetLink->next) {
24492
24493 switch (facetLink->facet->type) {
24494 case XML_SCHEMA_FACET_LENGTH:
24495 case XML_SCHEMA_FACET_MINLENGTH:
24496 case XML_SCHEMA_FACET_MAXLENGTH:
24497 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24498 value, length, NULL);
24499 break;
24500 default:
24501 continue;
24502 }
24503 if (ret < 0) {
24504 AERROR_INT("xmlSchemaValidateFacets",
24505 "validating against a list type facet");
24506 return (-1);
24507 } else if (ret > 0) {
24508 if (fireErrors)
24509 xmlSchemaFacetErr(actxt, ret, node,
24510 value, length, type, facetLink->facet, NULL, NULL, NULL);
24511 else
24512 return (ret);
24513 if (error == 0)
24514 error = ret;
24515 }
24516 ret = 0;
24517 }
24518
24519pattern_and_enum:
24520 found = 0;
24521 /*
24522 * Process enumerations. Facet values are in the value space
24523 * of the defining type's base type. This seems to be a bug in the
24524 * XML Schema 1.0 spec. Use the whitespace type of the base type.
24525 * Only the first set of enumerations in the ancestor-or-self axis
24526 * is used for validation.
24527 */
24528 ret = 0;
24529 tmpType = type;
24530 do {
24531 for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24532 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24533 continue;
24534 found = 1;
24535 ret = xmlSchemaAreValuesEqual(facet->val, val);
24536 if (ret == 1)
24537 break;
24538 else if (ret < 0) {
24539 AERROR_INT("xmlSchemaValidateFacets",
24540 "validating against an enumeration facet");
24541 return (-1);
24542 }
24543 }
24544 if (ret != 0)
24545 break;
24546 /*
24547 * Break on the first set of enumerations. Any additional
24548 * enumerations which might be existent on the ancestors
24549 * of the current type are restricted by this set; thus
24550 * *must* *not* be taken into account.
24551 */
24552 if (found)
24553 break;
24554 tmpType = tmpType->baseType;
24555 } while ((tmpType != NULL) &&
24556 (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24557 if (found && (ret == 0)) {
24559 if (fireErrors) {
24560 xmlSchemaFacetErr(actxt, ret, node,
24561 value, 0, type, NULL, NULL, NULL, NULL);
24562 } else
24563 return (ret);
24564 if (error == 0)
24565 error = ret;
24566 }
24567
24568 /*
24569 * Process patters. Pattern facets are ORed at type level
24570 * and ANDed if derived. Walk the base type axis.
24571 */
24572 tmpType = type;
24573 facet = NULL;
24574 do {
24575 found = 0;
24576 for (facetLink = tmpType->facetSet; facetLink != NULL;
24577 facetLink = facetLink->next) {
24578 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24579 continue;
24580 found = 1;
24581 /*
24582 * NOTE that for patterns, @value needs to be the
24583 * normalized value.
24584 */
24585 ret = xmlRegexpExec(facetLink->facet->regexp, value);
24586 if (ret == 1)
24587 break;
24588 else if (ret < 0) {
24589 AERROR_INT("xmlSchemaValidateFacets",
24590 "validating against a pattern facet");
24591 return (-1);
24592 } else {
24593 /*
24594 * Save the last non-validating facet.
24595 */
24596 facet = facetLink->facet;
24597 }
24598 }
24599 if (found && (ret != 1)) {
24601 if (fireErrors) {
24602 xmlSchemaFacetErr(actxt, ret, node,
24603 value, 0, type, facet, NULL, NULL, NULL);
24604 } else
24605 return (ret);
24606 if (error == 0)
24607 error = ret;
24608 break;
24609 }
24610 tmpType = tmpType->baseType;
24611 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24612
24613 return (error);
24614}
24615
24616static xmlChar *
24617xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24618 const xmlChar *value)
24619{
24620 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24621 case XML_SCHEMA_WHITESPACE_COLLAPSE:
24622 return (xmlSchemaCollapseString(value));
24623 case XML_SCHEMA_WHITESPACE_REPLACE:
24624 return (xmlSchemaWhiteSpaceReplace(value));
24625 default:
24626 return (NULL);
24627 }
24628}
24629
24630static int
24631xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24632 const xmlChar *value,
24633 xmlSchemaValPtr *val,
24634 int valNeeded)
24635{
24636 int ret;
24637 xmlChar *stripped;
24638 const xmlChar *nsName;
24639 xmlChar *local, *prefix = NULL;
24640
24641 ret = xmlValidateQName(value, 1);
24642 if (ret != 0) {
24643 if (ret == -1) {
24644 VERROR_INT("xmlSchemaValidateQName",
24645 "calling xmlValidateQName()");
24646 return (-1);
24647 }
24649 }
24650 /*
24651 * NOTE: xmlSplitQName2 will always return a duplicated
24652 * strings.
24653 */
24654 /* TODO: Export and use xmlSchemaStrip instead */
24655 stripped = xmlSchemaCollapseString(value);
24656 local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24657 xmlFree(stripped);
24658 if (local == NULL)
24660 /*
24661 * OPTIMIZE TODO: Use flags for:
24662 * - is there any namespace binding?
24663 * - is there a default namespace?
24664 */
24665 nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24666
24667 if (prefix != NULL) {
24668 xmlFree(prefix);
24669 /*
24670 * A namespace must be found if the prefix is
24671 * NOT NULL.
24672 */
24673 if (nsName == NULL) {
24675 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24676 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24677 "The QName value '%s' has no "
24678 "corresponding namespace declaration in "
24679 "scope", value, NULL);
24680 if (local != NULL)
24681 xmlFree(local);
24682 return (ret);
24683 }
24684 }
24685 if (valNeeded && val) {
24686 if (nsName != NULL)
24687 *val = xmlSchemaNewQNameValue(
24688 BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24689 else
24690 *val = xmlSchemaNewQNameValue(NULL,
24691 BAD_CAST local);
24692 } else
24693 xmlFree(local);
24694 return (0);
24695}
24696
24697/*
24698* cvc-simple-type
24699*/
24700static int
24701xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24703 xmlSchemaTypePtr type,
24704 const xmlChar *value,
24705 xmlSchemaValPtr *retVal,
24706 int fireErrors,
24707 int normalize,
24708 int isNormalized)
24709{
24710 int ret = 0, valNeeded = (retVal) ? 1 : 0;
24711 xmlSchemaValPtr val = NULL;
24712 /* xmlSchemaWhitespaceValueType ws; */
24713 xmlChar *normValue = NULL;
24714
24715#define NORMALIZE(atype) \
24716 if ((! isNormalized) && \
24717 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24718 normValue = xmlSchemaNormalizeValue(atype, value); \
24719 if (normValue != NULL) \
24720 value = normValue; \
24721 isNormalized = 1; \
24722 }
24723
24724 if ((retVal != NULL) && (*retVal != NULL)) {
24725 xmlSchemaFreeValue(*retVal);
24726 *retVal = NULL;
24727 }
24728 /*
24729 * 3.14.4 Simple Type Definition Validation Rules
24730 * Validation Rule: String Valid
24731 */
24732 /*
24733 * 1 It is schema-valid with respect to that definition as defined
24734 * by Datatype Valid in [XML Schemas: Datatypes].
24735 */
24736 /*
24737 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24738 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24739 * the string must be a `declared entity name`.
24740 */
24741 /*
24742 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24743 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24744 * then every whitespace-delimited substring of the string must be a `declared
24745 * entity name`.
24746 */
24747 /*
24748 * 2.3 otherwise no further condition applies.
24749 */
24750 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24751 valNeeded = 1;
24752 if (value == NULL)
24753 value = BAD_CAST "";
24754 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24755 xmlSchemaTypePtr biType; /* The built-in type. */
24756 /*
24757 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24758 * a literal in the `lexical space` of {base type definition}"
24759 */
24760 /*
24761 * Whitespace-normalize.
24762 */
24763 NORMALIZE(type);
24764 if (type->type != XML_SCHEMA_TYPE_BASIC) {
24765 /*
24766 * Get the built-in type.
24767 */
24768 biType = type->baseType;
24769 while ((biType != NULL) &&
24770 (biType->type != XML_SCHEMA_TYPE_BASIC))
24771 biType = biType->baseType;
24772
24773 if (biType == NULL) {
24774 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24775 "could not get the built-in type");
24776 goto internal_error;
24777 }
24778 } else
24779 biType = type;
24780 /*
24781 * NOTATIONs need to be processed here, since they need
24782 * to lookup in the hashtable of NOTATION declarations of the schema.
24783 */
24784 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24785 switch (biType->builtInType) {
24786 case XML_SCHEMAS_NOTATION:
24787 ret = xmlSchemaValidateNotation(
24788 (xmlSchemaValidCtxtPtr) actxt,
24789 ((xmlSchemaValidCtxtPtr) actxt)->schema,
24790 NULL, value, &val, valNeeded);
24791 break;
24792 case XML_SCHEMAS_QNAME:
24793 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24794 value, &val, valNeeded);
24795 break;
24796 default:
24797 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24798 if (valNeeded)
24799 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24800 value, &val, node);
24801 else
24802 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24803 value, NULL, node);
24804 break;
24805 }
24806 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24807 switch (biType->builtInType) {
24808 case XML_SCHEMAS_NOTATION:
24809 ret = xmlSchemaValidateNotation(NULL,
24810 ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24811 value, &val, valNeeded);
24812 break;
24813 default:
24814 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24815 if (valNeeded)
24816 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24817 value, &val, node);
24818 else
24819 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24820 value, NULL, node);
24821 break;
24822 }
24823 } else {
24824 /*
24825 * Validation via a public API is not implemented yet.
24826 */
24827 TODO
24828 goto internal_error;
24829 }
24830 if (ret != 0) {
24831 if (ret < 0) {
24832 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24833 "validating against a built-in type");
24834 goto internal_error;
24835 }
24836 if (WXS_IS_LIST(type))
24838 else
24840 }
24841 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24842 /*
24843 * Check facets.
24844 */
24845 ret = xmlSchemaValidateFacets(actxt, node, type,
24846 (xmlSchemaValType) biType->builtInType, value, val,
24847 0, fireErrors);
24848 if (ret != 0) {
24849 if (ret < 0) {
24850 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24851 "validating facets of atomic simple type");
24852 goto internal_error;
24853 }
24854 if (WXS_IS_LIST(type))
24856 else
24858 }
24859 }
24860 else if (fireErrors && (ret > 0))
24861 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24862 } else if (WXS_IS_LIST(type)) {
24863
24864 xmlSchemaTypePtr itemType;
24865 const xmlChar *cur, *end;
24866 xmlChar *tmpValue = NULL;
24867 unsigned long len = 0;
24868 xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24869 /* 1.2.2 if {variety} is `list` then the string must be a sequence
24870 * of white space separated tokens, each of which `match`es a literal
24871 * in the `lexical space` of {item type definition}
24872 */
24873 /*
24874 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24875 * the list type has an enum or pattern facet.
24876 */
24877 NORMALIZE(type);
24878 /*
24879 * VAL TODO: Optimize validation of empty values.
24880 * VAL TODO: We do not have computed values for lists.
24881 */
24882 itemType = WXS_LIST_ITEMTYPE(type);
24883 cur = value;
24884 do {
24885 while (IS_BLANK_CH(*cur))
24886 cur++;
24887 end = cur;
24888 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24889 end++;
24890 if (end == cur)
24891 break;
24892 tmpValue = xmlStrndup(cur, end - cur);
24893 len++;
24894
24895 if (valNeeded)
24896 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24897 tmpValue, &curVal, fireErrors, 0, 1);
24898 else
24899 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24900 tmpValue, NULL, fireErrors, 0, 1);
24901 FREE_AND_NULL(tmpValue);
24902 if (curVal != NULL) {
24903 /*
24904 * Add to list of computed values.
24905 */
24906 if (val == NULL)
24907 val = curVal;
24908 else
24909 xmlSchemaValueAppend(prevVal, curVal);
24910 prevVal = curVal;
24911 curVal = NULL;
24912 }
24913 if (ret != 0) {
24914 if (ret < 0) {
24915 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24916 "validating an item of list simple type");
24917 goto internal_error;
24918 }
24920 break;
24921 }
24922 cur = end;
24923 } while (*cur != 0);
24924 FREE_AND_NULL(tmpValue);
24925 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24926 /*
24927 * Apply facets (pattern, enumeration).
24928 */
24929 ret = xmlSchemaValidateFacets(actxt, node, type,
24930 XML_SCHEMAS_UNKNOWN, value, val,
24931 len, fireErrors);
24932 if (ret != 0) {
24933 if (ret < 0) {
24934 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24935 "validating facets of list simple type");
24936 goto internal_error;
24937 }
24939 }
24940 }
24941 if (fireErrors && (ret > 0)) {
24942 /*
24943 * Report the normalized value.
24944 */
24945 normalize = 1;
24946 NORMALIZE(type);
24947 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24948 }
24949 } else if (WXS_IS_UNION(type)) {
24950 xmlSchemaTypeLinkPtr memberLink;
24951 /*
24952 * TODO: For all datatypes `derived` by `union` whiteSpace does
24953 * not apply directly; however, the normalization behavior of `union`
24954 * types is controlled by the value of whiteSpace on that one of the
24955 * `memberTypes` against which the `union` is successfully validated.
24956 *
24957 * This means that the value is normalized by the first validating
24958 * member type, then the facets of the union type are applied. This
24959 * needs changing of the value!
24960 */
24961
24962 /*
24963 * 1.2.3 if {variety} is `union` then the string must `match` a
24964 * literal in the `lexical space` of at least one member of
24965 * {member type definitions}
24966 */
24967 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24968 if (memberLink == NULL) {
24969 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24970 "union simple type has no member types");
24971 goto internal_error;
24972 }
24973 /*
24974 * Always normalize union type values, since we currently
24975 * cannot store the whitespace information with the value
24976 * itself; otherwise a later value-comparison would be
24977 * not possible.
24978 */
24979 while (memberLink != NULL) {
24980 if (valNeeded)
24981 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24982 memberLink->type, value, &val, 0, 1, 0);
24983 else
24984 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24985 memberLink->type, value, NULL, 0, 1, 0);
24986 if (ret <= 0)
24987 break;
24988 memberLink = memberLink->next;
24989 }
24990 if (ret != 0) {
24991 if (ret < 0) {
24992 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24993 "validating members of union simple type");
24994 goto internal_error;
24995 }
24997 }
24998 /*
24999 * Apply facets (pattern, enumeration).
25000 */
25001 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
25002 /*
25003 * The normalization behavior of `union` types is controlled by
25004 * the value of whiteSpace on that one of the `memberTypes`
25005 * against which the `union` is successfully validated.
25006 */
25007 NORMALIZE(memberLink->type);
25008 ret = xmlSchemaValidateFacets(actxt, node, type,
25009 XML_SCHEMAS_UNKNOWN, value, val,
25010 0, fireErrors);
25011 if (ret != 0) {
25012 if (ret < 0) {
25013 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
25014 "validating facets of union simple type");
25015 goto internal_error;
25016 }
25018 }
25019 }
25020 if (fireErrors && (ret > 0))
25021 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
25022 }
25023
25024 if (normValue != NULL)
25025 xmlFree(normValue);
25026 if (ret == 0) {
25027 if (retVal != NULL)
25028 *retVal = val;
25029 else if (val != NULL)
25030 xmlSchemaFreeValue(val);
25031 } else if (val != NULL)
25032 xmlSchemaFreeValue(val);
25033 return (ret);
25034internal_error:
25035 if (normValue != NULL)
25036 xmlFree(normValue);
25037 if (val != NULL)
25038 xmlSchemaFreeValue(val);
25039 return (-1);
25040}
25041
25042static int
25043xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
25044 const xmlChar *value,
25045 const xmlChar **nsName,
25046 const xmlChar **localName)
25047{
25048 int ret = 0;
25049
25050 if ((nsName == NULL) || (localName == NULL))
25051 return (-1);
25052 *nsName = NULL;
25053 *localName = NULL;
25054
25055 ret = xmlValidateQName(value, 1);
25056 if (ret == -1)
25057 return (-1);
25058 if (ret > 0) {
25059 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
25061 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
25062 return (1);
25063 }
25064 {
25065 xmlChar *local = NULL;
25066 xmlChar *prefix;
25067
25068 /*
25069 * NOTE: xmlSplitQName2 will return a duplicated
25070 * string.
25071 */
25072 local = xmlSplitQName2(value, &prefix);
25073 if (local == NULL)
25074 *localName = xmlDictLookup(vctxt->dict, value, -1);
25075 else {
25076 *localName = xmlDictLookup(vctxt->dict, local, -1);
25077 xmlFree(local);
25078 }
25079
25080 *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
25081
25082 if (prefix != NULL) {
25083 xmlFree(prefix);
25084 /*
25085 * A namespace must be found if the prefix is NOT NULL.
25086 */
25087 if (*nsName == NULL) {
25088 xmlSchemaCustomErr(ACTXT_CAST vctxt,
25090 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
25091 "The QName value '%s' has no "
25092 "corresponding namespace declaration in scope",
25093 value, NULL);
25094 return (2);
25095 }
25096 }
25097 }
25098 return (0);
25099}
25100
25101static int
25102xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
25103 xmlSchemaAttrInfoPtr iattr,
25104 xmlSchemaTypePtr *localType,
25105 xmlSchemaElementPtr elemDecl)
25106{
25107 int ret = 0;
25108 /*
25109 * cvc-elt (3.3.4) : (4)
25110 * AND
25111 * Schema-Validity Assessment (Element) (cvc-assess-elt)
25112 * (1.2.1.2.1) - (1.2.1.2.4)
25113 * Handle 'xsi:type'.
25114 */
25115 if (localType == NULL)
25116 return (-1);
25117 *localType = NULL;
25118 if (iattr == NULL)
25119 return (0);
25120 else {
25121 const xmlChar *nsName = NULL, *local = NULL;
25122 /*
25123 * TODO: We should report a *warning* that the type was overridden
25124 * by the instance.
25125 */
25126 ACTIVATE_ATTRIBUTE(iattr);
25127 /*
25128 * (cvc-elt) (3.3.4) : (4.1)
25129 * (cvc-assess-elt) (1.2.1.2.2)
25130 */
25131 ret = xmlSchemaVExpandQName(vctxt, iattr->value,
25132 &nsName, &local);
25133 if (ret != 0) {
25134 if (ret < 0) {
25135 VERROR_INT("xmlSchemaValidateElementByDeclaration",
25136 "calling xmlSchemaQNameExpand() to validate the "
25137 "attribute 'xsi:type'");
25138 goto internal_error;
25139 }
25140 goto exit;
25141 }
25142 /*
25143 * (cvc-elt) (3.3.4) : (4.2)
25144 * (cvc-assess-elt) (1.2.1.2.3)
25145 */
25146 *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
25147 if (*localType == NULL) {
25148 xmlChar *str = NULL;
25149
25150 xmlSchemaCustomErr(ACTXT_CAST vctxt,
25152 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
25153 "The QName value '%s' of the xsi:type attribute does not "
25154 "resolve to a type definition",
25155 xmlSchemaFormatQName(&str, nsName, local), NULL);
25156 FREE_AND_NULL(str);
25157 ret = vctxt->err;
25158 goto exit;
25159 }
25160 if (elemDecl != NULL) {
25161 int set = 0;
25162
25163 /*
25164 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
25165 * "The `local type definition` must be validly
25166 * derived from the {type definition} given the union of
25167 * the {disallowed substitutions} and the {type definition}'s
25168 * {prohibited substitutions}, as defined in
25169 * Type Derivation OK (Complex) ($3.4.6)
25170 * (if it is a complex type definition),
25171 * or given {disallowed substitutions} as defined in Type
25172 * Derivation OK (Simple) ($3.14.6) (if it is a simple type
25173 * definition)."
25174 *
25175 * {disallowed substitutions}: the "block" on the element decl.
25176 * {prohibited substitutions}: the "block" on the type def.
25177 */
25178 /*
25179 * OPTIMIZE TODO: We could map types already evaluated
25180 * to be validly derived from other types to avoid checking
25181 * this over and over for the same types.
25182 */
25183 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
25184 (elemDecl->subtypes->flags &
25185 XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
25186 set |= SUBSET_EXTENSION;
25187
25188 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
25189 (elemDecl->subtypes->flags &
25190 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
25191 set |= SUBSET_RESTRICTION;
25192
25193 /*
25194 * REMOVED and CHANGED since this produced a parser context
25195 * which adds to the string dict of the schema. So this would
25196 * change the schema and we don't want this. We don't need
25197 * the parser context anymore.
25198 *
25199 * if ((vctxt->pctxt == NULL) &&
25200 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
25201 * return (-1);
25202 */
25203
25204 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
25205 elemDecl->subtypes, set) != 0) {
25206 xmlChar *str = NULL;
25207
25208 xmlSchemaCustomErr(ACTXT_CAST vctxt,
25210 "The type definition '%s', specified by xsi:type, is "
25211 "blocked or not validly derived from the type definition "
25212 "of the element declaration",
25213 xmlSchemaFormatQName(&str,
25214 (*localType)->targetNamespace,
25215 (*localType)->name),
25216 NULL);
25217 FREE_AND_NULL(str);
25218 ret = vctxt->err;
25219 *localType = NULL;
25220 }
25221 }
25222 }
25223exit:
25224 ACTIVATE_ELEM;
25225 return (ret);
25226internal_error:
25227 ACTIVATE_ELEM;
25228 return (-1);
25229}
25230
25231static int
25232xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
25233{
25234 xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
25235 xmlSchemaTypePtr actualType;
25236
25237 /*
25238 * cvc-elt (3.3.4) : 1
25239 */
25240 if (elemDecl == NULL) {
25242 "No matching declaration available");
25243 return (vctxt->err);
25244 }
25245 actualType = WXS_ELEM_TYPEDEF(elemDecl);
25246 /*
25247 * cvc-elt (3.3.4) : 2
25248 */
25249 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
25251 "The element declaration is abstract");
25252 return (vctxt->err);
25253 }
25254 if (actualType == NULL) {
25256 "The type definition is absent");
25257 return (XML_SCHEMAV_CVC_TYPE_1);
25258 }
25259 if (vctxt->nbAttrInfos != 0) {
25260 int ret;
25261 xmlSchemaAttrInfoPtr iattr;
25262 /*
25263 * cvc-elt (3.3.4) : 3
25264 * Handle 'xsi:nil'.
25265 */
25266 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25267 XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25268 if (iattr) {
25269 ACTIVATE_ATTRIBUTE(iattr);
25270 /*
25271 * Validate the value.
25272 */
25273 ret = xmlSchemaVCheckCVCSimpleType(
25274 ACTXT_CAST vctxt, NULL,
25275 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25276 iattr->value, &(iattr->val), 1, 0, 0);
25277 ACTIVATE_ELEM;
25278 if (ret < 0) {
25279 VERROR_INT("xmlSchemaValidateElemDecl",
25280 "calling xmlSchemaVCheckCVCSimpleType() to "
25281 "validate the attribute 'xsi:nil'");
25282 return (-1);
25283 }
25284 if (ret == 0) {
25285 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25286 /*
25287 * cvc-elt (3.3.4) : 3.1
25288 */
25290 "The element is not 'nillable'");
25291 /* Does not return an error on purpose. */
25292 } else {
25293 if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25294 /*
25295 * cvc-elt (3.3.4) : 3.2.2
25296 */
25297 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25298 (elemDecl->value != NULL)) {
25300 "The element cannot be 'nilled' because "
25301 "there is a fixed value constraint defined "
25302 "for it");
25303 /* Does not return an error on purpose. */
25304 } else
25305 vctxt->inode->flags |=
25306 XML_SCHEMA_ELEM_INFO_NILLED;
25307 }
25308 }
25309 }
25310 }
25311 /*
25312 * cvc-elt (3.3.4) : 4
25313 * Handle 'xsi:type'.
25314 */
25315 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25316 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25317 if (iattr) {
25318 xmlSchemaTypePtr localType = NULL;
25319
25320 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25321 elemDecl);
25322 if (ret != 0) {
25323 if (ret == -1) {
25324 VERROR_INT("xmlSchemaValidateElemDecl",
25325 "calling xmlSchemaProcessXSIType() to "
25326 "process the attribute 'xsi:type'");
25327 return (-1);
25328 }
25329 /* Does not return an error on purpose. */
25330 }
25331 if (localType != NULL) {
25332 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25333 actualType = localType;
25334 }
25335 }
25336 }
25337 /*
25338 * IDC: Register identity-constraint XPath matchers.
25339 */
25340 if ((elemDecl->idcs != NULL) &&
25341 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25342 return (-1);
25343 /*
25344 * No actual type definition.
25345 */
25346 if (actualType == NULL) {
25348 "The type definition is absent");
25349 return (XML_SCHEMAV_CVC_TYPE_1);
25350 }
25351 /*
25352 * Remember the actual type definition.
25353 */
25354 vctxt->inode->typeDef = actualType;
25355
25356 return (0);
25357}
25358
25359static int
25360xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25361{
25362 xmlSchemaAttrInfoPtr iattr;
25363 int ret = 0, i;
25364
25365 /*
25366 * SPEC cvc-type (3.1.1)
25367 * "The attributes of must be empty, excepting those whose namespace
25368 * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25369 * whose local name is one of type, nil, schemaLocation or
25370 * noNamespaceSchemaLocation."
25371 */
25372 if (vctxt->nbAttrInfos == 0)
25373 return (0);
25374 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25375 iattr = vctxt->attrInfos[i];
25376 if (! iattr->metaType) {
25377 ACTIVATE_ATTRIBUTE(iattr)
25378 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25381 }
25382 }
25383 ACTIVATE_ELEM
25384 return (ret);
25385}
25386
25387/*
25388* Cleanup currently used attribute infos.
25389*/
25390static void
25391xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25392{
25393 int i;
25394 xmlSchemaAttrInfoPtr attr;
25395
25396 if (vctxt->nbAttrInfos == 0)
25397 return;
25398 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25399 attr = vctxt->attrInfos[i];
25400 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25401 if (attr->localName != NULL)
25402 xmlFree((xmlChar *) attr->localName);
25403 if (attr->nsName != NULL)
25404 xmlFree((xmlChar *) attr->nsName);
25405 }
25406 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25407 if (attr->value != NULL)
25408 xmlFree((xmlChar *) attr->value);
25409 }
25410 if (attr->val != NULL) {
25411 xmlSchemaFreeValue(attr->val);
25412 attr->val = NULL;
25413 }
25414 memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25415 }
25416 vctxt->nbAttrInfos = 0;
25417}
25418
25419/*
25420* 3.4.4 Complex Type Definition Validation Rules
25421* Element Locally Valid (Complex Type) (cvc-complex-type)
25422* 3.2.4 Attribute Declaration Validation Rules
25423* Validation Rule: Attribute Locally Valid (cvc-attribute)
25424* Attribute Locally Valid (Use) (cvc-au)
25425*
25426* Only "assessed" attribute information items will be visible to
25427* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25428*/
25429static int
25430xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25431{
25432 xmlSchemaTypePtr type = vctxt->inode->typeDef;
25433 xmlSchemaItemListPtr attrUseList;
25434 xmlSchemaAttributeUsePtr attrUse = NULL;
25435 xmlSchemaAttributePtr attrDecl = NULL;
25436 xmlSchemaAttrInfoPtr iattr, tmpiattr;
25437 int i, j, found, nbAttrs, nbUses;
25438 int xpathRes = 0, res, wildIDs = 0, fixed;
25439 xmlNodePtr defAttrOwnerElem = NULL;
25440
25441 /*
25442 * SPEC (cvc-attribute)
25443 * (1) "The declaration must not be `absent` (see Missing
25444 * Sub-components ($5.3) for how this can fail to be
25445 * the case)."
25446 * (2) "Its {type definition} must not be absent."
25447 *
25448 * NOTE (1) + (2): This is not handled here, since we currently do not
25449 * allow validation against schemas which have missing sub-components.
25450 *
25451 * SPEC (cvc-complex-type)
25452 * (3) "For each attribute information item in the element information
25453 * item's [attributes] excepting those whose [namespace name] is
25454 * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25455 * [local name] is one of type, nil, schemaLocation or
25456 * noNamespaceSchemaLocation, the appropriate case among the following
25457 * must be true:
25458 *
25459 */
25460 attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25461 /*
25462 * @nbAttrs is the number of attributes present in the instance.
25463 */
25464 nbAttrs = vctxt->nbAttrInfos;
25465 if (attrUseList != NULL)
25466 nbUses = attrUseList->nbItems;
25467 else
25468 nbUses = 0;
25469 for (i = 0; i < nbUses; i++) {
25470 found = 0;
25471 attrUse = attrUseList->items[i];
25472 attrDecl = WXS_ATTRUSE_DECL(attrUse);
25473 for (j = 0; j < nbAttrs; j++) {
25474 iattr = vctxt->attrInfos[j];
25475 /*
25476 * SPEC (cvc-complex-type) (3)
25477 * Skip meta attributes.
25478 */
25479 if (iattr->metaType)
25480 continue;
25481 if (iattr->localName[0] != attrDecl->name[0])
25482 continue;
25483 if (!xmlStrEqual(iattr->localName, attrDecl->name))
25484 continue;
25485 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25486 continue;
25487 found = 1;
25488 /*
25489 * SPEC (cvc-complex-type)
25490 * (3.1) "If there is among the {attribute uses} an attribute
25491 * use with an {attribute declaration} whose {name} matches
25492 * the attribute information item's [local name] and whose
25493 * {target namespace} is identical to the attribute information
25494 * item's [namespace name] (where an `absent` {target namespace}
25495 * is taken to be identical to a [namespace name] with no value),
25496 * then the attribute information must be `valid` with respect
25497 * to that attribute use as per Attribute Locally Valid (Use)
25498 * ($3.5.4). In this case the {attribute declaration} of that
25499 * attribute use is the `context-determined declaration` for the
25500 * attribute information item with respect to Schema-Validity
25501 * Assessment (Attribute) ($3.2.4) and
25502 * Assessment Outcome (Attribute) ($3.2.5).
25503 */
25504 iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25505 iattr->use = attrUse;
25506 /*
25507 * Context-determined declaration.
25508 */
25509 iattr->decl = attrDecl;
25510 iattr->typeDef = attrDecl->subtypes;
25511 break;
25512 }
25513
25514 if (found)
25515 continue;
25516
25517 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25518 /*
25519 * Handle non-existent, required attributes.
25520 *
25521 * SPEC (cvc-complex-type)
25522 * (4) "The {attribute declaration} of each attribute use in
25523 * the {attribute uses} whose {required} is true matches one
25524 * of the attribute information items in the element information
25525 * item's [attributes] as per clause 3.1 above."
25526 */
25527 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25528 if (tmpiattr == NULL) {
25529 VERROR_INT(
25530 "xmlSchemaVAttributesComplex",
25531 "calling xmlSchemaGetFreshAttrInfo()");
25532 return (-1);
25533 }
25534 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25535 tmpiattr->use = attrUse;
25536 tmpiattr->decl = attrDecl;
25537 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25538 ((attrUse->defValue != NULL) ||
25539 (attrDecl->defValue != NULL))) {
25540 /*
25541 * Handle non-existent, optional, default/fixed attributes.
25542 */
25543 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25544 if (tmpiattr == NULL) {
25545 VERROR_INT(
25546 "xmlSchemaVAttributesComplex",
25547 "calling xmlSchemaGetFreshAttrInfo()");
25548 return (-1);
25549 }
25550 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25551 tmpiattr->use = attrUse;
25552 tmpiattr->decl = attrDecl;
25553 tmpiattr->typeDef = attrDecl->subtypes;
25554 tmpiattr->localName = attrDecl->name;
25555 tmpiattr->nsName = attrDecl->targetNamespace;
25556 }
25557 }
25558
25559 if (vctxt->nbAttrInfos == 0)
25560 return (0);
25561 /*
25562 * Validate against the wildcard.
25563 */
25564 if (type->attributeWildcard != NULL) {
25565 /*
25566 * SPEC (cvc-complex-type)
25567 * (3.2.1) "There must be an {attribute wildcard}."
25568 */
25569 for (i = 0; i < nbAttrs; i++) {
25570 iattr = vctxt->attrInfos[i];
25571 /*
25572 * SPEC (cvc-complex-type) (3)
25573 * Skip meta attributes.
25574 */
25575 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25576 continue;
25577 /*
25578 * SPEC (cvc-complex-type)
25579 * (3.2.2) "The attribute information item must be `valid` with
25580 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25581 *
25582 * SPEC Item Valid (Wildcard) (cvc-wildcard)
25583 * "... its [namespace name] must be `valid` with respect to
25584 * the wildcard constraint, as defined in Wildcard allows
25585 * Namespace Name ($3.10.4)."
25586 */
25587 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25588 iattr->nsName) == 0) {
25589 /*
25590 * Handle processContents.
25591 *
25592 * SPEC (cvc-wildcard):
25593 * processContents | context-determined declaration:
25594 * "strict" "mustFind"
25595 * "lax" "none"
25596 * "skip" "skip"
25597 */
25598 if (type->attributeWildcard->processContents ==
25599 XML_SCHEMAS_ANY_SKIP) {
25600 /*
25601 * context-determined declaration = "skip"
25602 *
25603 * SPEC PSVI Assessment Outcome (Attribute)
25604 * [validity] = "notKnown"
25605 * [validation attempted] = "none"
25606 */
25607 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25608 continue;
25609 }
25610 /*
25611 * Find an attribute declaration.
25612 */
25613 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25614 iattr->localName, iattr->nsName);
25615 if (iattr->decl != NULL) {
25616 iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25617 /*
25618 * SPEC (cvc-complex-type)
25619 * (5) "Let [Definition:] the wild IDs be the set of
25620 * all attribute information item to which clause 3.2
25621 * applied and whose `validation` resulted in a
25622 * `context-determined declaration` of mustFind or no
25623 * `context-determined declaration` at all, and whose
25624 * [local name] and [namespace name] resolve (as
25625 * defined by QName resolution (Instance) ($3.15.4)) to
25626 * an attribute declaration whose {type definition} is
25627 * or is derived from ID. Then all of the following
25628 * must be true:"
25629 */
25630 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25631 if (xmlSchemaIsDerivedFromBuiltInType(
25632 iattr->typeDef, XML_SCHEMAS_ID)) {
25633 /*
25634 * SPEC (5.1) "There must be no more than one
25635 * item in `wild IDs`."
25636 */
25637 if (wildIDs != 0) {
25638 /* VAL TODO */
25639 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25640 TODO
25641 continue;
25642 }
25643 wildIDs++;
25644 /*
25645 * SPEC (cvc-complex-type)
25646 * (5.2) "If `wild IDs` is non-empty, there must not
25647 * be any attribute uses among the {attribute uses}
25648 * whose {attribute declaration}'s {type definition}
25649 * is or is derived from ID."
25650 */
25651 if (attrUseList != NULL) {
25652 for (j = 0; j < attrUseList->nbItems; j++) {
25653 if (xmlSchemaIsDerivedFromBuiltInType(
25654 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25655 XML_SCHEMAS_ID)) {
25656 /* URGENT VAL TODO: implement */
25657 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25658 TODO
25659 break;
25660 }
25661 }
25662 }
25663 }
25664 } else if (type->attributeWildcard->processContents ==
25665 XML_SCHEMAS_ANY_LAX) {
25666 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25667 /*
25668 * SPEC PSVI Assessment Outcome (Attribute)
25669 * [validity] = "notKnown"
25670 * [validation attempted] = "none"
25671 */
25672 } else {
25673 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25674 }
25675 }
25676 }
25677 }
25678
25679 if (vctxt->nbAttrInfos == 0)
25680 return (0);
25681
25682 /*
25683 * Get the owner element; needed for creation of default attributes.
25684 * This fixes bug #341337, reported by David Grohmann.
25685 */
25686 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25687 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25688 if (ielem && ielem->node && ielem->node->doc)
25689 defAttrOwnerElem = ielem->node;
25690 }
25691 /*
25692 * Validate values, create default attributes, evaluate IDCs.
25693 */
25694 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25695 iattr = vctxt->attrInfos[i];
25696 /*
25697 * VAL TODO: Note that we won't try to resolve IDCs to
25698 * "lax" and "skip" validated attributes. Check what to
25699 * do in this case.
25700 */
25701 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25702 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25703 continue;
25704 /*
25705 * VAL TODO: What to do if the type definition is missing?
25706 */
25707 if (iattr->typeDef == NULL) {
25708 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25709 continue;
25710 }
25711
25712 ACTIVATE_ATTRIBUTE(iattr);
25713 fixed = 0;
25714 xpathRes = 0;
25715
25716 if (vctxt->xpathStates != NULL) {
25717 /*
25718 * Evaluate IDCs.
25719 */
25720 xpathRes = xmlSchemaXPathEvaluate(vctxt,
25722 if (xpathRes == -1) {
25723 VERROR_INT("xmlSchemaVAttributesComplex",
25724 "calling xmlSchemaXPathEvaluate()");
25725 goto internal_error;
25726 }
25727 }
25728
25729 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25730 /*
25731 * Default/fixed attributes.
25732 * We need the value only if we need to resolve IDCs or
25733 * will create default attributes.
25734 */
25735 if ((xpathRes) || (defAttrOwnerElem)) {
25736 if (iattr->use->defValue != NULL) {
25737 iattr->value = (xmlChar *) iattr->use->defValue;
25738 iattr->val = iattr->use->defVal;
25739 } else {
25740 iattr->value = (xmlChar *) iattr->decl->defValue;
25741 iattr->val = iattr->decl->defVal;
25742 }
25743 /*
25744 * IDCs will consume the precomputed default value,
25745 * so we need to clone it.
25746 */
25747 if (iattr->val == NULL) {
25748 VERROR_INT("xmlSchemaVAttributesComplex",
25749 "default/fixed value on an attribute use was "
25750 "not precomputed");
25751 goto internal_error;
25752 }
25753 iattr->val = xmlSchemaCopyValue(iattr->val);
25754 if (iattr->val == NULL) {
25755 VERROR_INT("xmlSchemaVAttributesComplex",
25756 "calling xmlSchemaCopyValue()");
25757 goto internal_error;
25758 }
25759 }
25760 /*
25761 * PSVI: Add the default attribute to the current element.
25762 * VAL TODO: Should we use the *normalized* value? This currently
25763 * uses the *initial* value.
25764 */
25765
25766 if (defAttrOwnerElem) {
25767 xmlChar *normValue;
25768 const xmlChar *value;
25769
25770 value = iattr->value;
25771 /*
25772 * Normalize the value.
25773 */
25774 normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25775 iattr->value);
25776 if (normValue != NULL)
25777 value = BAD_CAST normValue;
25778
25779 if (iattr->nsName == NULL) {
25780 if (xmlNewProp(defAttrOwnerElem,
25781 iattr->localName, value) == NULL) {
25782 VERROR_INT("xmlSchemaVAttributesComplex",
25783 "calling xmlNewProp()");
25784 if (normValue != NULL)
25785 xmlFree(normValue);
25786 goto internal_error;
25787 }
25788 } else {
25789 xmlNsPtr ns;
25790
25791 ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25792 defAttrOwnerElem, iattr->nsName);
25793 if (ns == NULL) {
25794 xmlChar prefix[12];
25795 int counter = 0;
25796
25797 /*
25798 * Create a namespace declaration on the validation
25799 * root node if no namespace declaration is in scope.
25800 */
25801 do {
25802 snprintf((char *) prefix, 12, "p%d", counter++);
25803 ns = xmlSearchNs(defAttrOwnerElem->doc,
25804 defAttrOwnerElem, BAD_CAST prefix);
25805 if (counter > 1000) {
25806 VERROR_INT(
25807 "xmlSchemaVAttributesComplex",
25808 "could not compute a ns prefix for a "
25809 "default/fixed attribute");
25810 if (normValue != NULL)
25811 xmlFree(normValue);
25812 goto internal_error;
25813 }
25814 } while (ns != NULL);
25815 ns = xmlNewNs(vctxt->validationRoot,
25816 iattr->nsName, BAD_CAST prefix);
25817 }
25818 /*
25819 * TODO:
25820 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25821 * If we have QNames: do we need to ensure there's a
25822 * prefix defined for the QName?
25823 */
25824 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25825 }
25826 if (normValue != NULL)
25827 xmlFree(normValue);
25828 }
25829 /*
25830 * Go directly to IDC evaluation.
25831 */
25832 goto eval_idcs;
25833 }
25834 /*
25835 * Validate the value.
25836 */
25837 if (vctxt->value != NULL) {
25838 /*
25839 * Free last computed value; just for safety reasons.
25840 */
25841 xmlSchemaFreeValue(vctxt->value);
25842 vctxt->value = NULL;
25843 }
25844 /*
25845 * Note that the attribute *use* can be unavailable, if
25846 * the attribute was a wild attribute.
25847 */
25848 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25849 ((iattr->use != NULL) &&
25850 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25851 fixed = 1;
25852 else
25853 fixed = 0;
25854 /*
25855 * SPEC (cvc-attribute)
25856 * (3) "The item's `normalized value` must be locally `valid`
25857 * with respect to that {type definition} as per
25858 * String Valid ($3.14.4)."
25859 *
25860 * VAL TODO: Do we already have the
25861 * "normalized attribute value" here?
25862 */
25863 if (xpathRes || fixed) {
25864 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25865 /*
25866 * Request a computed value.
25867 */
25868 res = xmlSchemaVCheckCVCSimpleType(
25869 ACTXT_CAST vctxt,
25870 iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25871 1, 1, 0);
25872 } else {
25873 res = xmlSchemaVCheckCVCSimpleType(
25874 ACTXT_CAST vctxt,
25875 iattr->node, iattr->typeDef, iattr->value, NULL,
25876 1, 0, 0);
25877 }
25878
25879 if (res != 0) {
25880 if (res == -1) {
25881 VERROR_INT("xmlSchemaVAttributesComplex",
25882 "calling xmlSchemaStreamValidateSimpleTypeValue()");
25883 goto internal_error;
25884 }
25885 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25886 /*
25887 * SPEC PSVI Assessment Outcome (Attribute)
25888 * [validity] = "invalid"
25889 */
25890 goto eval_idcs;
25891 }
25892
25893 if (fixed) {
25894 /*
25895 * SPEC Attribute Locally Valid (Use) (cvc-au)
25896 * "For an attribute information item to be `valid`
25897 * with respect to an attribute use its *normalized*
25898 * value must match the *canonical* lexical
25899 * representation of the attribute use's {value
25900 * constraint}value, if it is present and fixed."
25901 *
25902 * VAL TODO: The requirement for the *canonical* value
25903 * will be removed in XML Schema 1.1.
25904 */
25905 /*
25906 * SPEC Attribute Locally Valid (cvc-attribute)
25907 * (4) "The item's *actual* value must match the *value* of
25908 * the {value constraint}, if it is present and fixed."
25909 */
25910 if (iattr->val == NULL) {
25911 /* VAL TODO: A value was not precomputed. */
25912 TODO
25913 goto eval_idcs;
25914 }
25915 if ((iattr->use != NULL) &&
25916 (iattr->use->defValue != NULL)) {
25917 if (iattr->use->defVal == NULL) {
25918 /* VAL TODO: A default value was not precomputed. */
25919 TODO
25920 goto eval_idcs;
25921 }
25922 iattr->vcValue = iattr->use->defValue;
25923 /*
25924 if (xmlSchemaCompareValuesWhtsp(attr->val,
25925 (xmlSchemaWhitespaceValueType) ws,
25926 attr->use->defVal,
25927 (xmlSchemaWhitespaceValueType) ws) != 0) {
25928 */
25929 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25930 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25931 } else {
25932 if (iattr->decl->defVal == NULL) {
25933 /* VAL TODO: A default value was not precomputed. */
25934 TODO
25935 goto eval_idcs;
25936 }
25937 iattr->vcValue = iattr->decl->defValue;
25938 /*
25939 if (xmlSchemaCompareValuesWhtsp(attr->val,
25940 (xmlSchemaWhitespaceValueType) ws,
25941 attrDecl->defVal,
25942 (xmlSchemaWhitespaceValueType) ws) != 0) {
25943 */
25944 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25945 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25946 }
25947 /*
25948 * [validity] = "valid"
25949 */
25950 }
25951eval_idcs:
25952 /*
25953 * Evaluate IDCs.
25954 */
25955 if (xpathRes) {
25956 if (xmlSchemaXPathProcessHistory(vctxt,
25957 vctxt->depth +1) == -1) {
25958 VERROR_INT("xmlSchemaVAttributesComplex",
25959 "calling xmlSchemaXPathEvaluate()");
25960 goto internal_error;
25961 }
25962 } else if (vctxt->xpathStates != NULL)
25963 xmlSchemaXPathPop(vctxt);
25964 }
25965
25966 /*
25967 * Report errors.
25968 */
25969 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25970 iattr = vctxt->attrInfos[i];
25971 if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25972 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25973 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25974 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25975 continue;
25976 ACTIVATE_ATTRIBUTE(iattr);
25977 switch (iattr->state) {
25978 case XML_SCHEMAS_ATTR_ERR_MISSING: {
25979 xmlChar *str = NULL;
25980 ACTIVATE_ELEM;
25981 xmlSchemaCustomErr(ACTXT_CAST vctxt,
25983 "The attribute '%s' is required but missing",
25984 xmlSchemaFormatQName(&str,
25985 iattr->decl->targetNamespace,
25986 iattr->decl->name),
25987 NULL);
25988 FREE_AND_NULL(str)
25989 break;
25990 }
25991 case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25993 "The type definition is absent");
25994 break;
25995 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25996 xmlSchemaCustomErr(ACTXT_CAST vctxt,
25998 "The value '%s' does not match the fixed "
25999 "value constraint '%s'",
26000 iattr->value, iattr->vcValue);
26001 break;
26002 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
26004 "No matching global attribute declaration available, but "
26005 "demanded by the strict wildcard");
26006 break;
26007 case XML_SCHEMAS_ATTR_UNKNOWN:
26008 if (iattr->metaType)
26009 break;
26010 /*
26011 * MAYBE VAL TODO: One might report different error messages
26012 * for the following errors.
26013 */
26014 if (type->attributeWildcard == NULL) {
26015 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
26017 } else {
26018 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
26020 }
26021 break;
26022 default:
26023 break;
26024 }
26025 }
26026
26027 ACTIVATE_ELEM;
26028 return (0);
26029internal_error:
26030 ACTIVATE_ELEM;
26031 return (-1);
26032}
26033
26034static int
26035xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
26036 int *skip)
26037{
26038 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
26039 /*
26040 * The namespace of the element was already identified to be
26041 * matching the wildcard.
26042 */
26043 if ((skip == NULL) || (wild == NULL) ||
26044 (wild->type != XML_SCHEMA_TYPE_ANY)) {
26045 VERROR_INT("xmlSchemaValidateElemWildcard",
26046 "bad arguments");
26047 return (-1);
26048 }
26049 *skip = 0;
26050 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
26051 /*
26052 * URGENT VAL TODO: Either we need to position the stream to the
26053 * next sibling, or walk the whole subtree.
26054 */
26055 *skip = 1;
26056 return (0);
26057 }
26058 {
26059 xmlSchemaElementPtr decl = NULL;
26060
26061 decl = xmlSchemaGetElem(vctxt->schema,
26062 vctxt->inode->localName, vctxt->inode->nsName);
26063 if (decl != NULL) {
26064 vctxt->inode->decl = decl;
26065 return (0);
26066 }
26067 }
26068 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
26069 /* VAL TODO: Change to proper error code. */
26070 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
26071 "No matching global element declaration available, but "
26072 "demanded by the strict wildcard");
26073 return (vctxt->err);
26074 }
26075 if (vctxt->nbAttrInfos != 0) {
26076 xmlSchemaAttrInfoPtr iattr;
26077 /*
26078 * SPEC Validation Rule: Schema-Validity Assessment (Element)
26079 * (1.2.1.2.1) - (1.2.1.2.3 )
26080 *
26081 * Use the xsi:type attribute for the type definition.
26082 */
26083 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26084 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26085 if (iattr != NULL) {
26086 if (xmlSchemaProcessXSIType(vctxt, iattr,
26087 &(vctxt->inode->typeDef), NULL) == -1) {
26088 VERROR_INT("xmlSchemaValidateElemWildcard",
26089 "calling xmlSchemaProcessXSIType() to "
26090 "process the attribute 'xsi:nil'");
26091 return (-1);
26092 }
26093 /*
26094 * Don't return an error on purpose.
26095 */
26096 return (0);
26097 }
26098 }
26099 /*
26100 * SPEC Validation Rule: Schema-Validity Assessment (Element)
26101 *
26102 * Fallback to "anyType".
26103 */
26104 vctxt->inode->typeDef =
26105 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26106 return (0);
26107}
26108
26109/*
26110* xmlSchemaCheckCOSValidDefault:
26111*
26112* This will be called if: not nilled, no content and a default/fixed
26113* value is provided.
26114*/
26115
26116static int
26117xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
26118 const xmlChar *value,
26119 xmlSchemaValPtr *val)
26120{
26121 int ret = 0;
26122 xmlSchemaNodeInfoPtr inode = vctxt->inode;
26123
26124 /*
26125 * cos-valid-default:
26126 * Schema Component Constraint: Element Default Valid (Immediate)
26127 * For a string to be a valid default with respect to a type
26128 * definition the appropriate case among the following must be true:
26129 */
26130 if WXS_IS_COMPLEX(inode->typeDef) {
26131 /*
26132 * Complex type.
26133 *
26134 * SPEC (2.1) "its {content type} must be a simple type definition
26135 * or mixed."
26136 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
26137 * type}'s particle must be `emptiable` as defined by
26138 * Particle Emptiable ($3.9.6)."
26139 */
26140 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
26141 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
26142 (! WXS_EMPTIABLE(inode->typeDef)))) {
26144 /* NOTE that this covers (2.2.2) as well. */
26145 VERROR(ret, NULL,
26146 "For a string to be a valid default, the type definition "
26147 "must be a simple type or a complex type with simple content "
26148 "or mixed content and a particle emptiable");
26149 return(ret);
26150 }
26151 }
26152 /*
26153 * 1 If the type definition is a simple type definition, then the string
26154 * must be `valid` with respect to that definition as defined by String
26155 * Valid ($3.14.4).
26156 *
26157 * AND
26158 *
26159 * 2.2.1 If the {content type} is a simple type definition, then the
26160 * string must be `valid` with respect to that simple type definition
26161 * as defined by String Valid ($3.14.4).
26162 */
26163 if (WXS_IS_SIMPLE(inode->typeDef)) {
26164
26165 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
26166 NULL, inode->typeDef, value, val, 1, 1, 0);
26167
26168 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26169
26170 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
26171 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
26172 }
26173 if (ret < 0) {
26174 VERROR_INT("xmlSchemaCheckCOSValidDefault",
26175 "calling xmlSchemaVCheckCVCSimpleType()");
26176 }
26177 return (ret);
26178}
26179
26180static void
26181xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
26183 void *transdata, void *inputdata)
26184{
26185 xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
26186 xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
26187 inode->decl = item;
26188#ifdef DEBUG_CONTENT
26189 {
26190 xmlChar *str = NULL;
26191
26192 if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
26194 "AUTOMATON callback for '%s' [declaration]\n",
26195 xmlSchemaFormatQName(&str,
26196 inode->localName, inode->nsName));
26197 } else {
26199 "AUTOMATON callback for '%s' [wildcard]\n",
26200 xmlSchemaFormatQName(&str,
26201 inode->localName, inode->nsName));
26202
26203 }
26204 FREE_AND_NULL(str)
26205 }
26206#endif
26207}
26208
26209static int
26210xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
26211{
26212 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
26213 if (vctxt->inode == NULL) {
26214 VERROR_INT("xmlSchemaValidatorPushElem",
26215 "calling xmlSchemaGetFreshElemInfo()");
26216 return (-1);
26217 }
26218 vctxt->nbAttrInfos = 0;
26219 return (0);
26220}
26221
26222static int
26223xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
26224 xmlSchemaNodeInfoPtr inode,
26225 xmlSchemaTypePtr type,
26226 const xmlChar *value)
26227{
26228 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
26229 return (xmlSchemaVCheckCVCSimpleType(
26230 ACTXT_CAST vctxt, NULL,
26231 type, value, &(inode->val), 1, 1, 0));
26232 else
26233 return (xmlSchemaVCheckCVCSimpleType(
26234 ACTXT_CAST vctxt, NULL,
26235 type, value, NULL, 1, 0, 0));
26236}
26237
26238
26239
26240/*
26241* Process END of element.
26242*/
26243static int
26244xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
26245{
26246 int ret = 0;
26247 xmlSchemaNodeInfoPtr inode = vctxt->inode;
26248
26249 if (vctxt->nbAttrInfos != 0)
26250 xmlSchemaClearAttrInfos(vctxt);
26251 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
26252 /*
26253 * This element was not expected;
26254 * we will not validate child elements of broken parents.
26255 * Skip validation of all content of the parent.
26256 */
26257 vctxt->skipDepth = vctxt->depth -1;
26258 goto end_elem;
26259 }
26260 if ((inode->typeDef == NULL) ||
26261 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
26262 /*
26263 * 1. the type definition might be missing if the element was
26264 * error prone
26265 * 2. it might be abstract.
26266 */
26267 goto end_elem;
26268 }
26269 /*
26270 * Check the content model.
26271 */
26272 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
26273 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
26274
26275 /*
26276 * Workaround for "anyType".
26277 */
26278 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26279 goto character_content;
26280
26281 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
26282 xmlChar *values[10];
26283 int terminal, nbval = 10, nbneg;
26284
26285 if (inode->regexCtxt == NULL) {
26286 /*
26287 * Create the regex context.
26288 */
26289 inode->regexCtxt =
26290 xmlRegNewExecCtxt(inode->typeDef->contModel,
26291 xmlSchemaVContentModelCallback, vctxt);
26292 if (inode->regexCtxt == NULL) {
26293 VERROR_INT("xmlSchemaValidatorPopElem",
26294 "failed to create a regex context");
26295 goto internal_error;
26296 }
26297#ifdef DEBUG_AUTOMATA
26299 "AUTOMATON create on '%s'\n", inode->localName);
26300#endif
26301 }
26302
26303 /*
26304 * Do not check further content if the node has been nilled
26305 */
26306 if (INODE_NILLED(inode)) {
26307 ret = 0;
26308#ifdef DEBUG_AUTOMATA
26310 "AUTOMATON succeeded on nilled '%s'\n",
26311 inode->localName);
26312#endif
26313 goto skip_nilled;
26314 }
26315
26316 /*
26317 * Get hold of the still expected content, since a further
26318 * call to xmlRegExecPushString() will lose this information.
26319 */
26320 xmlRegExecNextValues(inode->regexCtxt,
26321 &nbval, &nbneg, &values[0], &terminal);
26322 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26323 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26324 /*
26325 * Still missing something.
26326 */
26327 ret = 1;
26328 inode->flags |=
26329 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26330 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26332 "Missing child element(s)",
26333 nbval, nbneg, values);
26334#ifdef DEBUG_AUTOMATA
26336 "AUTOMATON missing ERROR on '%s'\n",
26337 inode->localName);
26338#endif
26339 } else {
26340 /*
26341 * Content model is satisfied.
26342 */
26343 ret = 0;
26344#ifdef DEBUG_AUTOMATA
26346 "AUTOMATON succeeded on '%s'\n",
26347 inode->localName);
26348#endif
26349 }
26350
26351 }
26352 }
26353
26354skip_nilled:
26355
26356 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26357 goto end_elem;
26358
26359character_content:
26360
26361 if (vctxt->value != NULL) {
26362 xmlSchemaFreeValue(vctxt->value);
26363 vctxt->value = NULL;
26364 }
26365 /*
26366 * Check character content.
26367 */
26368 if (inode->decl == NULL) {
26369 /*
26370 * Speedup if no declaration exists.
26371 */
26372 if (WXS_IS_SIMPLE(inode->typeDef)) {
26373 ret = xmlSchemaVCheckINodeDataType(vctxt,
26374 inode, inode->typeDef, inode->value);
26375 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26376 ret = xmlSchemaVCheckINodeDataType(vctxt,
26377 inode, inode->typeDef->contentTypeDef,
26378 inode->value);
26379 }
26380 if (ret < 0) {
26381 VERROR_INT("xmlSchemaValidatorPopElem",
26382 "calling xmlSchemaVCheckCVCSimpleType()");
26383 goto internal_error;
26384 }
26385 goto end_elem;
26386 }
26387 /*
26388 * cvc-elt (3.3.4) : 5
26389 * The appropriate case among the following must be true:
26390 */
26391 /*
26392 * cvc-elt (3.3.4) : 5.1
26393 * If the declaration has a {value constraint},
26394 * the item has neither element nor character [children] and
26395 * clause 3.2 has not applied, then all of the following must be true:
26396 */
26397 if ((inode->decl->value != NULL) &&
26398 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26399 (! INODE_NILLED(inode))) {
26400 /*
26401 * cvc-elt (3.3.4) : 5.1.1
26402 * If the `actual type definition` is a `local type definition`
26403 * then the canonical lexical representation of the {value constraint}
26404 * value must be a valid default for the `actual type definition` as
26405 * defined in Element Default Valid (Immediate) ($3.3.6).
26406 */
26407 /*
26408 * NOTE: 'local' above means types acquired by xsi:type.
26409 * NOTE: Although the *canonical* value is stated, it is not
26410 * relevant if canonical or not. Additionally XML Schema 1.1
26411 * will removed this requirement as well.
26412 */
26413 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26414
26415 ret = xmlSchemaCheckCOSValidDefault(vctxt,
26416 inode->decl->value, &(inode->val));
26417 if (ret != 0) {
26418 if (ret < 0) {
26419 VERROR_INT("xmlSchemaValidatorPopElem",
26420 "calling xmlSchemaCheckCOSValidDefault()");
26421 goto internal_error;
26422 }
26423 goto end_elem;
26424 }
26425 /*
26426 * Stop here, to avoid redundant validation of the value
26427 * (see following).
26428 */
26429 goto default_psvi;
26430 }
26431 /*
26432 * cvc-elt (3.3.4) : 5.1.2
26433 * The element information item with the canonical lexical
26434 * representation of the {value constraint} value used as its
26435 * `normalized value` must be `valid` with respect to the
26436 * `actual type definition` as defined by Element Locally Valid (Type)
26437 * ($3.3.4).
26438 */
26439 if (WXS_IS_SIMPLE(inode->typeDef)) {
26440 ret = xmlSchemaVCheckINodeDataType(vctxt,
26441 inode, inode->typeDef, inode->decl->value);
26442 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26443 ret = xmlSchemaVCheckINodeDataType(vctxt,
26444 inode, inode->typeDef->contentTypeDef,
26445 inode->decl->value);
26446 }
26447 if (ret != 0) {
26448 if (ret < 0) {
26449 VERROR_INT("xmlSchemaValidatorPopElem",
26450 "calling xmlSchemaVCheckCVCSimpleType()");
26451 goto internal_error;
26452 }
26453 goto end_elem;
26454 }
26455
26456default_psvi:
26457 /*
26458 * PSVI: Create a text node on the instance element.
26459 */
26460 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26461 (inode->node != NULL)) {
26462 xmlNodePtr textChild;
26463 xmlChar *normValue;
26464 /*
26465 * VAL TODO: Normalize the value.
26466 */
26467 normValue = xmlSchemaNormalizeValue(inode->typeDef,
26468 inode->decl->value);
26469 if (normValue != NULL) {
26470 textChild = xmlNewDocText(inode->node->doc,
26471 BAD_CAST normValue);
26472 xmlFree(normValue);
26473 } else
26474 textChild = xmlNewDocText(inode->node->doc,
26475 inode->decl->value);
26476 if (textChild == NULL) {
26477 VERROR_INT("xmlSchemaValidatorPopElem",
26478 "calling xmlNewDocText()");
26479 goto internal_error;
26480 } else
26481 xmlAddChild(inode->node, textChild);
26482 }
26483
26484 } else if (! INODE_NILLED(inode)) {
26485 /*
26486 * 5.2.1 The element information item must be `valid` with respect
26487 * to the `actual type definition` as defined by Element Locally
26488 * Valid (Type) ($3.3.4).
26489 */
26490 if (WXS_IS_SIMPLE(inode->typeDef)) {
26491 /*
26492 * SPEC (cvc-type) (3.1)
26493 * "If the type definition is a simple type definition, ..."
26494 * (3.1.3) "If clause 3.2 of Element Locally Valid
26495 * (Element) ($3.3.4) did not apply, then the `normalized value`
26496 * must be `valid` with respect to the type definition as defined
26497 * by String Valid ($3.14.4).
26498 */
26499 ret = xmlSchemaVCheckINodeDataType(vctxt,
26500 inode, inode->typeDef, inode->value);
26501 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26502 /*
26503 * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26504 * definition, then the element information item must be
26505 * `valid` with respect to the type definition as per
26506 * Element Locally Valid (Complex Type) ($3.4.4);"
26507 *
26508 * SPEC (cvc-complex-type) (2.2)
26509 * "If the {content type} is a simple type definition, ...
26510 * the `normalized value` of the element information item is
26511 * `valid` with respect to that simple type definition as
26512 * defined by String Valid ($3.14.4)."
26513 */
26514 ret = xmlSchemaVCheckINodeDataType(vctxt,
26515 inode, inode->typeDef->contentTypeDef, inode->value);
26516 }
26517 if (ret != 0) {
26518 if (ret < 0) {
26519 VERROR_INT("xmlSchemaValidatorPopElem",
26520 "calling xmlSchemaVCheckCVCSimpleType()");
26521 goto internal_error;
26522 }
26523 goto end_elem;
26524 }
26525 /*
26526 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26527 * not applied, all of the following must be true:
26528 */
26529 if ((inode->decl->value != NULL) &&
26530 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26531
26532 /*
26533 * TODO: We will need a computed value, when comparison is
26534 * done on computed values.
26535 */
26536 /*
26537 * 5.2.2.1 The element information item must have no element
26538 * information item [children].
26539 */
26540 if (inode->flags &
26541 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26543 VERROR(ret, NULL,
26544 "The content must not contain element nodes since "
26545 "there is a fixed value constraint");
26546 goto end_elem;
26547 } else {
26548 /*
26549 * 5.2.2.2 The appropriate case among the following must
26550 * be true:
26551 */
26552 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26553 /*
26554 * 5.2.2.2.1 If the {content type} of the `actual type
26555 * definition` is mixed, then the *initial value* of the
26556 * item must match the canonical lexical representation
26557 * of the {value constraint} value.
26558 *
26559 * ... the *initial value* of an element information
26560 * item is the string composed of, in order, the
26561 * [character code] of each character information item in
26562 * the [children] of that element information item.
26563 */
26564 if (! xmlStrEqual(inode->value, inode->decl->value)){
26565 /*
26566 * VAL TODO: Report invalid & expected values as well.
26567 * VAL TODO: Implement the canonical stuff.
26568 */
26570 xmlSchemaCustomErr(ACTXT_CAST vctxt,
26571 ret, NULL, NULL,
26572 "The initial value '%s' does not match the fixed "
26573 "value constraint '%s'",
26574 inode->value, inode->decl->value);
26575 goto end_elem;
26576 }
26577 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26578 /*
26579 * 5.2.2.2.2 If the {content type} of the `actual type
26580 * definition` is a simple type definition, then the
26581 * *actual value* of the item must match the canonical
26582 * lexical representation of the {value constraint} value.
26583 */
26584 /*
26585 * VAL TODO: *actual value* is the normalized value, impl.
26586 * this.
26587 * VAL TODO: Report invalid & expected values as well.
26588 * VAL TODO: Implement a comparison with the computed values.
26589 */
26590 if (! xmlStrEqual(inode->value,
26591 inode->decl->value)) {
26593 xmlSchemaCustomErr(ACTXT_CAST vctxt,
26594 ret, NULL, NULL,
26595 "The actual value '%s' does not match the fixed "
26596 "value constraint '%s'",
26597 inode->value,
26598 inode->decl->value);
26599 goto end_elem;
26600 }
26601 }
26602 }
26603 }
26604 }
26605
26606end_elem:
26607 if (vctxt->depth < 0) {
26608 /* TODO: raise error? */
26609 return (0);
26610 }
26611 if (vctxt->depth == vctxt->skipDepth)
26612 vctxt->skipDepth = -1;
26613 /*
26614 * Evaluate the history of XPath state objects.
26615 */
26616 if (inode->appliedXPath &&
26617 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26618 goto internal_error;
26619 /*
26620 * MAYBE TODO:
26621 * SPEC (6) "The element information item must be `valid` with
26622 * respect to each of the {identity-constraint definitions} as per
26623 * Identity-constraint Satisfied ($3.11.4)."
26624 */
26625 /*
26626 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26627 * need to be built in any case.
26628 * We will currently build IDC node-tables and bubble them only if
26629 * keyrefs do exist.
26630 */
26631
26632 /*
26633 * Add the current IDC target-nodes to the IDC node-tables.
26634 */
26635 if ((inode->idcMatchers != NULL) &&
26636 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26637 {
26638 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26639 goto internal_error;
26640 }
26641 /*
26642 * Validate IDC keyrefs.
26643 */
26644 if (vctxt->inode->hasKeyrefs)
26645 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26646 goto internal_error;
26647 /*
26648 * Merge/free the IDC table.
26649 */
26650 if (inode->idcTable != NULL) {
26651#ifdef DEBUG_IDC_NODE_TABLE
26652 xmlSchemaDebugDumpIDCTable(stdout,
26653 inode->nsName,
26654 inode->localName,
26655 inode->idcTable);
26656#endif
26657 if ((vctxt->depth > 0) &&
26658 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26659 {
26660 /*
26661 * Merge the IDC node table with the table of the parent node.
26662 */
26663 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26664 goto internal_error;
26665 }
26666 }
26667 /*
26668 * Clear the current ielem.
26669 * VAL TODO: Don't free the PSVI IDC tables if they are
26670 * requested for the PSVI.
26671 */
26672 xmlSchemaClearElemInfo(vctxt, inode);
26673 /*
26674 * Skip further processing if we are on the validation root.
26675 */
26676 if (vctxt->depth == 0) {
26677 vctxt->depth--;
26678 vctxt->inode = NULL;
26679 return (0);
26680 }
26681 /*
26682 * Reset the keyrefDepth if needed.
26683 */
26684 if (vctxt->aidcs != NULL) {
26685 xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26686 do {
26687 if (aidc->keyrefDepth == vctxt->depth) {
26688 /*
26689 * A 'keyrefDepth' of a key/unique IDC matches the current
26690 * depth, this means that we are leaving the scope of the
26691 * top-most keyref IDC which refers to this IDC.
26692 */
26693 aidc->keyrefDepth = -1;
26694 }
26695 aidc = aidc->next;
26696 } while (aidc != NULL);
26697 }
26698 vctxt->depth--;
26699 vctxt->inode = vctxt->elemInfos[vctxt->depth];
26700 /*
26701 * VAL TODO: 7 If the element information item is the `validation root`, it must be
26702 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26703 */
26704 return (ret);
26705
26706internal_error:
26707 vctxt->err = -1;
26708 return (-1);
26709}
26710
26711/*
26712* 3.4.4 Complex Type Definition Validation Rules
26713* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26714*/
26715static int
26716xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26717{
26718 xmlSchemaNodeInfoPtr pielem;
26719 xmlSchemaTypePtr ptype;
26720 int ret = 0;
26721
26722 if (vctxt->depth <= 0) {
26723 VERROR_INT("xmlSchemaValidateChildElem",
26724 "not intended for the validation root");
26725 return (-1);
26726 }
26727 pielem = vctxt->elemInfos[vctxt->depth -1];
26728 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26729 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26730 /*
26731 * Handle 'nilled' elements.
26732 */
26733 if (INODE_NILLED(pielem)) {
26734 /*
26735 * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26736 */
26737 ACTIVATE_PARENT_ELEM;
26739 VERROR(ret, NULL,
26740 "Neither character nor element content is allowed, "
26741 "because the element was 'nilled'");
26742 ACTIVATE_ELEM;
26743 goto unexpected_elem;
26744 }
26745
26746 ptype = pielem->typeDef;
26747
26748 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26749 /*
26750 * Workaround for "anyType": we have currently no content model
26751 * assigned for "anyType", so handle it explicitly.
26752 * "anyType" has an unbounded, lax "any" wildcard.
26753 */
26754 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26755 vctxt->inode->localName,
26756 vctxt->inode->nsName);
26757
26758 if (vctxt->inode->decl == NULL) {
26759 xmlSchemaAttrInfoPtr iattr;
26760 /*
26761 * Process "xsi:type".
26762 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26763 */
26764 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26765 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26766 if (iattr != NULL) {
26767 ret = xmlSchemaProcessXSIType(vctxt, iattr,
26768 &(vctxt->inode->typeDef), NULL);
26769 if (ret != 0) {
26770 if (ret == -1) {
26771 VERROR_INT("xmlSchemaValidateChildElem",
26772 "calling xmlSchemaProcessXSIType() to "
26773 "process the attribute 'xsi:nil'");
26774 return (-1);
26775 }
26776 return (ret);
26777 }
26778 } else {
26779 /*
26780 * Fallback to "anyType".
26781 *
26782 * SPEC (cvc-assess-elt)
26783 * "If the item cannot be `strictly assessed`, [...]
26784 * an element information item's schema validity may be laxly
26785 * assessed if its `context-determined declaration` is not
26786 * skip by `validating` with respect to the `ur-type
26787 * definition` as per Element Locally Valid (Type) ($3.3.4)."
26788 */
26789 vctxt->inode->typeDef =
26790 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26791 }
26792 }
26793 return (0);
26794 }
26795
26796 switch (ptype->contentType) {
26797 case XML_SCHEMA_CONTENT_EMPTY:
26798 /*
26799 * SPEC (2.1) "If the {content type} is empty, then the
26800 * element information item has no character or element
26801 * information item [children]."
26802 */
26803 ACTIVATE_PARENT_ELEM
26805 VERROR(ret, NULL,
26806 "Element content is not allowed, "
26807 "because the content type is empty");
26808 ACTIVATE_ELEM
26809 goto unexpected_elem;
26810 break;
26811
26812 case XML_SCHEMA_CONTENT_MIXED:
26813 case XML_SCHEMA_CONTENT_ELEMENTS: {
26814 xmlRegExecCtxtPtr regexCtxt;
26815 xmlChar *values[10];
26816 int terminal, nbval = 10, nbneg;
26817
26818 /* VAL TODO: Optimized "anyType" validation.*/
26819
26820 if (ptype->contModel == NULL) {
26821 VERROR_INT("xmlSchemaValidateChildElem",
26822 "type has elem content but no content model");
26823 return (-1);
26824 }
26825 /*
26826 * Safety belt for evaluation if the cont. model was already
26827 * examined to be invalid.
26828 */
26829 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26830 VERROR_INT("xmlSchemaValidateChildElem",
26831 "validating elem, but elem content is already invalid");
26832 return (-1);
26833 }
26834
26835 regexCtxt = pielem->regexCtxt;
26836 if (regexCtxt == NULL) {
26837 /*
26838 * Create the regex context.
26839 */
26840 regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26841 xmlSchemaVContentModelCallback, vctxt);
26842 if (regexCtxt == NULL) {
26843 VERROR_INT("xmlSchemaValidateChildElem",
26844 "failed to create a regex context");
26845 return (-1);
26846 }
26847 pielem->regexCtxt = regexCtxt;
26848#ifdef DEBUG_AUTOMATA
26849 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26850 pielem->localName);
26851#endif
26852 }
26853
26854 /*
26855 * SPEC (2.4) "If the {content type} is element-only or mixed,
26856 * then the sequence of the element information item's
26857 * element information item [children], if any, taken in
26858 * order, is `valid` with respect to the {content type}'s
26859 * particle, as defined in Element Sequence Locally Valid
26860 * (Particle) ($3.9.4)."
26861 */
26862 ret = xmlRegExecPushString2(regexCtxt,
26863 vctxt->inode->localName,
26864 vctxt->inode->nsName,
26865 vctxt->inode);
26866#ifdef DEBUG_AUTOMATA
26867 if (ret < 0)
26869 "AUTOMATON push ERROR for '%s' on '%s'\n",
26870 vctxt->inode->localName, pielem->localName);
26871 else
26873 "AUTOMATON push OK for '%s' on '%s'\n",
26874 vctxt->inode->localName, pielem->localName);
26875#endif
26876 if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26877 VERROR_INT("xmlSchemaValidateChildElem",
26878 "calling xmlRegExecPushString2()");
26879 return (-1);
26880 }
26881 if (ret < 0) {
26882 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26883 &values[0], &terminal);
26884 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26886 "This element is not expected",
26887 nbval, nbneg, values);
26888 ret = vctxt->err;
26889 goto unexpected_elem;
26890 } else
26891 ret = 0;
26892 }
26893 break;
26894 case XML_SCHEMA_CONTENT_SIMPLE:
26895 case XML_SCHEMA_CONTENT_BASIC:
26896 ACTIVATE_PARENT_ELEM
26897 if (WXS_IS_COMPLEX(ptype)) {
26898 /*
26899 * SPEC (cvc-complex-type) (2.2)
26900 * "If the {content type} is a simple type definition, then
26901 * the element information item has no element information
26902 * item [children], ..."
26903 */
26905 VERROR(ret, NULL, "Element content is not allowed, "
26906 "because the content type is a simple type definition");
26907 } else {
26908 /*
26909 * SPEC (cvc-type) (3.1.2) "The element information item must
26910 * have no element information item [children]."
26911 */
26913 VERROR(ret, NULL, "Element content is not allowed, "
26914 "because the type definition is simple");
26915 }
26916 ACTIVATE_ELEM
26917 ret = vctxt->err;
26918 goto unexpected_elem;
26919 break;
26920
26921 default:
26922 break;
26923 }
26924 return (ret);
26925unexpected_elem:
26926 /*
26927 * Pop this element and set the skipDepth to skip
26928 * all further content of the parent element.
26929 */
26930 vctxt->skipDepth = vctxt->depth;
26931 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26932 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26933 return (ret);
26934}
26935
26936#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26937#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26938#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26939
26940static int
26941xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26942 int nodeType, const xmlChar *value, int len,
26943 int mode, int *consumed)
26944{
26945 /*
26946 * Unfortunately we have to duplicate the text sometimes.
26947 * OPTIMIZE: Maybe we could skip it, if:
26948 * 1. content type is simple
26949 * 2. whitespace is "collapse"
26950 * 3. it consists of whitespace only
26951 *
26952 * Process character content.
26953 */
26954 if (consumed != NULL)
26955 *consumed = 0;
26956 if (INODE_NILLED(vctxt->inode)) {
26957 /*
26958 * SPEC cvc-elt (3.3.4 - 3.2.1)
26959 * "The element information item must have no character or
26960 * element information item [children]."
26961 */
26963 "Neither character nor element content is allowed "
26964 "because the element is 'nilled'");
26965 return (vctxt->err);
26966 }
26967 /*
26968 * SPEC (2.1) "If the {content type} is empty, then the
26969 * element information item has no character or element
26970 * information item [children]."
26971 */
26972 if (vctxt->inode->typeDef->contentType ==
26973 XML_SCHEMA_CONTENT_EMPTY) {
26975 "Character content is not allowed, "
26976 "because the content type is empty");
26977 return (vctxt->err);
26978 }
26979
26980 if (vctxt->inode->typeDef->contentType ==
26981 XML_SCHEMA_CONTENT_ELEMENTS) {
26982 if ((nodeType != XML_TEXT_NODE) ||
26983 (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26984 /*
26985 * SPEC cvc-complex-type (2.3)
26986 * "If the {content type} is element-only, then the
26987 * element information item has no character information
26988 * item [children] other than those whose [character
26989 * code] is defined as a white space in [XML 1.0 (Second
26990 * Edition)]."
26991 */
26993 "Character content other than whitespace is not allowed "
26994 "because the content type is 'element-only'");
26995 return (vctxt->err);
26996 }
26997 return (0);
26998 }
26999
27000 if ((value == NULL) || (value[0] == 0))
27001 return (0);
27002 /*
27003 * Save the value.
27004 * NOTE that even if the content type is *mixed*, we need the
27005 * *initial value* for default/fixed value constraints.
27006 */
27007 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
27008 ((vctxt->inode->decl == NULL) ||
27009 (vctxt->inode->decl->value == NULL)))
27010 return (0);
27011
27012 if (vctxt->inode->value == NULL) {
27013 /*
27014 * Set the value.
27015 */
27016 switch (mode) {
27017 case XML_SCHEMA_PUSH_TEXT_PERSIST:
27018 /*
27019 * When working on a tree.
27020 */
27021 vctxt->inode->value = value;
27022 break;
27023 case XML_SCHEMA_PUSH_TEXT_CREATED:
27024 /*
27025 * When working with the reader.
27026 * The value will be freed by the element info.
27027 */
27028 vctxt->inode->value = value;
27029 if (consumed != NULL)
27030 *consumed = 1;
27031 vctxt->inode->flags |=
27032 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27033 break;
27034 case XML_SCHEMA_PUSH_TEXT_VOLATILE:
27035 /*
27036 * When working with SAX.
27037 * The value will be freed by the element info.
27038 */
27039 if (len != -1)
27040 vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
27041 else
27042 vctxt->inode->value = BAD_CAST xmlStrdup(value);
27043 vctxt->inode->flags |=
27044 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27045 break;
27046 default:
27047 break;
27048 }
27049 } else {
27050 if (len < 0)
27051 len = xmlStrlen(value);
27052 /*
27053 * Concat the value.
27054 */
27055 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
27056 vctxt->inode->value = BAD_CAST xmlStrncat(
27057 (xmlChar *) vctxt->inode->value, value, len);
27058 } else {
27059 vctxt->inode->value =
27060 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
27061 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27062 }
27063 }
27064
27065 return (0);
27066}
27067
27068static int
27069xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
27070{
27071 int ret = 0;
27072
27073 if ((vctxt->skipDepth != -1) &&
27074 (vctxt->depth >= vctxt->skipDepth)) {
27075 VERROR_INT("xmlSchemaValidateElem",
27076 "in skip-state");
27077 goto internal_error;
27078 }
27079 if (vctxt->xsiAssemble) {
27080 /*
27081 * We will stop validation if there was an error during
27082 * dynamic schema construction.
27083 * Note that we simply set @skipDepth to 0, this could
27084 * mean that a streaming document via SAX would be
27085 * still read to the end but it won't be validated any more.
27086 * TODO: If we are sure how to stop the validation at once
27087 * for all input scenarios, then this should be changed to
27088 * instantly stop the validation.
27089 */
27090 ret = xmlSchemaAssembleByXSI(vctxt);
27091 if (ret != 0) {
27092 if (ret == -1)
27093 goto internal_error;
27094 vctxt->skipDepth = 0;
27095 return(ret);
27096 }
27097 /*
27098 * Augment the IDC definitions for the main schema and all imported ones
27099 * NOTE: main schema is the first in the imported list
27100 */
27101 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
27102 vctxt);
27103 }
27104 if (vctxt->depth > 0) {
27105 /*
27106 * Validate this element against the content model
27107 * of the parent.
27108 */
27109 ret = xmlSchemaValidateChildElem(vctxt);
27110 if (ret != 0) {
27111 if (ret < 0) {
27112 VERROR_INT("xmlSchemaValidateElem",
27113 "calling xmlSchemaStreamValidateChildElement()");
27114 goto internal_error;
27115 }
27116 goto exit;
27117 }
27118 if (vctxt->depth == vctxt->skipDepth)
27119 goto exit;
27120 if ((vctxt->inode->decl == NULL) &&
27121 (vctxt->inode->typeDef == NULL)) {
27122 VERROR_INT("xmlSchemaValidateElem",
27123 "the child element was valid but neither the "
27124 "declaration nor the type was set");
27125 goto internal_error;
27126 }
27127 } else {
27128 /*
27129 * Get the declaration of the validation root.
27130 */
27131 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
27132 vctxt->inode->localName,
27133 vctxt->inode->nsName);
27134 if (vctxt->inode->decl == NULL) {
27136 VERROR(ret, NULL,
27137 "No matching global declaration available "
27138 "for the validation root");
27139 goto exit;
27140 }
27141 }
27142
27143 if (vctxt->inode->decl == NULL)
27144 goto type_validation;
27145
27146 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
27147 int skip;
27148 /*
27149 * Wildcards.
27150 */
27151 ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
27152 if (ret != 0) {
27153 if (ret < 0) {
27154 VERROR_INT("xmlSchemaValidateElem",
27155 "calling xmlSchemaValidateElemWildcard()");
27156 goto internal_error;
27157 }
27158 goto exit;
27159 }
27160 if (skip) {
27161 vctxt->skipDepth = vctxt->depth;
27162 goto exit;
27163 }
27164 /*
27165 * The declaration might be set by the wildcard validation,
27166 * when the processContents is "lax" or "strict".
27167 */
27168 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
27169 /*
27170 * Clear the "decl" field to not confuse further processing.
27171 */
27172 vctxt->inode->decl = NULL;
27173 goto type_validation;
27174 }
27175 }
27176 /*
27177 * Validate against the declaration.
27178 */
27179 ret = xmlSchemaValidateElemDecl(vctxt);
27180 if (ret != 0) {
27181 if (ret < 0) {
27182 VERROR_INT("xmlSchemaValidateElem",
27183 "calling xmlSchemaValidateElemDecl()");
27184 goto internal_error;
27185 }
27186 goto exit;
27187 }
27188 /*
27189 * Validate against the type definition.
27190 */
27191type_validation:
27192
27193 if (vctxt->inode->typeDef == NULL) {
27194 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
27196 VERROR(ret, NULL,
27197 "The type definition is absent");
27198 goto exit;
27199 }
27200 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
27201 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
27203 VERROR(ret, NULL,
27204 "The type definition is abstract");
27205 goto exit;
27206 }
27207 /*
27208 * Evaluate IDCs. Do it here, since new IDC matchers are registered
27209 * during validation against the declaration. This must be done
27210 * _before_ attribute validation.
27211 */
27212 if (vctxt->xpathStates != NULL) {
27213 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
27214 vctxt->inode->appliedXPath = 1;
27215 if (ret == -1) {
27216 VERROR_INT("xmlSchemaValidateElem",
27217 "calling xmlSchemaXPathEvaluate()");
27218 goto internal_error;
27219 }
27220 }
27221 /*
27222 * Validate attributes.
27223 */
27224 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
27225 if ((vctxt->nbAttrInfos != 0) ||
27226 (vctxt->inode->typeDef->attrUses != NULL)) {
27227
27228 ret = xmlSchemaVAttributesComplex(vctxt);
27229 }
27230 } else if (vctxt->nbAttrInfos != 0) {
27231
27232 ret = xmlSchemaVAttributesSimple(vctxt);
27233 }
27234 /*
27235 * Clear registered attributes.
27236 */
27237 if (vctxt->nbAttrInfos != 0)
27238 xmlSchemaClearAttrInfos(vctxt);
27239 if (ret == -1) {
27240 VERROR_INT("xmlSchemaValidateElem",
27241 "calling attributes validation");
27242 goto internal_error;
27243 }
27244 /*
27245 * Don't return an error if attributes are invalid on purpose.
27246 */
27247 ret = 0;
27248
27249exit:
27250 if (ret != 0)
27251 vctxt->skipDepth = vctxt->depth;
27252 return (ret);
27253internal_error:
27254 return (-1);
27255}
27256
27257#ifdef XML_SCHEMA_READER_ENABLED
27258static int
27259xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
27260{
27261 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
27262 int depth, nodeType, ret = 0, consumed;
27263 xmlSchemaNodeInfoPtr ielem;
27264
27265 vctxt->depth = -1;
27266 ret = xmlTextReaderRead(vctxt->reader);
27267 /*
27268 * Move to the document element.
27269 */
27270 while (ret == 1) {
27271 nodeType = xmlTextReaderNodeType(vctxt->reader);
27272 if (nodeType == XML_ELEMENT_NODE)
27273 goto root_found;
27274 ret = xmlTextReaderRead(vctxt->reader);
27275 }
27276 goto exit;
27277
27278root_found:
27279
27280 do {
27281 depth = xmlTextReaderDepth(vctxt->reader);
27282 nodeType = xmlTextReaderNodeType(vctxt->reader);
27283
27284 if (nodeType == XML_ELEMENT_NODE) {
27285
27286 vctxt->depth++;
27287 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27288 VERROR_INT("xmlSchemaVReaderWalk",
27289 "calling xmlSchemaValidatorPushElem()");
27290 goto internal_error;
27291 }
27292 ielem = vctxt->inode;
27293 ielem->localName = xmlTextReaderLocalName(vctxt->reader);
27294 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
27295 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
27296 /*
27297 * Is the element empty?
27298 */
27299 ret = xmlTextReaderIsEmptyElement(vctxt->reader);
27300 if (ret == -1) {
27301 VERROR_INT("xmlSchemaVReaderWalk",
27302 "calling xmlTextReaderIsEmptyElement()");
27303 goto internal_error;
27304 }
27305 if (ret) {
27306 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27307 }
27308 /*
27309 * Register attributes.
27310 */
27311 vctxt->nbAttrInfos = 0;
27312 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
27313 if (ret == -1) {
27314 VERROR_INT("xmlSchemaVReaderWalk",
27315 "calling xmlTextReaderMoveToFirstAttribute()");
27316 goto internal_error;
27317 }
27318 if (ret == 1) {
27319 do {
27320 /*
27321 * VAL TODO: How do we know that the reader works on a
27322 * node tree, to be able to pass a node here?
27323 */
27324 if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27325 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27326 xmlTextReaderNamespaceUri(vctxt->reader), 1,
27327 xmlTextReaderValue(vctxt->reader), 1) == -1) {
27328
27329 VERROR_INT("xmlSchemaVReaderWalk",
27330 "calling xmlSchemaValidatorPushAttribute()");
27331 goto internal_error;
27332 }
27333 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27334 if (ret == -1) {
27335 VERROR_INT("xmlSchemaVReaderWalk",
27336 "calling xmlTextReaderMoveToFirstAttribute()");
27337 goto internal_error;
27338 }
27339 } while (ret == 1);
27340 /*
27341 * Back to element position.
27342 */
27343 ret = xmlTextReaderMoveToElement(vctxt->reader);
27344 if (ret == -1) {
27345 VERROR_INT("xmlSchemaVReaderWalk",
27346 "calling xmlTextReaderMoveToElement()");
27347 goto internal_error;
27348 }
27349 }
27350 /*
27351 * Validate the element.
27352 */
27353 ret= xmlSchemaValidateElem(vctxt);
27354 if (ret != 0) {
27355 if (ret == -1) {
27356 VERROR_INT("xmlSchemaVReaderWalk",
27357 "calling xmlSchemaValidateElem()");
27358 goto internal_error;
27359 }
27360 goto exit;
27361 }
27362 if (vctxt->depth == vctxt->skipDepth) {
27363 int curDepth;
27364 /*
27365 * Skip all content.
27366 */
27367 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27368 ret = xmlTextReaderRead(vctxt->reader);
27369 curDepth = xmlTextReaderDepth(vctxt->reader);
27370 while ((ret == 1) && (curDepth != depth)) {
27371 ret = xmlTextReaderRead(vctxt->reader);
27372 curDepth = xmlTextReaderDepth(vctxt->reader);
27373 }
27374 if (ret < 0) {
27375 /*
27376 * VAL TODO: A reader error occurred; what to do here?
27377 */
27378 ret = 1;
27379 goto exit;
27380 }
27381 }
27382 goto leave_elem;
27383 }
27384 /*
27385 * READER VAL TODO: Is an END_ELEM really never called
27386 * if the elem is empty?
27387 */
27388 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27389 goto leave_elem;
27390 } else if (nodeType == END_ELEM) {
27391 /*
27392 * Process END of element.
27393 */
27394leave_elem:
27395 ret = xmlSchemaValidatorPopElem(vctxt);
27396 if (ret != 0) {
27397 if (ret < 0) {
27398 VERROR_INT("xmlSchemaVReaderWalk",
27399 "calling xmlSchemaValidatorPopElem()");
27400 goto internal_error;
27401 }
27402 goto exit;
27403 }
27404 if (vctxt->depth >= 0)
27405 ielem = vctxt->inode;
27406 else
27407 ielem = NULL;
27408 } else if ((nodeType == XML_TEXT_NODE) ||
27409 (nodeType == XML_CDATA_SECTION_NODE) ||
27410 (nodeType == WHTSP) ||
27411 (nodeType == SIGN_WHTSP)) {
27412 /*
27413 * Process character content.
27414 */
27415 xmlChar *value;
27416
27417 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27418 nodeType = XML_TEXT_NODE;
27419
27420 value = xmlTextReaderValue(vctxt->reader);
27421 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27422 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27423 if (! consumed)
27424 xmlFree(value);
27425 if (ret == -1) {
27426 VERROR_INT("xmlSchemaVReaderWalk",
27427 "calling xmlSchemaVPushText()");
27428 goto internal_error;
27429 }
27430 } else if ((nodeType == XML_ENTITY_NODE) ||
27431 (nodeType == XML_ENTITY_REF_NODE)) {
27432 /*
27433 * VAL TODO: What to do with entities?
27434 */
27435 TODO
27436 }
27437 /*
27438 * Read next node.
27439 */
27440 ret = xmlTextReaderRead(vctxt->reader);
27441 } while (ret == 1);
27442
27443exit:
27444 return (ret);
27445internal_error:
27446 return (-1);
27447}
27448#endif
27449
27450/************************************************************************
27451 * *
27452 * SAX validation handlers *
27453 * *
27454 ************************************************************************/
27455
27456/*
27457* Process text content.
27458*/
27459static void
27460xmlSchemaSAXHandleText(void *ctx,
27461 const xmlChar * ch,
27462 int len)
27463{
27464 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27465
27466 if (vctxt->depth < 0)
27467 return;
27468 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27469 return;
27470 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27471 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27472 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27473 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27474 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27475 "calling xmlSchemaVPushText()");
27476 vctxt->err = -1;
27477 xmlStopParser(vctxt->parserCtxt);
27478 }
27479}
27480
27481/*
27482* Process CDATA content.
27483*/
27484static void
27485xmlSchemaSAXHandleCDataSection(void *ctx,
27486 const xmlChar * ch,
27487 int len)
27488{
27489 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27490
27491 if (vctxt->depth < 0)
27492 return;
27493 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27494 return;
27495 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27496 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27497 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27498 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27499 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27500 "calling xmlSchemaVPushText()");
27501 vctxt->err = -1;
27502 xmlStopParser(vctxt->parserCtxt);
27503 }
27504}
27505
27506static void
27507xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27509{
27510 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27511
27512 if (vctxt->depth < 0)
27513 return;
27514 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27515 return;
27516 /* SAX VAL TODO: What to do here? */
27517 TODO
27518}
27519
27520static void
27521xmlSchemaSAXHandleStartElementNs(void *ctx,
27522 const xmlChar * localname,
27523 const xmlChar * prefix ATTRIBUTE_UNUSED,
27524 const xmlChar * URI,
27525 int nb_namespaces,
27526 const xmlChar ** namespaces,
27527 int nb_attributes,
27528 int nb_defaulted ATTRIBUTE_UNUSED,
27529 const xmlChar ** attributes)
27530{
27531 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27532 int ret;
27533 xmlSchemaNodeInfoPtr ielem;
27534 int i, j;
27535
27536 /*
27537 * SAX VAL TODO: What to do with nb_defaulted?
27538 */
27539 /*
27540 * Skip elements if inside a "skip" wildcard or invalid.
27541 */
27542 vctxt->depth++;
27543 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27544 return;
27545 /*
27546 * Push the element.
27547 */
27548 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27549 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27550 "calling xmlSchemaValidatorPushElem()");
27551 goto internal_error;
27552 }
27553 ielem = vctxt->inode;
27554 /*
27555 * TODO: Is this OK?
27556 */
27557 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27558 ielem->localName = localname;
27559 ielem->nsName = URI;
27560 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27561 /*
27562 * Register namespaces on the elem info.
27563 */
27564 if (nb_namespaces != 0) {
27565 /*
27566 * Although the parser builds its own namespace list,
27567 * we have no access to it, so we'll use an own one.
27568 */
27569 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27570 /*
27571 * Store prefix and namespace name.
27572 */
27573 if (ielem->nsBindings == NULL) {
27574 ielem->nsBindings =
27575 (const xmlChar **) xmlMalloc(10 *
27576 sizeof(const xmlChar *));
27577 if (ielem->nsBindings == NULL) {
27578 xmlSchemaVErrMemory(vctxt,
27579 "allocating namespace bindings for SAX validation",
27580 NULL);
27581 goto internal_error;
27582 }
27583 ielem->nbNsBindings = 0;
27584 ielem->sizeNsBindings = 5;
27585 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27586 ielem->sizeNsBindings *= 2;
27587 ielem->nsBindings =
27588 (const xmlChar **) xmlRealloc(
27589 (void *) ielem->nsBindings,
27590 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27591 if (ielem->nsBindings == NULL) {
27592 xmlSchemaVErrMemory(vctxt,
27593 "re-allocating namespace bindings for SAX validation",
27594 NULL);
27595 goto internal_error;
27596 }
27597 }
27598
27599 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27600 if (namespaces[j+1][0] == 0) {
27601 /*
27602 * Handle xmlns="".
27603 */
27604 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27605 } else
27606 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27607 namespaces[j+1];
27608 ielem->nbNsBindings++;
27609 }
27610 }
27611 /*
27612 * Register attributes.
27613 * SAX VAL TODO: We are not adding namespace declaration
27614 * attributes yet.
27615 */
27616 if (nb_attributes != 0) {
27617 int valueLen, k, l;
27618 xmlChar *value;
27619
27620 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27621 /*
27622 * Duplicate the value, changing any &#38; to a literal ampersand.
27623 *
27624 * libxml2 differs from normal SAX here in that it escapes all ampersands
27625 * as &#38; instead of delivering the raw converted string. Changing the
27626 * behavior at this point would break applications that use this API, so
27627 * we are forced to work around it.
27628 */
27629 valueLen = attributes[j+4] - attributes[j+3];
27630 value = xmlMallocAtomic(valueLen + 1);
27631 if (value == NULL) {
27632 xmlSchemaVErrMemory(vctxt,
27633 "allocating string for decoded attribute",
27634 NULL);
27635 goto internal_error;
27636 }
27637 for (k = 0, l = 0; k < valueLen; l++) {
27638 if (k < valueLen - 4 &&
27639 attributes[j+3][k+0] == '&' &&
27640 attributes[j+3][k+1] == '#' &&
27641 attributes[j+3][k+2] == '3' &&
27642 attributes[j+3][k+3] == '8' &&
27643 attributes[j+3][k+4] == ';') {
27644 value[l] = '&';
27645 k += 5;
27646 } else {
27647 value[l] = attributes[j+3][k];
27648 k++;
27649 }
27650 }
27651 value[l] = '\0';
27652 /*
27653 * TODO: Set the node line.
27654 */
27655 ret = xmlSchemaValidatorPushAttribute(vctxt,
27656 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27657 value, 1);
27658 if (ret == -1) {
27659 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27660 "calling xmlSchemaValidatorPushAttribute()");
27661 goto internal_error;
27662 }
27663 }
27664 }
27665 /*
27666 * Validate the element.
27667 */
27668 ret = xmlSchemaValidateElem(vctxt);
27669 if (ret != 0) {
27670 if (ret == -1) {
27671 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27672 "calling xmlSchemaValidateElem()");
27673 goto internal_error;
27674 }
27675 goto exit;
27676 }
27677
27678exit:
27679 return;
27680internal_error:
27681 vctxt->err = -1;
27682 xmlStopParser(vctxt->parserCtxt);
27683 return;
27684}
27685
27686static void
27687xmlSchemaSAXHandleEndElementNs(void *ctx,
27688 const xmlChar * localname ATTRIBUTE_UNUSED,
27689 const xmlChar * prefix ATTRIBUTE_UNUSED,
27690 const xmlChar * URI ATTRIBUTE_UNUSED)
27691{
27692 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27693 int res;
27694
27695 /*
27696 * Skip elements if inside a "skip" wildcard or if invalid.
27697 */
27698 if (vctxt->skipDepth != -1) {
27699 if (vctxt->depth > vctxt->skipDepth) {
27700 vctxt->depth--;
27701 return;
27702 } else
27703 vctxt->skipDepth = -1;
27704 }
27705 /*
27706 * SAX VAL TODO: Just a temporary check.
27707 */
27708 if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27709 (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27710 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27711 "elem pop mismatch");
27712 }
27713 res = xmlSchemaValidatorPopElem(vctxt);
27714 if (res != 0) {
27715 if (res < 0) {
27716 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27717 "calling xmlSchemaValidatorPopElem()");
27718 goto internal_error;
27719 }
27720 goto exit;
27721 }
27722exit:
27723 return;
27724internal_error:
27725 vctxt->err = -1;
27726 xmlStopParser(vctxt->parserCtxt);
27727 return;
27728}
27729
27730/************************************************************************
27731 * *
27732 * Validation interfaces *
27733 * *
27734 ************************************************************************/
27735
27744xmlSchemaValidCtxtPtr
27745xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27746{
27747 xmlSchemaValidCtxtPtr ret;
27748
27749 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27750 if (ret == NULL) {
27751 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27752 return (NULL);
27753 }
27754 memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27755 ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27756 ret->dict = xmlDictCreate();
27757 ret->nodeQNames = xmlSchemaItemListCreate();
27758 ret->schema = schema;
27759 return (ret);
27760}
27761
27770void
27771xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27772 if (vctxt == NULL)
27773 return;
27774 if (vctxt->filename != NULL)
27775 xmlFree(vctxt->filename);
27776 if (filename != NULL)
27777 vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27778 else
27779 vctxt->filename = NULL;
27780}
27781
27789static void
27790xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27791{
27792 if (vctxt == NULL)
27793 return;
27794
27795 /*
27796 * TODO: Should we clear the flags?
27797 * Might be problematic if one reuses the context
27798 * and assumes that the options remain the same.
27799 */
27800 vctxt->flags = 0;
27801 vctxt->validationRoot = NULL;
27802 vctxt->doc = NULL;
27803#ifdef LIBXML_READER_ENABLED
27804 vctxt->reader = NULL;
27805#endif
27806 vctxt->hasKeyrefs = 0;
27807
27808 if (vctxt->value != NULL) {
27809 xmlSchemaFreeValue(vctxt->value);
27810 vctxt->value = NULL;
27811 }
27812 /*
27813 * Augmented IDC information.
27814 */
27815 if (vctxt->aidcs != NULL) {
27816 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27817 do {
27818 next = cur->next;
27819 xmlFree(cur);
27820 cur = next;
27821 } while (cur != NULL);
27822 vctxt->aidcs = NULL;
27823 }
27824
27825 if (vctxt->idcNodes != NULL) {
27826 int i;
27827 xmlSchemaPSVIIDCNodePtr item;
27828
27829 for (i = 0; i < vctxt->nbIdcNodes; i++) {
27830 item = vctxt->idcNodes[i];
27831 xmlFree(item->keys);
27832 xmlFree(item);
27833 }
27834 xmlFree(vctxt->idcNodes);
27835 vctxt->idcNodes = NULL;
27836 vctxt->nbIdcNodes = 0;
27837 vctxt->sizeIdcNodes = 0;
27838 }
27839
27840 if (vctxt->idcKeys != NULL) {
27841 int i;
27842 for (i = 0; i < vctxt->nbIdcKeys; i++)
27843 xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27844 xmlFree(vctxt->idcKeys);
27845 vctxt->idcKeys = NULL;
27846 vctxt->nbIdcKeys = 0;
27847 vctxt->sizeIdcKeys = 0;
27848 }
27849
27850 /*
27851 * Note that we won't delete the XPath state pool here.
27852 */
27853 if (vctxt->xpathStates != NULL) {
27854 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27855 vctxt->xpathStates = NULL;
27856 }
27857 /*
27858 * Attribute info.
27859 */
27860 if (vctxt->nbAttrInfos != 0) {
27861 xmlSchemaClearAttrInfos(vctxt);
27862 }
27863 /*
27864 * Element info.
27865 */
27866 if (vctxt->elemInfos != NULL) {
27867 int i;
27868 xmlSchemaNodeInfoPtr ei;
27869
27870 for (i = 0; i < vctxt->sizeElemInfos; i++) {
27871 ei = vctxt->elemInfos[i];
27872 if (ei == NULL)
27873 break;
27874 xmlSchemaClearElemInfo(vctxt, ei);
27875 }
27876 }
27877 xmlSchemaItemListClear(vctxt->nodeQNames);
27878 /* Recreate the dict. */
27879 xmlDictFree(vctxt->dict);
27880 /*
27881 * TODO: Is is save to recreate it? Do we have a scenario
27882 * where the user provides the dict?
27883 */
27884 vctxt->dict = xmlDictCreate();
27885
27886 if (vctxt->filename != NULL) {
27887 xmlFree(vctxt->filename);
27888 vctxt->filename = NULL;
27889 }
27890
27891 /*
27892 * Note that some cleanup functions can move items to the cache,
27893 * so the cache shouldn't be freed too early.
27894 */
27895 if (vctxt->idcMatcherCache != NULL) {
27896 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27897
27898 while (matcher) {
27899 tmp = matcher;
27900 matcher = matcher->nextCached;
27901 xmlSchemaIDCFreeMatcherList(tmp);
27902 }
27903 vctxt->idcMatcherCache = NULL;
27904 }
27905}
27906
27913void
27914xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27915{
27916 if (ctxt == NULL)
27917 return;
27918 if (ctxt->value != NULL)
27919 xmlSchemaFreeValue(ctxt->value);
27920 if (ctxt->pctxt != NULL)
27921 xmlSchemaFreeParserCtxt(ctxt->pctxt);
27922 if (ctxt->idcNodes != NULL) {
27923 int i;
27924 xmlSchemaPSVIIDCNodePtr item;
27925
27926 for (i = 0; i < ctxt->nbIdcNodes; i++) {
27927 item = ctxt->idcNodes[i];
27928 xmlFree(item->keys);
27929 xmlFree(item);
27930 }
27931 xmlFree(ctxt->idcNodes);
27932 }
27933 if (ctxt->idcKeys != NULL) {
27934 int i;
27935 for (i = 0; i < ctxt->nbIdcKeys; i++)
27936 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27937 xmlFree(ctxt->idcKeys);
27938 }
27939
27940 if (ctxt->xpathStates != NULL) {
27941 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27942 ctxt->xpathStates = NULL;
27943 }
27944 if (ctxt->xpathStatePool != NULL) {
27945 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27946 ctxt->xpathStatePool = NULL;
27947 }
27948
27949 /*
27950 * Augmented IDC information.
27951 */
27952 if (ctxt->aidcs != NULL) {
27953 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27954 do {
27955 next = cur->next;
27956 xmlFree(cur);
27957 cur = next;
27958 } while (cur != NULL);
27959 }
27960 if (ctxt->attrInfos != NULL) {
27961 int i;
27962 xmlSchemaAttrInfoPtr attr;
27963
27964 /* Just a paranoid call to the cleanup. */
27965 if (ctxt->nbAttrInfos != 0)
27966 xmlSchemaClearAttrInfos(ctxt);
27967 for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27968 attr = ctxt->attrInfos[i];
27969 xmlFree(attr);
27970 }
27971 xmlFree(ctxt->attrInfos);
27972 }
27973 if (ctxt->elemInfos != NULL) {
27974 int i;
27975 xmlSchemaNodeInfoPtr ei;
27976
27977 for (i = 0; i < ctxt->sizeElemInfos; i++) {
27978 ei = ctxt->elemInfos[i];
27979 if (ei == NULL)
27980 break;
27981 xmlSchemaClearElemInfo(ctxt, ei);
27982 xmlFree(ei);
27983 }
27984 xmlFree(ctxt->elemInfos);
27985 }
27986 if (ctxt->nodeQNames != NULL)
27987 xmlSchemaItemListFree(ctxt->nodeQNames);
27988 if (ctxt->dict != NULL)
27989 xmlDictFree(ctxt->dict);
27990 if (ctxt->filename != NULL)
27991 xmlFree(ctxt->filename);
27992 xmlFree(ctxt);
27993}
27994
28004int
28005xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
28006{
28007 if (ctxt == NULL)
28008 return(-1);
28009 return(ctxt->err == 0);
28010}
28011
28021void
28022xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
28023 xmlSchemaValidityErrorFunc err,
28024 xmlSchemaValidityWarningFunc warn, void *ctx)
28025{
28026 if (ctxt == NULL)
28027 return;
28028 ctxt->error = err;
28029 ctxt->warning = warn;
28030 ctxt->errCtxt = ctx;
28031 if (ctxt->pctxt != NULL)
28032 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
28033}
28034
28043void
28044xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
28045 xmlStructuredErrorFunc serror, void *ctx)
28046{
28047 if (ctxt == NULL)
28048 return;
28049 ctxt->serror = serror;
28050 ctxt->error = NULL;
28051 ctxt->warning = NULL;
28052 ctxt->errCtxt = ctx;
28053 if (ctxt->pctxt != NULL)
28054 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
28055}
28056
28068int
28069xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
28070 xmlSchemaValidityErrorFunc * err,
28071 xmlSchemaValidityWarningFunc * warn, void **ctx)
28072{
28073 if (ctxt == NULL)
28074 return (-1);
28075 if (err != NULL)
28076 *err = ctxt->error;
28077 if (warn != NULL)
28078 *warn = ctxt->warning;
28079 if (ctx != NULL)
28080 *ctx = ctxt->errCtxt;
28081 return (0);
28082}
28083
28084
28095int
28096xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
28097 int options)
28098
28099{
28100 int i;
28101
28102 if (ctxt == NULL)
28103 return (-1);
28104 /*
28105 * WARNING: Change the start value if adding to the
28106 * xmlSchemaValidOption.
28107 * TODO: Is there an other, more easy to maintain,
28108 * way?
28109 */
28110 for (i = 1; i < (int) sizeof(int) * 8; i++) {
28111 if (options & 1<<i)
28112 return (-1);
28113 }
28114 ctxt->options = options;
28115 return (0);
28116}
28117
28126int
28127xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
28128
28129{
28130 if (ctxt == NULL)
28131 return (-1);
28132 else
28133 return (ctxt->options);
28134}
28135
28136static int
28137xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
28138{
28140 int ret = 0;
28141 xmlSchemaNodeInfoPtr ielem = NULL;
28142 xmlNodePtr node, valRoot;
28143 const xmlChar *nsName;
28144
28145 /* DOC VAL TODO: Move this to the start function. */
28146 if (vctxt->validationRoot != NULL)
28147 valRoot = vctxt->validationRoot;
28148 else
28149 valRoot = xmlDocGetRootElement(vctxt->doc);
28150 if (valRoot == NULL) {
28151 /* VAL TODO: Error code? */
28152 VERROR(1, NULL, "The document has no document element");
28153 return (1);
28154 }
28155 vctxt->depth = -1;
28156 vctxt->validationRoot = valRoot;
28157 node = valRoot;
28158 while (node != NULL) {
28159 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
28160 goto next_sibling;
28161 if (node->type == XML_ELEMENT_NODE) {
28162
28163 /*
28164 * Init the node-info.
28165 */
28166 vctxt->depth++;
28167 if (xmlSchemaValidatorPushElem(vctxt) == -1)
28168 goto internal_error;
28169 ielem = vctxt->inode;
28170 ielem->node = node;
28171 ielem->nodeLine = node->line;
28172 ielem->localName = node->name;
28173 if (node->ns != NULL)
28174 ielem->nsName = node->ns->href;
28175 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
28176 /*
28177 * Register attributes.
28178 * DOC VAL TODO: We do not register namespace declaration
28179 * attributes yet.
28180 */
28181 vctxt->nbAttrInfos = 0;
28182 if (node->properties != NULL) {
28183 attr = node->properties;
28184 do {
28185 if (attr->ns != NULL)
28186 nsName = attr->ns->href;
28187 else
28188 nsName = NULL;
28189 ret = xmlSchemaValidatorPushAttribute(vctxt,
28190 (xmlNodePtr) attr,
28191 /*
28192 * Note that we give it the line number of the
28193 * parent element.
28194 */
28195 ielem->nodeLine,
28196 attr->name, nsName, 0,
28197 xmlNodeListGetString(attr->doc, attr->children, 1), 1);
28198 if (ret == -1) {
28199 VERROR_INT("xmlSchemaDocWalk",
28200 "calling xmlSchemaValidatorPushAttribute()");
28201 goto internal_error;
28202 }
28203 attr = attr->next;
28204 } while (attr);
28205 }
28206 /*
28207 * Validate the element.
28208 */
28209 ret = xmlSchemaValidateElem(vctxt);
28210 if (ret != 0) {
28211 if (ret == -1) {
28212 VERROR_INT("xmlSchemaDocWalk",
28213 "calling xmlSchemaValidateElem()");
28214 goto internal_error;
28215 }
28216 /*
28217 * Don't stop validation; just skip the content
28218 * of this element.
28219 */
28220 goto leave_node;
28221 }
28222 if ((vctxt->skipDepth != -1) &&
28223 (vctxt->depth >= vctxt->skipDepth))
28224 goto leave_node;
28225 } else if ((node->type == XML_TEXT_NODE) ||
28226 (node->type == XML_CDATA_SECTION_NODE)) {
28227 /*
28228 * Process character content.
28229 */
28230 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
28231 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
28232 ret = xmlSchemaVPushText(vctxt, node->type, node->content,
28233 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
28234 if (ret < 0) {
28235 VERROR_INT("xmlSchemaVDocWalk",
28236 "calling xmlSchemaVPushText()");
28237 goto internal_error;
28238 }
28239 /*
28240 * DOC VAL TODO: Should we skip further validation of the
28241 * element content here?
28242 */
28243 } else if ((node->type == XML_ENTITY_NODE) ||
28244 (node->type == XML_ENTITY_REF_NODE)) {
28245 /*
28246 * DOC VAL TODO: What to do with entities?
28247 */
28248 VERROR_INT("xmlSchemaVDocWalk",
28249 "there is at least one entity reference in the node-tree "
28250 "currently being validated. Processing of entities with "
28251 "this XML Schema processor is not supported (yet). Please "
28252 "substitute entities before validation.");
28253 goto internal_error;
28254 } else {
28255 goto leave_node;
28256 /*
28257 * DOC VAL TODO: XInclude nodes, etc.
28258 */
28259 }
28260 /*
28261 * Walk the doc.
28262 */
28263 if (node->children != NULL) {
28264 node = node->children;
28265 continue;
28266 }
28267leave_node:
28268 if (node->type == XML_ELEMENT_NODE) {
28269 /*
28270 * Leaving the scope of an element.
28271 */
28272 if (node != vctxt->inode->node) {
28273 VERROR_INT("xmlSchemaVDocWalk",
28274 "element position mismatch");
28275 goto internal_error;
28276 }
28277 ret = xmlSchemaValidatorPopElem(vctxt);
28278 if (ret != 0) {
28279 if (ret < 0) {
28280 VERROR_INT("xmlSchemaVDocWalk",
28281 "calling xmlSchemaValidatorPopElem()");
28282 goto internal_error;
28283 }
28284 }
28285 if (node == valRoot)
28286 goto exit;
28287 }
28288next_sibling:
28289 if (node->next != NULL)
28290 node = node->next;
28291 else {
28292 node = node->parent;
28293 goto leave_node;
28294 }
28295 }
28296
28297exit:
28298 return (ret);
28299internal_error:
28300 return (-1);
28301}
28302
28303static int
28304xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
28305 /*
28306 * Some initialization.
28307 */
28308 vctxt->err = 0;
28309 vctxt->nberrors = 0;
28310 vctxt->depth = -1;
28311 vctxt->skipDepth = -1;
28312 vctxt->hasKeyrefs = 0;
28313#ifdef ENABLE_IDC_NODE_TABLES_TEST
28314 vctxt->createIDCNodeTables = 1;
28315#else
28316 vctxt->createIDCNodeTables = 0;
28317#endif
28318 /*
28319 * Create a schema + parser if necessary.
28320 */
28321 if (vctxt->schema == NULL) {
28322 xmlSchemaParserCtxtPtr pctxt;
28323
28324 vctxt->xsiAssemble = 1;
28325 /*
28326 * If not schema was given then we will create a schema
28327 * dynamically using XSI schema locations.
28328 *
28329 * Create the schema parser context.
28330 */
28331 if ((vctxt->pctxt == NULL) &&
28332 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
28333 return (-1);
28334 pctxt = vctxt->pctxt;
28335 pctxt->xsiAssemble = 1;
28336 /*
28337 * Create the schema.
28338 */
28339 vctxt->schema = xmlSchemaNewSchema(pctxt);
28340 if (vctxt->schema == NULL)
28341 return (-1);
28342 /*
28343 * Create the schema construction context.
28344 */
28345 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
28346 if (pctxt->constructor == NULL)
28347 return(-1);
28348 pctxt->constructor->mainSchema = vctxt->schema;
28349 /*
28350 * Take ownership of the constructor to be able to free it.
28351 */
28352 pctxt->ownsConstructor = 1;
28353 }
28354 /*
28355 * Augment the IDC definitions for the main schema and all imported ones
28356 * NOTE: main schema if the first in the imported list
28357 */
28358 xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
28359 vctxt);
28360
28361 return(0);
28362}
28363
28364static void
28365xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28366 if (vctxt->xsiAssemble) {
28367 if (vctxt->schema != NULL) {
28368 xmlSchemaFree(vctxt->schema);
28369 vctxt->schema = NULL;
28370 }
28371 }
28372 xmlSchemaClearValidCtxt(vctxt);
28373}
28374
28375static int
28376xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28377{
28378 int ret = 0;
28379
28380 if (xmlSchemaPreRun(vctxt) < 0)
28381 return(-1);
28382
28383 if (vctxt->doc != NULL) {
28384 /*
28385 * Tree validation.
28386 */
28387 ret = xmlSchemaVDocWalk(vctxt);
28388#ifdef LIBXML_READER_ENABLED
28389 } else if (vctxt->reader != NULL) {
28390 /*
28391 * XML Reader validation.
28392 */
28393#ifdef XML_SCHEMA_READER_ENABLED
28394 ret = xmlSchemaVReaderWalk(vctxt);
28395#endif
28396#endif
28397 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28398 /*
28399 * SAX validation.
28400 */
28401 ret = xmlParseDocument(vctxt->parserCtxt);
28402 } else {
28403 VERROR_INT("xmlSchemaVStart",
28404 "no instance to validate");
28405 ret = -1;
28406 }
28407
28408 xmlSchemaPostRun(vctxt);
28409 if (ret == 0)
28410 ret = vctxt->err;
28411 return (ret);
28412}
28413
28424int
28425xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28426{
28427 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28428 return (-1);
28429
28430 if (ctxt->schema == NULL)
28431 return (-1);
28432
28433 ctxt->doc = elem->doc;
28434 ctxt->node = elem;
28435 ctxt->validationRoot = elem;
28436 return(xmlSchemaVStart(ctxt));
28437}
28438
28449int
28450xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28451{
28452 if ((ctxt == NULL) || (doc == NULL))
28453 return (-1);
28454
28455 ctxt->doc = doc;
28456 ctxt->node = xmlDocGetRootElement(doc);
28457 if (ctxt->node == NULL) {
28458 xmlSchemaCustomErr(ACTXT_CAST ctxt,
28460 (xmlNodePtr) doc, NULL,
28461 "The document has no document element", NULL, NULL);
28462 return (ctxt->err);
28463 }
28464 ctxt->validationRoot = ctxt->node;
28465 return (xmlSchemaVStart(ctxt));
28466}
28467
28468
28469/************************************************************************
28470 * *
28471 * Function and data for SAX streaming API *
28472 * *
28473 ************************************************************************/
28474typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28475typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28476
28477struct _xmlSchemaSplitSAXData {
28478 xmlSAXHandlerPtr user_sax;
28479 void *user_data;
28480 xmlSchemaValidCtxtPtr ctxt;
28481 xmlSAXHandlerPtr schemas_sax;
28482};
28483
28484#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28485
28486struct _xmlSchemaSAXPlug {
28487 unsigned int magic;
28488
28489 /* the original callbacks information */
28490 xmlSAXHandlerPtr *user_sax_ptr;
28491 xmlSAXHandlerPtr user_sax;
28492 void **user_data_ptr;
28493 void *user_data;
28494
28495 /* the block plugged back and validation information */
28496 xmlSAXHandler schemas_sax;
28497 xmlSchemaValidCtxtPtr ctxt;
28498};
28499
28500/* All those functions just bounces to the user provided SAX handlers */
28501static void
28502internalSubsetSplit(void *ctx, const xmlChar *name,
28503 const xmlChar *ExternalID, const xmlChar *SystemID)
28504{
28505 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28506 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28507 (ctxt->user_sax->internalSubset != NULL))
28508 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28509 SystemID);
28510}
28511
28512static int
28513isStandaloneSplit(void *ctx)
28514{
28515 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28516 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28517 (ctxt->user_sax->isStandalone != NULL))
28518 return(ctxt->user_sax->isStandalone(ctxt->user_data));
28519 return(0);
28520}
28521
28522static int
28523hasInternalSubsetSplit(void *ctx)
28524{
28525 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28526 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28527 (ctxt->user_sax->hasInternalSubset != NULL))
28528 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28529 return(0);
28530}
28531
28532static int
28533hasExternalSubsetSplit(void *ctx)
28534{
28535 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28536 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28537 (ctxt->user_sax->hasExternalSubset != NULL))
28538 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28539 return(0);
28540}
28541
28542static void
28543externalSubsetSplit(void *ctx, const xmlChar *name,
28544 const xmlChar *ExternalID, const xmlChar *SystemID)
28545{
28546 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28547 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28548 (ctxt->user_sax->externalSubset != NULL))
28549 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28550 SystemID);
28551}
28552
28553static xmlParserInputPtr
28554resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28555{
28556 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28557 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28558 (ctxt->user_sax->resolveEntity != NULL))
28559 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28560 systemId));
28561 return(NULL);
28562}
28563
28564static xmlEntityPtr
28565getEntitySplit(void *ctx, const xmlChar *name)
28566{
28567 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28568 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28569 (ctxt->user_sax->getEntity != NULL))
28570 return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28571 return(NULL);
28572}
28573
28574static xmlEntityPtr
28575getParameterEntitySplit(void *ctx, const xmlChar *name)
28576{
28577 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28578 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28579 (ctxt->user_sax->getParameterEntity != NULL))
28580 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28581 return(NULL);
28582}
28583
28584
28585static void
28586entityDeclSplit(void *ctx, const xmlChar *name, int type,
28587 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28588{
28589 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28590 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28591 (ctxt->user_sax->entityDecl != NULL))
28592 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28593 systemId, content);
28594}
28595
28596static void
28597attributeDeclSplit(void *ctx, const xmlChar * elem,
28598 const xmlChar * name, int type, int def,
28599 const xmlChar * defaultValue, xmlEnumerationPtr tree)
28600{
28601 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28602 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28603 (ctxt->user_sax->attributeDecl != NULL)) {
28604 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28605 def, defaultValue, tree);
28606 } else {
28608 }
28609}
28610
28611static void
28612elementDeclSplit(void *ctx, const xmlChar *name, int type,
28614{
28615 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28616 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28617 (ctxt->user_sax->elementDecl != NULL))
28618 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28619}
28620
28621static void
28622notationDeclSplit(void *ctx, const xmlChar *name,
28623 const xmlChar *publicId, const xmlChar *systemId)
28624{
28625 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28626 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28627 (ctxt->user_sax->notationDecl != NULL))
28628 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28629 systemId);
28630}
28631
28632static void
28633unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28634 const xmlChar *publicId, const xmlChar *systemId,
28635 const xmlChar *notationName)
28636{
28637 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28638 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28639 (ctxt->user_sax->unparsedEntityDecl != NULL))
28640 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28641 systemId, notationName);
28642}
28643
28644static void
28645setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28646{
28647 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28648 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28649 (ctxt->user_sax->setDocumentLocator != NULL))
28650 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28651}
28652
28653static void
28654startDocumentSplit(void *ctx)
28655{
28656 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28657 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28658 (ctxt->user_sax->startDocument != NULL))
28659 ctxt->user_sax->startDocument(ctxt->user_data);
28660}
28661
28662static void
28663endDocumentSplit(void *ctx)
28664{
28665 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28666 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28667 (ctxt->user_sax->endDocument != NULL))
28668 ctxt->user_sax->endDocument(ctxt->user_data);
28669}
28670
28671static void
28672processingInstructionSplit(void *ctx, const xmlChar *target,
28673 const xmlChar *data)
28674{
28675 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28676 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28677 (ctxt->user_sax->processingInstruction != NULL))
28678 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28679}
28680
28681static void
28682commentSplit(void *ctx, const xmlChar *value)
28683{
28684 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28685 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28686 (ctxt->user_sax->comment != NULL))
28687 ctxt->user_sax->comment(ctxt->user_data, value);
28688}
28689
28690/*
28691 * Varargs error callbacks to the user application, harder ...
28692 */
28693
28694static void XMLCDECL
28695warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28696 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28697 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28698 (ctxt->user_sax->warning != NULL)) {
28699 TODO
28700 }
28701}
28702static void XMLCDECL
28703errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28704 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28705 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28706 (ctxt->user_sax->error != NULL)) {
28707 TODO
28708 }
28709}
28710static void XMLCDECL
28711fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28712 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28713 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28714 (ctxt->user_sax->fatalError != NULL)) {
28715 TODO
28716 }
28717}
28718
28719/*
28720 * Those are function where both the user handler and the schemas handler
28721 * need to be called.
28722 */
28723static void
28724charactersSplit(void *ctx, const xmlChar *ch, int len)
28725{
28726 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28727 if (ctxt == NULL)
28728 return;
28729 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28730 ctxt->user_sax->characters(ctxt->user_data, ch, len);
28731 if (ctxt->ctxt != NULL)
28732 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28733}
28734
28735static void
28736ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28737{
28738 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28739 if (ctxt == NULL)
28740 return;
28741 if ((ctxt->user_sax != NULL) &&
28742 (ctxt->user_sax->ignorableWhitespace != NULL))
28743 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28744 if (ctxt->ctxt != NULL)
28745 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28746}
28747
28748static void
28749cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28750{
28751 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28752 if (ctxt == NULL)
28753 return;
28754 if ((ctxt->user_sax != NULL) &&
28755 (ctxt->user_sax->cdataBlock != NULL))
28756 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28757 if (ctxt->ctxt != NULL)
28758 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28759}
28760
28761static void
28762referenceSplit(void *ctx, const xmlChar *name)
28763{
28764 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28765 if (ctxt == NULL)
28766 return;
28767 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28768 (ctxt->user_sax->reference != NULL))
28769 ctxt->user_sax->reference(ctxt->user_data, name);
28770 if (ctxt->ctxt != NULL)
28771 xmlSchemaSAXHandleReference(ctxt->user_data, name);
28772}
28773
28774static void
28775startElementNsSplit(void *ctx, const xmlChar * localname,
28776 const xmlChar * prefix, const xmlChar * URI,
28777 int nb_namespaces, const xmlChar ** namespaces,
28778 int nb_attributes, int nb_defaulted,
28779 const xmlChar ** attributes) {
28780 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28781 if (ctxt == NULL)
28782 return;
28783 if ((ctxt->user_sax != NULL) &&
28784 (ctxt->user_sax->startElementNs != NULL))
28785 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28786 URI, nb_namespaces, namespaces,
28787 nb_attributes, nb_defaulted,
28788 attributes);
28789 if (ctxt->ctxt != NULL)
28790 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28791 URI, nb_namespaces, namespaces,
28792 nb_attributes, nb_defaulted,
28793 attributes);
28794}
28795
28796static void
28797endElementNsSplit(void *ctx, const xmlChar * localname,
28798 const xmlChar * prefix, const xmlChar * URI) {
28799 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28800 if (ctxt == NULL)
28801 return;
28802 if ((ctxt->user_sax != NULL) &&
28803 (ctxt->user_sax->endElementNs != NULL))
28804 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28805 if (ctxt->ctxt != NULL)
28806 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28807}
28808
28822xmlSchemaSAXPlugPtr
28823xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28824 xmlSAXHandlerPtr *sax, void **user_data)
28825{
28826 xmlSchemaSAXPlugPtr ret;
28827 xmlSAXHandlerPtr old_sax;
28828
28829 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28830 return(NULL);
28831
28832 /*
28833 * We only allow to plug into SAX2 event streams
28834 */
28835 old_sax = *sax;
28836 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28837 return(NULL);
28838 if ((old_sax != NULL) &&
28839 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28840 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28841 return(NULL);
28842
28843 /*
28844 * everything seems right allocate the local data needed for that layer
28845 */
28846 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28847 if (ret == NULL) {
28848 return(NULL);
28849 }
28850 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28851 ret->magic = XML_SAX_PLUG_MAGIC;
28852 ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28853 ret->ctxt = ctxt;
28854 ret->user_sax_ptr = sax;
28855 ret->user_sax = old_sax;
28856 if (old_sax == NULL) {
28857 /*
28858 * go direct, no need for the split block and functions.
28859 */
28860 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28861 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28862 /*
28863 * Note that we use the same text-function for both, to prevent
28864 * the parser from testing for ignorable whitespace.
28865 */
28866 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28867 ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28868
28869 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28870 ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28871
28872 ret->user_data = ctxt;
28873 *user_data = ctxt;
28874 } else {
28875 /*
28876 * for each callback unused by Schemas initialize it to the Split
28877 * routine only if non NULL in the user block, this can speed up
28878 * things at the SAX level.
28879 */
28880 if (old_sax->internalSubset != NULL)
28881 ret->schemas_sax.internalSubset = internalSubsetSplit;
28882 if (old_sax->isStandalone != NULL)
28883 ret->schemas_sax.isStandalone = isStandaloneSplit;
28884 if (old_sax->hasInternalSubset != NULL)
28885 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28886 if (old_sax->hasExternalSubset != NULL)
28887 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28888 if (old_sax->resolveEntity != NULL)
28889 ret->schemas_sax.resolveEntity = resolveEntitySplit;
28890 if (old_sax->getEntity != NULL)
28891 ret->schemas_sax.getEntity = getEntitySplit;
28892 if (old_sax->entityDecl != NULL)
28893 ret->schemas_sax.entityDecl = entityDeclSplit;
28894 if (old_sax->notationDecl != NULL)
28895 ret->schemas_sax.notationDecl = notationDeclSplit;
28896 if (old_sax->attributeDecl != NULL)
28897 ret->schemas_sax.attributeDecl = attributeDeclSplit;
28898 if (old_sax->elementDecl != NULL)
28899 ret->schemas_sax.elementDecl = elementDeclSplit;
28900 if (old_sax->unparsedEntityDecl != NULL)
28901 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28902 if (old_sax->setDocumentLocator != NULL)
28903 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28904 if (old_sax->startDocument != NULL)
28905 ret->schemas_sax.startDocument = startDocumentSplit;
28906 if (old_sax->endDocument != NULL)
28907 ret->schemas_sax.endDocument = endDocumentSplit;
28908 if (old_sax->processingInstruction != NULL)
28909 ret->schemas_sax.processingInstruction = processingInstructionSplit;
28910 if (old_sax->comment != NULL)
28911 ret->schemas_sax.comment = commentSplit;
28912 if (old_sax->warning != NULL)
28913 ret->schemas_sax.warning = warningSplit;
28914 if (old_sax->error != NULL)
28915 ret->schemas_sax.error = errorSplit;
28916 if (old_sax->fatalError != NULL)
28917 ret->schemas_sax.fatalError = fatalErrorSplit;
28918 if (old_sax->getParameterEntity != NULL)
28919 ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28920 if (old_sax->externalSubset != NULL)
28921 ret->schemas_sax.externalSubset = externalSubsetSplit;
28922
28923 /*
28924 * the 6 schemas callback have to go to the splitter functions
28925 * Note that we use the same text-function for ignorableWhitespace
28926 * if possible, to prevent the parser from testing for ignorable
28927 * whitespace.
28928 */
28929 ret->schemas_sax.characters = charactersSplit;
28930 if ((old_sax->ignorableWhitespace != NULL) &&
28931 (old_sax->ignorableWhitespace != old_sax->characters))
28932 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28933 else
28934 ret->schemas_sax.ignorableWhitespace = charactersSplit;
28935 ret->schemas_sax.cdataBlock = cdataBlockSplit;
28936 ret->schemas_sax.reference = referenceSplit;
28937 ret->schemas_sax.startElementNs = startElementNsSplit;
28938 ret->schemas_sax.endElementNs = endElementNsSplit;
28939
28940 ret->user_data_ptr = user_data;
28941 ret->user_data = *user_data;
28942 *user_data = ret;
28943 }
28944
28945 /*
28946 * plug the pointers back.
28947 */
28948 *sax = &(ret->schemas_sax);
28949 ctxt->sax = *sax;
28950 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28951 xmlSchemaPreRun(ctxt);
28952 return(ret);
28953}
28954
28964int
28965xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28966{
28968 void **user_data;
28969
28970 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28971 return(-1);
28972 plug->magic = 0;
28973
28974 xmlSchemaPostRun(plug->ctxt);
28975 /* restore the data */
28976 sax = plug->user_sax_ptr;
28977 *sax = plug->user_sax;
28978 if (plug->user_sax != NULL) {
28979 user_data = plug->user_data_ptr;
28980 *user_data = plug->user_data;
28981 }
28982
28983 /* free and return */
28984 xmlFree(plug);
28985 return(0);
28986}
28987
29000void
29001xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
29002 xmlSchemaValidityLocatorFunc f,
29003 void *ctxt)
29004{
29005 if (vctxt == NULL) return;
29006 vctxt->locFunc = f;
29007 vctxt->locCtxt = ctxt;
29008}
29009
29021static int
29022xmlSchemaValidateStreamLocator(void *ctx, const char **file,
29023 unsigned long *line) {
29024 xmlParserCtxtPtr ctxt;
29025
29026 if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
29027 return(-1);
29028
29029 if (file != NULL)
29030 *file = NULL;
29031 if (line != NULL)
29032 *line = 0;
29033
29034 ctxt = (xmlParserCtxtPtr) ctx;
29035 if (ctxt->input != NULL) {
29036 if (file != NULL)
29037 *file = ctxt->input->filename;
29038 if (line != NULL)
29039 *line = ctxt->input->line;
29040 return(0);
29041 }
29042 return(-1);
29043}
29044
29060int
29061xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
29063 xmlSAXHandlerPtr sax, void *user_data)
29064{
29065 xmlSchemaSAXPlugPtr plug = NULL;
29066 xmlSAXHandlerPtr old_sax = NULL;
29067 xmlParserCtxtPtr pctxt = NULL;
29068 xmlParserInputPtr inputStream = NULL;
29069 int ret;
29070
29071 if ((ctxt == NULL) || (input == NULL))
29072 return (-1);
29073
29074 /*
29075 * prepare the parser
29076 */
29077 pctxt = xmlNewParserCtxt();
29078 if (pctxt == NULL)
29079 return (-1);
29080 old_sax = pctxt->sax;
29081 pctxt->sax = sax;
29082 pctxt->userData = user_data;
29083#if 0
29084 if (options)
29085 xmlCtxtUseOptions(pctxt, options);
29086#endif
29087 pctxt->linenumbers = 1;
29088 xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
29089
29090 inputStream = xmlNewIOInputStream(pctxt, input, enc);;
29091 if (inputStream == NULL) {
29092 ret = -1;
29093 goto done;
29094 }
29095 inputPush(pctxt, inputStream);
29096 ctxt->parserCtxt = pctxt;
29097 ctxt->input = input;
29098
29099 /*
29100 * Plug the validation and launch the parsing
29101 */
29102 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
29103 if (plug == NULL) {
29104 ret = -1;
29105 goto done;
29106 }
29107 ctxt->input = input;
29108 ctxt->enc = enc;
29109 ctxt->sax = pctxt->sax;
29110 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
29111 ret = xmlSchemaVStart(ctxt);
29112
29113 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
29114 ret = ctxt->parserCtxt->errNo;
29115 if (ret == 0)
29116 ret = 1;
29117 }
29118
29119done:
29120 ctxt->parserCtxt = NULL;
29121 ctxt->sax = NULL;
29122 ctxt->input = NULL;
29123 if (plug != NULL) {
29124 xmlSchemaSAXUnplug(plug);
29125 }
29126 /* cleanup */
29127 if (pctxt != NULL) {
29128 pctxt->sax = old_sax;
29129 xmlFreeParserCtxt(pctxt);
29130 }
29131 return (ret);
29132}
29133
29146int
29147xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
29148 const char * filename,
29150{
29151 int ret;
29153
29154 if ((ctxt == NULL) || (filename == NULL))
29155 return (-1);
29156
29159 if (input == NULL)
29160 return (-1);
29161 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
29162 NULL, NULL);
29163 return (ret);
29164}
29165
29176xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
29177{
29178 if (ctxt == NULL)
29179 return(NULL);
29180 return (ctxt->parserCtxt);
29181}
29182
29183#endif /* LIBXML_SCHEMAS_ENABLED */
#define TODO
Definition: SAX2.c:44
XMLPUBFUN int XMLCALL xmlSAX2GetLineNumber(void *ctx)
Definition: SAX2.c:243
ios_base &_STLP_CALL fixed(ios_base &__s)
Definition: _ios_base.h:332
char * strchr(const char *String, int ch)
Definition: utclib.c:501
struct outqueuenode * head
Definition: adnsresfilter.c:66
static int state
Definition: maze.c:121
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define msg(x)
Definition: auth_time.c:54
#define index(s, c)
Definition: various.h:29
static void normalize(float vec[3])
Definition: bezierEval.cc:234
struct _root root
r l[0]
Definition: byte_order.h:168
fmtflags flags() const
Definition: _ios_base.h:107
Definition: list.h:37
Definition: _set.h:50
const WCHAR * link
Definition: db.cpp:997
#define NULL
Definition: types.h:112
#define IS_BLANK_NODE(n)
Definition: attributes.c:29
unsigned int idx
Definition: utils.c:41
content
Definition: atl_ax.c:994
static const WCHAR des[]
Definition: oid.c:1212
const WCHAR * action
Definition: action.c:7479
static NTSTATUS create_key(HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr)
Definition: compobj.c:303
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
r parent
Definition: btrfs.c:3010
xmlCharEncoding
Definition: encoding.h:56
@ XML_CHAR_ENCODING_NONE
Definition: encoding.h:58
#define local
Definition: zutil.h:30
FxCollectionEntry * cur
static struct netconfig_info ni
Definition: getnetconfig.c:158
GLuint start
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint reference
Definition: glext.h:11729
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLboolean GLuint group
Definition: glext.h:11120
const GLint * first
Definition: glext.h:5794
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLsizei const GLvoid GLenum preserve
Definition: glext.h:9550
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLbyte ty
Definition: glext.h:8756
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define ATTRIBUTE_UNUSED
Definition: i386-dis.c:36
@ extra
Definition: id3.c:95
#define INT_MAX
Definition: limits.h:40
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
const char * filename
Definition: ioapi.h:137
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define location(file, line)
Definition: kmtest.h:18
XMLPUBFUN xmlChar *XMLCALL xmlEscapeFormatString(xmlChar **msg)
Definition: xmlstring.c:1001
if(dx< 0)
Definition: linetemp.h:194
const WCHAR * schema
#define error(str)
Definition: mkdosfs.c:1605
LOCAL int prim(arg_t *ap)
Definition: match.c:440
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define for
Definition: utility.h:88
BOOL expected
Definition: store.c:2063
static WCHAR name1[]
Definition: record.c:34
static WCHAR name2[]
Definition: record.c:35
static UINT UINT last
Definition: font.c:45
static size_t elem
Definition: string.c:68
static char * dest
Definition: rtl.c:135
const char * fields[10]
Definition: parser.c:313
const char * uri
Definition: sec_mgr.c:1588
char strA[12]
Definition: clipboard.c:2028
static HWND child
Definition: cursoricon.c:298
static ATOM item
Definition: dde.c:856
#define shift
Definition: input.c:1755
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
static short search(int val, const short *table, int size)
Definition: msg711.c:255
u32_t magic(void)
static TCHAR * items[]
Definition: page1.c:45
XMLPUBFUN int XMLCALL inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
Definition: parser.c:1745
#define IS_BLANK_CH(c)
#define NORMALIZE(x, addr)
Definition: ppb.c:18
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
static unsigned __int64 next
Definition: rand_nt.c:6
#define warn(...)
#define err(...)
#define equal(x, y)
Definition: reader.cc:56
#define list
Definition: rosglue.h:35
const WCHAR * str
int consumed
Definition: scanf.h:134
#define warning(s)
Definition: debug.h:83
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:867
XMLPUBFUN xmlDictPtr XMLCALL xmlDictCreate(void)
Definition: dict.c:577
XMLPUBFUN void XMLCALL xmlDictFree(xmlDictPtr dict)
Definition: dict.c:802
XMLPUBFUN int XMLCALL xmlDictReference(xmlDictPtr dict)
Definition: dict.c:647
XMLPUBVAR xmlMallocFunc xmlMallocAtomic
Definition: globals.h:249
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:353
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:337
XMLPUBFUN int XMLCALL xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, void *userdata)
Definition: hash.c:406
XMLPUBFUN void XMLCALL xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f)
Definition: hash.c:322
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:461
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:176
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreateDict(int size, xmlDictPtr dict)
Definition: hash.c:210
XMLPUBFUN void XMLCALL xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data)
Definition: hash.c:875
XMLPUBFUN int XMLCALL xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata)
Definition: hash.c:389
XMLPUBFUN void *XMLCALL xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2)
Definition: hash.c:476
XMLPUBFUN void XMLCALL xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data)
Definition: hash.c:859
XMLPUBFUN xmlParserInputPtr XMLCALL xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input, xmlCharEncoding enc)
XMLPUBFUN void XMLCALL xmlStopParser(xmlParserCtxtPtr ctxt)
Definition: parser.c:12583
XMLPUBFUN xmlDocPtr XMLCALL xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size, const char *URL, const char *encoding, int options)
Definition: parser.c:15426
XMLPUBFUN int XMLCALL xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
Definition: parser.c:15141
XMLPUBFUN void XMLCALL xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
XMLPUBFUN int XMLCALL xmlParseDocument(xmlParserCtxtPtr ctxt)
Definition: parser.c:10697
#define XML_SAX2_MAGIC
Definition: parser.h:671
XMLPUBFUN xmlDocPtr XMLCALL xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename, const char *encoding, int options)
Definition: parser.c:15390
XMLPUBFUN xmlParserCtxtPtr XMLCALL xmlNewParserCtxt(void)
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChild(xmlNodePtr parent, xmlNodePtr cur)
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetContent(const xmlNode *cur)
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
@ XML_ATTRIBUTE_ID
Definition: tree.h:208
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
XMLPUBFUN xmlAttrPtr XMLCALL xmlHasProp(const xmlNode *node, const xmlChar *name)
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
XMLPUBFUN int XMLCALL xmlNodeGetSpacePreserve(const xmlNode *cur)
XMLPUBFUN xmlChar *XMLCALL xmlGetNoNsProp(const xmlNode *node, const xmlChar *name)
xmlNode * xmlNodePtr
Definition: tree.h:488
xmlElementType
Definition: tree.h:159
@ XML_ATTRIBUTE_NODE
Definition: tree.h:161
@ XML_ENTITY_DECL
Definition: tree.h:176
@ XML_CDATA_SECTION_NODE
Definition: tree.h:163
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_ENTITY_NODE
Definition: tree.h:165
@ XML_ELEMENT_NODE
Definition: tree.h:160
@ XML_ENTITY_REF_NODE
Definition: tree.h:164
XMLPUBFUN void XMLCALL xmlUnlinkNode(xmlNodePtr cur)
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href)
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur)
xmlParserCtxt * xmlParserCtxtPtr
Definition: tree.h:39
#define XML_XML_NAMESPACE
Definition: tree.h:140
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocText(const xmlDoc *doc, const xmlChar *content)
XMLPUBFUN long XMLCALL xmlGetLineNo(const xmlNode *node)
XMLPUBFUN void XMLCALL xmlFreeNode(xmlNodePtr cur)
XMLPUBFUN const xmlChar *XMLCALL xmlSplitQName3(const xmlChar *name, int *len)
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
XMLPUBFUN xmlChar *XMLCALL xmlSplitQName2(const xmlChar *name, xmlChar **prefix)
XMLPUBFUN xmlAttrPtr XMLCALL xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, const xmlChar *value)
XMLPUBFUN xmlChar *XMLCALL xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
const char * ws
Definition: skip_ws.cpp:7
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
Definition: tree.h:434
xmlNs * ns
Definition: tree.h:444
struct _xmlAttr * next
Definition: tree.h:441
const xmlChar * name
Definition: tree.h:437
Definition: dict.c:111
struct _xmlDictEntry * dict
Definition: dict.c:114
Definition: tree.h:551
const xmlChar * URL
Definition: tree.h:577
int domain
Definition: xmlerror.h:79
Definition: tree.h:457
Definition: tree.h:489
struct _xmlDoc * doc
Definition: tree.h:498
const xmlChar * name
Definition: tree.h:492
xmlElementType type
Definition: tree.h:491
struct _xmlNode * parent
Definition: tree.h:495
xmlNs * ns
Definition: tree.h:501
Definition: tree.h:389
const xmlChar * href
Definition: tree.h:392
const xmlChar * prefix
Definition: tree.h:393
struct _xmlSAXHandler * sax
Definition: parser.h:185
xmlDictPtr dict
Definition: parser.h:263
void * userData
Definition: parser.h:186
int linenumbers
Definition: parser.h:259
xmlParserInputPtr input
Definition: parser.h:199
const char * filename
Definition: parser.h:56
unparsedEntityDeclSAXFunc unparsedEntityDecl
Definition: parser.h:730
hasExternalSubsetSAXFunc hasExternalSubset
Definition: parser.h:723
setDocumentLocatorSAXFunc setDocumentLocator
Definition: parser.h:731
getEntitySAXFunc getEntity
Definition: parser.h:725
commentSAXFunc comment
Definition: parser.h:740
errorSAXFunc error
Definition: parser.h:742
attributeDeclSAXFunc attributeDecl
Definition: parser.h:728
startElementNsSAX2Func startElementNs
Definition: parser.h:750
externalSubsetSAXFunc externalSubset
Definition: parser.h:746
internalSubsetSAXFunc internalSubset
Definition: parser.h:720
endElementSAXFunc endElement
Definition: parser.h:735
isStandaloneSAXFunc isStandalone
Definition: parser.h:721
endDocumentSAXFunc endDocument
Definition: parser.h:733
fatalErrorSAXFunc fatalError
Definition: parser.h:743
hasInternalSubsetSAXFunc hasInternalSubset
Definition: parser.h:722
notationDeclSAXFunc notationDecl
Definition: parser.h:727
resolveEntitySAXFunc resolveEntity
Definition: parser.h:724
getParameterEntitySAXFunc getParameterEntity
Definition: parser.h:744
endElementNsSAX2Func endElementNs
Definition: parser.h:751
startElementSAXFunc startElement
Definition: parser.h:734
entityDeclSAXFunc entityDecl
Definition: parser.h:726
processingInstructionSAXFunc processingInstruction
Definition: parser.h:739
charactersSAXFunc characters
Definition: parser.h:737
warningSAXFunc warning
Definition: parser.h:741
startDocumentSAXFunc startDocument
Definition: parser.h:732
elementDeclSAXFunc elementDecl
Definition: parser.h:729
unsigned int initialized
Definition: parser.h:747
ignorableWhitespaceSAXFunc ignorableWhitespace
Definition: parser.h:738
Definition: cookie.c:202
WCHAR * value
Definition: cookie.c:204
WCHAR * name
Definition: cookie.c:203
Definition: http.c:7252
struct define * next
Definition: compiler.c:65
char * value
Definition: compiler.c:67
char * name
Definition: compiler.c:66
Definition: parser.c:44
Definition: fci.c:127
Definition: fs.h:78
Definition: copy.c:22
Definition: parser.c:49
char name[MAX_NAME_LEN]
DWORD type
Definition: tftpd.h:60
Definition: name.c:39
WCHAR * name
Definition: name.c:42
Definition: mxnamespace.c:45
Definition: reader.h:84
Definition: send.c:48
char name[1]
Definition: send.c:52
#define max(a, b)
Definition: svc.c:63
else
Definition: tritemp.h:161
Definition: dlist.c:348
void * next
Definition: dlist.c:360
Definition: pdh_main.c:94
XMLPUBFUN xmlChar *XMLCALL xmlBuildURI(const xmlChar *URI, const xmlChar *base)
Definition: uri.c:1892
XMLPUBFUN xmlIDPtr XMLCALL xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value, xmlAttrPtr attr)
Definition: valid.c:2672
XMLPUBFUN void XMLCALL xmlFreeEnumeration(xmlEnumerationPtr cur)
Definition: valid.c:1817
static HRESULT return_null(VARIANT *res)
Definition: global.c:394
int ret
#define snprintf
Definition: wintirpc.h:48
XMLPUBFUN xmlParserInputBufferPtr XMLCALL xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc)
void(XMLCDECL * xmlGenericErrorFunc)(void *ctx, const char *msg,...) LIBXML_ATTR_FORMAT(2
Definition: xmlerror.h:847
XMLPUBFUN xmlErrorPtr XMLCALL xmlGetLastError(void)
xmlErrorLevel
Definition: xmlerror.h:24
@ XML_ERR_WARNING
Definition: xmlerror.h:26
@ XML_ERR_ERROR
Definition: xmlerror.h:27
@ XML_FROM_SCHEMASP
Definition: xmlerror.h:53
@ XML_FROM_SCHEMASV
Definition: xmlerror.h:54
@ XML_FROM_IO
Definition: xmlerror.h:45
void(XMLCDECL *) typedef void(XMLCALL * xmlStructuredErrorFunc)(void *userData, xmlErrorPtr error)
Definition: xmlerror.h:858
xmlParserErrors
Definition: xmlerror.h:99
@ XML_SCHEMAV_CVC_WILDCARD
Definition: xmlerror.h:677
@ XML_SCHEMAV_CVC_COMPLEX_TYPE_4
Definition: xmlerror.h:667
@ XML_SCHEMAP_SRC_ATTRIBUTE_1
Definition: xmlerror.h:747
@ XML_SCHEMAP_SRC_ELEMENT_2_1
Definition: xmlerror.h:735
@ XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3
Definition: xmlerror.h:625
@ XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1
Definition: xmlerror.h:709
@ XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
Definition: xmlerror.h:640
@ XML_SCHEMAV_CVC_ELT_3_2_2
Definition: xmlerror.h:648
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2
Definition: xmlerror.h:597
@ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
Definition: xmlerror.h:731
@ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1
Definition: xmlerror.h:720
@ XML_SCHEMAP_AU_PROPS_CORRECT
Definition: xmlerror.h:785
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3
Definition: xmlerror.h:773
@ XML_SCHEMAV_CVC_TYPE_3_1_1
Definition: xmlerror.h:626
@ XML_SCHEMAP_SRC_ATTRIBUTE_2
Definition: xmlerror.h:748
@ XML_SCHEMAV_CVC_ELT_1
Definition: xmlerror.h:644
@ XML_SCHEMAP_A_PROPS_CORRECT_3
Definition: xmlerror.h:786
@ XML_SCHEMAP_NOT_DETERMINISTIC
Definition: xmlerror.h:766
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3
Definition: xmlerror.h:598
@ XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3
Definition: xmlerror.h:642
@ XML_SCHEMAP_NO_XMLNS
Definition: xmlerror.h:752
@ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2
Definition: xmlerror.h:722
@ XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
Definition: xmlerror.h:623
@ XML_SCHEMAP_COS_ST_RESTRICTS_1_2
Definition: xmlerror.h:708
@ XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2
Definition: xmlerror.h:641
@ XML_SCHEMAV_CVC_ELT_5_2_2_2_2
Definition: xmlerror.h:657
@ XML_SCHEMAV_CVC_ELT_2
Definition: xmlerror.h:645
@ XML_SCHEMAP_UNKNOWN_FACET_CHILD
Definition: xmlerror.h:539
@ XML_SCHEMAP_FAILED_LOAD
Definition: xmlerror.h:556
@ XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
Definition: xmlerror.h:782
@ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4
Definition: xmlerror.h:725
@ XML_SCHEMAP_S4S_ATTR_MISSING
Definition: xmlerror.h:732
@ XML_SCHEMAP_COS_ALL_LIMITED
Definition: xmlerror.h:787
@ XML_SCHEMAP_ATTRFORMDEFAULT_VALUE
Definition: xmlerror.h:500
@ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
Definition: xmlerror.h:729
@ XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE
Definition: xmlerror.h:701
@ XML_SCHEMAP_NOTHING_TO_PARSE
Definition: xmlerror.h:557
@ XML_SCHEMAP_COS_ST_RESTRICTS_2_1
Definition: xmlerror.h:711
@ XML_SCHEMAV_CVC_ELT_5_2_2_2_1
Definition: xmlerror.h:656
@ XML_SCHEMAP_SRC_IMPORT
Definition: xmlerror.h:778
@ XML_SCHEMAV_CVC_ELT_5_2_2_1
Definition: xmlerror.h:655
@ XML_SCHEMAP_COS_ST_DERIVED_OK_2_1
Definition: xmlerror.h:727
@ XML_SCHEMAP_COS_VALID_DEFAULT_2_1
Definition: xmlerror.h:755
@ XML_SCHEMAV_CVC_IDC
Definition: xmlerror.h:676
@ XML_SCHEMAP_SRC_RESOLVE
Definition: xmlerror.h:700
@ XML_SCHEMAV_CVC_ELT_3_2_1
Definition: xmlerror.h:647
@ XML_SCHEMAP_C_PROPS_CORRECT
Definition: xmlerror.h:776
@ XML_SCHEMAP_COS_CT_EXTENDS_1_2
Definition: xmlerror.h:784
@ XML_SCHEMAP_REDEFINED_TYPE
Definition: xmlerror.h:560
@ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
Definition: xmlerror.h:733
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
Definition: xmlerror.h:586
@ XML_SCHEMAP_SRC_INCLUDE
Definition: xmlerror.h:746
@ XML_SCHEMAP_E_PROPS_CORRECT_3
Definition: xmlerror.h:742
@ XML_SCHEMAP_SRC_IMPORT_1_2
Definition: xmlerror.h:761
@ XML_SCHEMAP_NOTATION_NO_NAME
Definition: xmlerror.h:522
@ XML_SCHEMAP_INTERNAL
Definition: xmlerror.h:765
@ XML_SCHEMAP_MG_PROPS_CORRECT_2
Definition: xmlerror.h:771
@ XML_SCHEMAP_COS_CT_EXTENDS_1_3
Definition: xmlerror.h:599
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2
Definition: xmlerror.h:589
@ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1
Definition: xmlerror.h:723
@ XML_SCHEMAP_SRC_ELEMENT_1
Definition: xmlerror.h:734
@ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2
Definition: xmlerror.h:721
@ XML_SCHEMAP_UNKNOWN_FACET_TYPE
Definition: xmlerror.h:540
@ XML_SCHEMAP_SRC_ELEMENT_3
Definition: xmlerror.h:737
@ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1
Definition: xmlerror.h:712
@ XML_SCHEMAV_ELEMENT_CONTENT
Definition: xmlerror.h:670
@ XML_SCHEMAP_SRC_ELEMENT_2_2
Definition: xmlerror.h:736
@ XML_SCHEMAP_E_PROPS_CORRECT_4
Definition: xmlerror.h:743
@ XML_SCHEMAP_A_PROPS_CORRECT_2
Definition: xmlerror.h:775
@ XML_SCHEMAP_FACET_NO_VALUE
Definition: xmlerror.h:507
@ XML_SCHEMAV_CVC_AU
Definition: xmlerror.h:673
@ XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING
Definition: xmlerror.h:671
@ XML_SCHEMAP_ST_PROPS_CORRECT_3
Definition: xmlerror.h:706
@ XML_SCHEMAP_COS_CT_EXTENDS_1_1
Definition: xmlerror.h:759
@ XML_SCHEMAP_INVALID_FACET_VALUE
Definition: xmlerror.h:516
@ XML_SCHEMAV_CVC_TYPE_3_1_2
Definition: xmlerror.h:627
@ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2
Definition: xmlerror.h:713
@ XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3
Definition: xmlerror.h:724
@ XML_SCHEMAV_INTERNAL
Definition: xmlerror.h:617
@ XML_SCHEMAP_NO_XSI
Definition: xmlerror.h:753
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3
Definition: xmlerror.h:590
@ XML_SCHEMAP_SRC_ATTRIBUTE_4
Definition: xmlerror.h:751
@ XML_SCHEMAP_SRC_ATTRIBUTE_3_2
Definition: xmlerror.h:750
@ XML_SCHEMAP_SRC_REDEFINE
Definition: xmlerror.h:777
@ XML_SCHEMAP_INVALID_ATTR_USE
Definition: xmlerror.h:573
@ XML_SCHEMAP_ST_PROPS_CORRECT_2
Definition: xmlerror.h:705
@ XML_SCHEMAV_CVC_ENUMERATION_VALID
Definition: xmlerror.h:639
@ XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2
Definition: xmlerror.h:666
@ XML_SCHEMAP_INVALID_BOOLEAN
Definition: xmlerror.h:513
@ XML_SCHEMAP_UNION_NOT_EXPRESSIBLE
Definition: xmlerror.h:593
@ XML_SCHEMAP_COS_ST_RESTRICTS_1_1
Definition: xmlerror.h:707
@ XML_SCHEMAP_ST_PROPS_CORRECT_1
Definition: xmlerror.h:704
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1
Definition: xmlerror.h:587
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2
Definition: xmlerror.h:588
@ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1
Definition: xmlerror.h:714
@ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3
Definition: xmlerror.h:716
@ XML_SCHEMAV_CVC_ELT_4_3
Definition: xmlerror.h:651
@ XML_SCHEMAP_P_PROPS_CORRECT_2_2
Definition: xmlerror.h:740
@ XML_SCHEMAP_SRC_CT_1
Definition: xmlerror.h:772
@ XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1
Definition: xmlerror.h:596
@ XML_SCHEMAP_ELEMFORMDEFAULT_VALUE
Definition: xmlerror.h:504
@ XML_SCHEMAP_SRC_SIMPLE_TYPE_4
Definition: xmlerror.h:699
@ XML_SCHEMAP_COS_ST_DERIVED_OK_2_2
Definition: xmlerror.h:728
@ XML_SCHEMAP_COS_ST_RESTRICTS_3_1
Definition: xmlerror.h:719
@ XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE
Definition: xmlerror.h:592
@ XML_SCHEMAV_CVC_ATTRIBUTE_2
Definition: xmlerror.h:661
@ XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES
Definition: xmlerror.h:703
@ XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1
Definition: xmlerror.h:665
@ XML_SCHEMAP_SRC_SIMPLE_TYPE_1
Definition: xmlerror.h:696
@ XML_SCHEMAP_REGEXP_INVALID
Definition: xmlerror.h:555
@ XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
Definition: xmlerror.h:624
@ XML_SCHEMAP_WARN_SKIP_SCHEMA
Definition: xmlerror.h:779
@ XML_SCHEMAP_E_PROPS_CORRECT_6
Definition: xmlerror.h:745
@ XML_SCHEMAP_AU_PROPS_CORRECT_2
Definition: xmlerror.h:774
@ XML_SCHEMAV_CVC_ELT_4_2
Definition: xmlerror.h:650
@ XML_SCHEMAP_P_PROPS_CORRECT_2_1
Definition: xmlerror.h:739
@ XML_SCHEMAP_AG_PROPS_CORRECT
Definition: xmlerror.h:783
@ XML_SCHEMAV_CVC_TYPE_2
Definition: xmlerror.h:675
@ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2
Definition: xmlerror.h:715
@ XML_SCHEMAV_MISC
Definition: xmlerror.h:678
@ XML_SCHEMAP_S4S_ELEM_MISSING
Definition: xmlerror.h:730
@ XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER
Definition: xmlerror.h:591
@ XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3
Definition: xmlerror.h:769
@ XML_SCHEMAP_NOROOT
Definition: xmlerror.h:558
@ XML_SCHEMAV_CVC_PATTERN_VALID
Definition: xmlerror.h:638
@ XML_SCHEMAV_CVC_TYPE_1
Definition: xmlerror.h:674
@ XML_SCHEMAV_CVC_ELT_3_1
Definition: xmlerror.h:646
@ XML_SCHEMAP_SRC_IMPORT_2_1
Definition: xmlerror.h:763
@ XML_ERR_NO_MEMORY
Definition: xmlerror.h:102
@ XML_SCHEMAP_E_PROPS_CORRECT_5
Definition: xmlerror.h:744
@ XML_SCHEMAP_SRC_IMPORT_1_1
Definition: xmlerror.h:760
@ XML_SCHEMAP_WARN_UNLOCATED_SCHEMA
Definition: xmlerror.h:780
@ XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4
Definition: xmlerror.h:717
@ XML_SCHEMAP_NOT_SCHEMA
Definition: xmlerror.h:571
#define XMLCDECL
Definition: xmlexports.h:52
static int sax
Definition: xmllint.c:193
static unsigned int block
Definition: xmlmemory.c:101
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524
XMLPUBFUN xmlChar *XMLCALL xmlStrncat(xmlChar *cur, const xmlChar *add, int len)
Definition: xmlstring.c:446
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
XMLPUBFUN xmlChar *XMLCALL xmlCharStrdup(const char *cur)
Definition: xmlstring.c:114
XMLPUBFUN xmlChar *XMLCALL xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:483
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:426
unsigned char xmlChar
Definition: xmlstring.h:28
#define LIBXML_ATTR_FORMAT(fmt, args)
Definition: xmlversion.h:486
#define const
Definition: zconf.h:233