Coverage Report

Created: 2024-09-06 07:53

/src/libxml2/xmlschemas.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * schemas.c : implementation of the XML Schema handling and
3
 *             schema validity checking
4
 *
5
 * See Copyright for the status of this software.
6
 *
7
 * Daniel Veillard <veillard@redhat.com>
8
 */
9
10
/*
11
 * TODO:
12
 *   - when types are redefined in includes, check that all
13
 *     types in the redef list are equal
14
 *     -> need a type equality operation.
15
 *   - if we don't intend to use the schema for schemas, we
16
 *     need to validate all schema attributes (ref, type, name)
17
 *     against their types.
18
 *   - Eliminate item creation for: ??
19
 *
20
 * URGENT TODO:
21
 *   - For xsi-driven schema acquisition, augment the IDCs after every
22
 *     acquisition episode (xmlSchemaAugmentIDC).
23
 *
24
 * NOTES:
25
 *   - Eliminated item creation for: <restriction>, <extension>,
26
 *     <simpleContent>, <complexContent>, <list>, <union>
27
 *
28
 * PROBLEMS:
29
 *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
30
 *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
31
 *     XPath will have trouble to resolve to this namespace, since not known.
32
 *
33
 *
34
 * CONSTRAINTS:
35
 *
36
 * Schema Component Constraint:
37
 *   All Group Limited (cos-all-limited)
38
 *   Status: complete
39
 *   (1.2)
40
 *     In xmlSchemaGroupDefReferenceTermFixup() and
41
 *   (2)
42
 *     In xmlSchemaParseModelGroup()
43
 *     TODO: Actually this should go to component-level checks,
44
 *     but is done here due to performance. Move it to an other layer
45
 *     is schema construction via an API is implemented.
46
 */
47
48
/* To avoid EBCDIC trouble when parsing on zOS */
49
#if defined(__MVS__)
50
#pragma convert("ISO8859-1")
51
#endif
52
53
#define IN_LIBXML
54
#include "libxml.h"
55
56
#ifdef LIBXML_SCHEMAS_ENABLED
57
58
#include <string.h>
59
#include <libxml/xmlmemory.h>
60
#include <libxml/parser.h>
61
#include <libxml/parserInternals.h>
62
#include <libxml/hash.h>
63
#include <libxml/uri.h>
64
#include <libxml/xmlschemas.h>
65
#include <libxml/schemasInternals.h>
66
#include <libxml/xmlschemastypes.h>
67
#include <libxml/xmlautomata.h>
68
#include <libxml/xmlregexp.h>
69
#include <libxml/dict.h>
70
#include <libxml/encoding.h>
71
#include <libxml/xmlIO.h>
72
#ifdef LIBXML_PATTERN_ENABLED
73
#include <libxml/pattern.h>
74
#endif
75
#ifdef LIBXML_READER_ENABLED
76
#include <libxml/xmlreader.h>
77
#endif
78
79
#include "private/error.h"
80
#include "private/string.h"
81
82
/* #define WXS_ELEM_DECL_CONS_ENABLED */
83
84
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
85
86
#define ENABLE_REDEFINE
87
88
/* #define ENABLE_NAMED_LOCALS */
89
90
/* #define ENABLE_IDC_NODE_TABLES_TEST */
91
92
#define DUMP_CONTENT_MODEL
93
94
#ifdef LIBXML_READER_ENABLED
95
/* #define XML_SCHEMA_READER_ENABLED */
96
#endif
97
98
0
#define UNBOUNDED (1 << 30)
99
100
0
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
101
102
/*
103
 * The XML Schemas namespaces
104
 */
105
static const xmlChar *xmlSchemaNs = (const xmlChar *)
106
    "http://www.w3.org/2001/XMLSchema";
107
108
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
109
    "http://www.w3.org/2001/XMLSchema-instance";
110
111
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
112
    "http://www.w3.org/2000/xmlns/";
113
114
/*
115
* Come casting macros.
116
*/
117
0
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
118
0
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
119
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
120
0
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
121
0
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
122
0
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
123
0
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
124
0
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
125
0
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
126
0
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
127
0
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
128
0
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
129
0
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
130
0
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
131
0
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
132
0
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
133
0
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
134
135
/*
136
* Macros to query common properties of components.
137
*/
138
0
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
139
140
0
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
141
/*
142
* Macros for element declarations.
143
*/
144
0
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
145
146
0
#define WXS_SUBST_HEAD(item) (item)->refDecl
147
/*
148
* Macros for attribute declarations.
149
*/
150
0
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
151
/*
152
* Macros for attribute uses.
153
*/
154
0
#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
155
156
0
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
157
158
0
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
159
160
0
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
161
/*
162
* Macros for attribute groups.
163
*/
164
0
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
165
0
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
166
/*
167
* Macros for particles.
168
*/
169
0
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
170
171
0
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
172
173
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
174
175
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
176
/*
177
* Macros for model groups definitions.
178
*/
179
0
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
180
/*
181
* Macros for model groups.
182
*/
183
#define WXS_IS_MODEL_GROUP(i) \
184
0
    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
185
0
     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
186
0
     ((i)->type == XML_SCHEMA_TYPE_ALL))
187
188
0
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
189
/*
190
* Macros for schema buckets.
191
*/
192
0
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
193
0
    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
194
195
0
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
196
0
    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
197
198
0
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
199
200
0
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
201
/*
202
* Macros for complex/simple types.
203
*/
204
#define WXS_IS_ANYTYPE(i) \
205
0
     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
206
0
      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
207
208
#define WXS_IS_COMPLEX(i) \
209
0
    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
210
0
     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
211
212
#define WXS_IS_SIMPLE(item) \
213
0
    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
214
0
     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
215
0
      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
216
217
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
218
0
    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
219
0
      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
220
221
#define WXS_IS_RESTRICTION(t) \
222
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
223
224
#define WXS_IS_EXTENSION(t) \
225
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
226
227
#define WXS_IS_TYPE_NOT_FIXED(i) \
228
0
    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
229
0
     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
230
231
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
232
0
    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
233
0
     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
234
235
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
236
237
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
238
/*
239
* Macros for exclusively for complex types.
240
*/
241
#define WXS_HAS_COMPLEX_CONTENT(item) \
242
    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
243
     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
244
     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
245
246
#define WXS_HAS_SIMPLE_CONTENT(item) \
247
0
    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
248
0
     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
249
250
#define WXS_HAS_MIXED_CONTENT(item) \
251
0
    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
252
253
#define WXS_EMPTIABLE(t) \
254
0
    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
255
256
0
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
257
258
0
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
259
260
0
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
261
/*
262
* Macros for exclusively for simple types.
263
*/
264
0
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
265
266
0
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
267
268
0
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
269
270
0
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
271
/*
272
* Misc parser context macros.
273
*/
274
0
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
275
276
0
#define WXS_HAS_BUCKETS(ctx) \
277
0
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
278
0
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
279
280
0
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
281
282
0
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
283
284
#define WXS_SCHEMA(ctx) (ctx)->schema
285
286
#define WXS_ADD_LOCAL(ctx, item) \
287
0
    do { \
288
0
        if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) < 0) { \
289
0
            xmlFree(item); \
290
0
            item = NULL; \
291
0
        } \
292
0
    } while (0)
293
294
#define WXS_ADD_GLOBAL(ctx, item) \
295
0
    do { \
296
0
        if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) < 0) { \
297
0
            xmlFree(item); \
298
0
            item = NULL; \
299
0
        } \
300
0
    } while (0)
301
302
#define WXS_ADD_PENDING(ctx, item) \
303
0
    xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
304
/*
305
* xmlSchemaItemList macros.
306
*/
307
0
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
308
/*
309
* Misc macros.
310
*/
311
#define IS_SCHEMA(node, type) \
312
0
   ((node != NULL) && (node->ns != NULL) && \
313
0
    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
314
0
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
315
316
0
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
317
318
/*
319
* Since we put the default/fixed values into the dict, we can
320
* use pointer comparison for those values.
321
* REMOVED: (xmlStrEqual((v1), (v2)))
322
*/
323
0
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
324
325
0
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
326
327
0
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
328
329
0
#define HFAILURE if (res == -1) goto exit_failure;
330
331
0
#define HERROR if (res != 0) goto exit_error;
332
333
0
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
334
/*
335
* Some flags used for various schema constraints.
336
*/
337
0
#define SUBSET_RESTRICTION  1<<0
338
0
#define SUBSET_EXTENSION    1<<1
339
#define SUBSET_SUBSTITUTION 1<<2
340
#define SUBSET_LIST         1<<3
341
#define SUBSET_UNION        1<<4
342
343
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
344
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
345
346
typedef struct _xmlSchemaItemList xmlSchemaItemList;
347
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
348
struct _xmlSchemaItemList {
349
    void **items;  /* used for dynamic addition of schemata */
350
    int nbItems; /* used for dynamic addition of schemata */
351
    int sizeItems; /* used for dynamic addition of schemata */
352
};
353
354
0
#define XML_SCHEMA_CTXT_PARSER 1
355
0
#define XML_SCHEMA_CTXT_VALIDATOR 2
356
357
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
358
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
359
struct _xmlSchemaAbstractCtxt {
360
    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
361
    void *dummy; /* Fix alignment issues */
362
};
363
364
typedef struct _xmlSchemaBucket xmlSchemaBucket;
365
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
366
367
0
#define XML_SCHEMA_SCHEMA_MAIN 0
368
0
#define XML_SCHEMA_SCHEMA_IMPORT 1
369
0
#define XML_SCHEMA_SCHEMA_INCLUDE 2
370
0
#define XML_SCHEMA_SCHEMA_REDEFINE 3
371
372
/**
373
 * xmlSchemaSchemaRelation:
374
 *
375
 * Used to create a graph of schema relationships.
376
 */
377
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
378
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
379
struct _xmlSchemaSchemaRelation {
380
    xmlSchemaSchemaRelationPtr next;
381
    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
382
    const xmlChar *importNamespace;
383
    xmlSchemaBucketPtr bucket;
384
};
385
386
0
#define XML_SCHEMA_BUCKET_MARKED 1<<0
387
0
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
388
389
struct _xmlSchemaBucket {
390
    int type;
391
    int flags;
392
    const xmlChar *schemaLocation;
393
    const xmlChar *origTargetNamespace;
394
    const xmlChar *targetNamespace;
395
    xmlDocPtr doc;
396
    xmlSchemaSchemaRelationPtr relations;
397
    int located;
398
    int parsed;
399
    int imported;
400
    int preserveDoc;
401
    xmlSchemaItemListPtr globals; /* Global components. */
402
    xmlSchemaItemListPtr locals; /* Local components. */
403
};
404
405
/**
406
 * xmlSchemaImport:
407
 * (extends xmlSchemaBucket)
408
 *
409
 * Reflects a schema. Holds some information
410
 * about the schema and its toplevel components. Duplicate
411
 * toplevel components are not checked at this level.
412
 */
413
typedef struct _xmlSchemaImport xmlSchemaImport;
414
typedef xmlSchemaImport *xmlSchemaImportPtr;
415
struct _xmlSchemaImport {
416
    int type; /* Main OR import OR include. */
417
    int flags;
418
    const xmlChar *schemaLocation; /* The URI of the schema document. */
419
    /* For chameleon includes, @origTargetNamespace will be NULL */
420
    const xmlChar *origTargetNamespace;
421
    /*
422
    * For chameleon includes, @targetNamespace will be the
423
    * targetNamespace of the including schema.
424
    */
425
    const xmlChar *targetNamespace;
426
    xmlDocPtr doc; /* The schema node-tree. */
427
    /* @relations will hold any included/imported/redefined schemas. */
428
    xmlSchemaSchemaRelationPtr relations;
429
    int located;
430
    int parsed;
431
    int imported;
432
    int preserveDoc;
433
    xmlSchemaItemListPtr globals;
434
    xmlSchemaItemListPtr locals;
435
    /* The imported schema. */
436
    xmlSchemaPtr schema;
437
};
438
439
/*
440
* (extends xmlSchemaBucket)
441
*/
442
typedef struct _xmlSchemaInclude xmlSchemaInclude;
443
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
444
struct _xmlSchemaInclude {
445
    int type;
446
    int flags;
447
    const xmlChar *schemaLocation;
448
    const xmlChar *origTargetNamespace;
449
    const xmlChar *targetNamespace;
450
    xmlDocPtr doc;
451
    xmlSchemaSchemaRelationPtr relations;
452
    int located;
453
    int parsed;
454
    int imported;
455
    int preserveDoc;
456
    xmlSchemaItemListPtr globals; /* Global components. */
457
    xmlSchemaItemListPtr locals; /* Local components. */
458
459
    /* The owning main or import schema bucket. */
460
    xmlSchemaImportPtr ownerImport;
461
};
462
463
/**
464
 * xmlSchemaBasicItem:
465
 *
466
 * The abstract base type for schema components.
467
 */
468
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
469
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
470
struct _xmlSchemaBasicItem {
471
    xmlSchemaTypeType type;
472
    void *dummy; /* Fix alignment issues */
473
};
474
475
/**
476
 * xmlSchemaAnnotItem:
477
 *
478
 * The abstract base type for annotated schema components.
479
 * (Extends xmlSchemaBasicItem)
480
 */
481
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
482
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
483
struct _xmlSchemaAnnotItem {
484
    xmlSchemaTypeType type;
485
    xmlSchemaAnnotPtr annot;
486
};
487
488
/**
489
 * xmlSchemaTreeItem:
490
 *
491
 * The abstract base type for tree-like structured schema components.
492
 * (Extends xmlSchemaAnnotItem)
493
 */
494
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
495
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
496
struct _xmlSchemaTreeItem {
497
    xmlSchemaTypeType type;
498
    xmlSchemaAnnotPtr annot;
499
    xmlSchemaTreeItemPtr next;
500
    xmlSchemaTreeItemPtr children;
501
};
502
503
504
0
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
505
/**
506
 * xmlSchemaAttributeUsePtr:
507
 *
508
 * The abstract base type for tree-like structured schema components.
509
 * (Extends xmlSchemaTreeItem)
510
 */
511
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
512
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
513
struct _xmlSchemaAttributeUse {
514
    xmlSchemaTypeType type;
515
    xmlSchemaAnnotPtr annot;
516
    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
517
    /*
518
    * The attr. decl. OR a QName-ref. to an attr. decl. OR
519
    * a QName-ref. to an attribute group definition.
520
    */
521
    xmlSchemaAttributePtr attrDecl;
522
523
    int flags;
524
    xmlNodePtr node;
525
    int occurs; /* required, optional */
526
    const xmlChar * defValue;
527
    xmlSchemaValPtr defVal;
528
};
529
530
/**
531
 * xmlSchemaAttributeUseProhibPtr:
532
 *
533
 * A helper component to reflect attribute prohibitions.
534
 * (Extends xmlSchemaBasicItem)
535
 */
536
typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
537
typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
538
struct _xmlSchemaAttributeUseProhib {
539
    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
540
    xmlNodePtr node;
541
    const xmlChar *name;
542
    const xmlChar *targetNamespace;
543
    int isRef;
544
};
545
546
/**
547
 * xmlSchemaRedef:
548
 */
549
typedef struct _xmlSchemaRedef xmlSchemaRedef;
550
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
551
struct _xmlSchemaRedef {
552
    xmlSchemaRedefPtr next;
553
    xmlSchemaBasicItemPtr item; /* The redefining component. */
554
    xmlSchemaBasicItemPtr reference; /* The referencing component. */
555
    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
556
    const xmlChar *refName; /* The name of the to-be-redefined component. */
557
    const xmlChar *refTargetNs; /* The target namespace of the
558
                                   to-be-redefined comp. */
559
    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
560
};
561
562
/**
563
 * xmlSchemaConstructionCtxt:
564
 */
565
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
566
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
567
struct _xmlSchemaConstructionCtxt {
568
    xmlSchemaPtr mainSchema; /* The main schema. */
569
    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
570
    xmlDictPtr dict;
571
    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
572
    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
573
    xmlSchemaBucketPtr bucket; /* The current schema bucket */
574
    xmlSchemaItemListPtr pending; /* All Components of all schemas that
575
                                     need to be fixed. */
576
    xmlHashTablePtr substGroups;
577
    xmlSchemaRedefPtr redefs;
578
    xmlSchemaRedefPtr lastRedef;
579
};
580
581
#define XML_SCHEMAS_PARSE_ERROR   1
582
0
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
583
584
struct _xmlSchemaParserCtxt {
585
    int type;
586
    void *errCtxt;             /* user specific error context */
587
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
588
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
589
    int err;
590
    int nberrors;
591
    xmlStructuredErrorFunc serror;
592
593
    xmlSchemaConstructionCtxtPtr constructor;
594
    int ownsConstructor; /* TODO: Move this to parser *flags*. */
595
596
    /* xmlSchemaPtr topschema;  */
597
    /* xmlHashTablePtr namespaces;  */
598
599
    xmlSchemaPtr schema;        /* The main schema in use */
600
    int counter;
601
602
    const xmlChar *URL;
603
    xmlDocPtr doc;
604
    int preserve;   /* Whether the doc should be freed  */
605
606
    const char *buffer;
607
    int size;
608
609
    /*
610
     * Used to build complex element content models
611
     */
612
    xmlAutomataPtr am;
613
    xmlAutomataStatePtr start;
614
    xmlAutomataStatePtr end;
615
    xmlAutomataStatePtr state;
616
617
    xmlDictPtr dict;    /* dictionary for interned string names */
618
    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
619
    int options;
620
    xmlSchemaValidCtxtPtr vctxt;
621
    int isS4S;
622
    int isRedefine;
623
    int xsiAssemble;
624
    int stop; /* If the parser should stop; i.e. a critical error. */
625
    const xmlChar *targetNamespace;
626
    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
627
628
    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
629
    int redefCounter; /* Used for redefinitions. */
630
    xmlSchemaItemListPtr attrProhibs;
631
632
    xmlResourceLoader resourceLoader;
633
    void *resourceCtxt;
634
};
635
636
/**
637
 * xmlSchemaQNameRef:
638
 *
639
 * A component reference item (not a schema component)
640
 * (Extends xmlSchemaBasicItem)
641
 */
642
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
643
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
644
struct _xmlSchemaQNameRef {
645
    xmlSchemaTypeType type;
646
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
647
    xmlSchemaTypeType itemType;
648
    const xmlChar *name;
649
    const xmlChar *targetNamespace;
650
    xmlNodePtr node;
651
};
652
653
/**
654
 * xmlSchemaParticle:
655
 *
656
 * A particle component.
657
 * (Extends xmlSchemaTreeItem)
658
 */
659
typedef struct _xmlSchemaParticle xmlSchemaParticle;
660
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
661
struct _xmlSchemaParticle {
662
    xmlSchemaTypeType type;
663
    xmlSchemaAnnotPtr annot;
664
    xmlSchemaTreeItemPtr next; /* next particle */
665
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
666
  a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
667
        etc.) */
668
    int minOccurs;
669
    int maxOccurs;
670
    xmlNodePtr node;
671
};
672
673
/**
674
 * xmlSchemaModelGroup:
675
 *
676
 * A model group component.
677
 * (Extends xmlSchemaTreeItem)
678
 */
679
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
680
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
681
struct _xmlSchemaModelGroup {
682
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
683
    xmlSchemaAnnotPtr annot;
684
    xmlSchemaTreeItemPtr next; /* not used */
685
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
686
    xmlNodePtr node;
687
};
688
689
0
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
690
0
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
691
/**
692
 * xmlSchemaModelGroupDef:
693
 *
694
 * A model group definition component.
695
 * (Extends xmlSchemaTreeItem)
696
 */
697
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
698
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
699
struct _xmlSchemaModelGroupDef {
700
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
701
    xmlSchemaAnnotPtr annot;
702
    xmlSchemaTreeItemPtr next; /* not used */
703
    xmlSchemaTreeItemPtr children; /* the "model group" */
704
    const xmlChar *name;
705
    const xmlChar *targetNamespace;
706
    xmlNodePtr node;
707
    int flags;
708
};
709
710
typedef struct _xmlSchemaIDC xmlSchemaIDC;
711
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
712
713
/**
714
 * xmlSchemaIDCSelect:
715
 *
716
 * The identity-constraint "field" and "selector" item, holding the
717
 * XPath expression.
718
 */
719
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
720
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
721
struct _xmlSchemaIDCSelect {
722
    xmlSchemaIDCSelectPtr next;
723
    xmlSchemaIDCPtr idc;
724
    int index; /* an index position if significant for IDC key-sequences */
725
    const xmlChar *xpath; /* the XPath expression */
726
    void *xpathComp; /* the compiled XPath expression */
727
};
728
729
/**
730
 * xmlSchemaIDC:
731
 *
732
 * The identity-constraint definition component.
733
 * (Extends xmlSchemaAnnotItem)
734
 */
735
736
struct _xmlSchemaIDC {
737
    xmlSchemaTypeType type;
738
    xmlSchemaAnnotPtr annot;
739
    xmlSchemaIDCPtr next;
740
    xmlNodePtr node;
741
    const xmlChar *name;
742
    const xmlChar *targetNamespace;
743
    xmlSchemaIDCSelectPtr selector;
744
    xmlSchemaIDCSelectPtr fields;
745
    int nbFields;
746
    xmlSchemaQNameRefPtr ref;
747
};
748
749
/**
750
 * xmlSchemaIDCAug:
751
 *
752
 * The augmented IDC information used for validation.
753
 */
754
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
755
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
756
struct _xmlSchemaIDCAug {
757
    xmlSchemaIDCAugPtr next; /* next in a list */
758
    xmlSchemaIDCPtr def; /* the IDC definition */
759
    int keyrefDepth; /* the lowest tree level to which IDC
760
                        tables need to be bubbled upwards */
761
};
762
763
/**
764
 * xmlSchemaPSVIIDCKeySequence:
765
 *
766
 * The key sequence of a node table item.
767
 */
768
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
769
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
770
struct _xmlSchemaPSVIIDCKey {
771
    xmlSchemaTypePtr type;
772
    xmlSchemaValPtr val;
773
};
774
775
/**
776
 * xmlSchemaPSVIIDCNode:
777
 *
778
 * The node table item of a node table.
779
 */
780
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
781
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
782
struct _xmlSchemaPSVIIDCNode {
783
    xmlNodePtr node;
784
    xmlSchemaPSVIIDCKeyPtr *keys;
785
    int nodeLine;
786
    int nodeQNameID;
787
788
};
789
790
/**
791
 * xmlSchemaPSVIIDCBinding:
792
 *
793
 * The identity-constraint binding item of the [identity-constraint table].
794
 */
795
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
796
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
797
struct _xmlSchemaPSVIIDCBinding {
798
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
799
    xmlSchemaIDCPtr definition; /* the IDC definition */
800
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
801
    int nbNodes; /* number of entries in the node table */
802
    int sizeNodes; /* size of the node table */
803
    xmlSchemaItemListPtr dupls;
804
};
805
806
807
0
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
808
0
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
809
810
#define XPATH_STATE_OBJ_MATCHES -2
811
#define XPATH_STATE_OBJ_BLOCKED -3
812
813
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
814
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
815
816
/**
817
 * xmlSchemaIDCStateObj:
818
 *
819
 * The state object used to evaluate XPath expressions.
820
 */
821
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
822
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
823
struct _xmlSchemaIDCStateObj {
824
    int type;
825
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
826
    int depth; /* depth of creation */
827
    int *history; /* list of (depth, state-id) tuples */
828
    int nbHistory;
829
    int sizeHistory;
830
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
831
                                       matcher */
832
    xmlSchemaIDCSelectPtr sel;
833
    void *xpathCtxt;
834
};
835
836
0
#define IDC_MATCHER 0
837
838
/**
839
 * xmlSchemaIDCMatcher:
840
 *
841
 * Used to evaluate IDC selectors (and fields).
842
 */
843
struct _xmlSchemaIDCMatcher {
844
    int type;
845
    int depth; /* the tree depth at creation time */
846
    xmlSchemaIDCMatcherPtr next; /* next in the list */
847
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
848
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
849
    int idcType;
850
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
851
                                         elements */
852
    int sizeKeySeqs;
853
    xmlSchemaItemListPtr targets; /* list of target-node
854
                                     (xmlSchemaPSVIIDCNodePtr) entries */
855
    xmlHashTablePtr htab;
856
};
857
858
/*
859
* Element info flags.
860
*/
861
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
862
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
863
0
#define XML_SCHEMA_ELEM_INFO_NILLED        1<<2
864
0
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        1<<3
865
866
0
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
867
0
#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
868
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
869
870
0
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
871
0
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
872
0
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
873
0
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
874
875
/**
876
 * xmlSchemaNodeInfo:
877
 *
878
 * Holds information of an element node.
879
 */
880
struct _xmlSchemaNodeInfo {
881
    int nodeType;
882
    xmlNodePtr node;
883
    int nodeLine;
884
    const xmlChar *localName;
885
    const xmlChar *nsName;
886
    const xmlChar *value;
887
    xmlSchemaValPtr val; /* the pre-computed value if any */
888
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
889
890
    int flags; /* combination of node info flags */
891
892
    int valNeeded;
893
    int normVal;
894
895
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
896
    int depth;
897
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
898
                                            for the scope element*/
899
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
900
                                           element */
901
    xmlRegExecCtxtPtr regexCtxt;
902
903
    const xmlChar **nsBindings; /* Namespace bindings on this element */
904
    int nbNsBindings;
905
    int sizeNsBindings;
906
907
    int hasKeyrefs;
908
    int appliedXPath; /* Indicates that an XPath has been applied. */
909
};
910
911
0
#define XML_SCHEMAS_ATTR_UNKNOWN 1
912
0
#define XML_SCHEMAS_ATTR_ASSESSED 2
913
#define XML_SCHEMAS_ATTR_PROHIBITED 3
914
0
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
915
0
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
916
0
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
917
0
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
918
0
#define XML_SCHEMAS_ATTR_DEFAULT 8
919
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
920
0
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
921
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
922
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
923
0
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
924
0
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
925
0
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
926
0
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
927
0
#define XML_SCHEMAS_ATTR_META 17
928
/*
929
* @metaType values of xmlSchemaAttrInfo.
930
*/
931
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
932
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
933
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
934
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
935
0
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
936
937
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
938
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
939
struct _xmlSchemaAttrInfo {
940
    int nodeType;
941
    xmlNodePtr node;
942
    int nodeLine;
943
    const xmlChar *localName;
944
    const xmlChar *nsName;
945
    const xmlChar *value;
946
    xmlSchemaValPtr val; /* the pre-computed value if any */
947
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
948
    int flags; /* combination of node info flags */
949
950
    xmlSchemaAttributePtr decl; /* the attribute declaration */
951
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
952
    int state;
953
    int metaType;
954
    const xmlChar *vcValue; /* the value constraint value */
955
    xmlSchemaNodeInfoPtr parent;
956
};
957
958
959
0
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
960
/**
961
 * xmlSchemaValidCtxt:
962
 *
963
 * A Schemas validation context
964
 */
965
struct _xmlSchemaValidCtxt {
966
    int type;
967
    void *errCtxt;             /* user specific data block */
968
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
969
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
970
    xmlStructuredErrorFunc serror;
971
972
    xmlSchemaPtr schema;        /* The schema in use */
973
    xmlDocPtr doc;
974
    xmlParserInputBufferPtr input;
975
    xmlCharEncoding enc;
976
    xmlSAXHandlerPtr sax;
977
    xmlParserCtxtPtr parserCtxt;
978
    void *user_data; /* TODO: What is this for? */
979
    char *filename;
980
981
    int err;
982
    int nberrors;
983
984
    xmlNodePtr node;
985
    xmlNodePtr cur;
986
    /* xmlSchemaTypePtr type; */
987
988
    xmlRegExecCtxtPtr regexp;
989
    xmlSchemaValPtr value;
990
991
    int valueWS;
992
    int options;
993
    xmlNodePtr validationRoot;
994
    xmlSchemaParserCtxtPtr pctxt;
995
    int xsiAssemble;
996
997
    int depth;
998
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
999
    int sizeElemInfos;
1000
    xmlSchemaNodeInfoPtr inode; /* the current element information */
1001
1002
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1003
1004
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1005
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1006
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1007
1008
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1009
    int nbIdcNodes;
1010
    int sizeIdcNodes;
1011
1012
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1013
    int nbIdcKeys;
1014
    int sizeIdcKeys;
1015
1016
    int flags;
1017
1018
    xmlDictPtr dict;
1019
1020
#ifdef LIBXML_READER_ENABLED
1021
    xmlTextReaderPtr reader;
1022
#endif
1023
1024
    xmlSchemaAttrInfoPtr *attrInfos;
1025
    int nbAttrInfos;
1026
    int sizeAttrInfos;
1027
1028
    int skipDepth;
1029
    xmlSchemaItemListPtr nodeQNames;
1030
    int hasKeyrefs;
1031
    int createIDCNodeTables;
1032
    int psviExposeIDCNodeTables;
1033
1034
    /* Locator for error reporting in streaming mode */
1035
    xmlSchemaValidityLocatorFunc locFunc;
1036
    void *locCtxt;
1037
};
1038
1039
/**
1040
 * xmlSchemaSubstGroup:
1041
 *
1042
 *
1043
 */
1044
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1045
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1046
struct _xmlSchemaSubstGroup {
1047
    xmlSchemaElementPtr head;
1048
    xmlSchemaItemListPtr members;
1049
};
1050
1051
/**
1052
 * xmlIDCHashEntry:
1053
 *
1054
 * an entry in hash tables to quickly look up keys/uniques
1055
 */
1056
typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1057
typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1058
struct _xmlIDCHashEntry {
1059
    xmlIDCHashEntryPtr next; /* next item with same hash */
1060
    int index;               /* index into associated item list */
1061
};
1062
1063
/************************************************************************
1064
 *                  *
1065
 *      Some predeclarations        *
1066
 *                  *
1067
 ************************************************************************/
1068
1069
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1070
                                 xmlSchemaPtr schema,
1071
                                 xmlNodePtr node);
1072
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1073
                                 xmlSchemaPtr schema,
1074
                                 xmlNodePtr node);
1075
static int
1076
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1077
                   xmlSchemaAbstractCtxtPtr ctxt);
1078
static const xmlChar *
1079
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1080
static int
1081
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1082
                     xmlNodePtr node);
1083
static int
1084
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1085
                       xmlSchemaParserCtxtPtr ctxt);
1086
static void
1087
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1088
static xmlSchemaWhitespaceValueType
1089
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1090
static xmlSchemaTreeItemPtr
1091
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1092
       xmlNodePtr node, xmlSchemaTypeType type,
1093
       int withParticle);
1094
static const xmlChar *
1095
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1096
static xmlSchemaTypeLinkPtr
1097
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1098
static void
1099
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1100
         const char *funcName,
1101
         const char *message) LIBXML_ATTR_FORMAT(3,0);
1102
static int
1103
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1104
           xmlSchemaTypePtr type,
1105
           xmlSchemaTypePtr baseType,
1106
           int subset);
1107
static void
1108
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1109
           xmlSchemaParserCtxtPtr ctxt);
1110
static void
1111
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1112
static xmlSchemaQNameRefPtr
1113
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1114
        xmlSchemaPtr schema,
1115
        xmlNodePtr node);
1116
1117
/************************************************************************
1118
 *                  *
1119
 *      Helper functions              *
1120
 *                  *
1121
 ************************************************************************/
1122
1123
/**
1124
 * xmlSchemaItemTypeToStr:
1125
 * @type: the type of the schema item
1126
 *
1127
 * Returns the component name of a schema item.
1128
 */
1129
static const xmlChar *
1130
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1131
0
{
1132
0
    switch (type) {
1133
0
  case XML_SCHEMA_TYPE_BASIC:
1134
0
      return(BAD_CAST "simple type definition");
1135
0
  case XML_SCHEMA_TYPE_SIMPLE:
1136
0
      return(BAD_CAST "simple type definition");
1137
0
  case XML_SCHEMA_TYPE_COMPLEX:
1138
0
      return(BAD_CAST "complex type definition");
1139
0
  case XML_SCHEMA_TYPE_ELEMENT:
1140
0
      return(BAD_CAST "element declaration");
1141
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1142
0
      return(BAD_CAST "attribute use");
1143
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1144
0
      return(BAD_CAST "attribute declaration");
1145
0
  case XML_SCHEMA_TYPE_GROUP:
1146
0
      return(BAD_CAST "model group definition");
1147
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1148
0
      return(BAD_CAST "attribute group definition");
1149
0
  case XML_SCHEMA_TYPE_NOTATION:
1150
0
      return(BAD_CAST "notation declaration");
1151
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1152
0
      return(BAD_CAST "model group (sequence)");
1153
0
  case XML_SCHEMA_TYPE_CHOICE:
1154
0
      return(BAD_CAST "model group (choice)");
1155
0
  case XML_SCHEMA_TYPE_ALL:
1156
0
      return(BAD_CAST "model group (all)");
1157
0
  case XML_SCHEMA_TYPE_PARTICLE:
1158
0
      return(BAD_CAST "particle");
1159
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1160
0
      return(BAD_CAST "unique identity-constraint");
1161
      /* return(BAD_CAST "IDC (unique)"); */
1162
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1163
0
      return(BAD_CAST "key identity-constraint");
1164
      /* return(BAD_CAST "IDC (key)"); */
1165
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1166
0
      return(BAD_CAST "keyref identity-constraint");
1167
      /* return(BAD_CAST "IDC (keyref)"); */
1168
0
  case XML_SCHEMA_TYPE_ANY:
1169
0
      return(BAD_CAST "wildcard (any)");
1170
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1171
0
      return(BAD_CAST "[helper component] QName reference");
1172
0
  case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1173
0
      return(BAD_CAST "[helper component] attribute use prohibition");
1174
0
  default:
1175
0
      return(BAD_CAST "Not a schema component");
1176
0
    }
1177
0
}
1178
1179
/**
1180
 * xmlSchemaGetComponentTypeStr:
1181
 * @type: the type of the schema item
1182
 *
1183
 * Returns the component name of a schema item.
1184
 */
1185
static const xmlChar *
1186
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1187
0
{
1188
0
    switch (item->type) {
1189
0
  case XML_SCHEMA_TYPE_BASIC:
1190
0
      if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1191
0
    return(BAD_CAST "complex type definition");
1192
0
      else
1193
0
    return(BAD_CAST "simple type definition");
1194
0
  default:
1195
0
      return(xmlSchemaItemTypeToStr(item->type));
1196
0
    }
1197
0
}
1198
1199
/**
1200
 * xmlSchemaGetComponentNode:
1201
 * @item: a schema component
1202
 *
1203
 * Returns node associated with the schema component.
1204
 * NOTE that such a node need not be available; plus, a component's
1205
 * node need not to reflect the component directly, since there is no
1206
 * one-to-one relationship between the XML Schema representation and
1207
 * the component representation.
1208
 */
1209
static xmlNodePtr
1210
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1211
0
{
1212
0
    switch (item->type) {
1213
0
  case XML_SCHEMA_TYPE_ELEMENT:
1214
0
      return (((xmlSchemaElementPtr) item)->node);
1215
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1216
0
      return (((xmlSchemaAttributePtr) item)->node);
1217
0
  case XML_SCHEMA_TYPE_COMPLEX:
1218
0
  case XML_SCHEMA_TYPE_SIMPLE:
1219
0
      return (((xmlSchemaTypePtr) item)->node);
1220
0
  case XML_SCHEMA_TYPE_ANY:
1221
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1222
0
      return (((xmlSchemaWildcardPtr) item)->node);
1223
0
  case XML_SCHEMA_TYPE_PARTICLE:
1224
0
      return (((xmlSchemaParticlePtr) item)->node);
1225
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1226
0
  case XML_SCHEMA_TYPE_CHOICE:
1227
0
  case XML_SCHEMA_TYPE_ALL:
1228
0
      return (((xmlSchemaModelGroupPtr) item)->node);
1229
0
  case XML_SCHEMA_TYPE_GROUP:
1230
0
      return (((xmlSchemaModelGroupDefPtr) item)->node);
1231
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1232
0
      return (((xmlSchemaAttributeGroupPtr) item)->node);
1233
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1234
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1235
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1236
0
      return (((xmlSchemaIDCPtr) item)->node);
1237
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1238
0
      return(((xmlSchemaQNameRefPtr) item)->node);
1239
  /* TODO: What to do with NOTATIONs?
1240
  case XML_SCHEMA_TYPE_NOTATION:
1241
      return (((xmlSchemaNotationPtr) item)->node);
1242
  */
1243
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1244
0
      return (((xmlSchemaAttributeUsePtr) item)->node);
1245
0
  default:
1246
0
      return (NULL);
1247
0
    }
1248
0
}
1249
1250
#if 0
1251
/**
1252
 * xmlSchemaGetNextComponent:
1253
 * @item: a schema component
1254
 *
1255
 * Returns the next sibling of the schema component.
1256
 */
1257
static xmlSchemaBasicItemPtr
1258
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1259
{
1260
    switch (item->type) {
1261
  case XML_SCHEMA_TYPE_ELEMENT:
1262
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1263
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1264
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1265
  case XML_SCHEMA_TYPE_COMPLEX:
1266
  case XML_SCHEMA_TYPE_SIMPLE:
1267
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1268
  case XML_SCHEMA_TYPE_ANY:
1269
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1270
      return (NULL);
1271
  case XML_SCHEMA_TYPE_PARTICLE:
1272
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1273
  case XML_SCHEMA_TYPE_SEQUENCE:
1274
  case XML_SCHEMA_TYPE_CHOICE:
1275
  case XML_SCHEMA_TYPE_ALL:
1276
      return (NULL);
1277
  case XML_SCHEMA_TYPE_GROUP:
1278
      return (NULL);
1279
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1280
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1281
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1282
  case XML_SCHEMA_TYPE_IDC_KEY:
1283
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1284
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1285
  default:
1286
      return (NULL);
1287
    }
1288
}
1289
#endif
1290
1291
1292
/**
1293
 * xmlSchemaFormatQName:
1294
 * @buf: the string buffer
1295
 * @namespaceName:  the namespace name
1296
 * @localName: the local name
1297
 *
1298
 * Returns the given QName in the format "{namespaceName}localName" or
1299
 * just "localName" if @namespaceName is NULL.
1300
 *
1301
 * Returns the localName if @namespaceName is NULL, a formatted
1302
 * string otherwise.
1303
 */
1304
static const xmlChar*
1305
xmlSchemaFormatQName(xmlChar **buf,
1306
         const xmlChar *namespaceName,
1307
         const xmlChar *localName)
1308
0
{
1309
0
    FREE_AND_NULL(*buf)
1310
0
    if (namespaceName != NULL) {
1311
0
  *buf = xmlStrdup(BAD_CAST "{");
1312
0
  *buf = xmlStrcat(*buf, namespaceName);
1313
0
  *buf = xmlStrcat(*buf, BAD_CAST "}");
1314
0
    }
1315
0
    if (localName != NULL) {
1316
0
  if (namespaceName == NULL)
1317
0
      return(localName);
1318
0
  *buf = xmlStrcat(*buf, localName);
1319
0
    } else {
1320
0
  *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1321
0
    }
1322
0
    return ((const xmlChar *) *buf);
1323
0
}
1324
1325
static const xmlChar*
1326
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1327
0
{
1328
0
    if (ns != NULL)
1329
0
  return (xmlSchemaFormatQName(buf, ns->href, localName));
1330
0
    else
1331
0
  return (xmlSchemaFormatQName(buf, NULL, localName));
1332
0
}
1333
1334
static const xmlChar *
1335
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1336
0
{
1337
0
    if (item == NULL) {
1338
0
        return (NULL);
1339
0
    }
1340
0
    switch (item->type) {
1341
0
  case XML_SCHEMA_TYPE_ELEMENT:
1342
0
      return (((xmlSchemaElementPtr) item)->name);
1343
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1344
0
      return (((xmlSchemaAttributePtr) item)->name);
1345
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1346
0
      return (((xmlSchemaAttributeGroupPtr) item)->name);
1347
0
  case XML_SCHEMA_TYPE_BASIC:
1348
0
  case XML_SCHEMA_TYPE_SIMPLE:
1349
0
  case XML_SCHEMA_TYPE_COMPLEX:
1350
0
      return (((xmlSchemaTypePtr) item)->name);
1351
0
  case XML_SCHEMA_TYPE_GROUP:
1352
0
      return (((xmlSchemaModelGroupDefPtr) item)->name);
1353
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1354
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1355
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1356
0
      return (((xmlSchemaIDCPtr) item)->name);
1357
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1358
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1359
0
    return(xmlSchemaGetComponentName(
1360
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1361
0
      } else
1362
0
    return(NULL);
1363
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1364
0
      return (((xmlSchemaQNameRefPtr) item)->name);
1365
0
  case XML_SCHEMA_TYPE_NOTATION:
1366
0
      return (((xmlSchemaNotationPtr) item)->name);
1367
0
  default:
1368
      /*
1369
      * Other components cannot have names.
1370
      */
1371
0
      break;
1372
0
    }
1373
0
    return (NULL);
1374
0
}
1375
1376
0
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1377
0
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1378
/*
1379
static const xmlChar *
1380
xmlSchemaGetQNameRefName(void *ref)
1381
{
1382
    return(((xmlSchemaQNameRefPtr) ref)->name);
1383
}
1384
1385
static const xmlChar *
1386
xmlSchemaGetQNameRefTargetNs(void *ref)
1387
{
1388
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1389
}
1390
*/
1391
1392
static const xmlChar *
1393
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1394
0
{
1395
0
    if (item == NULL) {
1396
0
        return (NULL);
1397
0
    }
1398
0
    switch (item->type) {
1399
0
  case XML_SCHEMA_TYPE_ELEMENT:
1400
0
      return (((xmlSchemaElementPtr) item)->targetNamespace);
1401
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1402
0
      return (((xmlSchemaAttributePtr) item)->targetNamespace);
1403
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1404
0
      return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1405
0
  case XML_SCHEMA_TYPE_BASIC:
1406
0
      return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1407
0
  case XML_SCHEMA_TYPE_SIMPLE:
1408
0
  case XML_SCHEMA_TYPE_COMPLEX:
1409
0
      return (((xmlSchemaTypePtr) item)->targetNamespace);
1410
0
  case XML_SCHEMA_TYPE_GROUP:
1411
0
      return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1412
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1413
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1414
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1415
0
      return (((xmlSchemaIDCPtr) item)->targetNamespace);
1416
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1417
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1418
0
    return(xmlSchemaGetComponentTargetNs(
1419
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1420
0
      }
1421
      /* TODO: Will returning NULL break something? */
1422
0
      break;
1423
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1424
0
      return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1425
0
  case XML_SCHEMA_TYPE_NOTATION:
1426
0
      return (((xmlSchemaNotationPtr) item)->targetNamespace);
1427
0
  default:
1428
      /*
1429
      * Other components cannot have names.
1430
      */
1431
0
      break;
1432
0
    }
1433
0
    return (NULL);
1434
0
}
1435
1436
static const xmlChar*
1437
xmlSchemaGetComponentQName(xmlChar **buf,
1438
         void *item)
1439
0
{
1440
0
    return (xmlSchemaFormatQName(buf,
1441
0
  xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1442
0
  xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1443
0
}
1444
1445
static const xmlChar*
1446
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1447
0
{
1448
0
    xmlChar *str = NULL;
1449
1450
0
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1451
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1452
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1453
0
  (xmlSchemaBasicItemPtr) item));
1454
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1455
0
    FREE_AND_NULL(str);
1456
0
    return(*buf);
1457
0
}
1458
1459
static const xmlChar*
1460
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1461
0
{
1462
0
    return(xmlSchemaGetComponentDesignation(buf, idc));
1463
0
}
1464
1465
/**
1466
 * xmlSchemaWildcardPCToString:
1467
 * @pc: the type of processContents
1468
 *
1469
 * Returns a string representation of the type of
1470
 * processContents.
1471
 */
1472
static const xmlChar *
1473
xmlSchemaWildcardPCToString(int pc)
1474
0
{
1475
0
    switch (pc) {
1476
0
  case XML_SCHEMAS_ANY_SKIP:
1477
0
      return (BAD_CAST "skip");
1478
0
  case XML_SCHEMAS_ANY_LAX:
1479
0
      return (BAD_CAST "lax");
1480
0
  case XML_SCHEMAS_ANY_STRICT:
1481
0
      return (BAD_CAST "strict");
1482
0
  default:
1483
0
      return (BAD_CAST "invalid process contents");
1484
0
    }
1485
0
}
1486
1487
/**
1488
 * xmlSchemaGetCanonValueWhtspExt:
1489
 * @val: the precomputed value
1490
 * @retValue: the returned value
1491
 * @ws: the whitespace type of the value
1492
 * @for_hash: non-zero if this is supposed to generate a string for hashing
1493
 *
1494
 * Get a the canonical representation of the value.
1495
 * The caller has to free the returned retValue.
1496
 *
1497
 * Returns 0 if the value could be built and -1 in case of
1498
 *         API errors or if the value type is not supported yet.
1499
 */
1500
static int
1501
xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1502
               xmlSchemaWhitespaceValueType ws,
1503
               xmlChar **retValue,
1504
         int for_hash)
1505
0
{
1506
0
    int list;
1507
0
    xmlSchemaValType valType;
1508
0
    const xmlChar *value, *value2 = NULL;
1509
1510
1511
0
    if ((retValue == NULL) || (val == NULL))
1512
0
  return (-1);
1513
0
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1514
0
    *retValue = NULL;
1515
0
    do {
1516
0
  value = NULL;
1517
0
  valType = xmlSchemaGetValType(val);
1518
0
  switch (valType) {
1519
0
      case XML_SCHEMAS_STRING:
1520
0
      case XML_SCHEMAS_NORMSTRING:
1521
0
      case XML_SCHEMAS_ANYSIMPLETYPE:
1522
0
    value = xmlSchemaValueGetAsString(val);
1523
0
    if (value != NULL) {
1524
0
        if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1525
0
      value2 = xmlSchemaCollapseString(value);
1526
0
        else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1527
0
      value2 = xmlSchemaWhiteSpaceReplace(value);
1528
0
        if (value2 != NULL)
1529
0
      value = value2;
1530
0
    }
1531
0
    break;
1532
0
      default:
1533
0
    if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1534
0
        if (value2 != NULL)
1535
0
      xmlFree((xmlChar *) value2);
1536
0
        goto internal_error;
1537
0
    }
1538
0
    if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1539
        /* We can mostly use the canonical value for hashing,
1540
           except in the case of decimal.  There the canonical
1541
           representation requires a trailing '.0' even for
1542
           non-fractional numbers, but for the derived integer
1543
           types it forbids any decimal point.  Nevertheless they
1544
           compare equal if the value is equal.  We need to generate
1545
           the same hash value for this to work, and it's easiest
1546
           to just cut off the useless '.0' suffix for the
1547
           decimal type.  */
1548
0
        int len = xmlStrlen(value2);
1549
0
        if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1550
0
          ((xmlChar*)value2)[len-2] = 0;
1551
0
    }
1552
0
    value = value2;
1553
0
  }
1554
0
  if (*retValue == NULL)
1555
0
      if (value == NULL) {
1556
0
    if (! list)
1557
0
        *retValue = xmlStrdup(BAD_CAST "");
1558
0
      } else
1559
0
    *retValue = xmlStrdup(value);
1560
0
  else if (value != NULL) {
1561
      /* List. */
1562
0
      *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1563
0
      *retValue = xmlStrcat((xmlChar *) *retValue, value);
1564
0
  }
1565
0
  FREE_AND_NULL(value2)
1566
0
  val = xmlSchemaValueGetNext(val);
1567
0
    } while (val != NULL);
1568
1569
0
    return (0);
1570
0
internal_error:
1571
0
    if (*retValue != NULL)
1572
0
  xmlFree((xmlChar *) (*retValue));
1573
0
    if (value2 != NULL)
1574
0
  xmlFree((xmlChar *) value2);
1575
0
    return (-1);
1576
0
}
1577
1578
static int
1579
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1580
             xmlSchemaWhitespaceValueType ws,
1581
             xmlChar **retValue)
1582
0
{
1583
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1584
0
}
1585
1586
static int
1587
xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1588
         xmlChar **retValue)
1589
0
{
1590
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1591
0
              retValue, 1);
1592
0
}
1593
1594
/**
1595
 * xmlSchemaFormatItemForReport:
1596
 * @buf: the string buffer
1597
 * @itemDes: the designation of the item
1598
 * @itemName: the name of the item
1599
 * @item: the item as an object
1600
 * @itemNode: the node of the item
1601
 * @local: the local name
1602
 * @parsing: if the function is used during the parse
1603
 *
1604
 * Returns a representation of the given item used
1605
 * for error reports.
1606
 *
1607
 * The following order is used to build the resulting
1608
 * designation if the arguments are not NULL:
1609
 * 1a. If itemDes not NULL -> itemDes
1610
 * 1b. If (itemDes not NULL) and (itemName not NULL)
1611
 *     -> itemDes + itemName
1612
 * 2. If the preceding was NULL and (item not NULL) -> item
1613
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1614
 *
1615
 * If the itemNode is an attribute node, the name of the attribute
1616
 * will be appended to the result.
1617
 *
1618
 * Returns the formatted string and sets @buf to the resulting value.
1619
 */
1620
static xmlChar*
1621
xmlSchemaFormatItemForReport(xmlChar **buf,
1622
         const xmlChar *itemDes,
1623
         xmlSchemaBasicItemPtr item,
1624
         xmlNodePtr itemNode)
1625
0
{
1626
0
    xmlChar *str = NULL;
1627
0
    int named = 1;
1628
1629
0
    if (*buf != NULL) {
1630
0
  xmlFree(*buf);
1631
0
  *buf = NULL;
1632
0
    }
1633
1634
0
    if (itemDes != NULL) {
1635
0
  *buf = xmlStrdup(itemDes);
1636
0
    } else if (item != NULL) {
1637
0
  switch (item->type) {
1638
0
  case XML_SCHEMA_TYPE_BASIC: {
1639
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1640
1641
0
      if (WXS_IS_ATOMIC(type))
1642
0
    *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1643
0
      else if (WXS_IS_LIST(type))
1644
0
    *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1645
0
      else if (WXS_IS_UNION(type))
1646
0
    *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1647
0
      else
1648
0
    *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1649
0
      *buf = xmlStrcat(*buf, type->name);
1650
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1651
0
      }
1652
0
      break;
1653
0
  case XML_SCHEMA_TYPE_SIMPLE: {
1654
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1655
1656
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1657
0
    *buf = xmlStrdup(BAD_CAST"");
1658
0
      } else {
1659
0
    *buf = xmlStrdup(BAD_CAST "local ");
1660
0
      }
1661
0
      if (WXS_IS_ATOMIC(type))
1662
0
    *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1663
0
      else if (WXS_IS_LIST(type))
1664
0
    *buf = xmlStrcat(*buf, BAD_CAST "list type");
1665
0
      else if (WXS_IS_UNION(type))
1666
0
    *buf = xmlStrcat(*buf, BAD_CAST "union type");
1667
0
      else
1668
0
    *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1669
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1670
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1671
0
    *buf = xmlStrcat(*buf, type->name);
1672
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1673
0
      }
1674
0
      }
1675
0
      break;
1676
0
  case XML_SCHEMA_TYPE_COMPLEX: {
1677
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1678
1679
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1680
0
    *buf = xmlStrdup(BAD_CAST "");
1681
0
      else
1682
0
    *buf = xmlStrdup(BAD_CAST "local ");
1683
0
      *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1684
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1685
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1686
0
    *buf = xmlStrcat(*buf, type->name);
1687
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1688
0
      }
1689
0
      }
1690
0
      break;
1691
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1692
0
    xmlSchemaAttributeUsePtr ause;
1693
1694
0
    ause = WXS_ATTR_USE_CAST item;
1695
0
    *buf = xmlStrdup(BAD_CAST "attribute use ");
1696
0
    if (WXS_ATTRUSE_DECL(ause) != NULL) {
1697
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1698
0
        *buf = xmlStrcat(*buf,
1699
0
      xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1700
0
        FREE_AND_NULL(str)
1701
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1702
0
    } else {
1703
0
        *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1704
0
    }
1705
0
      }
1706
0
      break;
1707
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
1708
0
    xmlSchemaAttributePtr attr;
1709
1710
0
    attr = (xmlSchemaAttributePtr) item;
1711
0
    *buf = xmlStrdup(BAD_CAST "attribute decl.");
1712
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1713
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1714
0
        attr->targetNamespace, attr->name));
1715
0
    FREE_AND_NULL(str)
1716
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1717
0
      }
1718
0
      break;
1719
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1720
0
      xmlSchemaGetComponentDesignation(buf, item);
1721
0
      break;
1722
0
  case XML_SCHEMA_TYPE_ELEMENT: {
1723
0
    xmlSchemaElementPtr elem;
1724
1725
0
    elem = (xmlSchemaElementPtr) item;
1726
0
    *buf = xmlStrdup(BAD_CAST "element decl.");
1727
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1728
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1729
0
        elem->targetNamespace, elem->name));
1730
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1731
0
      }
1732
0
      break;
1733
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1734
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1735
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1736
0
      if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1737
0
    *buf = xmlStrdup(BAD_CAST "unique '");
1738
0
      else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1739
0
    *buf = xmlStrdup(BAD_CAST "key '");
1740
0
      else
1741
0
    *buf = xmlStrdup(BAD_CAST "keyRef '");
1742
0
      *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1743
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1744
0
      break;
1745
0
  case XML_SCHEMA_TYPE_ANY:
1746
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1747
0
      *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1748
0
        ((xmlSchemaWildcardPtr) item)->processContents));
1749
0
      *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1750
0
      break;
1751
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
1752
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
1753
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
1754
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1755
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
1756
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
1757
0
  case XML_SCHEMA_FACET_PATTERN:
1758
0
  case XML_SCHEMA_FACET_ENUMERATION:
1759
0
  case XML_SCHEMA_FACET_WHITESPACE:
1760
0
  case XML_SCHEMA_FACET_LENGTH:
1761
0
  case XML_SCHEMA_FACET_MAXLENGTH:
1762
0
  case XML_SCHEMA_FACET_MINLENGTH:
1763
0
      *buf = xmlStrdup(BAD_CAST "facet '");
1764
0
      *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1765
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1766
0
      break;
1767
0
  case XML_SCHEMA_TYPE_GROUP: {
1768
0
    *buf = xmlStrdup(BAD_CAST "model group def.");
1769
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1770
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1771
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1772
0
    FREE_AND_NULL(str)
1773
0
      }
1774
0
      break;
1775
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1776
0
  case XML_SCHEMA_TYPE_CHOICE:
1777
0
  case XML_SCHEMA_TYPE_ALL:
1778
0
  case XML_SCHEMA_TYPE_PARTICLE:
1779
0
      *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1780
0
      break;
1781
0
  case XML_SCHEMA_TYPE_NOTATION: {
1782
0
    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1783
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1784
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1785
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1786
0
    FREE_AND_NULL(str);
1787
0
      }
1788
            /* Falls through. */
1789
0
  default:
1790
0
      named = 0;
1791
0
  }
1792
0
    } else
1793
0
  named = 0;
1794
1795
0
    if ((named == 0) && (itemNode != NULL)) {
1796
0
  xmlNodePtr elem;
1797
1798
0
  if (itemNode->type == XML_ATTRIBUTE_NODE)
1799
0
      elem = itemNode->parent;
1800
0
  else
1801
0
      elem = itemNode;
1802
0
  *buf = xmlStrdup(BAD_CAST "Element '");
1803
0
  if (elem->ns != NULL) {
1804
0
      *buf = xmlStrcat(*buf,
1805
0
    xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1806
0
      FREE_AND_NULL(str)
1807
0
  } else
1808
0
      *buf = xmlStrcat(*buf, elem->name);
1809
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1810
1811
0
    }
1812
0
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1813
0
  *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1814
0
  if (itemNode->ns != NULL) {
1815
0
      *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1816
0
    itemNode->ns->href, itemNode->name));
1817
0
      FREE_AND_NULL(str)
1818
0
  } else
1819
0
      *buf = xmlStrcat(*buf, itemNode->name);
1820
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1821
0
    }
1822
0
    FREE_AND_NULL(str)
1823
1824
0
    return (xmlEscapeFormatString(buf));
1825
0
}
1826
1827
/**
1828
 * xmlSchemaFormatFacetEnumSet:
1829
 * @buf: the string buffer
1830
 * @type: the type holding the enumeration facets
1831
 *
1832
 * Builds a string consisting of all enumeration elements.
1833
 *
1834
 * Returns a string of all enumeration elements.
1835
 */
1836
static const xmlChar *
1837
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1838
          xmlChar **buf, xmlSchemaTypePtr type)
1839
0
{
1840
0
    xmlSchemaFacetPtr facet;
1841
0
    xmlSchemaWhitespaceValueType ws;
1842
0
    xmlChar *value = NULL;
1843
0
    int res, found = 0;
1844
1845
0
    if (*buf != NULL)
1846
0
  xmlFree(*buf);
1847
0
    *buf = NULL;
1848
1849
0
    do {
1850
  /*
1851
  * Use the whitespace type of the base type.
1852
  */
1853
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1854
0
  for (facet = type->facets; facet != NULL; facet = facet->next) {
1855
0
      if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1856
0
    continue;
1857
0
      found = 1;
1858
0
      res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1859
0
    ws, &value);
1860
0
      if (res == -1) {
1861
0
    xmlSchemaInternalErr(actxt,
1862
0
        "xmlSchemaFormatFacetEnumSet",
1863
0
        "compute the canonical lexical representation");
1864
0
    if (*buf != NULL)
1865
0
        xmlFree(*buf);
1866
0
    *buf = NULL;
1867
0
    return (NULL);
1868
0
      }
1869
0
      if (*buf == NULL)
1870
0
    *buf = xmlStrdup(BAD_CAST "'");
1871
0
      else
1872
0
    *buf = xmlStrcat(*buf, BAD_CAST ", '");
1873
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
1874
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1875
0
      if (value != NULL) {
1876
0
    xmlFree((xmlChar *)value);
1877
0
    value = NULL;
1878
0
      }
1879
0
  }
1880
  /*
1881
  * The enumeration facet of a type restricts the enumeration
1882
  * facet of the ancestor type; i.e., such restricted enumerations
1883
  * do not belong to the set of the given type. Thus we break
1884
  * on the first found enumeration.
1885
  */
1886
0
  if (found)
1887
0
      break;
1888
0
  type = type->baseType;
1889
0
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1890
1891
0
    return ((const xmlChar *) *buf);
1892
0
}
1893
1894
/************************************************************************
1895
 *                  *
1896
 *      Error functions               *
1897
 *                  *
1898
 ************************************************************************/
1899
1900
/**
1901
 * xmlSchemaPErrMemory:
1902
 * @node: a context node
1903
 * @extra:  extra information
1904
 *
1905
 * Handle an out of memory condition
1906
 */
1907
static void
1908
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt)
1909
0
{
1910
0
    xmlGenericErrorFunc channel = NULL;
1911
0
    xmlStructuredErrorFunc schannel = NULL;
1912
0
    void *data = NULL;
1913
1914
0
    if (ctxt != NULL) {
1915
0
        ctxt->nberrors++;
1916
0
        ctxt->err = XML_ERR_NO_MEMORY;
1917
0
        channel = ctxt->error;
1918
0
        schannel = ctxt->serror;
1919
0
        data = ctxt->errCtxt;
1920
0
    }
1921
1922
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASP, NULL);
1923
0
}
1924
1925
static void LIBXML_ATTR_FORMAT(11,12)
1926
xmlSchemaPErrFull(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1927
                  xmlErrorLevel level, const char *file, int line,
1928
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
1929
0
                  int col, const char *msg, ...) {
1930
0
    xmlGenericErrorFunc channel = NULL;
1931
0
    xmlStructuredErrorFunc schannel = NULL;
1932
0
    void *data = NULL;
1933
0
    int res;
1934
0
    va_list ap;
1935
1936
0
    if (ctxt != NULL) {
1937
        /* Don't overwrite memory errors */
1938
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
1939
0
            return;
1940
1941
0
        if (level == XML_ERR_WARNING) {
1942
0
            channel = ctxt->warning;
1943
0
        } else {
1944
0
            ctxt->nberrors++;
1945
0
            ctxt->err = code;
1946
0
            channel = ctxt->error;
1947
0
        }
1948
0
        data = ctxt->errCtxt;
1949
0
        schannel = ctxt->serror;
1950
0
    }
1951
1952
0
    if ((channel == NULL) && (schannel == NULL)) {
1953
0
        channel = xmlGenericError;
1954
0
        data = xmlGenericErrorContext;
1955
0
    }
1956
1957
0
    va_start(ap, msg);
1958
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
1959
0
                         XML_FROM_SCHEMASP, code, level, file, line,
1960
0
                         (const char *) str1,
1961
0
                         (const char *) str2,
1962
0
                         (const char *) str3,
1963
0
                         0, col, msg, ap);
1964
0
    va_end(ap);
1965
1966
0
    if (res < 0)
1967
0
        xmlSchemaPErrMemory(ctxt);
1968
0
}
1969
1970
/**
1971
 * xmlSchemaPErr:
1972
 * @ctxt: the parsing context
1973
 * @node: the context node
1974
 * @error: the error code
1975
 * @msg: the error message
1976
 * @str1: extra data
1977
 * @str2: extra data
1978
 *
1979
 * Handle a parser error
1980
 */
1981
static void LIBXML_ATTR_FORMAT(4,0)
1982
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1983
              const char *msg, const xmlChar * str1, const xmlChar * str2)
1984
0
{
1985
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
1986
0
                      str1, str2, NULL, 0, msg, str1, str2);
1987
0
}
1988
1989
/**
1990
 * xmlSchemaPErr2:
1991
 * @ctxt: the parsing context
1992
 * @node: the context node
1993
 * @node: the current child
1994
 * @error: the error code
1995
 * @msg: the error message
1996
 * @str1: extra data
1997
 * @str2: extra data
1998
 *
1999
 * Handle a parser error
2000
 */
2001
static void LIBXML_ATTR_FORMAT(5,0)
2002
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
2003
               xmlNodePtr child, int error,
2004
               const char *msg, const xmlChar * str1, const xmlChar * str2)
2005
0
{
2006
0
    if (child != NULL)
2007
0
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
2008
0
    else
2009
0
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
2010
0
}
2011
2012
2013
/**
2014
 * xmlSchemaPErrExt:
2015
 * @ctxt: the parsing context
2016
 * @node: the context node
2017
 * @error: the error code
2018
 * @strData1: extra data
2019
 * @strData2: extra data
2020
 * @strData3: extra data
2021
 * @msg: the message
2022
 * @str1:  extra parameter for the message display
2023
 * @str2:  extra parameter for the message display
2024
 * @str3:  extra parameter for the message display
2025
 * @str4:  extra parameter for the message display
2026
 * @str5:  extra parameter for the message display
2027
 *
2028
 * Handle a parser error
2029
 */
2030
static void LIBXML_ATTR_FORMAT(7,0)
2031
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
2032
    const xmlChar * strData1, const xmlChar * strData2,
2033
    const xmlChar * strData3, const char *msg, const xmlChar * str1,
2034
    const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2035
    const xmlChar * str5)
2036
0
{
2037
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
2038
0
                      strData1, strData2, strData3, 0,
2039
0
                      msg, str1, str2, str3, str4, str5);
2040
0
}
2041
2042
/************************************************************************
2043
 *                  *
2044
 *      Allround error functions      *
2045
 *                  *
2046
 ************************************************************************/
2047
2048
/**
2049
 * xmlSchemaVTypeErrMemory:
2050
 * @node: a context node
2051
 * @extra:  extra information
2052
 *
2053
 * Handle an out of memory condition
2054
 */
2055
static void
2056
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt)
2057
0
{
2058
0
    xmlGenericErrorFunc channel = NULL;
2059
0
    xmlStructuredErrorFunc schannel = NULL;
2060
0
    void *data = NULL;
2061
2062
0
    if (ctxt != NULL) {
2063
0
        ctxt->nberrors++;
2064
0
        ctxt->err = XML_ERR_NO_MEMORY;
2065
0
        channel = ctxt->error;
2066
0
        schannel = ctxt->serror;
2067
0
        data = ctxt->errCtxt;
2068
0
    }
2069
2070
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASV, NULL);
2071
0
}
2072
2073
static void LIBXML_ATTR_FORMAT(11,12)
2074
xmlSchemaVErrFull(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int code,
2075
                  xmlErrorLevel level, const char *file, int line,
2076
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
2077
0
                  int col, const char *msg, ...) {
2078
0
    xmlGenericErrorFunc channel = NULL;
2079
0
    xmlStructuredErrorFunc schannel = NULL;
2080
0
    void *data = NULL;
2081
0
    int res;
2082
0
    va_list ap;
2083
2084
0
    if (ctxt != NULL) {
2085
        /* Don't overwrite memory errors */
2086
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
2087
0
            return;
2088
2089
0
        if (level == XML_ERR_WARNING) {
2090
0
            channel = ctxt->warning;
2091
0
        } else {
2092
0
            ctxt->nberrors++;
2093
0
            ctxt->err = code;
2094
0
            channel = ctxt->error;
2095
0
        }
2096
0
        data = ctxt->errCtxt;
2097
0
        schannel = ctxt->serror;
2098
0
    }
2099
2100
0
    if ((channel == NULL) && (schannel == NULL)) {
2101
0
        channel = xmlGenericError;
2102
0
        data = xmlGenericErrorContext;
2103
0
    }
2104
2105
0
    va_start(ap, msg);
2106
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
2107
0
                         XML_FROM_SCHEMASV, code, level, file, line,
2108
0
                         (const char *) str1,
2109
0
                         (const char *) str2,
2110
0
                         (const char *) str3,
2111
0
                         0, col, msg, ap);
2112
0
    va_end(ap);
2113
2114
0
    if (res < 0)
2115
0
        xmlSchemaVErrMemory(ctxt);
2116
0
}
2117
2118
#define WXS_ERROR_TYPE_ERROR 1
2119
#define WXS_ERROR_TYPE_WARNING 2
2120
/**
2121
 * xmlSchemaErr4Line:
2122
 * @ctxt: the validation context
2123
 * @errorLevel: the error level
2124
 * @error: the error code
2125
 * @node: the context node
2126
 * @line: the line number
2127
 * @msg: the error message
2128
 * @str1: extra data
2129
 * @str2: extra data
2130
 * @str3: extra data
2131
 * @str4: extra data
2132
 *
2133
 * Handle a validation error
2134
 */
2135
static void LIBXML_ATTR_FORMAT(6,0)
2136
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2137
      xmlErrorLevel errorLevel,
2138
      int code, xmlNodePtr node, int line, const char *msg,
2139
      const xmlChar *str1, const xmlChar *str2,
2140
      const xmlChar *str3, const xmlChar *str4)
2141
0
{
2142
0
    if (ctxt != NULL) {
2143
0
  if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2144
0
      xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2145
0
      const char *file = NULL;
2146
0
      int col = 0;
2147
2148
      /*
2149
      * Error node. If we specify a line number, then
2150
      * do not channel any node to the error function.
2151
      */
2152
0
      if (line == 0) {
2153
0
    if ((node == NULL) &&
2154
0
        (vctxt->depth >= 0) &&
2155
0
        (vctxt->inode != NULL)) {
2156
0
        node = vctxt->inode->node;
2157
0
    }
2158
    /*
2159
    * Get filename and line if no node-tree.
2160
    */
2161
0
    if ((node == NULL) &&
2162
0
        (vctxt->parserCtxt != NULL) &&
2163
0
        (vctxt->parserCtxt->input != NULL)) {
2164
0
        file = vctxt->parserCtxt->input->filename;
2165
0
                    if (vctxt->inode != NULL) {
2166
0
            line = vctxt->inode->nodeLine;
2167
0
                        col = 0;
2168
0
                    } else {
2169
                        /* This is inaccurate. */
2170
0
            line = vctxt->parserCtxt->input->line;
2171
0
            col = vctxt->parserCtxt->input->col;
2172
0
                    }
2173
0
    }
2174
0
      } else {
2175
    /*
2176
    * Override the given node's (if any) position
2177
    * and channel only the given line number.
2178
    */
2179
0
    node = NULL;
2180
    /*
2181
    * Get filename.
2182
    */
2183
0
    if (vctxt->doc != NULL)
2184
0
        file = (const char *) vctxt->doc->URL;
2185
0
    else if ((vctxt->parserCtxt != NULL) &&
2186
0
        (vctxt->parserCtxt->input != NULL))
2187
0
        file = vctxt->parserCtxt->input->filename;
2188
0
      }
2189
0
      if (vctxt->locFunc != NULL) {
2190
0
          if ((file == NULL) || (line == 0)) {
2191
0
        unsigned long l;
2192
0
        const char *f;
2193
0
        vctxt->locFunc(vctxt->locCtxt, &f, &l);
2194
0
        if (file == NULL)
2195
0
            file = f;
2196
0
        if (line == 0)
2197
0
            line = (int) l;
2198
0
    }
2199
0
      }
2200
0
      if ((file == NULL) && (vctxt->filename != NULL))
2201
0
          file = vctxt->filename;
2202
2203
0
            xmlSchemaVErrFull(vctxt, node, code, errorLevel,
2204
0
                              file, line, str1, str2, str3, col,
2205
0
                              msg, str1, str2, str3, str4);
2206
0
  } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2207
0
      xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2208
2209
0
            xmlSchemaPErrFull(pctxt, node, code, errorLevel,
2210
0
                              NULL, 0, str1, str2, str3, 0,
2211
0
                              msg, str1, str2, str3, str4);
2212
0
  }
2213
0
    }
2214
0
}
2215
2216
/**
2217
 * xmlSchemaErr3:
2218
 * @ctxt: the validation context
2219
 * @node: the context node
2220
 * @error: the error code
2221
 * @msg: the error message
2222
 * @str1: extra data
2223
 * @str2: extra data
2224
 * @str3: extra data
2225
 *
2226
 * Handle a validation error
2227
 */
2228
static void LIBXML_ATTR_FORMAT(4,0)
2229
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2230
        int error, xmlNodePtr node, const char *msg,
2231
        const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2232
0
{
2233
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2234
0
  msg, str1, str2, str3, NULL);
2235
0
}
2236
2237
static void LIBXML_ATTR_FORMAT(4,0)
2238
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2239
        int error, xmlNodePtr node, const char *msg,
2240
        const xmlChar *str1, const xmlChar *str2,
2241
        const xmlChar *str3, const xmlChar *str4)
2242
0
{
2243
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2244
0
  msg, str1, str2, str3, str4);
2245
0
}
2246
2247
static void LIBXML_ATTR_FORMAT(4,0)
2248
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2249
       int error, xmlNodePtr node, const char *msg,
2250
       const xmlChar *str1, const xmlChar *str2)
2251
0
{
2252
0
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2253
0
}
2254
2255
static xmlChar *
2256
xmlSchemaFormatNodeForError(xmlChar ** msg,
2257
          xmlSchemaAbstractCtxtPtr actxt,
2258
          xmlNodePtr node)
2259
0
{
2260
0
    xmlChar *str = NULL;
2261
2262
0
    *msg = NULL;
2263
0
    if ((node != NULL) &&
2264
0
  (node->type != XML_ELEMENT_NODE) &&
2265
0
  (node->type != XML_ATTRIBUTE_NODE))
2266
0
    {
2267
  /*
2268
  * Don't try to format other nodes than element and
2269
  * attribute nodes.
2270
  * Play safe and return an empty string.
2271
  */
2272
0
  *msg = xmlStrdup(BAD_CAST "");
2273
0
  return(*msg);
2274
0
    }
2275
0
    if (node != NULL) {
2276
  /*
2277
  * Work on tree nodes.
2278
  */
2279
0
  if (node->type == XML_ATTRIBUTE_NODE) {
2280
0
      xmlNodePtr elem = node->parent;
2281
2282
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2283
0
      if (elem->ns != NULL)
2284
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2285
0
        elem->ns->href, elem->name));
2286
0
      else
2287
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2288
0
        NULL, elem->name));
2289
0
      FREE_AND_NULL(str);
2290
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2291
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2292
0
  } else {
2293
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2294
0
  }
2295
0
  if (node->ns != NULL)
2296
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2297
0
      node->ns->href, node->name));
2298
0
  else
2299
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2300
0
      NULL, node->name));
2301
0
  FREE_AND_NULL(str);
2302
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2303
0
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2304
0
  xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2305
  /*
2306
  * Work on node infos.
2307
  */
2308
0
  if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2309
0
      xmlSchemaNodeInfoPtr ielem =
2310
0
    vctxt->elemInfos[vctxt->depth];
2311
2312
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2313
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2314
0
    ielem->nsName, ielem->localName));
2315
0
      FREE_AND_NULL(str);
2316
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2317
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2318
0
  } else {
2319
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2320
0
  }
2321
0
  *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2322
0
      vctxt->inode->nsName, vctxt->inode->localName));
2323
0
  FREE_AND_NULL(str);
2324
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2325
0
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2326
  /*
2327
  * Hmm, no node while parsing?
2328
  * Return an empty string, in case NULL will break something.
2329
  */
2330
0
  *msg = xmlStrdup(BAD_CAST "");
2331
0
    } else {
2332
  /* TODO */
2333
0
  return (NULL);
2334
0
    }
2335
2336
    /*
2337
     * xmlSchemaFormatItemForReport() also returns an escaped format
2338
     * string, so do this before calling it below (in the future).
2339
     */
2340
0
    xmlEscapeFormatString(msg);
2341
2342
    /*
2343
    * VAL TODO: The output of the given schema component is currently
2344
    * disabled.
2345
    */
2346
#if 0
2347
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2348
  *msg = xmlStrcat(*msg, BAD_CAST " [");
2349
  *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2350
      NULL, type, NULL, 0));
2351
  FREE_AND_NULL(str)
2352
  *msg = xmlStrcat(*msg, BAD_CAST "]");
2353
    }
2354
#endif
2355
0
    return (*msg);
2356
0
}
2357
2358
static void LIBXML_ATTR_FORMAT(3,0)
2359
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2360
         const char *funcName,
2361
         const char *message,
2362
         const xmlChar *str1,
2363
         const xmlChar *str2)
2364
0
{
2365
0
    xmlChar *msg = NULL;
2366
2367
0
    if (actxt == NULL)
2368
0
        return;
2369
0
    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2370
0
    msg = xmlStrcat(msg, BAD_CAST message);
2371
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2372
2373
0
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2374
0
  xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2375
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2376
0
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2377
0
  xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2378
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2379
2380
0
    FREE_AND_NULL(msg)
2381
0
}
2382
2383
static void LIBXML_ATTR_FORMAT(3,0)
2384
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2385
         const char *funcName,
2386
         const char *message)
2387
0
{
2388
0
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2389
0
}
2390
2391
#if 0
2392
static void LIBXML_ATTR_FORMAT(3,0)
2393
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2394
         const char *funcName,
2395
         const char *message,
2396
         const xmlChar *str1,
2397
         const xmlChar *str2)
2398
{
2399
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2400
  str1, str2);
2401
}
2402
#endif
2403
2404
static void LIBXML_ATTR_FORMAT(5,0)
2405
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2406
       xmlParserErrors error,
2407
       xmlNodePtr node,
2408
       xmlSchemaBasicItemPtr item,
2409
       const char *message,
2410
       const xmlChar *str1, const xmlChar *str2,
2411
       const xmlChar *str3, const xmlChar *str4)
2412
0
{
2413
0
    xmlChar *msg = NULL;
2414
2415
0
    if ((node == NULL) && (item != NULL) &&
2416
0
  (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2417
0
  node = WXS_ITEM_NODE(item);
2418
0
  xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2419
0
  msg = xmlStrcat(msg, BAD_CAST ": ");
2420
0
    } else
2421
0
  xmlSchemaFormatNodeForError(&msg, actxt, node);
2422
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2423
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2424
0
    xmlSchemaErr4(actxt, error, node,
2425
0
  (const char *) msg, str1, str2, str3, str4);
2426
0
    FREE_AND_NULL(msg)
2427
0
}
2428
2429
static void LIBXML_ATTR_FORMAT(5,0)
2430
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2431
       xmlParserErrors error,
2432
       xmlNodePtr node,
2433
       xmlSchemaBasicItemPtr item,
2434
       const char *message,
2435
       const xmlChar *str1,
2436
       const xmlChar *str2)
2437
0
{
2438
0
    xmlSchemaCustomErr4(actxt, error, node, item,
2439
0
  message, str1, str2, NULL, NULL);
2440
0
}
2441
2442
2443
2444
static void LIBXML_ATTR_FORMAT(5,0)
2445
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2446
       xmlParserErrors error,
2447
       xmlNodePtr node,
2448
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2449
       const char *message,
2450
       const xmlChar *str1,
2451
       const xmlChar *str2,
2452
       const xmlChar *str3)
2453
0
{
2454
0
    xmlChar *msg = NULL;
2455
2456
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2457
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2458
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2459
2460
    /* URGENT TODO: Set the error code to something sane. */
2461
0
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2462
0
  (const char *) msg, str1, str2, str3, NULL);
2463
2464
0
    FREE_AND_NULL(msg)
2465
0
}
2466
2467
2468
2469
static void LIBXML_ATTR_FORMAT(5,0)
2470
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2471
       xmlParserErrors error,
2472
       xmlSchemaPSVIIDCNodePtr idcNode,
2473
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2474
       const char *message,
2475
       const xmlChar *str1,
2476
       const xmlChar *str2)
2477
0
{
2478
0
    xmlChar *msg = NULL, *qname = NULL;
2479
2480
0
    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2481
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2482
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2483
0
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2484
0
  error, NULL, idcNode->nodeLine, (const char *) msg,
2485
0
  xmlSchemaFormatQName(&qname,
2486
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2487
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2488
0
  str1, str2, NULL);
2489
0
    FREE_AND_NULL(qname);
2490
0
    FREE_AND_NULL(msg);
2491
0
}
2492
2493
static int
2494
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2495
         xmlNodePtr node)
2496
0
{
2497
0
    if (node != NULL)
2498
0
  return (node->type);
2499
0
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2500
0
  (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2501
0
  return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2502
0
    return (-1);
2503
0
}
2504
2505
static int
2506
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2507
0
{
2508
0
    switch (item->type) {
2509
0
  case XML_SCHEMA_TYPE_COMPLEX:
2510
0
  case XML_SCHEMA_TYPE_SIMPLE:
2511
0
      if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2512
0
    return(1);
2513
0
      break;
2514
0
  case XML_SCHEMA_TYPE_GROUP:
2515
0
      return (1);
2516
0
  case XML_SCHEMA_TYPE_ELEMENT:
2517
0
      if ( ((xmlSchemaElementPtr) item)->flags &
2518
0
    XML_SCHEMAS_ELEM_GLOBAL)
2519
0
    return(1);
2520
0
      break;
2521
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
2522
0
      if ( ((xmlSchemaAttributePtr) item)->flags &
2523
0
    XML_SCHEMAS_ATTR_GLOBAL)
2524
0
    return(1);
2525
0
      break;
2526
  /* Note that attribute groups are always global. */
2527
0
  default:
2528
0
      return(1);
2529
0
    }
2530
0
    return (0);
2531
0
}
2532
2533
static void
2534
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2535
           xmlParserErrors error,
2536
           xmlNodePtr node,
2537
           const xmlChar *value,
2538
           xmlSchemaTypePtr type,
2539
           int displayValue)
2540
0
{
2541
0
    xmlChar *msg = NULL;
2542
2543
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2544
2545
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2546
0
      XML_ATTRIBUTE_NODE))
2547
0
  msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2548
0
    else
2549
0
  msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2550
0
      "value of ");
2551
2552
0
    if (! xmlSchemaIsGlobalItem(type))
2553
0
  msg = xmlStrcat(msg, BAD_CAST "the local ");
2554
0
    else
2555
0
  msg = xmlStrcat(msg, BAD_CAST "the ");
2556
2557
0
    if (WXS_IS_ATOMIC(type))
2558
0
  msg = xmlStrcat(msg, BAD_CAST "atomic type");
2559
0
    else if (WXS_IS_LIST(type))
2560
0
  msg = xmlStrcat(msg, BAD_CAST "list type");
2561
0
    else if (WXS_IS_UNION(type))
2562
0
  msg = xmlStrcat(msg, BAD_CAST "union type");
2563
2564
0
    if (xmlSchemaIsGlobalItem(type)) {
2565
0
  xmlChar *str = NULL;
2566
0
  msg = xmlStrcat(msg, BAD_CAST " '");
2567
0
  if (type->builtInType != 0) {
2568
0
      msg = xmlStrcat(msg, BAD_CAST "xs:");
2569
0
      str = xmlStrdup(type->name);
2570
0
  } else {
2571
0
      const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2572
0
      if (!str)
2573
0
    str = xmlStrdup(qName);
2574
0
  }
2575
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2576
0
  msg = xmlStrcat(msg, BAD_CAST "'");
2577
0
  FREE_AND_NULL(str);
2578
0
    }
2579
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2580
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2581
0
      XML_ATTRIBUTE_NODE))
2582
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2583
0
    else
2584
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2585
0
    FREE_AND_NULL(msg)
2586
0
}
2587
2588
static const xmlChar *
2589
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2590
            xmlSchemaNodeInfoPtr ni,
2591
            xmlNodePtr node)
2592
0
{
2593
0
    if (node != NULL) {
2594
0
  if (node->ns != NULL)
2595
0
      return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2596
0
  else
2597
0
      return (xmlSchemaFormatQName(str, NULL, node->name));
2598
0
    } else if (ni != NULL)
2599
0
  return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2600
0
    return (NULL);
2601
0
}
2602
2603
static void
2604
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2605
      xmlParserErrors error,
2606
      xmlSchemaAttrInfoPtr ni,
2607
      xmlNodePtr node)
2608
0
{
2609
0
    xmlChar *msg = NULL, *str = NULL;
2610
2611
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2612
0
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2613
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2614
0
  xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2615
0
  NULL);
2616
0
    FREE_AND_NULL(str)
2617
0
    FREE_AND_NULL(msg)
2618
0
}
2619
2620
static void LIBXML_ATTR_FORMAT(5,0)
2621
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2622
            xmlParserErrors error,
2623
            xmlNodePtr node,
2624
      xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2625
      const char *message,
2626
      int nbval,
2627
      int nbneg,
2628
      xmlChar **values)
2629
0
{
2630
0
    xmlChar *str = NULL, *msg = NULL;
2631
0
    xmlChar *localName, *nsName;
2632
0
    const xmlChar *cur, *end;
2633
0
    int i;
2634
2635
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2636
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2637
0
    msg = xmlStrcat(msg, BAD_CAST ".");
2638
    /*
2639
    * Note that is does not make sense to report that we have a
2640
    * wildcard here, since the wildcard might be unfolded into
2641
    * multiple transitions.
2642
    */
2643
0
    if (nbval + nbneg > 0) {
2644
0
  if (nbval + nbneg > 1) {
2645
0
      str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2646
0
  } else
2647
0
      str = xmlStrdup(BAD_CAST " Expected is ( ");
2648
0
  nsName = NULL;
2649
2650
0
  for (i = 0; i < nbval + nbneg; i++) {
2651
0
      cur = values[i];
2652
0
      if (cur == NULL)
2653
0
          continue;
2654
0
      if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2655
0
          (cur[3] == ' ')) {
2656
0
    cur += 4;
2657
0
    str = xmlStrcat(str, BAD_CAST "##other");
2658
0
      }
2659
      /*
2660
      * Get the local name.
2661
      */
2662
0
      localName = NULL;
2663
2664
0
      end = cur;
2665
0
      if (*end == '*') {
2666
0
    localName = xmlStrdup(BAD_CAST "*");
2667
0
    end++;
2668
0
      } else {
2669
0
    while ((*end != 0) && (*end != '|'))
2670
0
        end++;
2671
0
    localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2672
0
      }
2673
0
      if (*end != 0) {
2674
0
    end++;
2675
    /*
2676
    * Skip "*|*" if they come with negated expressions, since
2677
    * they represent the same negated wildcard.
2678
    */
2679
0
    if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2680
        /*
2681
        * Get the namespace name.
2682
        */
2683
0
        cur = end;
2684
0
        if (*end == '*') {
2685
0
      nsName = xmlStrdup(BAD_CAST "{*}");
2686
0
        } else {
2687
0
      while (*end != 0)
2688
0
          end++;
2689
2690
0
      if (i >= nbval)
2691
0
          nsName = xmlStrdup(BAD_CAST "{##other:");
2692
0
      else
2693
0
          nsName = xmlStrdup(BAD_CAST "{");
2694
2695
0
      nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2696
0
      nsName = xmlStrcat(nsName, BAD_CAST "}");
2697
0
        }
2698
0
        str = xmlStrcat(str, BAD_CAST nsName);
2699
0
        FREE_AND_NULL(nsName)
2700
0
    } else {
2701
0
        FREE_AND_NULL(localName);
2702
0
        continue;
2703
0
    }
2704
0
      }
2705
0
      str = xmlStrcat(str, BAD_CAST localName);
2706
0
      FREE_AND_NULL(localName);
2707
2708
0
      if (i < nbval + nbneg -1)
2709
0
    str = xmlStrcat(str, BAD_CAST ", ");
2710
0
  }
2711
0
  str = xmlStrcat(str, BAD_CAST " ).\n");
2712
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2713
0
  FREE_AND_NULL(str)
2714
0
    } else
2715
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
2716
0
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2717
0
    xmlFree(msg);
2718
0
}
2719
2720
static void LIBXML_ATTR_FORMAT(8,0)
2721
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2722
      xmlParserErrors error,
2723
      xmlNodePtr node,
2724
      const xmlChar *value,
2725
      unsigned long length,
2726
      xmlSchemaTypePtr type,
2727
      xmlSchemaFacetPtr facet,
2728
      const char *message,
2729
      const xmlChar *str1,
2730
      const xmlChar *str2)
2731
0
{
2732
0
    xmlChar *str = NULL, *msg = NULL;
2733
0
    xmlSchemaTypeType facetType;
2734
0
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2735
2736
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2737
0
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2738
0
  facetType = XML_SCHEMA_FACET_ENUMERATION;
2739
  /*
2740
  * If enumerations are validated, one must not expect the
2741
  * facet to be given.
2742
  */
2743
0
    } else
2744
0
  facetType = facet->type;
2745
0
    msg = xmlStrcat(msg, BAD_CAST "[");
2746
0
    msg = xmlStrcat(msg, BAD_CAST "facet '");
2747
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2748
0
    msg = xmlStrcat(msg, BAD_CAST "'] ");
2749
0
    if (message == NULL) {
2750
  /*
2751
  * Use a default message.
2752
  */
2753
0
  if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2754
0
      (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2755
0
      (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2756
2757
0
      char len[25], actLen[25];
2758
2759
      /* FIXME, TODO: What is the max expected string length of the
2760
      * this value?
2761
      */
2762
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2763
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2764
0
      else
2765
0
    msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2766
2767
0
      snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2768
0
      snprintf(actLen, 24, "%lu", length);
2769
2770
0
      if (facetType == XML_SCHEMA_FACET_LENGTH)
2771
0
    msg = xmlStrcat(msg,
2772
0
    BAD_CAST "this differs from the allowed length of '%s'.\n");
2773
0
      else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2774
0
    msg = xmlStrcat(msg,
2775
0
    BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2776
0
      else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2777
0
    msg = xmlStrcat(msg,
2778
0
    BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2779
2780
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2781
0
    xmlSchemaErr3(actxt, error, node, (const char *) msg,
2782
0
        value, (const xmlChar *) actLen, (const xmlChar *) len);
2783
0
      else
2784
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2785
0
        (const xmlChar *) actLen, (const xmlChar *) len);
2786
2787
0
  } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2788
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2789
0
    "of the set {%s}.\n");
2790
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2791
0
    xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2792
0
  } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2793
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2794
0
    "by the pattern '%s'.\n");
2795
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2796
0
    facet->value);
2797
0
  } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2798
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2799
0
    "minimum value allowed ('%s').\n");
2800
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2801
0
    facet->value);
2802
0
  } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2803
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2804
0
    "maximum value allowed ('%s').\n");
2805
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2806
0
    facet->value);
2807
0
  } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2808
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2809
0
    "'%s'.\n");
2810
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2811
0
    facet->value);
2812
0
  } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2813
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2814
0
    "'%s'.\n");
2815
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2816
0
    facet->value);
2817
0
  } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2818
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2819
0
    "digits than are allowed ('%s').\n");
2820
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2821
0
    facet->value);
2822
0
  } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2823
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2824
0
    "digits than are allowed ('%s').\n");
2825
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2826
0
    facet->value);
2827
0
  } else if (nodeType == XML_ATTRIBUTE_NODE) {
2828
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2829
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2830
0
  } else {
2831
0
      msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2832
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2833
0
  }
2834
0
    } else {
2835
0
  msg = xmlStrcat(msg, (const xmlChar *) message);
2836
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
2837
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2838
0
    }
2839
0
    FREE_AND_NULL(str)
2840
0
    xmlFree(msg);
2841
0
}
2842
2843
#define VERROR(err, type, msg) \
2844
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2845
2846
0
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2847
2848
0
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2849
0
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2850
2851
0
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2852
2853
2854
/**
2855
 * xmlSchemaPMissingAttrErr:
2856
 * @ctxt: the schema validation context
2857
 * @ownerItem: the owner as a schema object
2858
 * @ownerElem: the owner as an element node
2859
 * @node: the parent element node of the missing attribute node
2860
 * @type: the corresponding type of the attribute node
2861
 *
2862
 * Reports an illegal attribute.
2863
 */
2864
static void
2865
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2866
       xmlParserErrors error,
2867
       xmlSchemaBasicItemPtr ownerItem,
2868
       xmlNodePtr ownerElem,
2869
       const char *name,
2870
       const char *message)
2871
0
{
2872
0
    xmlChar *des = NULL;
2873
2874
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2875
2876
0
    if (message != NULL)
2877
0
  xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2878
0
    else
2879
0
  xmlSchemaPErr(ctxt, ownerElem, error,
2880
0
      "%s: The attribute '%s' is required but missing.\n",
2881
0
      BAD_CAST des, BAD_CAST name);
2882
0
    FREE_AND_NULL(des);
2883
0
}
2884
2885
2886
/**
2887
 * xmlSchemaPResCompAttrErr:
2888
 * @ctxt: the schema validation context
2889
 * @error: the error code
2890
 * @ownerItem: the owner as a schema object
2891
 * @ownerElem: the owner as an element node
2892
 * @name: the name of the attribute holding the QName
2893
 * @refName: the referenced local name
2894
 * @refURI: the referenced namespace URI
2895
 * @message: optional message
2896
 *
2897
 * Used to report QName attribute values that failed to resolve
2898
 * to schema components.
2899
 */
2900
static void
2901
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2902
       xmlParserErrors error,
2903
       xmlSchemaBasicItemPtr ownerItem,
2904
       xmlNodePtr ownerElem,
2905
       const char *name,
2906
       const xmlChar *refName,
2907
       const xmlChar *refURI,
2908
       xmlSchemaTypeType refType,
2909
       const char *refTypeStr)
2910
0
{
2911
0
    xmlChar *des = NULL, *strA = NULL;
2912
2913
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2914
0
    if (refTypeStr == NULL)
2915
0
  refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2916
0
    xmlSchemaPErrExt(ctxt, ownerElem, error,
2917
0
      NULL, NULL, NULL,
2918
0
      "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2919
0
      "%s.\n", BAD_CAST des, BAD_CAST name,
2920
0
      xmlSchemaFormatQName(&strA, refURI, refName),
2921
0
      BAD_CAST refTypeStr, NULL);
2922
0
    FREE_AND_NULL(des)
2923
0
    FREE_AND_NULL(strA)
2924
0
}
2925
2926
/**
2927
 * xmlSchemaPCustomAttrErr:
2928
 * @ctxt: the schema parser context
2929
 * @error: the error code
2930
 * @ownerDes: the designation of the owner
2931
 * @ownerItem: the owner as a schema object
2932
 * @attr: the illegal attribute node
2933
 *
2934
 * Reports an illegal attribute during the parse.
2935
 */
2936
static void
2937
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2938
      xmlParserErrors error,
2939
      xmlChar **ownerDes,
2940
      xmlSchemaBasicItemPtr ownerItem,
2941
      xmlAttrPtr attr,
2942
      const char *msg)
2943
0
{
2944
0
    xmlChar *des = NULL;
2945
2946
0
    if (ownerDes == NULL)
2947
0
  xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2948
0
    else if (*ownerDes == NULL) {
2949
0
  xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2950
0
  des = *ownerDes;
2951
0
    } else
2952
0
  des = *ownerDes;
2953
0
    if (attr == NULL) {
2954
0
  xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2955
0
      "%s, attribute '%s': %s.\n",
2956
0
      BAD_CAST des, (const xmlChar *) "Unknown",
2957
0
      (const xmlChar *) msg, NULL, NULL);
2958
0
    } else {
2959
0
  xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2960
0
      "%s, attribute '%s': %s.\n",
2961
0
      BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2962
0
    }
2963
0
    if (ownerDes == NULL)
2964
0
  FREE_AND_NULL(des);
2965
0
}
2966
2967
/**
2968
 * xmlSchemaPIllegalAttrErr:
2969
 * @ctxt: the schema parser context
2970
 * @error: the error code
2971
 * @ownerItem: the attribute's owner item
2972
 * @attr: the illegal attribute node
2973
 *
2974
 * Reports an illegal attribute during the parse.
2975
 */
2976
static void
2977
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2978
       xmlParserErrors error,
2979
       xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2980
       xmlAttrPtr attr)
2981
0
{
2982
0
    xmlChar *strA = NULL, *strB = NULL;
2983
2984
0
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2985
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2986
0
  "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2987
0
  xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2988
0
  NULL, NULL);
2989
0
    FREE_AND_NULL(strA);
2990
0
    FREE_AND_NULL(strB);
2991
0
}
2992
2993
/**
2994
 * xmlSchemaPCustomErr:
2995
 * @ctxt: the schema parser context
2996
 * @error: the error code
2997
 * @itemDes: the designation of the schema item
2998
 * @item: the schema item
2999
 * @itemElem: the node of the schema item
3000
 * @message: the error message
3001
 * @str1: an optional param for the error message
3002
 * @str2: an optional param for the error message
3003
 * @str3: an optional param for the error message
3004
 *
3005
 * Reports an error during parsing.
3006
 */
3007
static void LIBXML_ATTR_FORMAT(5,0)
3008
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
3009
        xmlParserErrors error,
3010
        xmlSchemaBasicItemPtr item,
3011
        xmlNodePtr itemElem,
3012
        const char *message,
3013
        const xmlChar *str1,
3014
        const xmlChar *str2,
3015
        const xmlChar *str3)
3016
0
{
3017
0
    xmlChar *des = NULL, *msg = NULL;
3018
3019
0
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
3020
0
    msg = xmlStrdup(BAD_CAST "%s: ");
3021
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3022
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3023
0
    if ((itemElem == NULL) && (item != NULL))
3024
0
  itemElem = WXS_ITEM_NODE(item);
3025
0
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3026
0
  (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3027
0
    FREE_AND_NULL(des);
3028
0
    FREE_AND_NULL(msg);
3029
0
}
3030
3031
/**
3032
 * xmlSchemaPCustomErr:
3033
 * @ctxt: the schema parser context
3034
 * @error: the error code
3035
 * @itemDes: the designation of the schema item
3036
 * @item: the schema item
3037
 * @itemElem: the node of the schema item
3038
 * @message: the error message
3039
 * @str1: the optional param for the error message
3040
 *
3041
 * Reports an error during parsing.
3042
 */
3043
static void LIBXML_ATTR_FORMAT(5,0)
3044
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3045
        xmlParserErrors error,
3046
        xmlSchemaBasicItemPtr item,
3047
        xmlNodePtr itemElem,
3048
        const char *message,
3049
        const xmlChar *str1)
3050
0
{
3051
0
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3052
0
  str1, NULL, NULL);
3053
0
}
3054
3055
/**
3056
 * xmlSchemaPAttrUseErr:
3057
 * @ctxt: the schema parser context
3058
 * @error: the error code
3059
 * @itemDes: the designation of the schema type
3060
 * @item: the schema type
3061
 * @itemElem: the node of the schema type
3062
 * @attr: the invalid schema attribute
3063
 * @message: the error message
3064
 * @str1: the optional param for the error message
3065
 *
3066
 * Reports an attribute use error during parsing.
3067
 */
3068
static void LIBXML_ATTR_FORMAT(6,0)
3069
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3070
        xmlParserErrors error,
3071
        xmlNodePtr node,
3072
        xmlSchemaBasicItemPtr ownerItem,
3073
        const xmlSchemaAttributeUsePtr attruse,
3074
        const char *message,
3075
        const xmlChar *str1, const xmlChar *str2,
3076
        const xmlChar *str3,const xmlChar *str4)
3077
0
{
3078
0
    xmlChar *str = NULL, *msg = NULL;
3079
3080
0
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3081
0
    msg = xmlStrcat(msg, BAD_CAST ", ");
3082
0
    msg = xmlStrcat(msg,
3083
0
  BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3084
0
  WXS_BASIC_CAST attruse, NULL));
3085
0
    FREE_AND_NULL(str);
3086
0
    msg = xmlStrcat(msg, BAD_CAST ": ");
3087
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3088
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3089
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3090
0
  (const char *) msg, str1, str2, str3, str4);
3091
0
    xmlFree(msg);
3092
0
}
3093
3094
/**
3095
 * xmlSchemaPIllegalFacetAtomicErr:
3096
 * @ctxt: the schema parser context
3097
 * @error: the error code
3098
 * @type: the schema type
3099
 * @baseType: the base type of type
3100
 * @facet: the illegal facet
3101
 *
3102
 * Reports an illegal facet for atomic simple types.
3103
 */
3104
static void
3105
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3106
        xmlParserErrors error,
3107
        xmlSchemaTypePtr type,
3108
        xmlSchemaTypePtr baseType,
3109
        xmlSchemaFacetPtr facet)
3110
0
{
3111
0
    xmlChar *des = NULL, *strT = NULL;
3112
3113
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3114
0
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3115
0
  "%s: The facet '%s' is not allowed on types derived from the "
3116
0
  "type %s.\n",
3117
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3118
0
  xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3119
0
  NULL, NULL);
3120
0
    FREE_AND_NULL(des);
3121
0
    FREE_AND_NULL(strT);
3122
0
}
3123
3124
/**
3125
 * xmlSchemaPIllegalFacetListUnionErr:
3126
 * @ctxt: the schema parser context
3127
 * @error: the error code
3128
 * @itemDes: the designation of the schema item involved
3129
 * @item: the schema item involved
3130
 * @facet: the illegal facet
3131
 *
3132
 * Reports an illegal facet for <list> and <union>.
3133
 */
3134
static void
3135
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3136
        xmlParserErrors error,
3137
        xmlSchemaTypePtr type,
3138
        xmlSchemaFacetPtr facet)
3139
0
{
3140
0
    xmlChar *des = NULL;
3141
3142
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3143
0
  type->node);
3144
0
    xmlSchemaPErr(ctxt, type->node, error,
3145
0
  "%s: The facet '%s' is not allowed.\n",
3146
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3147
0
    FREE_AND_NULL(des);
3148
0
}
3149
3150
/**
3151
 * xmlSchemaPMutualExclAttrErr:
3152
 * @ctxt: the schema validation context
3153
 * @error: the error code
3154
 * @elemDes: the designation of the parent element node
3155
 * @attr: the bad attribute node
3156
 * @type: the corresponding type of the attribute node
3157
 *
3158
 * Reports an illegal attribute.
3159
 */
3160
static void
3161
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3162
       xmlParserErrors error,
3163
       xmlSchemaBasicItemPtr ownerItem,
3164
       xmlAttrPtr attr,
3165
       const char *name1,
3166
       const char *name2)
3167
0
{
3168
0
    xmlChar *des = NULL;
3169
3170
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3171
0
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3172
0
  "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3173
0
  BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3174
0
    FREE_AND_NULL(des);
3175
0
}
3176
3177
/**
3178
 * xmlSchemaPSimpleTypeErr:
3179
 * @ctxt:  the schema validation context
3180
 * @error: the error code
3181
 * @type: the type specifier
3182
 * @ownerItem: the schema object if existent
3183
 * @node: the validated node
3184
 * @value: the validated value
3185
 *
3186
 * Reports a simple type validation error.
3187
 * TODO: Should this report the value of an element as well?
3188
 */
3189
static void LIBXML_ATTR_FORMAT(8,0)
3190
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3191
      xmlParserErrors error,
3192
      xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3193
      xmlNodePtr node,
3194
      xmlSchemaTypePtr type,
3195
      const char *expected,
3196
      const xmlChar *value,
3197
      const char *message,
3198
      const xmlChar *str1,
3199
      const xmlChar *str2)
3200
0
{
3201
0
    xmlChar *msg = NULL;
3202
3203
0
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3204
0
    if (message == NULL) {
3205
  /*
3206
  * Use default messages.
3207
  */
3208
0
  if (type != NULL) {
3209
0
      if (node->type == XML_ATTRIBUTE_NODE)
3210
0
    msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3211
0
      else
3212
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3213
0
    "valid value of ");
3214
0
      if (! xmlSchemaIsGlobalItem(type))
3215
0
    msg = xmlStrcat(msg, BAD_CAST "the local ");
3216
0
      else
3217
0
    msg = xmlStrcat(msg, BAD_CAST "the ");
3218
3219
0
      if (WXS_IS_ATOMIC(type))
3220
0
    msg = xmlStrcat(msg, BAD_CAST "atomic type");
3221
0
      else if (WXS_IS_LIST(type))
3222
0
    msg = xmlStrcat(msg, BAD_CAST "list type");
3223
0
      else if (WXS_IS_UNION(type))
3224
0
    msg = xmlStrcat(msg, BAD_CAST "union type");
3225
3226
0
      if (xmlSchemaIsGlobalItem(type)) {
3227
0
    xmlChar *str = NULL;
3228
0
    msg = xmlStrcat(msg, BAD_CAST " '");
3229
0
    if (type->builtInType != 0) {
3230
0
        msg = xmlStrcat(msg, BAD_CAST "xs:");
3231
0
        str = xmlStrdup(type->name);
3232
0
    } else {
3233
0
        const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3234
0
        if (!str)
3235
0
      str = xmlStrdup(qName);
3236
0
    }
3237
0
    msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3238
0
    msg = xmlStrcat(msg, BAD_CAST "'.");
3239
0
    FREE_AND_NULL(str);
3240
0
      }
3241
0
  } else {
3242
0
      if (node->type == XML_ATTRIBUTE_NODE)
3243
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3244
0
      else
3245
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3246
0
    "valid.");
3247
0
  }
3248
0
  if (expected) {
3249
0
      xmlChar *expectedEscaped = xmlCharStrdup(expected);
3250
0
      msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3251
0
      msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3252
0
      FREE_AND_NULL(expectedEscaped);
3253
0
      msg = xmlStrcat(msg, BAD_CAST "'.\n");
3254
0
  } else
3255
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
3256
0
  if (node->type == XML_ATTRIBUTE_NODE)
3257
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3258
0
  else
3259
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3260
0
    } else {
3261
0
  msg = xmlStrcat(msg, BAD_CAST message);
3262
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
3263
0
  xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3264
0
       (const char*) msg, str1, str2, NULL, NULL, NULL);
3265
0
    }
3266
    /* Cleanup. */
3267
0
    FREE_AND_NULL(msg)
3268
0
}
3269
3270
/**
3271
 * xmlSchemaPContentErr:
3272
 * @ctxt: the schema parser context
3273
 * @error: the error code
3274
 * @ownerItem: the owner item of the holder of the content
3275
 * @ownerElem: the node of the holder of the content
3276
 * @child: the invalid child node
3277
 * @message: the optional error message
3278
 * @content: the optional string describing the correct content
3279
 *
3280
 * Reports an error concerning the content of a schema element.
3281
 */
3282
static void
3283
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3284
         xmlParserErrors error,
3285
         xmlSchemaBasicItemPtr ownerItem,
3286
         xmlNodePtr ownerElem,
3287
         xmlNodePtr child,
3288
         const char *message,
3289
         const char *content)
3290
0
{
3291
0
    xmlChar *des = NULL;
3292
3293
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3294
0
    if (message != NULL)
3295
0
  xmlSchemaPErr2(ctxt, ownerElem, child, error,
3296
0
      "%s: %s.\n",
3297
0
      BAD_CAST des, BAD_CAST message);
3298
0
    else {
3299
0
  if (content != NULL) {
3300
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3301
0
    "%s: The content is not valid. Expected is %s.\n",
3302
0
    BAD_CAST des, BAD_CAST content);
3303
0
  } else {
3304
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3305
0
    "%s: The content is not valid.\n",
3306
0
    BAD_CAST des, NULL);
3307
0
  }
3308
0
    }
3309
0
    FREE_AND_NULL(des)
3310
0
}
3311
3312
/************************************************************************
3313
 *                  *
3314
 *      Streamable error functions                      *
3315
 *                  *
3316
 ************************************************************************/
3317
3318
3319
3320
3321
/************************************************************************
3322
 *                  *
3323
 *      Validation helper functions     *
3324
 *                  *
3325
 ************************************************************************/
3326
3327
3328
/************************************************************************
3329
 *                  *
3330
 *      Allocation functions        *
3331
 *                  *
3332
 ************************************************************************/
3333
3334
/**
3335
 * xmlSchemaNewSchemaForParserCtxt:
3336
 * @ctxt:  a schema validation context
3337
 *
3338
 * Allocate a new Schema structure.
3339
 *
3340
 * Returns the newly allocated structure or NULL in case or error
3341
 */
3342
static xmlSchemaPtr
3343
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3344
0
{
3345
0
    xmlSchemaPtr ret;
3346
3347
0
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3348
0
    if (ret == NULL) {
3349
0
        xmlSchemaPErrMemory(ctxt);
3350
0
        return (NULL);
3351
0
    }
3352
0
    memset(ret, 0, sizeof(xmlSchema));
3353
0
    ret->dict = ctxt->dict;
3354
0
    xmlDictReference(ret->dict);
3355
3356
0
    return (ret);
3357
0
}
3358
3359
/**
3360
 * xmlSchemaNewFacet:
3361
 *
3362
 * Allocate a new Facet structure.
3363
 *
3364
 * Returns the newly allocated structure or NULL in case or error
3365
 */
3366
xmlSchemaFacetPtr
3367
xmlSchemaNewFacet(void)
3368
0
{
3369
0
    xmlSchemaFacetPtr ret;
3370
3371
0
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3372
0
    if (ret == NULL) {
3373
0
        return (NULL);
3374
0
    }
3375
0
    memset(ret, 0, sizeof(xmlSchemaFacet));
3376
3377
0
    return (ret);
3378
0
}
3379
3380
/**
3381
 * xmlSchemaNewAnnot:
3382
 * @ctxt:  a schema validation context
3383
 * @node:  a node
3384
 *
3385
 * Allocate a new annotation structure.
3386
 *
3387
 * Returns the newly allocated structure or NULL in case or error
3388
 */
3389
static xmlSchemaAnnotPtr
3390
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3391
0
{
3392
0
    xmlSchemaAnnotPtr ret;
3393
3394
0
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3395
0
    if (ret == NULL) {
3396
0
        xmlSchemaPErrMemory(ctxt);
3397
0
        return (NULL);
3398
0
    }
3399
0
    memset(ret, 0, sizeof(xmlSchemaAnnot));
3400
0
    ret->content = node;
3401
0
    return (ret);
3402
0
}
3403
3404
static xmlSchemaItemListPtr
3405
xmlSchemaItemListCreate(void)
3406
0
{
3407
0
    xmlSchemaItemListPtr ret;
3408
3409
0
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3410
0
    if (ret == NULL) {
3411
0
  xmlSchemaPErrMemory(NULL);
3412
0
  return (NULL);
3413
0
    }
3414
0
    memset(ret, 0, sizeof(xmlSchemaItemList));
3415
0
    return (ret);
3416
0
}
3417
3418
static void
3419
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3420
0
{
3421
0
    if (list->items != NULL) {
3422
0
  xmlFree(list->items);
3423
0
  list->items = NULL;
3424
0
    }
3425
0
    list->nbItems = 0;
3426
0
    list->sizeItems = 0;
3427
0
}
3428
3429
static int
3430
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3431
0
{
3432
0
    if (list->sizeItems <= list->nbItems) {
3433
0
        void **tmp;
3434
0
        size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3435
3436
0
  tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3437
0
  if (tmp == NULL) {
3438
0
      xmlSchemaPErrMemory(NULL);
3439
0
      return(-1);
3440
0
  }
3441
0
        list->items = tmp;
3442
0
  list->sizeItems = newSize;
3443
0
    }
3444
0
    list->items[list->nbItems++] = item;
3445
0
    return(0);
3446
0
}
3447
3448
static int
3449
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3450
       int initialSize,
3451
       void *item)
3452
0
{
3453
0
    if (list->items == NULL) {
3454
0
  if (initialSize <= 0)
3455
0
      initialSize = 1;
3456
0
  list->items = (void **) xmlMalloc(
3457
0
      initialSize * sizeof(void *));
3458
0
  if (list->items == NULL) {
3459
0
      xmlSchemaPErrMemory(NULL);
3460
0
      return(-1);
3461
0
  }
3462
0
  list->sizeItems = initialSize;
3463
0
    } else if (list->sizeItems <= list->nbItems) {
3464
0
        void **tmp;
3465
3466
0
  list->sizeItems *= 2;
3467
0
  tmp = (void **) xmlRealloc(list->items,
3468
0
      list->sizeItems * sizeof(void *));
3469
0
  if (tmp == NULL) {
3470
0
      xmlSchemaPErrMemory(NULL);
3471
0
      list->sizeItems /= 2;
3472
0
      return(-1);
3473
0
  }
3474
0
        list->items = tmp;
3475
0
    }
3476
0
    list->items[list->nbItems++] = item;
3477
0
    return(0);
3478
0
}
3479
3480
static int
3481
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3482
0
{
3483
0
    if (list->sizeItems <= list->nbItems) {
3484
0
        void **tmp;
3485
0
        size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3486
3487
0
  tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3488
0
  if (tmp == NULL) {
3489
0
      xmlSchemaPErrMemory(NULL);
3490
0
      return(-1);
3491
0
  }
3492
0
        list->items = tmp;
3493
0
  list->sizeItems = newSize;
3494
0
    }
3495
    /*
3496
    * Just append if the index is greater/equal than the item count.
3497
    */
3498
0
    if (idx >= list->nbItems) {
3499
0
  list->items[list->nbItems++] = item;
3500
0
    } else {
3501
0
  int i;
3502
0
  for (i = list->nbItems; i > idx; i--)
3503
0
      list->items[i] = list->items[i-1];
3504
0
  list->items[idx] = item;
3505
0
  list->nbItems++;
3506
0
    }
3507
0
    return(0);
3508
0
}
3509
3510
#if 0 /* enable if ever needed */
3511
static int
3512
xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3513
          int initialSize,
3514
          void *item,
3515
          int idx)
3516
{
3517
    if (list->items == NULL) {
3518
  if (initialSize <= 0)
3519
      initialSize = 1;
3520
  list->items = (void **) xmlMalloc(
3521
      initialSize * sizeof(void *));
3522
  if (list->items == NULL) {
3523
      xmlSchemaPErrMemory(NULL);
3524
      return(-1);
3525
  }
3526
  list->sizeItems = initialSize;
3527
    } else if (list->sizeItems <= list->nbItems) {
3528
  list->sizeItems *= 2;
3529
  list->items = (void **) xmlRealloc(list->items,
3530
      list->sizeItems * sizeof(void *));
3531
  if (list->items == NULL) {
3532
      xmlSchemaPErrMemory(NULL);
3533
      list->sizeItems = 0;
3534
      return(-1);
3535
  }
3536
    }
3537
    /*
3538
    * Just append if the index is greater/equal than the item count.
3539
    */
3540
    if (idx >= list->nbItems) {
3541
  list->items[list->nbItems++] = item;
3542
    } else {
3543
  int i;
3544
  for (i = list->nbItems; i > idx; i--)
3545
      list->items[i] = list->items[i-1];
3546
  list->items[idx] = item;
3547
  list->nbItems++;
3548
    }
3549
    return(0);
3550
}
3551
#endif
3552
3553
static int
3554
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3555
0
{
3556
0
    int i;
3557
0
    if ((list->items == NULL) || (idx >= list->nbItems))
3558
0
  return(-1);
3559
3560
0
    if (list->nbItems == 1) {
3561
  /* TODO: Really free the list? */
3562
0
  xmlFree(list->items);
3563
0
  list->items = NULL;
3564
0
  list->nbItems = 0;
3565
0
  list->sizeItems = 0;
3566
0
    } else if (list->nbItems -1 == idx) {
3567
0
  list->nbItems--;
3568
0
    } else {
3569
0
  for (i = idx; i < list->nbItems -1; i++)
3570
0
      list->items[i] = list->items[i+1];
3571
0
  list->nbItems--;
3572
0
    }
3573
0
    return(0);
3574
0
}
3575
3576
/**
3577
 * xmlSchemaItemListFree:
3578
 * @annot:  a schema type structure
3579
 *
3580
 * Deallocate a annotation structure
3581
 */
3582
static void
3583
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3584
0
{
3585
0
    if (list == NULL)
3586
0
  return;
3587
0
    if (list->items != NULL)
3588
0
  xmlFree(list->items);
3589
0
    xmlFree(list);
3590
0
}
3591
3592
static void
3593
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3594
0
{
3595
0
    if (bucket == NULL)
3596
0
  return;
3597
0
    if (bucket->globals != NULL) {
3598
0
  xmlSchemaComponentListFree(bucket->globals);
3599
0
  xmlSchemaItemListFree(bucket->globals);
3600
0
    }
3601
0
    if (bucket->locals != NULL) {
3602
0
  xmlSchemaComponentListFree(bucket->locals);
3603
0
  xmlSchemaItemListFree(bucket->locals);
3604
0
    }
3605
0
    if (bucket->relations != NULL) {
3606
0
  xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3607
0
  do {
3608
0
      prev = cur;
3609
0
      cur = cur->next;
3610
0
      xmlFree(prev);
3611
0
  } while (cur != NULL);
3612
0
    }
3613
0
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3614
0
  xmlFreeDoc(bucket->doc);
3615
0
    }
3616
0
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3617
0
  if (WXS_IMPBUCKET(bucket)->schema != NULL)
3618
0
      xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3619
0
    }
3620
0
    xmlFree(bucket);
3621
0
}
3622
3623
static void
3624
xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3625
0
{
3626
0
    xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3627
0
}
3628
3629
static xmlSchemaBucketPtr
3630
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3631
       int type, const xmlChar *targetNamespace)
3632
0
{
3633
0
    xmlSchemaBucketPtr ret;
3634
0
    int size;
3635
0
    xmlSchemaPtr mainSchema;
3636
3637
0
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3638
0
  PERROR_INT("xmlSchemaBucketCreate",
3639
0
      "no main schema on constructor");
3640
0
  return(NULL);
3641
0
    }
3642
0
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3643
    /* Create the schema bucket. */
3644
0
    if (WXS_IS_BUCKET_INCREDEF(type))
3645
0
  size = sizeof(xmlSchemaInclude);
3646
0
    else
3647
0
  size = sizeof(xmlSchemaImport);
3648
0
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3649
0
    if (ret == NULL) {
3650
0
  xmlSchemaPErrMemory(NULL);
3651
0
  return(NULL);
3652
0
    }
3653
0
    memset(ret, 0, size);
3654
0
    ret->targetNamespace = targetNamespace;
3655
0
    ret->type = type;
3656
0
    ret->globals = xmlSchemaItemListCreate();
3657
0
    if (ret->globals == NULL) {
3658
0
  xmlSchemaBucketFree(ret);
3659
0
  return(NULL);
3660
0
    }
3661
0
    ret->locals = xmlSchemaItemListCreate();
3662
0
    if (ret->locals == NULL) {
3663
0
  xmlSchemaBucketFree(ret);
3664
0
  return(NULL);
3665
0
    }
3666
    /*
3667
    * The following will assure that only the first bucket is marked as
3668
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3669
    * For each following import buckets an xmlSchema will be created.
3670
    * An xmlSchema will be created for every distinct targetNamespace.
3671
    * We assign the targetNamespace to the schemata here.
3672
    */
3673
0
    if (! WXS_HAS_BUCKETS(pctxt)) {
3674
0
  if (WXS_IS_BUCKET_INCREDEF(type)) {
3675
0
      PERROR_INT("xmlSchemaBucketCreate",
3676
0
    "first bucket but it's an include or redefine");
3677
0
      xmlSchemaBucketFree(ret);
3678
0
      return(NULL);
3679
0
  }
3680
  /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3681
0
  ret->type = XML_SCHEMA_SCHEMA_MAIN;
3682
  /* Point to the *main* schema. */
3683
0
  WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3684
0
  WXS_IMPBUCKET(ret)->schema = mainSchema;
3685
  /*
3686
  * Ensure that the main schema gets a targetNamespace.
3687
  */
3688
0
  mainSchema->targetNamespace = targetNamespace;
3689
0
    } else {
3690
0
  if (type == XML_SCHEMA_SCHEMA_MAIN) {
3691
0
      PERROR_INT("xmlSchemaBucketCreate",
3692
0
    "main bucket but it's not the first one");
3693
0
      xmlSchemaBucketFree(ret);
3694
0
      return(NULL);
3695
0
  } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3696
      /*
3697
      * Create a schema for imports and assign the
3698
      * targetNamespace.
3699
      */
3700
0
      WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3701
0
      if (WXS_IMPBUCKET(ret)->schema == NULL) {
3702
0
    xmlSchemaBucketFree(ret);
3703
0
    return(NULL);
3704
0
      }
3705
0
      WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3706
0
  }
3707
0
    }
3708
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3709
0
  int res;
3710
  /*
3711
  * Imports go into the "schemasImports" slot of the main *schema*.
3712
  * Note that we create an import entry for the main schema as well; i.e.,
3713
  * even if there's only one schema, we'll get an import.
3714
  */
3715
0
  if (mainSchema->schemasImports == NULL) {
3716
0
      mainSchema->schemasImports = xmlHashCreateDict(5,
3717
0
    WXS_CONSTRUCTOR(pctxt)->dict);
3718
0
      if (mainSchema->schemasImports == NULL) {
3719
0
    xmlSchemaBucketFree(ret);
3720
0
    return(NULL);
3721
0
      }
3722
0
  }
3723
0
  if (targetNamespace == NULL)
3724
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3725
0
    XML_SCHEMAS_NO_NAMESPACE, ret);
3726
0
  else
3727
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3728
0
    targetNamespace, ret);
3729
0
  if (res != 0) {
3730
0
      PERROR_INT("xmlSchemaBucketCreate",
3731
0
    "failed to add the schema bucket to the hash");
3732
0
      xmlSchemaBucketFree(ret);
3733
0
      return(NULL);
3734
0
  }
3735
0
    } else {
3736
  /* Set the @ownerImport of an include bucket. */
3737
0
  if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3738
0
      WXS_INCBUCKET(ret)->ownerImport =
3739
0
    WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3740
0
  else
3741
0
      WXS_INCBUCKET(ret)->ownerImport =
3742
0
    WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3743
3744
  /* Includes got into the "includes" slot of the *main* schema. */
3745
0
  if (mainSchema->includes == NULL) {
3746
0
      mainSchema->includes = xmlSchemaItemListCreate();
3747
0
      if (mainSchema->includes == NULL) {
3748
0
    xmlSchemaBucketFree(ret);
3749
0
    return(NULL);
3750
0
      }
3751
0
  }
3752
0
  if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
3753
0
      xmlSchemaBucketFree(ret);
3754
0
      return(NULL);
3755
0
        }
3756
0
    }
3757
    /*
3758
    * Add to list of all buckets; this is used for lookup
3759
    * during schema construction time only.
3760
    */
3761
0
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3762
0
  return(NULL);
3763
0
    return(ret);
3764
0
}
3765
3766
static int
3767
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3768
0
{
3769
0
    if (*list == NULL) {
3770
0
  *list = xmlSchemaItemListCreate();
3771
0
  if (*list == NULL)
3772
0
      return(-1);
3773
0
    }
3774
0
    return(xmlSchemaItemListAddSize(*list, initialSize, item));
3775
0
}
3776
3777
/**
3778
 * xmlSchemaFreeAnnot:
3779
 * @annot:  a schema type structure
3780
 *
3781
 * Deallocate a annotation structure
3782
 */
3783
static void
3784
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3785
0
{
3786
0
    if (annot == NULL)
3787
0
        return;
3788
0
    if (annot->next == NULL) {
3789
0
  xmlFree(annot);
3790
0
    } else {
3791
0
  xmlSchemaAnnotPtr prev;
3792
3793
0
  do {
3794
0
      prev = annot;
3795
0
      annot = annot->next;
3796
0
      xmlFree(prev);
3797
0
  } while (annot != NULL);
3798
0
    }
3799
0
}
3800
3801
/**
3802
 * xmlSchemaFreeNotation:
3803
 * @schema:  a schema notation structure
3804
 *
3805
 * Deallocate a Schema Notation structure.
3806
 */
3807
static void
3808
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3809
0
{
3810
0
    if (nota == NULL)
3811
0
        return;
3812
0
    if (nota->annot != NULL)
3813
0
  xmlSchemaFreeAnnot(nota->annot);
3814
0
    xmlFree(nota);
3815
0
}
3816
3817
/**
3818
 * xmlSchemaFreeAttribute:
3819
 * @attr:  an attribute declaration
3820
 *
3821
 * Deallocates an attribute declaration structure.
3822
 */
3823
static void
3824
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3825
0
{
3826
0
    if (attr == NULL)
3827
0
        return;
3828
0
    if (attr->annot != NULL)
3829
0
  xmlSchemaFreeAnnot(attr->annot);
3830
0
    if (attr->defVal != NULL)
3831
0
  xmlSchemaFreeValue(attr->defVal);
3832
0
    xmlFree(attr);
3833
0
}
3834
3835
/**
3836
 * xmlSchemaFreeAttributeUse:
3837
 * @use:  an attribute use
3838
 *
3839
 * Deallocates an attribute use structure.
3840
 */
3841
static void
3842
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3843
0
{
3844
0
    if (use == NULL)
3845
0
        return;
3846
0
    if (use->annot != NULL)
3847
0
  xmlSchemaFreeAnnot(use->annot);
3848
0
    if (use->defVal != NULL)
3849
0
  xmlSchemaFreeValue(use->defVal);
3850
0
    xmlFree(use);
3851
0
}
3852
3853
/**
3854
 * xmlSchemaFreeAttributeUseProhib:
3855
 * @prohib:  an attribute use prohibition
3856
 *
3857
 * Deallocates an attribute use structure.
3858
 */
3859
static void
3860
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3861
0
{
3862
0
    if (prohib == NULL)
3863
0
        return;
3864
0
    xmlFree(prohib);
3865
0
}
3866
3867
/**
3868
 * xmlSchemaFreeWildcardNsSet:
3869
 * set:  a schema wildcard namespace
3870
 *
3871
 * Deallocates a list of wildcard constraint structures.
3872
 */
3873
static void
3874
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3875
0
{
3876
0
    xmlSchemaWildcardNsPtr next;
3877
3878
0
    while (set != NULL) {
3879
0
  next = set->next;
3880
0
  xmlFree(set);
3881
0
  set = next;
3882
0
    }
3883
0
}
3884
3885
/**
3886
 * xmlSchemaFreeWildcard:
3887
 * @wildcard:  a wildcard structure
3888
 *
3889
 * Deallocates a wildcard structure.
3890
 */
3891
void
3892
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3893
0
{
3894
0
    if (wildcard == NULL)
3895
0
        return;
3896
0
    if (wildcard->annot != NULL)
3897
0
        xmlSchemaFreeAnnot(wildcard->annot);
3898
0
    if (wildcard->nsSet != NULL)
3899
0
  xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3900
0
    if (wildcard->negNsSet != NULL)
3901
0
  xmlFree(wildcard->negNsSet);
3902
0
    xmlFree(wildcard);
3903
0
}
3904
3905
/**
3906
 * xmlSchemaFreeAttributeGroup:
3907
 * @schema:  a schema attribute group structure
3908
 *
3909
 * Deallocate a Schema Attribute Group structure.
3910
 */
3911
static void
3912
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3913
0
{
3914
0
    if (attrGr == NULL)
3915
0
        return;
3916
0
    if (attrGr->annot != NULL)
3917
0
        xmlSchemaFreeAnnot(attrGr->annot);
3918
0
    if (attrGr->attrUses != NULL)
3919
0
  xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3920
0
    xmlFree(attrGr);
3921
0
}
3922
3923
/**
3924
 * xmlSchemaFreeQNameRef:
3925
 * @item: a QName reference structure
3926
 *
3927
 * Deallocatea a QName reference structure.
3928
 */
3929
static void
3930
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3931
0
{
3932
0
    xmlFree(item);
3933
0
}
3934
3935
/**
3936
 * xmlSchemaFreeTypeLinkList:
3937
 * @alink: a type link
3938
 *
3939
 * Deallocate a list of types.
3940
 */
3941
static void
3942
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3943
0
{
3944
0
    xmlSchemaTypeLinkPtr next;
3945
3946
0
    while (link != NULL) {
3947
0
  next = link->next;
3948
0
  xmlFree(link);
3949
0
  link = next;
3950
0
    }
3951
0
}
3952
3953
static void
3954
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3955
0
{
3956
0
    xmlSchemaIDCStateObjPtr next;
3957
0
    while (sto != NULL) {
3958
0
  next = sto->next;
3959
0
  if (sto->history != NULL)
3960
0
      xmlFree(sto->history);
3961
0
  if (sto->xpathCtxt != NULL)
3962
0
      xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3963
0
  xmlFree(sto);
3964
0
  sto = next;
3965
0
    }
3966
0
}
3967
3968
/**
3969
 * xmlSchemaFreeIDC:
3970
 * @idc: a identity-constraint definition
3971
 *
3972
 * Deallocates an identity-constraint definition.
3973
 */
3974
static void
3975
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3976
0
{
3977
0
    xmlSchemaIDCSelectPtr cur, prev;
3978
3979
0
    if (idcDef == NULL)
3980
0
  return;
3981
0
    if (idcDef->annot != NULL)
3982
0
        xmlSchemaFreeAnnot(idcDef->annot);
3983
    /* Selector */
3984
0
    if (idcDef->selector != NULL) {
3985
0
  if (idcDef->selector->xpathComp != NULL)
3986
0
      xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3987
0
  xmlFree(idcDef->selector);
3988
0
    }
3989
    /* Fields */
3990
0
    if (idcDef->fields != NULL) {
3991
0
  cur = idcDef->fields;
3992
0
  do {
3993
0
      prev = cur;
3994
0
      cur = cur->next;
3995
0
      if (prev->xpathComp != NULL)
3996
0
    xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3997
0
      xmlFree(prev);
3998
0
  } while (cur != NULL);
3999
0
    }
4000
0
    xmlFree(idcDef);
4001
0
}
4002
4003
/**
4004
 * xmlSchemaFreeElement:
4005
 * @schema:  a schema element structure
4006
 *
4007
 * Deallocate a Schema Element structure.
4008
 */
4009
static void
4010
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
4011
0
{
4012
0
    if (elem == NULL)
4013
0
        return;
4014
0
    if (elem->annot != NULL)
4015
0
        xmlSchemaFreeAnnot(elem->annot);
4016
0
    if (elem->contModel != NULL)
4017
0
        xmlRegFreeRegexp(elem->contModel);
4018
0
    if (elem->defVal != NULL)
4019
0
  xmlSchemaFreeValue(elem->defVal);
4020
0
    xmlFree(elem);
4021
0
}
4022
4023
/**
4024
 * xmlSchemaFreeFacet:
4025
 * @facet:  a schema facet structure
4026
 *
4027
 * Deallocate a Schema Facet structure.
4028
 */
4029
void
4030
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4031
0
{
4032
0
    if (facet == NULL)
4033
0
        return;
4034
0
    if (facet->val != NULL)
4035
0
        xmlSchemaFreeValue(facet->val);
4036
0
    if (facet->regexp != NULL)
4037
0
        xmlRegFreeRegexp(facet->regexp);
4038
0
    if (facet->annot != NULL)
4039
0
        xmlSchemaFreeAnnot(facet->annot);
4040
0
    xmlFree(facet);
4041
0
}
4042
4043
/**
4044
 * xmlSchemaFreeType:
4045
 * @type:  a schema type structure
4046
 *
4047
 * Deallocate a Schema Type structure.
4048
 */
4049
void
4050
xmlSchemaFreeType(xmlSchemaTypePtr type)
4051
0
{
4052
0
    if (type == NULL)
4053
0
        return;
4054
0
    if (type->annot != NULL)
4055
0
        xmlSchemaFreeAnnot(type->annot);
4056
0
    if (type->facets != NULL) {
4057
0
        xmlSchemaFacetPtr facet, next;
4058
4059
0
        facet = type->facets;
4060
0
        while (facet != NULL) {
4061
0
            next = facet->next;
4062
0
            xmlSchemaFreeFacet(facet);
4063
0
            facet = next;
4064
0
        }
4065
0
    }
4066
0
    if (type->attrUses != NULL)
4067
0
  xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4068
0
    if (type->memberTypes != NULL)
4069
0
  xmlSchemaFreeTypeLinkList(type->memberTypes);
4070
0
    if (type->facetSet != NULL) {
4071
0
  xmlSchemaFacetLinkPtr next, link;
4072
4073
0
  link = type->facetSet;
4074
0
  do {
4075
0
      next = link->next;
4076
0
      xmlFree(link);
4077
0
      link = next;
4078
0
  } while (link != NULL);
4079
0
    }
4080
0
    if (type->contModel != NULL)
4081
0
        xmlRegFreeRegexp(type->contModel);
4082
0
    xmlFree(type);
4083
0
}
4084
4085
/**
4086
 * xmlSchemaFreeModelGroupDef:
4087
 * @item:  a schema model group definition
4088
 *
4089
 * Deallocates a schema model group definition.
4090
 */
4091
static void
4092
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4093
0
{
4094
0
    if (item->annot != NULL)
4095
0
  xmlSchemaFreeAnnot(item->annot);
4096
0
    xmlFree(item);
4097
0
}
4098
4099
/**
4100
 * xmlSchemaFreeModelGroup:
4101
 * @item:  a schema model group
4102
 *
4103
 * Deallocates a schema model group structure.
4104
 */
4105
static void
4106
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4107
0
{
4108
0
    if (item->annot != NULL)
4109
0
  xmlSchemaFreeAnnot(item->annot);
4110
0
    xmlFree(item);
4111
0
}
4112
4113
static void
4114
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4115
0
{
4116
0
    if ((list == NULL) || (list->nbItems == 0))
4117
0
  return;
4118
0
    {
4119
0
  xmlSchemaTreeItemPtr item;
4120
0
  xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4121
0
  int i;
4122
4123
0
  for (i = 0; i < list->nbItems; i++) {
4124
0
      item = items[i];
4125
0
      if (item == NULL)
4126
0
    continue;
4127
0
      switch (item->type) {
4128
0
    case XML_SCHEMA_TYPE_SIMPLE:
4129
0
    case XML_SCHEMA_TYPE_COMPLEX:
4130
0
        xmlSchemaFreeType((xmlSchemaTypePtr) item);
4131
0
        break;
4132
0
    case XML_SCHEMA_TYPE_ATTRIBUTE:
4133
0
        xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4134
0
        break;
4135
0
    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4136
0
        xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4137
0
        break;
4138
0
    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4139
0
        xmlSchemaFreeAttributeUseProhib(
4140
0
      (xmlSchemaAttributeUseProhibPtr) item);
4141
0
        break;
4142
0
    case XML_SCHEMA_TYPE_ELEMENT:
4143
0
        xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4144
0
        break;
4145
0
    case XML_SCHEMA_TYPE_PARTICLE:
4146
0
        if (item->annot != NULL)
4147
0
      xmlSchemaFreeAnnot(item->annot);
4148
0
        xmlFree(item);
4149
0
        break;
4150
0
    case XML_SCHEMA_TYPE_SEQUENCE:
4151
0
    case XML_SCHEMA_TYPE_CHOICE:
4152
0
    case XML_SCHEMA_TYPE_ALL:
4153
0
        xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4154
0
        break;
4155
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4156
0
        xmlSchemaFreeAttributeGroup(
4157
0
      (xmlSchemaAttributeGroupPtr) item);
4158
0
        break;
4159
0
    case XML_SCHEMA_TYPE_GROUP:
4160
0
        xmlSchemaFreeModelGroupDef(
4161
0
      (xmlSchemaModelGroupDefPtr) item);
4162
0
        break;
4163
0
    case XML_SCHEMA_TYPE_ANY:
4164
0
    case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4165
0
        xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4166
0
        break;
4167
0
    case XML_SCHEMA_TYPE_IDC_KEY:
4168
0
    case XML_SCHEMA_TYPE_IDC_UNIQUE:
4169
0
    case XML_SCHEMA_TYPE_IDC_KEYREF:
4170
0
        xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4171
0
        break;
4172
0
    case XML_SCHEMA_TYPE_NOTATION:
4173
0
        xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4174
0
        break;
4175
0
    case XML_SCHEMA_EXTRA_QNAMEREF:
4176
0
        xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4177
0
        break;
4178
0
    default:
4179
        /* TODO: This should never be hit. */
4180
0
        break;
4181
0
      }
4182
0
  }
4183
0
  list->nbItems = 0;
4184
0
    }
4185
0
}
4186
4187
/**
4188
 * xmlSchemaFree:
4189
 * @schema:  a schema structure
4190
 *
4191
 * Deallocate a Schema structure.
4192
 */
4193
void
4194
xmlSchemaFree(xmlSchemaPtr schema)
4195
0
{
4196
0
    if (schema == NULL)
4197
0
        return;
4198
    /*
4199
    * Note that those slots are not responsible for freeing
4200
    * schema components anymore; this will now be done by
4201
    * the schema buckets.
4202
    */
4203
0
    if (schema->notaDecl != NULL)
4204
0
        xmlHashFree(schema->notaDecl, NULL);
4205
0
    if (schema->attrDecl != NULL)
4206
0
        xmlHashFree(schema->attrDecl, NULL);
4207
0
    if (schema->attrgrpDecl != NULL)
4208
0
        xmlHashFree(schema->attrgrpDecl, NULL);
4209
0
    if (schema->elemDecl != NULL)
4210
0
        xmlHashFree(schema->elemDecl, NULL);
4211
0
    if (schema->typeDecl != NULL)
4212
0
        xmlHashFree(schema->typeDecl, NULL);
4213
0
    if (schema->groupDecl != NULL)
4214
0
        xmlHashFree(schema->groupDecl, NULL);
4215
0
    if (schema->idcDef != NULL)
4216
0
        xmlHashFree(schema->idcDef, NULL);
4217
4218
0
    if (schema->schemasImports != NULL)
4219
0
  xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4220
0
    if (schema->includes != NULL) {
4221
0
  xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4222
0
  int i;
4223
0
  for (i = 0; i < list->nbItems; i++) {
4224
0
      xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4225
0
  }
4226
0
  xmlSchemaItemListFree(list);
4227
0
    }
4228
0
    if (schema->annot != NULL)
4229
0
        xmlSchemaFreeAnnot(schema->annot);
4230
    /* Never free the doc here, since this will be done by the buckets. */
4231
4232
0
    xmlDictFree(schema->dict);
4233
0
    xmlFree(schema);
4234
0
}
4235
4236
/************************************************************************
4237
 *                  *
4238
 *      Debug functions         *
4239
 *                  *
4240
 ************************************************************************/
4241
4242
#ifdef LIBXML_OUTPUT_ENABLED
4243
4244
static void
4245
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4246
4247
/**
4248
 * xmlSchemaElementDump:
4249
 * @elem:  an element
4250
 * @output:  the file output
4251
 *
4252
 * Dump the element
4253
 */
4254
static void
4255
xmlSchemaElementDump(void *payload, void *data,
4256
                     const xmlChar * name ATTRIBUTE_UNUSED,
4257
         const xmlChar * namespace ATTRIBUTE_UNUSED,
4258
                     const xmlChar * context ATTRIBUTE_UNUSED)
4259
0
{
4260
0
    xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4261
0
    FILE *output = (FILE *) data;
4262
0
    if (elem == NULL)
4263
0
        return;
4264
4265
4266
0
    fprintf(output, "Element");
4267
0
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4268
0
  fprintf(output, " (global)");
4269
0
    fprintf(output, ": '%s' ", elem->name);
4270
0
    if (namespace != NULL)
4271
0
  fprintf(output, "ns '%s'", namespace);
4272
0
    fprintf(output, "\n");
4273
#if 0
4274
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4275
  fprintf(output, "  min %d ", elem->minOccurs);
4276
        if (elem->maxOccurs >= UNBOUNDED)
4277
            fprintf(output, "max: unbounded\n");
4278
        else if (elem->maxOccurs != 1)
4279
            fprintf(output, "max: %d\n", elem->maxOccurs);
4280
        else
4281
            fprintf(output, "\n");
4282
    }
4283
#endif
4284
    /*
4285
    * Misc other properties.
4286
    */
4287
0
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4288
0
  (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4289
0
  (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4290
0
  (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4291
0
  fprintf(output, "  props: ");
4292
0
  if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4293
0
      fprintf(output, "[fixed] ");
4294
0
  if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4295
0
      fprintf(output, "[default] ");
4296
0
  if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4297
0
      fprintf(output, "[abstract] ");
4298
0
  if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4299
0
      fprintf(output, "[nillable] ");
4300
0
  fprintf(output, "\n");
4301
0
    }
4302
    /*
4303
    * Default/fixed value.
4304
    */
4305
0
    if (elem->value != NULL)
4306
0
  fprintf(output, "  value: '%s'\n", elem->value);
4307
    /*
4308
    * Type.
4309
    */
4310
0
    if (elem->namedType != NULL) {
4311
0
  fprintf(output, "  type: '%s' ", elem->namedType);
4312
0
  if (elem->namedTypeNs != NULL)
4313
0
      fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4314
0
  else
4315
0
      fprintf(output, "\n");
4316
0
    } else if (elem->subtypes != NULL) {
4317
  /*
4318
  * Dump local types.
4319
  */
4320
0
  xmlSchemaTypeDump(elem->subtypes, output);
4321
0
    }
4322
    /*
4323
    * Substitution group.
4324
    */
4325
0
    if (elem->substGroup != NULL) {
4326
0
  fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4327
0
  if (elem->substGroupNs != NULL)
4328
0
      fprintf(output, "ns '%s'\n", elem->substGroupNs);
4329
0
  else
4330
0
      fprintf(output, "\n");
4331
0
    }
4332
0
}
4333
4334
/**
4335
 * xmlSchemaAnnotDump:
4336
 * @output:  the file output
4337
 * @annot:  a annotation
4338
 *
4339
 * Dump the annotation
4340
 */
4341
static void
4342
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4343
0
{
4344
0
    xmlChar *content;
4345
4346
0
    if (annot == NULL)
4347
0
        return;
4348
4349
0
    content = xmlNodeGetContent(annot->content);
4350
0
    if (content != NULL) {
4351
0
        fprintf(output, "  Annot: %s\n", content);
4352
0
        xmlFree(content);
4353
0
    } else
4354
0
        fprintf(output, "  Annot: empty\n");
4355
0
}
4356
4357
/**
4358
 * xmlSchemaContentModelDump:
4359
 * @particle: the schema particle
4360
 * @output: the file output
4361
 * @depth: the depth used for indentation
4362
 *
4363
 * Dump a SchemaType structure
4364
 */
4365
static void
4366
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4367
0
{
4368
0
    xmlChar *str = NULL;
4369
0
    xmlSchemaTreeItemPtr term;
4370
0
    char shift[100];
4371
0
    int i;
4372
4373
0
    if (particle == NULL)
4374
0
  return;
4375
0
    for (i = 0;((i < depth) && (i < 25));i++)
4376
0
        shift[2 * i] = shift[2 * i + 1] = ' ';
4377
0
    shift[2 * i] = shift[2 * i + 1] = 0;
4378
0
    fprintf(output, "%s", shift);
4379
0
    if (particle->children == NULL) {
4380
0
  fprintf(output, "MISSING particle term\n");
4381
0
  return;
4382
0
    }
4383
0
    term = particle->children;
4384
0
    if (term == NULL) {
4385
0
  fprintf(output, "(NULL)");
4386
0
    } else {
4387
0
  switch (term->type) {
4388
0
      case XML_SCHEMA_TYPE_ELEMENT:
4389
0
    fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4390
0
        ((xmlSchemaElementPtr)term)->targetNamespace,
4391
0
        ((xmlSchemaElementPtr)term)->name));
4392
0
    FREE_AND_NULL(str);
4393
0
    break;
4394
0
      case XML_SCHEMA_TYPE_SEQUENCE:
4395
0
    fprintf(output, "SEQUENCE");
4396
0
    break;
4397
0
      case XML_SCHEMA_TYPE_CHOICE:
4398
0
    fprintf(output, "CHOICE");
4399
0
    break;
4400
0
      case XML_SCHEMA_TYPE_ALL:
4401
0
    fprintf(output, "ALL");
4402
0
    break;
4403
0
      case XML_SCHEMA_TYPE_ANY:
4404
0
    fprintf(output, "ANY");
4405
0
    break;
4406
0
      default:
4407
0
    fprintf(output, "UNKNOWN\n");
4408
0
    return;
4409
0
  }
4410
0
    }
4411
0
    if (particle->minOccurs != 1)
4412
0
  fprintf(output, " min: %d", particle->minOccurs);
4413
0
    if (particle->maxOccurs >= UNBOUNDED)
4414
0
  fprintf(output, " max: unbounded");
4415
0
    else if (particle->maxOccurs != 1)
4416
0
  fprintf(output, " max: %d", particle->maxOccurs);
4417
0
    fprintf(output, "\n");
4418
0
    if (term &&
4419
0
  ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4420
0
   (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4421
0
   (term->type == XML_SCHEMA_TYPE_ALL)) &&
4422
0
   (term->children != NULL)) {
4423
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4424
0
      output, depth +1);
4425
0
    }
4426
0
    if (particle->next != NULL)
4427
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4428
0
    output, depth);
4429
0
}
4430
4431
/**
4432
 * xmlSchemaAttrUsesDump:
4433
 * @uses:  attribute uses list
4434
 * @output:  the file output
4435
 *
4436
 * Dumps a list of attribute use components.
4437
 */
4438
static void
4439
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4440
0
{
4441
0
    xmlSchemaAttributeUsePtr use;
4442
0
    xmlSchemaAttributeUseProhibPtr prohib;
4443
0
    xmlSchemaQNameRefPtr ref;
4444
0
    const xmlChar *name, *tns;
4445
0
    xmlChar *str = NULL;
4446
0
    int i;
4447
4448
0
    if ((uses == NULL) || (uses->nbItems == 0))
4449
0
        return;
4450
4451
0
    fprintf(output, "  attributes:\n");
4452
0
    for (i = 0; i < uses->nbItems; i++) {
4453
0
  use = uses->items[i];
4454
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4455
0
      fprintf(output, "  [prohibition] ");
4456
0
      prohib = (xmlSchemaAttributeUseProhibPtr) use;
4457
0
      name = prohib->name;
4458
0
      tns = prohib->targetNamespace;
4459
0
  } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4460
0
      fprintf(output, "  [reference] ");
4461
0
      ref = (xmlSchemaQNameRefPtr) use;
4462
0
      name = ref->name;
4463
0
      tns = ref->targetNamespace;
4464
0
  } else {
4465
0
      fprintf(output, "  [use] ");
4466
0
      name = WXS_ATTRUSE_DECL_NAME(use);
4467
0
      tns = WXS_ATTRUSE_DECL_TNS(use);
4468
0
  }
4469
0
  fprintf(output, "'%s'\n",
4470
0
      (const char *) xmlSchemaFormatQName(&str, tns, name));
4471
0
  FREE_AND_NULL(str);
4472
0
    }
4473
0
}
4474
4475
/**
4476
 * xmlSchemaTypeDump:
4477
 * @output:  the file output
4478
 * @type:  a type structure
4479
 *
4480
 * Dump a SchemaType structure
4481
 */
4482
static void
4483
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4484
0
{
4485
0
    if (type == NULL) {
4486
0
        fprintf(output, "Type: NULL\n");
4487
0
        return;
4488
0
    }
4489
0
    fprintf(output, "Type: ");
4490
0
    if (type->name != NULL)
4491
0
        fprintf(output, "'%s' ", type->name);
4492
0
    else
4493
0
        fprintf(output, "(no name) ");
4494
0
    if (type->targetNamespace != NULL)
4495
0
  fprintf(output, "ns '%s' ", type->targetNamespace);
4496
0
    switch (type->type) {
4497
0
        case XML_SCHEMA_TYPE_BASIC:
4498
0
            fprintf(output, "[basic] ");
4499
0
            break;
4500
0
        case XML_SCHEMA_TYPE_SIMPLE:
4501
0
            fprintf(output, "[simple] ");
4502
0
            break;
4503
0
        case XML_SCHEMA_TYPE_COMPLEX:
4504
0
            fprintf(output, "[complex] ");
4505
0
            break;
4506
0
        case XML_SCHEMA_TYPE_SEQUENCE:
4507
0
            fprintf(output, "[sequence] ");
4508
0
            break;
4509
0
        case XML_SCHEMA_TYPE_CHOICE:
4510
0
            fprintf(output, "[choice] ");
4511
0
            break;
4512
0
        case XML_SCHEMA_TYPE_ALL:
4513
0
            fprintf(output, "[all] ");
4514
0
            break;
4515
0
        case XML_SCHEMA_TYPE_UR:
4516
0
            fprintf(output, "[ur] ");
4517
0
            break;
4518
0
        case XML_SCHEMA_TYPE_RESTRICTION:
4519
0
            fprintf(output, "[restriction] ");
4520
0
            break;
4521
0
        case XML_SCHEMA_TYPE_EXTENSION:
4522
0
            fprintf(output, "[extension] ");
4523
0
            break;
4524
0
        default:
4525
0
            fprintf(output, "[unknown type %d] ", type->type);
4526
0
            break;
4527
0
    }
4528
0
    fprintf(output, "content: ");
4529
0
    switch (type->contentType) {
4530
0
        case XML_SCHEMA_CONTENT_UNKNOWN:
4531
0
            fprintf(output, "[unknown] ");
4532
0
            break;
4533
0
        case XML_SCHEMA_CONTENT_EMPTY:
4534
0
            fprintf(output, "[empty] ");
4535
0
            break;
4536
0
        case XML_SCHEMA_CONTENT_ELEMENTS:
4537
0
            fprintf(output, "[element] ");
4538
0
            break;
4539
0
        case XML_SCHEMA_CONTENT_MIXED:
4540
0
            fprintf(output, "[mixed] ");
4541
0
            break;
4542
0
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4543
  /* not used. */
4544
0
            break;
4545
0
        case XML_SCHEMA_CONTENT_BASIC:
4546
0
            fprintf(output, "[basic] ");
4547
0
            break;
4548
0
        case XML_SCHEMA_CONTENT_SIMPLE:
4549
0
            fprintf(output, "[simple] ");
4550
0
            break;
4551
0
        case XML_SCHEMA_CONTENT_ANY:
4552
0
            fprintf(output, "[any] ");
4553
0
            break;
4554
0
    }
4555
0
    fprintf(output, "\n");
4556
0
    if (type->base != NULL) {
4557
0
        fprintf(output, "  base type: '%s'", type->base);
4558
0
  if (type->baseNs != NULL)
4559
0
      fprintf(output, " ns '%s'\n", type->baseNs);
4560
0
  else
4561
0
      fprintf(output, "\n");
4562
0
    }
4563
0
    if (type->attrUses != NULL)
4564
0
  xmlSchemaAttrUsesDump(type->attrUses, output);
4565
0
    if (type->annot != NULL)
4566
0
        xmlSchemaAnnotDump(output, type->annot);
4567
0
#ifdef DUMP_CONTENT_MODEL
4568
0
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4569
0
  (type->subtypes != NULL)) {
4570
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4571
0
      output, 1);
4572
0
    }
4573
0
#endif
4574
0
}
4575
4576
static void
4577
xmlSchemaTypeDumpEntry(void *type, void *output,
4578
                       const xmlChar *name ATTRIBUTE_UNUSED)
4579
0
{
4580
0
    xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4581
0
}
4582
4583
/**
4584
 * xmlSchemaDump:
4585
 * @output:  the file output
4586
 * @schema:  a schema structure
4587
 *
4588
 * Dump a Schema structure.
4589
 */
4590
void
4591
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4592
0
{
4593
0
    if (output == NULL)
4594
0
        return;
4595
0
    if (schema == NULL) {
4596
0
        fprintf(output, "Schemas: NULL\n");
4597
0
        return;
4598
0
    }
4599
0
    fprintf(output, "Schemas: ");
4600
0
    if (schema->name != NULL)
4601
0
        fprintf(output, "%s, ", schema->name);
4602
0
    else
4603
0
        fprintf(output, "no name, ");
4604
0
    if (schema->targetNamespace != NULL)
4605
0
        fprintf(output, "%s", (const char *) schema->targetNamespace);
4606
0
    else
4607
0
        fprintf(output, "no target namespace");
4608
0
    fprintf(output, "\n");
4609
0
    if (schema->annot != NULL)
4610
0
        xmlSchemaAnnotDump(output, schema->annot);
4611
0
    xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4612
0
    xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4613
0
}
4614
4615
#endif /* LIBXML_OUTPUT_ENABLED */
4616
4617
/************************************************************************
4618
 *                  *
4619
 *      Utilities         *
4620
 *                  *
4621
 ************************************************************************/
4622
4623
/**
4624
 * xmlSchemaGetPropNode:
4625
 * @node: the element node
4626
 * @name: the name of the attribute
4627
 *
4628
 * Seeks an attribute with a name of @name in
4629
 * no namespace.
4630
 *
4631
 * Returns the attribute or NULL if not present.
4632
 */
4633
static xmlAttrPtr
4634
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4635
0
{
4636
0
    xmlAttrPtr prop;
4637
4638
0
    if ((node == NULL) || (name == NULL))
4639
0
  return(NULL);
4640
0
    prop = node->properties;
4641
0
    while (prop != NULL) {
4642
0
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4643
0
      return(prop);
4644
0
  prop = prop->next;
4645
0
    }
4646
0
    return (NULL);
4647
0
}
4648
4649
/**
4650
 * xmlSchemaGetPropNodeNs:
4651
 * @node: the element node
4652
 * @uri: the uri
4653
 * @name: the name of the attribute
4654
 *
4655
 * Seeks an attribute with a local name of @name and
4656
 * a namespace URI of @uri.
4657
 *
4658
 * Returns the attribute or NULL if not present.
4659
 */
4660
static xmlAttrPtr
4661
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4662
0
{
4663
0
    xmlAttrPtr prop;
4664
4665
0
    if ((node == NULL) || (name == NULL))
4666
0
  return(NULL);
4667
0
    prop = node->properties;
4668
0
    while (prop != NULL) {
4669
0
  if ((prop->ns != NULL) &&
4670
0
      xmlStrEqual(prop->name, BAD_CAST name) &&
4671
0
      xmlStrEqual(prop->ns->href, BAD_CAST uri))
4672
0
      return(prop);
4673
0
  prop = prop->next;
4674
0
    }
4675
0
    return (NULL);
4676
0
}
4677
4678
static const xmlChar *
4679
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4680
0
{
4681
0
    xmlChar *val;
4682
0
    const xmlChar *ret;
4683
4684
0
    val = xmlNodeGetContent(node);
4685
0
    if (val == NULL)
4686
0
  val = xmlStrdup((xmlChar *)"");
4687
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4688
0
    xmlFree(val);
4689
0
    if (ret == NULL)
4690
0
        xmlSchemaPErrMemory(ctxt);
4691
0
    return(ret);
4692
0
}
4693
4694
static const xmlChar *
4695
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4696
0
{
4697
0
    return((const xmlChar*) xmlNodeGetContent(node));
4698
0
}
4699
4700
/**
4701
 * xmlSchemaGetProp:
4702
 * @ctxt: the parser context
4703
 * @node: the node
4704
 * @name: the property name
4705
 *
4706
 * Read a attribute value and internalize the string
4707
 *
4708
 * Returns the string or NULL if not present.
4709
 */
4710
static const xmlChar *
4711
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4712
                 const char *name)
4713
0
{
4714
0
    xmlChar *val;
4715
0
    const xmlChar *ret;
4716
4717
0
    val = xmlGetNoNsProp(node, BAD_CAST name);
4718
0
    if (val == NULL)
4719
0
        return(NULL);
4720
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4721
0
    xmlFree(val);
4722
0
    return(ret);
4723
0
}
4724
4725
/************************************************************************
4726
 *                  *
4727
 *      Parsing functions       *
4728
 *                  *
4729
 ************************************************************************/
4730
4731
#define WXS_FIND_GLOBAL_ITEM(slot)      \
4732
0
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4733
0
  ret = xmlHashLookup(schema->slot, name); \
4734
0
  if (ret != NULL) goto exit; \
4735
0
    } \
4736
0
    if (xmlHashSize(schema->schemasImports) > 1) { \
4737
0
  xmlSchemaImportPtr import; \
4738
0
  if (nsName == NULL) \
4739
0
      import = xmlHashLookup(schema->schemasImports, \
4740
0
    XML_SCHEMAS_NO_NAMESPACE); \
4741
0
  else \
4742
0
      import = xmlHashLookup(schema->schemasImports, nsName); \
4743
0
  if (import == NULL) \
4744
0
      goto exit; \
4745
0
  ret = xmlHashLookup(import->schema->slot, name); \
4746
0
    }
4747
4748
/**
4749
 * xmlSchemaGetElem:
4750
 * @schema:  the schema context
4751
 * @name:  the element name
4752
 * @ns:  the element namespace
4753
 *
4754
 * Lookup a global element declaration in the schema.
4755
 *
4756
 * Returns the element declaration or NULL if not found.
4757
 */
4758
static xmlSchemaElementPtr
4759
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4760
                 const xmlChar * nsName)
4761
0
{
4762
0
    xmlSchemaElementPtr ret = NULL;
4763
4764
0
    if ((name == NULL) || (schema == NULL))
4765
0
        return(NULL);
4766
0
    if (schema != NULL) {
4767
0
  WXS_FIND_GLOBAL_ITEM(elemDecl)
4768
0
    }
4769
0
exit:
4770
0
    return (ret);
4771
0
}
4772
4773
/**
4774
 * xmlSchemaGetType:
4775
 * @schema:  the main schema
4776
 * @name:  the type's name
4777
 * nsName:  the type's namespace
4778
 *
4779
 * Lookup a type in the schemas or the predefined types
4780
 *
4781
 * Returns the group definition or NULL if not found.
4782
 */
4783
static xmlSchemaTypePtr
4784
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4785
                 const xmlChar * nsName)
4786
0
{
4787
0
    xmlSchemaTypePtr ret = NULL;
4788
4789
0
    if (name == NULL)
4790
0
        return (NULL);
4791
    /* First try the built-in types. */
4792
0
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4793
0
  ret = xmlSchemaGetPredefinedType(name, nsName);
4794
0
  if (ret != NULL)
4795
0
      goto exit;
4796
  /*
4797
  * Note that we try the parsed schemas as well here
4798
  * since one might have parsed the S4S, which contain more
4799
  * than the built-in types.
4800
  * TODO: Can we optimize this?
4801
  */
4802
0
    }
4803
0
    if (schema != NULL) {
4804
0
  WXS_FIND_GLOBAL_ITEM(typeDecl)
4805
0
    }
4806
0
exit:
4807
4808
0
    return (ret);
4809
0
}
4810
4811
/**
4812
 * xmlSchemaGetAttributeDecl:
4813
 * @schema:  the context of the schema
4814
 * @name:  the name of the attribute
4815
 * @ns:  the target namespace of the attribute
4816
 *
4817
 * Lookup a an attribute in the schema or imported schemas
4818
 *
4819
 * Returns the attribute declaration or NULL if not found.
4820
 */
4821
static xmlSchemaAttributePtr
4822
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4823
                 const xmlChar * nsName)
4824
0
{
4825
0
    xmlSchemaAttributePtr ret = NULL;
4826
4827
0
    if ((name == NULL) || (schema == NULL))
4828
0
        return (NULL);
4829
0
    if (schema != NULL) {
4830
0
  WXS_FIND_GLOBAL_ITEM(attrDecl)
4831
0
    }
4832
0
exit:
4833
0
    return (ret);
4834
0
}
4835
4836
/**
4837
 * xmlSchemaGetAttributeGroup:
4838
 * @schema:  the context of the schema
4839
 * @name:  the name of the attribute group
4840
 * @ns:  the target namespace of the attribute group
4841
 *
4842
 * Lookup a an attribute group in the schema or imported schemas
4843
 *
4844
 * Returns the attribute group definition or NULL if not found.
4845
 */
4846
static xmlSchemaAttributeGroupPtr
4847
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4848
                 const xmlChar * nsName)
4849
0
{
4850
0
    xmlSchemaAttributeGroupPtr ret = NULL;
4851
4852
0
    if ((name == NULL) || (schema == NULL))
4853
0
        return (NULL);
4854
0
    if (schema != NULL) {
4855
0
  WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4856
0
    }
4857
0
exit:
4858
    /* TODO:
4859
    if ((ret != NULL) && (ret->redef != NULL)) {
4860
  * Return the last redefinition. *
4861
  ret = ret->redef;
4862
    }
4863
    */
4864
0
    return (ret);
4865
0
}
4866
4867
/**
4868
 * xmlSchemaGetGroup:
4869
 * @schema:  the context of the schema
4870
 * @name:  the name of the group
4871
 * @ns:  the target namespace of the group
4872
 *
4873
 * Lookup a group in the schema or imported schemas
4874
 *
4875
 * Returns the group definition or NULL if not found.
4876
 */
4877
static xmlSchemaModelGroupDefPtr
4878
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4879
                 const xmlChar * nsName)
4880
0
{
4881
0
    xmlSchemaModelGroupDefPtr ret = NULL;
4882
4883
0
    if ((name == NULL) || (schema == NULL))
4884
0
        return (NULL);
4885
0
    if (schema != NULL) {
4886
0
  WXS_FIND_GLOBAL_ITEM(groupDecl)
4887
0
    }
4888
0
exit:
4889
4890
0
    return (ret);
4891
0
}
4892
4893
static xmlSchemaNotationPtr
4894
xmlSchemaGetNotation(xmlSchemaPtr schema,
4895
         const xmlChar *name,
4896
         const xmlChar *nsName)
4897
0
{
4898
0
    xmlSchemaNotationPtr ret = NULL;
4899
4900
0
    if ((name == NULL) || (schema == NULL))
4901
0
        return (NULL);
4902
0
    if (schema != NULL) {
4903
0
  WXS_FIND_GLOBAL_ITEM(notaDecl)
4904
0
    }
4905
0
exit:
4906
0
    return (ret);
4907
0
}
4908
4909
static xmlSchemaIDCPtr
4910
xmlSchemaGetIDC(xmlSchemaPtr schema,
4911
    const xmlChar *name,
4912
    const xmlChar *nsName)
4913
0
{
4914
0
    xmlSchemaIDCPtr ret = NULL;
4915
4916
0
    if ((name == NULL) || (schema == NULL))
4917
0
        return (NULL);
4918
0
    if (schema != NULL) {
4919
0
  WXS_FIND_GLOBAL_ITEM(idcDef)
4920
0
    }
4921
0
exit:
4922
0
    return (ret);
4923
0
}
4924
4925
/**
4926
 * xmlSchemaGetNamedComponent:
4927
 * @schema:  the schema
4928
 * @name:  the name of the group
4929
 * @ns:  the target namespace of the group
4930
 *
4931
 * Lookup a group in the schema or imported schemas
4932
 *
4933
 * Returns the group definition or NULL if not found.
4934
 */
4935
static xmlSchemaBasicItemPtr
4936
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4937
         xmlSchemaTypeType itemType,
4938
         const xmlChar *name,
4939
         const xmlChar *targetNs)
4940
0
{
4941
0
    switch (itemType) {
4942
0
  case XML_SCHEMA_TYPE_GROUP:
4943
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4944
0
    name, targetNs));
4945
0
  case XML_SCHEMA_TYPE_ELEMENT:
4946
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4947
0
    name, targetNs));
4948
0
  default:
4949
      /* TODO */
4950
0
      return (NULL);
4951
0
    }
4952
0
}
4953
4954
/************************************************************************
4955
 *                  *
4956
 *      Parsing functions       *
4957
 *                  *
4958
 ************************************************************************/
4959
4960
#define IS_BLANK_NODE(n)            \
4961
0
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4962
4963
/**
4964
 * xmlSchemaIsBlank:
4965
 * @str:  a string
4966
 * @len: the length of the string or -1
4967
 *
4968
 * Check if a string is ignorable
4969
 *
4970
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4971
 */
4972
static int
4973
xmlSchemaIsBlank(xmlChar * str, int len)
4974
0
{
4975
0
    if (str == NULL)
4976
0
        return (1);
4977
0
    if (len < 0) {
4978
0
  while (*str != 0) {
4979
0
      if (!(IS_BLANK_CH(*str)))
4980
0
    return (0);
4981
0
      str++;
4982
0
  }
4983
0
    } else while ((*str != 0) && (len != 0)) {
4984
0
  if (!(IS_BLANK_CH(*str)))
4985
0
      return (0);
4986
0
  str++;
4987
0
  len--;
4988
0
    }
4989
4990
0
    return (1);
4991
0
}
4992
4993
0
#define WXS_COMP_NAME(c, t) ((t) (c))->name
4994
0
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
4995
/*
4996
* xmlSchemaFindRedefCompInGraph:
4997
* ATTENTION TODO: This uses pointer comp. for strings.
4998
*/
4999
static xmlSchemaBasicItemPtr
5000
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5001
            xmlSchemaTypeType type,
5002
            const xmlChar *name,
5003
            const xmlChar *nsName)
5004
0
{
5005
0
    xmlSchemaBasicItemPtr ret;
5006
0
    int i;
5007
5008
0
    if ((bucket == NULL) || (name == NULL))
5009
0
  return(NULL);
5010
0
    if ((bucket->globals == NULL) ||
5011
0
  (bucket->globals->nbItems == 0))
5012
0
  goto subschemas;
5013
    /*
5014
    * Search in global components.
5015
    */
5016
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
5017
0
  ret = bucket->globals->items[i];
5018
0
  if (ret->type == type) {
5019
0
      switch (type) {
5020
0
    case XML_SCHEMA_TYPE_COMPLEX:
5021
0
    case XML_SCHEMA_TYPE_SIMPLE:
5022
0
        if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5023
0
      (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5024
0
      nsName))
5025
0
        {
5026
0
      return(ret);
5027
0
        }
5028
0
        break;
5029
0
    case XML_SCHEMA_TYPE_GROUP:
5030
0
        if ((WXS_COMP_NAME(ret,
5031
0
          xmlSchemaModelGroupDefPtr) == name) &&
5032
0
      (WXS_COMP_TNS(ret,
5033
0
          xmlSchemaModelGroupDefPtr) == nsName))
5034
0
        {
5035
0
      return(ret);
5036
0
        }
5037
0
        break;
5038
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5039
0
        if ((WXS_COMP_NAME(ret,
5040
0
          xmlSchemaAttributeGroupPtr) == name) &&
5041
0
      (WXS_COMP_TNS(ret,
5042
0
          xmlSchemaAttributeGroupPtr) == nsName))
5043
0
        {
5044
0
      return(ret);
5045
0
        }
5046
0
        break;
5047
0
    default:
5048
        /* Should not be hit. */
5049
0
        return(NULL);
5050
0
      }
5051
0
  }
5052
0
    }
5053
0
subschemas:
5054
    /*
5055
    * Process imported/included schemas.
5056
    */
5057
0
    if (bucket->relations != NULL) {
5058
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
5059
5060
  /*
5061
  * TODO: Marking the bucket will not avoid multiple searches
5062
  * in the same schema, but avoids at least circularity.
5063
  */
5064
0
  bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5065
0
  do {
5066
0
      if ((rel->bucket != NULL) &&
5067
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5068
0
    ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5069
0
        type, name, nsName);
5070
0
    if (ret != NULL)
5071
0
        return(ret);
5072
0
      }
5073
0
      rel = rel->next;
5074
0
  } while (rel != NULL);
5075
0
   bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5076
0
    }
5077
0
    return(NULL);
5078
0
}
5079
5080
/**
5081
 * xmlSchemaAddNotation:
5082
 * @ctxt:  a schema parser context
5083
 * @schema:  the schema being built
5084
 * @name:  the item name
5085
 *
5086
 * Add an XML schema annotation declaration
5087
 * *WARNING* this interface is highly subject to change
5088
 *
5089
 * Returns the new structure or NULL in case of error
5090
 */
5091
static xmlSchemaNotationPtr
5092
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5093
                     const xmlChar *name, const xmlChar *nsName,
5094
         xmlNodePtr node ATTRIBUTE_UNUSED)
5095
0
{
5096
0
    xmlSchemaNotationPtr ret = NULL;
5097
5098
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5099
0
        return (NULL);
5100
5101
0
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5102
0
    if (ret == NULL) {
5103
0
        xmlSchemaPErrMemory(ctxt);
5104
0
        return (NULL);
5105
0
    }
5106
0
    memset(ret, 0, sizeof(xmlSchemaNotation));
5107
0
    ret->type = XML_SCHEMA_TYPE_NOTATION;
5108
0
    ret->name = name;
5109
0
    ret->targetNamespace = nsName;
5110
    /* TODO: do we need the node to be set?
5111
    * ret->node = node;*/
5112
0
    WXS_ADD_GLOBAL(ctxt, ret);
5113
0
    return (ret);
5114
0
}
5115
5116
/**
5117
 * xmlSchemaAddAttribute:
5118
 * @ctxt:  a schema parser context
5119
 * @schema:  the schema being built
5120
 * @name:  the item name
5121
 * @namespace:  the namespace
5122
 *
5123
 * Add an XML schema Attribute declaration
5124
 * *WARNING* this interface is highly subject to change
5125
 *
5126
 * Returns the new structure or NULL in case of error
5127
 */
5128
static xmlSchemaAttributePtr
5129
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5130
                      const xmlChar * name, const xmlChar * nsName,
5131
          xmlNodePtr node, int topLevel)
5132
0
{
5133
0
    xmlSchemaAttributePtr ret = NULL;
5134
5135
0
    if ((ctxt == NULL) || (schema == NULL))
5136
0
        return (NULL);
5137
5138
0
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5139
0
    if (ret == NULL) {
5140
0
        xmlSchemaPErrMemory(ctxt);
5141
0
        return (NULL);
5142
0
    }
5143
0
    memset(ret, 0, sizeof(xmlSchemaAttribute));
5144
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5145
0
    ret->node = node;
5146
0
    ret->name = name;
5147
0
    ret->targetNamespace = nsName;
5148
5149
0
    if (topLevel)
5150
0
  WXS_ADD_GLOBAL(ctxt, ret);
5151
0
    else
5152
0
  WXS_ADD_LOCAL(ctxt, ret);
5153
0
    WXS_ADD_PENDING(ctxt, ret);
5154
0
    return (ret);
5155
0
}
5156
5157
/**
5158
 * xmlSchemaAddAttributeUse:
5159
 * @ctxt:  a schema parser context
5160
 * @schema:  the schema being built
5161
 * @name:  the item name
5162
 * @namespace:  the namespace
5163
 *
5164
 * Add an XML schema Attribute declaration
5165
 * *WARNING* this interface is highly subject to change
5166
 *
5167
 * Returns the new structure or NULL in case of error
5168
 */
5169
static xmlSchemaAttributeUsePtr
5170
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5171
       xmlNodePtr node)
5172
0
{
5173
0
    xmlSchemaAttributeUsePtr ret = NULL;
5174
5175
0
    if (pctxt == NULL)
5176
0
        return (NULL);
5177
5178
0
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5179
0
    if (ret == NULL) {
5180
0
        xmlSchemaPErrMemory(pctxt);
5181
0
        return (NULL);
5182
0
    }
5183
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5184
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5185
0
    ret->node = node;
5186
5187
0
    WXS_ADD_LOCAL(pctxt, ret);
5188
0
    return (ret);
5189
0
}
5190
5191
/*
5192
* xmlSchemaAddRedef:
5193
*
5194
* Adds a redefinition information. This is used at a later stage to:
5195
* resolve references to the redefined components and to check constraints.
5196
*/
5197
static xmlSchemaRedefPtr
5198
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5199
      xmlSchemaBucketPtr targetBucket,
5200
      void *item,
5201
      const xmlChar *refName,
5202
      const xmlChar *refTargetNs)
5203
0
{
5204
0
    xmlSchemaRedefPtr ret;
5205
5206
0
    ret = (xmlSchemaRedefPtr)
5207
0
  xmlMalloc(sizeof(xmlSchemaRedef));
5208
0
    if (ret == NULL) {
5209
0
  xmlSchemaPErrMemory(pctxt);
5210
0
  return (NULL);
5211
0
    }
5212
0
    memset(ret, 0, sizeof(xmlSchemaRedef));
5213
0
    ret->item = item;
5214
0
    ret->targetBucket = targetBucket;
5215
0
    ret->refName = refName;
5216
0
    ret->refTargetNs = refTargetNs;
5217
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5218
0
  WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5219
0
    else
5220
0
  WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5221
0
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5222
5223
0
    return (ret);
5224
0
}
5225
5226
/**
5227
 * xmlSchemaAddAttributeGroupDefinition:
5228
 * @ctxt:  a schema parser context
5229
 * @schema:  the schema being built
5230
 * @name:  the item name
5231
 * @nsName:  the target namespace
5232
 * @node: the corresponding node
5233
 *
5234
 * Add an XML schema Attribute Group definition.
5235
 *
5236
 * Returns the new structure or NULL in case of error
5237
 */
5238
static xmlSchemaAttributeGroupPtr
5239
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5240
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5241
         const xmlChar *name,
5242
         const xmlChar *nsName,
5243
         xmlNodePtr node)
5244
0
{
5245
0
    xmlSchemaAttributeGroupPtr ret = NULL;
5246
5247
0
    if ((pctxt == NULL) || (name == NULL))
5248
0
        return (NULL);
5249
5250
0
    ret = (xmlSchemaAttributeGroupPtr)
5251
0
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5252
0
    if (ret == NULL) {
5253
0
  xmlSchemaPErrMemory(pctxt);
5254
0
  return (NULL);
5255
0
    }
5256
0
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5257
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5258
0
    ret->name = name;
5259
0
    ret->targetNamespace = nsName;
5260
0
    ret->node = node;
5261
5262
    /* TODO: Remove the flag. */
5263
0
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5264
0
    if (pctxt->isRedefine) {
5265
0
  pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5266
0
      ret, name, nsName);
5267
0
  if (pctxt->redef == NULL) {
5268
0
      xmlFree(ret);
5269
0
      return(NULL);
5270
0
  }
5271
0
  pctxt->redefCounter = 0;
5272
0
    }
5273
0
    WXS_ADD_GLOBAL(pctxt, ret);
5274
0
    WXS_ADD_PENDING(pctxt, ret);
5275
0
    return (ret);
5276
0
}
5277
5278
/**
5279
 * xmlSchemaAddElement:
5280
 * @ctxt:  a schema parser context
5281
 * @schema:  the schema being built
5282
 * @name:  the type name
5283
 * @namespace:  the type namespace
5284
 *
5285
 * Add an XML schema Element declaration
5286
 * *WARNING* this interface is highly subject to change
5287
 *
5288
 * Returns the new structure or NULL in case of error
5289
 */
5290
static xmlSchemaElementPtr
5291
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5292
                    const xmlChar * name, const xmlChar * nsName,
5293
        xmlNodePtr node, int topLevel)
5294
0
{
5295
0
    xmlSchemaElementPtr ret = NULL;
5296
5297
0
    if ((ctxt == NULL) || (name == NULL))
5298
0
        return (NULL);
5299
5300
0
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5301
0
    if (ret == NULL) {
5302
0
        xmlSchemaPErrMemory(ctxt);
5303
0
        return (NULL);
5304
0
    }
5305
0
    memset(ret, 0, sizeof(xmlSchemaElement));
5306
0
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5307
0
    ret->name = name;
5308
0
    ret->targetNamespace = nsName;
5309
0
    ret->node = node;
5310
5311
0
    if (topLevel)
5312
0
  WXS_ADD_GLOBAL(ctxt, ret);
5313
0
    else
5314
0
  WXS_ADD_LOCAL(ctxt, ret);
5315
0
    WXS_ADD_PENDING(ctxt, ret);
5316
0
    return (ret);
5317
0
}
5318
5319
/**
5320
 * xmlSchemaAddType:
5321
 * @ctxt:  a schema parser context
5322
 * @schema:  the schema being built
5323
 * @name:  the item name
5324
 * @namespace:  the namespace
5325
 *
5326
 * Add an XML schema item
5327
 * *WARNING* this interface is highly subject to change
5328
 *
5329
 * Returns the new structure or NULL in case of error
5330
 */
5331
static xmlSchemaTypePtr
5332
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5333
     xmlSchemaTypeType type,
5334
                 const xmlChar * name, const xmlChar * nsName,
5335
     xmlNodePtr node, int topLevel)
5336
0
{
5337
0
    xmlSchemaTypePtr ret = NULL;
5338
5339
0
    if ((ctxt == NULL) || (schema == NULL))
5340
0
        return (NULL);
5341
5342
0
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5343
0
    if (ret == NULL) {
5344
0
        xmlSchemaPErrMemory(ctxt);
5345
0
        return (NULL);
5346
0
    }
5347
0
    memset(ret, 0, sizeof(xmlSchemaType));
5348
0
    ret->type = type;
5349
0
    ret->name = name;
5350
0
    ret->targetNamespace = nsName;
5351
0
    ret->node = node;
5352
0
    if (topLevel) {
5353
0
  if (ctxt->isRedefine) {
5354
0
      ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5355
0
    ret, name, nsName);
5356
0
      if (ctxt->redef == NULL) {
5357
0
    xmlFree(ret);
5358
0
    return(NULL);
5359
0
      }
5360
0
      ctxt->redefCounter = 0;
5361
0
  }
5362
0
  WXS_ADD_GLOBAL(ctxt, ret);
5363
0
    } else
5364
0
  WXS_ADD_LOCAL(ctxt, ret);
5365
0
    WXS_ADD_PENDING(ctxt, ret);
5366
0
    return (ret);
5367
0
}
5368
5369
static xmlSchemaQNameRefPtr
5370
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5371
         xmlSchemaTypeType refType,
5372
         const xmlChar *refName,
5373
         const xmlChar *refNs)
5374
0
{
5375
0
    xmlSchemaQNameRefPtr ret;
5376
5377
0
    ret = (xmlSchemaQNameRefPtr)
5378
0
  xmlMalloc(sizeof(xmlSchemaQNameRef));
5379
0
    if (ret == NULL) {
5380
0
  xmlSchemaPErrMemory(pctxt);
5381
0
  return (NULL);
5382
0
    }
5383
0
    ret->node = NULL;
5384
0
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5385
0
    ret->name = refName;
5386
0
    ret->targetNamespace = refNs;
5387
0
    ret->item = NULL;
5388
0
    ret->itemType = refType;
5389
    /*
5390
    * Store the reference item in the schema.
5391
    */
5392
0
    WXS_ADD_LOCAL(pctxt, ret);
5393
0
    return (ret);
5394
0
}
5395
5396
static xmlSchemaAttributeUseProhibPtr
5397
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5398
0
{
5399
0
    xmlSchemaAttributeUseProhibPtr ret;
5400
5401
0
    ret = (xmlSchemaAttributeUseProhibPtr)
5402
0
  xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5403
0
    if (ret == NULL) {
5404
0
  xmlSchemaPErrMemory(pctxt);
5405
0
  return (NULL);
5406
0
    }
5407
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5408
0
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5409
0
    WXS_ADD_LOCAL(pctxt, ret);
5410
0
    return (ret);
5411
0
}
5412
5413
5414
/**
5415
 * xmlSchemaAddModelGroup:
5416
 * @ctxt:  a schema parser context
5417
 * @schema:  the schema being built
5418
 * @type: the "compositor" type of the model group
5419
 * @node: the node in the schema doc
5420
 *
5421
 * Adds a schema model group
5422
 * *WARNING* this interface is highly subject to change
5423
 *
5424
 * Returns the new structure or NULL in case of error
5425
 */
5426
static xmlSchemaModelGroupPtr
5427
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5428
           xmlSchemaPtr schema,
5429
           xmlSchemaTypeType type,
5430
           xmlNodePtr node)
5431
0
{
5432
0
    xmlSchemaModelGroupPtr ret = NULL;
5433
5434
0
    if ((ctxt == NULL) || (schema == NULL))
5435
0
        return (NULL);
5436
5437
0
    ret = (xmlSchemaModelGroupPtr)
5438
0
  xmlMalloc(sizeof(xmlSchemaModelGroup));
5439
0
    if (ret == NULL) {
5440
0
  xmlSchemaPErrMemory(ctxt);
5441
0
  return (NULL);
5442
0
    }
5443
0
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5444
0
    ret->type = type;
5445
0
    ret->node = node;
5446
0
    WXS_ADD_LOCAL(ctxt, ret);
5447
0
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5448
0
  (type == XML_SCHEMA_TYPE_CHOICE))
5449
0
  WXS_ADD_PENDING(ctxt, ret);
5450
0
    return (ret);
5451
0
}
5452
5453
5454
/**
5455
 * xmlSchemaAddParticle:
5456
 * @ctxt:  a schema parser context
5457
 * @schema:  the schema being built
5458
 * @node: the corresponding node in the schema doc
5459
 * @min: the minOccurs
5460
 * @max: the maxOccurs
5461
 *
5462
 * Adds an XML schema particle component.
5463
 * *WARNING* this interface is highly subject to change
5464
 *
5465
 * Returns the new structure or NULL in case of error
5466
 */
5467
static xmlSchemaParticlePtr
5468
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5469
         xmlNodePtr node, int min, int max)
5470
0
{
5471
0
    xmlSchemaParticlePtr ret = NULL;
5472
0
    if (ctxt == NULL)
5473
0
        return (NULL);
5474
5475
0
    ret = (xmlSchemaParticlePtr)
5476
0
  xmlMalloc(sizeof(xmlSchemaParticle));
5477
0
    if (ret == NULL) {
5478
0
  xmlSchemaPErrMemory(ctxt);
5479
0
  return (NULL);
5480
0
    }
5481
0
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5482
0
    ret->annot = NULL;
5483
0
    ret->node = node;
5484
0
    ret->minOccurs = min;
5485
0
    ret->maxOccurs = max;
5486
0
    ret->next = NULL;
5487
0
    ret->children = NULL;
5488
5489
0
    WXS_ADD_LOCAL(ctxt, ret);
5490
    /*
5491
    * Note that addition to pending components will be done locally
5492
    * to the specific parsing function, since the most particles
5493
    * need not to be fixed up (i.e. the reference to be resolved).
5494
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5495
    */
5496
0
    return (ret);
5497
0
}
5498
5499
/**
5500
 * xmlSchemaAddModelGroupDefinition:
5501
 * @ctxt:  a schema validation context
5502
 * @schema:  the schema being built
5503
 * @name:  the group name
5504
 *
5505
 * Add an XML schema Group definition
5506
 *
5507
 * Returns the new structure or NULL in case of error
5508
 */
5509
static xmlSchemaModelGroupDefPtr
5510
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5511
         xmlSchemaPtr schema,
5512
         const xmlChar *name,
5513
         const xmlChar *nsName,
5514
         xmlNodePtr node)
5515
0
{
5516
0
    xmlSchemaModelGroupDefPtr ret = NULL;
5517
5518
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5519
0
        return (NULL);
5520
5521
0
    ret = (xmlSchemaModelGroupDefPtr)
5522
0
  xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5523
0
    if (ret == NULL) {
5524
0
        xmlSchemaPErrMemory(ctxt);
5525
0
        return (NULL);
5526
0
    }
5527
0
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5528
0
    ret->name = name;
5529
0
    ret->type = XML_SCHEMA_TYPE_GROUP;
5530
0
    ret->node = node;
5531
0
    ret->targetNamespace = nsName;
5532
5533
0
    if (ctxt->isRedefine) {
5534
0
  ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5535
0
      ret, name, nsName);
5536
0
  if (ctxt->redef == NULL) {
5537
0
      xmlFree(ret);
5538
0
      return(NULL);
5539
0
  }
5540
0
  ctxt->redefCounter = 0;
5541
0
    }
5542
0
    WXS_ADD_GLOBAL(ctxt, ret);
5543
0
    WXS_ADD_PENDING(ctxt, ret);
5544
0
    return (ret);
5545
0
}
5546
5547
/**
5548
 * xmlSchemaNewWildcardNs:
5549
 * @ctxt:  a schema validation context
5550
 *
5551
 * Creates a new wildcard namespace constraint.
5552
 *
5553
 * Returns the new structure or NULL in case of error
5554
 */
5555
static xmlSchemaWildcardNsPtr
5556
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5557
0
{
5558
0
    xmlSchemaWildcardNsPtr ret;
5559
5560
0
    ret = (xmlSchemaWildcardNsPtr)
5561
0
  xmlMalloc(sizeof(xmlSchemaWildcardNs));
5562
0
    if (ret == NULL) {
5563
0
  xmlSchemaPErrMemory(ctxt);
5564
0
  return (NULL);
5565
0
    }
5566
0
    ret->value = NULL;
5567
0
    ret->next = NULL;
5568
0
    return (ret);
5569
0
}
5570
5571
static xmlSchemaIDCPtr
5572
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5573
                  const xmlChar *name, const xmlChar *nsName,
5574
      int category, xmlNodePtr node)
5575
0
{
5576
0
    xmlSchemaIDCPtr ret = NULL;
5577
5578
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5579
0
        return (NULL);
5580
5581
0
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5582
0
    if (ret == NULL) {
5583
0
        xmlSchemaPErrMemory(ctxt);
5584
0
        return (NULL);
5585
0
    }
5586
0
    memset(ret, 0, sizeof(xmlSchemaIDC));
5587
    /* The target namespace of the parent element declaration. */
5588
0
    ret->targetNamespace = nsName;
5589
0
    ret->name = name;
5590
0
    ret->type = category;
5591
0
    ret->node = node;
5592
5593
0
    WXS_ADD_GLOBAL(ctxt, ret);
5594
    /*
5595
    * Only keyrefs need to be fixup up.
5596
    */
5597
0
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5598
0
  WXS_ADD_PENDING(ctxt, ret);
5599
0
    return (ret);
5600
0
}
5601
5602
/**
5603
 * xmlSchemaAddWildcard:
5604
 * @ctxt:  a schema validation context
5605
 * @schema: a schema
5606
 *
5607
 * Adds a wildcard.
5608
 * It corresponds to a xsd:anyAttribute and xsd:any.
5609
 *
5610
 * Returns the new structure or NULL in case of error
5611
 */
5612
static xmlSchemaWildcardPtr
5613
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5614
         xmlSchemaTypeType type, xmlNodePtr node)
5615
0
{
5616
0
    xmlSchemaWildcardPtr ret = NULL;
5617
5618
0
    if ((ctxt == NULL) || (schema == NULL))
5619
0
        return (NULL);
5620
5621
0
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5622
0
    if (ret == NULL) {
5623
0
        xmlSchemaPErrMemory(ctxt);
5624
0
        return (NULL);
5625
0
    }
5626
0
    memset(ret, 0, sizeof(xmlSchemaWildcard));
5627
0
    ret->type = type;
5628
0
    ret->node = node;
5629
0
    WXS_ADD_LOCAL(ctxt, ret);
5630
0
    return (ret);
5631
0
}
5632
5633
static void
5634
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5635
0
{
5636
0
    if (group == NULL)
5637
0
  return;
5638
0
    if (group->members != NULL)
5639
0
  xmlSchemaItemListFree(group->members);
5640
0
    xmlFree(group);
5641
0
}
5642
5643
static void
5644
xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5645
0
{
5646
0
    xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5647
0
}
5648
5649
static xmlSchemaSubstGroupPtr
5650
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5651
           xmlSchemaElementPtr head)
5652
0
{
5653
0
    xmlSchemaSubstGroupPtr ret;
5654
5655
    /* Init subst group hash. */
5656
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5657
0
  WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5658
0
  if (WXS_SUBST_GROUPS(pctxt) == NULL)
5659
0
      return(NULL);
5660
0
    }
5661
    /* Create a new substitution group. */
5662
0
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5663
0
    if (ret == NULL) {
5664
0
  xmlSchemaPErrMemory(NULL);
5665
0
  return(NULL);
5666
0
    }
5667
0
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5668
0
    ret->head = head;
5669
    /* Create list of members. */
5670
0
    ret->members = xmlSchemaItemListCreate();
5671
0
    if (ret->members == NULL) {
5672
0
  xmlSchemaSubstGroupFree(ret);
5673
0
  return(NULL);
5674
0
    }
5675
    /* Add subst group to hash. */
5676
0
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5677
0
  head->name, head->targetNamespace, ret) != 0) {
5678
0
  PERROR_INT("xmlSchemaSubstGroupAdd",
5679
0
      "failed to add a new substitution container");
5680
0
  xmlSchemaSubstGroupFree(ret);
5681
0
  return(NULL);
5682
0
    }
5683
0
    return(ret);
5684
0
}
5685
5686
static xmlSchemaSubstGroupPtr
5687
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5688
           xmlSchemaElementPtr head)
5689
0
{
5690
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5691
0
  return(NULL);
5692
0
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5693
0
  head->name, head->targetNamespace));
5694
5695
0
}
5696
5697
/**
5698
 * xmlSchemaAddElementSubstitutionMember:
5699
 * @pctxt:  a schema parser context
5700
 * @head:  the head of the substitution group
5701
 * @member: the new member of the substitution group
5702
 *
5703
 * Allocate a new annotation structure.
5704
 *
5705
 * Returns the newly allocated structure or NULL in case or error
5706
 */
5707
static int
5708
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5709
              xmlSchemaElementPtr head,
5710
              xmlSchemaElementPtr member)
5711
0
{
5712
0
    xmlSchemaSubstGroupPtr substGroup = NULL;
5713
5714
0
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5715
0
  return (-1);
5716
5717
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5718
0
    if (substGroup == NULL)
5719
0
  substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5720
0
    if (substGroup == NULL)
5721
0
  return(-1);
5722
0
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5723
0
  return(-1);
5724
0
    return(0);
5725
0
}
5726
5727
/************************************************************************
5728
 *                  *
5729
 *    Utilities for parsing         *
5730
 *                  *
5731
 ************************************************************************/
5732
5733
/**
5734
 * xmlSchemaPValAttrNodeQNameValue:
5735
 * @ctxt:  a schema parser context
5736
 * @schema: the schema context
5737
 * @ownerItem: the parent as a schema object
5738
 * @value:  the QName value
5739
 * @uri:  the resulting namespace URI if found
5740
 * @local: the resulting local part if found, the attribute value otherwise
5741
 *
5742
 * Extracts the local name and the URI of a QName value and validates it.
5743
 * This one is intended to be used on attribute values that
5744
 * should resolve to schema components.
5745
 *
5746
 * Returns 0, in case the QName is valid, a positive error code
5747
 * if not valid and -1 if an internal error occurs.
5748
 */
5749
static int
5750
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5751
               xmlSchemaPtr schema,
5752
               xmlSchemaBasicItemPtr ownerItem,
5753
               xmlAttrPtr attr,
5754
               const xmlChar *value,
5755
               const xmlChar **uri,
5756
               const xmlChar **local)
5757
0
{
5758
0
    const xmlChar *pref;
5759
0
    xmlNsPtr ns;
5760
0
    int len, ret;
5761
5762
0
    *uri = NULL;
5763
0
    *local = NULL;
5764
0
    ret = xmlValidateQName(value, 1);
5765
0
    if (ret > 0) {
5766
0
  xmlSchemaPSimpleTypeErr(ctxt,
5767
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5768
0
      ownerItem, (xmlNodePtr) attr,
5769
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5770
0
      NULL, value, NULL, NULL, NULL);
5771
0
  *local = value;
5772
0
  return (ctxt->err);
5773
0
    } else if (ret < 0)
5774
0
  return (-1);
5775
5776
0
    if (!strchr((char *) value, ':')) {
5777
0
  ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5778
0
  if (ns && ns->href && ns->href[0])
5779
0
      *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5780
0
  else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5781
      /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5782
      * parser context. */
5783
      /*
5784
      * This one takes care of included schemas with no
5785
      * target namespace.
5786
      */
5787
0
      *uri = ctxt->targetNamespace;
5788
0
  }
5789
0
  *local = xmlDictLookup(ctxt->dict, value, -1);
5790
0
  return (0);
5791
0
    }
5792
    /*
5793
    * At this point xmlSplitQName3 has to return a local name.
5794
    */
5795
0
    *local = xmlSplitQName3(value, &len);
5796
0
    *local = xmlDictLookup(ctxt->dict, *local, -1);
5797
0
    pref = xmlDictLookup(ctxt->dict, value, len);
5798
0
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5799
0
    if (ns == NULL) {
5800
0
  xmlSchemaPSimpleTypeErr(ctxt,
5801
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5802
0
      ownerItem, (xmlNodePtr) attr,
5803
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5804
0
      "The value '%s' of simple type 'xs:QName' has no "
5805
0
      "corresponding namespace declaration in scope", value, NULL);
5806
0
  return (ctxt->err);
5807
0
    } else {
5808
0
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5809
0
    }
5810
0
    return (0);
5811
0
}
5812
5813
/**
5814
 * xmlSchemaPValAttrNodeQName:
5815
 * @ctxt:  a schema parser context
5816
 * @schema: the schema context
5817
 * @ownerItem: the owner as a schema object
5818
 * @attr:  the attribute node
5819
 * @uri:  the resulting namespace URI if found
5820
 * @local: the resulting local part if found, the attribute value otherwise
5821
 *
5822
 * Extracts and validates the QName of an attribute value.
5823
 * This one is intended to be used on attribute values that
5824
 * should resolve to schema components.
5825
 *
5826
 * Returns 0, in case the QName is valid, a positive error code
5827
 * if not valid and -1 if an internal error occurs.
5828
 */
5829
static int
5830
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5831
               xmlSchemaPtr schema,
5832
               xmlSchemaBasicItemPtr ownerItem,
5833
               xmlAttrPtr attr,
5834
               const xmlChar **uri,
5835
               const xmlChar **local)
5836
0
{
5837
0
    const xmlChar *value;
5838
5839
0
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5840
0
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5841
0
  ownerItem, attr, value, uri, local));
5842
0
}
5843
5844
/**
5845
 * xmlSchemaPValAttrQName:
5846
 * @ctxt:  a schema parser context
5847
 * @schema: the schema context
5848
 * @ownerItem: the owner as a schema object
5849
 * @ownerElem:  the parent node of the attribute
5850
 * @name:  the name of the attribute
5851
 * @uri:  the resulting namespace URI if found
5852
 * @local: the resulting local part if found, the attribute value otherwise
5853
 *
5854
 * Extracts and validates the QName of an attribute value.
5855
 *
5856
 * Returns 0, in case the QName is valid, a positive error code
5857
 * if not valid and -1 if an internal error occurs.
5858
 */
5859
static int
5860
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5861
           xmlSchemaPtr schema,
5862
           xmlSchemaBasicItemPtr ownerItem,
5863
           xmlNodePtr ownerElem,
5864
           const char *name,
5865
           const xmlChar **uri,
5866
           const xmlChar **local)
5867
0
{
5868
0
    xmlAttrPtr attr;
5869
5870
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
5871
0
    if (attr == NULL) {
5872
0
  *local = NULL;
5873
0
  *uri = NULL;
5874
0
  return (0);
5875
0
    }
5876
0
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5877
0
  ownerItem, attr, uri, local));
5878
0
}
5879
5880
/**
5881
 * xmlSchemaPValAttrID:
5882
 * @ctxt:  a schema parser context
5883
 *
5884
 * Extracts and validates the ID of an attribute value.
5885
 *
5886
 * Returns 0, in case the ID is valid, a positive error code
5887
 * if not valid and -1 if an internal error occurs.
5888
 */
5889
static int
5890
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5891
0
{
5892
0
    int ret;
5893
0
    const xmlChar *value;
5894
5895
0
    if (attr == NULL)
5896
0
  return(0);
5897
0
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5898
0
    ret = xmlValidateNCName(value, 1);
5899
0
    if (ret == 0) {
5900
  /*
5901
  * NOTE: the IDness might have already be declared in the DTD
5902
  */
5903
0
  if (attr->atype != XML_ATTRIBUTE_ID) {
5904
0
      xmlChar *strip;
5905
0
            int res;
5906
5907
      /*
5908
      * TODO: Use xmlSchemaStrip here; it's not exported at this
5909
      * moment.
5910
      */
5911
0
      strip = xmlSchemaCollapseString(value);
5912
0
      if (strip != NULL) {
5913
0
    xmlFree((xmlChar *) value);
5914
0
    value = strip;
5915
0
      }
5916
0
      res = xmlAddIDSafe(attr, value);
5917
0
            if (res < 0) {
5918
0
                xmlSchemaPErrMemory(ctxt);
5919
0
      } else if (res == 0) {
5920
0
    ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5921
0
    xmlSchemaPSimpleTypeErr(ctxt,
5922
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5923
0
        NULL, (xmlNodePtr) attr,
5924
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5925
0
        NULL, NULL, "Duplicate value '%s' of simple "
5926
0
        "type 'xs:ID'", value, NULL);
5927
0
      }
5928
0
  }
5929
0
    } else if (ret > 0) {
5930
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5931
0
  xmlSchemaPSimpleTypeErr(ctxt,
5932
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5933
0
      NULL, (xmlNodePtr) attr,
5934
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5935
0
      NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
5936
0
      "not a valid 'xs:NCName'",
5937
0
      value, NULL);
5938
0
    }
5939
0
    if (value != NULL)
5940
0
  xmlFree((xmlChar *)value);
5941
5942
0
    return (ret);
5943
0
}
5944
5945
static int
5946
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5947
        xmlNodePtr ownerElem,
5948
        const xmlChar *name)
5949
0
{
5950
0
    xmlAttrPtr attr;
5951
5952
0
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5953
0
    if (attr == NULL)
5954
0
  return(0);
5955
0
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
5956
5957
0
}
5958
5959
/**
5960
 * xmlGetMaxOccurs:
5961
 * @ctxt:  a schema validation context
5962
 * @node:  a subtree containing XML Schema information
5963
 *
5964
 * Get the maxOccurs property
5965
 *
5966
 * Returns the default if not found, or the value
5967
 */
5968
static int
5969
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5970
    int min, int max, int def, const char *expected)
5971
0
{
5972
0
    const xmlChar *val, *cur;
5973
0
    int ret = 0;
5974
0
    xmlAttrPtr attr;
5975
5976
0
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
5977
0
    if (attr == NULL)
5978
0
  return (def);
5979
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5980
0
    if (val == NULL)
5981
0
        return (def);
5982
5983
0
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
5984
0
  if (max != UNBOUNDED) {
5985
0
      xmlSchemaPSimpleTypeErr(ctxt,
5986
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5987
    /* XML_SCHEMAP_INVALID_MINOCCURS, */
5988
0
    NULL, (xmlNodePtr) attr, NULL, expected,
5989
0
    val, NULL, NULL, NULL);
5990
0
      return (def);
5991
0
  } else
5992
0
      return (UNBOUNDED);  /* encoding it with -1 might be another option */
5993
0
    }
5994
5995
0
    cur = val;
5996
0
    while (IS_BLANK_CH(*cur))
5997
0
        cur++;
5998
0
    if (*cur == 0) {
5999
0
        xmlSchemaPSimpleTypeErr(ctxt,
6000
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6001
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6002
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6003
0
      val, NULL, NULL, NULL);
6004
0
  return (def);
6005
0
    }
6006
0
    while ((*cur >= '0') && (*cur <= '9')) {
6007
0
        if (ret > INT_MAX / 10) {
6008
0
            ret = INT_MAX;
6009
0
        } else {
6010
0
            int digit = *cur - '0';
6011
0
            ret *= 10;
6012
0
            if (ret > INT_MAX - digit)
6013
0
                ret = INT_MAX;
6014
0
            else
6015
0
                ret += digit;
6016
0
        }
6017
0
        cur++;
6018
0
    }
6019
0
    while (IS_BLANK_CH(*cur))
6020
0
        cur++;
6021
    /*
6022
    * TODO: Restrict the maximal value to Integer.
6023
    */
6024
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6025
0
  xmlSchemaPSimpleTypeErr(ctxt,
6026
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6027
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6028
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6029
0
      val, NULL, NULL, NULL);
6030
0
        return (def);
6031
0
    }
6032
0
    return (ret);
6033
0
}
6034
6035
/**
6036
 * xmlGetMinOccurs:
6037
 * @ctxt:  a schema validation context
6038
 * @node:  a subtree containing XML Schema information
6039
 *
6040
 * Get the minOccurs property
6041
 *
6042
 * Returns the default if not found, or the value
6043
 */
6044
static int
6045
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6046
    int min, int max, int def, const char *expected)
6047
0
{
6048
0
    const xmlChar *val, *cur;
6049
0
    int ret = 0;
6050
0
    xmlAttrPtr attr;
6051
6052
0
    attr = xmlSchemaGetPropNode(node, "minOccurs");
6053
0
    if (attr == NULL)
6054
0
  return (def);
6055
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6056
0
    if (val == NULL)
6057
0
  return (def);
6058
0
    cur = val;
6059
0
    while (IS_BLANK_CH(*cur))
6060
0
        cur++;
6061
0
    if (*cur == 0) {
6062
0
        xmlSchemaPSimpleTypeErr(ctxt,
6063
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6064
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6065
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6066
0
      val, NULL, NULL, NULL);
6067
0
        return (def);
6068
0
    }
6069
0
    while ((*cur >= '0') && (*cur <= '9')) {
6070
0
        if (ret > INT_MAX / 10) {
6071
0
            ret = INT_MAX;
6072
0
        } else {
6073
0
            int digit = *cur - '0';
6074
0
            ret *= 10;
6075
0
            if (ret > INT_MAX - digit)
6076
0
                ret = INT_MAX;
6077
0
            else
6078
0
                ret += digit;
6079
0
        }
6080
0
        cur++;
6081
0
    }
6082
0
    while (IS_BLANK_CH(*cur))
6083
0
        cur++;
6084
    /*
6085
    * TODO: Restrict the maximal value to Integer.
6086
    */
6087
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6088
0
  xmlSchemaPSimpleTypeErr(ctxt,
6089
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6090
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6091
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6092
0
      val, NULL, NULL, NULL);
6093
0
        return (def);
6094
0
    }
6095
0
    return (ret);
6096
0
}
6097
6098
/**
6099
 * xmlSchemaPGetBoolNodeValue:
6100
 * @ctxt:  a schema validation context
6101
 * @ownerItem:  the owner as a schema item
6102
 * @node: the node holding the value
6103
 *
6104
 * Converts a boolean string value into 1 or 0.
6105
 *
6106
 * Returns 0 or 1.
6107
 */
6108
static int
6109
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6110
         xmlSchemaBasicItemPtr ownerItem,
6111
         xmlNodePtr node)
6112
0
{
6113
0
    xmlChar *value = NULL;
6114
0
    int res = 0;
6115
6116
0
    value = xmlNodeGetContent(node);
6117
    /*
6118
    * 3.2.2.1 Lexical representation
6119
    * An instance of a datatype that is defined as `boolean`
6120
    * can have the following legal literals {true, false, 1, 0}.
6121
    */
6122
0
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6123
0
        res = 1;
6124
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6125
0
        res = 0;
6126
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6127
0
  res = 1;
6128
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6129
0
        res = 0;
6130
0
    else {
6131
0
        xmlSchemaPSimpleTypeErr(ctxt,
6132
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6133
0
      ownerItem, node,
6134
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6135
0
      NULL, BAD_CAST value,
6136
0
      NULL, NULL, NULL);
6137
0
    }
6138
0
    if (value != NULL)
6139
0
  xmlFree(value);
6140
0
    return (res);
6141
0
}
6142
6143
/**
6144
 * xmlGetBooleanProp:
6145
 * @ctxt:  a schema validation context
6146
 * @node:  a subtree containing XML Schema information
6147
 * @name:  the attribute name
6148
 * @def:  the default value
6149
 *
6150
 * Evaluate if a boolean property is set
6151
 *
6152
 * Returns the default if not found, 0 if found to be false,
6153
 * 1 if found to be true
6154
 */
6155
static int
6156
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6157
      xmlNodePtr node,
6158
                  const char *name, int def)
6159
0
{
6160
0
    const xmlChar *val;
6161
6162
0
    val = xmlSchemaGetProp(ctxt, node, name);
6163
0
    if (val == NULL)
6164
0
        return (def);
6165
    /*
6166
    * 3.2.2.1 Lexical representation
6167
    * An instance of a datatype that is defined as `boolean`
6168
    * can have the following legal literals {true, false, 1, 0}.
6169
    */
6170
0
    if (xmlStrEqual(val, BAD_CAST "true"))
6171
0
        def = 1;
6172
0
    else if (xmlStrEqual(val, BAD_CAST "false"))
6173
0
        def = 0;
6174
0
    else if (xmlStrEqual(val, BAD_CAST "1"))
6175
0
  def = 1;
6176
0
    else if (xmlStrEqual(val, BAD_CAST "0"))
6177
0
        def = 0;
6178
0
    else {
6179
0
        xmlSchemaPSimpleTypeErr(ctxt,
6180
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6181
0
      NULL,
6182
0
      (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6183
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6184
0
      NULL, val, NULL, NULL, NULL);
6185
0
    }
6186
0
    return (def);
6187
0
}
6188
6189
/************************************************************************
6190
 *                  *
6191
 *    Schema extraction from an Infoset     *
6192
 *                  *
6193
 ************************************************************************/
6194
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6195
                                                 ctxt, xmlSchemaPtr schema,
6196
                                                 xmlNodePtr node,
6197
             int topLevel);
6198
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6199
                                                  ctxt,
6200
                                                  xmlSchemaPtr schema,
6201
                                                  xmlNodePtr node,
6202
              int topLevel);
6203
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6204
                                                  ctxt,
6205
                                                  xmlSchemaPtr schema,
6206
                                                  xmlNodePtr node,
6207
              xmlSchemaTypeType parentType);
6208
static xmlSchemaBasicItemPtr
6209
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6210
           xmlSchemaPtr schema,
6211
           xmlNodePtr node,
6212
           xmlSchemaItemListPtr uses,
6213
           int parentType);
6214
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6215
                                           xmlSchemaPtr schema,
6216
                                           xmlNodePtr node);
6217
static xmlSchemaWildcardPtr
6218
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6219
                           xmlSchemaPtr schema, xmlNodePtr node);
6220
6221
/**
6222
 * xmlSchemaPValAttrNodeValue:
6223
 *
6224
 * @pctxt:  a schema parser context
6225
 * @ownerItem: the schema object owner if existent
6226
 * @attr:  the schema attribute node being validated
6227
 * @value: the value
6228
 * @type: the built-in type to be validated against
6229
 *
6230
 * Validates a value against the given built-in type.
6231
 * This one is intended to be used internally for validation
6232
 * of schema attribute values during parsing of the schema.
6233
 *
6234
 * Returns 0 if the value is valid, a positive error code
6235
 * number otherwise and -1 in case of an internal or API error.
6236
 */
6237
static int
6238
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6239
         xmlSchemaBasicItemPtr ownerItem,
6240
         xmlAttrPtr attr,
6241
         const xmlChar *value,
6242
         xmlSchemaTypePtr type)
6243
0
{
6244
6245
0
    int ret = 0;
6246
6247
    /*
6248
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6249
    * one is really meant to be used internally, so better not.
6250
    */
6251
0
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6252
0
  return (-1);
6253
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6254
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6255
0
      "the given type is not a built-in type");
6256
0
  return (-1);
6257
0
    }
6258
0
    switch (type->builtInType) {
6259
0
  case XML_SCHEMAS_NCNAME:
6260
0
  case XML_SCHEMAS_QNAME:
6261
0
  case XML_SCHEMAS_ANYURI:
6262
0
  case XML_SCHEMAS_TOKEN:
6263
0
  case XML_SCHEMAS_LANGUAGE:
6264
0
      ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6265
0
    (xmlNodePtr) attr);
6266
0
      break;
6267
0
  default: {
6268
0
      PERROR_INT("xmlSchemaPValAttrNodeValue",
6269
0
    "validation using the given type is not supported while "
6270
0
    "parsing a schema");
6271
0
      return (-1);
6272
0
  }
6273
0
    }
6274
    /*
6275
    * TODO: Should we use the S4S error codes instead?
6276
    */
6277
0
    if (ret < 0) {
6278
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6279
0
      "failed to validate a schema attribute value");
6280
0
  return (-1);
6281
0
    } else if (ret > 0) {
6282
0
  if (WXS_IS_LIST(type))
6283
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6284
0
  else
6285
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6286
0
  xmlSchemaPSimpleTypeErr(pctxt,
6287
0
      ret, ownerItem, (xmlNodePtr) attr,
6288
0
      type, NULL, value, NULL, NULL, NULL);
6289
0
    }
6290
0
    return (ret);
6291
0
}
6292
6293
/**
6294
 * xmlSchemaPValAttrNode:
6295
 *
6296
 * @ctxt:  a schema parser context
6297
 * @ownerItem: the schema object owner if existent
6298
 * @attr:  the schema attribute node being validated
6299
 * @type: the built-in type to be validated against
6300
 * @value: the resulting value if any
6301
 *
6302
 * Extracts and validates a value against the given built-in type.
6303
 * This one is intended to be used internally for validation
6304
 * of schema attribute values during parsing of the schema.
6305
 *
6306
 * Returns 0 if the value is valid, a positive error code
6307
 * number otherwise and -1 in case of an internal or API error.
6308
 */
6309
static int
6310
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6311
         xmlSchemaBasicItemPtr ownerItem,
6312
         xmlAttrPtr attr,
6313
         xmlSchemaTypePtr type,
6314
         const xmlChar **value)
6315
0
{
6316
0
    const xmlChar *val;
6317
6318
0
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6319
0
  return (-1);
6320
6321
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6322
0
    if (value != NULL)
6323
0
  *value = val;
6324
6325
0
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6326
0
  val, type));
6327
0
}
6328
6329
/**
6330
 * xmlSchemaPValAttr:
6331
 *
6332
 * @ctxt:  a schema parser context
6333
 * @node: the element node of the attribute
6334
 * @ownerItem: the schema object owner if existent
6335
 * @ownerElem: the owner element node
6336
 * @name:  the name of the schema attribute node
6337
 * @type: the built-in type to be validated against
6338
 * @value: the resulting value if any
6339
 *
6340
 * Extracts and validates a value against the given built-in type.
6341
 * This one is intended to be used internally for validation
6342
 * of schema attribute values during parsing of the schema.
6343
 *
6344
 * Returns 0 if the value is valid, a positive error code
6345
 * number otherwise and -1 in case of an internal or API error.
6346
 */
6347
static int
6348
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6349
           xmlSchemaBasicItemPtr ownerItem,
6350
           xmlNodePtr ownerElem,
6351
           const char *name,
6352
           xmlSchemaTypePtr type,
6353
           const xmlChar **value)
6354
0
{
6355
0
    xmlAttrPtr attr;
6356
6357
0
    if ((ctxt == NULL) || (type == NULL)) {
6358
0
  if (value != NULL)
6359
0
      *value = NULL;
6360
0
  return (-1);
6361
0
    }
6362
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6363
0
  if (value != NULL)
6364
0
      *value = NULL;
6365
0
  xmlSchemaPErr(ctxt, ownerElem,
6366
0
      XML_SCHEMAP_INTERNAL,
6367
0
      "Internal error: xmlSchemaPValAttr, the given "
6368
0
      "type '%s' is not a built-in type.\n",
6369
0
      type->name, NULL);
6370
0
  return (-1);
6371
0
    }
6372
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
6373
0
    if (attr == NULL) {
6374
0
  if (value != NULL)
6375
0
      *value = NULL;
6376
0
  return (0);
6377
0
    }
6378
0
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6379
0
  type, value));
6380
0
}
6381
6382
static int
6383
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6384
      xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6385
      xmlNodePtr node,
6386
      xmlAttrPtr attr,
6387
      const xmlChar *namespaceName)
6388
0
{
6389
    /* TODO: Pointer comparison instead? */
6390
0
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6391
0
  return (0);
6392
0
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
6393
0
  return (0);
6394
    /*
6395
    * Check if the referenced namespace was <import>ed.
6396
    */
6397
0
    if (WXS_BUCKET(pctxt)->relations != NULL) {
6398
0
  xmlSchemaSchemaRelationPtr rel;
6399
6400
0
  rel = WXS_BUCKET(pctxt)->relations;
6401
0
  do {
6402
0
      if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6403
0
    xmlStrEqual(namespaceName, rel->importNamespace))
6404
0
    return (0);
6405
0
      rel = rel->next;
6406
0
  } while (rel != NULL);
6407
0
    }
6408
    /*
6409
    * No matching <import>ed namespace found.
6410
    */
6411
0
    {
6412
0
  xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6413
6414
0
  if (namespaceName == NULL)
6415
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6416
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6417
0
    "References from this schema to components in no "
6418
0
    "namespace are not allowed, since not indicated by an "
6419
0
    "import statement", NULL, NULL);
6420
0
  else
6421
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6422
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6423
0
    "References from this schema to components in the "
6424
0
    "namespace '%s' are not allowed, since not indicated by an "
6425
0
    "import statement", namespaceName, NULL);
6426
0
    }
6427
0
    return (XML_SCHEMAP_SRC_RESOLVE);
6428
0
}
6429
6430
/**
6431
 * xmlSchemaParseLocalAttributes:
6432
 * @ctxt:  a schema validation context
6433
 * @schema:  the schema being built
6434
 * @node:  a subtree containing XML Schema information
6435
 * @type:  the hosting type where the attributes will be anchored
6436
 *
6437
 * Parses attribute uses and attribute declarations and
6438
 * attribute group references.
6439
 */
6440
static int
6441
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6442
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
6443
      int parentType, int *hasRefs)
6444
0
{
6445
0
    void *item;
6446
6447
0
    while ((IS_SCHEMA((*child), "attribute")) ||
6448
0
           (IS_SCHEMA((*child), "attributeGroup"))) {
6449
0
        if (IS_SCHEMA((*child), "attribute")) {
6450
0
      item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6451
0
    *list, parentType);
6452
0
        } else {
6453
0
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6454
0
      if ((item != NULL) && (hasRefs != NULL))
6455
0
    *hasRefs = 1;
6456
0
        }
6457
0
  if (item != NULL) {
6458
0
      if (*list == NULL) {
6459
    /* TODO: Customize grow factor. */
6460
0
    *list = xmlSchemaItemListCreate();
6461
0
    if (*list == NULL)
6462
0
        return(-1);
6463
0
      }
6464
0
      if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6465
0
    return(-1);
6466
0
  }
6467
0
        *child = (*child)->next;
6468
0
    }
6469
0
    return (0);
6470
0
}
6471
6472
/**
6473
 * xmlSchemaParseAnnotation:
6474
 * @ctxt:  a schema validation context
6475
 * @schema:  the schema being built
6476
 * @node:  a subtree containing XML Schema information
6477
 *
6478
 * parse a XML schema Attribute declaration
6479
 * *WARNING* this interface is highly subject to change
6480
 *
6481
 * Returns -1 in case of error, 0 if the declaration is improper and
6482
 *         1 in case of success.
6483
 */
6484
static xmlSchemaAnnotPtr
6485
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6486
0
{
6487
0
    xmlSchemaAnnotPtr ret;
6488
0
    xmlNodePtr child = NULL;
6489
0
    xmlAttrPtr attr;
6490
0
    int barked = 0;
6491
6492
    /*
6493
    * INFO: S4S completed.
6494
    */
6495
    /*
6496
    * id = ID
6497
    * {any attributes with non-schema namespace . . .}>
6498
    * Content: (appinfo | documentation)*
6499
    */
6500
0
    if ((ctxt == NULL) || (node == NULL))
6501
0
        return (NULL);
6502
0
    if (needed)
6503
0
  ret = xmlSchemaNewAnnot(ctxt, node);
6504
0
    else
6505
0
  ret = NULL;
6506
0
    attr = node->properties;
6507
0
    while (attr != NULL) {
6508
0
  if (((attr->ns == NULL) &&
6509
0
      (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6510
0
      ((attr->ns != NULL) &&
6511
0
      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6512
6513
0
      xmlSchemaPIllegalAttrErr(ctxt,
6514
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6515
0
  }
6516
0
  attr = attr->next;
6517
0
    }
6518
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6519
    /*
6520
    * And now for the children...
6521
    */
6522
0
    child = node->children;
6523
0
    while (child != NULL) {
6524
0
  if (IS_SCHEMA(child, "appinfo")) {
6525
      /* TODO: make available the content of "appinfo". */
6526
      /*
6527
      * source = anyURI
6528
      * {any attributes with non-schema namespace . . .}>
6529
      * Content: ({any})*
6530
      */
6531
0
      attr = child->properties;
6532
0
      while (attr != NULL) {
6533
0
    if (((attr->ns == NULL) &&
6534
0
         (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6535
0
         ((attr->ns != NULL) &&
6536
0
          xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6537
6538
0
        xmlSchemaPIllegalAttrErr(ctxt,
6539
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6540
0
    }
6541
0
    attr = attr->next;
6542
0
      }
6543
0
      xmlSchemaPValAttr(ctxt, NULL, child, "source",
6544
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6545
0
      child = child->next;
6546
0
  } else if (IS_SCHEMA(child, "documentation")) {
6547
      /* TODO: make available the content of "documentation". */
6548
      /*
6549
      * source = anyURI
6550
      * {any attributes with non-schema namespace . . .}>
6551
      * Content: ({any})*
6552
      */
6553
0
      attr = child->properties;
6554
0
      while (attr != NULL) {
6555
0
    if (attr->ns == NULL) {
6556
0
        if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6557
0
      xmlSchemaPIllegalAttrErr(ctxt,
6558
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6559
0
        }
6560
0
    } else {
6561
0
        if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6562
0
      (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6563
0
      (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6564
6565
0
      xmlSchemaPIllegalAttrErr(ctxt,
6566
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6567
0
        }
6568
0
    }
6569
0
    attr = attr->next;
6570
0
      }
6571
      /*
6572
      * Attribute "xml:lang".
6573
      */
6574
0
      attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6575
0
      if (attr != NULL)
6576
0
    xmlSchemaPValAttrNode(ctxt, NULL, attr,
6577
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6578
0
      child = child->next;
6579
0
  } else {
6580
0
      if (!barked)
6581
0
    xmlSchemaPContentErr(ctxt,
6582
0
        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6583
0
        NULL, node, child, NULL, "(appinfo | documentation)*");
6584
0
      barked = 1;
6585
0
      child = child->next;
6586
0
  }
6587
0
    }
6588
6589
0
    return (ret);
6590
0
}
6591
6592
/**
6593
 * xmlSchemaParseFacet:
6594
 * @ctxt:  a schema validation context
6595
 * @schema:  the schema being built
6596
 * @node:  a subtree containing XML Schema information
6597
 *
6598
 * parse a XML schema Facet declaration
6599
 * *WARNING* this interface is highly subject to change
6600
 *
6601
 * Returns the new type structure or NULL in case of error
6602
 */
6603
static xmlSchemaFacetPtr
6604
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6605
                    xmlNodePtr node)
6606
0
{
6607
0
    xmlSchemaFacetPtr facet;
6608
0
    xmlNodePtr child = NULL;
6609
0
    const xmlChar *value;
6610
6611
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6612
0
        return (NULL);
6613
6614
0
    facet = xmlSchemaNewFacet();
6615
0
    if (facet == NULL) {
6616
0
        xmlSchemaPErrMemory(ctxt);
6617
0
        return (NULL);
6618
0
    }
6619
0
    facet->node = node;
6620
0
    value = xmlSchemaGetProp(ctxt, node, "value");
6621
0
    if (value == NULL) {
6622
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6623
0
                       "Facet %s has no value\n", node->name, NULL);
6624
0
        xmlSchemaFreeFacet(facet);
6625
0
        return (NULL);
6626
0
    }
6627
0
    if (IS_SCHEMA(node, "minInclusive")) {
6628
0
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6629
0
    } else if (IS_SCHEMA(node, "minExclusive")) {
6630
0
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6631
0
    } else if (IS_SCHEMA(node, "maxInclusive")) {
6632
0
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6633
0
    } else if (IS_SCHEMA(node, "maxExclusive")) {
6634
0
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6635
0
    } else if (IS_SCHEMA(node, "totalDigits")) {
6636
0
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6637
0
    } else if (IS_SCHEMA(node, "fractionDigits")) {
6638
0
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6639
0
    } else if (IS_SCHEMA(node, "pattern")) {
6640
0
        facet->type = XML_SCHEMA_FACET_PATTERN;
6641
0
    } else if (IS_SCHEMA(node, "enumeration")) {
6642
0
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
6643
0
    } else if (IS_SCHEMA(node, "whiteSpace")) {
6644
0
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
6645
0
    } else if (IS_SCHEMA(node, "length")) {
6646
0
        facet->type = XML_SCHEMA_FACET_LENGTH;
6647
0
    } else if (IS_SCHEMA(node, "maxLength")) {
6648
0
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6649
0
    } else if (IS_SCHEMA(node, "minLength")) {
6650
0
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
6651
0
    } else {
6652
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6653
0
                       "Unknown facet type %s\n", node->name, NULL);
6654
0
        xmlSchemaFreeFacet(facet);
6655
0
        return (NULL);
6656
0
    }
6657
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6658
0
    facet->value = value;
6659
0
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6660
0
  (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6661
0
  const xmlChar *fixed;
6662
6663
0
  fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6664
0
  if (fixed != NULL) {
6665
0
      if (xmlStrEqual(fixed, BAD_CAST "true"))
6666
0
    facet->fixed = 1;
6667
0
  }
6668
0
    }
6669
0
    child = node->children;
6670
6671
0
    if (IS_SCHEMA(child, "annotation")) {
6672
0
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6673
0
        child = child->next;
6674
0
    }
6675
0
    if (child != NULL) {
6676
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6677
0
                       "Facet %s has unexpected child content\n",
6678
0
                       node->name, NULL);
6679
0
    }
6680
0
    return (facet);
6681
0
}
6682
6683
/**
6684
 * xmlSchemaParseWildcardNs:
6685
 * @ctxt:  a schema parser context
6686
 * @wildc:  the wildcard, already created
6687
 * @node:  a subtree containing XML Schema information
6688
 *
6689
 * Parses the attribute "processContents" and "namespace"
6690
 * of a xsd:anyAttribute and xsd:any.
6691
 * *WARNING* this interface is highly subject to change
6692
 *
6693
 * Returns 0 if everything goes fine, a positive error code
6694
 * if something is not valid and -1 if an internal error occurs.
6695
 */
6696
static int
6697
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6698
       xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6699
       xmlSchemaWildcardPtr wildc,
6700
       xmlNodePtr node)
6701
0
{
6702
0
    const xmlChar *pc, *ns, *dictnsItem;
6703
0
    int ret = 0;
6704
0
    xmlChar *nsItem;
6705
0
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6706
0
    xmlAttrPtr attr;
6707
6708
0
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
6709
0
    if ((pc == NULL)
6710
0
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6711
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6712
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6713
0
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6714
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6715
0
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
6716
0
    } else {
6717
0
        xmlSchemaPSimpleTypeErr(ctxt,
6718
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6719
0
      NULL, node,
6720
0
      NULL, "(strict | skip | lax)", pc,
6721
0
      NULL, NULL, NULL);
6722
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6723
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6724
0
    }
6725
    /*
6726
     * Build the namespace constraints.
6727
     */
6728
0
    attr = xmlSchemaGetPropNode(node, "namespace");
6729
0
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6730
0
    if (ns == NULL)
6731
0
        return (-1);
6732
0
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6733
0
  wildc->any = 1;
6734
0
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6735
0
  wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6736
0
  if (wildc->negNsSet == NULL) {
6737
0
      return (-1);
6738
0
  }
6739
0
  wildc->negNsSet->value = ctxt->targetNamespace;
6740
0
    } else {
6741
0
  const xmlChar *end, *cur;
6742
6743
0
  cur = ns;
6744
0
  do {
6745
0
      while (IS_BLANK_CH(*cur))
6746
0
    cur++;
6747
0
      end = cur;
6748
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6749
0
    end++;
6750
0
      if (end == cur)
6751
0
    break;
6752
0
      nsItem = xmlStrndup(cur, end - cur);
6753
0
      if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6754
0
        (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6755
0
    xmlSchemaPSimpleTypeErr(ctxt,
6756
0
        XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6757
0
        NULL, (xmlNodePtr) attr,
6758
0
        NULL,
6759
0
        "((##any | ##other) | List of (xs:anyURI | "
6760
0
        "(##targetNamespace | ##local)))",
6761
0
        nsItem, NULL, NULL, NULL);
6762
0
    ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6763
0
      } else {
6764
0
    if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6765
0
        dictnsItem = ctxt->targetNamespace;
6766
0
    } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6767
0
        dictnsItem = NULL;
6768
0
    } else {
6769
        /*
6770
        * Validate the item (anyURI).
6771
        */
6772
0
        xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6773
0
      nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6774
0
        dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6775
0
    }
6776
    /*
6777
    * Avoid duplicate namespaces.
6778
    */
6779
0
    tmp = wildc->nsSet;
6780
0
    while (tmp != NULL) {
6781
0
        if (dictnsItem == tmp->value)
6782
0
      break;
6783
0
        tmp = tmp->next;
6784
0
    }
6785
0
    if (tmp == NULL) {
6786
0
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6787
0
        if (tmp == NULL) {
6788
0
      xmlFree(nsItem);
6789
0
      return (-1);
6790
0
        }
6791
0
        tmp->value = dictnsItem;
6792
0
        tmp->next = NULL;
6793
0
        if (wildc->nsSet == NULL)
6794
0
      wildc->nsSet = tmp;
6795
0
        else if (lastNs != NULL)
6796
0
      lastNs->next = tmp;
6797
0
        lastNs = tmp;
6798
0
    }
6799
6800
0
      }
6801
0
      xmlFree(nsItem);
6802
0
      cur = end;
6803
0
  } while (*cur != 0);
6804
0
    }
6805
0
    return (ret);
6806
0
}
6807
6808
static int
6809
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6810
         xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6811
         xmlNodePtr node,
6812
         int minOccurs,
6813
0
         int maxOccurs) {
6814
6815
0
    if ((maxOccurs == 0) && ( minOccurs == 0))
6816
0
  return (0);
6817
0
    if (maxOccurs != UNBOUNDED) {
6818
  /*
6819
  * TODO: Maybe we should better not create the particle,
6820
  * if min/max is invalid, since it could confuse the build of the
6821
  * content model.
6822
  */
6823
  /*
6824
  * 3.9.6 Schema Component Constraint: Particle Correct
6825
  *
6826
  */
6827
0
  if (maxOccurs < 1) {
6828
      /*
6829
      * 2.2 {max occurs} must be greater than or equal to 1.
6830
      */
6831
0
      xmlSchemaPCustomAttrErr(ctxt,
6832
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6833
0
    NULL, NULL,
6834
0
    xmlSchemaGetPropNode(node, "maxOccurs"),
6835
0
    "The value must be greater than or equal to 1");
6836
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6837
0
  } else if (minOccurs > maxOccurs) {
6838
      /*
6839
      * 2.1 {min occurs} must not be greater than {max occurs}.
6840
      */
6841
0
      xmlSchemaPCustomAttrErr(ctxt,
6842
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6843
0
    NULL, NULL,
6844
0
    xmlSchemaGetPropNode(node, "minOccurs"),
6845
0
    "The value must not be greater than the value of 'maxOccurs'");
6846
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6847
0
  }
6848
0
    }
6849
0
    return (0);
6850
0
}
6851
6852
/**
6853
 * xmlSchemaParseAny:
6854
 * @ctxt:  a schema validation context
6855
 * @schema:  the schema being built
6856
 * @node:  a subtree containing XML Schema information
6857
 *
6858
 * Parsea a XML schema <any> element. A particle and wildcard
6859
 * will be created (except if minOccurs==maxOccurs==0, in this case
6860
 * nothing will be created).
6861
 * *WARNING* this interface is highly subject to change
6862
 *
6863
 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6864
 */
6865
static xmlSchemaParticlePtr
6866
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6867
                  xmlNodePtr node)
6868
0
{
6869
0
    xmlSchemaParticlePtr particle;
6870
0
    xmlNodePtr child = NULL;
6871
0
    xmlSchemaWildcardPtr wild;
6872
0
    int min, max;
6873
0
    xmlAttrPtr attr;
6874
0
    xmlSchemaAnnotPtr annot = NULL;
6875
6876
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6877
0
        return (NULL);
6878
    /*
6879
    * Check for illegal attributes.
6880
    */
6881
0
    attr = node->properties;
6882
0
    while (attr != NULL) {
6883
0
  if (attr->ns == NULL) {
6884
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6885
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
6886
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
6887
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6888
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6889
0
    xmlSchemaPIllegalAttrErr(ctxt,
6890
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6891
0
      }
6892
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6893
0
      xmlSchemaPIllegalAttrErr(ctxt,
6894
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6895
0
  }
6896
0
  attr = attr->next;
6897
0
    }
6898
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6899
    /*
6900
    * minOccurs/maxOccurs.
6901
    */
6902
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
6903
0
  "(xs:nonNegativeInteger | unbounded)");
6904
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
6905
0
  "xs:nonNegativeInteger");
6906
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
6907
    /*
6908
    * Create & parse the wildcard.
6909
    */
6910
0
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6911
0
    if (wild == NULL)
6912
0
  return (NULL);
6913
0
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6914
    /*
6915
    * And now for the children...
6916
    */
6917
0
    child = node->children;
6918
0
    if (IS_SCHEMA(child, "annotation")) {
6919
0
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6920
0
        child = child->next;
6921
0
    }
6922
0
    if (child != NULL) {
6923
0
  xmlSchemaPContentErr(ctxt,
6924
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6925
0
      NULL, node, child,
6926
0
      NULL, "(annotation?)");
6927
0
    }
6928
    /*
6929
    * No component if minOccurs==maxOccurs==0.
6930
    */
6931
0
    if ((min == 0) && (max == 0)) {
6932
  /* Don't free the wildcard, since it's already on the list. */
6933
0
  return (NULL);
6934
0
    }
6935
    /*
6936
    * Create the particle.
6937
    */
6938
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
6939
0
    if (particle == NULL)
6940
0
        return (NULL);
6941
0
    particle->annot = annot;
6942
0
    particle->children = (xmlSchemaTreeItemPtr) wild;
6943
6944
0
    return (particle);
6945
0
}
6946
6947
/**
6948
 * xmlSchemaParseNotation:
6949
 * @ctxt:  a schema validation context
6950
 * @schema:  the schema being built
6951
 * @node:  a subtree containing XML Schema information
6952
 *
6953
 * parse a XML schema Notation declaration
6954
 *
6955
 * Returns the new structure or NULL in case of error
6956
 */
6957
static xmlSchemaNotationPtr
6958
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6959
                       xmlNodePtr node)
6960
0
{
6961
0
    const xmlChar *name;
6962
0
    xmlSchemaNotationPtr ret;
6963
0
    xmlNodePtr child = NULL;
6964
6965
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6966
0
        return (NULL);
6967
0
    name = xmlSchemaGetProp(ctxt, node, "name");
6968
0
    if (name == NULL) {
6969
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6970
0
                       "Notation has no name\n", NULL, NULL);
6971
0
        return (NULL);
6972
0
    }
6973
0
    ret = xmlSchemaAddNotation(ctxt, schema, name,
6974
0
  ctxt->targetNamespace, node);
6975
0
    if (ret == NULL)
6976
0
        return (NULL);
6977
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6978
6979
0
    child = node->children;
6980
0
    if (IS_SCHEMA(child, "annotation")) {
6981
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6982
0
        child = child->next;
6983
0
    }
6984
0
    if (child != NULL) {
6985
0
  xmlSchemaPContentErr(ctxt,
6986
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6987
0
      NULL, node, child,
6988
0
      NULL, "(annotation?)");
6989
0
    }
6990
6991
0
    return (ret);
6992
0
}
6993
6994
/**
6995
 * xmlSchemaParseAnyAttribute:
6996
 * @ctxt:  a schema validation context
6997
 * @schema:  the schema being built
6998
 * @node:  a subtree containing XML Schema information
6999
 *
7000
 * parse a XML schema AnyAttribute declaration
7001
 * *WARNING* this interface is highly subject to change
7002
 *
7003
 * Returns a wildcard or NULL.
7004
 */
7005
static xmlSchemaWildcardPtr
7006
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7007
                           xmlSchemaPtr schema, xmlNodePtr node)
7008
0
{
7009
0
    xmlSchemaWildcardPtr ret;
7010
0
    xmlNodePtr child = NULL;
7011
0
    xmlAttrPtr attr;
7012
7013
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7014
0
        return (NULL);
7015
7016
0
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7017
0
  node);
7018
0
    if (ret == NULL) {
7019
0
        return (NULL);
7020
0
    }
7021
    /*
7022
    * Check for illegal attributes.
7023
    */
7024
0
    attr = node->properties;
7025
0
    while (attr != NULL) {
7026
0
  if (attr->ns == NULL) {
7027
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7028
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7029
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7030
0
    xmlSchemaPIllegalAttrErr(ctxt,
7031
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7032
0
      }
7033
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7034
0
      xmlSchemaPIllegalAttrErr(ctxt,
7035
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7036
0
  }
7037
0
  attr = attr->next;
7038
0
    }
7039
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7040
    /*
7041
    * Parse the namespace list.
7042
    */
7043
0
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7044
0
  return (NULL);
7045
    /*
7046
    * And now for the children...
7047
    */
7048
0
    child = node->children;
7049
0
    if (IS_SCHEMA(child, "annotation")) {
7050
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7051
0
        child = child->next;
7052
0
    }
7053
0
    if (child != NULL) {
7054
0
  xmlSchemaPContentErr(ctxt,
7055
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7056
0
      NULL, node, child,
7057
0
      NULL, "(annotation?)");
7058
0
    }
7059
7060
0
    return (ret);
7061
0
}
7062
7063
7064
/**
7065
 * xmlSchemaParseAttribute:
7066
 * @ctxt:  a schema validation context
7067
 * @schema:  the schema being built
7068
 * @node:  a subtree containing XML Schema information
7069
 *
7070
 * parse a XML schema Attribute declaration
7071
 * *WARNING* this interface is highly subject to change
7072
 *
7073
 * Returns the attribute declaration.
7074
 */
7075
static xmlSchemaBasicItemPtr
7076
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7077
           xmlSchemaPtr schema,
7078
           xmlNodePtr node,
7079
           xmlSchemaItemListPtr uses,
7080
           int parentType)
7081
0
{
7082
0
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
7083
0
    xmlSchemaAttributeUsePtr use = NULL;
7084
0
    xmlNodePtr child = NULL;
7085
0
    xmlAttrPtr attr;
7086
0
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7087
0
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7088
0
    int nberrors, hasForm = 0, defValueType = 0;
7089
7090
0
#define WXS_ATTR_DEF_VAL_DEFAULT 1
7091
0
#define WXS_ATTR_DEF_VAL_FIXED 2
7092
7093
    /*
7094
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7095
     */
7096
7097
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7098
0
        return (NULL);
7099
0
    attr = xmlSchemaGetPropNode(node, "ref");
7100
0
    if (attr != NULL) {
7101
0
  if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7102
0
      NULL, attr, &tmpNs, &tmpName) != 0) {
7103
0
      return (NULL);
7104
0
  }
7105
0
  if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7106
0
      return(NULL);
7107
0
  isRef = 1;
7108
0
    }
7109
0
    nberrors = pctxt->nberrors;
7110
    /*
7111
    * Check for illegal attributes.
7112
    */
7113
0
    attr = node->properties;
7114
0
    while (attr != NULL) {
7115
0
  if (attr->ns == NULL) {
7116
0
      if (isRef) {
7117
0
    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7118
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7119
0
        goto attr_next;
7120
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7121
0
        goto attr_next;
7122
0
    }
7123
0
      } else {
7124
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7125
0
        goto attr_next;
7126
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7127
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7128
0
        goto attr_next;
7129
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7130
0
        xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7131
0
      attr, &tmpNs, &tmpName);
7132
0
        goto attr_next;
7133
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7134
        /*
7135
        * Evaluate the target namespace
7136
        */
7137
0
        hasForm = 1;
7138
0
        attrValue = xmlSchemaGetNodeContent(pctxt,
7139
0
      (xmlNodePtr) attr);
7140
0
        if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7141
0
      ns = pctxt->targetNamespace;
7142
0
        } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7143
0
        {
7144
0
      xmlSchemaPSimpleTypeErr(pctxt,
7145
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7146
0
          NULL, (xmlNodePtr) attr,
7147
0
          NULL, "(qualified | unqualified)",
7148
0
          attrValue, NULL, NULL, NULL);
7149
0
        }
7150
0
        goto attr_next;
7151
0
    }
7152
0
      }
7153
0
      if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7154
7155
0
    attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7156
    /* TODO: Maybe we need to normalize the value beforehand. */
7157
0
    if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7158
0
        occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7159
0
    else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7160
0
        occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7161
0
    else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7162
0
        occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7163
0
    else {
7164
0
        xmlSchemaPSimpleTypeErr(pctxt,
7165
0
      XML_SCHEMAP_INVALID_ATTR_USE,
7166
0
      NULL, (xmlNodePtr) attr,
7167
0
      NULL, "(optional | prohibited | required)",
7168
0
      attrValue, NULL, NULL, NULL);
7169
0
    }
7170
0
    goto attr_next;
7171
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7172
    /*
7173
    * 3.2.3 : 1
7174
    * default and fixed must not both be present.
7175
    */
7176
0
    if (defValue) {
7177
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7178
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7179
0
      NULL, attr, "default", "fixed");
7180
0
    } else {
7181
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7182
0
        defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7183
0
    }
7184
0
    goto attr_next;
7185
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7186
    /*
7187
    * 3.2.3 : 1
7188
    * default and fixed must not both be present.
7189
    */
7190
0
    if (defValue) {
7191
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7192
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7193
0
      NULL, attr, "default", "fixed");
7194
0
    } else {
7195
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7196
0
        defValueType = WXS_ATTR_DEF_VAL_FIXED;
7197
0
    }
7198
0
    goto attr_next;
7199
0
      }
7200
0
  } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7201
0
      goto attr_next;
7202
7203
0
  xmlSchemaPIllegalAttrErr(pctxt,
7204
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7205
7206
0
attr_next:
7207
0
  attr = attr->next;
7208
0
    }
7209
    /*
7210
    * 3.2.3 : 2
7211
    * If default and use are both present, use must have
7212
    * the actual value optional.
7213
    */
7214
0
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7215
0
  (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7216
0
  xmlSchemaPSimpleTypeErr(pctxt,
7217
0
      XML_SCHEMAP_SRC_ATTRIBUTE_2,
7218
0
      NULL, node, NULL,
7219
0
      "(optional | prohibited | required)", NULL,
7220
0
      "The value of the attribute 'use' must be 'optional' "
7221
0
      "if the attribute 'default' is present",
7222
0
      NULL, NULL);
7223
0
    }
7224
    /*
7225
    * We want correct attributes.
7226
    */
7227
0
    if (nberrors != pctxt->nberrors)
7228
0
  return(NULL);
7229
0
    if (! isRef) {
7230
0
  xmlSchemaAttributePtr attrDecl;
7231
7232
  /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7233
0
  if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7234
0
      ns = pctxt->targetNamespace;
7235
  /*
7236
  * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7237
  * TODO: Move this to the component layer.
7238
  */
7239
0
  if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7240
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7241
0
    XML_SCHEMAP_NO_XSI,
7242
0
    node, NULL,
7243
0
    "The target namespace must not match '%s'",
7244
0
    xmlSchemaInstanceNs, NULL);
7245
0
  }
7246
0
  attr = xmlSchemaGetPropNode(node, "name");
7247
0
  if (attr == NULL) {
7248
0
      xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7249
0
    NULL, node, "name", NULL);
7250
0
      return (NULL);
7251
0
  }
7252
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7253
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7254
0
      return (NULL);
7255
0
  }
7256
  /*
7257
  * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7258
  * TODO: Move this to the component layer.
7259
  */
7260
0
  if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7261
0
      xmlSchemaPSimpleTypeErr(pctxt,
7262
0
    XML_SCHEMAP_NO_XMLNS,
7263
0
    NULL, (xmlNodePtr) attr,
7264
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7265
0
    "The value of the attribute must not match 'xmlns'",
7266
0
    NULL, NULL);
7267
0
      return (NULL);
7268
0
  }
7269
0
  if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7270
0
      goto check_children;
7271
  /*
7272
  * Create the attribute use component.
7273
  */
7274
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7275
0
  if (use == NULL)
7276
0
      return(NULL);
7277
0
  use->occurs = occurs;
7278
  /*
7279
  * Create the attribute declaration.
7280
  */
7281
0
  attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7282
0
  if (attrDecl == NULL)
7283
0
      return (NULL);
7284
0
  if (tmpName != NULL) {
7285
0
      attrDecl->typeName = tmpName;
7286
0
      attrDecl->typeNs = tmpNs;
7287
0
  }
7288
0
  use->attrDecl = attrDecl;
7289
  /*
7290
  * Value constraint.
7291
  */
7292
0
  if (defValue != NULL) {
7293
0
      attrDecl->defValue = defValue;
7294
0
      if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7295
0
    attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7296
0
  }
7297
0
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7298
0
  xmlSchemaQNameRefPtr ref;
7299
7300
  /*
7301
  * Create the attribute use component.
7302
  */
7303
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7304
0
  if (use == NULL)
7305
0
      return(NULL);
7306
  /*
7307
  * We need to resolve the reference at later stage.
7308
  */
7309
0
  WXS_ADD_PENDING(pctxt, use);
7310
0
  use->occurs = occurs;
7311
  /*
7312
  * Create a QName reference to the attribute declaration.
7313
  */
7314
0
  ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7315
0
      tmpName, tmpNs);
7316
0
  if (ref == NULL)
7317
0
      return(NULL);
7318
  /*
7319
  * Assign the reference. This will be substituted for the
7320
  * referenced attribute declaration when the QName is resolved.
7321
  */
7322
0
  use->attrDecl = WXS_ATTR_CAST ref;
7323
  /*
7324
  * Value constraint.
7325
  */
7326
0
  if (defValue != NULL)
7327
0
      use->defValue = defValue;
7328
0
  if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7329
0
      use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7330
0
    }
7331
7332
0
check_children:
7333
    /*
7334
    * And now for the children...
7335
    */
7336
0
    child = node->children;
7337
0
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7338
0
  xmlSchemaAttributeUseProhibPtr prohib;
7339
7340
0
  if (IS_SCHEMA(child, "annotation")) {
7341
0
      xmlSchemaParseAnnotation(pctxt, child, 0);
7342
0
      child = child->next;
7343
0
  }
7344
0
  if (child != NULL) {
7345
0
      xmlSchemaPContentErr(pctxt,
7346
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7347
0
    NULL, node, child, NULL,
7348
0
    "(annotation?)");
7349
0
  }
7350
  /*
7351
  * Check for pointlessness of attribute prohibitions.
7352
  */
7353
0
  if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7354
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7355
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7356
0
    node, NULL,
7357
0
    "Skipping attribute use prohibition, since it is "
7358
0
    "pointless inside an <attributeGroup>",
7359
0
    NULL, NULL, NULL);
7360
0
      return(NULL);
7361
0
  } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7362
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7363
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7364
0
    node, NULL,
7365
0
    "Skipping attribute use prohibition, since it is "
7366
0
    "pointless when extending a type",
7367
0
    NULL, NULL, NULL);
7368
0
      return(NULL);
7369
0
  }
7370
0
  if (! isRef) {
7371
0
      tmpName = name;
7372
0
      tmpNs = ns;
7373
0
  }
7374
  /*
7375
  * Check for duplicate attribute prohibitions.
7376
  */
7377
0
  if (uses) {
7378
0
      int i;
7379
7380
0
      for (i = 0; i < uses->nbItems; i++) {
7381
0
    use = uses->items[i];
7382
0
    if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7383
0
        (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7384
0
        (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7385
0
    {
7386
0
        xmlChar *str = NULL;
7387
7388
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7389
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7390
0
      node, NULL,
7391
0
      "Skipping duplicate attribute use prohibition '%s'",
7392
0
      xmlSchemaFormatQName(&str, tmpNs, tmpName),
7393
0
      NULL, NULL);
7394
0
        FREE_AND_NULL(str)
7395
0
        return(NULL);
7396
0
    }
7397
0
      }
7398
0
  }
7399
  /*
7400
  * Create the attribute prohibition helper component.
7401
  */
7402
0
  prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7403
0
  if (prohib == NULL)
7404
0
      return(NULL);
7405
0
  prohib->node = node;
7406
0
  prohib->name = tmpName;
7407
0
  prohib->targetNamespace = tmpNs;
7408
0
  if (isRef) {
7409
      /*
7410
      * We need at least to resolve to the attribute declaration.
7411
      */
7412
0
      WXS_ADD_PENDING(pctxt, prohib);
7413
0
  }
7414
0
  return(WXS_BASIC_CAST prohib);
7415
0
    } else {
7416
0
  if (IS_SCHEMA(child, "annotation")) {
7417
      /*
7418
      * TODO: Should this go into the attr decl?
7419
      */
7420
0
      use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7421
0
      child = child->next;
7422
0
  }
7423
0
  if (isRef) {
7424
0
      if (child != NULL) {
7425
0
    if (IS_SCHEMA(child, "simpleType"))
7426
        /*
7427
        * 3.2.3 : 3.2
7428
        * If ref is present, then all of <simpleType>,
7429
        * form and type must be absent.
7430
        */
7431
0
        xmlSchemaPContentErr(pctxt,
7432
0
      XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7433
0
      NULL, node, child, NULL,
7434
0
      "(annotation?)");
7435
0
    else
7436
0
        xmlSchemaPContentErr(pctxt,
7437
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7438
0
      NULL, node, child, NULL,
7439
0
      "(annotation?)");
7440
0
      }
7441
0
  } else {
7442
0
      if (IS_SCHEMA(child, "simpleType")) {
7443
0
    if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7444
        /*
7445
        * 3.2.3 : 4
7446
        * type and <simpleType> must not both be present.
7447
        */
7448
0
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7449
0
      NULL, node, child,
7450
0
      "The attribute 'type' and the <simpleType> child "
7451
0
      "are mutually exclusive", NULL);
7452
0
    } else
7453
0
        WXS_ATTRUSE_TYPEDEF(use) =
7454
0
      xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7455
0
    child = child->next;
7456
0
      }
7457
0
      if (child != NULL)
7458
0
    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7459
0
    NULL, node, child, NULL,
7460
0
    "(annotation?, simpleType?)");
7461
0
  }
7462
0
    }
7463
0
    return (WXS_BASIC_CAST use);
7464
0
}
7465
7466
7467
static xmlSchemaAttributePtr
7468
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7469
            xmlSchemaPtr schema,
7470
            xmlNodePtr node)
7471
0
{
7472
0
    const xmlChar *attrValue;
7473
0
    xmlSchemaAttributePtr ret;
7474
0
    xmlNodePtr child = NULL;
7475
0
    xmlAttrPtr attr;
7476
7477
    /*
7478
     * Note that the w3c spec assumes the schema to be validated with schema
7479
     * for schemas beforehand.
7480
     *
7481
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7482
     */
7483
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7484
0
        return (NULL);
7485
    /*
7486
    * 3.2.3 : 3.1
7487
    * One of ref or name must be present, but not both
7488
    */
7489
0
    attr = xmlSchemaGetPropNode(node, "name");
7490
0
    if (attr == NULL) {
7491
0
  xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7492
0
      NULL, node, "name", NULL);
7493
0
  return (NULL);
7494
0
    }
7495
0
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7496
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7497
0
  return (NULL);
7498
0
    }
7499
    /*
7500
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7501
    * TODO: Move this to the component layer.
7502
    */
7503
0
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7504
0
  xmlSchemaPSimpleTypeErr(pctxt,
7505
0
      XML_SCHEMAP_NO_XMLNS,
7506
0
      NULL, (xmlNodePtr) attr,
7507
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7508
0
      "The value of the attribute must not match 'xmlns'",
7509
0
      NULL, NULL);
7510
0
  return (NULL);
7511
0
    }
7512
    /*
7513
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7514
    * TODO: Move this to the component layer.
7515
    *       Or better leave it here and add it to the component layer
7516
    *       if we have a schema construction API.
7517
    */
7518
0
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7519
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
7520
0
      XML_SCHEMAP_NO_XSI, node, NULL,
7521
0
      "The target namespace must not match '%s'",
7522
0
      xmlSchemaInstanceNs, NULL);
7523
0
    }
7524
7525
0
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7526
0
  pctxt->targetNamespace, node, 1);
7527
0
    if (ret == NULL)
7528
0
  return (NULL);
7529
0
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7530
7531
    /*
7532
    * Check for illegal attributes.
7533
    */
7534
0
    attr = node->properties;
7535
0
    while (attr != NULL) {
7536
0
  if (attr->ns == NULL) {
7537
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7538
0
    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7539
0
    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7540
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7541
0
    (!xmlStrEqual(attr->name, BAD_CAST "type")))
7542
0
      {
7543
0
    xmlSchemaPIllegalAttrErr(pctxt,
7544
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7545
0
      }
7546
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7547
0
      xmlSchemaPIllegalAttrErr(pctxt,
7548
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7549
0
  }
7550
0
  attr = attr->next;
7551
0
    }
7552
0
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
7553
0
  node, "type", &ret->typeNs, &ret->typeName);
7554
7555
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7556
    /*
7557
    * Attribute "fixed".
7558
    */
7559
0
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7560
0
    if (ret->defValue != NULL)
7561
0
  ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7562
    /*
7563
    * Attribute "default".
7564
    */
7565
0
    attr = xmlSchemaGetPropNode(node, "default");
7566
0
    if (attr != NULL) {
7567
  /*
7568
  * 3.2.3 : 1
7569
  * default and fixed must not both be present.
7570
  */
7571
0
  if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7572
0
      xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7573
0
    WXS_BASIC_CAST ret, attr, "default", "fixed");
7574
0
  } else
7575
0
      ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7576
0
    }
7577
    /*
7578
    * And now for the children...
7579
    */
7580
0
    child = node->children;
7581
0
    if (IS_SCHEMA(child, "annotation")) {
7582
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7583
0
        child = child->next;
7584
0
    }
7585
0
    if (IS_SCHEMA(child, "simpleType")) {
7586
0
  if (ret->typeName != NULL) {
7587
      /*
7588
      * 3.2.3 : 4
7589
      * type and <simpleType> must not both be present.
7590
      */
7591
0
      xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7592
0
    NULL, node, child,
7593
0
    "The attribute 'type' and the <simpleType> child "
7594
0
    "are mutually exclusive", NULL);
7595
0
  } else
7596
0
      ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7597
0
  child = child->next;
7598
0
    }
7599
0
    if (child != NULL)
7600
0
  xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7601
0
      NULL, node, child, NULL,
7602
0
      "(annotation?, simpleType?)");
7603
7604
0
    return (ret);
7605
0
}
7606
7607
/**
7608
 * xmlSchemaParseAttributeGroupRef:
7609
 * @ctxt:  a schema validation context
7610
 * @schema:  the schema being built
7611
 * @node:  a subtree containing XML Schema information
7612
 *
7613
 * Parse an attribute group definition reference.
7614
 * Note that a reference to an attribute group does not
7615
 * correspond to any component at all.
7616
 * *WARNING* this interface is highly subject to change
7617
 *
7618
 * Returns the attribute group or NULL in case of error.
7619
 */
7620
static xmlSchemaQNameRefPtr
7621
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7622
        xmlSchemaPtr schema,
7623
        xmlNodePtr node)
7624
0
{
7625
0
    xmlSchemaQNameRefPtr ret;
7626
0
    xmlNodePtr child = NULL;
7627
0
    xmlAttrPtr attr;
7628
0
    const xmlChar *refNs = NULL, *ref = NULL;
7629
7630
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7631
0
        return (NULL);
7632
7633
0
    attr = xmlSchemaGetPropNode(node, "ref");
7634
0
    if (attr == NULL) {
7635
0
  xmlSchemaPMissingAttrErr(pctxt,
7636
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7637
0
      NULL, node, "ref", NULL);
7638
0
  return (NULL);
7639
0
    }
7640
0
    xmlSchemaPValAttrNodeQName(pctxt, schema,
7641
0
  NULL, attr, &refNs, &ref);
7642
0
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7643
0
  return(NULL);
7644
7645
    /*
7646
    * Check for illegal attributes.
7647
    */
7648
0
    attr = node->properties;
7649
0
    while (attr != NULL) {
7650
0
  if (attr->ns == NULL) {
7651
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7652
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7653
0
      {
7654
0
    xmlSchemaPIllegalAttrErr(pctxt,
7655
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7656
0
      }
7657
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7658
0
      xmlSchemaPIllegalAttrErr(pctxt,
7659
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7660
0
  }
7661
0
  attr = attr->next;
7662
0
    }
7663
    /* Attribute ID */
7664
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7665
7666
    /*
7667
    * And now for the children...
7668
    */
7669
0
    child = node->children;
7670
0
    if (IS_SCHEMA(child, "annotation")) {
7671
  /*
7672
  * TODO: We do not have a place to store the annotation, do we?
7673
  */
7674
0
        xmlSchemaParseAnnotation(pctxt, child, 0);
7675
0
        child = child->next;
7676
0
    }
7677
0
    if (child != NULL) {
7678
0
  xmlSchemaPContentErr(pctxt,
7679
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7680
0
      NULL, node, child, NULL,
7681
0
      "(annotation?)");
7682
0
    }
7683
7684
    /*
7685
    * Handle attribute group redefinitions.
7686
    */
7687
0
    if (pctxt->isRedefine && pctxt->redef &&
7688
0
  (pctxt->redef->item->type ==
7689
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7690
0
  (ref == pctxt->redef->refName) &&
7691
0
  (refNs == pctxt->redef->refTargetNs))
7692
0
    {
7693
  /*
7694
  * SPEC src-redefine:
7695
  * (7.1) "If it has an <attributeGroup> among its contents
7696
  * the `actual value` of whose ref [attribute] is the same
7697
  * as the `actual value` of its own name attribute plus
7698
  * target namespace, then it must have exactly one such group."
7699
  */
7700
0
  if (pctxt->redefCounter != 0) {
7701
0
      xmlChar *str = NULL;
7702
7703
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7704
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7705
0
    "The redefining attribute group definition "
7706
0
    "'%s' must not contain more than one "
7707
0
    "reference to the redefined definition",
7708
0
    xmlSchemaFormatQName(&str, refNs, ref), NULL);
7709
0
      FREE_AND_NULL(str);
7710
0
      return(NULL);
7711
0
  }
7712
0
  pctxt->redefCounter++;
7713
  /*
7714
  * URGENT TODO: How to ensure that the reference will not be
7715
  * handled by the normal component resolution mechanism?
7716
  */
7717
0
  ret = xmlSchemaNewQNameRef(pctxt,
7718
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7719
0
  if (ret == NULL)
7720
0
      return(NULL);
7721
0
  ret->node = node;
7722
0
  pctxt->redef->reference = WXS_BASIC_CAST ret;
7723
0
    } else {
7724
  /*
7725
  * Create a QName-reference helper component. We will substitute this
7726
  * component for the attribute uses of the referenced attribute group
7727
  * definition.
7728
  */
7729
0
  ret = xmlSchemaNewQNameRef(pctxt,
7730
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7731
0
  if (ret == NULL)
7732
0
      return(NULL);
7733
0
  ret->node = node;
7734
  /* Add to pending items, to be able to resolve the reference. */
7735
0
  WXS_ADD_PENDING(pctxt, ret);
7736
0
    }
7737
0
    return (ret);
7738
0
}
7739
7740
/**
7741
 * xmlSchemaParseAttributeGroupDefinition:
7742
 * @pctxt:  a schema validation context
7743
 * @schema:  the schema being built
7744
 * @node:  a subtree containing XML Schema information
7745
 *
7746
 * parse a XML schema Attribute Group declaration
7747
 * *WARNING* this interface is highly subject to change
7748
 *
7749
 * Returns the attribute group definition or NULL in case of error.
7750
 */
7751
static xmlSchemaAttributeGroupPtr
7752
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7753
               xmlSchemaPtr schema,
7754
               xmlNodePtr node)
7755
0
{
7756
0
    const xmlChar *name;
7757
0
    xmlSchemaAttributeGroupPtr ret;
7758
0
    xmlNodePtr child = NULL;
7759
0
    xmlAttrPtr attr;
7760
0
    int hasRefs = 0;
7761
7762
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7763
0
        return (NULL);
7764
7765
0
    attr = xmlSchemaGetPropNode(node, "name");
7766
0
    if (attr == NULL) {
7767
0
  xmlSchemaPMissingAttrErr(pctxt,
7768
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7769
0
      NULL, node, "name", NULL);
7770
0
  return (NULL);
7771
0
    }
7772
    /*
7773
    * The name is crucial, exit if invalid.
7774
    */
7775
0
    if (xmlSchemaPValAttrNode(pctxt,
7776
0
  NULL, attr,
7777
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7778
0
  return (NULL);
7779
0
    }
7780
0
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7781
0
  name, pctxt->targetNamespace, node);
7782
0
    if (ret == NULL)
7783
0
  return (NULL);
7784
    /*
7785
    * Check for illegal attributes.
7786
    */
7787
0
    attr = node->properties;
7788
0
    while (attr != NULL) {
7789
0
  if (attr->ns == NULL) {
7790
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7791
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7792
0
      {
7793
0
    xmlSchemaPIllegalAttrErr(pctxt,
7794
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7795
0
      }
7796
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7797
0
      xmlSchemaPIllegalAttrErr(pctxt,
7798
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7799
0
  }
7800
0
  attr = attr->next;
7801
0
    }
7802
    /* Attribute ID */
7803
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7804
    /*
7805
    * And now for the children...
7806
    */
7807
0
    child = node->children;
7808
0
    if (IS_SCHEMA(child, "annotation")) {
7809
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7810
0
        child = child->next;
7811
0
    }
7812
    /*
7813
    * Parse contained attribute decls/refs.
7814
    */
7815
0
    if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7816
0
  (xmlSchemaItemListPtr *) &(ret->attrUses),
7817
0
  XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7818
0
  return(NULL);
7819
0
    if (hasRefs)
7820
0
  ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7821
    /*
7822
    * Parse the attribute wildcard.
7823
    */
7824
0
    if (IS_SCHEMA(child, "anyAttribute")) {
7825
0
  ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7826
0
      schema, child);
7827
0
  child = child->next;
7828
0
    }
7829
0
    if (child != NULL) {
7830
0
  xmlSchemaPContentErr(pctxt,
7831
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7832
0
      NULL, node, child, NULL,
7833
0
      "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7834
0
    }
7835
0
    return (ret);
7836
0
}
7837
7838
/**
7839
 * xmlSchemaPValAttrFormDefault:
7840
 * @value:  the value
7841
 * @flags: the flags to be modified
7842
 * @flagQualified: the specific flag for "qualified"
7843
 *
7844
 * Returns 0 if the value is valid, 1 otherwise.
7845
 */
7846
static int
7847
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7848
           int *flags,
7849
           int flagQualified)
7850
0
{
7851
0
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
7852
0
  if  ((*flags & flagQualified) == 0)
7853
0
      *flags |= flagQualified;
7854
0
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7855
0
  return (1);
7856
7857
0
    return (0);
7858
0
}
7859
7860
/**
7861
 * xmlSchemaPValAttrBlockFinal:
7862
 * @value:  the value
7863
 * @flags: the flags to be modified
7864
 * @flagAll: the specific flag for "#all"
7865
 * @flagExtension: the specific flag for "extension"
7866
 * @flagRestriction: the specific flag for "restriction"
7867
 * @flagSubstitution: the specific flag for "substitution"
7868
 * @flagList: the specific flag for "list"
7869
 * @flagUnion: the specific flag for "union"
7870
 *
7871
 * Validates the value of the attribute "final" and "block". The value
7872
 * is converted into the specified flag values and returned in @flags.
7873
 *
7874
 * Returns 0 if the value is valid, 1 otherwise.
7875
 */
7876
7877
static int
7878
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7879
          int *flags,
7880
          int flagAll,
7881
          int flagExtension,
7882
          int flagRestriction,
7883
          int flagSubstitution,
7884
          int flagList,
7885
          int flagUnion)
7886
0
{
7887
0
    int ret = 0;
7888
7889
    /*
7890
    * TODO: This does not check for duplicate entries.
7891
    */
7892
0
    if ((flags == NULL) || (value == NULL))
7893
0
  return (-1);
7894
0
    if (value[0] == 0)
7895
0
  return (0);
7896
0
    if (xmlStrEqual(value, BAD_CAST "#all")) {
7897
0
  if (flagAll != -1)
7898
0
      *flags |= flagAll;
7899
0
  else {
7900
0
      if (flagExtension != -1)
7901
0
    *flags |= flagExtension;
7902
0
      if (flagRestriction != -1)
7903
0
    *flags |= flagRestriction;
7904
0
      if (flagSubstitution != -1)
7905
0
    *flags |= flagSubstitution;
7906
0
      if (flagList != -1)
7907
0
    *flags |= flagList;
7908
0
      if (flagUnion != -1)
7909
0
    *flags |= flagUnion;
7910
0
  }
7911
0
    } else {
7912
0
  const xmlChar *end, *cur = value;
7913
0
  xmlChar *item;
7914
7915
0
  do {
7916
0
      while (IS_BLANK_CH(*cur))
7917
0
    cur++;
7918
0
      end = cur;
7919
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
7920
0
    end++;
7921
0
      if (end == cur)
7922
0
    break;
7923
0
      item = xmlStrndup(cur, end - cur);
7924
0
      if (xmlStrEqual(item, BAD_CAST "extension")) {
7925
0
    if (flagExtension != -1) {
7926
0
        if ((*flags & flagExtension) == 0)
7927
0
      *flags |= flagExtension;
7928
0
    } else
7929
0
        ret = 1;
7930
0
      } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
7931
0
    if (flagRestriction != -1) {
7932
0
        if ((*flags & flagRestriction) == 0)
7933
0
      *flags |= flagRestriction;
7934
0
    } else
7935
0
        ret = 1;
7936
0
      } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
7937
0
    if (flagSubstitution != -1) {
7938
0
        if ((*flags & flagSubstitution) == 0)
7939
0
      *flags |= flagSubstitution;
7940
0
    } else
7941
0
        ret = 1;
7942
0
      } else if (xmlStrEqual(item, BAD_CAST "list")) {
7943
0
    if (flagList != -1) {
7944
0
        if ((*flags & flagList) == 0)
7945
0
      *flags |= flagList;
7946
0
    } else
7947
0
        ret = 1;
7948
0
      } else if (xmlStrEqual(item, BAD_CAST "union")) {
7949
0
    if (flagUnion != -1) {
7950
0
        if ((*flags & flagUnion) == 0)
7951
0
      *flags |= flagUnion;
7952
0
    } else
7953
0
        ret = 1;
7954
0
      } else
7955
0
    ret = 1;
7956
0
      if (item != NULL)
7957
0
    xmlFree(item);
7958
0
      cur = end;
7959
0
  } while ((ret == 0) && (*cur != 0));
7960
0
    }
7961
7962
0
    return (ret);
7963
0
}
7964
7965
static int
7966
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7967
           xmlSchemaIDCPtr idc,
7968
           xmlSchemaIDCSelectPtr selector,
7969
           xmlAttrPtr attr,
7970
           int isField)
7971
0
{
7972
0
    xmlNodePtr node;
7973
7974
    /*
7975
    * c-selector-xpath:
7976
    * Schema Component Constraint: Selector Value OK
7977
    *
7978
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
7979
    * in [XPath].
7980
    */
7981
0
    if (selector == NULL) {
7982
0
  xmlSchemaPErr(ctxt, idc->node,
7983
0
      XML_SCHEMAP_INTERNAL,
7984
0
      "Internal error: xmlSchemaCheckCSelectorXPath, "
7985
0
      "the selector is not specified.\n", NULL, NULL);
7986
0
  return (-1);
7987
0
    }
7988
0
    if (attr == NULL)
7989
0
  node = idc->node;
7990
0
    else
7991
0
  node = (xmlNodePtr) attr;
7992
0
    if (selector->xpath == NULL) {
7993
0
  xmlSchemaPCustomErr(ctxt,
7994
      /* TODO: Adjust error code. */
7995
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7996
0
      NULL, node,
7997
0
      "The XPath expression of the selector is not valid", NULL);
7998
0
  return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
7999
0
    } else {
8000
0
  const xmlChar **nsArray = NULL;
8001
0
  xmlNsPtr *nsList = NULL;
8002
  /*
8003
  * Compile the XPath expression.
8004
  */
8005
  /*
8006
  * TODO: We need the array of in-scope namespaces for compilation.
8007
  * TODO: Call xmlPatterncompile with different options for selector/
8008
  * field.
8009
  */
8010
0
  if (attr == NULL)
8011
0
      nsList = NULL;
8012
0
  else
8013
0
      nsList = xmlGetNsList(attr->doc, attr->parent);
8014
  /*
8015
  * Build an array of prefixes and namespaces.
8016
  */
8017
0
  if (nsList != NULL) {
8018
0
      int i, count = 0;
8019
8020
0
      for (i = 0; nsList[i] != NULL; i++)
8021
0
    count++;
8022
8023
0
      nsArray = (const xmlChar **) xmlMalloc(
8024
0
    (count * 2 + 1) * sizeof(const xmlChar *));
8025
0
      if (nsArray == NULL) {
8026
0
    xmlSchemaPErrMemory(ctxt);
8027
0
    xmlFree(nsList);
8028
0
    return (-1);
8029
0
      }
8030
0
      for (i = 0; i < count; i++) {
8031
0
    nsArray[2 * i] = nsList[i]->href;
8032
0
    nsArray[2 * i + 1] = nsList[i]->prefix;
8033
0
      }
8034
0
      nsArray[count * 2] = NULL;
8035
0
      xmlFree(nsList);
8036
0
  }
8037
  /*
8038
  * TODO: Differentiate between "selector" and "field".
8039
  */
8040
0
  if (isField)
8041
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8042
0
    NULL, XML_PATTERN_XSFIELD, nsArray);
8043
0
  else
8044
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8045
0
    NULL, XML_PATTERN_XSSEL, nsArray);
8046
0
  if (nsArray != NULL)
8047
0
      xmlFree((xmlChar **) nsArray);
8048
8049
0
  if (selector->xpathComp == NULL) {
8050
0
      xmlSchemaPCustomErr(ctxt,
8051
    /* TODO: Adjust error code? */
8052
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8053
0
    NULL, node,
8054
0
    "The XPath expression '%s' could not be "
8055
0
    "compiled", selector->xpath);
8056
0
      return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8057
0
  }
8058
0
    }
8059
0
    return (0);
8060
0
}
8061
8062
#define ADD_ANNOTATION(annot)   \
8063
0
    xmlSchemaAnnotPtr cur = item->annot; \
8064
0
    if (item->annot == NULL) {  \
8065
0
  item->annot = annot;    \
8066
0
  return (annot);         \
8067
0
    }                           \
8068
0
    cur = item->annot;          \
8069
0
    while (cur->next != NULL) { \
8070
0
  cur = cur->next;  \
8071
0
    }                           \
8072
0
    cur->next = annot;
8073
8074
/**
8075
 * xmlSchemaAssignAnnotation:
8076
 * @item: the schema component
8077
 * @annot: the annotation
8078
 *
8079
 * Adds the annotation to the given schema component.
8080
 *
8081
 * Returns the given annotation.
8082
 */
8083
static xmlSchemaAnnotPtr
8084
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8085
           xmlSchemaAnnotPtr annot)
8086
0
{
8087
0
    if ((annItem == NULL) || (annot == NULL))
8088
0
  return (NULL);
8089
0
    switch (annItem->type) {
8090
0
  case XML_SCHEMA_TYPE_ELEMENT: {
8091
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8092
0
    ADD_ANNOTATION(annot)
8093
0
      }
8094
0
      break;
8095
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
8096
0
    xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8097
0
    ADD_ANNOTATION(annot)
8098
0
      }
8099
0
      break;
8100
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8101
0
  case XML_SCHEMA_TYPE_ANY: {
8102
0
    xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8103
0
    ADD_ANNOTATION(annot)
8104
0
      }
8105
0
      break;
8106
0
  case XML_SCHEMA_TYPE_PARTICLE:
8107
0
  case XML_SCHEMA_TYPE_IDC_KEY:
8108
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
8109
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8110
0
    xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8111
0
    ADD_ANNOTATION(annot)
8112
0
      }
8113
0
      break;
8114
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8115
0
    xmlSchemaAttributeGroupPtr item =
8116
0
        (xmlSchemaAttributeGroupPtr) annItem;
8117
0
    ADD_ANNOTATION(annot)
8118
0
      }
8119
0
      break;
8120
0
  case XML_SCHEMA_TYPE_NOTATION: {
8121
0
    xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8122
0
    ADD_ANNOTATION(annot)
8123
0
      }
8124
0
      break;
8125
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
8126
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
8127
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
8128
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8129
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
8130
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
8131
0
  case XML_SCHEMA_FACET_PATTERN:
8132
0
  case XML_SCHEMA_FACET_ENUMERATION:
8133
0
  case XML_SCHEMA_FACET_WHITESPACE:
8134
0
  case XML_SCHEMA_FACET_LENGTH:
8135
0
  case XML_SCHEMA_FACET_MAXLENGTH:
8136
0
  case XML_SCHEMA_FACET_MINLENGTH: {
8137
0
    xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8138
0
    ADD_ANNOTATION(annot)
8139
0
      }
8140
0
      break;
8141
0
  case XML_SCHEMA_TYPE_SIMPLE:
8142
0
  case XML_SCHEMA_TYPE_COMPLEX: {
8143
0
    xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8144
0
    ADD_ANNOTATION(annot)
8145
0
      }
8146
0
      break;
8147
0
  case XML_SCHEMA_TYPE_GROUP: {
8148
0
    xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8149
0
    ADD_ANNOTATION(annot)
8150
0
      }
8151
0
      break;
8152
0
  case XML_SCHEMA_TYPE_SEQUENCE:
8153
0
  case XML_SCHEMA_TYPE_CHOICE:
8154
0
  case XML_SCHEMA_TYPE_ALL: {
8155
0
    xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8156
0
    ADD_ANNOTATION(annot)
8157
0
      }
8158
0
      break;
8159
0
  default:
8160
0
       xmlSchemaPCustomErr(NULL,
8161
0
    XML_SCHEMAP_INTERNAL,
8162
0
    NULL, NULL,
8163
0
    "Internal error: xmlSchemaAddAnnotation, "
8164
0
    "The item is not a annotated schema component", NULL);
8165
0
       break;
8166
0
    }
8167
0
    return (annot);
8168
0
}
8169
8170
/**
8171
 * xmlSchemaParseIDCSelectorAndField:
8172
 * @ctxt:  a schema validation context
8173
 * @schema:  the schema being built
8174
 * @node:  a subtree containing XML Schema information
8175
 *
8176
 * Parses a XML Schema identity-constraint definition's
8177
 * <selector> and <field> elements.
8178
 *
8179
 * Returns the parsed identity-constraint definition.
8180
 */
8181
static xmlSchemaIDCSelectPtr
8182
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8183
        xmlSchemaIDCPtr idc,
8184
        xmlNodePtr node,
8185
        int isField)
8186
0
{
8187
0
    xmlSchemaIDCSelectPtr item;
8188
0
    xmlNodePtr child = NULL;
8189
0
    xmlAttrPtr attr;
8190
8191
    /*
8192
    * Check for illegal attributes.
8193
    */
8194
0
    attr = node->properties;
8195
0
    while (attr != NULL) {
8196
0
  if (attr->ns == NULL) {
8197
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8198
0
    (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8199
0
    xmlSchemaPIllegalAttrErr(ctxt,
8200
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8201
0
      }
8202
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8203
0
      xmlSchemaPIllegalAttrErr(ctxt,
8204
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8205
0
  }
8206
0
  attr = attr->next;
8207
0
    }
8208
    /*
8209
    * Create the item.
8210
    */
8211
0
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8212
0
    if (item == NULL) {
8213
0
        xmlSchemaPErrMemory(ctxt);
8214
0
        return (NULL);
8215
0
    }
8216
0
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
8217
    /*
8218
    * Attribute "xpath" (mandatory).
8219
    */
8220
0
    attr = xmlSchemaGetPropNode(node, "xpath");
8221
0
    if (attr == NULL) {
8222
0
  xmlSchemaPMissingAttrErr(ctxt,
8223
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8224
0
      NULL, node,
8225
0
      "name", NULL);
8226
0
    } else {
8227
0
  item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8228
  /*
8229
  * URGENT TODO: "field"s have an other syntax than "selector"s.
8230
  */
8231
8232
0
  if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8233
0
      isField) == -1) {
8234
0
      xmlSchemaPErr(ctxt,
8235
0
    (xmlNodePtr) attr,
8236
0
    XML_SCHEMAP_INTERNAL,
8237
0
    "Internal error: xmlSchemaParseIDCSelectorAndField, "
8238
0
    "validating the XPath expression of a IDC selector.\n",
8239
0
    NULL, NULL);
8240
0
  }
8241
8242
0
    }
8243
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8244
    /*
8245
    * And now for the children...
8246
    */
8247
0
    child = node->children;
8248
0
    if (IS_SCHEMA(child, "annotation")) {
8249
  /*
8250
  * Add the annotation to the parent IDC.
8251
  */
8252
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8253
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8254
0
  child = child->next;
8255
0
    }
8256
0
    if (child != NULL) {
8257
0
  xmlSchemaPContentErr(ctxt,
8258
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8259
0
      NULL, node, child,
8260
0
      NULL, "(annotation?)");
8261
0
    }
8262
8263
0
    return (item);
8264
0
}
8265
8266
/**
8267
 * xmlSchemaParseIDC:
8268
 * @ctxt:  a schema validation context
8269
 * @schema:  the schema being built
8270
 * @node:  a subtree containing XML Schema information
8271
 *
8272
 * Parses a XML Schema identity-constraint definition.
8273
 *
8274
 * Returns the parsed identity-constraint definition.
8275
 */
8276
static xmlSchemaIDCPtr
8277
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8278
      xmlSchemaPtr schema,
8279
      xmlNodePtr node,
8280
      xmlSchemaTypeType idcCategory,
8281
      const xmlChar *targetNamespace)
8282
0
{
8283
0
    xmlSchemaIDCPtr item = NULL;
8284
0
    xmlNodePtr child = NULL;
8285
0
    xmlAttrPtr attr;
8286
0
    const xmlChar *name = NULL;
8287
0
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8288
8289
    /*
8290
    * Check for illegal attributes.
8291
    */
8292
0
    attr = node->properties;
8293
0
    while (attr != NULL) {
8294
0
  if (attr->ns == NULL) {
8295
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8296
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8297
0
    ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8298
0
     (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8299
0
    xmlSchemaPIllegalAttrErr(ctxt,
8300
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8301
0
      }
8302
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8303
0
      xmlSchemaPIllegalAttrErr(ctxt,
8304
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8305
0
  }
8306
0
  attr = attr->next;
8307
0
    }
8308
    /*
8309
    * Attribute "name" (mandatory).
8310
    */
8311
0
    attr = xmlSchemaGetPropNode(node, "name");
8312
0
    if (attr == NULL) {
8313
0
  xmlSchemaPMissingAttrErr(ctxt,
8314
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8315
0
      NULL, node,
8316
0
      "name", NULL);
8317
0
  return (NULL);
8318
0
    } else if (xmlSchemaPValAttrNode(ctxt,
8319
0
  NULL, attr,
8320
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8321
0
  return (NULL);
8322
0
    }
8323
    /* Create the component. */
8324
0
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8325
0
  idcCategory, node);
8326
0
    if (item == NULL)
8327
0
  return(NULL);
8328
8329
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8330
0
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8331
  /*
8332
  * Attribute "refer" (mandatory).
8333
  */
8334
0
  attr = xmlSchemaGetPropNode(node, "refer");
8335
0
  if (attr == NULL) {
8336
0
      xmlSchemaPMissingAttrErr(ctxt,
8337
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8338
0
    NULL, node,
8339
0
    "refer", NULL);
8340
0
  } else {
8341
      /*
8342
      * Create a reference item.
8343
      */
8344
0
      item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8345
0
    NULL, NULL);
8346
0
      if (item->ref == NULL)
8347
0
    return (NULL);
8348
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8349
0
    NULL, attr,
8350
0
    &(item->ref->targetNamespace),
8351
0
    &(item->ref->name));
8352
0
      xmlSchemaCheckReference(ctxt, schema, node, attr,
8353
0
    item->ref->targetNamespace);
8354
0
  }
8355
0
    }
8356
    /*
8357
    * And now for the children...
8358
    */
8359
0
    child = node->children;
8360
0
    if (IS_SCHEMA(child, "annotation")) {
8361
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8362
0
  child = child->next;
8363
0
    }
8364
0
    if (child == NULL) {
8365
0
  xmlSchemaPContentErr(ctxt,
8366
0
    XML_SCHEMAP_S4S_ELEM_MISSING,
8367
0
    NULL, node, child,
8368
0
    "A child element is missing",
8369
0
    "(annotation?, (selector, field+))");
8370
0
    }
8371
    /*
8372
    * Child element <selector>.
8373
    */
8374
0
    if (IS_SCHEMA(child, "selector")) {
8375
0
  item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8376
0
      item, child, 0);
8377
0
  child = child->next;
8378
  /*
8379
  * Child elements <field>.
8380
  */
8381
0
  if (IS_SCHEMA(child, "field")) {
8382
0
      do {
8383
0
    field = xmlSchemaParseIDCSelectorAndField(ctxt,
8384
0
        item, child, 1);
8385
0
    if (field != NULL) {
8386
0
        field->index = item->nbFields;
8387
0
        item->nbFields++;
8388
0
        if (lastField != NULL)
8389
0
      lastField->next = field;
8390
0
        else
8391
0
      item->fields = field;
8392
0
        lastField = field;
8393
0
    }
8394
0
    child = child->next;
8395
0
      } while (IS_SCHEMA(child, "field"));
8396
0
  } else {
8397
0
      xmlSchemaPContentErr(ctxt,
8398
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8399
0
    NULL, node, child,
8400
0
    NULL, "(annotation?, (selector, field+))");
8401
0
  }
8402
0
    }
8403
0
    if (child != NULL) {
8404
0
  xmlSchemaPContentErr(ctxt,
8405
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8406
0
      NULL, node, child,
8407
0
      NULL, "(annotation?, (selector, field+))");
8408
0
    }
8409
8410
0
    return (item);
8411
0
}
8412
8413
/**
8414
 * xmlSchemaParseElement:
8415
 * @ctxt:  a schema validation context
8416
 * @schema:  the schema being built
8417
 * @node:  a subtree containing XML Schema information
8418
 * @topLevel: indicates if this is global declaration
8419
 *
8420
 * Parses a XML schema element declaration.
8421
 * *WARNING* this interface is highly subject to change
8422
 *
8423
 * Returns the element declaration or a particle; NULL in case
8424
 * of an error or if the particle has minOccurs==maxOccurs==0.
8425
 */
8426
static xmlSchemaBasicItemPtr
8427
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8428
                      xmlNodePtr node, int *isElemRef, int topLevel)
8429
0
{
8430
0
    xmlSchemaElementPtr decl = NULL;
8431
0
    xmlSchemaParticlePtr particle = NULL;
8432
0
    xmlSchemaAnnotPtr annot = NULL;
8433
0
    xmlNodePtr child = NULL;
8434
0
    xmlAttrPtr attr, nameAttr;
8435
0
    int min, max, isRef = 0;
8436
0
    xmlChar *des = NULL;
8437
8438
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
8439
    /* TODO: Complete implementation of 3.3.6 */
8440
8441
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8442
0
        return (NULL);
8443
8444
0
    if (isElemRef != NULL)
8445
0
  *isElemRef = 0;
8446
    /*
8447
    * If we get a "ref" attribute on a local <element> we will assume it's
8448
    * a reference - even if there's a "name" attribute; this seems to be more
8449
    * robust.
8450
    */
8451
0
    nameAttr = xmlSchemaGetPropNode(node, "name");
8452
0
    attr = xmlSchemaGetPropNode(node, "ref");
8453
0
    if ((topLevel) || (attr == NULL)) {
8454
0
  if (nameAttr == NULL) {
8455
0
      xmlSchemaPMissingAttrErr(ctxt,
8456
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8457
0
    NULL, node, "name", NULL);
8458
0
      return (NULL);
8459
0
  }
8460
0
    } else
8461
0
  isRef = 1;
8462
8463
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8464
0
    child = node->children;
8465
0
    if (IS_SCHEMA(child, "annotation")) {
8466
0
  annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8467
0
  child = child->next;
8468
0
    }
8469
    /*
8470
    * Skip particle part if a global declaration.
8471
    */
8472
0
    if (topLevel)
8473
0
  goto declaration_part;
8474
    /*
8475
    * The particle part ==================================================
8476
    */
8477
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8478
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8479
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8480
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
8481
0
    if (particle == NULL)
8482
0
  goto return_null;
8483
8484
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8485
8486
0
    if (isRef) {
8487
0
  const xmlChar *refNs = NULL, *ref = NULL;
8488
0
  xmlSchemaQNameRefPtr refer = NULL;
8489
  /*
8490
  * The reference part =============================================
8491
  */
8492
0
  if (isElemRef != NULL)
8493
0
      *isElemRef = 1;
8494
8495
0
  xmlSchemaPValAttrNodeQName(ctxt, schema,
8496
0
      NULL, attr, &refNs, &ref);
8497
0
  xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8498
  /*
8499
  * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8500
  */
8501
0
  if (nameAttr != NULL) {
8502
0
      xmlSchemaPMutualExclAttrErr(ctxt,
8503
0
    XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8504
0
  }
8505
  /*
8506
  * Check for illegal attributes.
8507
  */
8508
0
  attr = node->properties;
8509
0
  while (attr != NULL) {
8510
0
      if (attr->ns == NULL) {
8511
0
    if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8512
0
        xmlStrEqual(attr->name, BAD_CAST "name") ||
8513
0
        xmlStrEqual(attr->name, BAD_CAST "id") ||
8514
0
        xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8515
0
        xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8516
0
    {
8517
0
        attr = attr->next;
8518
0
        continue;
8519
0
    } else {
8520
        /* SPEC (3.3.3 : 2.2) */
8521
0
        xmlSchemaPCustomAttrErr(ctxt,
8522
0
      XML_SCHEMAP_SRC_ELEMENT_2_2,
8523
0
      NULL, NULL, attr,
8524
0
      "Only the attributes 'minOccurs', 'maxOccurs' and "
8525
0
      "'id' are allowed in addition to 'ref'");
8526
0
        break;
8527
0
    }
8528
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8529
0
    xmlSchemaPIllegalAttrErr(ctxt,
8530
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8531
0
      }
8532
0
      attr = attr->next;
8533
0
  }
8534
  /*
8535
  * No children except <annotation> expected.
8536
  */
8537
0
  if (child != NULL) {
8538
0
      xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8539
0
    NULL, node, child, NULL, "(annotation?)");
8540
0
  }
8541
0
  if ((min == 0) && (max == 0))
8542
0
      goto return_null;
8543
  /*
8544
  * Create the reference item and attach it to the particle.
8545
  */
8546
0
  refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8547
0
      ref, refNs);
8548
0
  if (refer == NULL)
8549
0
      goto return_null;
8550
0
  particle->children = (xmlSchemaTreeItemPtr) refer;
8551
0
  particle->annot = annot;
8552
  /*
8553
  * Add the particle to pending components, since the reference
8554
  * need to be resolved.
8555
  */
8556
0
  WXS_ADD_PENDING(ctxt, particle);
8557
0
  return ((xmlSchemaBasicItemPtr) particle);
8558
0
    }
8559
    /*
8560
    * The declaration part ===============================================
8561
    */
8562
0
declaration_part:
8563
0
    {
8564
0
  const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8565
0
  xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8566
8567
0
  if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8568
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8569
0
      goto return_null;
8570
  /*
8571
  * Evaluate the target namespace.
8572
  */
8573
0
  if (topLevel) {
8574
0
      ns = ctxt->targetNamespace;
8575
0
  } else {
8576
0
      attr = xmlSchemaGetPropNode(node, "form");
8577
0
      if (attr != NULL) {
8578
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8579
0
    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8580
0
        ns = ctxt->targetNamespace;
8581
0
    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8582
0
        xmlSchemaPSimpleTypeErr(ctxt,
8583
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8584
0
      NULL, (xmlNodePtr) attr,
8585
0
      NULL, "(qualified | unqualified)",
8586
0
      attrValue, NULL, NULL, NULL);
8587
0
    }
8588
0
      } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8589
0
    ns = ctxt->targetNamespace;
8590
0
  }
8591
0
  decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8592
0
  if (decl == NULL) {
8593
0
      goto return_null;
8594
0
  }
8595
  /*
8596
  * Check for illegal attributes.
8597
  */
8598
0
  attr = node->properties;
8599
0
  while (attr != NULL) {
8600
0
      if (attr->ns == NULL) {
8601
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8602
0
        (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8603
0
        (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8604
0
        (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8605
0
        (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8606
0
        (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8607
0
        (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8608
0
    {
8609
0
        if (topLevel == 0) {
8610
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8611
0
          (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8612
0
          (!xmlStrEqual(attr->name, BAD_CAST "form")))
8613
0
      {
8614
0
          xmlSchemaPIllegalAttrErr(ctxt,
8615
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8616
0
      }
8617
0
        } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8618
0
      (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8619
0
      (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8620
8621
0
      xmlSchemaPIllegalAttrErr(ctxt,
8622
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8623
0
        }
8624
0
    }
8625
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8626
8627
0
    xmlSchemaPIllegalAttrErr(ctxt,
8628
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8629
0
      }
8630
0
      attr = attr->next;
8631
0
  }
8632
  /*
8633
  * Extract/validate attributes.
8634
  */
8635
0
  if (topLevel) {
8636
      /*
8637
      * Process top attributes of global element declarations here.
8638
      */
8639
0
      decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8640
0
      decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8641
0
      xmlSchemaPValAttrQName(ctxt, schema,
8642
0
    NULL, node, "substitutionGroup",
8643
0
    &(decl->substGroupNs), &(decl->substGroup));
8644
0
      if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8645
0
    decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8646
      /*
8647
      * Attribute "final".
8648
      */
8649
0
      attr = xmlSchemaGetPropNode(node, "final");
8650
0
      if (attr == NULL) {
8651
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8652
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8653
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8654
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8655
0
      } else {
8656
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8657
0
    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8658
0
        -1,
8659
0
        XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8660
0
        XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8661
0
        xmlSchemaPSimpleTypeErr(ctxt,
8662
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8663
0
      NULL, (xmlNodePtr) attr,
8664
0
      NULL, "(#all | List of (extension | restriction))",
8665
0
      attrValue, NULL, NULL, NULL);
8666
0
    }
8667
0
      }
8668
0
  }
8669
  /*
8670
  * Attribute "block".
8671
  */
8672
0
  attr = xmlSchemaGetPropNode(node, "block");
8673
0
  if (attr == NULL) {
8674
      /*
8675
      * Apply default "block" values.
8676
      */
8677
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8678
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8679
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8680
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8681
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8682
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8683
0
  } else {
8684
0
      attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8685
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8686
0
    -1,
8687
0
    XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8688
0
    XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8689
0
    XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8690
0
    xmlSchemaPSimpleTypeErr(ctxt,
8691
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8692
0
        NULL, (xmlNodePtr) attr,
8693
0
        NULL, "(#all | List of (extension | "
8694
0
        "restriction | substitution))", attrValue,
8695
0
        NULL, NULL, NULL);
8696
0
      }
8697
0
  }
8698
0
  if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8699
0
      decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8700
8701
0
  attr = xmlSchemaGetPropNode(node, "type");
8702
0
  if (attr != NULL) {
8703
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8704
0
    NULL, attr,
8705
0
    &(decl->namedTypeNs), &(decl->namedType));
8706
0
      xmlSchemaCheckReference(ctxt, schema, node,
8707
0
    attr, decl->namedTypeNs);
8708
0
  }
8709
0
  decl->value = xmlSchemaGetProp(ctxt, node, "default");
8710
0
  attr = xmlSchemaGetPropNode(node, "fixed");
8711
0
  if (attr != NULL) {
8712
0
      fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8713
0
      if (decl->value != NULL) {
8714
    /*
8715
    * 3.3.3 : 1
8716
    * default and fixed must not both be present.
8717
    */
8718
0
    xmlSchemaPMutualExclAttrErr(ctxt,
8719
0
        XML_SCHEMAP_SRC_ELEMENT_1,
8720
0
        NULL, attr, "default", "fixed");
8721
0
      } else {
8722
0
    decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8723
0
    decl->value = fixed;
8724
0
      }
8725
0
  }
8726
  /*
8727
  * And now for the children...
8728
  */
8729
0
  if (IS_SCHEMA(child, "complexType")) {
8730
      /*
8731
      * 3.3.3 : 3
8732
      * "type" and either <simpleType> or <complexType> are mutually
8733
      * exclusive
8734
      */
8735
0
      if (decl->namedType != NULL) {
8736
0
    xmlSchemaPContentErr(ctxt,
8737
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8738
0
        NULL, node, child,
8739
0
        "The attribute 'type' and the <complexType> child are "
8740
0
        "mutually exclusive", NULL);
8741
0
      } else
8742
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8743
0
      child = child->next;
8744
0
  } else if (IS_SCHEMA(child, "simpleType")) {
8745
      /*
8746
      * 3.3.3 : 3
8747
      * "type" and either <simpleType> or <complexType> are
8748
      * mutually exclusive
8749
      */
8750
0
      if (decl->namedType != NULL) {
8751
0
    xmlSchemaPContentErr(ctxt,
8752
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8753
0
        NULL, node, child,
8754
0
        "The attribute 'type' and the <simpleType> child are "
8755
0
        "mutually exclusive", NULL);
8756
0
      } else
8757
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8758
0
      child = child->next;
8759
0
  }
8760
0
  while ((IS_SCHEMA(child, "unique")) ||
8761
0
      (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8762
0
      if (IS_SCHEMA(child, "unique")) {
8763
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8764
0
        XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8765
0
      } else if (IS_SCHEMA(child, "key")) {
8766
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8767
0
        XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8768
0
      } else if (IS_SCHEMA(child, "keyref")) {
8769
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8770
0
        XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8771
0
      }
8772
0
      if (lastIDC != NULL)
8773
0
    lastIDC->next = curIDC;
8774
0
      else
8775
0
    decl->idcs = (void *) curIDC;
8776
0
      lastIDC = curIDC;
8777
0
      child = child->next;
8778
0
  }
8779
0
  if (child != NULL) {
8780
0
      xmlSchemaPContentErr(ctxt,
8781
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8782
0
    NULL, node, child,
8783
0
    NULL, "(annotation?, ((simpleType | complexType)?, "
8784
0
    "(unique | key | keyref)*))");
8785
0
  }
8786
0
  decl->annot = annot;
8787
0
    }
8788
    /*
8789
    * NOTE: Element Declaration Representation OK 4. will be checked at a
8790
    * different layer.
8791
    */
8792
0
    FREE_AND_NULL(des)
8793
0
    if (topLevel)
8794
0
  return ((xmlSchemaBasicItemPtr) decl);
8795
0
    else {
8796
0
  particle->children = (xmlSchemaTreeItemPtr) decl;
8797
0
  return ((xmlSchemaBasicItemPtr) particle);
8798
0
    }
8799
8800
0
return_null:
8801
0
    FREE_AND_NULL(des);
8802
0
    if (annot != NULL) {
8803
0
  if (particle != NULL)
8804
0
      particle->annot = NULL;
8805
0
  if (decl != NULL)
8806
0
      decl->annot = NULL;
8807
0
  xmlSchemaFreeAnnot(annot);
8808
0
    }
8809
0
    return (NULL);
8810
0
}
8811
8812
/**
8813
 * xmlSchemaParseUnion:
8814
 * @ctxt:  a schema validation context
8815
 * @schema:  the schema being built
8816
 * @node:  a subtree containing XML Schema information
8817
 *
8818
 * parse a XML schema Union definition
8819
 * *WARNING* this interface is highly subject to change
8820
 *
8821
 * Returns -1 in case of internal error, 0 in case of success and a positive
8822
 * error code otherwise.
8823
 */
8824
static int
8825
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8826
                    xmlNodePtr node)
8827
0
{
8828
0
    xmlSchemaTypePtr type;
8829
0
    xmlNodePtr child = NULL;
8830
0
    xmlAttrPtr attr;
8831
0
    const xmlChar *cur = NULL;
8832
8833
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8834
0
        return (-1);
8835
    /* Not a component, don't create it. */
8836
0
    type = ctxt->ctxtType;
8837
    /*
8838
    * Mark the simple type as being of variety "union".
8839
    */
8840
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8841
    /*
8842
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8843
    * then the `simple ur-type definition`."
8844
    */
8845
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8846
    /*
8847
    * Check for illegal attributes.
8848
    */
8849
0
    attr = node->properties;
8850
0
    while (attr != NULL) {
8851
0
  if (attr->ns == NULL) {
8852
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8853
0
    (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8854
0
    xmlSchemaPIllegalAttrErr(ctxt,
8855
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8856
0
      }
8857
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8858
0
      xmlSchemaPIllegalAttrErr(ctxt,
8859
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8860
0
  }
8861
0
  attr = attr->next;
8862
0
    }
8863
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8864
    /*
8865
    * Attribute "memberTypes". This is a list of QNames.
8866
    * TODO: Check the value to contain anything.
8867
    */
8868
0
    attr = xmlSchemaGetPropNode(node, "memberTypes");
8869
0
    if (attr != NULL) {
8870
0
  const xmlChar *end;
8871
0
  xmlChar *tmp;
8872
0
  const xmlChar *localName, *nsName;
8873
0
  xmlSchemaTypeLinkPtr link, lastLink = NULL;
8874
0
  xmlSchemaQNameRefPtr ref;
8875
8876
0
  cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8877
0
        if (cur == NULL)
8878
0
            return (-1);
8879
0
  type->base = cur;
8880
0
  do {
8881
0
      while (IS_BLANK_CH(*cur))
8882
0
    cur++;
8883
0
      end = cur;
8884
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8885
0
    end++;
8886
0
      if (end == cur)
8887
0
    break;
8888
0
      tmp = xmlStrndup(cur, end - cur);
8889
0
            if (tmp == NULL) {
8890
0
                xmlSchemaPErrMemory(ctxt);
8891
0
                return (-1);
8892
0
            }
8893
0
      if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8894
0
    NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
8895
    /*
8896
    * Create the member type link.
8897
    */
8898
0
    link = (xmlSchemaTypeLinkPtr)
8899
0
        xmlMalloc(sizeof(xmlSchemaTypeLink));
8900
0
    if (link == NULL) {
8901
0
        xmlSchemaPErrMemory(ctxt);
8902
0
              FREE_AND_NULL(tmp)
8903
0
        return (-1);
8904
0
    }
8905
0
    link->type = NULL;
8906
0
    link->next = NULL;
8907
0
    if (lastLink == NULL)
8908
0
        type->memberTypes = link;
8909
0
    else
8910
0
        lastLink->next = link;
8911
0
    lastLink = link;
8912
    /*
8913
    * Create a reference item.
8914
    */
8915
0
    ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8916
0
        localName, nsName);
8917
0
    if (ref == NULL) {
8918
0
        FREE_AND_NULL(tmp)
8919
0
        return (-1);
8920
0
    }
8921
    /*
8922
    * Assign the reference to the link, it will be resolved
8923
    * later during fixup of the union simple type.
8924
    */
8925
0
    link->type = (xmlSchemaTypePtr) ref;
8926
0
      }
8927
0
      FREE_AND_NULL(tmp)
8928
0
      cur = end;
8929
0
  } while (*cur != 0);
8930
8931
0
    }
8932
    /*
8933
    * And now for the children...
8934
    */
8935
0
    child = node->children;
8936
0
    if (IS_SCHEMA(child, "annotation")) {
8937
  /*
8938
  * Add the annotation to the simple type ancestor.
8939
  */
8940
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8941
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8942
0
        child = child->next;
8943
0
    }
8944
0
    if (IS_SCHEMA(child, "simpleType")) {
8945
0
  xmlSchemaTypePtr subtype, last = NULL;
8946
8947
  /*
8948
  * Anchor the member types in the "subtypes" field of the
8949
  * simple type.
8950
  */
8951
0
  while (IS_SCHEMA(child, "simpleType")) {
8952
0
      subtype = (xmlSchemaTypePtr)
8953
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8954
0
      if (subtype != NULL) {
8955
0
    if (last == NULL) {
8956
0
        type->subtypes = subtype;
8957
0
        last = subtype;
8958
0
    } else {
8959
0
        last->next = subtype;
8960
0
        last = subtype;
8961
0
    }
8962
0
    last->next = NULL;
8963
0
      }
8964
0
      child = child->next;
8965
0
  }
8966
0
    }
8967
0
    if (child != NULL) {
8968
0
  xmlSchemaPContentErr(ctxt,
8969
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8970
0
      NULL, node, child, NULL, "(annotation?, simpleType*)");
8971
0
    }
8972
0
    if ((attr == NULL) && (type->subtypes == NULL)) {
8973
   /*
8974
  * src-union-memberTypes-or-simpleTypes
8975
  * Either the memberTypes [attribute] of the <union> element must
8976
  * be non-empty or there must be at least one simpleType [child].
8977
  */
8978
0
  xmlSchemaPCustomErr(ctxt,
8979
0
      XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8980
0
      NULL, node,
8981
0
      "Either the attribute 'memberTypes' or "
8982
0
      "at least one <simpleType> child must be present", NULL);
8983
0
    }
8984
0
    return (0);
8985
0
}
8986
8987
/**
8988
 * xmlSchemaParseList:
8989
 * @ctxt:  a schema validation context
8990
 * @schema:  the schema being built
8991
 * @node:  a subtree containing XML Schema information
8992
 *
8993
 * parse a XML schema List definition
8994
 * *WARNING* this interface is highly subject to change
8995
 *
8996
 * Returns -1 in case of error, 0 if the declaration is improper and
8997
 *         1 in case of success.
8998
 */
8999
static xmlSchemaTypePtr
9000
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9001
                   xmlNodePtr node)
9002
0
{
9003
0
    xmlSchemaTypePtr type;
9004
0
    xmlNodePtr child = NULL;
9005
0
    xmlAttrPtr attr;
9006
9007
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9008
0
        return (NULL);
9009
    /* Not a component, don't create it. */
9010
0
    type = ctxt->ctxtType;
9011
    /*
9012
    * Mark the type as being of variety "list".
9013
    */
9014
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9015
    /*
9016
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9017
    * then the `simple ur-type definition`."
9018
    */
9019
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9020
    /*
9021
    * Check for illegal attributes.
9022
    */
9023
0
    attr = node->properties;
9024
0
    while (attr != NULL) {
9025
0
  if (attr->ns == NULL) {
9026
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9027
0
    (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
9028
0
    xmlSchemaPIllegalAttrErr(ctxt,
9029
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9030
0
      }
9031
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9032
0
      xmlSchemaPIllegalAttrErr(ctxt,
9033
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9034
0
  }
9035
0
  attr = attr->next;
9036
0
    }
9037
9038
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9039
9040
    /*
9041
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9042
    * fields for holding the reference to the itemType.
9043
    *
9044
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9045
    * the "ref" fields.
9046
    */
9047
0
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
9048
0
  node, "itemType", &(type->baseNs), &(type->base));
9049
    /*
9050
    * And now for the children...
9051
    */
9052
0
    child = node->children;
9053
0
    if (IS_SCHEMA(child, "annotation")) {
9054
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9055
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
9056
0
        child = child->next;
9057
0
    }
9058
0
    if (IS_SCHEMA(child, "simpleType")) {
9059
  /*
9060
  * src-list-itemType-or-simpleType
9061
  * Either the itemType [attribute] or the <simpleType> [child] of
9062
  * the <list> element must be present, but not both.
9063
  */
9064
0
  if (type->base != NULL) {
9065
0
      xmlSchemaPCustomErr(ctxt,
9066
0
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9067
0
    NULL, node,
9068
0
    "The attribute 'itemType' and the <simpleType> child "
9069
0
    "are mutually exclusive", NULL);
9070
0
  } else {
9071
0
      type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9072
0
  }
9073
0
        child = child->next;
9074
0
    } else if (type->base == NULL) {
9075
0
  xmlSchemaPCustomErr(ctxt,
9076
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9077
0
      NULL, node,
9078
0
      "Either the attribute 'itemType' or the <simpleType> child "
9079
0
      "must be present", NULL);
9080
0
    }
9081
0
    if (child != NULL) {
9082
0
  xmlSchemaPContentErr(ctxt,
9083
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9084
0
      NULL, node, child, NULL, "(annotation?, simpleType?)");
9085
0
    }
9086
0
    if ((type->base == NULL) &&
9087
0
  (type->subtypes == NULL) &&
9088
0
  (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9089
0
  xmlSchemaPCustomErr(ctxt,
9090
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9091
0
      NULL, node,
9092
0
      "Either the attribute 'itemType' or the <simpleType> child "
9093
0
      "must be present", NULL);
9094
0
    }
9095
0
    return (NULL);
9096
0
}
9097
9098
/**
9099
 * xmlSchemaParseSimpleType:
9100
 * @ctxt:  a schema validation context
9101
 * @schema:  the schema being built
9102
 * @node:  a subtree containing XML Schema information
9103
 *
9104
 * parse a XML schema Simple Type definition
9105
 * *WARNING* this interface is highly subject to change
9106
 *
9107
 * Returns -1 in case of error, 0 if the declaration is improper and
9108
 * 1 in case of success.
9109
 */
9110
static xmlSchemaTypePtr
9111
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9112
                         xmlNodePtr node, int topLevel)
9113
0
{
9114
0
    xmlSchemaTypePtr type, oldCtxtType;
9115
0
    xmlNodePtr child = NULL;
9116
0
    const xmlChar *attrValue = NULL;
9117
0
    xmlAttrPtr attr;
9118
0
    int hasRestriction = 0;
9119
9120
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9121
0
        return (NULL);
9122
9123
0
    if (topLevel) {
9124
0
  attr = xmlSchemaGetPropNode(node, "name");
9125
0
  if (attr == NULL) {
9126
0
      xmlSchemaPMissingAttrErr(ctxt,
9127
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
9128
0
    NULL, node,
9129
0
    "name", NULL);
9130
0
      return (NULL);
9131
0
  } else {
9132
0
      if (xmlSchemaPValAttrNode(ctxt,
9133
0
    NULL, attr,
9134
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9135
0
    return (NULL);
9136
      /*
9137
      * Skip built-in types.
9138
      */
9139
0
      if (ctxt->isS4S) {
9140
0
    xmlSchemaTypePtr biType;
9141
9142
0
    if (ctxt->isRedefine) {
9143
        /*
9144
        * REDEFINE: Disallow redefinition of built-in-types.
9145
        * TODO: It seems that the spec does not say anything
9146
        * about this case.
9147
        */
9148
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9149
0
      NULL, node,
9150
0
      "Redefinition of built-in simple types is not "
9151
0
      "supported", NULL);
9152
0
        return(NULL);
9153
0
    }
9154
0
    biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9155
0
    if (biType != NULL)
9156
0
        return (biType);
9157
0
      }
9158
0
  }
9159
0
    }
9160
    /*
9161
    * TargetNamespace:
9162
    * SPEC "The `actual value` of the targetNamespace [attribute]
9163
    * of the <schema> ancestor element information item if present,
9164
    * otherwise `absent`.
9165
    */
9166
0
    if (topLevel == 0) {
9167
#ifdef ENABLE_NAMED_LOCALS
9168
        char buf[40];
9169
#endif
9170
  /*
9171
  * Parse as local simple type definition.
9172
  */
9173
#ifdef ENABLE_NAMED_LOCALS
9174
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9175
  type = xmlSchemaAddType(ctxt, schema,
9176
      XML_SCHEMA_TYPE_SIMPLE,
9177
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9178
      ctxt->targetNamespace, node, 0);
9179
#else
9180
0
  type = xmlSchemaAddType(ctxt, schema,
9181
0
      XML_SCHEMA_TYPE_SIMPLE,
9182
0
      NULL, ctxt->targetNamespace, node, 0);
9183
0
#endif
9184
0
  if (type == NULL)
9185
0
      return (NULL);
9186
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9187
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9188
  /*
9189
  * Check for illegal attributes.
9190
  */
9191
0
  attr = node->properties;
9192
0
  while (attr != NULL) {
9193
0
      if (attr->ns == NULL) {
9194
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9195
0
        xmlSchemaPIllegalAttrErr(ctxt,
9196
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9197
0
    }
9198
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9199
0
        xmlSchemaPIllegalAttrErr(ctxt,
9200
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9201
0
      }
9202
0
      attr = attr->next;
9203
0
  }
9204
0
    } else {
9205
  /*
9206
  * Parse as global simple type definition.
9207
  *
9208
  * Note that attrValue is the value of the attribute "name" here.
9209
  */
9210
0
  type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9211
0
      attrValue, ctxt->targetNamespace, node, 1);
9212
0
  if (type == NULL)
9213
0
      return (NULL);
9214
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9215
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9216
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9217
  /*
9218
  * Check for illegal attributes.
9219
  */
9220
0
  attr = node->properties;
9221
0
  while (attr != NULL) {
9222
0
      if (attr->ns == NULL) {
9223
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9224
0
        (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9225
0
        (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9226
0
        xmlSchemaPIllegalAttrErr(ctxt,
9227
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9228
0
    }
9229
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9230
0
    xmlSchemaPIllegalAttrErr(ctxt,
9231
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9232
0
      }
9233
0
      attr = attr->next;
9234
0
  }
9235
  /*
9236
  * Attribute "final".
9237
  */
9238
0
  attr = xmlSchemaGetPropNode(node, "final");
9239
0
  if (attr == NULL) {
9240
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9241
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9242
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9243
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9244
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9245
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9246
0
  } else {
9247
0
      attrValue = xmlSchemaGetProp(ctxt, node, "final");
9248
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9249
0
    -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9250
0
    XML_SCHEMAS_TYPE_FINAL_LIST,
9251
0
    XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9252
9253
0
    xmlSchemaPSimpleTypeErr(ctxt,
9254
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9255
0
        WXS_BASIC_CAST type, (xmlNodePtr) attr,
9256
0
        NULL, "(#all | List of (list | union | restriction)",
9257
0
        attrValue, NULL, NULL, NULL);
9258
0
      }
9259
0
  }
9260
0
    }
9261
0
    type->targetNamespace = ctxt->targetNamespace;
9262
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9263
    /*
9264
    * And now for the children...
9265
    */
9266
0
    oldCtxtType = ctxt->ctxtType;
9267
9268
0
    ctxt->ctxtType = type;
9269
9270
0
    child = node->children;
9271
0
    if (IS_SCHEMA(child, "annotation")) {
9272
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9273
0
        child = child->next;
9274
0
    }
9275
0
    if (child == NULL) {
9276
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9277
0
      NULL, node, child, NULL,
9278
0
      "(annotation?, (restriction | list | union))");
9279
0
    } else if (IS_SCHEMA(child, "restriction")) {
9280
0
        xmlSchemaParseRestriction(ctxt, schema, child,
9281
0
      XML_SCHEMA_TYPE_SIMPLE);
9282
0
  hasRestriction = 1;
9283
0
        child = child->next;
9284
0
    } else if (IS_SCHEMA(child, "list")) {
9285
0
        xmlSchemaParseList(ctxt, schema, child);
9286
0
        child = child->next;
9287
0
    } else if (IS_SCHEMA(child, "union")) {
9288
0
        xmlSchemaParseUnion(ctxt, schema, child);
9289
0
        child = child->next;
9290
0
    }
9291
0
    if (child != NULL) {
9292
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9293
0
      NULL, node, child, NULL,
9294
0
      "(annotation?, (restriction | list | union))");
9295
0
    }
9296
    /*
9297
    * REDEFINE: SPEC src-redefine (5)
9298
    * "Within the [children], each <simpleType> must have a
9299
    * <restriction> among its [children] ... the `actual value` of whose
9300
    * base [attribute] must be the same as the `actual value` of its own
9301
    * name attribute plus target namespace;"
9302
    */
9303
0
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9304
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9305
0
      NULL, node, "This is a redefinition, thus the "
9306
0
      "<simpleType> must have a <restriction> child", NULL);
9307
0
    }
9308
9309
0
    ctxt->ctxtType = oldCtxtType;
9310
0
    return (type);
9311
0
}
9312
9313
/**
9314
 * xmlSchemaParseModelGroupDefRef:
9315
 * @ctxt:  the parser context
9316
 * @schema: the schema being built
9317
 * @node:  the node
9318
 *
9319
 * Parses a reference to a model group definition.
9320
 *
9321
 * We will return a particle component with a qname-component or
9322
 * NULL in case of an error.
9323
 */
9324
static xmlSchemaTreeItemPtr
9325
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9326
             xmlSchemaPtr schema,
9327
             xmlNodePtr node)
9328
0
{
9329
0
    xmlSchemaParticlePtr item;
9330
0
    xmlNodePtr child = NULL;
9331
0
    xmlAttrPtr attr;
9332
0
    const xmlChar *ref = NULL, *refNs = NULL;
9333
0
    int min, max;
9334
9335
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9336
0
        return (NULL);
9337
9338
0
    attr = xmlSchemaGetPropNode(node, "ref");
9339
0
    if (attr == NULL) {
9340
0
  xmlSchemaPMissingAttrErr(ctxt,
9341
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9342
0
      NULL, node, "ref", NULL);
9343
0
  return (NULL);
9344
0
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9345
0
  attr, &refNs, &ref) != 0) {
9346
0
  return (NULL);
9347
0
    }
9348
0
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9349
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9350
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9351
0
  "(xs:nonNegativeInteger | unbounded)");
9352
    /*
9353
    * Check for illegal attributes.
9354
    */
9355
0
    attr = node->properties;
9356
0
    while (attr != NULL) {
9357
0
  if (attr->ns == NULL) {
9358
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9359
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9360
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9361
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9362
0
    xmlSchemaPIllegalAttrErr(ctxt,
9363
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9364
0
      }
9365
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9366
0
      xmlSchemaPIllegalAttrErr(ctxt,
9367
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9368
0
  }
9369
0
  attr = attr->next;
9370
0
    }
9371
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9372
0
    item = xmlSchemaAddParticle(ctxt, node, min, max);
9373
0
    if (item == NULL)
9374
0
  return (NULL);
9375
    /*
9376
    * Create a qname-reference and set as the term; it will be substituted
9377
    * for the model group after the reference has been resolved.
9378
    */
9379
0
    item->children = (xmlSchemaTreeItemPtr)
9380
0
  xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9381
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9382
    /*
9383
    * And now for the children...
9384
    */
9385
0
    child = node->children;
9386
    /* TODO: Is annotation even allowed for a model group reference? */
9387
0
    if (IS_SCHEMA(child, "annotation")) {
9388
  /*
9389
  * TODO: What to do exactly with the annotation?
9390
  */
9391
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9392
0
  child = child->next;
9393
0
    }
9394
0
    if (child != NULL) {
9395
0
  xmlSchemaPContentErr(ctxt,
9396
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9397
0
      NULL, node, child, NULL,
9398
0
      "(annotation?)");
9399
0
    }
9400
    /*
9401
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
9402
    */
9403
0
    if ((min == 0) && (max == 0))
9404
0
  return (NULL);
9405
9406
0
    return ((xmlSchemaTreeItemPtr) item);
9407
0
}
9408
9409
/**
9410
 * xmlSchemaParseModelGroupDefinition:
9411
 * @ctxt:  a schema validation context
9412
 * @schema:  the schema being built
9413
 * @node:  a subtree containing XML Schema information
9414
 *
9415
 * Parses a XML schema model group definition.
9416
 *
9417
 * Note that the constraint src-redefine (6.2) can't be applied until
9418
 * references have been resolved. So we will do this at the
9419
 * component fixup level.
9420
 *
9421
 * *WARNING* this interface is highly subject to change
9422
 *
9423
 * Returns -1 in case of error, 0 if the declaration is improper and
9424
 *         1 in case of success.
9425
 */
9426
static xmlSchemaModelGroupDefPtr
9427
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9428
           xmlSchemaPtr schema,
9429
           xmlNodePtr node)
9430
0
{
9431
0
    xmlSchemaModelGroupDefPtr item;
9432
0
    xmlNodePtr child = NULL;
9433
0
    xmlAttrPtr attr;
9434
0
    const xmlChar *name;
9435
9436
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9437
0
        return (NULL);
9438
9439
0
    attr = xmlSchemaGetPropNode(node, "name");
9440
0
    if (attr == NULL) {
9441
0
  xmlSchemaPMissingAttrErr(ctxt,
9442
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9443
0
      NULL, node,
9444
0
      "name", NULL);
9445
0
  return (NULL);
9446
0
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9447
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9448
0
  return (NULL);
9449
0
    }
9450
0
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9451
0
  ctxt->targetNamespace, node);
9452
0
    if (item == NULL)
9453
0
  return (NULL);
9454
    /*
9455
    * Check for illegal attributes.
9456
    */
9457
0
    attr = node->properties;
9458
0
    while (attr != NULL) {
9459
0
  if (attr->ns == NULL) {
9460
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9461
0
    (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9462
0
    xmlSchemaPIllegalAttrErr(ctxt,
9463
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9464
0
      }
9465
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9466
0
      xmlSchemaPIllegalAttrErr(ctxt,
9467
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9468
0
  }
9469
0
  attr = attr->next;
9470
0
    }
9471
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9472
    /*
9473
    * And now for the children...
9474
    */
9475
0
    child = node->children;
9476
0
    if (IS_SCHEMA(child, "annotation")) {
9477
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9478
0
  child = child->next;
9479
0
    }
9480
0
    if (IS_SCHEMA(child, "all")) {
9481
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9482
0
      XML_SCHEMA_TYPE_ALL, 0);
9483
0
  child = child->next;
9484
0
    } else if (IS_SCHEMA(child, "choice")) {
9485
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9486
0
      XML_SCHEMA_TYPE_CHOICE, 0);
9487
0
  child = child->next;
9488
0
    } else if (IS_SCHEMA(child, "sequence")) {
9489
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9490
0
      XML_SCHEMA_TYPE_SEQUENCE, 0);
9491
0
  child = child->next;
9492
0
    }
9493
9494
9495
9496
0
    if (child != NULL) {
9497
0
  xmlSchemaPContentErr(ctxt,
9498
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9499
0
      NULL, node, child, NULL,
9500
0
      "(annotation?, (all | choice | sequence)?)");
9501
0
    }
9502
0
    return (item);
9503
0
}
9504
9505
/**
9506
 * xmlSchemaCleanupDoc:
9507
 * @ctxt:  a schema validation context
9508
 * @node:  the root of the document.
9509
 *
9510
 * removes unwanted nodes in a schemas document tree
9511
 */
9512
static void
9513
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9514
0
{
9515
0
    xmlNodePtr delete, cur;
9516
9517
0
    if ((ctxt == NULL) || (root == NULL)) return;
9518
9519
    /*
9520
     * Remove all the blank text nodes
9521
     */
9522
0
    delete = NULL;
9523
0
    cur = root;
9524
0
    while (cur != NULL) {
9525
0
        if (delete != NULL) {
9526
0
            xmlUnlinkNode(delete);
9527
0
            xmlFreeNode(delete);
9528
0
            delete = NULL;
9529
0
        }
9530
0
        if (cur->type == XML_TEXT_NODE) {
9531
0
            if (IS_BLANK_NODE(cur)) {
9532
0
                if (xmlNodeGetSpacePreserve(cur) != 1) {
9533
0
                    delete = cur;
9534
0
                }
9535
0
            }
9536
0
        } else if ((cur->type != XML_ELEMENT_NODE) &&
9537
0
                   (cur->type != XML_CDATA_SECTION_NODE)) {
9538
0
            delete = cur;
9539
0
            goto skip_children;
9540
0
        }
9541
9542
        /*
9543
         * Skip to next node
9544
         */
9545
0
        if (cur->children != NULL) {
9546
0
            if ((cur->children->type != XML_ENTITY_DECL) &&
9547
0
                (cur->children->type != XML_ENTITY_REF_NODE) &&
9548
0
                (cur->children->type != XML_ENTITY_NODE)) {
9549
0
                cur = cur->children;
9550
0
                continue;
9551
0
            }
9552
0
        }
9553
0
      skip_children:
9554
0
        if (cur->next != NULL) {
9555
0
            cur = cur->next;
9556
0
            continue;
9557
0
        }
9558
9559
0
        do {
9560
0
            cur = cur->parent;
9561
0
            if (cur == NULL)
9562
0
                break;
9563
0
            if (cur == root) {
9564
0
                cur = NULL;
9565
0
                break;
9566
0
            }
9567
0
            if (cur->next != NULL) {
9568
0
                cur = cur->next;
9569
0
                break;
9570
0
            }
9571
0
        } while (cur != NULL);
9572
0
    }
9573
0
    if (delete != NULL) {
9574
0
        xmlUnlinkNode(delete);
9575
0
        xmlFreeNode(delete);
9576
0
        delete = NULL;
9577
0
    }
9578
0
}
9579
9580
9581
static void
9582
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9583
0
{
9584
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9585
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9586
9587
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9588
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9589
9590
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9591
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9592
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9593
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9594
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9595
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9596
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9597
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9598
9599
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9600
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9601
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9602
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9603
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9604
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9605
0
}
9606
9607
static int
9608
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9609
           xmlSchemaPtr schema,
9610
           xmlNodePtr node)
9611
0
{
9612
0
    xmlAttrPtr attr;
9613
0
    const xmlChar *val;
9614
0
    int res = 0, oldErrs = ctxt->nberrors;
9615
9616
    /*
9617
    * Those flags should be moved to the parser context flags,
9618
    * since they are not visible at the component level. I.e.
9619
    * they are used if processing schema *documents* only.
9620
    */
9621
0
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9622
0
    HFAILURE;
9623
9624
    /*
9625
    * Since the version is of type xs:token, we won't bother to
9626
    * check it.
9627
    */
9628
    /* REMOVED:
9629
    attr = xmlSchemaGetPropNode(node, "version");
9630
    if (attr != NULL) {
9631
  res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9632
      xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9633
  HFAILURE;
9634
    }
9635
    */
9636
0
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
9637
0
    if (attr != NULL) {
9638
0
  res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9639
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9640
0
  HFAILURE;
9641
0
  if (res != 0) {
9642
0
      ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9643
0
      goto exit;
9644
0
  }
9645
0
    }
9646
0
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9647
0
    if (attr != NULL) {
9648
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9649
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9650
0
      XML_SCHEMAS_QUALIF_ELEM);
9651
0
  HFAILURE;
9652
0
  if (res != 0) {
9653
0
      xmlSchemaPSimpleTypeErr(ctxt,
9654
0
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9655
0
    NULL, (xmlNodePtr) attr, NULL,
9656
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9657
0
  }
9658
0
    }
9659
0
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9660
0
    if (attr != NULL) {
9661
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9662
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9663
0
      XML_SCHEMAS_QUALIF_ATTR);
9664
0
  HFAILURE;
9665
0
  if (res != 0) {
9666
0
      xmlSchemaPSimpleTypeErr(ctxt,
9667
0
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9668
0
    NULL, (xmlNodePtr) attr, NULL,
9669
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9670
0
  }
9671
0
    }
9672
0
    attr = xmlSchemaGetPropNode(node, "finalDefault");
9673
0
    if (attr != NULL) {
9674
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9675
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9676
0
      XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9677
0
      XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9678
0
      -1,
9679
0
      XML_SCHEMAS_FINAL_DEFAULT_LIST,
9680
0
      XML_SCHEMAS_FINAL_DEFAULT_UNION);
9681
0
  HFAILURE;
9682
0
  if (res != 0) {
9683
0
      xmlSchemaPSimpleTypeErr(ctxt,
9684
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9685
0
    NULL, (xmlNodePtr) attr, NULL,
9686
0
    "(#all | List of (extension | restriction | list | union))",
9687
0
    val, NULL, NULL, NULL);
9688
0
  }
9689
0
    }
9690
0
    attr = xmlSchemaGetPropNode(node, "blockDefault");
9691
0
    if (attr != NULL) {
9692
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9693
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9694
0
      XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9695
0
      XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9696
0
      XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9697
0
  HFAILURE;
9698
0
  if (res != 0) {
9699
0
      xmlSchemaPSimpleTypeErr(ctxt,
9700
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9701
0
    NULL, (xmlNodePtr) attr, NULL,
9702
0
    "(#all | List of (extension | restriction | substitution))",
9703
0
    val, NULL, NULL, NULL);
9704
0
  }
9705
0
    }
9706
9707
0
exit:
9708
0
    if (oldErrs != ctxt->nberrors)
9709
0
  res = ctxt->err;
9710
0
    return(res);
9711
0
exit_failure:
9712
0
    return(-1);
9713
0
}
9714
9715
/**
9716
 * xmlSchemaParseSchemaTopLevel:
9717
 * @ctxt:  a schema validation context
9718
 * @schema:  the schemas
9719
 * @nodes:  the list of top level nodes
9720
 *
9721
 * Returns the internal XML Schema structure built from the resource or
9722
 *         NULL in case of error
9723
 */
9724
static int
9725
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9726
                             xmlSchemaPtr schema, xmlNodePtr nodes)
9727
0
{
9728
0
    xmlNodePtr child;
9729
0
    xmlSchemaAnnotPtr annot;
9730
0
    int res = 0, oldErrs, tmpOldErrs;
9731
9732
0
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9733
0
        return(-1);
9734
9735
0
    oldErrs = ctxt->nberrors;
9736
0
    child = nodes;
9737
0
    while ((IS_SCHEMA(child, "include")) ||
9738
0
     (IS_SCHEMA(child, "import")) ||
9739
0
     (IS_SCHEMA(child, "redefine")) ||
9740
0
     (IS_SCHEMA(child, "annotation"))) {
9741
0
  if (IS_SCHEMA(child, "annotation")) {
9742
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9743
0
      if (schema->annot == NULL)
9744
0
    schema->annot = annot;
9745
0
      else
9746
0
    xmlSchemaFreeAnnot(annot);
9747
0
  } else if (IS_SCHEMA(child, "import")) {
9748
0
      tmpOldErrs = ctxt->nberrors;
9749
0
      res = xmlSchemaParseImport(ctxt, schema, child);
9750
0
      HFAILURE;
9751
0
      HSTOP(ctxt);
9752
0
      if (tmpOldErrs != ctxt->nberrors)
9753
0
    goto exit;
9754
0
  } else if (IS_SCHEMA(child, "include")) {
9755
0
      tmpOldErrs = ctxt->nberrors;
9756
0
      res = xmlSchemaParseInclude(ctxt, schema, child);
9757
0
      HFAILURE;
9758
0
      HSTOP(ctxt);
9759
0
      if (tmpOldErrs != ctxt->nberrors)
9760
0
    goto exit;
9761
0
  } else if (IS_SCHEMA(child, "redefine")) {
9762
0
      tmpOldErrs = ctxt->nberrors;
9763
0
      res = xmlSchemaParseRedefine(ctxt, schema, child);
9764
0
      HFAILURE;
9765
0
      HSTOP(ctxt);
9766
0
      if (tmpOldErrs != ctxt->nberrors)
9767
0
    goto exit;
9768
0
  }
9769
0
  child = child->next;
9770
0
    }
9771
    /*
9772
    * URGENT TODO: Change the functions to return int results.
9773
    * We need especially to catch internal errors.
9774
    */
9775
0
    while (child != NULL) {
9776
0
  if (IS_SCHEMA(child, "complexType")) {
9777
0
      xmlSchemaParseComplexType(ctxt, schema, child, 1);
9778
0
      child = child->next;
9779
0
  } else if (IS_SCHEMA(child, "simpleType")) {
9780
0
      xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9781
0
      child = child->next;
9782
0
  } else if (IS_SCHEMA(child, "element")) {
9783
0
      xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9784
0
      child = child->next;
9785
0
  } else if (IS_SCHEMA(child, "attribute")) {
9786
0
      xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9787
0
      child = child->next;
9788
0
  } else if (IS_SCHEMA(child, "attributeGroup")) {
9789
0
      xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9790
0
      child = child->next;
9791
0
  } else if (IS_SCHEMA(child, "group")) {
9792
0
      xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9793
0
      child = child->next;
9794
0
  } else if (IS_SCHEMA(child, "notation")) {
9795
0
      xmlSchemaParseNotation(ctxt, schema, child);
9796
0
      child = child->next;
9797
0
  } else {
9798
0
      xmlSchemaPContentErr(ctxt,
9799
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9800
0
    NULL, child->parent, child,
9801
0
    NULL, "((include | import | redefine | annotation)*, "
9802
0
    "(((simpleType | complexType | group | attributeGroup) "
9803
0
    "| element | attribute | notation), annotation*)*)");
9804
0
      child = child->next;
9805
0
  }
9806
0
  while (IS_SCHEMA(child, "annotation")) {
9807
      /*
9808
      * TODO: We should add all annotations.
9809
      */
9810
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9811
0
      if (schema->annot == NULL)
9812
0
    schema->annot = annot;
9813
0
      else
9814
0
    xmlSchemaFreeAnnot(annot);
9815
0
      child = child->next;
9816
0
  }
9817
0
    }
9818
0
exit:
9819
0
    ctxt->ctxtType = NULL;
9820
0
    if (oldErrs != ctxt->nberrors)
9821
0
  res = ctxt->err;
9822
0
    return(res);
9823
0
exit_failure:
9824
0
    return(-1);
9825
0
}
9826
9827
static xmlSchemaSchemaRelationPtr
9828
xmlSchemaSchemaRelationCreate(void)
9829
0
{
9830
0
    xmlSchemaSchemaRelationPtr ret;
9831
9832
0
    ret = (xmlSchemaSchemaRelationPtr)
9833
0
  xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9834
0
    if (ret == NULL) {
9835
0
  xmlSchemaPErrMemory(NULL);
9836
0
  return(NULL);
9837
0
    }
9838
0
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9839
0
    return(ret);
9840
0
}
9841
9842
#if 0
9843
static void
9844
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9845
{
9846
    xmlFree(rel);
9847
}
9848
#endif
9849
9850
static void
9851
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9852
0
{
9853
0
    xmlSchemaRedefPtr prev;
9854
9855
0
    while (redef != NULL) {
9856
0
  prev = redef;
9857
0
  redef = redef->next;
9858
0
  xmlFree(prev);
9859
0
    }
9860
0
}
9861
9862
static void
9863
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9864
0
{
9865
    /*
9866
    * After the construction context has been freed, there will be
9867
    * no schema graph available any more. Only the schema buckets
9868
    * will stay alive, which are put into the "schemasImports" and
9869
    * "includes" slots of the xmlSchema.
9870
    */
9871
0
    if (con->buckets != NULL)
9872
0
  xmlSchemaItemListFree(con->buckets);
9873
0
    if (con->pending != NULL)
9874
0
  xmlSchemaItemListFree(con->pending);
9875
0
    if (con->substGroups != NULL)
9876
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9877
0
    if (con->redefs != NULL)
9878
0
  xmlSchemaRedefListFree(con->redefs);
9879
0
    if (con->dict != NULL)
9880
0
  xmlDictFree(con->dict);
9881
0
    xmlFree(con);
9882
0
}
9883
9884
static xmlSchemaConstructionCtxtPtr
9885
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9886
0
{
9887
0
    xmlSchemaConstructionCtxtPtr ret;
9888
9889
0
    ret = (xmlSchemaConstructionCtxtPtr)
9890
0
  xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9891
0
    if (ret == NULL) {
9892
0
        xmlSchemaPErrMemory(NULL);
9893
0
        return (NULL);
9894
0
    }
9895
0
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9896
9897
0
    ret->buckets = xmlSchemaItemListCreate();
9898
0
    if (ret->buckets == NULL) {
9899
0
  xmlSchemaPErrMemory(NULL);
9900
0
  xmlFree(ret);
9901
0
        return (NULL);
9902
0
    }
9903
0
    ret->pending = xmlSchemaItemListCreate();
9904
0
    if (ret->pending == NULL) {
9905
0
  xmlSchemaPErrMemory(NULL);
9906
0
  xmlSchemaConstructionCtxtFree(ret);
9907
0
        return (NULL);
9908
0
    }
9909
0
    ret->dict = dict;
9910
0
    xmlDictReference(dict);
9911
0
    return(ret);
9912
0
}
9913
9914
static xmlSchemaParserCtxtPtr
9915
xmlSchemaParserCtxtCreate(void)
9916
0
{
9917
0
    xmlSchemaParserCtxtPtr ret;
9918
9919
0
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9920
0
    if (ret == NULL) {
9921
0
        xmlSchemaPErrMemory(NULL);
9922
0
        return (NULL);
9923
0
    }
9924
0
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9925
0
    ret->type = XML_SCHEMA_CTXT_PARSER;
9926
0
    ret->attrProhibs = xmlSchemaItemListCreate();
9927
0
    if (ret->attrProhibs == NULL) {
9928
0
  xmlFree(ret);
9929
0
  return(NULL);
9930
0
    }
9931
0
    return(ret);
9932
0
}
9933
9934
/**
9935
 * xmlSchemaNewParserCtxtUseDict:
9936
 * @URL:  the location of the schema
9937
 * @dict: the dictionary to be used
9938
 *
9939
 * Create an XML Schemas parse context for that file/resource expected
9940
 * to contain an XML Schemas file.
9941
 *
9942
 * Returns the parser context or NULL in case of error
9943
 */
9944
static xmlSchemaParserCtxtPtr
9945
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9946
0
{
9947
0
    xmlSchemaParserCtxtPtr ret;
9948
9949
0
    ret = xmlSchemaParserCtxtCreate();
9950
0
    if (ret == NULL)
9951
0
        return (NULL);
9952
0
    ret->dict = dict;
9953
0
    xmlDictReference(dict);
9954
0
    if (URL != NULL)
9955
0
  ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9956
0
    return (ret);
9957
0
}
9958
9959
static int
9960
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9961
0
{
9962
0
    if (vctxt->pctxt == NULL) {
9963
0
        if (vctxt->schema != NULL)
9964
0
      vctxt->pctxt =
9965
0
    xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9966
0
  else
9967
0
      vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9968
0
  if (vctxt->pctxt == NULL) {
9969
0
      VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
9970
0
    "failed to create a temp. parser context");
9971
0
      return (-1);
9972
0
  }
9973
  /* TODO: Pass user data. */
9974
0
  xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9975
0
      vctxt->warning, vctxt->errCtxt);
9976
0
  xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9977
0
      vctxt->errCtxt);
9978
0
    }
9979
0
    return (0);
9980
0
}
9981
9982
/**
9983
 * xmlSchemaGetSchemaBucket:
9984
 * @pctxt: the schema parser context
9985
 * @schemaLocation: the URI of the schema document
9986
 *
9987
 * Returns a schema bucket if it was already parsed.
9988
 *
9989
 * Returns a schema bucket if it was already parsed from
9990
 *         @schemaLocation, NULL otherwise.
9991
 */
9992
static xmlSchemaBucketPtr
9993
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9994
          const xmlChar *schemaLocation)
9995
0
{
9996
0
    xmlSchemaBucketPtr cur;
9997
0
    xmlSchemaItemListPtr list;
9998
9999
0
    list = pctxt->constructor->buckets;
10000
0
    if (list->nbItems == 0)
10001
0
  return(NULL);
10002
0
    else {
10003
0
  int i;
10004
0
  for (i = 0; i < list->nbItems; i++) {
10005
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10006
      /* Pointer comparison! */
10007
0
      if (cur->schemaLocation == schemaLocation)
10008
0
    return(cur);
10009
0
  }
10010
0
    }
10011
0
    return(NULL);
10012
0
}
10013
10014
static xmlSchemaBucketPtr
10015
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10016
             const xmlChar *schemaLocation,
10017
             const xmlChar *targetNamespace)
10018
0
{
10019
0
    xmlSchemaBucketPtr cur;
10020
0
    xmlSchemaItemListPtr list;
10021
10022
0
    list = pctxt->constructor->buckets;
10023
0
    if (list->nbItems == 0)
10024
0
  return(NULL);
10025
0
    else {
10026
0
  int i;
10027
0
  for (i = 0; i < list->nbItems; i++) {
10028
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10029
      /* Pointer comparison! */
10030
0
      if ((cur->origTargetNamespace == NULL) &&
10031
0
    (cur->schemaLocation == schemaLocation) &&
10032
0
    (cur->targetNamespace == targetNamespace))
10033
0
    return(cur);
10034
0
  }
10035
0
    }
10036
0
    return(NULL);
10037
0
}
10038
10039
10040
#define IS_BAD_SCHEMA_DOC(b) \
10041
0
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10042
10043
static xmlSchemaBucketPtr
10044
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10045
         const xmlChar *targetNamespace,
10046
         int imported)
10047
0
{
10048
0
    xmlSchemaBucketPtr cur;
10049
0
    xmlSchemaItemListPtr list;
10050
10051
0
    list = pctxt->constructor->buckets;
10052
0
    if (list->nbItems == 0)
10053
0
  return(NULL);
10054
0
    else {
10055
0
  int i;
10056
0
  for (i = 0; i < list->nbItems; i++) {
10057
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10058
0
      if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10059
0
    (cur->origTargetNamespace == targetNamespace) &&
10060
0
    ((imported && cur->imported) ||
10061
0
     ((!imported) && (!cur->imported))))
10062
0
    return(cur);
10063
0
  }
10064
0
    }
10065
0
    return(NULL);
10066
0
}
10067
10068
static int
10069
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10070
         xmlSchemaPtr schema,
10071
         xmlSchemaBucketPtr bucket)
10072
0
{
10073
0
    int oldFlags;
10074
0
    xmlDocPtr oldDoc;
10075
0
    xmlNodePtr node;
10076
0
    int ret, oldErrs;
10077
0
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10078
10079
    /*
10080
    * Save old values; reset the *main* schema.
10081
    * URGENT TODO: This is not good; move the per-document information
10082
    * to the parser. Get rid of passing the main schema to the
10083
    * parsing functions.
10084
    */
10085
0
    oldFlags = schema->flags;
10086
0
    oldDoc = schema->doc;
10087
0
    if (schema->flags != 0)
10088
0
  xmlSchemaClearSchemaDefaults(schema);
10089
0
    schema->doc = bucket->doc;
10090
0
    pctxt->schema = schema;
10091
    /*
10092
    * Keep the current target namespace on the parser *not* on the
10093
    * main schema.
10094
    */
10095
0
    pctxt->targetNamespace = bucket->targetNamespace;
10096
0
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10097
10098
0
    if ((bucket->targetNamespace != NULL) &&
10099
0
  xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10100
  /*
10101
  * We are parsing the schema for schemas!
10102
  */
10103
0
  pctxt->isS4S = 1;
10104
0
    }
10105
    /* Mark it as parsed, even if parsing fails. */
10106
0
    bucket->parsed++;
10107
    /* Compile the schema doc. */
10108
0
    node = xmlDocGetRootElement(bucket->doc);
10109
0
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10110
0
    if (ret != 0)
10111
0
  goto exit;
10112
    /* An empty schema; just get out. */
10113
0
    if (node->children == NULL)
10114
0
  goto exit;
10115
0
    oldErrs = pctxt->nberrors;
10116
0
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10117
0
    if (ret != 0)
10118
0
  goto exit;
10119
    /*
10120
    * TODO: Not nice, but I'm not 100% sure we will get always an error
10121
    * as a result of the above functions; so better rely on pctxt->err
10122
    * as well.
10123
    */
10124
0
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10125
0
  ret = pctxt->err;
10126
0
  goto exit;
10127
0
    }
10128
10129
0
exit:
10130
0
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10131
    /* Restore schema values. */
10132
0
    schema->doc = oldDoc;
10133
0
    schema->flags = oldFlags;
10134
0
    return(ret);
10135
0
}
10136
10137
static int
10138
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10139
         xmlSchemaPtr schema,
10140
         xmlSchemaBucketPtr bucket)
10141
0
{
10142
0
    xmlSchemaParserCtxtPtr newpctxt;
10143
0
    int res = 0;
10144
10145
0
    if (bucket == NULL)
10146
0
  return(0);
10147
0
    if (bucket->parsed) {
10148
0
  PERROR_INT("xmlSchemaParseNewDoc",
10149
0
      "reparsing a schema doc");
10150
0
  return(-1);
10151
0
    }
10152
0
    if (bucket->doc == NULL) {
10153
0
  PERROR_INT("xmlSchemaParseNewDoc",
10154
0
      "parsing a schema doc, but there's no doc");
10155
0
  return(-1);
10156
0
    }
10157
0
    if (pctxt->constructor == NULL) {
10158
0
  PERROR_INT("xmlSchemaParseNewDoc",
10159
0
      "no constructor");
10160
0
  return(-1);
10161
0
    }
10162
    /* Create and init the temporary parser context. */
10163
0
    newpctxt = xmlSchemaNewParserCtxtUseDict(
10164
0
  (const char *) bucket->schemaLocation, pctxt->dict);
10165
0
    if (newpctxt == NULL)
10166
0
  return(-1);
10167
0
    newpctxt->constructor = pctxt->constructor;
10168
    /*
10169
    * TODO: Can we avoid that the parser knows about the main schema?
10170
    * It would be better if he knows about the current schema bucket
10171
    * only.
10172
    */
10173
0
    newpctxt->schema = schema;
10174
0
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10175
0
  pctxt->errCtxt);
10176
0
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10177
0
  pctxt->errCtxt);
10178
0
    newpctxt->counter = pctxt->counter;
10179
10180
10181
0
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10182
10183
    /* Channel back errors and cleanup the temporary parser context. */
10184
0
    if (res != 0)
10185
0
  pctxt->err = res;
10186
0
    pctxt->nberrors += newpctxt->nberrors;
10187
0
    pctxt->counter = newpctxt->counter;
10188
0
    newpctxt->constructor = NULL;
10189
    /* Free the parser context. */
10190
0
    xmlSchemaFreeParserCtxt(newpctxt);
10191
0
    return(res);
10192
0
}
10193
10194
static void
10195
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10196
        xmlSchemaSchemaRelationPtr rel)
10197
0
{
10198
0
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
10199
10200
0
    if (cur == NULL) {
10201
0
  bucket->relations = rel;
10202
0
  return;
10203
0
    }
10204
0
    while (cur->next != NULL)
10205
0
  cur = cur->next;
10206
0
    cur->next = rel;
10207
0
}
10208
10209
10210
static const xmlChar *
10211
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10212
        xmlNodePtr ctxtNode)
10213
0
{
10214
    /*
10215
    * Build an absolute location URI.
10216
    */
10217
0
    if (location != NULL) {
10218
0
  if (ctxtNode == NULL)
10219
0
      return(location);
10220
0
  else {
10221
0
      xmlChar *base, *URI;
10222
0
      const xmlChar *ret = NULL;
10223
10224
0
      base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10225
0
      if (base == NULL) {
10226
0
    URI = xmlBuildURI(location, ctxtNode->doc->URL);
10227
0
      } else {
10228
0
    URI = xmlBuildURI(location, base);
10229
0
    xmlFree(base);
10230
0
      }
10231
0
      if (URI != NULL) {
10232
0
    ret = xmlDictLookup(dict, URI, -1);
10233
0
    xmlFree(URI);
10234
0
    return(ret);
10235
0
      }
10236
0
  }
10237
0
    }
10238
0
    return(NULL);
10239
0
}
10240
10241
10242
10243
/**
10244
 * xmlSchemaAddSchemaDoc:
10245
 * @pctxt:  a schema validation context
10246
 * @schema:  the schema being built
10247
 * @node:  a subtree containing XML Schema information
10248
 *
10249
 * Parse an included (and to-be-redefined) XML schema document.
10250
 *
10251
 * Returns 0 on success, a positive error code on errors and
10252
 *         -1 in case of an internal or API error.
10253
 */
10254
10255
static int
10256
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10257
    int type, /* import or include or redefine */
10258
    const xmlChar *schemaLocation,
10259
    xmlDocPtr schemaDoc,
10260
    const char *schemaBuffer,
10261
    int schemaBufferLen,
10262
    xmlNodePtr invokingNode,
10263
    const xmlChar *sourceTargetNamespace,
10264
    const xmlChar *importNamespace,
10265
    xmlSchemaBucketPtr *bucket)
10266
0
{
10267
0
    const xmlChar *targetNamespace = NULL;
10268
0
    xmlSchemaSchemaRelationPtr relation = NULL;
10269
0
    xmlDocPtr doc = NULL;
10270
0
    int res = 0, err = 0, located = 0, preserveDoc = 0;
10271
0
    xmlSchemaBucketPtr bkt = NULL;
10272
10273
0
    if (bucket != NULL)
10274
0
  *bucket = NULL;
10275
10276
0
    switch (type) {
10277
0
  case XML_SCHEMA_SCHEMA_IMPORT:
10278
0
  case XML_SCHEMA_SCHEMA_MAIN:
10279
0
      err = XML_SCHEMAP_SRC_IMPORT;
10280
0
      break;
10281
0
  case XML_SCHEMA_SCHEMA_INCLUDE:
10282
0
      err = XML_SCHEMAP_SRC_INCLUDE;
10283
0
      break;
10284
0
  case XML_SCHEMA_SCHEMA_REDEFINE:
10285
0
      err = XML_SCHEMAP_SRC_REDEFINE;
10286
0
      break;
10287
0
    }
10288
10289
10290
    /* Special handling for the main schema:
10291
    * skip the location and relation logic and just parse the doc.
10292
    * We need just a bucket to be returned in this case.
10293
    */
10294
0
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10295
0
  goto doc_load;
10296
10297
    /* Note that we expect the location to be an absolute URI. */
10298
0
    if (schemaLocation != NULL) {
10299
0
  bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10300
0
  if ((bkt != NULL) &&
10301
0
      (pctxt->constructor->bucket == bkt)) {
10302
      /* Report self-imports/inclusions/redefinitions. */
10303
10304
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10305
0
    invokingNode, NULL,
10306
0
    "The schema must not import/include/redefine itself",
10307
0
    NULL, NULL);
10308
0
      goto exit;
10309
0
  }
10310
0
    }
10311
    /*
10312
    * Create a relation for the graph of schemas.
10313
    */
10314
0
    relation = xmlSchemaSchemaRelationCreate();
10315
0
    if (relation == NULL)
10316
0
  return(-1);
10317
0
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10318
0
  relation);
10319
0
    relation->type = type;
10320
10321
    /*
10322
    * Save the namespace import information.
10323
    */
10324
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10325
0
  relation->importNamespace = importNamespace;
10326
0
  if (schemaLocation == NULL) {
10327
      /*
10328
      * No location; this is just an import of the namespace.
10329
      * Note that we don't assign a bucket to the relation
10330
      * in this case.
10331
      */
10332
0
      goto exit;
10333
0
  }
10334
0
  targetNamespace = importNamespace;
10335
0
    }
10336
10337
    /* Did we already fetch the doc? */
10338
0
    if (bkt != NULL) {
10339
0
  if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10340
      /*
10341
      * We included/redefined and then try to import a schema,
10342
      * but the new location provided for import was different.
10343
      */
10344
0
      if (schemaLocation == NULL)
10345
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10346
0
      if (!xmlStrEqual(schemaLocation,
10347
0
    bkt->schemaLocation)) {
10348
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10349
0
        invokingNode, NULL,
10350
0
        "The schema document '%s' cannot be imported, since "
10351
0
        "it was already included or redefined",
10352
0
        schemaLocation, NULL);
10353
0
    goto exit;
10354
0
      }
10355
0
  } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10356
      /*
10357
      * We imported and then try to include/redefine a schema,
10358
      * but the new location provided for the include/redefine
10359
      * was different.
10360
      */
10361
0
      if (schemaLocation == NULL)
10362
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10363
0
      if (!xmlStrEqual(schemaLocation,
10364
0
    bkt->schemaLocation)) {
10365
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10366
0
        invokingNode, NULL,
10367
0
        "The schema document '%s' cannot be included or "
10368
0
        "redefined, since it was already imported",
10369
0
        schemaLocation, NULL);
10370
0
    goto exit;
10371
0
      }
10372
0
  }
10373
0
    }
10374
10375
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10376
  /*
10377
  * Given that the schemaLocation [attribute] is only a hint, it is open
10378
  * to applications to ignore all but the first <import> for a given
10379
  * namespace, regardless of the `actual value` of schemaLocation, but
10380
  * such a strategy risks missing useful information when new
10381
  * schemaLocations are offered.
10382
  *
10383
  * We will use the first <import> that comes with a location.
10384
  * Further <import>s *with* a location, will result in an error.
10385
  * TODO: Better would be to just report a warning here, but
10386
  * we'll try it this way until someone complains.
10387
  *
10388
  * Schema Document Location Strategy:
10389
  * 3 Based on the namespace name, identify an existing schema document,
10390
  * either as a resource which is an XML document or a <schema> element
10391
  * information item, in some local schema repository;
10392
  * 5 Attempt to resolve the namespace name to locate such a resource.
10393
  *
10394
  * NOTE: (3) and (5) are not supported.
10395
  */
10396
0
  if (bkt != NULL) {
10397
0
      relation->bucket = bkt;
10398
0
      goto exit;
10399
0
  }
10400
0
  bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10401
0
      importNamespace, 1);
10402
10403
0
  if (bkt != NULL) {
10404
0
      relation->bucket = bkt;
10405
0
      if (bkt->schemaLocation == NULL) {
10406
    /* First given location of the schema; load the doc. */
10407
0
    bkt->schemaLocation = schemaLocation;
10408
0
      } else {
10409
0
    if (!xmlStrEqual(schemaLocation,
10410
0
        bkt->schemaLocation)) {
10411
        /*
10412
        * Additional location given; just skip it.
10413
        * URGENT TODO: We should report a warning here.
10414
        * res = XML_SCHEMAP_SRC_IMPORT;
10415
        */
10416
0
        if (schemaLocation == NULL)
10417
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10418
10419
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10420
0
      XML_SCHEMAP_WARN_SKIP_SCHEMA,
10421
0
      invokingNode, NULL,
10422
0
      "Skipping import of schema located at '%s' for the "
10423
0
      "namespace '%s', since this namespace was already "
10424
0
      "imported with the schema located at '%s'",
10425
0
      schemaLocation, importNamespace, bkt->schemaLocation);
10426
0
    }
10427
0
    goto exit;
10428
0
      }
10429
0
  }
10430
  /*
10431
  * No bucket + first location: load the doc and create a
10432
  * bucket.
10433
  */
10434
0
    } else {
10435
  /* <include> and <redefine> */
10436
0
  if (bkt != NULL) {
10437
10438
0
      if ((bkt->origTargetNamespace == NULL) &&
10439
0
    (bkt->targetNamespace != sourceTargetNamespace)) {
10440
0
    xmlSchemaBucketPtr chamel;
10441
10442
    /*
10443
    * Chameleon include/redefine: skip loading only if it was
10444
    * already build for the targetNamespace of the including
10445
    * schema.
10446
    */
10447
    /*
10448
    * URGENT TODO: If the schema is a chameleon-include then copy
10449
    * the components into the including schema and modify the
10450
    * targetNamespace of those components, do nothing otherwise.
10451
    * NOTE: This is currently worked-around by compiling the
10452
    * chameleon for every distinct including targetNamespace; thus
10453
    * not performant at the moment.
10454
    * TODO: Check when the namespace in wildcards for chameleons
10455
    * needs to be converted: before we built wildcard intersections
10456
    * or after.
10457
    *   Answer: after!
10458
    */
10459
0
    chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10460
0
        schemaLocation, sourceTargetNamespace);
10461
0
    if (chamel != NULL) {
10462
        /* A fitting chameleon was already parsed; NOP. */
10463
0
        relation->bucket = chamel;
10464
0
        goto exit;
10465
0
    }
10466
    /*
10467
    * We need to parse the chameleon again for a different
10468
    * targetNamespace.
10469
    * CHAMELEON TODO: Optimize this by only parsing the
10470
    * chameleon once, and then copying the components to
10471
    * the new targetNamespace.
10472
    */
10473
0
    bkt = NULL;
10474
0
      } else {
10475
0
    relation->bucket = bkt;
10476
0
    goto exit;
10477
0
      }
10478
0
  }
10479
0
    }
10480
0
    if ((bkt != NULL) && (bkt->doc != NULL)) {
10481
0
  PERROR_INT("xmlSchemaAddSchemaDoc",
10482
0
      "trying to load a schema doc, but a doc is already "
10483
0
      "assigned to the schema bucket");
10484
0
  goto exit_failure;
10485
0
    }
10486
10487
0
doc_load:
10488
    /*
10489
    * Load the document.
10490
    */
10491
0
    if (schemaDoc != NULL) {
10492
0
  doc = schemaDoc;
10493
  /* Don' free this one, since it was provided by the caller. */
10494
0
  preserveDoc = 1;
10495
  /* TODO: Does the context or the doc hold the location? */
10496
0
  if (schemaDoc->URL != NULL)
10497
0
      schemaLocation = xmlDictLookup(pctxt->dict,
10498
0
    schemaDoc->URL, -1);
10499
0
        else
10500
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10501
0
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10502
0
  xmlParserCtxtPtr parserCtxt;
10503
10504
0
  parserCtxt = xmlNewParserCtxt();
10505
0
  if (parserCtxt == NULL) {
10506
0
      xmlSchemaPErrMemory(NULL);
10507
0
      goto exit_failure;
10508
0
  }
10509
10510
0
        if (pctxt->serror != NULL)
10511
0
            xmlCtxtSetErrorHandler(parserCtxt, pctxt->serror, pctxt->errCtxt);
10512
0
        if (pctxt->resourceLoader != NULL)
10513
0
            xmlCtxtSetResourceLoader(parserCtxt, pctxt->resourceLoader,
10514
0
                                     pctxt->resourceCtxt);
10515
10516
0
  if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10517
      /*
10518
      * TODO: Do we have to burden the schema parser dict with all
10519
      * the content of the schema doc?
10520
      */
10521
0
      xmlDictFree(parserCtxt->dict);
10522
0
      parserCtxt->dict = pctxt->dict;
10523
0
      xmlDictReference(parserCtxt->dict);
10524
0
  }
10525
0
  if (schemaLocation != NULL) {
10526
      /* Parse from file. */
10527
0
      doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10528
0
    NULL, SCHEMAS_PARSE_OPTIONS);
10529
0
  } else if (schemaBuffer != NULL) {
10530
      /* Parse from memory buffer. */
10531
0
      doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10532
0
    NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10533
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10534
0
      if (doc != NULL)
10535
0
    doc->URL = xmlStrdup(schemaLocation);
10536
0
  }
10537
  /*
10538
  * For <import>:
10539
  * 2.1 The referent is (a fragment of) a resource which is an
10540
  * XML document (see clause 1.1), which in turn corresponds to
10541
  * a <schema> element information item in a well-formed information
10542
  * set, which in turn corresponds to a valid schema.
10543
  * TODO: (2.1) fragments of XML documents are not supported.
10544
  *
10545
  * 2.2 The referent is a <schema> element information item in
10546
  * a well-formed information set, which in turn corresponds
10547
  * to a valid schema.
10548
  * TODO: (2.2) is not supported.
10549
  */
10550
0
  if (doc == NULL) {
10551
0
      const xmlError *lerr;
10552
0
      lerr = xmlGetLastError();
10553
      /*
10554
      * Check if this a parser error, or if the document could
10555
      * just not be located.
10556
      * TODO: Try to find specific error codes to react only on
10557
      * localisation failures.
10558
      */
10559
0
      if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10560
    /*
10561
    * We assume a parser error here.
10562
    */
10563
0
    located = 1;
10564
    /* TODO: Error code ?? */
10565
0
    res = XML_SCHEMAP_SRC_IMPORT_2_1;
10566
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10567
0
        invokingNode, NULL,
10568
0
        "Failed to parse the XML resource '%s'",
10569
0
        schemaLocation, NULL);
10570
0
      }
10571
0
  }
10572
0
  xmlFreeParserCtxt(parserCtxt);
10573
0
  if ((doc == NULL) && located)
10574
0
      goto exit_error;
10575
0
    } else {
10576
0
  xmlSchemaPErr(pctxt, NULL,
10577
0
      XML_SCHEMAP_NOTHING_TO_PARSE,
10578
0
      "No information for parsing was provided with the "
10579
0
      "given schema parser context.\n",
10580
0
      NULL, NULL);
10581
0
  goto exit_failure;
10582
0
    }
10583
    /*
10584
    * Preprocess the document.
10585
    */
10586
0
    if (doc != NULL) {
10587
0
  xmlNodePtr docElem = NULL;
10588
10589
0
  located = 1;
10590
0
  docElem = xmlDocGetRootElement(doc);
10591
0
  if (docElem == NULL) {
10592
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10593
0
    invokingNode, NULL,
10594
0
    "The document '%s' has no document element",
10595
0
    schemaLocation, NULL);
10596
0
      goto exit_error;
10597
0
  }
10598
  /*
10599
  * Remove all the blank text nodes.
10600
  */
10601
0
  xmlSchemaCleanupDoc(pctxt, docElem);
10602
  /*
10603
  * Check the schema's top level element.
10604
  */
10605
0
  if (!IS_SCHEMA(docElem, "schema")) {
10606
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10607
0
    invokingNode, NULL,
10608
0
    "The XML document '%s' is not a schema document",
10609
0
    schemaLocation, NULL);
10610
0
      goto exit_error;
10611
0
  }
10612
  /*
10613
  * Note that we don't apply a type check for the
10614
  * targetNamespace value here.
10615
  */
10616
0
  targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10617
0
      "targetNamespace");
10618
0
    }
10619
10620
/* after_doc_loading: */
10621
0
    if ((bkt == NULL) && located) {
10622
  /* Only create a bucket if the schema was located. */
10623
0
        bkt = xmlSchemaBucketCreate(pctxt, type,
10624
0
      targetNamespace);
10625
0
  if (bkt == NULL)
10626
0
      goto exit_failure;
10627
0
    }
10628
0
    if (bkt != NULL) {
10629
0
  bkt->schemaLocation = schemaLocation;
10630
0
  bkt->located = located;
10631
0
  if (doc != NULL) {
10632
0
      bkt->doc = doc;
10633
0
      bkt->targetNamespace = targetNamespace;
10634
0
      bkt->origTargetNamespace = targetNamespace;
10635
0
      if (preserveDoc)
10636
0
    bkt->preserveDoc = 1;
10637
0
  }
10638
0
  if (WXS_IS_BUCKET_IMPMAIN(type))
10639
0
      bkt->imported++;
10640
      /*
10641
      * Add it to the graph of schemas.
10642
      */
10643
0
  if (relation != NULL)
10644
0
      relation->bucket = bkt;
10645
0
    }
10646
10647
0
exit:
10648
    /*
10649
    * Return the bucket explicitly; this is needed for the
10650
    * main schema.
10651
    */
10652
0
    if (bucket != NULL)
10653
0
  *bucket = bkt;
10654
0
    return (0);
10655
10656
0
exit_error:
10657
0
    if ((doc != NULL) && (! preserveDoc)) {
10658
0
  xmlFreeDoc(doc);
10659
0
  if (bkt != NULL)
10660
0
      bkt->doc = NULL;
10661
0
    }
10662
0
    return(pctxt->err);
10663
10664
0
exit_failure:
10665
0
    if ((doc != NULL) && (! preserveDoc)) {
10666
0
  xmlFreeDoc(doc);
10667
0
  if (bkt != NULL)
10668
0
      bkt->doc = NULL;
10669
0
    }
10670
0
    return (-1);
10671
0
}
10672
10673
/**
10674
 * xmlSchemaParseImport:
10675
 * @ctxt:  a schema validation context
10676
 * @schema:  the schema being built
10677
 * @node:  a subtree containing XML Schema information
10678
 *
10679
 * parse a XML schema Import definition
10680
 * *WARNING* this interface is highly subject to change
10681
 *
10682
 * Returns 0 in case of success, a positive error code if
10683
 * not valid and -1 in case of an internal error.
10684
 */
10685
static int
10686
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10687
                     xmlNodePtr node)
10688
0
{
10689
0
    xmlNodePtr child;
10690
0
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10691
0
    const xmlChar *thisTargetNamespace;
10692
0
    xmlAttrPtr attr;
10693
0
    int ret = 0;
10694
0
    xmlSchemaBucketPtr bucket = NULL;
10695
10696
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10697
0
        return (-1);
10698
10699
    /*
10700
    * Check for illegal attributes.
10701
    */
10702
0
    attr = node->properties;
10703
0
    while (attr != NULL) {
10704
0
  if (attr->ns == NULL) {
10705
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10706
0
    (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10707
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10708
0
    xmlSchemaPIllegalAttrErr(pctxt,
10709
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10710
0
      }
10711
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10712
0
      xmlSchemaPIllegalAttrErr(pctxt,
10713
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10714
0
  }
10715
0
  attr = attr->next;
10716
0
    }
10717
    /*
10718
    * Extract and validate attributes.
10719
    */
10720
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10721
0
  "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10722
0
  &namespaceName) != 0) {
10723
0
  xmlSchemaPSimpleTypeErr(pctxt,
10724
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10725
0
      NULL, node,
10726
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10727
0
      NULL, namespaceName, NULL, NULL, NULL);
10728
0
  return (pctxt->err);
10729
0
    }
10730
10731
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10732
0
  "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10733
0
  &schemaLocation) != 0) {
10734
0
  xmlSchemaPSimpleTypeErr(pctxt,
10735
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10736
0
      NULL, node,
10737
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10738
0
      NULL, schemaLocation, NULL, NULL, NULL);
10739
0
  return (pctxt->err);
10740
0
    }
10741
    /*
10742
    * And now for the children...
10743
    */
10744
0
    child = node->children;
10745
0
    if (IS_SCHEMA(child, "annotation")) {
10746
        /*
10747
         * the annotation here is simply discarded ...
10748
   * TODO: really?
10749
         */
10750
0
        child = child->next;
10751
0
    }
10752
0
    if (child != NULL) {
10753
0
  xmlSchemaPContentErr(pctxt,
10754
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10755
0
      NULL, node, child, NULL,
10756
0
      "(annotation?)");
10757
0
    }
10758
    /*
10759
    * Apply additional constraints.
10760
    *
10761
    * Note that it is important to use the original @targetNamespace
10762
    * (or none at all), to rule out imports of schemas _with_ a
10763
    * @targetNamespace if the importing schema is a chameleon schema
10764
    * (with no @targetNamespace).
10765
    */
10766
0
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10767
0
    if (namespaceName != NULL) {
10768
  /*
10769
  * 1.1 If the namespace [attribute] is present, then its `actual value`
10770
  * must not match the `actual value` of the enclosing <schema>'s
10771
  * targetNamespace [attribute].
10772
  */
10773
0
  if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10774
0
      xmlSchemaPCustomErr(pctxt,
10775
0
    XML_SCHEMAP_SRC_IMPORT_1_1,
10776
0
    NULL, node,
10777
0
    "The value of the attribute 'namespace' must not match "
10778
0
    "the target namespace '%s' of the importing schema",
10779
0
    thisTargetNamespace);
10780
0
      return (pctxt->err);
10781
0
  }
10782
0
    } else {
10783
  /*
10784
  * 1.2 If the namespace [attribute] is not present, then the enclosing
10785
  * <schema> must have a targetNamespace [attribute].
10786
  */
10787
0
  if (thisTargetNamespace == NULL) {
10788
0
      xmlSchemaPCustomErr(pctxt,
10789
0
    XML_SCHEMAP_SRC_IMPORT_1_2,
10790
0
    NULL, node,
10791
0
    "The attribute 'namespace' must be existent if "
10792
0
    "the importing schema has no target namespace",
10793
0
    NULL);
10794
0
      return (pctxt->err);
10795
0
  }
10796
0
    }
10797
    /*
10798
    * Locate and acquire the schema document.
10799
    */
10800
0
    if (schemaLocation != NULL)
10801
0
  schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10802
0
      schemaLocation, node);
10803
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10804
0
  schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10805
0
  namespaceName, &bucket);
10806
10807
0
    if (ret != 0)
10808
0
  return(ret);
10809
10810
    /*
10811
    * For <import>: "It is *not* an error for the application
10812
    * schema reference strategy to fail."
10813
    * So just don't parse if no schema document was found.
10814
    * Note that we will get no bucket if the schema could not be
10815
    * located or if there was no schemaLocation.
10816
    */
10817
0
    if ((bucket == NULL) && (schemaLocation != NULL)) {
10818
0
  xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10819
0
      XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10820
0
      node, NULL,
10821
0
      "Failed to locate a schema at location '%s'. "
10822
0
      "Skipping the import", schemaLocation, NULL, NULL);
10823
0
    }
10824
10825
0
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10826
0
  ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10827
0
    }
10828
10829
0
    return (ret);
10830
0
}
10831
10832
static int
10833
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10834
             xmlSchemaPtr schema,
10835
             xmlNodePtr node,
10836
             xmlChar **schemaLocation,
10837
             int type)
10838
0
{
10839
0
    xmlAttrPtr attr;
10840
10841
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10842
0
  (schemaLocation == NULL))
10843
0
        return (-1);
10844
10845
0
    *schemaLocation = NULL;
10846
    /*
10847
    * Check for illegal attributes.
10848
    * Applies for both <include> and <redefine>.
10849
    */
10850
0
    attr = node->properties;
10851
0
    while (attr != NULL) {
10852
0
  if (attr->ns == NULL) {
10853
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10854
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10855
0
    xmlSchemaPIllegalAttrErr(pctxt,
10856
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10857
0
      }
10858
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10859
0
      xmlSchemaPIllegalAttrErr(pctxt,
10860
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10861
0
  }
10862
0
  attr = attr->next;
10863
0
    }
10864
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10865
    /*
10866
    * Preliminary step, extract the URI-Reference and make an URI
10867
    * from the base.
10868
    */
10869
    /*
10870
    * Attribute "schemaLocation" is mandatory.
10871
    */
10872
0
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
10873
0
    if (attr != NULL) {
10874
0
        xmlChar *base = NULL;
10875
0
        xmlChar *uri = NULL;
10876
10877
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10878
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10879
0
      (const xmlChar **) schemaLocation) != 0)
10880
0
      goto exit_error;
10881
0
  base = xmlNodeGetBase(node->doc, node);
10882
0
  if (base == NULL) {
10883
0
      uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10884
0
  } else {
10885
0
      uri = xmlBuildURI(*schemaLocation, base);
10886
0
      xmlFree(base);
10887
0
  }
10888
0
  if (uri == NULL) {
10889
0
      PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10890
0
    "could not build an URI from the schemaLocation")
10891
0
      goto exit_failure;
10892
0
  }
10893
0
  (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10894
0
  xmlFree(uri);
10895
0
    } else {
10896
0
  xmlSchemaPMissingAttrErr(pctxt,
10897
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
10898
0
      NULL, node, "schemaLocation", NULL);
10899
0
  goto exit_error;
10900
0
    }
10901
    /*
10902
    * Report self-inclusion and self-redefinition.
10903
    */
10904
0
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10905
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10906
0
      xmlSchemaPCustomErr(pctxt,
10907
0
    XML_SCHEMAP_SRC_REDEFINE,
10908
0
    NULL, node,
10909
0
    "The schema document '%s' cannot redefine itself.",
10910
0
    *schemaLocation);
10911
0
  } else {
10912
0
      xmlSchemaPCustomErr(pctxt,
10913
0
    XML_SCHEMAP_SRC_INCLUDE,
10914
0
    NULL, node,
10915
0
    "The schema document '%s' cannot include itself.",
10916
0
    *schemaLocation);
10917
0
  }
10918
0
  goto exit_error;
10919
0
    }
10920
10921
0
    return(0);
10922
0
exit_error:
10923
0
    return(pctxt->err);
10924
0
exit_failure:
10925
0
    return(-1);
10926
0
}
10927
10928
static int
10929
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10930
        xmlSchemaPtr schema,
10931
        xmlNodePtr node,
10932
        int type)
10933
0
{
10934
0
    xmlNodePtr child = NULL;
10935
0
    const xmlChar *schemaLocation = NULL;
10936
0
    int res = 0; /* hasRedefinitions = 0 */
10937
0
    int isChameleon = 0, wasChameleon = 0;
10938
0
    xmlSchemaBucketPtr bucket = NULL;
10939
10940
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10941
0
        return (-1);
10942
10943
    /*
10944
    * Parse attributes. Note that the returned schemaLocation will
10945
    * be already converted to an absolute URI.
10946
    */
10947
0
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10948
0
  node, (xmlChar **) (&schemaLocation), type);
10949
0
    if (res != 0)
10950
0
  return(res);
10951
    /*
10952
    * Load and add the schema document.
10953
    */
10954
0
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10955
0
  NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10956
0
    if (res != 0)
10957
0
  return(res);
10958
    /*
10959
    * If we get no schema bucket back, then this means that the schema
10960
    * document could not be located or was broken XML or was not
10961
    * a schema document.
10962
    */
10963
0
    if ((bucket == NULL) || (bucket->doc == NULL)) {
10964
0
  if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10965
      /*
10966
      * WARNING for <include>:
10967
      * We will raise an error if the schema cannot be located
10968
      * for inclusions, since the that was the feedback from the
10969
      * schema people. I.e. the following spec piece will *not* be
10970
      * satisfied:
10971
      * SPEC src-include: "It is not an error for the `actual value` of the
10972
      * schemaLocation [attribute] to fail to resolve it all, in which
10973
      * case no corresponding inclusion is performed.
10974
      * So do we need a warning report here?"
10975
      */
10976
0
      res = XML_SCHEMAP_SRC_INCLUDE;
10977
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10978
0
    node, NULL,
10979
0
    "Failed to load the document '%s' for inclusion",
10980
0
    schemaLocation, NULL);
10981
0
  } else {
10982
      /*
10983
      * NOTE: This was changed to raise an error even if no redefinitions
10984
      * are specified.
10985
      *
10986
      * SPEC src-redefine (1)
10987
      * "If there are any element information items among the [children]
10988
      * other than <annotation> then the `actual value` of the
10989
      * schemaLocation [attribute] must successfully resolve."
10990
      * TODO: Ask the WG if a the location has always to resolve
10991
      * here as well!
10992
      */
10993
0
      res = XML_SCHEMAP_SRC_REDEFINE;
10994
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10995
0
    node, NULL,
10996
0
    "Failed to load the document '%s' for redefinition",
10997
0
    schemaLocation, NULL);
10998
0
  }
10999
0
    } else {
11000
  /*
11001
  * Check targetNamespace sanity before parsing the new schema.
11002
  * TODO: Note that we won't check further content if the
11003
  * targetNamespace was bad.
11004
  */
11005
0
  if (bucket->origTargetNamespace != NULL) {
11006
      /*
11007
      * SPEC src-include (2.1)
11008
      * "SII has a targetNamespace [attribute], and its `actual
11009
      * value` is identical to the `actual value` of the targetNamespace
11010
      * [attribute] of SII' (which must have such an [attribute])."
11011
      */
11012
0
      if (pctxt->targetNamespace == NULL) {
11013
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
11014
0
        XML_SCHEMAP_SRC_INCLUDE,
11015
0
        node, NULL,
11016
0
        "The target namespace of the included/redefined schema "
11017
0
        "'%s' has to be absent, since the including/redefining "
11018
0
        "schema has no target namespace",
11019
0
        schemaLocation, NULL);
11020
0
    goto exit_error;
11021
0
      } else if (!xmlStrEqual(bucket->origTargetNamespace,
11022
0
    pctxt->targetNamespace)) {
11023
    /* TODO: Change error function. */
11024
0
    xmlSchemaPCustomErrExt(pctxt,
11025
0
        XML_SCHEMAP_SRC_INCLUDE,
11026
0
        NULL, node,
11027
0
        "The target namespace '%s' of the included/redefined "
11028
0
        "schema '%s' differs from '%s' of the "
11029
0
        "including/redefining schema",
11030
0
        bucket->origTargetNamespace, schemaLocation,
11031
0
        pctxt->targetNamespace);
11032
0
    goto exit_error;
11033
0
      }
11034
0
  } else if (pctxt->targetNamespace != NULL) {
11035
      /*
11036
      * Chameleons: the original target namespace will
11037
      * differ from the resulting namespace.
11038
      */
11039
0
      isChameleon = 1;
11040
0
      bucket->targetNamespace = pctxt->targetNamespace;
11041
0
  }
11042
0
    }
11043
    /*
11044
    * Parse the schema.
11045
    */
11046
0
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11047
0
  if (isChameleon) {
11048
      /* TODO: Get rid of this flag on the schema itself. */
11049
0
      if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11050
0
    schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11051
0
      } else
11052
0
    wasChameleon = 1;
11053
0
  }
11054
0
  xmlSchemaParseNewDoc(pctxt, schema, bucket);
11055
  /* Restore chameleon flag. */
11056
0
  if (isChameleon && (!wasChameleon))
11057
0
      schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11058
0
    }
11059
    /*
11060
    * And now for the children...
11061
    */
11062
0
    child = node->children;
11063
0
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11064
  /*
11065
  * Parse (simpleType | complexType | group | attributeGroup))*
11066
  */
11067
0
  pctxt->redefined = bucket;
11068
  /*
11069
  * How to proceed if the redefined schema was not located?
11070
  */
11071
0
  pctxt->isRedefine = 1;
11072
0
  while (IS_SCHEMA(child, "annotation") ||
11073
0
      IS_SCHEMA(child, "simpleType") ||
11074
0
      IS_SCHEMA(child, "complexType") ||
11075
0
      IS_SCHEMA(child, "group") ||
11076
0
      IS_SCHEMA(child, "attributeGroup")) {
11077
0
      if (IS_SCHEMA(child, "annotation")) {
11078
    /*
11079
    * TODO: discard or not?
11080
    */
11081
0
      } else if (IS_SCHEMA(child, "simpleType")) {
11082
0
    xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11083
0
      } else if (IS_SCHEMA(child, "complexType")) {
11084
0
    xmlSchemaParseComplexType(pctxt, schema, child, 1);
11085
    /* hasRedefinitions = 1; */
11086
0
      } else if (IS_SCHEMA(child, "group")) {
11087
    /* hasRedefinitions = 1; */
11088
0
    xmlSchemaParseModelGroupDefinition(pctxt,
11089
0
        schema, child);
11090
0
      } else if (IS_SCHEMA(child, "attributeGroup")) {
11091
    /* hasRedefinitions = 1; */
11092
0
    xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11093
0
        child);
11094
0
      }
11095
0
      child = child->next;
11096
0
  }
11097
0
  pctxt->redefined = NULL;
11098
0
  pctxt->isRedefine = 0;
11099
0
    } else {
11100
0
  if (IS_SCHEMA(child, "annotation")) {
11101
      /*
11102
      * TODO: discard or not?
11103
      */
11104
0
      child = child->next;
11105
0
  }
11106
0
    }
11107
0
    if (child != NULL) {
11108
0
  res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11109
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11110
0
      xmlSchemaPContentErr(pctxt, res,
11111
0
    NULL, node, child, NULL,
11112
0
    "(annotation | (simpleType | complexType | group | attributeGroup))*");
11113
0
  } else {
11114
0
       xmlSchemaPContentErr(pctxt, res,
11115
0
    NULL, node, child, NULL,
11116
0
    "(annotation?)");
11117
0
  }
11118
0
    }
11119
0
    return(res);
11120
11121
0
exit_error:
11122
0
    return(pctxt->err);
11123
0
}
11124
11125
static int
11126
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11127
                       xmlNodePtr node)
11128
0
{
11129
0
    int res;
11130
#ifndef ENABLE_REDEFINE
11131
    TODO
11132
    return(0);
11133
#endif
11134
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11135
0
  XML_SCHEMA_SCHEMA_REDEFINE);
11136
0
    if (res != 0)
11137
0
  return(res);
11138
0
    return(0);
11139
0
}
11140
11141
static int
11142
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11143
                       xmlNodePtr node)
11144
0
{
11145
0
    int res;
11146
11147
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11148
0
  XML_SCHEMA_SCHEMA_INCLUDE);
11149
0
    if (res != 0)
11150
0
  return(res);
11151
0
    return(0);
11152
0
}
11153
11154
/**
11155
 * xmlSchemaParseModelGroup:
11156
 * @ctxt:  a schema validation context
11157
 * @schema:  the schema being built
11158
 * @node:  a subtree containing XML Schema information
11159
 * @type: the "compositor" type
11160
 * @particleNeeded: if a a model group with a particle
11161
 *
11162
 * parse a XML schema Sequence definition.
11163
 * Applies parts of:
11164
 *   Schema Representation Constraint:
11165
 *     Redefinition Constraints and Semantics (src-redefine)
11166
 *     (6.1), (6.1.1), (6.1.2)
11167
 *
11168
 *   Schema Component Constraint:
11169
 *     All Group Limited (cos-all-limited) (2)
11170
 *     TODO: Actually this should go to component-level checks,
11171
 *     but is done here due to performance. Move it to an other layer
11172
 *     is schema construction via an API is implemented.
11173
 *
11174
 * *WARNING* this interface is highly subject to change
11175
 *
11176
 * Returns -1 in case of error, 0 if the declaration is improper and
11177
 *         1 in case of success.
11178
 */
11179
static xmlSchemaTreeItemPtr
11180
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11181
       xmlNodePtr node, xmlSchemaTypeType type,
11182
       int withParticle)
11183
0
{
11184
0
    xmlSchemaModelGroupPtr item;
11185
0
    xmlSchemaParticlePtr particle = NULL;
11186
0
    xmlNodePtr child = NULL;
11187
0
    xmlAttrPtr attr;
11188
0
    int min = 1, max = 1, isElemRef, hasRefs = 0;
11189
11190
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11191
0
        return (NULL);
11192
    /*
11193
    * Create a model group with the given compositor.
11194
    */
11195
0
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11196
0
    if (item == NULL)
11197
0
  return (NULL);
11198
11199
0
    if (withParticle) {
11200
0
  if (type == XML_SCHEMA_TYPE_ALL) {
11201
0
      min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11202
0
      max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11203
0
  } else {
11204
      /* choice + sequence */
11205
0
      min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11206
0
      max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11207
0
    "(xs:nonNegativeInteger | unbounded)");
11208
0
  }
11209
0
  xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11210
  /*
11211
  * Create a particle
11212
  */
11213
0
  particle = xmlSchemaAddParticle(ctxt, node, min, max);
11214
0
  if (particle == NULL)
11215
0
      return (NULL);
11216
0
  particle->children = (xmlSchemaTreeItemPtr) item;
11217
  /*
11218
  * Check for illegal attributes.
11219
  */
11220
0
  attr = node->properties;
11221
0
  while (attr != NULL) {
11222
0
      if (attr->ns == NULL) {
11223
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11224
0
        (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11225
0
        (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11226
0
        xmlSchemaPIllegalAttrErr(ctxt,
11227
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11228
0
    }
11229
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11230
0
    xmlSchemaPIllegalAttrErr(ctxt,
11231
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11232
0
      }
11233
0
      attr = attr->next;
11234
0
  }
11235
0
    } else {
11236
  /*
11237
  * Check for illegal attributes.
11238
  */
11239
0
  attr = node->properties;
11240
0
  while (attr != NULL) {
11241
0
      if (attr->ns == NULL) {
11242
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11243
0
        xmlSchemaPIllegalAttrErr(ctxt,
11244
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11245
0
    }
11246
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11247
0
    xmlSchemaPIllegalAttrErr(ctxt,
11248
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11249
0
      }
11250
0
      attr = attr->next;
11251
0
  }
11252
0
    }
11253
11254
    /*
11255
    * Extract and validate attributes.
11256
    */
11257
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11258
    /*
11259
    * And now for the children...
11260
    */
11261
0
    child = node->children;
11262
0
    if (IS_SCHEMA(child, "annotation")) {
11263
0
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11264
0
        child = child->next;
11265
0
    }
11266
0
    if (type == XML_SCHEMA_TYPE_ALL) {
11267
0
  xmlSchemaParticlePtr part, last = NULL;
11268
11269
0
  while (IS_SCHEMA(child, "element")) {
11270
0
      part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11271
0
    schema, child, &isElemRef, 0);
11272
      /*
11273
      * SPEC cos-all-limited (2)
11274
      * "The {max occurs} of all the particles in the {particles}
11275
      * of the ('all') group must be 0 or 1.
11276
      */
11277
0
      if (part != NULL) {
11278
0
    if (isElemRef)
11279
0
        hasRefs++;
11280
0
    if (part->minOccurs > 1) {
11281
0
        xmlSchemaPCustomErr(ctxt,
11282
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11283
0
      NULL, child,
11284
0
      "Invalid value for minOccurs (must be 0 or 1)",
11285
0
      NULL);
11286
        /* Reset to 1. */
11287
0
        part->minOccurs = 1;
11288
0
    }
11289
0
    if (part->maxOccurs > 1) {
11290
0
        xmlSchemaPCustomErr(ctxt,
11291
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11292
0
      NULL, child,
11293
0
      "Invalid value for maxOccurs (must be 0 or 1)",
11294
0
      NULL);
11295
        /* Reset to 1. */
11296
0
        part->maxOccurs = 1;
11297
0
    }
11298
0
    if (last == NULL)
11299
0
        item->children = (xmlSchemaTreeItemPtr) part;
11300
0
    else
11301
0
        last->next = (xmlSchemaTreeItemPtr) part;
11302
0
    last = part;
11303
0
      }
11304
0
      child = child->next;
11305
0
  }
11306
0
  if (child != NULL) {
11307
0
      xmlSchemaPContentErr(ctxt,
11308
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11309
0
    NULL, node, child, NULL,
11310
0
    "(annotation?, (annotation?, element*)");
11311
0
  }
11312
0
    } else {
11313
  /* choice + sequence */
11314
0
  xmlSchemaTreeItemPtr part = NULL, last = NULL;
11315
11316
0
  while ((IS_SCHEMA(child, "element")) ||
11317
0
      (IS_SCHEMA(child, "group")) ||
11318
0
      (IS_SCHEMA(child, "any")) ||
11319
0
      (IS_SCHEMA(child, "choice")) ||
11320
0
      (IS_SCHEMA(child, "sequence"))) {
11321
11322
0
      if (IS_SCHEMA(child, "element")) {
11323
0
    part = (xmlSchemaTreeItemPtr)
11324
0
        xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11325
0
    if (part && isElemRef)
11326
0
        hasRefs++;
11327
0
      } else if (IS_SCHEMA(child, "group")) {
11328
0
    part =
11329
0
        xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11330
0
    if (part != NULL)
11331
0
        hasRefs++;
11332
    /*
11333
    * Handle redefinitions.
11334
    */
11335
0
    if (ctxt->isRedefine && ctxt->redef &&
11336
0
        (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11337
0
        part && part->children)
11338
0
    {
11339
0
        if ((xmlSchemaGetQNameRefName(part->children) ==
11340
0
          ctxt->redef->refName) &&
11341
0
      (xmlSchemaGetQNameRefTargetNs(part->children) ==
11342
0
          ctxt->redef->refTargetNs))
11343
0
        {
11344
      /*
11345
      * SPEC src-redefine:
11346
      * (6.1) "If it has a <group> among its contents at
11347
      * some level the `actual value` of whose ref
11348
      * [attribute] is the same as the `actual value` of
11349
      * its own name attribute plus target namespace, then
11350
      * all of the following must be true:"
11351
      * (6.1.1) "It must have exactly one such group."
11352
      */
11353
0
      if (ctxt->redefCounter != 0) {
11354
0
          xmlChar *str = NULL;
11355
11356
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11357
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11358
0
        "The redefining model group definition "
11359
0
        "'%s' must not contain more than one "
11360
0
        "reference to the redefined definition",
11361
0
        xmlSchemaFormatQName(&str,
11362
0
            ctxt->redef->refTargetNs,
11363
0
            ctxt->redef->refName),
11364
0
        NULL);
11365
0
          FREE_AND_NULL(str)
11366
0
          part = NULL;
11367
0
      } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11368
0
          ((WXS_PARTICLE(part))->maxOccurs != 1))
11369
0
      {
11370
0
          xmlChar *str = NULL;
11371
          /*
11372
          * SPEC src-redefine:
11373
          * (6.1.2) "The `actual value` of both that
11374
          * group's minOccurs and maxOccurs [attribute]
11375
          * must be 1 (or `absent`).
11376
          */
11377
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11378
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11379
0
        "The redefining model group definition "
11380
0
        "'%s' must not contain a reference to the "
11381
0
        "redefined definition with a "
11382
0
        "maxOccurs/minOccurs other than 1",
11383
0
        xmlSchemaFormatQName(&str,
11384
0
            ctxt->redef->refTargetNs,
11385
0
            ctxt->redef->refName),
11386
0
        NULL);
11387
0
          FREE_AND_NULL(str)
11388
0
          part = NULL;
11389
0
      }
11390
0
      ctxt->redef->reference = WXS_BASIC_CAST part;
11391
0
      ctxt->redefCounter++;
11392
0
        }
11393
0
    }
11394
0
      } else if (IS_SCHEMA(child, "any")) {
11395
0
    part = (xmlSchemaTreeItemPtr)
11396
0
        xmlSchemaParseAny(ctxt, schema, child);
11397
0
      } else if (IS_SCHEMA(child, "choice")) {
11398
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11399
0
        XML_SCHEMA_TYPE_CHOICE, 1);
11400
0
      } else if (IS_SCHEMA(child, "sequence")) {
11401
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11402
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11403
0
      }
11404
0
      if (part != NULL) {
11405
0
    if (last == NULL)
11406
0
        item->children = part;
11407
0
    else
11408
0
        last->next = part;
11409
0
    last = part;
11410
0
      }
11411
0
      child = child->next;
11412
0
  }
11413
0
  if (child != NULL) {
11414
0
      xmlSchemaPContentErr(ctxt,
11415
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11416
0
    NULL, node, child, NULL,
11417
0
    "(annotation?, (element | group | choice | sequence | any)*)");
11418
0
  }
11419
0
    }
11420
0
    if ((max == 0) && (min == 0))
11421
0
  return (NULL);
11422
0
    if (hasRefs) {
11423
  /*
11424
  * We need to resolve references.
11425
  */
11426
0
  WXS_ADD_PENDING(ctxt, item);
11427
0
    }
11428
0
    if (withParticle)
11429
0
  return ((xmlSchemaTreeItemPtr) particle);
11430
0
    else
11431
0
  return ((xmlSchemaTreeItemPtr) item);
11432
0
}
11433
11434
/**
11435
 * xmlSchemaParseRestriction:
11436
 * @ctxt:  a schema validation context
11437
 * @schema:  the schema being built
11438
 * @node:  a subtree containing XML Schema information
11439
 *
11440
 * parse a XML schema Restriction definition
11441
 * *WARNING* this interface is highly subject to change
11442
 *
11443
 * Returns the type definition or NULL in case of error
11444
 */
11445
static xmlSchemaTypePtr
11446
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11447
                          xmlNodePtr node, xmlSchemaTypeType parentType)
11448
0
{
11449
0
    xmlSchemaTypePtr type;
11450
0
    xmlNodePtr child = NULL;
11451
0
    xmlAttrPtr attr;
11452
11453
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11454
0
        return (NULL);
11455
    /* Not a component, don't create it. */
11456
0
    type = ctxt->ctxtType;
11457
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11458
11459
    /*
11460
    * Check for illegal attributes.
11461
    */
11462
0
    attr = node->properties;
11463
0
    while (attr != NULL) {
11464
0
  if (attr->ns == NULL) {
11465
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11466
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11467
0
    xmlSchemaPIllegalAttrErr(ctxt,
11468
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11469
0
      }
11470
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11471
0
      xmlSchemaPIllegalAttrErr(ctxt,
11472
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11473
0
  }
11474
0
  attr = attr->next;
11475
0
    }
11476
    /*
11477
    * Extract and validate attributes.
11478
    */
11479
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11480
    /*
11481
    * Attribute
11482
    */
11483
    /*
11484
    * Extract the base type. The "base" attribute is mandatory if inside
11485
    * a complex type or if redefining.
11486
    *
11487
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11488
    * among its [children]), the simple type definition which is
11489
    * the {content type} of the type definition `resolved` to by
11490
    * the `actual value` of the base [attribute]"
11491
    */
11492
0
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11493
0
  &(type->baseNs), &(type->base)) == 0)
11494
0
    {
11495
0
  if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11496
0
      xmlSchemaPMissingAttrErr(ctxt,
11497
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
11498
0
    NULL, node, "base", NULL);
11499
0
  } else if ((ctxt->isRedefine) &&
11500
0
      (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11501
0
  {
11502
0
      if (type->base == NULL) {
11503
0
    xmlSchemaPMissingAttrErr(ctxt,
11504
0
        XML_SCHEMAP_S4S_ATTR_MISSING,
11505
0
        NULL, node, "base", NULL);
11506
0
      } else if ((! xmlStrEqual(type->base, type->name)) ||
11507
0
    (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11508
0
      {
11509
0
    xmlChar *str1 = NULL, *str2 = NULL;
11510
    /*
11511
    * REDEFINE: SPEC src-redefine (5)
11512
    * "Within the [children], each <simpleType> must have a
11513
    * <restriction> among its [children] ... the `actual value` of
11514
    * whose base [attribute] must be the same as the `actual value`
11515
    * of its own name attribute plus target namespace;"
11516
    */
11517
0
    xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11518
0
        NULL, node, "This is a redefinition, but the QName "
11519
0
        "value '%s' of the 'base' attribute does not match the "
11520
0
        "type's designation '%s'",
11521
0
        xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11522
0
        xmlSchemaFormatQName(&str2, type->targetNamespace,
11523
0
      type->name), NULL);
11524
0
    FREE_AND_NULL(str1);
11525
0
    FREE_AND_NULL(str2);
11526
    /* Avoid confusion and erase the values. */
11527
0
    type->base = NULL;
11528
0
    type->baseNs = NULL;
11529
0
      }
11530
0
  }
11531
0
    }
11532
    /*
11533
    * And now for the children...
11534
    */
11535
0
    child = node->children;
11536
0
    if (IS_SCHEMA(child, "annotation")) {
11537
  /*
11538
  * Add the annotation to the simple type ancestor.
11539
  */
11540
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11541
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11542
0
        child = child->next;
11543
0
    }
11544
0
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11545
  /*
11546
  * Corresponds to <simpleType><restriction><simpleType>.
11547
  */
11548
0
  if (IS_SCHEMA(child, "simpleType")) {
11549
0
      if (type->base != NULL) {
11550
    /*
11551
    * src-restriction-base-or-simpleType
11552
    * Either the base [attribute] or the simpleType [child] of the
11553
    * <restriction> element must be present, but not both.
11554
    */
11555
0
    xmlSchemaPContentErr(ctxt,
11556
0
        XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11557
0
        NULL, node, child,
11558
0
        "The attribute 'base' and the <simpleType> child are "
11559
0
        "mutually exclusive", NULL);
11560
0
      } else {
11561
0
    type->baseType = (xmlSchemaTypePtr)
11562
0
        xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11563
0
      }
11564
0
      child = child->next;
11565
0
  } else if (type->base == NULL) {
11566
0
      xmlSchemaPContentErr(ctxt,
11567
0
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11568
0
    NULL, node, child,
11569
0
    "Either the attribute 'base' or a <simpleType> child "
11570
0
    "must be present", NULL);
11571
0
  }
11572
0
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11573
  /*
11574
  * Corresponds to <complexType><complexContent><restriction>...
11575
  * followed by:
11576
  *
11577
  * Model groups <all>, <choice> and <sequence>.
11578
  */
11579
0
  if (IS_SCHEMA(child, "all")) {
11580
0
      type->subtypes = (xmlSchemaTypePtr)
11581
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11582
0
        XML_SCHEMA_TYPE_ALL, 1);
11583
0
      child = child->next;
11584
0
  } else if (IS_SCHEMA(child, "choice")) {
11585
0
      type->subtypes = (xmlSchemaTypePtr)
11586
0
    xmlSchemaParseModelGroup(ctxt,
11587
0
        schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11588
0
      child = child->next;
11589
0
  } else if (IS_SCHEMA(child, "sequence")) {
11590
0
      type->subtypes = (xmlSchemaTypePtr)
11591
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11592
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11593
0
      child = child->next;
11594
  /*
11595
  * Model group reference <group>.
11596
  */
11597
0
  } else if (IS_SCHEMA(child, "group")) {
11598
0
      type->subtypes = (xmlSchemaTypePtr)
11599
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11600
      /*
11601
      * Note that the reference will be resolved in
11602
      * xmlSchemaResolveTypeReferences();
11603
      */
11604
0
      child = child->next;
11605
0
  }
11606
0
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11607
  /*
11608
  * Corresponds to <complexType><simpleContent><restriction>...
11609
  *
11610
  * "1.1 the simple type definition corresponding to the <simpleType>
11611
  * among the [children] of <restriction> if there is one;"
11612
  */
11613
0
  if (IS_SCHEMA(child, "simpleType")) {
11614
      /*
11615
      * We will store the to-be-restricted simple type in
11616
      * type->contentTypeDef *temporarily*.
11617
      */
11618
0
      type->contentTypeDef = (xmlSchemaTypePtr)
11619
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11620
0
      if ( type->contentTypeDef == NULL)
11621
0
    return (NULL);
11622
0
      child = child->next;
11623
0
  }
11624
0
    }
11625
11626
0
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11627
0
  (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11628
0
  xmlSchemaFacetPtr facet, lastfacet = NULL;
11629
  /*
11630
  * Corresponds to <complexType><simpleContent><restriction>...
11631
  * <simpleType><restriction>...
11632
  */
11633
11634
  /*
11635
  * Add the facets to the simple type ancestor.
11636
  */
11637
  /*
11638
  * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11639
  * Simple Type Definition Schema Representation Constraint:
11640
  * *Single Facet Value*
11641
  */
11642
0
  while ((IS_SCHEMA(child, "minInclusive")) ||
11643
0
      (IS_SCHEMA(child, "minExclusive")) ||
11644
0
      (IS_SCHEMA(child, "maxInclusive")) ||
11645
0
      (IS_SCHEMA(child, "maxExclusive")) ||
11646
0
      (IS_SCHEMA(child, "totalDigits")) ||
11647
0
      (IS_SCHEMA(child, "fractionDigits")) ||
11648
0
      (IS_SCHEMA(child, "pattern")) ||
11649
0
      (IS_SCHEMA(child, "enumeration")) ||
11650
0
      (IS_SCHEMA(child, "whiteSpace")) ||
11651
0
      (IS_SCHEMA(child, "length")) ||
11652
0
      (IS_SCHEMA(child, "maxLength")) ||
11653
0
      (IS_SCHEMA(child, "minLength"))) {
11654
0
      facet = xmlSchemaParseFacet(ctxt, schema, child);
11655
0
      if (facet != NULL) {
11656
0
    if (lastfacet == NULL)
11657
0
        type->facets = facet;
11658
0
    else
11659
0
        lastfacet->next = facet;
11660
0
    lastfacet = facet;
11661
0
    lastfacet->next = NULL;
11662
0
      }
11663
0
      child = child->next;
11664
0
  }
11665
  /*
11666
  * Create links for derivation and validation.
11667
  */
11668
0
  if (type->facets != NULL) {
11669
0
      xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11670
11671
0
      facet = type->facets;
11672
0
      do {
11673
0
    facetLink = (xmlSchemaFacetLinkPtr)
11674
0
        xmlMalloc(sizeof(xmlSchemaFacetLink));
11675
0
    if (facetLink == NULL) {
11676
0
        xmlSchemaPErrMemory(ctxt);
11677
0
        xmlFree(facetLink);
11678
0
        return (NULL);
11679
0
    }
11680
0
    facetLink->facet = facet;
11681
0
    facetLink->next = NULL;
11682
0
    if (lastFacetLink == NULL)
11683
0
        type->facetSet = facetLink;
11684
0
    else
11685
0
        lastFacetLink->next = facetLink;
11686
0
    lastFacetLink = facetLink;
11687
0
    facet = facet->next;
11688
0
      } while (facet != NULL);
11689
0
  }
11690
0
    }
11691
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11692
  /*
11693
  * Attribute uses/declarations.
11694
  */
11695
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11696
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11697
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11698
0
      return(NULL);
11699
  /*
11700
  * Attribute wildcard.
11701
  */
11702
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11703
0
      type->attributeWildcard =
11704
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11705
0
      child = child->next;
11706
0
  }
11707
0
    }
11708
0
    if (child != NULL) {
11709
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11710
0
      xmlSchemaPContentErr(ctxt,
11711
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11712
0
    NULL, node, child, NULL,
11713
0
    "annotation?, (group | all | choice | sequence)?, "
11714
0
    "((attribute | attributeGroup)*, anyAttribute?))");
11715
0
  } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11716
0
       xmlSchemaPContentErr(ctxt,
11717
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11718
0
    NULL, node, child, NULL,
11719
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11720
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11721
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11722
0
    "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11723
0
  } else {
11724
      /* Simple type */
11725
0
      xmlSchemaPContentErr(ctxt,
11726
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11727
0
    NULL, node, child, NULL,
11728
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11729
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11730
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11731
0
    "pattern)*))");
11732
0
  }
11733
0
    }
11734
0
    return (NULL);
11735
0
}
11736
11737
/**
11738
 * xmlSchemaParseExtension:
11739
 * @ctxt:  a schema validation context
11740
 * @schema:  the schema being built
11741
 * @node:  a subtree containing XML Schema information
11742
 *
11743
 * Parses an <extension>, which is found inside a
11744
 * <simpleContent> or <complexContent>.
11745
 * *WARNING* this interface is highly subject to change.
11746
 *
11747
 * TODO: Returns the type definition or NULL in case of error
11748
 */
11749
static xmlSchemaTypePtr
11750
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11751
                        xmlNodePtr node, xmlSchemaTypeType parentType)
11752
0
{
11753
0
    xmlSchemaTypePtr type;
11754
0
    xmlNodePtr child = NULL;
11755
0
    xmlAttrPtr attr;
11756
11757
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11758
0
        return (NULL);
11759
    /* Not a component, don't create it. */
11760
0
    type = ctxt->ctxtType;
11761
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11762
11763
    /*
11764
    * Check for illegal attributes.
11765
    */
11766
0
    attr = node->properties;
11767
0
    while (attr != NULL) {
11768
0
  if (attr->ns == NULL) {
11769
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11770
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11771
0
    xmlSchemaPIllegalAttrErr(ctxt,
11772
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11773
0
      }
11774
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11775
0
      xmlSchemaPIllegalAttrErr(ctxt,
11776
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11777
0
  }
11778
0
  attr = attr->next;
11779
0
    }
11780
11781
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11782
11783
    /*
11784
    * Attribute "base" - mandatory.
11785
    */
11786
0
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11787
0
  "base", &(type->baseNs), &(type->base)) == 0) &&
11788
0
  (type->base == NULL)) {
11789
0
  xmlSchemaPMissingAttrErr(ctxt,
11790
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11791
0
      NULL, node, "base", NULL);
11792
0
    }
11793
    /*
11794
    * And now for the children...
11795
    */
11796
0
    child = node->children;
11797
0
    if (IS_SCHEMA(child, "annotation")) {
11798
  /*
11799
  * Add the annotation to the type ancestor.
11800
  */
11801
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11802
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11803
0
        child = child->next;
11804
0
    }
11805
0
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11806
  /*
11807
  * Corresponds to <complexType><complexContent><extension>... and:
11808
  *
11809
  * Model groups <all>, <choice>, <sequence> and <group>.
11810
  */
11811
0
  if (IS_SCHEMA(child, "all")) {
11812
0
      type->subtypes = (xmlSchemaTypePtr)
11813
0
    xmlSchemaParseModelGroup(ctxt, schema,
11814
0
        child, XML_SCHEMA_TYPE_ALL, 1);
11815
0
      child = child->next;
11816
0
  } else if (IS_SCHEMA(child, "choice")) {
11817
0
      type->subtypes = (xmlSchemaTypePtr)
11818
0
    xmlSchemaParseModelGroup(ctxt, schema,
11819
0
        child, XML_SCHEMA_TYPE_CHOICE, 1);
11820
0
      child = child->next;
11821
0
  } else if (IS_SCHEMA(child, "sequence")) {
11822
0
      type->subtypes = (xmlSchemaTypePtr)
11823
0
    xmlSchemaParseModelGroup(ctxt, schema,
11824
0
    child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11825
0
      child = child->next;
11826
0
  } else if (IS_SCHEMA(child, "group")) {
11827
0
      type->subtypes = (xmlSchemaTypePtr)
11828
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11829
      /*
11830
      * Note that the reference will be resolved in
11831
      * xmlSchemaResolveTypeReferences();
11832
      */
11833
0
      child = child->next;
11834
0
  }
11835
0
    }
11836
0
    if (child != NULL) {
11837
  /*
11838
  * Attribute uses/declarations.
11839
  */
11840
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11841
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11842
0
      XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11843
0
      return(NULL);
11844
  /*
11845
  * Attribute wildcard.
11846
  */
11847
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11848
0
      ctxt->ctxtType->attributeWildcard =
11849
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11850
0
      child = child->next;
11851
0
  }
11852
0
    }
11853
0
    if (child != NULL) {
11854
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11855
      /* Complex content extension. */
11856
0
      xmlSchemaPContentErr(ctxt,
11857
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11858
0
    NULL, node, child, NULL,
11859
0
    "(annotation?, ((group | all | choice | sequence)?, "
11860
0
    "((attribute | attributeGroup)*, anyAttribute?)))");
11861
0
  } else {
11862
      /* Simple content extension. */
11863
0
      xmlSchemaPContentErr(ctxt,
11864
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11865
0
    NULL, node, child, NULL,
11866
0
    "(annotation?, ((attribute | attributeGroup)*, "
11867
0
    "anyAttribute?))");
11868
0
  }
11869
0
    }
11870
0
    return (NULL);
11871
0
}
11872
11873
/**
11874
 * xmlSchemaParseSimpleContent:
11875
 * @ctxt:  a schema validation context
11876
 * @schema:  the schema being built
11877
 * @node:  a subtree containing XML Schema information
11878
 *
11879
 * parse a XML schema SimpleContent definition
11880
 * *WARNING* this interface is highly subject to change
11881
 *
11882
 * Returns the type definition or NULL in case of error
11883
 */
11884
static int
11885
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11886
                            xmlSchemaPtr schema, xmlNodePtr node,
11887
          int *hasRestrictionOrExtension)
11888
0
{
11889
0
    xmlSchemaTypePtr type;
11890
0
    xmlNodePtr child = NULL;
11891
0
    xmlAttrPtr attr;
11892
11893
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11894
0
  (hasRestrictionOrExtension == NULL))
11895
0
        return (-1);
11896
0
    *hasRestrictionOrExtension = 0;
11897
    /* Not a component, don't create it. */
11898
0
    type = ctxt->ctxtType;
11899
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11900
    /*
11901
    * Check for illegal attributes.
11902
    */
11903
0
    attr = node->properties;
11904
0
    while (attr != NULL) {
11905
0
  if (attr->ns == NULL) {
11906
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11907
0
    xmlSchemaPIllegalAttrErr(ctxt,
11908
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11909
0
      }
11910
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11911
0
      xmlSchemaPIllegalAttrErr(ctxt,
11912
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11913
0
  }
11914
0
  attr = attr->next;
11915
0
    }
11916
11917
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11918
11919
    /*
11920
    * And now for the children...
11921
    */
11922
0
    child = node->children;
11923
0
    if (IS_SCHEMA(child, "annotation")) {
11924
  /*
11925
  * Add the annotation to the complex type ancestor.
11926
  */
11927
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11928
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11929
0
        child = child->next;
11930
0
    }
11931
0
    if (child == NULL) {
11932
0
  xmlSchemaPContentErr(ctxt,
11933
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11934
0
      NULL, node, NULL, NULL,
11935
0
      "(annotation?, (restriction | extension))");
11936
0
    }
11937
0
    if (child == NULL) {
11938
0
  xmlSchemaPContentErr(ctxt,
11939
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11940
0
      NULL, node, NULL, NULL,
11941
0
      "(annotation?, (restriction | extension))");
11942
0
    }
11943
0
    if (IS_SCHEMA(child, "restriction")) {
11944
0
        xmlSchemaParseRestriction(ctxt, schema, child,
11945
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11946
0
  (*hasRestrictionOrExtension) = 1;
11947
0
        child = child->next;
11948
0
    } else if (IS_SCHEMA(child, "extension")) {
11949
0
        xmlSchemaParseExtension(ctxt, schema, child,
11950
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11951
0
  (*hasRestrictionOrExtension) = 1;
11952
0
        child = child->next;
11953
0
    }
11954
0
    if (child != NULL) {
11955
0
  xmlSchemaPContentErr(ctxt,
11956
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11957
0
      NULL, node, child, NULL,
11958
0
      "(annotation?, (restriction | extension))");
11959
0
    }
11960
0
    return (0);
11961
0
}
11962
11963
/**
11964
 * xmlSchemaParseComplexContent:
11965
 * @ctxt:  a schema validation context
11966
 * @schema:  the schema being built
11967
 * @node:  a subtree containing XML Schema information
11968
 *
11969
 * parse a XML schema ComplexContent definition
11970
 * *WARNING* this interface is highly subject to change
11971
 *
11972
 * Returns the type definition or NULL in case of error
11973
 */
11974
static int
11975
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11976
                             xmlSchemaPtr schema, xmlNodePtr node,
11977
           int *hasRestrictionOrExtension)
11978
0
{
11979
0
    xmlSchemaTypePtr type;
11980
0
    xmlNodePtr child = NULL;
11981
0
    xmlAttrPtr attr;
11982
11983
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11984
0
  (hasRestrictionOrExtension == NULL))
11985
0
        return (-1);
11986
0
    *hasRestrictionOrExtension = 0;
11987
    /* Not a component, don't create it. */
11988
0
    type = ctxt->ctxtType;
11989
    /*
11990
    * Check for illegal attributes.
11991
    */
11992
0
    attr = node->properties;
11993
0
    while (attr != NULL) {
11994
0
  if (attr->ns == NULL) {
11995
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11996
0
    (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
11997
0
      {
11998
0
    xmlSchemaPIllegalAttrErr(ctxt,
11999
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12000
0
      }
12001
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12002
0
      xmlSchemaPIllegalAttrErr(ctxt,
12003
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12004
0
  }
12005
0
  attr = attr->next;
12006
0
    }
12007
12008
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12009
12010
    /*
12011
    * Set the 'mixed' on the complex type ancestor.
12012
    */
12013
0
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12014
0
  if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12015
0
      type->flags |= XML_SCHEMAS_TYPE_MIXED;
12016
0
    }
12017
0
    child = node->children;
12018
0
    if (IS_SCHEMA(child, "annotation")) {
12019
  /*
12020
  * Add the annotation to the complex type ancestor.
12021
  */
12022
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12023
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
12024
0
        child = child->next;
12025
0
    }
12026
0
    if (child == NULL) {
12027
0
  xmlSchemaPContentErr(ctxt,
12028
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12029
0
      NULL, node, NULL,
12030
0
      NULL, "(annotation?, (restriction | extension))");
12031
0
    }
12032
0
    if (child == NULL) {
12033
0
  xmlSchemaPContentErr(ctxt,
12034
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12035
0
      NULL, node, NULL,
12036
0
      NULL, "(annotation?, (restriction | extension))");
12037
0
    }
12038
0
    if (IS_SCHEMA(child, "restriction")) {
12039
0
        xmlSchemaParseRestriction(ctxt, schema, child,
12040
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12041
0
  (*hasRestrictionOrExtension) = 1;
12042
0
        child = child->next;
12043
0
    } else if (IS_SCHEMA(child, "extension")) {
12044
0
        xmlSchemaParseExtension(ctxt, schema, child,
12045
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12046
0
  (*hasRestrictionOrExtension) = 1;
12047
0
        child = child->next;
12048
0
    }
12049
0
    if (child != NULL) {
12050
0
  xmlSchemaPContentErr(ctxt,
12051
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12052
0
      NULL, node, child,
12053
0
      NULL, "(annotation?, (restriction | extension))");
12054
0
    }
12055
0
    return (0);
12056
0
}
12057
12058
/**
12059
 * xmlSchemaParseComplexType:
12060
 * @ctxt:  a schema validation context
12061
 * @schema:  the schema being built
12062
 * @node:  a subtree containing XML Schema information
12063
 *
12064
 * parse a XML schema Complex Type definition
12065
 * *WARNING* this interface is highly subject to change
12066
 *
12067
 * Returns the type definition or NULL in case of error
12068
 */
12069
static xmlSchemaTypePtr
12070
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12071
                          xmlNodePtr node, int topLevel)
12072
0
{
12073
0
    xmlSchemaTypePtr type, ctxtType;
12074
0
    xmlNodePtr child = NULL;
12075
0
    const xmlChar *name = NULL;
12076
0
    xmlAttrPtr attr;
12077
0
    const xmlChar *attrValue;
12078
#ifdef ENABLE_NAMED_LOCALS
12079
    char buf[40];
12080
#endif
12081
0
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
12082
12083
12084
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12085
0
        return (NULL);
12086
12087
0
    ctxtType = ctxt->ctxtType;
12088
12089
0
    if (topLevel) {
12090
0
  attr = xmlSchemaGetPropNode(node, "name");
12091
0
  if (attr == NULL) {
12092
0
      xmlSchemaPMissingAttrErr(ctxt,
12093
0
    XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12094
0
      return (NULL);
12095
0
  } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12096
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12097
0
      return (NULL);
12098
0
  }
12099
0
    }
12100
12101
0
    if (topLevel == 0) {
12102
  /*
12103
  * Parse as local complex type definition.
12104
  */
12105
#ifdef ENABLE_NAMED_LOCALS
12106
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12107
  type = xmlSchemaAddType(ctxt, schema,
12108
      XML_SCHEMA_TYPE_COMPLEX,
12109
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12110
      ctxt->targetNamespace, node, 0);
12111
#else
12112
0
  type = xmlSchemaAddType(ctxt, schema,
12113
0
      XML_SCHEMA_TYPE_COMPLEX,
12114
0
      NULL, ctxt->targetNamespace, node, 0);
12115
0
#endif
12116
0
  if (type == NULL)
12117
0
      return (NULL);
12118
0
  name = type->name;
12119
0
  type->node = node;
12120
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12121
  /*
12122
  * TODO: We need the target namespace.
12123
  */
12124
0
    } else {
12125
  /*
12126
  * Parse as global complex type definition.
12127
  */
12128
0
  type = xmlSchemaAddType(ctxt, schema,
12129
0
      XML_SCHEMA_TYPE_COMPLEX,
12130
0
      name, ctxt->targetNamespace, node, 1);
12131
0
  if (type == NULL)
12132
0
      return (NULL);
12133
0
  type->node = node;
12134
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12135
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12136
0
    }
12137
0
    type->targetNamespace = ctxt->targetNamespace;
12138
    /*
12139
    * Handle attributes.
12140
    */
12141
0
    attr = node->properties;
12142
0
    while (attr != NULL) {
12143
0
  if (attr->ns == NULL) {
12144
0
      if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12145
    /*
12146
    * Attribute "id".
12147
    */
12148
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12149
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12150
    /*
12151
    * Attribute "mixed".
12152
    */
12153
0
    if (xmlSchemaPGetBoolNodeValue(ctxt,
12154
0
      NULL, (xmlNodePtr) attr))
12155
0
        type->flags |= XML_SCHEMAS_TYPE_MIXED;
12156
0
      } else if (topLevel) {
12157
    /*
12158
    * Attributes of global complex type definitions.
12159
    */
12160
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12161
        /* Pass. */
12162
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12163
        /*
12164
        * Attribute "abstract".
12165
        */
12166
0
        if (xmlSchemaPGetBoolNodeValue(ctxt,
12167
0
          NULL, (xmlNodePtr) attr))
12168
0
      type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12169
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12170
        /*
12171
        * Attribute "final".
12172
        */
12173
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12174
0
      (xmlNodePtr) attr);
12175
0
        if (xmlSchemaPValAttrBlockFinal(attrValue,
12176
0
      &(type->flags),
12177
0
      -1,
12178
0
      XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12179
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12180
0
      -1, -1, -1) != 0)
12181
0
        {
12182
0
      xmlSchemaPSimpleTypeErr(ctxt,
12183
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12184
0
          NULL, (xmlNodePtr) attr, NULL,
12185
0
          "(#all | List of (extension | restriction))",
12186
0
          attrValue, NULL, NULL, NULL);
12187
0
        } else
12188
0
      final = 1;
12189
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12190
        /*
12191
        * Attribute "block".
12192
        */
12193
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12194
0
      (xmlNodePtr) attr);
12195
0
        if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12196
0
      -1,
12197
0
      XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12198
0
      XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12199
0
      -1, -1, -1) != 0) {
12200
0
      xmlSchemaPSimpleTypeErr(ctxt,
12201
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12202
0
          NULL, (xmlNodePtr) attr, NULL,
12203
0
          "(#all | List of (extension | restriction)) ",
12204
0
          attrValue, NULL, NULL, NULL);
12205
0
        } else
12206
0
      block = 1;
12207
0
    } else {
12208
0
      xmlSchemaPIllegalAttrErr(ctxt,
12209
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12210
0
    }
12211
0
      } else {
12212
0
    xmlSchemaPIllegalAttrErr(ctxt,
12213
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12214
0
      }
12215
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12216
0
      xmlSchemaPIllegalAttrErr(ctxt,
12217
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12218
0
  }
12219
0
  attr = attr->next;
12220
0
    }
12221
0
    if (! block) {
12222
  /*
12223
  * Apply default "block" values.
12224
  */
12225
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12226
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12227
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12228
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12229
0
    }
12230
0
    if (! final) {
12231
  /*
12232
  * Apply default "block" values.
12233
  */
12234
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12235
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12236
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12237
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12238
0
    }
12239
    /*
12240
    * And now for the children...
12241
    */
12242
0
    child = node->children;
12243
0
    if (IS_SCHEMA(child, "annotation")) {
12244
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12245
0
        child = child->next;
12246
0
    }
12247
0
    ctxt->ctxtType = type;
12248
0
    if (IS_SCHEMA(child, "simpleContent")) {
12249
  /*
12250
  * <complexType><simpleContent>...
12251
  * 3.4.3 : 2.2
12252
  * Specifying mixed='true' when the <simpleContent>
12253
  * alternative is chosen has no effect
12254
  */
12255
0
  if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12256
0
      type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12257
0
        xmlSchemaParseSimpleContent(ctxt, schema, child,
12258
0
      &hasRestrictionOrExtension);
12259
0
        child = child->next;
12260
0
    } else if (IS_SCHEMA(child, "complexContent")) {
12261
  /*
12262
  * <complexType><complexContent>...
12263
  */
12264
0
  type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12265
0
        xmlSchemaParseComplexContent(ctxt, schema, child,
12266
0
      &hasRestrictionOrExtension);
12267
0
        child = child->next;
12268
0
    } else {
12269
  /*
12270
  * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12271
  *
12272
  * SPEC
12273
  * "...the third alternative (neither <simpleContent> nor
12274
  * <complexContent>) is chosen. This case is understood as shorthand
12275
  * for complex content restricting the `ur-type definition`, and the
12276
  * details of the mappings should be modified as necessary.
12277
  */
12278
0
  type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12279
0
  type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12280
  /*
12281
  * Parse model groups.
12282
  */
12283
0
        if (IS_SCHEMA(child, "all")) {
12284
0
            type->subtypes = (xmlSchemaTypePtr)
12285
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12286
0
        XML_SCHEMA_TYPE_ALL, 1);
12287
0
            child = child->next;
12288
0
        } else if (IS_SCHEMA(child, "choice")) {
12289
0
            type->subtypes = (xmlSchemaTypePtr)
12290
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12291
0
        XML_SCHEMA_TYPE_CHOICE, 1);
12292
0
            child = child->next;
12293
0
        } else if (IS_SCHEMA(child, "sequence")) {
12294
0
            type->subtypes = (xmlSchemaTypePtr)
12295
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12296
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
12297
0
            child = child->next;
12298
0
        } else if (IS_SCHEMA(child, "group")) {
12299
0
            type->subtypes = (xmlSchemaTypePtr)
12300
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12301
      /*
12302
      * Note that the reference will be resolved in
12303
      * xmlSchemaResolveTypeReferences();
12304
      */
12305
0
            child = child->next;
12306
0
        }
12307
  /*
12308
  * Parse attribute decls/refs.
12309
  */
12310
0
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12311
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
12312
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12313
0
      return(NULL);
12314
  /*
12315
  * Parse attribute wildcard.
12316
  */
12317
0
  if (IS_SCHEMA(child, "anyAttribute")) {
12318
0
      type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12319
0
      child = child->next;
12320
0
  }
12321
0
    }
12322
0
    if (child != NULL) {
12323
0
  xmlSchemaPContentErr(ctxt,
12324
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12325
0
      NULL, node, child,
12326
0
      NULL, "(annotation?, (simpleContent | complexContent | "
12327
0
      "((group | all | choice | sequence)?, ((attribute | "
12328
0
      "attributeGroup)*, anyAttribute?))))");
12329
0
    }
12330
    /*
12331
    * REDEFINE: SPEC src-redefine (5)
12332
    */
12333
0
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12334
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12335
0
      NULL, node, "This is a redefinition, thus the "
12336
0
      "<complexType> must have a <restriction> or <extension> "
12337
0
      "grand-child", NULL);
12338
0
    }
12339
0
    ctxt->ctxtType = ctxtType;
12340
0
    return (type);
12341
0
}
12342
12343
/************************************************************************
12344
 *                  *
12345
 *      Validating using Schemas      *
12346
 *                  *
12347
 ************************************************************************/
12348
12349
/************************************************************************
12350
 *                  *
12351
 *      Reading/Writing Schemas       *
12352
 *                  *
12353
 ************************************************************************/
12354
12355
#if 0 /* Will be enabled if it is clear what options are needed. */
12356
/**
12357
 * xmlSchemaParserCtxtSetOptions:
12358
 * @ctxt: a schema parser context
12359
 * @options: a combination of xmlSchemaParserOption
12360
 *
12361
 * Sets the options to be used during the parse.
12362
 *
12363
 * Returns 0 in case of success, -1 in case of an
12364
 * API error.
12365
 */
12366
static int
12367
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12368
            int options)
12369
12370
{
12371
    int i;
12372
12373
    if (ctxt == NULL)
12374
  return (-1);
12375
    /*
12376
    * WARNING: Change the start value if adding to the
12377
    * xmlSchemaParseOption.
12378
    */
12379
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
12380
        if (options & 1<<i) {
12381
      return (-1);
12382
        }
12383
    }
12384
    ctxt->options = options;
12385
    return (0);
12386
}
12387
12388
/**
12389
 * xmlSchemaValidCtxtGetOptions:
12390
 * @ctxt: a schema parser context
12391
 *
12392
 * Returns the option combination of the parser context.
12393
 */
12394
static int
12395
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12396
12397
{
12398
    if (ctxt == NULL)
12399
  return (-1);
12400
    else
12401
  return (ctxt->options);
12402
}
12403
#endif
12404
12405
/**
12406
 * xmlSchemaNewParserCtxt:
12407
 * @URL:  the location of the schema
12408
 *
12409
 * Create an XML Schemas parse context for that file/resource expected
12410
 * to contain an XML Schemas file.
12411
 *
12412
 * Returns the parser context or NULL in case of error
12413
 */
12414
xmlSchemaParserCtxtPtr
12415
xmlSchemaNewParserCtxt(const char *URL)
12416
0
{
12417
0
    xmlSchemaParserCtxtPtr ret;
12418
12419
0
    if (URL == NULL)
12420
0
        return (NULL);
12421
12422
0
    ret = xmlSchemaParserCtxtCreate();
12423
0
    if (ret == NULL)
12424
0
  return(NULL);
12425
0
    ret->dict = xmlDictCreate();
12426
0
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12427
0
    return (ret);
12428
0
}
12429
12430
/**
12431
 * xmlSchemaNewMemParserCtxt:
12432
 * @buffer:  a pointer to a char array containing the schemas
12433
 * @size:  the size of the array
12434
 *
12435
 * Create an XML Schemas parse context for that memory buffer expected
12436
 * to contain an XML Schemas file.
12437
 *
12438
 * Returns the parser context or NULL in case of error
12439
 */
12440
xmlSchemaParserCtxtPtr
12441
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12442
0
{
12443
0
    xmlSchemaParserCtxtPtr ret;
12444
12445
0
    if ((buffer == NULL) || (size <= 0))
12446
0
        return (NULL);
12447
0
    ret = xmlSchemaParserCtxtCreate();
12448
0
    if (ret == NULL)
12449
0
  return(NULL);
12450
0
    ret->buffer = buffer;
12451
0
    ret->size = size;
12452
0
    ret->dict = xmlDictCreate();
12453
0
    return (ret);
12454
0
}
12455
12456
/**
12457
 * xmlSchemaNewDocParserCtxt:
12458
 * @doc:  a preparsed document tree
12459
 *
12460
 * Create an XML Schemas parse context for that document.
12461
 * NB. The document may be modified during the parsing process.
12462
 *
12463
 * Returns the parser context or NULL in case of error
12464
 */
12465
xmlSchemaParserCtxtPtr
12466
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12467
0
{
12468
0
    xmlSchemaParserCtxtPtr ret;
12469
12470
0
    if (doc == NULL)
12471
0
      return (NULL);
12472
0
    ret = xmlSchemaParserCtxtCreate();
12473
0
    if (ret == NULL)
12474
0
  return(NULL);
12475
0
    ret->doc = doc;
12476
0
    ret->dict = xmlDictCreate();
12477
    /* The application has responsibility for the document */
12478
0
    ret->preserve = 1;
12479
12480
0
    return (ret);
12481
0
}
12482
12483
/**
12484
 * xmlSchemaFreeParserCtxt:
12485
 * @ctxt:  the schema parser context
12486
 *
12487
 * Free the resources associated to the schema parser context
12488
 */
12489
void
12490
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12491
0
{
12492
0
    if (ctxt == NULL)
12493
0
        return;
12494
0
    if (ctxt->doc != NULL && !ctxt->preserve)
12495
0
        xmlFreeDoc(ctxt->doc);
12496
0
    if (ctxt->vctxt != NULL) {
12497
0
  xmlSchemaFreeValidCtxt(ctxt->vctxt);
12498
0
    }
12499
0
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12500
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
12501
0
  ctxt->constructor = NULL;
12502
0
  ctxt->ownsConstructor = 0;
12503
0
    }
12504
0
    if (ctxt->attrProhibs != NULL)
12505
0
  xmlSchemaItemListFree(ctxt->attrProhibs);
12506
0
    xmlDictFree(ctxt->dict);
12507
0
    xmlFree(ctxt);
12508
0
}
12509
12510
/************************************************************************
12511
 *                  *
12512
 *      Building the content models     *
12513
 *                  *
12514
 ************************************************************************/
12515
12516
/**
12517
 * xmlSchemaBuildContentModelForSubstGroup:
12518
 *
12519
 * Returns 1 if nillable, 0 otherwise
12520
 */
12521
static int
12522
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12523
  xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12524
0
{
12525
0
    xmlAutomataStatePtr start, tmp;
12526
0
    xmlSchemaElementPtr elemDecl, member;
12527
0
    xmlSchemaSubstGroupPtr substGroup;
12528
0
    int i;
12529
0
    int ret = 0;
12530
12531
0
    elemDecl = (xmlSchemaElementPtr) particle->children;
12532
    /*
12533
    * Wrap the substitution group with a CHOICE.
12534
    */
12535
0
    start = pctxt->state;
12536
0
    if (end == NULL)
12537
0
  end = xmlAutomataNewState(pctxt->am);
12538
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12539
0
    if (substGroup == NULL) {
12540
0
  xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12541
0
      XML_SCHEMAP_INTERNAL,
12542
0
      "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12543
0
      "declaration is marked having a subst. group but none "
12544
0
      "available.\n", elemDecl->name, NULL);
12545
0
  return(0);
12546
0
    }
12547
0
    if (counter >= 0) {
12548
  /*
12549
  * NOTE that we put the declaration in, even if it's abstract.
12550
  * However, an error will be raised during *validation* if an element
12551
  * information item shall be validated against an abstract element
12552
  * declaration.
12553
  */
12554
0
  tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12555
0
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
12556
0
              elemDecl->name, elemDecl->targetNamespace, elemDecl);
12557
  /*
12558
  * Add subst. group members.
12559
  */
12560
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12561
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12562
0
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
12563
0
                   member->name, member->targetNamespace, member);
12564
0
  }
12565
0
    } else if (particle->maxOccurs == 1) {
12566
  /*
12567
  * NOTE that we put the declaration in, even if it's abstract,
12568
  */
12569
0
  xmlAutomataNewEpsilon(pctxt->am,
12570
0
      xmlAutomataNewTransition2(pctxt->am,
12571
0
      start, NULL,
12572
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12573
  /*
12574
  * Add subst. group members.
12575
  */
12576
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12577
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12578
      /*
12579
      * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12580
      *  was incorrectly used instead of xmlAutomataNewTransition2()
12581
      *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12582
      *  section in xmlSchemaBuildAContentModel() ).
12583
      * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12584
      *  intended for the above "counter" section originally. I.e.,
12585
      *  check xs:all with subst-groups.
12586
      *
12587
      * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12588
      *                member->name, member->targetNamespace,
12589
      *          1, 1, member);
12590
      */
12591
0
      tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12592
0
    member->name, member->targetNamespace, member);
12593
0
      xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12594
0
  }
12595
0
    } else {
12596
0
  xmlAutomataStatePtr hop;
12597
0
  int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12598
0
      UNBOUNDED : particle->maxOccurs - 1;
12599
0
  int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12600
12601
0
  counter =
12602
0
      xmlAutomataNewCounter(pctxt->am, minOccurs,
12603
0
      maxOccurs);
12604
0
  hop = xmlAutomataNewState(pctxt->am);
12605
12606
0
  xmlAutomataNewEpsilon(pctxt->am,
12607
0
      xmlAutomataNewTransition2(pctxt->am,
12608
0
      start, NULL,
12609
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl),
12610
0
      hop);
12611
  /*
12612
   * Add subst. group members.
12613
   */
12614
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12615
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12616
0
      xmlAutomataNewEpsilon(pctxt->am,
12617
0
    xmlAutomataNewTransition2(pctxt->am,
12618
0
    start, NULL,
12619
0
    member->name, member->targetNamespace, member),
12620
0
    hop);
12621
0
  }
12622
0
  xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12623
0
  xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12624
0
    }
12625
0
    if (particle->minOccurs == 0) {
12626
0
  xmlAutomataNewEpsilon(pctxt->am, start, end);
12627
0
        ret = 1;
12628
0
    }
12629
0
    pctxt->state = end;
12630
0
    return(ret);
12631
0
}
12632
12633
/**
12634
 * xmlSchemaBuildContentModelForElement:
12635
 *
12636
 * Returns 1 if nillable, 0 otherwise
12637
 */
12638
static int
12639
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12640
             xmlSchemaParticlePtr particle)
12641
0
{
12642
0
    int ret = 0;
12643
12644
0
    if (((xmlSchemaElementPtr) particle->children)->flags &
12645
0
  XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12646
  /*
12647
  * Substitution groups.
12648
  */
12649
0
  ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12650
0
    } else {
12651
0
  xmlSchemaElementPtr elemDecl;
12652
0
  xmlAutomataStatePtr start;
12653
12654
0
  elemDecl = (xmlSchemaElementPtr) particle->children;
12655
12656
0
  if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12657
0
      return(0);
12658
0
  if (particle->maxOccurs == 1) {
12659
0
      start = ctxt->state;
12660
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12661
0
        elemDecl->name, elemDecl->targetNamespace, elemDecl);
12662
0
  } else if ((particle->maxOccurs >= UNBOUNDED) &&
12663
0
             (particle->minOccurs < 2)) {
12664
      /* Special case. */
12665
0
      start = ctxt->state;
12666
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12667
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12668
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12669
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12670
0
  } else {
12671
0
      int counter;
12672
0
      int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12673
0
          UNBOUNDED : particle->maxOccurs - 1;
12674
0
      int minOccurs = particle->minOccurs < 1 ?
12675
0
          0 : particle->minOccurs - 1;
12676
12677
0
      start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12678
0
      counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12679
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12680
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12681
0
      xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12682
0
      ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12683
0
    NULL, counter);
12684
0
  }
12685
0
  if (particle->minOccurs == 0) {
12686
0
      xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12687
0
            ret = 1;
12688
0
        }
12689
0
    }
12690
0
    return(ret);
12691
0
}
12692
12693
/**
12694
 * xmlSchemaBuildAContentModel:
12695
 * @ctxt:  the schema parser context
12696
 * @particle:  the particle component
12697
 * @name:  the complex type's name whose content is being built
12698
 *
12699
 * Create the automaton for the {content type} of a complex type.
12700
 *
12701
 * Returns 1 if the content is nillable, 0 otherwise
12702
 */
12703
static int
12704
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12705
          xmlSchemaParticlePtr particle)
12706
0
{
12707
0
    int ret = 0, tmp2;
12708
12709
0
    if (particle == NULL) {
12710
0
  PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12711
0
  return(1);
12712
0
    }
12713
0
    if (particle->children == NULL) {
12714
  /*
12715
  * Just return in this case. A missing "term" of the particle
12716
  * might arise due to an invalid "term" component.
12717
  */
12718
0
  return(1);
12719
0
    }
12720
12721
0
    switch (particle->children->type) {
12722
0
  case XML_SCHEMA_TYPE_ANY: {
12723
0
      xmlAutomataStatePtr start, end;
12724
0
      xmlSchemaWildcardPtr wild;
12725
0
      xmlSchemaWildcardNsPtr ns;
12726
12727
0
      wild = (xmlSchemaWildcardPtr) particle->children;
12728
12729
0
      start = pctxt->state;
12730
0
      end = xmlAutomataNewState(pctxt->am);
12731
12732
0
      if (particle->maxOccurs == 1) {
12733
0
    if (wild->any == 1) {
12734
        /*
12735
        * We need to add both transitions:
12736
        *
12737
        * 1. the {"*", "*"} for elements in a namespace.
12738
        */
12739
0
        pctxt->state =
12740
0
      xmlAutomataNewTransition2(pctxt->am,
12741
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12742
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12743
        /*
12744
        * 2. the {"*"} for elements in no namespace.
12745
        */
12746
0
        pctxt->state =
12747
0
      xmlAutomataNewTransition2(pctxt->am,
12748
0
      start, NULL, BAD_CAST "*", NULL, wild);
12749
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12750
12751
0
    } else if (wild->nsSet != NULL) {
12752
0
        ns = wild->nsSet;
12753
0
        do {
12754
0
      pctxt->state = start;
12755
0
      pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12756
0
          pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12757
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12758
0
      ns = ns->next;
12759
0
        } while (ns != NULL);
12760
12761
0
    } else if (wild->negNsSet != NULL) {
12762
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12763
0
      start, end, BAD_CAST "*", wild->negNsSet->value,
12764
0
      wild);
12765
0
    }
12766
0
      } else {
12767
0
    int counter;
12768
0
    xmlAutomataStatePtr hop;
12769
0
    int maxOccurs =
12770
0
        particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12771
0
                                           particle->maxOccurs - 1;
12772
0
    int minOccurs =
12773
0
        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12774
12775
0
    counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12776
0
    hop = xmlAutomataNewState(pctxt->am);
12777
0
    if (wild->any == 1) {
12778
0
        pctxt->state =
12779
0
      xmlAutomataNewTransition2(pctxt->am,
12780
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12781
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12782
0
        pctxt->state =
12783
0
      xmlAutomataNewTransition2(pctxt->am,
12784
0
      start, NULL, BAD_CAST "*", NULL, wild);
12785
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12786
0
    } else if (wild->nsSet != NULL) {
12787
0
        ns = wild->nsSet;
12788
0
        do {
12789
0
      pctxt->state =
12790
0
          xmlAutomataNewTransition2(pctxt->am,
12791
0
        start, NULL, BAD_CAST "*", ns->value, wild);
12792
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12793
0
      ns = ns->next;
12794
0
        } while (ns != NULL);
12795
12796
0
    } else if (wild->negNsSet != NULL) {
12797
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12798
0
      start, hop, BAD_CAST "*", wild->negNsSet->value,
12799
0
      wild);
12800
0
    }
12801
0
    xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12802
0
    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12803
0
      }
12804
0
      if (particle->minOccurs == 0) {
12805
0
    xmlAutomataNewEpsilon(pctxt->am, start, end);
12806
0
                ret = 1;
12807
0
      }
12808
0
      pctxt->state = end;
12809
0
            break;
12810
0
  }
12811
0
        case XML_SCHEMA_TYPE_ELEMENT:
12812
0
      ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12813
0
      break;
12814
0
        case XML_SCHEMA_TYPE_SEQUENCE:{
12815
0
            xmlSchemaTreeItemPtr sub;
12816
12817
0
            ret = 1;
12818
            /*
12819
             * If max and min occurrences are default (1) then
12820
             * simply iterate over the particles of the <sequence>.
12821
             */
12822
0
            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12823
0
                sub = particle->children->children;
12824
12825
0
                while (sub != NULL) {
12826
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12827
0
                                        (xmlSchemaParticlePtr) sub);
12828
0
                    if (tmp2 != 1) ret = 0;
12829
0
                    sub = sub->next;
12830
0
                }
12831
0
            } else {
12832
0
                xmlAutomataStatePtr oldstate = pctxt->state;
12833
12834
0
                if (particle->maxOccurs >= UNBOUNDED) {
12835
0
                    if (particle->minOccurs > 1) {
12836
0
                        xmlAutomataStatePtr tmp;
12837
0
                        int counter;
12838
12839
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12840
0
                            oldstate, NULL);
12841
0
                        oldstate = pctxt->state;
12842
12843
0
                        counter = xmlAutomataNewCounter(pctxt->am,
12844
0
                            particle->minOccurs - 1, UNBOUNDED);
12845
12846
0
                        sub = particle->children->children;
12847
0
                        while (sub != NULL) {
12848
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12849
0
                                            (xmlSchemaParticlePtr) sub);
12850
0
                            if (tmp2 != 1) ret = 0;
12851
0
                            sub = sub->next;
12852
0
                        }
12853
0
                        tmp = pctxt->state;
12854
0
                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
12855
0
                                                   oldstate, counter);
12856
0
                        pctxt->state =
12857
0
                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
12858
0
                                                       NULL, counter);
12859
0
                        if (ret == 1)
12860
0
                            xmlAutomataNewEpsilon(pctxt->am,
12861
0
                                                oldstate, pctxt->state);
12862
12863
0
                    } else {
12864
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12865
0
                            oldstate, NULL);
12866
0
                        oldstate = pctxt->state;
12867
12868
0
                        sub = particle->children->children;
12869
0
                        while (sub != NULL) {
12870
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12871
0
                                        (xmlSchemaParticlePtr) sub);
12872
0
                            if (tmp2 != 1) ret = 0;
12873
0
                            sub = sub->next;
12874
0
                        }
12875
0
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12876
0
                                              oldstate);
12877
                        /*
12878
                         * epsilon needed to block previous trans from
12879
                         * being allowed to enter back from another
12880
                         * construct
12881
                         */
12882
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12883
0
                                            pctxt->state, NULL);
12884
0
                        if (particle->minOccurs == 0) {
12885
0
                            xmlAutomataNewEpsilon(pctxt->am,
12886
0
                                oldstate, pctxt->state);
12887
0
                            ret = 1;
12888
0
                        }
12889
0
                    }
12890
0
                } else if ((particle->maxOccurs > 1)
12891
0
                           || (particle->minOccurs > 1)) {
12892
0
                    xmlAutomataStatePtr tmp;
12893
0
                    int counter;
12894
12895
0
                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12896
0
                        oldstate, NULL);
12897
0
                    oldstate = pctxt->state;
12898
12899
0
                    counter = xmlAutomataNewCounter(pctxt->am,
12900
0
                        particle->minOccurs - 1,
12901
0
                        particle->maxOccurs - 1);
12902
12903
0
                    sub = particle->children->children;
12904
0
                    while (sub != NULL) {
12905
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12906
0
                                        (xmlSchemaParticlePtr) sub);
12907
0
                        if (tmp2 != 1) ret = 0;
12908
0
                        sub = sub->next;
12909
0
                    }
12910
0
                    tmp = pctxt->state;
12911
0
                    xmlAutomataNewCountedTrans(pctxt->am,
12912
0
                        tmp, oldstate, counter);
12913
0
                    pctxt->state =
12914
0
                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12915
0
                                                   counter);
12916
0
                    if ((particle->minOccurs == 0) || (ret == 1)) {
12917
0
                        xmlAutomataNewEpsilon(pctxt->am,
12918
0
                                            oldstate, pctxt->state);
12919
0
                        ret = 1;
12920
0
                    }
12921
0
                } else {
12922
0
                    sub = particle->children->children;
12923
0
                    while (sub != NULL) {
12924
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12925
0
                                        (xmlSchemaParticlePtr) sub);
12926
0
                        if (tmp2 != 1) ret = 0;
12927
0
                        sub = sub->next;
12928
0
                    }
12929
12930
        /*
12931
         * epsilon needed to block previous trans from
12932
         * being allowed to enter back from another
12933
         * construct
12934
         */
12935
0
        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12936
0
          pctxt->state, NULL);
12937
12938
0
                    if (particle->minOccurs == 0) {
12939
0
                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
12940
0
                                              pctxt->state);
12941
0
                        ret = 1;
12942
0
                    }
12943
0
                }
12944
0
            }
12945
0
            break;
12946
0
        }
12947
0
        case XML_SCHEMA_TYPE_CHOICE:{
12948
0
            xmlSchemaTreeItemPtr sub;
12949
0
            xmlAutomataStatePtr start, end;
12950
12951
0
            ret = 0;
12952
0
            start = pctxt->state;
12953
0
            end = xmlAutomataNewState(pctxt->am);
12954
12955
            /*
12956
             * iterate over the subtypes and remerge the end with an
12957
             * epsilon transition
12958
             */
12959
0
            if (particle->maxOccurs == 1) {
12960
0
                sub = particle->children->children;
12961
0
                while (sub != NULL) {
12962
0
                    pctxt->state = start;
12963
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12964
0
                                        (xmlSchemaParticlePtr) sub);
12965
0
                    if (tmp2 == 1) ret = 1;
12966
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12967
0
                    sub = sub->next;
12968
0
                }
12969
0
            } else {
12970
0
                int counter;
12971
0
                xmlAutomataStatePtr hop, base;
12972
0
                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12973
0
                    UNBOUNDED : particle->maxOccurs - 1;
12974
0
                int minOccurs =
12975
0
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12976
12977
                /*
12978
                 * use a counter to keep track of the number of transitions
12979
                 * which went through the choice.
12980
                 */
12981
0
                counter =
12982
0
                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12983
0
                hop = xmlAutomataNewState(pctxt->am);
12984
0
                base = xmlAutomataNewState(pctxt->am);
12985
12986
0
                sub = particle->children->children;
12987
0
                while (sub != NULL) {
12988
0
                    pctxt->state = base;
12989
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12990
0
                                        (xmlSchemaParticlePtr) sub);
12991
0
                    if (tmp2 == 1) ret = 1;
12992
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12993
0
                    sub = sub->next;
12994
0
                }
12995
0
                xmlAutomataNewEpsilon(pctxt->am, start, base);
12996
0
                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
12997
0
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12998
0
                if (ret == 1)
12999
0
                    xmlAutomataNewEpsilon(pctxt->am, base, end);
13000
0
            }
13001
0
            if (particle->minOccurs == 0) {
13002
0
                xmlAutomataNewEpsilon(pctxt->am, start, end);
13003
0
                ret = 1;
13004
0
            }
13005
0
            pctxt->state = end;
13006
0
            break;
13007
0
        }
13008
0
        case XML_SCHEMA_TYPE_ALL:{
13009
0
            xmlAutomataStatePtr start, tmp;
13010
0
            xmlSchemaParticlePtr sub;
13011
0
            xmlSchemaElementPtr elemDecl;
13012
13013
0
            ret = 1;
13014
13015
0
            sub = (xmlSchemaParticlePtr) particle->children->children;
13016
0
            if (sub == NULL)
13017
0
                break;
13018
13019
0
            ret = 0;
13020
13021
0
            start = pctxt->state;
13022
0
            tmp = xmlAutomataNewState(pctxt->am);
13023
0
            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13024
0
            pctxt->state = tmp;
13025
0
            while (sub != NULL) {
13026
0
                pctxt->state = tmp;
13027
13028
0
                elemDecl = (xmlSchemaElementPtr) sub->children;
13029
0
                if (elemDecl == NULL) {
13030
0
                    PERROR_INT("xmlSchemaBuildAContentModel",
13031
0
                        "<element> particle has no term");
13032
0
                    return(ret);
13033
0
                };
13034
                /*
13035
                * NOTE: The {max occurs} of all the particles in the
13036
                * {particles} of the group must be 0 or 1; this is
13037
                * already ensured during the parse of the content of
13038
                * <all>.
13039
                */
13040
0
                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13041
0
                    int counter;
13042
13043
                    /*
13044
                     * This is an abstract group, we need to share
13045
                     * the same counter for all the element transitions
13046
                     * derived from the group
13047
                     */
13048
0
                    counter = xmlAutomataNewCounter(pctxt->am,
13049
0
                                       sub->minOccurs, sub->maxOccurs);
13050
0
                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
13051
0
                                       sub, counter, pctxt->state);
13052
0
                } else {
13053
0
                    if ((sub->minOccurs == 1) &&
13054
0
                        (sub->maxOccurs == 1)) {
13055
0
                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13056
0
                                                pctxt->state,
13057
0
                                                elemDecl->name,
13058
0
                                                elemDecl->targetNamespace,
13059
0
                                                1, 1, elemDecl);
13060
0
                    } else if ((sub->minOccurs == 0) &&
13061
0
                        (sub->maxOccurs == 1)) {
13062
13063
0
                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13064
0
                                                 pctxt->state,
13065
0
                                                 elemDecl->name,
13066
0
                                                 elemDecl->targetNamespace,
13067
0
                                                 0,
13068
0
                                                 1,
13069
0
                                                 elemDecl);
13070
0
                    }
13071
0
                }
13072
0
                sub = (xmlSchemaParticlePtr) sub->next;
13073
0
            }
13074
0
            pctxt->state =
13075
0
                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13076
0
            if (particle->minOccurs == 0) {
13077
0
                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13078
0
                ret = 1;
13079
0
            }
13080
0
            break;
13081
0
        }
13082
0
  case XML_SCHEMA_TYPE_GROUP:
13083
      /*
13084
      * If we hit a model group definition, then this means that
13085
      * it was empty, thus was not substituted for the containing
13086
      * model group. Just do nothing in this case.
13087
      * TODO: But the group should be substituted and not occur at
13088
      * all in the content model at this point. Fix this.
13089
      */
13090
0
            ret = 1;
13091
0
      break;
13092
0
        default:
13093
0
      xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13094
0
    "xmlSchemaBuildAContentModel",
13095
0
    "found unexpected term of type '%s' in content model",
13096
0
    WXS_ITEM_TYPE_NAME(particle->children), NULL);
13097
0
            return(ret);
13098
0
    }
13099
0
    return(ret);
13100
0
}
13101
13102
/**
13103
 * xmlSchemaBuildContentModel:
13104
 * @ctxt:  the schema parser context
13105
 * @type:  the complex type definition
13106
 * @name:  the element name
13107
 *
13108
 * Builds the content model of the complex type.
13109
 */
13110
static void
13111
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13112
         xmlSchemaParserCtxtPtr ctxt)
13113
0
{
13114
0
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13115
0
  (type->contModel != NULL) ||
13116
0
  ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13117
0
  (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13118
0
  return;
13119
13120
0
    ctxt->am = NULL;
13121
0
    ctxt->am = xmlNewAutomata();
13122
0
    if (ctxt->am == NULL) {
13123
0
  xmlSchemaPErrMemory(ctxt);
13124
0
        return;
13125
0
    }
13126
0
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
13127
    /*
13128
    * Build the automaton.
13129
    */
13130
0
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13131
0
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13132
0
    type->contModel = xmlAutomataCompile(ctxt->am);
13133
0
    if (type->contModel == NULL) {
13134
0
        xmlSchemaPCustomErr(ctxt,
13135
0
      XML_SCHEMAP_INTERNAL,
13136
0
      WXS_BASIC_CAST type, type->node,
13137
0
      "Failed to compile the content model", NULL);
13138
0
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13139
0
        xmlSchemaPCustomErr(ctxt,
13140
0
      XML_SCHEMAP_NOT_DETERMINISTIC,
13141
      /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13142
0
      WXS_BASIC_CAST type, type->node,
13143
0
      "The content model is not determinist", NULL);
13144
0
    } else {
13145
0
    }
13146
0
    ctxt->state = NULL;
13147
0
    xmlFreeAutomata(ctxt->am);
13148
0
    ctxt->am = NULL;
13149
0
}
13150
13151
/**
13152
 * xmlSchemaResolveElementReferences:
13153
 * @elem:  the schema element context
13154
 * @ctxt:  the schema parser context
13155
 *
13156
 * Resolves the references of an element declaration
13157
 * or particle, which has an element declaration as it's
13158
 * term.
13159
 */
13160
static void
13161
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13162
          xmlSchemaParserCtxtPtr ctxt)
13163
0
{
13164
0
    if ((ctxt == NULL) || (elemDecl == NULL) ||
13165
0
  ((elemDecl != NULL) &&
13166
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13167
0
        return;
13168
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13169
13170
0
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13171
0
  xmlSchemaTypePtr type;
13172
13173
  /* (type definition) ... otherwise the type definition `resolved`
13174
  * to by the `actual value` of the type [attribute] ...
13175
  */
13176
0
  type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13177
0
      elemDecl->namedTypeNs);
13178
0
  if (type == NULL) {
13179
0
      xmlSchemaPResCompAttrErr(ctxt,
13180
0
    XML_SCHEMAP_SRC_RESOLVE,
13181
0
    WXS_BASIC_CAST elemDecl, elemDecl->node,
13182
0
    "type", elemDecl->namedType, elemDecl->namedTypeNs,
13183
0
    XML_SCHEMA_TYPE_BASIC, "type definition");
13184
0
  } else
13185
0
      elemDecl->subtypes = type;
13186
0
    }
13187
0
    if (elemDecl->substGroup != NULL) {
13188
0
  xmlSchemaElementPtr substHead;
13189
13190
  /*
13191
  * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13192
  * substitutionGroup?
13193
  */
13194
0
  substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13195
0
      elemDecl->substGroupNs);
13196
0
  if (substHead == NULL) {
13197
0
      xmlSchemaPResCompAttrErr(ctxt,
13198
0
    XML_SCHEMAP_SRC_RESOLVE,
13199
0
    WXS_BASIC_CAST elemDecl, NULL,
13200
0
    "substitutionGroup", elemDecl->substGroup,
13201
0
    elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13202
0
  } else {
13203
0
      xmlSchemaResolveElementReferences(substHead, ctxt);
13204
      /*
13205
      * Set the "substitution group affiliation".
13206
      * NOTE that now we use the "refDecl" field for this.
13207
      */
13208
0
      WXS_SUBST_HEAD(elemDecl) = substHead;
13209
      /*
13210
      * The type definitions is set to:
13211
      * SPEC "...the {type definition} of the element
13212
      * declaration `resolved` to by the `actual value`
13213
      * of the substitutionGroup [attribute], if present"
13214
      */
13215
0
      if (elemDecl->subtypes == NULL) {
13216
0
                if (substHead->subtypes == NULL) {
13217
                    /*
13218
                     * This can happen with self-referencing substitution
13219
                     * groups. The cycle will be detected later, but we have
13220
                     * to set subtypes to avoid null-pointer dereferences.
13221
                     */
13222
0
              elemDecl->subtypes = xmlSchemaGetBuiltInType(
13223
0
                            XML_SCHEMAS_ANYTYPE);
13224
0
                } else {
13225
0
        elemDecl->subtypes = substHead->subtypes;
13226
0
                }
13227
0
            }
13228
0
  }
13229
0
    }
13230
    /*
13231
    * SPEC "The definition of anyType serves as the default type definition
13232
    * for element declarations whose XML representation does not specify one."
13233
    */
13234
0
    if ((elemDecl->subtypes == NULL) &&
13235
0
  (elemDecl->namedType == NULL) &&
13236
0
  (elemDecl->substGroup == NULL))
13237
0
  elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13238
0
}
13239
13240
/**
13241
 * xmlSchemaResolveUnionMemberTypes:
13242
 * @ctxt:  the schema parser context
13243
 * @type:  the schema simple type definition
13244
 *
13245
 * Checks and builds the "member type definitions" property of the union
13246
 * simple type. This handles part (1), part (2) is done in
13247
 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13248
 *
13249
 * Returns -1 in case of an internal error, 0 otherwise.
13250
 */
13251
static int
13252
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13253
         xmlSchemaTypePtr type)
13254
0
{
13255
13256
0
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
13257
0
    xmlSchemaTypePtr memberType;
13258
13259
    /*
13260
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13261
    * define the explicit members as the type definitions `resolved`
13262
    * to by the items in the `actual value` of the memberTypes [attribute],
13263
    * if any, followed by the type definitions corresponding to the
13264
    * <simpleType>s among the [children] of <union>, if any."
13265
    */
13266
    /*
13267
    * Resolve references.
13268
    */
13269
0
    link = type->memberTypes;
13270
0
    lastLink = NULL;
13271
0
    while (link != NULL) {
13272
0
  const xmlChar *name, *nsName;
13273
13274
0
  name = ((xmlSchemaQNameRefPtr) link->type)->name;
13275
0
  nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13276
13277
0
  memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13278
0
  if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13279
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13280
0
    WXS_BASIC_CAST type, type->node, "memberTypes",
13281
0
    name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13282
      /*
13283
      * Remove the member type link.
13284
      */
13285
0
      if (lastLink == NULL)
13286
0
    type->memberTypes = link->next;
13287
0
      else
13288
0
    lastLink->next = link->next;
13289
0
      newLink = link;
13290
0
      link = link->next;
13291
0
      xmlFree(newLink);
13292
0
  } else {
13293
0
      link->type = memberType;
13294
0
      lastLink = link;
13295
0
      link = link->next;
13296
0
  }
13297
0
    }
13298
    /*
13299
    * Add local simple types,
13300
    */
13301
0
    memberType = type->subtypes;
13302
0
    while (memberType != NULL) {
13303
0
  link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13304
0
  if (link == NULL) {
13305
0
      xmlSchemaPErrMemory(ctxt);
13306
0
      return (-1);
13307
0
  }
13308
0
  link->type = memberType;
13309
0
  link->next = NULL;
13310
0
  if (lastLink == NULL)
13311
0
      type->memberTypes = link;
13312
0
  else
13313
0
      lastLink->next = link;
13314
0
  lastLink = link;
13315
0
  memberType = memberType->next;
13316
0
    }
13317
0
    return (0);
13318
0
}
13319
13320
/**
13321
 * xmlSchemaIsDerivedFromBuiltInType:
13322
 * @ctxt:  the schema parser context
13323
 * @type:  the type definition
13324
 * @valType: the value type
13325
 *
13326
 *
13327
 * Returns 1 if the type has the given value type, or
13328
 * is derived from such a type.
13329
 */
13330
static int
13331
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13332
0
{
13333
0
    if (type == NULL)
13334
0
  return (0);
13335
0
    if (WXS_IS_COMPLEX(type))
13336
0
  return (0);
13337
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13338
0
  if (type->builtInType == valType)
13339
0
      return(1);
13340
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13341
0
      (type->builtInType == XML_SCHEMAS_ANYTYPE))
13342
0
      return (0);
13343
0
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13344
0
    }
13345
0
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13346
0
}
13347
13348
#if 0
13349
/**
13350
 * xmlSchemaIsDerivedFromBuiltInType:
13351
 * @ctxt:  the schema parser context
13352
 * @type:  the type definition
13353
 * @valType: the value type
13354
 *
13355
 *
13356
 * Returns 1 if the type has the given value type, or
13357
 * is derived from such a type.
13358
 */
13359
static int
13360
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13361
{
13362
    if (type == NULL)
13363
  return (0);
13364
    if (WXS_IS_COMPLEX(type))
13365
  return (0);
13366
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13367
  if (type->builtInType == valType)
13368
      return(1);
13369
  return (0);
13370
    } else
13371
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13372
13373
    return (0);
13374
}
13375
13376
static xmlSchemaTypePtr
13377
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13378
{
13379
    if (type == NULL)
13380
  return (NULL);
13381
    if (WXS_IS_COMPLEX(type))
13382
  return (NULL);
13383
    if (type->type == XML_SCHEMA_TYPE_BASIC)
13384
  return(type);
13385
    return(xmlSchemaQueryBuiltInType(type->subtypes));
13386
}
13387
#endif
13388
13389
/**
13390
 * xmlSchemaGetPrimitiveType:
13391
 * @type:  the simpleType definition
13392
 *
13393
 * Returns the primitive type of the given type or
13394
 * NULL in case of error.
13395
 */
13396
static xmlSchemaTypePtr
13397
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13398
0
{
13399
13400
0
    while (type != NULL) {
13401
  /*
13402
  * Note that anySimpleType is actually not a primitive type
13403
  * but we need that here.
13404
  */
13405
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13406
0
     (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13407
0
      return (type);
13408
0
  type = type->baseType;
13409
0
    }
13410
13411
0
    return (NULL);
13412
0
}
13413
13414
#if 0
13415
/**
13416
 * xmlSchemaGetBuiltInTypeAncestor:
13417
 * @type:  the simpleType definition
13418
 *
13419
 * Returns the primitive type of the given type or
13420
 * NULL in case of error.
13421
 */
13422
static xmlSchemaTypePtr
13423
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13424
{
13425
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13426
  return (0);
13427
    while (type != NULL) {
13428
  if (type->type == XML_SCHEMA_TYPE_BASIC)
13429
      return (type);
13430
  type = type->baseType;
13431
    }
13432
13433
    return (NULL);
13434
}
13435
#endif
13436
13437
/**
13438
 * xmlSchemaCloneWildcardNsConstraints:
13439
 * @ctxt:  the schema parser context
13440
 * @dest:  the destination wildcard
13441
 * @source: the source wildcard
13442
 *
13443
 * Clones the namespace constraints of source
13444
 * and assigns them to dest.
13445
 * Returns -1 on internal error, 0 otherwise.
13446
 */
13447
static int
13448
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13449
            xmlSchemaWildcardPtr dest,
13450
            xmlSchemaWildcardPtr source)
13451
0
{
13452
0
    xmlSchemaWildcardNsPtr cur, tmp, last;
13453
13454
0
    if ((source == NULL) || (dest == NULL))
13455
0
  return(-1);
13456
0
    dest->any = source->any;
13457
0
    cur = source->nsSet;
13458
0
    last = NULL;
13459
0
    while (cur != NULL) {
13460
0
  tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13461
0
  if (tmp == NULL)
13462
0
      return(-1);
13463
0
  tmp->value = cur->value;
13464
0
  if (last == NULL)
13465
0
      dest->nsSet = tmp;
13466
0
  else
13467
0
      last->next = tmp;
13468
0
  last = tmp;
13469
0
  cur = cur->next;
13470
0
    }
13471
0
    if (dest->negNsSet != NULL)
13472
0
  xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13473
0
    if (source->negNsSet != NULL) {
13474
0
  dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13475
0
  if (dest->negNsSet == NULL)
13476
0
      return(-1);
13477
0
  dest->negNsSet->value = source->negNsSet->value;
13478
0
    } else
13479
0
  dest->negNsSet = NULL;
13480
0
    return(0);
13481
0
}
13482
13483
/**
13484
 * xmlSchemaUnionWildcards:
13485
 * @ctxt:  the schema parser context
13486
 * @completeWild:  the first wildcard
13487
 * @curWild: the second wildcard
13488
 *
13489
 * Unions the namespace constraints of the given wildcards.
13490
 * @completeWild will hold the resulting union.
13491
 * Returns a positive error code on failure, -1 in case of an
13492
 * internal error, 0 otherwise.
13493
 */
13494
static int
13495
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13496
          xmlSchemaWildcardPtr completeWild,
13497
          xmlSchemaWildcardPtr curWild)
13498
0
{
13499
0
    xmlSchemaWildcardNsPtr cur, curB, tmp;
13500
13501
    /*
13502
    * 1 If O1 and O2 are the same value, then that value must be the
13503
    * value.
13504
    */
13505
0
    if ((completeWild->any == curWild->any) &&
13506
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13507
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13508
13509
0
  if ((completeWild->negNsSet == NULL) ||
13510
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13511
13512
0
      if (completeWild->nsSet != NULL) {
13513
0
    int found = 0;
13514
13515
    /*
13516
    * Check equality of sets.
13517
    */
13518
0
    cur = completeWild->nsSet;
13519
0
    while (cur != NULL) {
13520
0
        found = 0;
13521
0
        curB = curWild->nsSet;
13522
0
        while (curB != NULL) {
13523
0
      if (cur->value == curB->value) {
13524
0
          found = 1;
13525
0
          break;
13526
0
      }
13527
0
      curB = curB->next;
13528
0
        }
13529
0
        if (!found)
13530
0
      break;
13531
0
        cur = cur->next;
13532
0
    }
13533
0
    if (found)
13534
0
        return(0);
13535
0
      } else
13536
0
    return(0);
13537
0
  }
13538
0
    }
13539
    /*
13540
    * 2 If either O1 or O2 is any, then any must be the value
13541
    */
13542
0
    if (completeWild->any != curWild->any) {
13543
0
  if (completeWild->any == 0) {
13544
0
      completeWild->any = 1;
13545
0
      if (completeWild->nsSet != NULL) {
13546
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13547
0
    completeWild->nsSet = NULL;
13548
0
      }
13549
0
      if (completeWild->negNsSet != NULL) {
13550
0
    xmlFree(completeWild->negNsSet);
13551
0
    completeWild->negNsSet = NULL;
13552
0
      }
13553
0
  }
13554
0
  return (0);
13555
0
    }
13556
    /*
13557
    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13558
    * then the union of those sets must be the value.
13559
    */
13560
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13561
0
  int found;
13562
0
  xmlSchemaWildcardNsPtr start;
13563
13564
0
  cur = curWild->nsSet;
13565
0
  start = completeWild->nsSet;
13566
0
  while (cur != NULL) {
13567
0
      found = 0;
13568
0
      curB = start;
13569
0
      while (curB != NULL) {
13570
0
    if (cur->value == curB->value) {
13571
0
        found = 1;
13572
0
        break;
13573
0
    }
13574
0
    curB = curB->next;
13575
0
      }
13576
0
      if (!found) {
13577
0
    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13578
0
    if (tmp == NULL)
13579
0
        return (-1);
13580
0
    tmp->value = cur->value;
13581
0
    tmp->next = completeWild->nsSet;
13582
0
    completeWild->nsSet = tmp;
13583
0
      }
13584
0
      cur = cur->next;
13585
0
  }
13586
13587
0
  return(0);
13588
0
    }
13589
    /*
13590
    * 4 If the two are negations of different values (namespace names
13591
    * or `absent`), then a pair of not and `absent` must be the value.
13592
    */
13593
0
    if ((completeWild->negNsSet != NULL) &&
13594
0
  (curWild->negNsSet != NULL) &&
13595
0
  (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13596
0
  completeWild->negNsSet->value = NULL;
13597
13598
0
  return(0);
13599
0
    }
13600
    /*
13601
     * 5.
13602
     */
13603
0
    if (((completeWild->negNsSet != NULL) &&
13604
0
  (completeWild->negNsSet->value != NULL) &&
13605
0
  (curWild->nsSet != NULL)) ||
13606
0
  ((curWild->negNsSet != NULL) &&
13607
0
  (curWild->negNsSet->value != NULL) &&
13608
0
  (completeWild->nsSet != NULL))) {
13609
13610
0
  int nsFound, absentFound = 0;
13611
13612
0
  if (completeWild->nsSet != NULL) {
13613
0
      cur = completeWild->nsSet;
13614
0
      curB = curWild->negNsSet;
13615
0
  } else {
13616
0
      cur = curWild->nsSet;
13617
0
      curB = completeWild->negNsSet;
13618
0
  }
13619
0
  nsFound = 0;
13620
0
  while (cur != NULL) {
13621
0
      if (cur->value == NULL)
13622
0
    absentFound = 1;
13623
0
      else if (cur->value == curB->value)
13624
0
    nsFound = 1;
13625
0
      if (nsFound && absentFound)
13626
0
    break;
13627
0
      cur = cur->next;
13628
0
  }
13629
13630
0
  if (nsFound && absentFound) {
13631
      /*
13632
      * 5.1 If the set S includes both the negated namespace
13633
      * name and `absent`, then any must be the value.
13634
      */
13635
0
      completeWild->any = 1;
13636
0
      if (completeWild->nsSet != NULL) {
13637
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13638
0
    completeWild->nsSet = NULL;
13639
0
      }
13640
0
      if (completeWild->negNsSet != NULL) {
13641
0
    xmlFree(completeWild->negNsSet);
13642
0
    completeWild->negNsSet = NULL;
13643
0
      }
13644
0
  } else if (nsFound && (!absentFound)) {
13645
      /*
13646
      * 5.2 If the set S includes the negated namespace name
13647
      * but not `absent`, then a pair of not and `absent` must
13648
      * be the value.
13649
      */
13650
0
      if (completeWild->nsSet != NULL) {
13651
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13652
0
    completeWild->nsSet = NULL;
13653
0
      }
13654
0
      if (completeWild->negNsSet == NULL) {
13655
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13656
0
    if (completeWild->negNsSet == NULL)
13657
0
        return (-1);
13658
0
      }
13659
0
      completeWild->negNsSet->value = NULL;
13660
0
  } else if ((!nsFound) && absentFound) {
13661
      /*
13662
      * 5.3 If the set S includes `absent` but not the negated
13663
      * namespace name, then the union is not expressible.
13664
      */
13665
0
      xmlSchemaPErr(ctxt, completeWild->node,
13666
0
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13667
0
    "The union of the wildcard is not expressible.\n",
13668
0
    NULL, NULL);
13669
0
      return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13670
0
  } else if ((!nsFound) && (!absentFound)) {
13671
      /*
13672
      * 5.4 If the set S does not include either the negated namespace
13673
      * name or `absent`, then whichever of O1 or O2 is a pair of not
13674
      * and a namespace name must be the value.
13675
      */
13676
0
      if (completeWild->negNsSet == NULL) {
13677
0
    if (completeWild->nsSet != NULL) {
13678
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13679
0
        completeWild->nsSet = NULL;
13680
0
    }
13681
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13682
0
    if (completeWild->negNsSet == NULL)
13683
0
        return (-1);
13684
0
    completeWild->negNsSet->value = curWild->negNsSet->value;
13685
0
      }
13686
0
  }
13687
0
  return (0);
13688
0
    }
13689
    /*
13690
     * 6.
13691
     */
13692
0
    if (((completeWild->negNsSet != NULL) &&
13693
0
  (completeWild->negNsSet->value == NULL) &&
13694
0
  (curWild->nsSet != NULL)) ||
13695
0
  ((curWild->negNsSet != NULL) &&
13696
0
  (curWild->negNsSet->value == NULL) &&
13697
0
  (completeWild->nsSet != NULL))) {
13698
13699
0
  if (completeWild->nsSet != NULL) {
13700
0
      cur = completeWild->nsSet;
13701
0
  } else {
13702
0
      cur = curWild->nsSet;
13703
0
  }
13704
0
  while (cur != NULL) {
13705
0
      if (cur->value == NULL) {
13706
    /*
13707
    * 6.1 If the set S includes `absent`, then any must be the
13708
    * value.
13709
    */
13710
0
    completeWild->any = 1;
13711
0
    if (completeWild->nsSet != NULL) {
13712
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13713
0
        completeWild->nsSet = NULL;
13714
0
    }
13715
0
    if (completeWild->negNsSet != NULL) {
13716
0
        xmlFree(completeWild->negNsSet);
13717
0
        completeWild->negNsSet = NULL;
13718
0
    }
13719
0
    return (0);
13720
0
      }
13721
0
      cur = cur->next;
13722
0
  }
13723
0
  if (completeWild->negNsSet == NULL) {
13724
      /*
13725
      * 6.2 If the set S does not include `absent`, then a pair of not
13726
      * and `absent` must be the value.
13727
      */
13728
0
      if (completeWild->nsSet != NULL) {
13729
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13730
0
    completeWild->nsSet = NULL;
13731
0
      }
13732
0
      completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13733
0
      if (completeWild->negNsSet == NULL)
13734
0
    return (-1);
13735
0
      completeWild->negNsSet->value = NULL;
13736
0
  }
13737
0
  return (0);
13738
0
    }
13739
0
    return (0);
13740
13741
0
}
13742
13743
/**
13744
 * xmlSchemaIntersectWildcards:
13745
 * @ctxt:  the schema parser context
13746
 * @completeWild:  the first wildcard
13747
 * @curWild: the second wildcard
13748
 *
13749
 * Intersects the namespace constraints of the given wildcards.
13750
 * @completeWild will hold the resulting intersection.
13751
 * Returns a positive error code on failure, -1 in case of an
13752
 * internal error, 0 otherwise.
13753
 */
13754
static int
13755
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13756
          xmlSchemaWildcardPtr completeWild,
13757
          xmlSchemaWildcardPtr curWild)
13758
0
{
13759
0
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13760
13761
    /*
13762
    * 1 If O1 and O2 are the same value, then that value must be the
13763
    * value.
13764
    */
13765
0
    if ((completeWild->any == curWild->any) &&
13766
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13767
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13768
13769
0
  if ((completeWild->negNsSet == NULL) ||
13770
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13771
13772
0
      if (completeWild->nsSet != NULL) {
13773
0
    int found = 0;
13774
13775
    /*
13776
    * Check equality of sets.
13777
    */
13778
0
    cur = completeWild->nsSet;
13779
0
    while (cur != NULL) {
13780
0
        found = 0;
13781
0
        curB = curWild->nsSet;
13782
0
        while (curB != NULL) {
13783
0
      if (cur->value == curB->value) {
13784
0
          found = 1;
13785
0
          break;
13786
0
      }
13787
0
      curB = curB->next;
13788
0
        }
13789
0
        if (!found)
13790
0
      break;
13791
0
        cur = cur->next;
13792
0
    }
13793
0
    if (found)
13794
0
        return(0);
13795
0
      } else
13796
0
    return(0);
13797
0
  }
13798
0
    }
13799
    /*
13800
    * 2 If either O1 or O2 is any, then the other must be the value.
13801
    */
13802
0
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
13803
0
  if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13804
0
      return(-1);
13805
0
  return(0);
13806
0
    }
13807
    /*
13808
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
13809
    * name or `absent`) and the other is a set of (namespace names or
13810
    * `absent`), then that set, minus the negated value if it was in
13811
    * the set, minus `absent` if it was in the set, must be the value.
13812
    */
13813
0
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13814
0
  ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13815
0
  const xmlChar *neg;
13816
13817
0
  if (completeWild->nsSet == NULL) {
13818
0
      neg = completeWild->negNsSet->value;
13819
0
      if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13820
0
    return(-1);
13821
0
  } else
13822
0
      neg = curWild->negNsSet->value;
13823
  /*
13824
  * Remove absent and negated.
13825
  */
13826
0
  prev = NULL;
13827
0
  cur = completeWild->nsSet;
13828
0
  while (cur != NULL) {
13829
0
      if (cur->value == NULL) {
13830
0
    if (prev == NULL)
13831
0
        completeWild->nsSet = cur->next;
13832
0
    else
13833
0
        prev->next = cur->next;
13834
0
    xmlFree(cur);
13835
0
    break;
13836
0
      }
13837
0
      prev = cur;
13838
0
      cur = cur->next;
13839
0
  }
13840
0
  if (neg != NULL) {
13841
0
      prev = NULL;
13842
0
      cur = completeWild->nsSet;
13843
0
      while (cur != NULL) {
13844
0
    if (cur->value == neg) {
13845
0
        if (prev == NULL)
13846
0
      completeWild->nsSet = cur->next;
13847
0
        else
13848
0
      prev->next = cur->next;
13849
0
        xmlFree(cur);
13850
0
        break;
13851
0
    }
13852
0
    prev = cur;
13853
0
    cur = cur->next;
13854
0
      }
13855
0
  }
13856
13857
0
  return(0);
13858
0
    }
13859
    /*
13860
    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13861
    * then the intersection of those sets must be the value.
13862
    */
13863
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13864
0
  int found;
13865
13866
0
  cur = completeWild->nsSet;
13867
0
  prev = NULL;
13868
0
  while (cur != NULL) {
13869
0
      found = 0;
13870
0
      curB = curWild->nsSet;
13871
0
      while (curB != NULL) {
13872
0
    if (cur->value == curB->value) {
13873
0
        found = 1;
13874
0
        break;
13875
0
    }
13876
0
    curB = curB->next;
13877
0
      }
13878
0
      if (!found) {
13879
0
    if (prev == NULL)
13880
0
        completeWild->nsSet = cur->next;
13881
0
    else
13882
0
        prev->next = cur->next;
13883
0
    tmp = cur->next;
13884
0
    xmlFree(cur);
13885
0
    cur = tmp;
13886
0
    continue;
13887
0
      }
13888
0
      prev = cur;
13889
0
      cur = cur->next;
13890
0
  }
13891
13892
0
  return(0);
13893
0
    }
13894
    /* 5 If the two are negations of different namespace names,
13895
    * then the intersection is not expressible
13896
    */
13897
0
    if ((completeWild->negNsSet != NULL) &&
13898
0
  (curWild->negNsSet != NULL) &&
13899
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13900
0
  (completeWild->negNsSet->value != NULL) &&
13901
0
  (curWild->negNsSet->value != NULL)) {
13902
13903
0
  xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13904
0
      "The intersection of the wildcard is not expressible.\n",
13905
0
      NULL, NULL);
13906
0
  return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13907
0
    }
13908
    /*
13909
    * 6 If the one is a negation of a namespace name and the other
13910
    * is a negation of `absent`, then the one which is the negation
13911
    * of a namespace name must be the value.
13912
    */
13913
0
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13914
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13915
0
  (completeWild->negNsSet->value == NULL)) {
13916
0
  completeWild->negNsSet->value =  curWild->negNsSet->value;
13917
0
    }
13918
0
    return(0);
13919
0
}
13920
13921
/**
13922
 * xmlSchemaIsWildcardNsConstraintSubset:
13923
 * @ctxt:  the schema parser context
13924
 * @sub:  the first wildcard
13925
 * @super: the second wildcard
13926
 *
13927
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13928
 *
13929
 * Returns 0 if the namespace constraint of @sub is an intensional
13930
 * subset of @super, 1 otherwise.
13931
 */
13932
static int
13933
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13934
        xmlSchemaWildcardPtr super)
13935
0
{
13936
    /*
13937
    * 1 super must be any.
13938
    */
13939
0
    if (super->any)
13940
0
  return (0);
13941
    /*
13942
    * 2.1 sub must be a pair of not and a namespace name or `absent`.
13943
    * 2.2 super must be a pair of not and the same value.
13944
    */
13945
0
    if ((sub->negNsSet != NULL) &&
13946
0
  (super->negNsSet != NULL) &&
13947
0
  (sub->negNsSet->value == super->negNsSet->value))
13948
0
  return (0);
13949
    /*
13950
    * 3.1 sub must be a set whose members are either namespace names or `absent`.
13951
    */
13952
0
    if (sub->nsSet != NULL) {
13953
  /*
13954
  * 3.2.1 super must be the same set or a superset thereof.
13955
  */
13956
0
  if (super->nsSet != NULL) {
13957
0
      xmlSchemaWildcardNsPtr cur, curB;
13958
0
      int found = 0;
13959
13960
0
      cur = sub->nsSet;
13961
0
      while (cur != NULL) {
13962
0
    found = 0;
13963
0
    curB = super->nsSet;
13964
0
    while (curB != NULL) {
13965
0
        if (cur->value == curB->value) {
13966
0
      found = 1;
13967
0
      break;
13968
0
        }
13969
0
        curB = curB->next;
13970
0
    }
13971
0
    if (!found)
13972
0
        return (1);
13973
0
    cur = cur->next;
13974
0
      }
13975
0
      if (found)
13976
0
    return (0);
13977
0
  } else if (super->negNsSet != NULL) {
13978
0
      xmlSchemaWildcardNsPtr cur;
13979
      /*
13980
      * 3.2.2 super must be a pair of not and a namespace name or
13981
      * `absent` and that value must not be in sub's set.
13982
      */
13983
0
      cur = sub->nsSet;
13984
0
      while (cur != NULL) {
13985
0
    if (cur->value == super->negNsSet->value)
13986
0
        return (1);
13987
0
    cur = cur->next;
13988
0
      }
13989
0
      return (0);
13990
0
  }
13991
0
    }
13992
0
    return (1);
13993
0
}
13994
13995
static int
13996
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13997
             int *fixed,
13998
             const xmlChar **value,
13999
             xmlSchemaValPtr *val)
14000
0
{
14001
0
    *fixed = 0;
14002
0
    *value = NULL;
14003
0
    if (val != 0)
14004
0
  *val = NULL;
14005
14006
0
    if (attruse->defValue != NULL) {
14007
0
  *value = attruse->defValue;
14008
0
  if (val != NULL)
14009
0
      *val = attruse->defVal;
14010
0
  if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14011
0
      *fixed = 1;
14012
0
  return(1);
14013
0
    } else if ((attruse->attrDecl != NULL) &&
14014
0
  (attruse->attrDecl->defValue != NULL)) {
14015
0
  *value = attruse->attrDecl->defValue;
14016
0
  if (val != NULL)
14017
0
      *val = attruse->attrDecl->defVal;
14018
0
  if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14019
0
      *fixed = 1;
14020
0
  return(1);
14021
0
    }
14022
0
    return(0);
14023
0
}
14024
/**
14025
 * xmlSchemaCheckCVCWildcardNamespace:
14026
 * @wild:  the wildcard
14027
 * @ns:  the namespace
14028
 *
14029
 * Validation Rule: Wildcard allows Namespace Name
14030
 * (cvc-wildcard-namespace)
14031
 *
14032
 * Returns 0 if the given namespace matches the wildcard,
14033
 * 1 otherwise and -1 on API errors.
14034
 */
14035
static int
14036
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14037
           const xmlChar* ns)
14038
0
{
14039
0
    if (wild == NULL)
14040
0
  return(-1);
14041
14042
0
    if (wild->any)
14043
0
  return(0);
14044
0
    else if (wild->nsSet != NULL) {
14045
0
  xmlSchemaWildcardNsPtr cur;
14046
14047
0
  cur = wild->nsSet;
14048
0
  while (cur != NULL) {
14049
0
      if (xmlStrEqual(cur->value, ns))
14050
0
    return(0);
14051
0
      cur = cur->next;
14052
0
  }
14053
0
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14054
0
  (!xmlStrEqual(wild->negNsSet->value, ns)))
14055
0
  return(0);
14056
14057
0
    return(1);
14058
0
}
14059
14060
0
#define XML_SCHEMA_ACTION_DERIVE 0
14061
0
#define XML_SCHEMA_ACTION_REDEFINE 1
14062
14063
0
#define WXS_ACTION_STR(a) \
14064
0
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14065
14066
/*
14067
* Schema Component Constraint:
14068
*   Derivation Valid (Restriction, Complex)
14069
*   derivation-ok-restriction (2) - (4)
14070
*
14071
* ATTENTION:
14072
* In XML Schema 1.1 this will be:
14073
* Validation Rule:
14074
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14075
*
14076
*/
14077
static int
14078
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14079
               int action,
14080
               xmlSchemaBasicItemPtr item,
14081
               xmlSchemaBasicItemPtr baseItem,
14082
               xmlSchemaItemListPtr uses,
14083
               xmlSchemaItemListPtr baseUses,
14084
               xmlSchemaWildcardPtr wild,
14085
               xmlSchemaWildcardPtr baseWild)
14086
0
{
14087
0
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
14088
0
    int i, j, found; /* err = 0; */
14089
0
    const xmlChar *bEffValue;
14090
0
    int effFixed;
14091
14092
0
    if (uses != NULL) {
14093
0
  for (i = 0; i < uses->nbItems; i++) {
14094
0
      cur = uses->items[i];
14095
0
      found = 0;
14096
0
      if (baseUses == NULL)
14097
0
    goto not_found;
14098
0
      for (j = 0; j < baseUses->nbItems; j++) {
14099
0
    bcur = baseUses->items[j];
14100
0
    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14101
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14102
0
        (WXS_ATTRUSE_DECL_TNS(cur) ==
14103
0
      WXS_ATTRUSE_DECL_TNS(bcur)))
14104
0
    {
14105
        /*
14106
        * (2.1) "If there is an attribute use in the {attribute
14107
        * uses} of the {base type definition} (call this B) whose
14108
        * {attribute declaration} has the same {name} and {target
14109
        * namespace}, then  all of the following must be true:"
14110
        */
14111
0
        found = 1;
14112
14113
0
        if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14114
0
      (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14115
0
        {
14116
0
      xmlChar *str = NULL;
14117
      /*
14118
      * (2.1.1) "one of the following must be true:"
14119
      * (2.1.1.1) "B's {required} is false."
14120
      * (2.1.1.2) "R's {required} is true."
14121
      */
14122
0
      xmlSchemaPAttrUseErr4(pctxt,
14123
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14124
0
          WXS_ITEM_NODE(item), item, cur,
14125
0
          "The 'optional' attribute use is inconsistent "
14126
0
          "with the corresponding 'required' attribute use of "
14127
0
          "the %s %s",
14128
0
          WXS_ACTION_STR(action),
14129
0
          xmlSchemaGetComponentDesignation(&str, baseItem),
14130
0
          NULL, NULL);
14131
0
      FREE_AND_NULL(str);
14132
      /* err = pctxt->err; */
14133
0
        } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14134
0
      WXS_ATTRUSE_TYPEDEF(cur),
14135
0
      WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14136
0
        {
14137
0
      xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14138
14139
      /*
14140
      * SPEC (2.1.2) "R's {attribute declaration}'s
14141
      * {type definition} must be validly derived from
14142
      * B's {type definition} given the empty set as
14143
      * defined in Type Derivation OK (Simple) ($3.14.6)."
14144
      */
14145
0
      xmlSchemaPAttrUseErr4(pctxt,
14146
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14147
0
          WXS_ITEM_NODE(item), item, cur,
14148
0
          "The attribute declaration's %s "
14149
0
          "is not validly derived from "
14150
0
          "the corresponding %s of the "
14151
0
          "attribute declaration in the %s %s",
14152
0
          xmlSchemaGetComponentDesignation(&strA,
14153
0
        WXS_ATTRUSE_TYPEDEF(cur)),
14154
0
          xmlSchemaGetComponentDesignation(&strB,
14155
0
        WXS_ATTRUSE_TYPEDEF(bcur)),
14156
0
          WXS_ACTION_STR(action),
14157
0
          xmlSchemaGetComponentDesignation(&strC, baseItem));
14158
          /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14159
0
      FREE_AND_NULL(strA);
14160
0
      FREE_AND_NULL(strB);
14161
0
      FREE_AND_NULL(strC);
14162
      /* err = pctxt->err; */
14163
0
        } else {
14164
      /*
14165
      * 2.1.3 [Definition:]  Let the effective value
14166
      * constraint of an attribute use be its {value
14167
      * constraint}, if present, otherwise its {attribute
14168
      * declaration}'s {value constraint} .
14169
      */
14170
0
      xmlSchemaGetEffectiveValueConstraint(bcur,
14171
0
          &effFixed, &bEffValue, NULL);
14172
      /*
14173
      * 2.1.3 ... one of the following must be true
14174
      *
14175
      * 2.1.3.1 B's `effective value constraint` is
14176
      * `absent` or default.
14177
      */
14178
0
      if ((bEffValue != NULL) &&
14179
0
          (effFixed == 1)) {
14180
0
          const xmlChar *rEffValue = NULL;
14181
14182
0
          xmlSchemaGetEffectiveValueConstraint(bcur,
14183
0
        &effFixed, &rEffValue, NULL);
14184
          /*
14185
          * 2.1.3.2 R's `effective value constraint` is
14186
          * fixed with the same string as B's.
14187
          * MAYBE TODO: Compare the computed values.
14188
          *       Hmm, it says "same string" so
14189
          *       string-equality might really be sufficient.
14190
          */
14191
0
          if ((effFixed == 0) ||
14192
0
        (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14193
0
          {
14194
0
        xmlChar *str = NULL;
14195
14196
0
        xmlSchemaPAttrUseErr4(pctxt,
14197
0
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14198
0
            WXS_ITEM_NODE(item), item, cur,
14199
0
            "The effective value constraint of the "
14200
0
            "attribute use is inconsistent with "
14201
0
            "its correspondent in the %s %s",
14202
0
            WXS_ACTION_STR(action),
14203
0
            xmlSchemaGetComponentDesignation(&str,
14204
0
          baseItem),
14205
0
            NULL, NULL);
14206
0
        FREE_AND_NULL(str);
14207
        /* err = pctxt->err; */
14208
0
          }
14209
0
      }
14210
0
        }
14211
0
        break;
14212
0
    }
14213
0
      }
14214
0
not_found:
14215
0
      if (!found) {
14216
    /*
14217
    * (2.2) "otherwise the {base type definition} must have an
14218
    * {attribute wildcard} and the {target namespace} of the
14219
    * R's {attribute declaration} must be `valid` with respect
14220
    * to that wildcard, as defined in Wildcard allows Namespace
14221
    * Name ($3.10.4)."
14222
    */
14223
0
    if ((baseWild == NULL) ||
14224
0
        (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14225
0
        (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14226
0
    {
14227
0
        xmlChar *str = NULL;
14228
14229
0
        xmlSchemaPAttrUseErr4(pctxt,
14230
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14231
0
      WXS_ITEM_NODE(item), item, cur,
14232
0
      "Neither a matching attribute use, "
14233
0
      "nor a matching wildcard exists in the %s %s",
14234
0
      WXS_ACTION_STR(action),
14235
0
      xmlSchemaGetComponentDesignation(&str, baseItem),
14236
0
      NULL, NULL);
14237
0
        FREE_AND_NULL(str);
14238
        /* err = pctxt->err; */
14239
0
    }
14240
0
      }
14241
0
  }
14242
0
    }
14243
    /*
14244
    * SPEC derivation-ok-restriction (3):
14245
    * (3) "For each attribute use in the {attribute uses} of the {base type
14246
    * definition} whose {required} is true, there must be an attribute
14247
    * use with an {attribute declaration} with the same {name} and
14248
    * {target namespace} as its {attribute declaration} in the {attribute
14249
    * uses} of the complex type definition itself whose {required} is true.
14250
    */
14251
0
    if (baseUses != NULL) {
14252
0
  for (j = 0; j < baseUses->nbItems; j++) {
14253
0
      bcur = baseUses->items[j];
14254
0
      if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14255
0
    continue;
14256
0
      found = 0;
14257
0
      if (uses != NULL) {
14258
0
    for (i = 0; i < uses->nbItems; i++) {
14259
0
        cur = uses->items[i];
14260
0
        if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14261
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14262
0
      (WXS_ATTRUSE_DECL_TNS(cur) ==
14263
0
      WXS_ATTRUSE_DECL_TNS(bcur))) {
14264
0
      found = 1;
14265
0
      break;
14266
0
        }
14267
0
    }
14268
0
      }
14269
0
      if (!found) {
14270
0
    xmlChar *strA = NULL, *strB = NULL;
14271
14272
0
    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14273
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14274
0
        NULL, item,
14275
0
        "A matching attribute use for the "
14276
0
        "'required' %s of the %s %s is missing",
14277
0
        xmlSchemaGetComponentDesignation(&strA, bcur),
14278
0
        WXS_ACTION_STR(action),
14279
0
        xmlSchemaGetComponentDesignation(&strB, baseItem),
14280
0
        NULL);
14281
0
    FREE_AND_NULL(strA);
14282
0
    FREE_AND_NULL(strB);
14283
0
      }
14284
0
  }
14285
0
    }
14286
    /*
14287
    * derivation-ok-restriction (4)
14288
    */
14289
0
    if (wild != NULL) {
14290
  /*
14291
  * (4) "If there is an {attribute wildcard}, all of the
14292
  * following must be true:"
14293
  */
14294
0
  if (baseWild == NULL) {
14295
0
      xmlChar *str = NULL;
14296
14297
      /*
14298
      * (4.1) "The {base type definition} must also have one."
14299
      */
14300
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14301
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14302
0
    NULL, item,
14303
0
    "The %s has an attribute wildcard, "
14304
0
    "but the %s %s '%s' does not have one",
14305
0
    WXS_ITEM_TYPE_NAME(item),
14306
0
    WXS_ACTION_STR(action),
14307
0
    WXS_ITEM_TYPE_NAME(baseItem),
14308
0
    xmlSchemaGetComponentQName(&str, baseItem));
14309
0
      FREE_AND_NULL(str);
14310
0
      return(pctxt->err);
14311
0
  } else if ((baseWild->any == 0) &&
14312
0
    xmlSchemaCheckCOSNSSubset(wild, baseWild))
14313
0
  {
14314
0
      xmlChar *str = NULL;
14315
      /*
14316
      * (4.2) "The complex type definition's {attribute wildcard}'s
14317
      * {namespace constraint} must be a subset of the {base type
14318
      * definition}'s {attribute wildcard}'s {namespace constraint},
14319
      * as defined by Wildcard Subset ($3.10.6)."
14320
      */
14321
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14322
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14323
0
    NULL, item,
14324
0
    "The attribute wildcard is not a valid "
14325
0
    "subset of the wildcard in the %s %s '%s'",
14326
0
    WXS_ACTION_STR(action),
14327
0
    WXS_ITEM_TYPE_NAME(baseItem),
14328
0
    xmlSchemaGetComponentQName(&str, baseItem),
14329
0
    NULL);
14330
0
      FREE_AND_NULL(str);
14331
0
      return(pctxt->err);
14332
0
  }
14333
  /* 4.3 Unless the {base type definition} is the `ur-type
14334
  * definition`, the complex type definition's {attribute
14335
  * wildcard}'s {process contents} must be identical to or
14336
  * stronger than the {base type definition}'s {attribute
14337
  * wildcard}'s {process contents}, where strict is stronger
14338
  * than lax is stronger than skip.
14339
  */
14340
0
  if ((! WXS_IS_ANYTYPE(baseItem)) &&
14341
0
      (wild->processContents < baseWild->processContents)) {
14342
0
      xmlChar *str = NULL;
14343
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14344
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14345
0
    NULL, baseItem,
14346
0
    "The {process contents} of the attribute wildcard is "
14347
0
    "weaker than the one in the %s %s '%s'",
14348
0
    WXS_ACTION_STR(action),
14349
0
    WXS_ITEM_TYPE_NAME(baseItem),
14350
0
    xmlSchemaGetComponentQName(&str, baseItem),
14351
0
    NULL);
14352
0
      FREE_AND_NULL(str)
14353
0
    return(pctxt->err);
14354
0
  }
14355
0
    }
14356
0
    return(0);
14357
0
}
14358
14359
14360
static int
14361
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14362
          xmlSchemaBasicItemPtr item,
14363
          xmlSchemaWildcardPtr *completeWild,
14364
          xmlSchemaItemListPtr list,
14365
          xmlSchemaItemListPtr prohibs);
14366
/**
14367
 * xmlSchemaFixupTypeAttributeUses:
14368
 * @ctxt:  the schema parser context
14369
 * @type:  the complex type definition
14370
 *
14371
 *
14372
 * Builds the wildcard and the attribute uses on the given complex type.
14373
 * Returns -1 if an internal error occurs, 0 otherwise.
14374
 *
14375
 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14376
 * strings, so recheck this if we start to hardcode some schemata, since
14377
 * they might not be in the same dict.
14378
 * NOTE: It is allowed to "extend" the xs:anyType type.
14379
 */
14380
static int
14381
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14382
          xmlSchemaTypePtr type)
14383
0
{
14384
0
    xmlSchemaTypePtr baseType = NULL;
14385
0
    xmlSchemaAttributeUsePtr use;
14386
0
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14387
14388
0
    if (type->baseType == NULL) {
14389
0
  PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14390
0
      "no base type");
14391
0
        return (-1);
14392
0
    }
14393
0
    baseType = type->baseType;
14394
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14395
0
  if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14396
0
      return(-1);
14397
14398
0
    uses = type->attrUses;
14399
0
    baseUses = baseType->attrUses;
14400
    /*
14401
    * Expand attribute group references. And build the 'complete'
14402
    * wildcard, i.e. intersect multiple wildcards.
14403
    * Move attribute prohibitions into a separate list.
14404
    */
14405
0
    if (uses != NULL) {
14406
0
  if (WXS_IS_RESTRICTION(type)) {
14407
      /*
14408
      * This one will transfer all attr. prohibitions
14409
      * into pctxt->attrProhibs.
14410
      */
14411
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14412
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14413
0
    pctxt->attrProhibs) == -1)
14414
0
      {
14415
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14416
0
    "failed to expand attributes");
14417
0
                return(-1);
14418
0
      }
14419
0
      if (pctxt->attrProhibs->nbItems != 0)
14420
0
    prohibs = pctxt->attrProhibs;
14421
0
  } else {
14422
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14423
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14424
0
    NULL) == -1)
14425
0
      {
14426
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14427
0
    "failed to expand attributes");
14428
0
                return(-1);
14429
0
      }
14430
0
  }
14431
0
    }
14432
    /*
14433
    * Inherit the attribute uses of the base type.
14434
    */
14435
0
    if (baseUses != NULL) {
14436
0
  int i, j;
14437
0
  xmlSchemaAttributeUseProhibPtr pro;
14438
14439
0
  if (WXS_IS_RESTRICTION(type)) {
14440
0
      int usesCount;
14441
0
      xmlSchemaAttributeUsePtr tmp;
14442
14443
0
      if (uses != NULL)
14444
0
    usesCount = uses->nbItems;
14445
0
      else
14446
0
    usesCount = 0;
14447
14448
      /* Restriction. */
14449
0
      for (i = 0; i < baseUses->nbItems; i++) {
14450
0
    use = baseUses->items[i];
14451
0
    if (prohibs) {
14452
        /*
14453
        * Filter out prohibited uses.
14454
        */
14455
0
        for (j = 0; j < prohibs->nbItems; j++) {
14456
0
      pro = prohibs->items[j];
14457
0
      if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14458
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14459
0
        pro->targetNamespace))
14460
0
      {
14461
0
          goto inherit_next;
14462
0
      }
14463
0
        }
14464
0
    }
14465
0
    if (usesCount) {
14466
        /*
14467
        * Filter out existing uses.
14468
        */
14469
0
        for (j = 0; j < usesCount; j++) {
14470
0
      tmp = uses->items[j];
14471
0
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
14472
0
        WXS_ATTRUSE_DECL_NAME(tmp)) &&
14473
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14474
0
        WXS_ATTRUSE_DECL_TNS(tmp)))
14475
0
      {
14476
0
          goto inherit_next;
14477
0
      }
14478
0
        }
14479
0
    }
14480
0
    if (uses == NULL) {
14481
0
        type->attrUses = xmlSchemaItemListCreate();
14482
0
        if (type->attrUses == NULL)
14483
0
      goto exit_failure;
14484
0
        uses = type->attrUses;
14485
0
    }
14486
0
    xmlSchemaItemListAddSize(uses, 2, use);
14487
0
inherit_next: {}
14488
0
      }
14489
0
  } else {
14490
      /* Extension. */
14491
0
      for (i = 0; i < baseUses->nbItems; i++) {
14492
0
    use = baseUses->items[i];
14493
0
    if (uses == NULL) {
14494
0
        type->attrUses = xmlSchemaItemListCreate();
14495
0
        if (type->attrUses == NULL)
14496
0
      goto exit_failure;
14497
0
        uses = type->attrUses;
14498
0
    }
14499
0
    xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14500
0
      }
14501
0
  }
14502
0
    }
14503
    /*
14504
    * Shrink attr. uses.
14505
    */
14506
0
    if (uses) {
14507
0
  if (uses->nbItems == 0) {
14508
0
      xmlSchemaItemListFree(uses);
14509
0
      type->attrUses = NULL;
14510
0
  }
14511
  /*
14512
  * TODO: We could shrink the size of the array
14513
  * to fit the actual number of items.
14514
  */
14515
0
    }
14516
    /*
14517
    * Compute the complete wildcard.
14518
    */
14519
0
    if (WXS_IS_EXTENSION(type)) {
14520
0
  if (baseType->attributeWildcard != NULL) {
14521
      /*
14522
      * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14523
      * the appropriate case among the following:"
14524
      */
14525
0
      if (type->attributeWildcard != NULL) {
14526
    /*
14527
    * Union the complete wildcard with the base wildcard.
14528
    * SPEC {attribute wildcard}
14529
    * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14530
    * and {annotation} are those of the `complete wildcard`,
14531
    * and whose {namespace constraint} is the intensional union
14532
    * of the {namespace constraint} of the `complete wildcard`
14533
    * and of the `base wildcard`, as defined in Attribute
14534
    * Wildcard Union ($3.10.6)."
14535
    */
14536
0
    if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14537
0
        baseType->attributeWildcard) == -1)
14538
0
        goto exit_failure;
14539
0
      } else {
14540
    /*
14541
    * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14542
    * then the `base wildcard`."
14543
    */
14544
0
    type->attributeWildcard = baseType->attributeWildcard;
14545
0
      }
14546
0
  } else {
14547
      /*
14548
      * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14549
      * `complete wildcard`"
14550
      * NOOP
14551
      */
14552
0
  }
14553
0
    } else {
14554
  /*
14555
  * SPEC {attribute wildcard}
14556
  * (3.1) "If the <restriction> alternative is chosen, then the
14557
  * `complete wildcard`;"
14558
  * NOOP
14559
  */
14560
0
    }
14561
14562
0
    return (0);
14563
14564
0
exit_failure:
14565
0
    return(-1);
14566
0
}
14567
14568
/**
14569
 * xmlSchemaTypeFinalContains:
14570
 * @schema:  the schema
14571
 * @type:  the type definition
14572
 * @final: the final
14573
 *
14574
 * Evaluates if a type definition contains the given "final".
14575
 * This does take "finalDefault" into account as well.
14576
 *
14577
 * Returns 1 if the type does contain the given "final",
14578
 * 0 otherwise.
14579
 */
14580
static int
14581
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14582
0
{
14583
0
    if (type == NULL)
14584
0
  return (0);
14585
0
    if (type->flags & final)
14586
0
  return (1);
14587
0
    else
14588
0
  return (0);
14589
0
}
14590
14591
/**
14592
 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14593
 * @type:  the Union Simple Type
14594
 *
14595
 * Returns a list of member types of @type if existing,
14596
 * returns NULL otherwise.
14597
 */
14598
static xmlSchemaTypeLinkPtr
14599
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14600
0
{
14601
0
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14602
0
  if (type->memberTypes != NULL)
14603
0
      return (type->memberTypes);
14604
0
  else
14605
0
      type = type->baseType;
14606
0
    }
14607
0
    return (NULL);
14608
0
}
14609
14610
#if 0
14611
/**
14612
 * xmlSchemaGetParticleTotalRangeMin:
14613
 * @particle: the particle
14614
 *
14615
 * Schema Component Constraint: Effective Total Range
14616
 * (all and sequence) + (choice)
14617
 *
14618
 * Returns the minimum Effective Total Range.
14619
 */
14620
static int
14621
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14622
{
14623
    if ((particle->children == NULL) ||
14624
  (particle->minOccurs == 0))
14625
  return (0);
14626
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14627
  int min = -1, cur;
14628
  xmlSchemaParticlePtr part =
14629
      (xmlSchemaParticlePtr) particle->children->children;
14630
14631
  if (part == NULL)
14632
      return (0);
14633
  while (part != NULL) {
14634
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14635
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14636
    cur = part->minOccurs;
14637
      else
14638
    cur = xmlSchemaGetParticleTotalRangeMin(part);
14639
      if (cur == 0)
14640
    return (0);
14641
      if ((min > cur) || (min == -1))
14642
    min = cur;
14643
      part = (xmlSchemaParticlePtr) part->next;
14644
  }
14645
  return (particle->minOccurs * min);
14646
    } else {
14647
  /* <all> and <sequence> */
14648
  int sum = 0;
14649
  xmlSchemaParticlePtr part =
14650
      (xmlSchemaParticlePtr) particle->children->children;
14651
14652
  if (part == NULL)
14653
      return (0);
14654
  do {
14655
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14656
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14657
    sum += part->minOccurs;
14658
      else
14659
    sum += xmlSchemaGetParticleTotalRangeMin(part);
14660
      part = (xmlSchemaParticlePtr) part->next;
14661
  } while (part != NULL);
14662
  return (particle->minOccurs * sum);
14663
    }
14664
}
14665
14666
/**
14667
 * xmlSchemaGetParticleTotalRangeMax:
14668
 * @particle: the particle
14669
 *
14670
 * Schema Component Constraint: Effective Total Range
14671
 * (all and sequence) + (choice)
14672
 *
14673
 * Returns the maximum Effective Total Range.
14674
 */
14675
static int
14676
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14677
{
14678
    if ((particle->children == NULL) ||
14679
  (particle->children->children == NULL))
14680
  return (0);
14681
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14682
  int max = -1, cur;
14683
  xmlSchemaParticlePtr part =
14684
      (xmlSchemaParticlePtr) particle->children->children;
14685
14686
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14687
      if (part->children == NULL)
14688
    continue;
14689
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14690
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14691
    cur = part->maxOccurs;
14692
      else
14693
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14694
      if (cur == UNBOUNDED)
14695
    return (UNBOUNDED);
14696
      if ((max < cur) || (max == -1))
14697
    max = cur;
14698
  }
14699
  /* TODO: Handle overflows? */
14700
  return (particle->maxOccurs * max);
14701
    } else {
14702
  /* <all> and <sequence> */
14703
  int sum = 0, cur;
14704
  xmlSchemaParticlePtr part =
14705
      (xmlSchemaParticlePtr) particle->children->children;
14706
14707
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14708
      if (part->children == NULL)
14709
    continue;
14710
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14711
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14712
    cur = part->maxOccurs;
14713
      else
14714
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14715
      if (cur == UNBOUNDED)
14716
    return (UNBOUNDED);
14717
      if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14718
    return (UNBOUNDED);
14719
      sum += cur;
14720
  }
14721
  /* TODO: Handle overflows? */
14722
  return (particle->maxOccurs * sum);
14723
    }
14724
}
14725
#endif
14726
14727
/**
14728
 * xmlSchemaGetParticleEmptiable:
14729
 * @particle: the particle
14730
 *
14731
 * Returns 1 if emptiable, 0 otherwise.
14732
 */
14733
static int
14734
xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14735
0
{
14736
0
    xmlSchemaParticlePtr part;
14737
0
    int emptiable;
14738
14739
0
    if ((particle->children == NULL) || (particle->minOccurs == 0))
14740
0
  return (1);
14741
14742
0
    part = (xmlSchemaParticlePtr) particle->children->children;
14743
0
    if (part == NULL)
14744
0
        return (1);
14745
14746
0
    while (part != NULL) {
14747
0
        if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14748
0
            (part->children->type == XML_SCHEMA_TYPE_ANY))
14749
0
            emptiable = (part->minOccurs == 0);
14750
0
        else
14751
0
            emptiable = xmlSchemaGetParticleEmptiable(part);
14752
0
        if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14753
0
            if (emptiable)
14754
0
                return (1);
14755
0
        } else {
14756
      /* <all> and <sequence> */
14757
0
            if (!emptiable)
14758
0
                return (0);
14759
0
        }
14760
0
        part = (xmlSchemaParticlePtr) part->next;
14761
0
    }
14762
14763
0
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14764
0
        return (0);
14765
0
    else
14766
0
        return (1);
14767
0
}
14768
14769
/**
14770
 * xmlSchemaIsParticleEmptiable:
14771
 * @particle: the particle
14772
 *
14773
 * Schema Component Constraint: Particle Emptiable
14774
 * Checks whether the given particle is emptiable.
14775
 *
14776
 * Returns 1 if emptiable, 0 otherwise.
14777
 */
14778
static int
14779
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14780
0
{
14781
    /*
14782
    * SPEC (1) "Its {min occurs} is 0."
14783
    */
14784
0
    if ((particle == NULL) || (particle->minOccurs == 0) ||
14785
0
  (particle->children == NULL))
14786
0
  return (1);
14787
    /*
14788
    * SPEC (2) "Its {term} is a group and the minimum part of the
14789
    * effective total range of that group, [...] is 0."
14790
    */
14791
0
    if (WXS_IS_MODEL_GROUP(particle->children))
14792
0
  return (xmlSchemaGetParticleEmptiable(particle));
14793
0
    return (0);
14794
0
}
14795
14796
/**
14797
 * xmlSchemaCheckCOSSTDerivedOK:
14798
 * @actxt: a context
14799
 * @type:  the derived simple type definition
14800
 * @baseType:  the base type definition
14801
 * @subset: the subset of ('restriction', etc.)
14802
 *
14803
 * Schema Component Constraint:
14804
 * Type Derivation OK (Simple) (cos-st-derived-OK)
14805
 *
14806
 * Checks whether @type can be validly
14807
 * derived from @baseType.
14808
 *
14809
 * Returns 0 on success, an positive error code otherwise.
14810
 */
14811
static int
14812
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14813
           xmlSchemaTypePtr type,
14814
           xmlSchemaTypePtr baseType,
14815
           int subset)
14816
0
{
14817
    /*
14818
    * 1 They are the same type definition.
14819
    * TODO: The identity check might have to be more complex than this.
14820
    */
14821
0
    if (type == baseType)
14822
0
  return (0);
14823
    /*
14824
    * 2.1 restriction is not in the subset, or in the {final}
14825
    * of its own {base type definition};
14826
    *
14827
    * NOTE that this will be used also via "xsi:type".
14828
    *
14829
    * TODO: Revise this, it looks strange. How can the "type"
14830
    * not be fixed or *in* fixing?
14831
    */
14832
0
    if (WXS_IS_TYPE_NOT_FIXED(type))
14833
0
  if (xmlSchemaTypeFixup(type, actxt) == -1)
14834
0
      return(-1);
14835
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14836
0
  if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14837
0
      return(-1);
14838
0
    if ((subset & SUBSET_RESTRICTION) ||
14839
0
  (xmlSchemaTypeFinalContains(type->baseType,
14840
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14841
0
  return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14842
0
    }
14843
    /* 2.2 */
14844
0
    if (type->baseType == baseType) {
14845
  /*
14846
  * 2.2.1 D's `base type definition` is B.
14847
  */
14848
0
  return (0);
14849
0
    }
14850
    /*
14851
    * 2.2.2 D's `base type definition` is not the `ur-type definition`
14852
    * and is validly derived from B given the subset, as defined by this
14853
    * constraint.
14854
    */
14855
0
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14856
0
  (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14857
0
      baseType, subset) == 0)) {
14858
0
  return (0);
14859
0
    }
14860
    /*
14861
    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14862
    * definition`.
14863
    */
14864
0
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14865
0
  (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14866
0
  return (0);
14867
0
    }
14868
    /*
14869
    * 2.2.4 B's {variety} is union and D is validly derived from a type
14870
    * definition in B's {member type definitions} given the subset, as
14871
    * defined by this constraint.
14872
    *
14873
    * NOTE: This seems not to involve built-in types, since there is no
14874
    * built-in Union Simple Type.
14875
    */
14876
0
    if (WXS_IS_UNION(baseType)) {
14877
0
  xmlSchemaTypeLinkPtr cur;
14878
14879
0
  cur = baseType->memberTypes;
14880
0
  while (cur != NULL) {
14881
0
      if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14882
0
    if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14883
0
        return(-1);
14884
0
      if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14885
0
        type, cur->type, subset) == 0)
14886
0
      {
14887
    /*
14888
    * It just has to be validly derived from at least one
14889
    * member-type.
14890
    */
14891
0
    return (0);
14892
0
      }
14893
0
      cur = cur->next;
14894
0
  }
14895
0
    }
14896
0
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14897
0
}
14898
14899
/**
14900
 * xmlSchemaCheckTypeDefCircularInternal:
14901
 * @pctxt:  the schema parser context
14902
 * @ctxtType:  the type definition
14903
 * @ancestor: an ancestor of @ctxtType
14904
 *
14905
 * Checks st-props-correct (2) + ct-props-correct (3).
14906
 * Circular type definitions are not allowed.
14907
 *
14908
 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14909
 * circular, 0 otherwise.
14910
 */
14911
static int
14912
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14913
         xmlSchemaTypePtr ctxtType,
14914
         xmlSchemaTypePtr ancestor)
14915
0
{
14916
0
    int ret;
14917
14918
0
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14919
0
  return (0);
14920
14921
0
    if (ctxtType == ancestor) {
14922
0
  xmlSchemaPCustomErr(pctxt,
14923
0
      XML_SCHEMAP_ST_PROPS_CORRECT_2,
14924
0
      WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14925
0
      "The definition is circular", NULL);
14926
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14927
0
    }
14928
0
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14929
  /*
14930
  * Avoid infinite recursion on circular types not yet checked.
14931
  */
14932
0
  return (0);
14933
0
    }
14934
0
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14935
0
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14936
0
  ancestor->baseType);
14937
0
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14938
0
    return (ret);
14939
0
}
14940
14941
/**
14942
 * xmlSchemaCheckTypeDefCircular:
14943
 * @item:  the complex/simple type definition
14944
 * @ctxt:  the parser context
14945
 * @name:  the name
14946
 *
14947
 * Checks for circular type definitions.
14948
 */
14949
static void
14950
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14951
            xmlSchemaParserCtxtPtr ctxt)
14952
0
{
14953
0
    if ((item == NULL) ||
14954
0
  (item->type == XML_SCHEMA_TYPE_BASIC) ||
14955
0
  (item->baseType == NULL))
14956
0
  return;
14957
0
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14958
0
  item->baseType);
14959
0
}
14960
14961
/*
14962
* Simple Type Definition Representation OK (src-simple-type) 4
14963
*
14964
* "4 Circular union type definition is disallowed. That is, if the
14965
* <union> alternative is chosen, there must not be any entries in the
14966
* memberTypes [attribute] at any depth which resolve to the component
14967
* corresponding to the <simpleType>."
14968
*
14969
* Note that this should work on the *representation* of a component,
14970
* thus assumes any union types in the member types not being yet
14971
* substituted. At this stage we need the variety of the types
14972
* to be already computed.
14973
*/
14974
static int
14975
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14976
          xmlSchemaTypePtr ctxType,
14977
          xmlSchemaTypeLinkPtr members)
14978
0
{
14979
0
    xmlSchemaTypeLinkPtr member;
14980
0
    xmlSchemaTypePtr memberType;
14981
14982
0
    member = members;
14983
0
    while (member != NULL) {
14984
0
  memberType = member->type;
14985
0
  while ((memberType != NULL) &&
14986
0
      (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14987
0
      if (memberType == ctxType) {
14988
0
    xmlSchemaPCustomErr(pctxt,
14989
0
        XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14990
0
        WXS_BASIC_CAST ctxType, NULL,
14991
0
        "The union type definition is circular", NULL);
14992
0
    return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14993
0
      }
14994
0
      if ((WXS_IS_UNION(memberType)) &&
14995
0
    ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14996
0
      {
14997
0
    int res;
14998
0
    memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14999
0
    res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
15000
0
        ctxType,
15001
0
        xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
15002
0
    memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
15003
0
    if (res != 0)
15004
0
        return(res);
15005
0
      }
15006
0
      memberType = memberType->baseType;
15007
0
  }
15008
0
  member = member->next;
15009
0
    }
15010
0
    return(0);
15011
0
}
15012
15013
static int
15014
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15015
           xmlSchemaTypePtr type)
15016
0
{
15017
0
    if (! WXS_IS_UNION(type))
15018
0
  return(0);
15019
0
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15020
0
  type->memberTypes));
15021
0
}
15022
15023
/**
15024
 * xmlSchemaResolveTypeReferences:
15025
 * @item:  the complex/simple type definition
15026
 * @ctxt:  the parser context
15027
 * @name:  the name
15028
 *
15029
 * Resolves type definition references
15030
 */
15031
static void
15032
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15033
       xmlSchemaParserCtxtPtr ctxt)
15034
0
{
15035
0
    if (typeDef == NULL)
15036
0
  return;
15037
15038
    /*
15039
    * Resolve the base type.
15040
    */
15041
0
    if (typeDef->baseType == NULL) {
15042
0
  typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15043
0
      typeDef->base, typeDef->baseNs);
15044
0
  if (typeDef->baseType == NULL) {
15045
0
      xmlSchemaPResCompAttrErr(ctxt,
15046
0
    XML_SCHEMAP_SRC_RESOLVE,
15047
0
    WXS_BASIC_CAST typeDef, typeDef->node,
15048
0
    "base", typeDef->base, typeDef->baseNs,
15049
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
15050
0
      return;
15051
0
  }
15052
0
    }
15053
0
    if (WXS_IS_SIMPLE(typeDef)) {
15054
0
  if (WXS_IS_UNION(typeDef)) {
15055
      /*
15056
      * Resolve the memberTypes.
15057
      */
15058
0
      xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15059
0
      return;
15060
0
  } else if (WXS_IS_LIST(typeDef)) {
15061
      /*
15062
      * Resolve the itemType.
15063
      */
15064
0
      if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15065
15066
0
    typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15067
0
        typeDef->base, typeDef->baseNs);
15068
15069
0
    if ((typeDef->subtypes == NULL) ||
15070
0
        (! WXS_IS_SIMPLE(typeDef->subtypes)))
15071
0
    {
15072
0
        typeDef->subtypes = NULL;
15073
0
        xmlSchemaPResCompAttrErr(ctxt,
15074
0
      XML_SCHEMAP_SRC_RESOLVE,
15075
0
      WXS_BASIC_CAST typeDef, typeDef->node,
15076
0
      "itemType", typeDef->base, typeDef->baseNs,
15077
0
      XML_SCHEMA_TYPE_SIMPLE, NULL);
15078
0
    }
15079
0
      }
15080
0
      return;
15081
0
  }
15082
0
    }
15083
    /*
15084
    * The ball of letters below means, that if we have a particle
15085
    * which has a QName-helper component as its {term}, we want
15086
    * to resolve it...
15087
    */
15088
0
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15089
0
  ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15090
0
      XML_SCHEMA_TYPE_PARTICLE) &&
15091
0
  (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15092
0
  ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15093
0
      XML_SCHEMA_EXTRA_QNAMEREF))
15094
0
    {
15095
0
  xmlSchemaQNameRefPtr ref =
15096
0
      WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15097
0
  xmlSchemaModelGroupDefPtr groupDef;
15098
15099
  /*
15100
  * URGENT TODO: Test this.
15101
  */
15102
0
  WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15103
  /*
15104
  * Resolve the MG definition reference.
15105
  */
15106
0
  groupDef =
15107
0
      WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15108
0
    ref->itemType, ref->name, ref->targetNamespace);
15109
0
  if (groupDef == NULL) {
15110
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15111
0
    NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15112
0
    "ref", ref->name, ref->targetNamespace, ref->itemType,
15113
0
    NULL);
15114
      /* Remove the particle. */
15115
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15116
0
  } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15117
      /* Remove the particle. */
15118
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15119
0
  else {
15120
      /*
15121
      * Assign the MG definition's {model group} to the
15122
      * particle's {term}.
15123
      */
15124
0
      WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15125
15126
0
      if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15127
    /*
15128
    * SPEC cos-all-limited (1.2)
15129
    * "1.2 the {term} property of a particle with
15130
    * {max occurs}=1 which is part of a pair which constitutes
15131
    * the {content type} of a complex type definition."
15132
    */
15133
0
    if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15134
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
15135
      /* TODO: error code */
15136
0
      XML_SCHEMAP_COS_ALL_LIMITED,
15137
0
      WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15138
0
      "The particle's {max occurs} must be 1, since the "
15139
0
      "reference resolves to an 'all' model group",
15140
0
      NULL, NULL);
15141
0
    }
15142
0
      }
15143
0
  }
15144
0
    }
15145
0
}
15146
15147
15148
15149
/**
15150
 * xmlSchemaCheckSTPropsCorrect:
15151
 * @ctxt:  the schema parser context
15152
 * @type:  the simple type definition
15153
 *
15154
 * Checks st-props-correct.
15155
 *
15156
 * Returns 0 if the properties are correct,
15157
 * if not, a positive error code and -1 on internal
15158
 * errors.
15159
 */
15160
static int
15161
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15162
           xmlSchemaTypePtr type)
15163
0
{
15164
0
    xmlSchemaTypePtr baseType = type->baseType;
15165
0
    xmlChar *str = NULL;
15166
15167
    /* STATE: error funcs converted. */
15168
    /*
15169
    * Schema Component Constraint: Simple Type Definition Properties Correct
15170
    *
15171
    * NOTE: This is somehow redundant, since we actually built a simple type
15172
    * to have all the needed information; this acts as an self test.
15173
    */
15174
    /* Base type: If the datatype has been `derived` by `restriction`
15175
    * then the Simple Type Definition component from which it is `derived`,
15176
    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15177
    */
15178
0
    if (baseType == NULL) {
15179
  /*
15180
  * TODO: Think about: "modulo the impact of Missing
15181
  * Sub-components ($5.3)."
15182
  */
15183
0
  xmlSchemaPCustomErr(ctxt,
15184
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15185
0
      WXS_BASIC_CAST type, NULL,
15186
0
      "No base type existent", NULL);
15187
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15188
15189
0
    }
15190
0
    if (! WXS_IS_SIMPLE(baseType)) {
15191
0
  xmlSchemaPCustomErr(ctxt,
15192
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15193
0
      WXS_BASIC_CAST type, NULL,
15194
0
      "The base type '%s' is not a simple type",
15195
0
      xmlSchemaGetComponentQName(&str, baseType));
15196
0
  FREE_AND_NULL(str)
15197
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15198
0
    }
15199
0
    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15200
0
  (WXS_IS_RESTRICTION(type) == 0) &&
15201
0
  ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15202
0
         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15203
0
  xmlSchemaPCustomErr(ctxt,
15204
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15205
0
      WXS_BASIC_CAST type, NULL,
15206
0
      "A type, derived by list or union, must have "
15207
0
      "the simple ur-type definition as base type, not '%s'",
15208
0
      xmlSchemaGetComponentQName(&str, baseType));
15209
0
  FREE_AND_NULL(str)
15210
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15211
0
    }
15212
    /*
15213
    * Variety: One of {atomic, list, union}.
15214
    */
15215
0
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15216
0
  (! WXS_IS_LIST(type))) {
15217
0
  xmlSchemaPCustomErr(ctxt,
15218
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15219
0
      WXS_BASIC_CAST type, NULL,
15220
0
      "The variety is absent", NULL);
15221
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15222
0
    }
15223
    /* TODO: Finish this. Hmm, is this finished? */
15224
15225
    /*
15226
    * 3 The {final} of the {base type definition} must not contain restriction.
15227
    */
15228
0
    if (xmlSchemaTypeFinalContains(baseType,
15229
0
  XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15230
0
  xmlSchemaPCustomErr(ctxt,
15231
0
      XML_SCHEMAP_ST_PROPS_CORRECT_3,
15232
0
      WXS_BASIC_CAST type, NULL,
15233
0
      "The 'final' of its base type '%s' must not contain "
15234
0
      "'restriction'",
15235
0
      xmlSchemaGetComponentQName(&str, baseType));
15236
0
  FREE_AND_NULL(str)
15237
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15238
0
    }
15239
15240
    /*
15241
    * 2 All simple type definitions must be derived ultimately from the `simple
15242
    * ur-type definition` (so circular definitions are disallowed). That is, it
15243
    * must be possible to reach a built-in primitive datatype or the `simple
15244
    * ur-type definition` by repeatedly following the {base type definition}.
15245
    *
15246
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15247
    */
15248
0
    return (0);
15249
0
}
15250
15251
/**
15252
 * xmlSchemaCheckCOSSTRestricts:
15253
 * @ctxt:  the schema parser context
15254
 * @type:  the simple type definition
15255
 *
15256
 * Schema Component Constraint:
15257
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15258
15259
 * Checks if the given @type (simpleType) is derived validly by restriction.
15260
 * STATUS:
15261
 *
15262
 * Returns -1 on internal errors, 0 if the type is validly derived,
15263
 * a positive error code otherwise.
15264
 */
15265
static int
15266
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15267
           xmlSchemaTypePtr type)
15268
0
{
15269
0
    xmlChar *str = NULL;
15270
15271
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15272
0
  PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15273
0
      "given type is not a user-derived simpleType");
15274
0
  return (-1);
15275
0
    }
15276
15277
0
    if (WXS_IS_ATOMIC(type)) {
15278
0
  xmlSchemaTypePtr primitive;
15279
  /*
15280
  * 1.1 The {base type definition} must be an atomic simple
15281
  * type definition or a built-in primitive datatype.
15282
  */
15283
0
  if (! WXS_IS_ATOMIC(type->baseType)) {
15284
0
      xmlSchemaPCustomErr(pctxt,
15285
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15286
0
    WXS_BASIC_CAST type, NULL,
15287
0
    "The base type '%s' is not an atomic simple type",
15288
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15289
0
      FREE_AND_NULL(str)
15290
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15291
0
  }
15292
  /* 1.2 The {final} of the {base type definition} must not contain
15293
  * restriction.
15294
  */
15295
  /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15296
0
  if (xmlSchemaTypeFinalContains(type->baseType,
15297
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15298
0
      xmlSchemaPCustomErr(pctxt,
15299
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15300
0
    WXS_BASIC_CAST type, NULL,
15301
0
    "The final of its base type '%s' must not contain 'restriction'",
15302
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15303
0
      FREE_AND_NULL(str)
15304
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15305
0
  }
15306
15307
  /*
15308
  * 1.3.1 DF must be an allowed constraining facet for the {primitive
15309
  * type definition}, as specified in the appropriate subsection of 3.2
15310
  * Primitive datatypes.
15311
  */
15312
0
  if (type->facets != NULL) {
15313
0
      xmlSchemaFacetPtr facet;
15314
0
      int ok = 1;
15315
15316
0
      primitive = xmlSchemaGetPrimitiveType(type);
15317
0
      if (primitive == NULL) {
15318
0
    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15319
0
        "failed to get primitive type");
15320
0
    return (-1);
15321
0
      }
15322
0
      facet = type->facets;
15323
0
      do {
15324
0
    if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15325
0
        ok = 0;
15326
0
        xmlSchemaPIllegalFacetAtomicErr(pctxt,
15327
0
      XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15328
0
      type, primitive, facet);
15329
0
    }
15330
0
    facet = facet->next;
15331
0
      } while (facet != NULL);
15332
0
      if (ok == 0)
15333
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15334
0
  }
15335
  /*
15336
  * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15337
  * of the {base type definition} (call this BF),then the DF's {value}
15338
  * must be a valid restriction of BF's {value} as defined in
15339
  * [XML Schemas: Datatypes]."
15340
  *
15341
  * NOTE (1.3.2) Facet derivation constraints are currently handled in
15342
  * xmlSchemaDeriveAndValidateFacets()
15343
  */
15344
0
    } else if (WXS_IS_LIST(type)) {
15345
0
  xmlSchemaTypePtr itemType = NULL;
15346
15347
0
  itemType = type->subtypes;
15348
0
  if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15349
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15350
0
    "failed to evaluate the item type");
15351
0
      return (-1);
15352
0
  }
15353
0
  if (WXS_IS_TYPE_NOT_FIXED(itemType))
15354
0
      xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15355
  /*
15356
  * 2.1 The {item type definition} must have a {variety} of atomic or
15357
  * union (in which case all the {member type definitions}
15358
  * must be atomic).
15359
  */
15360
0
  if ((! WXS_IS_ATOMIC(itemType)) &&
15361
0
      (! WXS_IS_UNION(itemType))) {
15362
0
      xmlSchemaPCustomErr(pctxt,
15363
0
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15364
0
    WXS_BASIC_CAST type, NULL,
15365
0
    "The item type '%s' does not have a variety of atomic or union",
15366
0
    xmlSchemaGetComponentQName(&str, itemType));
15367
0
      FREE_AND_NULL(str)
15368
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15369
0
  } else if (WXS_IS_UNION(itemType)) {
15370
0
      xmlSchemaTypeLinkPtr member;
15371
15372
0
      member = itemType->memberTypes;
15373
0
      while (member != NULL) {
15374
0
    if (! WXS_IS_ATOMIC(member->type)) {
15375
0
        xmlSchemaPCustomErr(pctxt,
15376
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15377
0
      WXS_BASIC_CAST type, NULL,
15378
0
      "The item type is a union type, but the "
15379
0
      "member type '%s' of this item type is not atomic",
15380
0
      xmlSchemaGetComponentQName(&str, member->type));
15381
0
        FREE_AND_NULL(str)
15382
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15383
0
    }
15384
0
    member = member->next;
15385
0
      }
15386
0
  }
15387
15388
0
  if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15389
0
      xmlSchemaFacetPtr facet;
15390
      /*
15391
      * This is the case if we have: <simpleType><list ..
15392
      */
15393
      /*
15394
      * 2.3.1
15395
      * 2.3.1.1 The {final} of the {item type definition} must not
15396
      * contain list.
15397
      */
15398
0
      if (xmlSchemaTypeFinalContains(itemType,
15399
0
    XML_SCHEMAS_TYPE_FINAL_LIST)) {
15400
0
    xmlSchemaPCustomErr(pctxt,
15401
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15402
0
        WXS_BASIC_CAST type, NULL,
15403
0
        "The final of its item type '%s' must not contain 'list'",
15404
0
        xmlSchemaGetComponentQName(&str, itemType));
15405
0
    FREE_AND_NULL(str)
15406
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15407
0
      }
15408
      /*
15409
      * 2.3.1.2 The {facets} must only contain the whiteSpace
15410
      * facet component.
15411
      * OPTIMIZE TODO: the S4S already disallows any facet
15412
      * to be specified.
15413
      */
15414
0
      if (type->facets != NULL) {
15415
0
    facet = type->facets;
15416
0
    do {
15417
0
        if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15418
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15419
0
          XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15420
0
          type, facet);
15421
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15422
0
        }
15423
0
        facet = facet->next;
15424
0
    } while (facet != NULL);
15425
0
      }
15426
      /*
15427
      * MAYBE TODO: (Hmm, not really) Datatypes states:
15428
      * A `list` datatype can be `derived` from an `atomic` datatype
15429
      * whose `lexical space` allows space (such as string or anyURI)or
15430
      * a `union` datatype any of whose {member type definitions}'s
15431
      * `lexical space` allows space.
15432
      */
15433
0
  } else {
15434
      /*
15435
      * This is the case if we have: <simpleType><restriction ...
15436
      * I.e. the variety of "list" is inherited.
15437
      */
15438
      /*
15439
      * 2.3.2
15440
      * 2.3.2.1 The {base type definition} must have a {variety} of list.
15441
      */
15442
0
      if (! WXS_IS_LIST(type->baseType)) {
15443
0
    xmlSchemaPCustomErr(pctxt,
15444
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15445
0
        WXS_BASIC_CAST type, NULL,
15446
0
        "The base type '%s' must be a list type",
15447
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15448
0
    FREE_AND_NULL(str)
15449
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15450
0
      }
15451
      /*
15452
      * 2.3.2.2 The {final} of the {base type definition} must not
15453
      * contain restriction.
15454
      */
15455
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15456
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15457
0
    xmlSchemaPCustomErr(pctxt,
15458
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15459
0
        WXS_BASIC_CAST type, NULL,
15460
0
        "The 'final' of the base type '%s' must not contain 'restriction'",
15461
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15462
0
    FREE_AND_NULL(str)
15463
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15464
0
      }
15465
      /*
15466
      * 2.3.2.3 The {item type definition} must be validly derived
15467
      * from the {base type definition}'s {item type definition} given
15468
      * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15469
      */
15470
0
      {
15471
0
    xmlSchemaTypePtr baseItemType;
15472
15473
0
    baseItemType = type->baseType->subtypes;
15474
0
    if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15475
0
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15476
0
      "failed to eval the item type of a base type");
15477
0
        return (-1);
15478
0
    }
15479
0
    if ((itemType != baseItemType) &&
15480
0
        (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15481
0
      baseItemType, 0) != 0)) {
15482
0
        xmlChar *strBIT = NULL, *strBT = NULL;
15483
0
        xmlSchemaPCustomErrExt(pctxt,
15484
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15485
0
      WXS_BASIC_CAST type, NULL,
15486
0
      "The item type '%s' is not validly derived from "
15487
0
      "the item type '%s' of the base type '%s'",
15488
0
      xmlSchemaGetComponentQName(&str, itemType),
15489
0
      xmlSchemaGetComponentQName(&strBIT, baseItemType),
15490
0
      xmlSchemaGetComponentQName(&strBT, type->baseType));
15491
15492
0
        FREE_AND_NULL(str)
15493
0
        FREE_AND_NULL(strBIT)
15494
0
        FREE_AND_NULL(strBT)
15495
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15496
0
    }
15497
0
      }
15498
15499
0
      if (type->facets != NULL) {
15500
0
    xmlSchemaFacetPtr facet;
15501
0
    int ok = 1;
15502
    /*
15503
    * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15504
    * and enumeration facet components are allowed among the {facets}.
15505
    */
15506
0
    facet = type->facets;
15507
0
    do {
15508
0
        switch (facet->type) {
15509
0
      case XML_SCHEMA_FACET_LENGTH:
15510
0
      case XML_SCHEMA_FACET_MINLENGTH:
15511
0
      case XML_SCHEMA_FACET_MAXLENGTH:
15512
0
      case XML_SCHEMA_FACET_WHITESPACE:
15513
          /*
15514
          * TODO: 2.5.1.2 List datatypes
15515
          * The value of `whiteSpace` is fixed to the value collapse.
15516
          */
15517
0
      case XML_SCHEMA_FACET_PATTERN:
15518
0
      case XML_SCHEMA_FACET_ENUMERATION:
15519
0
          break;
15520
0
      default: {
15521
0
          xmlSchemaPIllegalFacetListUnionErr(pctxt,
15522
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15523
0
        type, facet);
15524
          /*
15525
          * We could return, but it's nicer to report all
15526
          * invalid facets.
15527
          */
15528
0
          ok = 0;
15529
0
      }
15530
0
        }
15531
0
        facet = facet->next;
15532
0
    } while (facet != NULL);
15533
0
    if (ok == 0)
15534
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15535
    /*
15536
    * SPEC (2.3.2.5) (same as 1.3.2)
15537
    *
15538
    * NOTE (2.3.2.5) This is currently done in
15539
    * xmlSchemaDeriveAndValidateFacets()
15540
    */
15541
0
      }
15542
0
  }
15543
0
    } else if (WXS_IS_UNION(type)) {
15544
  /*
15545
  * 3.1 The {member type definitions} must all have {variety} of
15546
  * atomic or list.
15547
  */
15548
0
  xmlSchemaTypeLinkPtr member;
15549
15550
0
  member = type->memberTypes;
15551
0
  while (member != NULL) {
15552
0
      if (WXS_IS_TYPE_NOT_FIXED(member->type))
15553
0
    xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15554
15555
0
      if ((! WXS_IS_ATOMIC(member->type)) &&
15556
0
    (! WXS_IS_LIST(member->type))) {
15557
0
    xmlSchemaPCustomErr(pctxt,
15558
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15559
0
        WXS_BASIC_CAST type, NULL,
15560
0
        "The member type '%s' is neither an atomic, nor a list type",
15561
0
        xmlSchemaGetComponentQName(&str, member->type));
15562
0
    FREE_AND_NULL(str)
15563
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15564
0
      }
15565
0
      member = member->next;
15566
0
  }
15567
  /*
15568
  * 3.3.1 If the {base type definition} is the `simple ur-type
15569
  * definition`
15570
  */
15571
0
  if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15572
      /*
15573
      * 3.3.1.1 All of the {member type definitions} must have a
15574
      * {final} which does not contain union.
15575
      */
15576
0
      member = type->memberTypes;
15577
0
      while (member != NULL) {
15578
0
    if (xmlSchemaTypeFinalContains(member->type,
15579
0
        XML_SCHEMAS_TYPE_FINAL_UNION)) {
15580
0
        xmlSchemaPCustomErr(pctxt,
15581
0
      XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15582
0
      WXS_BASIC_CAST type, NULL,
15583
0
      "The 'final' of member type '%s' contains 'union'",
15584
0
      xmlSchemaGetComponentQName(&str, member->type));
15585
0
        FREE_AND_NULL(str)
15586
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15587
0
    }
15588
0
    member = member->next;
15589
0
      }
15590
      /*
15591
      * 3.3.1.2 The {facets} must be empty.
15592
      */
15593
0
      if (type->facetSet != NULL) {
15594
0
    xmlSchemaPCustomErr(pctxt,
15595
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15596
0
        WXS_BASIC_CAST type, NULL,
15597
0
        "No facets allowed", NULL);
15598
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15599
0
      }
15600
0
  } else {
15601
      /*
15602
      * 3.3.2.1 The {base type definition} must have a {variety} of union.
15603
      * I.e. the variety of "list" is inherited.
15604
      */
15605
0
      if (! WXS_IS_UNION(type->baseType)) {
15606
0
    xmlSchemaPCustomErr(pctxt,
15607
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15608
0
        WXS_BASIC_CAST type, NULL,
15609
0
        "The base type '%s' is not a union type",
15610
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15611
0
    FREE_AND_NULL(str)
15612
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15613
0
      }
15614
      /*
15615
      * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15616
      */
15617
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15618
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15619
0
    xmlSchemaPCustomErr(pctxt,
15620
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15621
0
        WXS_BASIC_CAST type, NULL,
15622
0
        "The 'final' of its base type '%s' must not contain 'restriction'",
15623
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15624
0
    FREE_AND_NULL(str)
15625
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15626
0
      }
15627
      /*
15628
      * 3.3.2.3 The {member type definitions}, in order, must be validly
15629
      * derived from the corresponding type definitions in the {base
15630
      * type definition}'s {member type definitions} given the empty set,
15631
      * as defined in Type Derivation OK (Simple) ($3.14.6).
15632
      */
15633
0
      {
15634
0
    xmlSchemaTypeLinkPtr baseMember;
15635
15636
    /*
15637
    * OPTIMIZE: if the type is restricting, it has no local defined
15638
    * member types and inherits the member types of the base type;
15639
    * thus a check for equality can be skipped.
15640
    */
15641
    /*
15642
    * Even worse: I cannot see a scenario where a restricting
15643
    * union simple type can have other member types as the member
15644
    * types of it's base type. This check seems not necessary with
15645
    * respect to the derivation process in libxml2.
15646
    * But necessary if constructing types with an API.
15647
    */
15648
0
    if (type->memberTypes != NULL) {
15649
0
        member = type->memberTypes;
15650
0
        baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15651
0
        if ((member == NULL) && (baseMember != NULL)) {
15652
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15653
0
          "different number of member types in base");
15654
0
        }
15655
0
        while (member != NULL) {
15656
0
      if (baseMember == NULL) {
15657
0
          PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15658
0
          "different number of member types in base");
15659
0
      } else if ((member->type != baseMember->type) &&
15660
0
          (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15661
0
        member->type, baseMember->type, 0) != 0)) {
15662
0
          xmlChar *strBMT = NULL, *strBT = NULL;
15663
15664
0
          xmlSchemaPCustomErrExt(pctxt,
15665
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15666
0
        WXS_BASIC_CAST type, NULL,
15667
0
        "The member type %s is not validly "
15668
0
        "derived from its corresponding member "
15669
0
        "type %s of the base type %s",
15670
0
        xmlSchemaGetComponentQName(&str, member->type),
15671
0
        xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15672
0
        xmlSchemaGetComponentQName(&strBT, type->baseType));
15673
0
          FREE_AND_NULL(str)
15674
0
          FREE_AND_NULL(strBMT)
15675
0
          FREE_AND_NULL(strBT)
15676
0
          return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15677
0
      }
15678
0
      member = member->next;
15679
0
                        if (baseMember != NULL)
15680
0
                            baseMember = baseMember->next;
15681
0
        }
15682
0
    }
15683
0
      }
15684
      /*
15685
      * 3.3.2.4 Only pattern and enumeration facet components are
15686
      * allowed among the {facets}.
15687
      */
15688
0
      if (type->facets != NULL) {
15689
0
    xmlSchemaFacetPtr facet;
15690
0
    int ok = 1;
15691
15692
0
    facet = type->facets;
15693
0
    do {
15694
0
        if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15695
0
      (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15696
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15697
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15698
0
        type, facet);
15699
0
      ok = 0;
15700
0
        }
15701
0
        facet = facet->next;
15702
0
    } while (facet != NULL);
15703
0
    if (ok == 0)
15704
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15705
15706
0
      }
15707
      /*
15708
      * SPEC (3.3.2.5) (same as 1.3.2)
15709
      *
15710
      * NOTE (3.3.2.5) This is currently done in
15711
      * xmlSchemaDeriveAndValidateFacets()
15712
      */
15713
0
  }
15714
0
    }
15715
15716
0
    return (0);
15717
0
}
15718
15719
/**
15720
 * xmlSchemaCheckSRCSimpleType:
15721
 * @ctxt:  the schema parser context
15722
 * @type:  the simple type definition
15723
 *
15724
 * Checks crc-simple-type constraints.
15725
 *
15726
 * Returns 0 if the constraints are satisfied,
15727
 * if not a positive error code and -1 on internal
15728
 * errors.
15729
 */
15730
#if 0
15731
static int
15732
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15733
          xmlSchemaTypePtr type)
15734
{
15735
    /*
15736
    * src-simple-type.1 The corresponding simple type definition, if any,
15737
    * must satisfy the conditions set out in Constraints on Simple Type
15738
    * Definition Schema Components ($3.14.6).
15739
    */
15740
    if (WXS_IS_RESTRICTION(type)) {
15741
  /*
15742
  * src-simple-type.2 "If the <restriction> alternative is chosen,
15743
  * either it must have a base [attribute] or a <simpleType> among its
15744
  * [children], but not both."
15745
  * NOTE: This is checked in the parse function of <restriction>.
15746
  */
15747
  /*
15748
  *
15749
  */
15750
    } else if (WXS_IS_LIST(type)) {
15751
  /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15752
  * an itemType [attribute] or a <simpleType> among its [children],
15753
  * but not both."
15754
  *
15755
  * NOTE: This is checked in the parse function of <list>.
15756
  */
15757
    } else if (WXS_IS_UNION(type)) {
15758
  /*
15759
  * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15760
  */
15761
    }
15762
    return (0);
15763
}
15764
#endif
15765
15766
static int
15767
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15768
0
{
15769
0
   if (ctxt->vctxt == NULL) {
15770
0
  ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15771
0
  if (ctxt->vctxt == NULL) {
15772
0
      xmlSchemaPErr(ctxt, NULL,
15773
0
    XML_SCHEMAP_INTERNAL,
15774
0
    "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15775
0
    "failed to create a temp. validation context.\n",
15776
0
    NULL, NULL);
15777
0
      return (-1);
15778
0
  }
15779
  /* TODO: Pass user data. */
15780
0
  xmlSchemaSetValidErrors(ctxt->vctxt,
15781
0
      ctxt->error, ctxt->warning, ctxt->errCtxt);
15782
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15783
0
      ctxt->serror, ctxt->errCtxt);
15784
0
    }
15785
0
    return (0);
15786
0
}
15787
15788
static int
15789
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15790
           xmlNodePtr node,
15791
           xmlSchemaTypePtr type,
15792
           const xmlChar *value,
15793
           xmlSchemaValPtr *retVal,
15794
           int fireErrors,
15795
           int normalize,
15796
           int isNormalized);
15797
15798
/**
15799
 * xmlSchemaParseCheckCOSValidDefault:
15800
 * @pctxt:  the schema parser context
15801
 * @type:  the simple type definition
15802
 * @value: the default value
15803
 * @node: an optional node (the holder of the value)
15804
 *
15805
 * Schema Component Constraint: Element Default Valid (Immediate)
15806
 * (cos-valid-default)
15807
 * This will be used by the parser only. For the validator there's
15808
 * an other version.
15809
 *
15810
 * Returns 0 if the constraints are satisfied,
15811
 * if not, a positive error code and -1 on internal
15812
 * errors.
15813
 */
15814
static int
15815
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15816
           xmlNodePtr node,
15817
           xmlSchemaTypePtr type,
15818
           const xmlChar *value,
15819
           xmlSchemaValPtr *val)
15820
0
{
15821
0
    int ret = 0;
15822
15823
    /*
15824
    * cos-valid-default:
15825
    * Schema Component Constraint: Element Default Valid (Immediate)
15826
    * For a string to be a valid default with respect to a type
15827
    * definition the appropriate case among the following must be true:
15828
    */
15829
0
    if WXS_IS_COMPLEX(type) {
15830
  /*
15831
  * Complex type.
15832
  *
15833
  * SPEC (2.1) "its {content type} must be a simple type definition
15834
  * or mixed."
15835
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15836
  * type}'s particle must be `emptiable` as defined by
15837
  * Particle Emptiable ($3.9.6)."
15838
  */
15839
0
  if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15840
0
      ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15841
      /* NOTE that this covers (2.2.2) as well. */
15842
0
      xmlSchemaPCustomErr(pctxt,
15843
0
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15844
0
    WXS_BASIC_CAST type, type->node,
15845
0
    "For a string to be a valid default, the type definition "
15846
0
    "must be a simple type or a complex type with mixed content "
15847
0
    "and a particle emptiable", NULL);
15848
0
      return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15849
0
  }
15850
0
    }
15851
    /*
15852
    * 1 If the type definition is a simple type definition, then the string
15853
    * must be `valid` with respect to that definition as defined by String
15854
    * Valid ($3.14.4).
15855
    *
15856
    * AND
15857
    *
15858
    * 2.2.1 If the {content type} is a simple type definition, then the
15859
    * string must be `valid` with respect to that simple type definition
15860
    * as defined by String Valid ($3.14.4).
15861
    */
15862
0
    if (WXS_IS_SIMPLE(type))
15863
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15864
0
      type, value, val, 1, 1, 0);
15865
0
    else if (WXS_HAS_SIMPLE_CONTENT(type))
15866
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15867
0
      type->contentTypeDef, value, val, 1, 1, 0);
15868
0
    else
15869
0
  return (ret);
15870
15871
0
    if (ret < 0) {
15872
0
  PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15873
0
      "calling xmlSchemaVCheckCVCSimpleType()");
15874
0
    }
15875
15876
0
    return (ret);
15877
0
}
15878
15879
/**
15880
 * xmlSchemaCheckCTPropsCorrect:
15881
 * @ctxt:  the schema parser context
15882
 * @type:  the complex type definition
15883
 *
15884
 *.(4.6) Constraints on Complex Type Definition Schema Components
15885
 * Schema Component Constraint:
15886
 * Complex Type Definition Properties Correct (ct-props-correct)
15887
 * STATUS: (seems) complete
15888
 *
15889
 * Returns 0 if the constraints are satisfied, a positive
15890
 * error code if not and -1 if an internal error occurred.
15891
 */
15892
static int
15893
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15894
           xmlSchemaTypePtr type)
15895
0
{
15896
    /*
15897
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15898
    *
15899
    * SPEC (1) "The values of the properties of a complex type definition must
15900
    * be as described in the property tableau in The Complex Type Definition
15901
    * Schema Component ($3.4.1), modulo the impact of Missing
15902
    * Sub-components ($5.3)."
15903
    */
15904
0
    if ((type->baseType != NULL) &&
15905
0
  (WXS_IS_SIMPLE(type->baseType)) &&
15906
0
  (WXS_IS_EXTENSION(type) == 0)) {
15907
  /*
15908
  * SPEC (2) "If the {base type definition} is a simple type definition,
15909
  * the {derivation method} must be extension."
15910
  */
15911
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
15912
0
      XML_SCHEMAP_SRC_CT_1,
15913
0
      NULL, WXS_BASIC_CAST type,
15914
0
      "If the base type is a simple type, the derivation method must be "
15915
0
      "'extension'", NULL, NULL);
15916
0
  return (XML_SCHEMAP_SRC_CT_1);
15917
0
    }
15918
    /*
15919
    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
15920
    * definition`. That is, it must be possible to reach the `ur-type
15921
    * definition` by repeatedly following the {base type definition}."
15922
    *
15923
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15924
    */
15925
    /*
15926
    * NOTE that (4) and (5) need the following:
15927
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
15928
    *   - attribute group references need to be expanded already
15929
    *   - simple types need to be typefixed already
15930
    */
15931
0
    if (type->attrUses &&
15932
0
  (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15933
0
    {
15934
0
  xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15935
0
  xmlSchemaAttributeUsePtr use, tmp;
15936
0
  int i, j, hasId = 0;
15937
15938
0
  for (i = uses->nbItems -1; i >= 0; i--) {
15939
0
      use = uses->items[i];
15940
15941
      /*
15942
      * SPEC ct-props-correct
15943
      * (4) "Two distinct attribute declarations in the
15944
      * {attribute uses} must not have identical {name}s and
15945
      * {target namespace}s."
15946
      */
15947
0
      if (i > 0) {
15948
0
    for (j = i -1; j >= 0; j--) {
15949
0
        tmp = uses->items[j];
15950
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
15951
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
15952
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
15953
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
15954
0
        {
15955
0
      xmlChar *str = NULL;
15956
15957
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15958
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15959
0
          NULL, WXS_BASIC_CAST type,
15960
0
          "Duplicate %s",
15961
0
          xmlSchemaGetComponentDesignation(&str, use),
15962
0
          NULL);
15963
0
      FREE_AND_NULL(str);
15964
      /*
15965
      * Remove the duplicate.
15966
      */
15967
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15968
0
          goto exit_failure;
15969
0
      goto next_use;
15970
0
        }
15971
0
    }
15972
0
      }
15973
      /*
15974
      * SPEC ct-props-correct
15975
      * (5) "Two distinct attribute declarations in the
15976
      * {attribute uses} must not have {type definition}s which
15977
      * are or are derived from ID."
15978
      */
15979
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15980
0
    if (xmlSchemaIsDerivedFromBuiltInType(
15981
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15982
0
    {
15983
0
        if (hasId) {
15984
0
      xmlChar *str = NULL;
15985
15986
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15987
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15988
0
          NULL, WXS_BASIC_CAST type,
15989
0
          "There must not exist more than one attribute "
15990
0
          "declaration of type 'xs:ID' "
15991
0
          "(or derived from 'xs:ID'). The %s violates this "
15992
0
          "constraint",
15993
0
          xmlSchemaGetComponentDesignation(&str, use),
15994
0
          NULL);
15995
0
      FREE_AND_NULL(str);
15996
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15997
0
          goto exit_failure;
15998
0
        }
15999
16000
0
        hasId = 1;
16001
0
    }
16002
0
      }
16003
0
next_use: {}
16004
0
  }
16005
0
    }
16006
0
    return (0);
16007
0
exit_failure:
16008
0
    return(-1);
16009
0
}
16010
16011
static int
16012
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16013
           xmlSchemaTypePtr typeB)
16014
0
{
16015
    /*
16016
    * TODO: This should implement component-identity
16017
    * in the future.
16018
    */
16019
0
    if ((typeA == NULL) || (typeB == NULL))
16020
0
  return (0);
16021
0
    return (typeA == typeB);
16022
0
}
16023
16024
/**
16025
 * xmlSchemaCheckCOSCTDerivedOK:
16026
 * @ctxt:  the schema parser context
16027
 * @type:  the to-be derived complex type definition
16028
 * @baseType:  the base complex type definition
16029
 * @set: the given set
16030
 *
16031
 * Schema Component Constraint:
16032
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16033
 *
16034
 * STATUS: completed
16035
 *
16036
 * Returns 0 if the constraints are satisfied, or 1
16037
 * if not.
16038
 */
16039
static int
16040
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16041
           xmlSchemaTypePtr type,
16042
           xmlSchemaTypePtr baseType,
16043
           int set)
16044
0
{
16045
0
    int equal = xmlSchemaAreEqualTypes(type, baseType);
16046
    /* TODO: Error codes. */
16047
    /*
16048
    * SPEC "For a complex type definition (call it D, for derived)
16049
    * to be validly derived from a type definition (call this
16050
    * B, for base) given a subset of {extension, restriction}
16051
    * all of the following must be true:"
16052
    */
16053
0
    if (! equal) {
16054
  /*
16055
  * SPEC (1) "If B and D are not the same type definition, then the
16056
  * {derivation method} of D must not be in the subset."
16057
  */
16058
0
  if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16059
0
      ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16060
0
      return (1);
16061
0
    } else {
16062
  /*
16063
  * SPEC (2.1) "B and D must be the same type definition."
16064
  */
16065
0
  return (0);
16066
0
    }
16067
    /*
16068
    * SPEC (2.2) "B must be D's {base type definition}."
16069
    */
16070
0
    if (type->baseType == baseType)
16071
0
  return (0);
16072
    /*
16073
    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16074
    * definition`."
16075
    */
16076
0
    if (WXS_IS_ANYTYPE(type->baseType))
16077
0
  return (1);
16078
16079
0
    if (WXS_IS_COMPLEX(type->baseType)) {
16080
  /*
16081
  * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16082
  * must be validly derived from B given the subset as defined by this
16083
  * constraint."
16084
  */
16085
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16086
0
      baseType, set));
16087
0
    } else {
16088
  /*
16089
  * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16090
  * must be validly derived from B given the subset as defined in Type
16091
  * Derivation OK (Simple) ($3.14.6).
16092
  */
16093
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16094
0
      baseType, set));
16095
0
    }
16096
0
}
16097
16098
/**
16099
 * xmlSchemaCheckCOSDerivedOK:
16100
 * @type:  the derived simple type definition
16101
 * @baseType:  the base type definition
16102
 *
16103
 * Calls:
16104
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16105
 *
16106
 * Checks whether @type can be validly derived from @baseType.
16107
 *
16108
 * Returns 0 on success, an positive error code otherwise.
16109
 */
16110
static int
16111
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16112
         xmlSchemaTypePtr type,
16113
         xmlSchemaTypePtr baseType,
16114
         int set)
16115
0
{
16116
0
    if (WXS_IS_SIMPLE(type))
16117
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16118
0
    else
16119
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16120
0
}
16121
16122
/**
16123
 * xmlSchemaCheckCOSCTExtends:
16124
 * @ctxt:  the schema parser context
16125
 * @type:  the complex type definition
16126
 *
16127
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16128
 * Schema Component Constraint:
16129
 * Derivation Valid (Extension) (cos-ct-extends)
16130
 *
16131
 * STATUS:
16132
 *   missing:
16133
 *     (1.5)
16134
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16135
 *
16136
 * Returns 0 if the constraints are satisfied, a positive
16137
 * error code if not and -1 if an internal error occurred.
16138
 */
16139
static int
16140
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16141
         xmlSchemaTypePtr type)
16142
0
{
16143
0
    xmlSchemaTypePtr base = type->baseType;
16144
    /*
16145
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16146
    * temporarily only.
16147
    */
16148
    /*
16149
    * SPEC (1) "If the {base type definition} is a complex type definition,
16150
    * then all of the following must be true:"
16151
    */
16152
0
    if (WXS_IS_COMPLEX(base)) {
16153
  /*
16154
  * SPEC (1.1) "The {final} of the {base type definition} must not
16155
  * contain extension."
16156
  */
16157
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16158
0
      xmlSchemaPCustomErr(ctxt,
16159
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16160
0
    WXS_BASIC_CAST type, NULL,
16161
0
    "The 'final' of the base type definition "
16162
0
    "contains 'extension'", NULL);
16163
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16164
0
  }
16165
16166
  /*
16167
  * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16168
  * since they are automatically satisfied through the
16169
  * inheriting mechanism.
16170
  * Note that even if redefining components, the inheriting mechanism
16171
  * is used.
16172
  */
16173
#if 0
16174
  /*
16175
  * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16176
  * uses}
16177
  * of the complex type definition itself, that is, for every attribute
16178
  * use in the {attribute uses} of the {base type definition}, there
16179
  * must be an attribute use in the {attribute uses} of the complex
16180
  * type definition itself whose {attribute declaration} has the same
16181
  * {name}, {target namespace} and {type definition} as its attribute
16182
  * declaration"
16183
  */
16184
  if (base->attrUses != NULL) {
16185
      int i, j, found;
16186
      xmlSchemaAttributeUsePtr use, buse;
16187
16188
      for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16189
    buse = (WXS_LIST_CAST base->attrUses)->items[i];
16190
    found = 0;
16191
    if (type->attrUses != NULL) {
16192
        use = (WXS_LIST_CAST type->attrUses)->items[j];
16193
        for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16194
        {
16195
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
16196
        WXS_ATTRUSE_DECL_NAME(buse)) &&
16197
          (WXS_ATTRUSE_DECL_TNS(use) ==
16198
        WXS_ATTRUSE_DECL_TNS(buse)) &&
16199
          (WXS_ATTRUSE_TYPEDEF(use) ==
16200
        WXS_ATTRUSE_TYPEDEF(buse))
16201
      {
16202
          found = 1;
16203
          break;
16204
      }
16205
        }
16206
    }
16207
    if (! found) {
16208
        xmlChar *str = NULL;
16209
16210
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
16211
      XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16212
      NULL, WXS_BASIC_CAST type,
16213
      /*
16214
      * TODO: The report does not indicate that also the
16215
      * type needs to be the same.
16216
      */
16217
      "This type is missing a matching correspondent "
16218
      "for its {base type}'s %s in its {attribute uses}",
16219
      xmlSchemaGetComponentDesignation(&str,
16220
          buse->children),
16221
      NULL);
16222
        FREE_AND_NULL(str)
16223
    }
16224
      }
16225
  }
16226
  /*
16227
  * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16228
  * definition must also have one, and the base type definition's
16229
  * {attribute  wildcard}'s {namespace constraint} must be a subset
16230
  * of the complex  type definition's {attribute wildcard}'s {namespace
16231
  * constraint}, as defined by Wildcard Subset ($3.10.6)."
16232
  */
16233
16234
  /*
16235
  * MAYBE TODO: Enable if ever needed. But this will be needed only
16236
  * if created the type via a schema construction API.
16237
  */
16238
  if (base->attributeWildcard != NULL) {
16239
      if (type->attributeWildcard == NULL) {
16240
    xmlChar *str = NULL;
16241
16242
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16243
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16244
        NULL, type,
16245
        "The base %s has an attribute wildcard, "
16246
        "but this type is missing an attribute wildcard",
16247
        xmlSchemaGetComponentDesignation(&str, base));
16248
    FREE_AND_NULL(str)
16249
16250
      } else if (xmlSchemaCheckCOSNSSubset(
16251
    base->attributeWildcard, type->attributeWildcard))
16252
      {
16253
    xmlChar *str = NULL;
16254
16255
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16256
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16257
        NULL, type,
16258
        "The attribute wildcard is not a valid "
16259
        "superset of the one in the base %s",
16260
        xmlSchemaGetComponentDesignation(&str, base));
16261
    FREE_AND_NULL(str)
16262
      }
16263
  }
16264
#endif
16265
  /*
16266
  * SPEC (1.4) "One of the following must be true:"
16267
  */
16268
0
  if ((type->contentTypeDef != NULL) &&
16269
0
      (type->contentTypeDef == base->contentTypeDef)) {
16270
      /*
16271
      * SPEC (1.4.1) "The {content type} of the {base type definition}
16272
      * and the {content type} of the complex type definition itself
16273
      * must be the same simple type definition"
16274
      * PASS
16275
      */
16276
0
  } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16277
0
      (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16278
      /*
16279
      * SPEC (1.4.2) "The {content type} of both the {base type
16280
      * definition} and the complex type definition itself must
16281
      * be empty."
16282
      * PASS
16283
      */
16284
0
  } else {
16285
      /*
16286
      * SPEC (1.4.3) "All of the following must be true:"
16287
      */
16288
0
      if (type->subtypes == NULL) {
16289
    /*
16290
    * SPEC 1.4.3.1 The {content type} of the complex type
16291
    * definition itself must specify a particle.
16292
    */
16293
0
    xmlSchemaPCustomErr(ctxt,
16294
0
        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16295
0
        WXS_BASIC_CAST type, NULL,
16296
0
        "The content type must specify a particle", NULL);
16297
0
    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16298
0
      }
16299
      /*
16300
      * SPEC (1.4.3.2) "One of the following must be true:"
16301
      */
16302
0
      if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16303
    /*
16304
    * SPEC (1.4.3.2.1) "The {content type} of the {base type
16305
    * definition} must be empty.
16306
    * PASS
16307
    */
16308
0
      } else {
16309
    /*
16310
    * SPEC (1.4.3.2.2) "All of the following must be true:"
16311
    */
16312
0
    if ((type->contentType != base->contentType) ||
16313
0
        ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16314
0
        (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16315
        /*
16316
        * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16317
        * or both must be element-only."
16318
        */
16319
0
        xmlSchemaPCustomErr(ctxt,
16320
0
      XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16321
0
      WXS_BASIC_CAST type, NULL,
16322
0
      "The content type of both, the type and its base "
16323
0
      "type, must either 'mixed' or 'element-only'", NULL);
16324
0
        return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16325
0
    }
16326
    /*
16327
    * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16328
    * complex type definition must be a `valid extension`
16329
    * of the {base type definition}'s particle, as defined
16330
    * in Particle Valid (Extension) ($3.9.6)."
16331
    *
16332
    * NOTE that we won't check "Particle Valid (Extension)",
16333
    * since it is ensured by the derivation process in
16334
    * xmlSchemaTypeFixup(). We need to implement this when heading
16335
    * for a construction API
16336
    * TODO: !! This is needed to be checked if redefining a type !!
16337
    */
16338
0
      }
16339
      /*
16340
      * URGENT TODO (1.5)
16341
      */
16342
0
  }
16343
0
    } else {
16344
  /*
16345
  * SPEC (2) "If the {base type definition} is a simple type definition,
16346
  * then all of the following must be true:"
16347
  */
16348
0
  if (type->contentTypeDef != base) {
16349
      /*
16350
      * SPEC (2.1) "The {content type} must be the same simple type
16351
      * definition."
16352
      */
16353
0
      xmlSchemaPCustomErr(ctxt,
16354
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16355
0
    WXS_BASIC_CAST type, NULL,
16356
0
    "The content type must be the simple base type", NULL);
16357
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16358
0
  }
16359
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16360
      /*
16361
      * SPEC (2.2) "The {final} of the {base type definition} must not
16362
      * contain extension"
16363
      * NOTE that this is the same as (1.1).
16364
      */
16365
0
      xmlSchemaPCustomErr(ctxt,
16366
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16367
0
    WXS_BASIC_CAST type, NULL,
16368
0
    "The 'final' of the base type definition "
16369
0
    "contains 'extension'", NULL);
16370
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16371
0
  }
16372
0
    }
16373
0
    return (0);
16374
0
}
16375
16376
/**
16377
 * xmlSchemaCheckDerivationOKRestriction:
16378
 * @ctxt:  the schema parser context
16379
 * @type:  the complex type definition
16380
 *
16381
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16382
 * Schema Component Constraint:
16383
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16384
 *
16385
 * STATUS:
16386
 *   missing:
16387
 *     (5.4.2) ???
16388
 *
16389
 * ATTENTION:
16390
 * In XML Schema 1.1 this will be:
16391
 * Validation Rule: Checking complex type subsumption
16392
 *
16393
 * Returns 0 if the constraints are satisfied, a positive
16394
 * error code if not and -1 if an internal error occurred.
16395
 */
16396
static int
16397
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16398
              xmlSchemaTypePtr type)
16399
0
{
16400
0
    xmlSchemaTypePtr base;
16401
16402
    /*
16403
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16404
    * temporarily only.
16405
    */
16406
0
    base = type->baseType;
16407
0
    if (! WXS_IS_COMPLEX(base)) {
16408
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16409
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16410
0
      type->node, WXS_BASIC_CAST type,
16411
0
      "The base type must be a complex type", NULL, NULL);
16412
0
  return(ctxt->err);
16413
0
    }
16414
0
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16415
  /*
16416
  * SPEC (1) "The {base type definition} must be a complex type
16417
  * definition whose {final} does not contain restriction."
16418
  */
16419
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16420
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16421
0
      type->node, WXS_BASIC_CAST type,
16422
0
      "The 'final' of the base type definition "
16423
0
      "contains 'restriction'", NULL, NULL);
16424
0
  return (ctxt->err);
16425
0
    }
16426
    /*
16427
    * SPEC (2), (3) and (4)
16428
    * Those are handled in a separate function, since the
16429
    * same constraints are needed for redefinition of
16430
    * attribute groups as well.
16431
    */
16432
0
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16433
0
  XML_SCHEMA_ACTION_DERIVE,
16434
0
  WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16435
0
  type->attrUses, base->attrUses,
16436
0
  type->attributeWildcard,
16437
0
  base->attributeWildcard) == -1)
16438
0
    {
16439
0
  return(-1);
16440
0
    }
16441
    /*
16442
    * SPEC (5) "One of the following must be true:"
16443
    */
16444
0
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16445
  /*
16446
  * SPEC (5.1) "The {base type definition} must be the
16447
  * `ur-type definition`."
16448
  * PASS
16449
  */
16450
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16451
0
      (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16452
  /*
16453
  * SPEC (5.2.1) "The {content type} of the complex type definition
16454
  * must be a simple type definition"
16455
  *
16456
  * SPEC (5.2.2) "One of the following must be true:"
16457
  */
16458
0
  if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16459
0
      (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16460
0
  {
16461
0
      int err;
16462
      /*
16463
      * SPEC (5.2.2.1) "The {content type} of the {base type
16464
      * definition} must be a simple type definition from which
16465
      * the {content type} is validly derived given the empty
16466
      * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16467
      *
16468
      * ATTENTION TODO: This seems not needed if the type implicitly
16469
      * derived from the base type.
16470
      *
16471
      */
16472
0
      err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16473
0
    type->contentTypeDef, base->contentTypeDef, 0);
16474
0
      if (err != 0) {
16475
0
    xmlChar *strA = NULL, *strB = NULL;
16476
16477
0
    if (err == -1)
16478
0
        return(-1);
16479
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16480
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16481
0
        NULL, WXS_BASIC_CAST type,
16482
0
        "The {content type} %s is not validly derived from the "
16483
0
        "base type's {content type} %s",
16484
0
        xmlSchemaGetComponentDesignation(&strA,
16485
0
      type->contentTypeDef),
16486
0
        xmlSchemaGetComponentDesignation(&strB,
16487
0
      base->contentTypeDef));
16488
0
    FREE_AND_NULL(strA);
16489
0
    FREE_AND_NULL(strB);
16490
0
    return(ctxt->err);
16491
0
      }
16492
0
  } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16493
0
      (xmlSchemaIsParticleEmptiable(
16494
0
    (xmlSchemaParticlePtr) base->subtypes))) {
16495
      /*
16496
      * SPEC (5.2.2.2) "The {base type definition} must be mixed
16497
      * and have a particle which is `emptiable` as defined in
16498
      * Particle Emptiable ($3.9.6)."
16499
      * PASS
16500
      */
16501
0
  } else {
16502
0
      xmlSchemaPCustomErr(ctxt,
16503
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16504
0
    WXS_BASIC_CAST type, NULL,
16505
0
    "The content type of the base type must be either "
16506
0
    "a simple type or 'mixed' and an emptiable particle", NULL);
16507
0
      return (ctxt->err);
16508
0
  }
16509
0
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16510
  /*
16511
  * SPEC (5.3.1) "The {content type} of the complex type itself must
16512
  * be empty"
16513
  */
16514
0
  if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16515
      /*
16516
      * SPEC (5.3.2.1) "The {content type} of the {base type
16517
      * definition} must also be empty."
16518
      * PASS
16519
      */
16520
0
  } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16521
0
      (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16522
0
      xmlSchemaIsParticleEmptiable(
16523
0
    (xmlSchemaParticlePtr) base->subtypes)) {
16524
      /*
16525
      * SPEC (5.3.2.2) "The {content type} of the {base type
16526
      * definition} must be elementOnly or mixed and have a particle
16527
      * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16528
      * PASS
16529
      */
16530
0
  } else {
16531
0
      xmlSchemaPCustomErr(ctxt,
16532
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16533
0
    WXS_BASIC_CAST type, NULL,
16534
0
    "The content type of the base type must be either "
16535
0
    "empty or 'mixed' (or 'elements-only') and an emptiable "
16536
0
    "particle", NULL);
16537
0
      return (ctxt->err);
16538
0
  }
16539
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16540
0
  WXS_HAS_MIXED_CONTENT(type)) {
16541
  /*
16542
  * SPEC (5.4.1.1) "The {content type} of the complex type definition
16543
  * itself must be element-only"
16544
  */
16545
0
  if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16546
      /*
16547
      * SPEC (5.4.1.2) "The {content type} of the complex type
16548
      * definition itself and of the {base type definition} must be
16549
      * mixed"
16550
      */
16551
0
      xmlSchemaPCustomErr(ctxt,
16552
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16553
0
    WXS_BASIC_CAST type, NULL,
16554
0
    "If the content type is 'mixed', then the content type of the "
16555
0
    "base type must also be 'mixed'", NULL);
16556
0
      return (ctxt->err);
16557
0
  }
16558
  /*
16559
  * SPEC (5.4.2) "The particle of the complex type definition itself
16560
  * must be a `valid restriction` of the particle of the {content
16561
  * type} of the {base type definition} as defined in Particle Valid
16562
  * (Restriction) ($3.9.6).
16563
  *
16564
  * URGENT TODO: (5.4.2)
16565
  */
16566
0
    } else {
16567
0
  xmlSchemaPCustomErr(ctxt,
16568
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16569
0
      WXS_BASIC_CAST type, NULL,
16570
0
      "The type is not a valid restriction of its base type", NULL);
16571
0
  return (ctxt->err);
16572
0
    }
16573
0
    return (0);
16574
0
}
16575
16576
/**
16577
 * xmlSchemaCheckCTComponent:
16578
 * @ctxt:  the schema parser context
16579
 * @type:  the complex type definition
16580
 *
16581
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16582
 *
16583
 * Returns 0 if the constraints are satisfied, a positive
16584
 * error code if not and -1 if an internal error occurred.
16585
 */
16586
static int
16587
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16588
        xmlSchemaTypePtr type)
16589
0
{
16590
0
    int ret;
16591
    /*
16592
    * Complex Type Definition Properties Correct
16593
    */
16594
0
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16595
0
    if (ret != 0)
16596
0
  return (ret);
16597
0
    if (WXS_IS_EXTENSION(type))
16598
0
  ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16599
0
    else
16600
0
  ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16601
0
    return (ret);
16602
0
}
16603
16604
/**
16605
 * xmlSchemaCheckSRCCT:
16606
 * @ctxt:  the schema parser context
16607
 * @type:  the complex type definition
16608
 *
16609
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16610
 * Schema Representation Constraint:
16611
 * Complex Type Definition Representation OK (src-ct)
16612
 *
16613
 * Returns 0 if the constraints are satisfied, a positive
16614
 * error code if not and -1 if an internal error occurred.
16615
 */
16616
static int
16617
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16618
        xmlSchemaTypePtr type)
16619
0
{
16620
0
    xmlSchemaTypePtr base;
16621
0
    int ret = 0;
16622
16623
    /*
16624
    * TODO: Adjust the error codes here, as I used
16625
    * XML_SCHEMAP_SRC_CT_1 only yet.
16626
    */
16627
0
    base = type->baseType;
16628
0
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16629
  /*
16630
  * 1 If the <complexContent> alternative is chosen, the type definition
16631
  * `resolved` to by the `actual value` of the base [attribute]
16632
  * must be a complex type definition;
16633
  */
16634
0
  if (! WXS_IS_COMPLEX(base)) {
16635
0
      xmlChar *str = NULL;
16636
0
      xmlSchemaPCustomErr(ctxt,
16637
0
    XML_SCHEMAP_SRC_CT_1,
16638
0
    WXS_BASIC_CAST type, type->node,
16639
0
    "If using <complexContent>, the base type is expected to be "
16640
0
    "a complex type. The base type '%s' is a simple type",
16641
0
    xmlSchemaFormatQName(&str, base->targetNamespace,
16642
0
    base->name));
16643
0
      FREE_AND_NULL(str)
16644
0
      return (XML_SCHEMAP_SRC_CT_1);
16645
0
  }
16646
0
    } else {
16647
  /*
16648
  * SPEC
16649
  * 2 If the <simpleContent> alternative is chosen, all of the
16650
  * following must be true:
16651
  * 2.1 The type definition `resolved` to by the `actual value` of the
16652
  * base [attribute] must be one of the following:
16653
  */
16654
0
  if (WXS_IS_SIMPLE(base)) {
16655
0
      if (WXS_IS_EXTENSION(type) == 0) {
16656
0
    xmlChar *str = NULL;
16657
    /*
16658
    * 2.1.3 only if the <extension> alternative is also
16659
    * chosen, a simple type definition.
16660
    */
16661
    /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16662
0
    xmlSchemaPCustomErr(ctxt,
16663
0
        XML_SCHEMAP_SRC_CT_1,
16664
0
        WXS_BASIC_CAST type, NULL,
16665
0
        "If using <simpleContent> and <restriction>, the base "
16666
0
        "type must be a complex type. The base type '%s' is "
16667
0
        "a simple type",
16668
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16669
0
      base->name));
16670
0
    FREE_AND_NULL(str)
16671
0
    return (XML_SCHEMAP_SRC_CT_1);
16672
0
      }
16673
0
  } else {
16674
      /* Base type is a complex type. */
16675
0
      if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16676
0
    (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16677
    /*
16678
    * 2.1.1 a complex type definition whose {content type} is a
16679
    * simple type definition;
16680
    * PASS
16681
    */
16682
0
    if (base->contentTypeDef == NULL) {
16683
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16684
0
      WXS_BASIC_CAST type, NULL,
16685
0
      "Internal error: xmlSchemaCheckSRCCT, "
16686
0
      "'%s', base type has no content type",
16687
0
      type->name);
16688
0
        return (-1);
16689
0
    }
16690
0
      } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16691
0
    (WXS_IS_RESTRICTION(type))) {
16692
16693
    /*
16694
    * 2.1.2 only if the <restriction> alternative is also
16695
    * chosen, a complex type definition whose {content type}
16696
    * is mixed and a particle emptiable.
16697
    */
16698
0
    if (! xmlSchemaIsParticleEmptiable(
16699
0
        (xmlSchemaParticlePtr) base->subtypes)) {
16700
0
        ret = XML_SCHEMAP_SRC_CT_1;
16701
0
    } else
16702
        /*
16703
        * Attention: at this point the <simpleType> child is in
16704
        * ->contentTypeDef (put there during parsing).
16705
        */
16706
0
        if (type->contentTypeDef == NULL) {
16707
0
        xmlChar *str = NULL;
16708
        /*
16709
        * 2.2 If clause 2.1.2 above is satisfied, then there
16710
        * must be a <simpleType> among the [children] of
16711
        * <restriction>.
16712
        */
16713
        /* TODO: Change error code to ..._SRC_CT_2_2. */
16714
0
        xmlSchemaPCustomErr(ctxt,
16715
0
      XML_SCHEMAP_SRC_CT_1,
16716
0
      WXS_BASIC_CAST type, NULL,
16717
0
      "A <simpleType> is expected among the children "
16718
0
      "of <restriction>, if <simpleContent> is used and "
16719
0
      "the base type '%s' is a complex type",
16720
0
      xmlSchemaFormatQName(&str, base->targetNamespace,
16721
0
      base->name));
16722
0
        FREE_AND_NULL(str)
16723
0
        return (XML_SCHEMAP_SRC_CT_1);
16724
0
    }
16725
0
      } else {
16726
0
    ret = XML_SCHEMAP_SRC_CT_1;
16727
0
      }
16728
0
  }
16729
0
  if (ret > 0) {
16730
0
      xmlChar *str = NULL;
16731
0
      if (WXS_IS_RESTRICTION(type)) {
16732
0
    xmlSchemaPCustomErr(ctxt,
16733
0
        XML_SCHEMAP_SRC_CT_1,
16734
0
        WXS_BASIC_CAST type, NULL,
16735
0
        "If <simpleContent> and <restriction> is used, the "
16736
0
        "base type must be a simple type or a complex type with "
16737
0
        "mixed content and particle emptiable. The base type "
16738
0
        "'%s' is none of those",
16739
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16740
0
        base->name));
16741
0
      } else {
16742
0
    xmlSchemaPCustomErr(ctxt,
16743
0
        XML_SCHEMAP_SRC_CT_1,
16744
0
        WXS_BASIC_CAST type, NULL,
16745
0
        "If <simpleContent> and <extension> is used, the "
16746
0
        "base type must be a simple type. The base type '%s' "
16747
0
        "is a complex type",
16748
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16749
0
        base->name));
16750
0
      }
16751
0
      FREE_AND_NULL(str)
16752
0
  }
16753
0
    }
16754
    /*
16755
    * SPEC (3) "The corresponding complex type definition component must
16756
    * satisfy the conditions set out in Constraints on Complex Type
16757
    * Definition Schema Components ($3.4.6);"
16758
    * NOTE (3) will be done in xmlSchemaTypeFixup().
16759
    */
16760
    /*
16761
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16762
    * above for {attribute wildcard} is satisfied, the intensional
16763
    * intersection must be expressible, as defined in Attribute Wildcard
16764
    * Intersection ($3.10.6).
16765
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16766
    */
16767
0
    return (ret);
16768
0
}
16769
16770
#ifdef ENABLE_PARTICLE_RESTRICTION
16771
/**
16772
 * xmlSchemaCheckParticleRangeOK:
16773
 * @ctxt:  the schema parser context
16774
 * @type:  the complex type definition
16775
 *
16776
 * (3.9.6) Constraints on Particle Schema Components
16777
 * Schema Component Constraint:
16778
 * Occurrence Range OK (range-ok)
16779
 *
16780
 * STATUS: complete
16781
 *
16782
 * Returns 0 if the constraints are satisfied, a positive
16783
 * error code if not and -1 if an internal error occurred.
16784
 */
16785
static int
16786
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16787
            int bmin, int bmax)
16788
{
16789
    if (rmin < bmin)
16790
  return (1);
16791
    if ((bmax != UNBOUNDED) &&
16792
  (rmax > bmax))
16793
  return (1);
16794
    return (0);
16795
}
16796
16797
/**
16798
 * xmlSchemaCheckRCaseNameAndTypeOK:
16799
 * @ctxt:  the schema parser context
16800
 * @r: the restricting element declaration particle
16801
 * @b: the base element declaration particle
16802
 *
16803
 * (3.9.6) Constraints on Particle Schema Components
16804
 * Schema Component Constraint:
16805
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16806
 * (rcase-NameAndTypeOK)
16807
 *
16808
 * STATUS:
16809
 *   MISSING (3.2.3)
16810
 *   CLARIFY: (3.2.2)
16811
 *
16812
 * Returns 0 if the constraints are satisfied, a positive
16813
 * error code if not and -1 if an internal error occurred.
16814
 */
16815
static int
16816
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16817
         xmlSchemaParticlePtr r,
16818
         xmlSchemaParticlePtr b)
16819
{
16820
    xmlSchemaElementPtr elemR, elemB;
16821
16822
    /* TODO: Error codes (rcase-NameAndTypeOK). */
16823
    elemR = (xmlSchemaElementPtr) r->children;
16824
    elemB = (xmlSchemaElementPtr) b->children;
16825
    /*
16826
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
16827
    * the same."
16828
    */
16829
    if ((elemR != elemB) &&
16830
  ((! xmlStrEqual(elemR->name, elemB->name)) ||
16831
  (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16832
  return (1);
16833
    /*
16834
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16835
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16836
    */
16837
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16838
      b->minOccurs, b->maxOccurs) != 0)
16839
  return (1);
16840
    /*
16841
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16842
    * {scope} are global."
16843
    */
16844
    if (elemR == elemB)
16845
  return (0);
16846
    /*
16847
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16848
    */
16849
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16850
  (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16851
   return (1);
16852
    /*
16853
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16854
    * or is not fixed, or R's declaration's {value constraint} is fixed
16855
    * with the same value."
16856
    */
16857
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16858
  ((elemR->value == NULL) ||
16859
   ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16860
   /* TODO: Equality of the initial value or normalized or canonical? */
16861
   (! xmlStrEqual(elemR->value, elemB->value))))
16862
   return (1);
16863
    /*
16864
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16865
    * definitions} is a subset of B's declaration's {identity-constraint
16866
    * definitions}, if any."
16867
    */
16868
    if (elemB->idcs != NULL) {
16869
  /* TODO */
16870
    }
16871
    /*
16872
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16873
    * superset of B's declaration's {disallowed substitutions}."
16874
    */
16875
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16876
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16877
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16878
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16879
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16880
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16881
   return (1);
16882
    /*
16883
    * SPEC (3.2.5) "R's {type definition} is validly derived given
16884
    * {extension, list, union} from B's {type definition}"
16885
    *
16886
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
16887
    * set, if the corresponding constraints handle "restriction" and
16888
    * "extension" only?
16889
    *
16890
    */
16891
    {
16892
  int set = 0;
16893
16894
  set |= SUBSET_EXTENSION;
16895
  set |= SUBSET_LIST;
16896
  set |= SUBSET_UNION;
16897
  if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16898
      elemB->subtypes, set) != 0)
16899
      return (1);
16900
    }
16901
    return (0);
16902
}
16903
16904
/**
16905
 * xmlSchemaCheckRCaseNSCompat:
16906
 * @ctxt:  the schema parser context
16907
 * @r: the restricting element declaration particle
16908
 * @b: the base wildcard particle
16909
 *
16910
 * (3.9.6) Constraints on Particle Schema Components
16911
 * Schema Component Constraint:
16912
 * Particle Derivation OK (Elt:Any -- NSCompat)
16913
 * (rcase-NSCompat)
16914
 *
16915
 * STATUS: complete
16916
 *
16917
 * Returns 0 if the constraints are satisfied, a positive
16918
 * error code if not and -1 if an internal error occurred.
16919
 */
16920
static int
16921
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16922
          xmlSchemaParticlePtr r,
16923
          xmlSchemaParticlePtr b)
16924
{
16925
    /* TODO:Error codes (rcase-NSCompat). */
16926
    /*
16927
    * SPEC "For an element declaration particle to be a `valid restriction`
16928
    * of a wildcard particle all of the following must be true:"
16929
    *
16930
    * SPEC (1) "The element declaration's {target namespace} is `valid`
16931
    * with respect to the wildcard's {namespace constraint} as defined by
16932
    * Wildcard allows Namespace Name ($3.10.4)."
16933
    */
16934
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16935
  ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16936
  return (1);
16937
    /*
16938
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16939
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16940
    */
16941
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16942
      b->minOccurs, b->maxOccurs) != 0)
16943
  return (1);
16944
16945
    return (0);
16946
}
16947
16948
/**
16949
 * xmlSchemaCheckRCaseRecurseAsIfGroup:
16950
 * @ctxt:  the schema parser context
16951
 * @r: the restricting element declaration particle
16952
 * @b: the base model group particle
16953
 *
16954
 * (3.9.6) Constraints on Particle Schema Components
16955
 * Schema Component Constraint:
16956
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16957
 * (rcase-RecurseAsIfGroup)
16958
 *
16959
 * STATUS: TODO
16960
 *
16961
 * Returns 0 if the constraints are satisfied, a positive
16962
 * error code if not and -1 if an internal error occurred.
16963
 */
16964
static int
16965
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16966
            xmlSchemaParticlePtr r,
16967
            xmlSchemaParticlePtr b)
16968
{
16969
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16970
    TODO
16971
    return (0);
16972
}
16973
16974
/**
16975
 * xmlSchemaCheckRCaseNSSubset:
16976
 * @ctxt:  the schema parser context
16977
 * @r: the restricting wildcard particle
16978
 * @b: the base wildcard particle
16979
 *
16980
 * (3.9.6) Constraints on Particle Schema Components
16981
 * Schema Component Constraint:
16982
 * Particle Derivation OK (Any:Any -- NSSubset)
16983
 * (rcase-NSSubset)
16984
 *
16985
 * STATUS: complete
16986
 *
16987
 * Returns 0 if the constraints are satisfied, a positive
16988
 * error code if not and -1 if an internal error occurred.
16989
 */
16990
static int
16991
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16992
            xmlSchemaParticlePtr r,
16993
            xmlSchemaParticlePtr b,
16994
            int isAnyTypeBase)
16995
{
16996
    /* TODO: Error codes (rcase-NSSubset). */
16997
    /*
16998
    * SPEC (1) "R's occurrence range is a valid restriction of B's
16999
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17000
    */
17001
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17002
      b->minOccurs, b->maxOccurs))
17003
  return (1);
17004
    /*
17005
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
17006
    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17007
    */
17008
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
17009
  (xmlSchemaWildcardPtr) b->children))
17010
  return (1);
17011
    /*
17012
    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17013
    * definition`, R's {process contents} must be identical to or stronger
17014
    * than B's {process contents}, where strict is stronger than lax is
17015
    * stronger than skip."
17016
    */
17017
    if (! isAnyTypeBase) {
17018
  if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17019
      ((xmlSchemaWildcardPtr) b->children)->processContents)
17020
      return (1);
17021
    }
17022
17023
    return (0);
17024
}
17025
17026
/**
17027
 * xmlSchemaCheckCOSParticleRestrict:
17028
 * @ctxt:  the schema parser context
17029
 * @type:  the complex type definition
17030
 *
17031
 * (3.9.6) Constraints on Particle Schema Components
17032
 * Schema Component Constraint:
17033
 * Particle Valid (Restriction) (cos-particle-restrict)
17034
 *
17035
 * STATUS: TODO
17036
 *
17037
 * Returns 0 if the constraints are satisfied, a positive
17038
 * error code if not and -1 if an internal error occurred.
17039
 */
17040
static int
17041
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17042
          xmlSchemaParticlePtr r,
17043
          xmlSchemaParticlePtr b)
17044
{
17045
    int ret = 0;
17046
17047
    /*part = WXS_TYPE_PARTICLE(type);
17048
    basePart = WXS_TYPE_PARTICLE(base);
17049
    */
17050
17051
    TODO
17052
17053
    /*
17054
    * SPEC (1) "They are the same particle."
17055
    */
17056
    if (r == b)
17057
  return (0);
17058
17059
17060
    return (0);
17061
}
17062
17063
#if 0
17064
/**
17065
 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17066
 * @ctxt:  the schema parser context
17067
 * @r: the model group particle
17068
 * @b: the base wildcard particle
17069
 *
17070
 * (3.9.6) Constraints on Particle Schema Components
17071
 * Schema Component Constraint:
17072
 * Particle Derivation OK (All/Choice/Sequence:Any --
17073
 *                         NSRecurseCheckCardinality)
17074
 * (rcase-NSRecurseCheckCardinality)
17075
 *
17076
 * STATUS: TODO: subst-groups
17077
 *
17078
 * Returns 0 if the constraints are satisfied, a positive
17079
 * error code if not and -1 if an internal error occurred.
17080
 */
17081
static int
17082
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17083
               xmlSchemaParticlePtr r,
17084
               xmlSchemaParticlePtr b)
17085
{
17086
    xmlSchemaParticlePtr part;
17087
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17088
    if ((r->children == NULL) || (r->children->children == NULL))
17089
  return (-1);
17090
    /*
17091
    * SPEC "For a group particle to be a `valid restriction` of a
17092
    * wildcard particle..."
17093
    *
17094
    * SPEC (1) "Every member of the {particles} of the group is a `valid
17095
    * restriction` of the wildcard as defined by
17096
    * Particle Valid (Restriction) ($3.9.6)."
17097
    */
17098
    part = (xmlSchemaParticlePtr) r->children->children;
17099
    do {
17100
  if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17101
      return (1);
17102
  part = (xmlSchemaParticlePtr) part->next;
17103
    } while (part != NULL);
17104
    /*
17105
    * SPEC (2) "The effective total range of the group [...] is a
17106
    * valid restriction of B's occurrence range as defined by
17107
    * Occurrence Range OK ($3.9.6)."
17108
    */
17109
    if (xmlSchemaCheckParticleRangeOK(
17110
      xmlSchemaGetParticleTotalRangeMin(r),
17111
      xmlSchemaGetParticleTotalRangeMax(r),
17112
      b->minOccurs, b->maxOccurs) != 0)
17113
  return (1);
17114
    return (0);
17115
}
17116
#endif
17117
17118
/**
17119
 * xmlSchemaCheckRCaseRecurse:
17120
 * @ctxt:  the schema parser context
17121
 * @r: the <all> or <sequence> model group particle
17122
 * @b: the base <all> or <sequence> model group particle
17123
 *
17124
 * (3.9.6) Constraints on Particle Schema Components
17125
 * Schema Component Constraint:
17126
 * Particle Derivation OK (All:All,Sequence:Sequence --
17127
                           Recurse)
17128
 * (rcase-Recurse)
17129
 *
17130
 * STATUS:  ?
17131
 * TODO: subst-groups
17132
 *
17133
 * Returns 0 if the constraints are satisfied, a positive
17134
 * error code if not and -1 if an internal error occurred.
17135
 */
17136
static int
17137
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17138
         xmlSchemaParticlePtr r,
17139
         xmlSchemaParticlePtr b)
17140
{
17141
    /* xmlSchemaParticlePtr part; */
17142
    /* TODO: Error codes (rcase-Recurse). */
17143
    if ((r->children == NULL) || (b->children == NULL) ||
17144
  (r->children->type != b->children->type))
17145
  return (-1);
17146
    /*
17147
    * SPEC "For an all or sequence group particle to be a `valid
17148
    * restriction` of another group particle with the same {compositor}..."
17149
    *
17150
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17151
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17152
    */
17153
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17154
      b->minOccurs, b->maxOccurs))
17155
  return (1);
17156
17157
17158
    return (0);
17159
}
17160
17161
#endif
17162
17163
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17164
0
    xmlSchemaPCustomErrExt(pctxt,      \
17165
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17166
0
  WXS_BASIC_CAST fac1, fac1->node, \
17167
0
  "It is an error for both '%s' and '%s' to be specified on the "\
17168
0
  "same type definition", \
17169
0
  BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17170
0
  BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17171
17172
#define FACET_RESTR_ERR(fac1, msg) \
17173
0
    xmlSchemaPCustomErr(pctxt,      \
17174
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17175
0
  WXS_BASIC_CAST fac1, fac1->node, \
17176
0
  msg, NULL);
17177
17178
#define FACET_RESTR_FIXED_ERR(fac) \
17179
0
    xmlSchemaPCustomErr(pctxt, \
17180
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17181
0
  WXS_BASIC_CAST fac, fac->node, \
17182
0
  "The base type's facet is 'fixed', thus the value must not " \
17183
0
  "differ", NULL);
17184
17185
static void
17186
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17187
      xmlSchemaFacetPtr facet1,
17188
      xmlSchemaFacetPtr facet2,
17189
      int lessGreater,
17190
      int orEqual,
17191
      int ofBase)
17192
0
{
17193
0
    xmlChar *msg = NULL;
17194
17195
0
    msg = xmlStrdup(BAD_CAST "'");
17196
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17197
0
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
17198
0
    if (lessGreater == 0)
17199
0
  msg = xmlStrcat(msg, BAD_CAST " equal to");
17200
0
    if (lessGreater == 1)
17201
0
  msg = xmlStrcat(msg, BAD_CAST " greater than");
17202
0
    else
17203
0
  msg = xmlStrcat(msg, BAD_CAST " less than");
17204
17205
0
    if (orEqual)
17206
0
  msg = xmlStrcat(msg, BAD_CAST " or equal to");
17207
0
    msg = xmlStrcat(msg, BAD_CAST " '");
17208
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17209
0
    if (ofBase)
17210
0
  msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17211
0
    else
17212
0
  msg = xmlStrcat(msg, BAD_CAST "'");
17213
17214
0
    xmlSchemaPCustomErr(pctxt,
17215
0
  XML_SCHEMAP_INVALID_FACET_VALUE,
17216
0
  WXS_BASIC_CAST facet1, NULL,
17217
0
  (const char *) msg, NULL);
17218
17219
0
    if (msg != NULL)
17220
0
  xmlFree(msg);
17221
0
}
17222
17223
/*
17224
* xmlSchemaDeriveAndValidateFacets:
17225
*
17226
* Schema Component Constraint: Simple Type Restriction (Facets)
17227
* (st-restrict-facets)
17228
*/
17229
static int
17230
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17231
         xmlSchemaTypePtr type)
17232
0
{
17233
0
    xmlSchemaTypePtr base = type->baseType;
17234
0
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
17235
0
    xmlSchemaFacetPtr facet, bfacet,
17236
0
  flength = NULL, ftotdig = NULL, ffracdig = NULL,
17237
0
  fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17238
0
  fmininc = NULL, fmaxinc = NULL,
17239
0
  fminexc = NULL, fmaxexc = NULL,
17240
0
  bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17241
0
  bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17242
0
  bfmininc = NULL, bfmaxinc = NULL,
17243
0
  bfminexc = NULL, bfmaxexc = NULL;
17244
0
    int res; /* err = 0, fixedErr; */
17245
17246
    /*
17247
    * SPEC st-restrict-facets 1:
17248
    * "The {variety} of R is the same as that of B."
17249
    */
17250
    /*
17251
    * SPEC st-restrict-facets 2:
17252
    * "If {variety} is atomic, the {primitive type definition}
17253
    * of R is the same as that of B."
17254
    *
17255
    * NOTE: we leave 1 & 2 out for now, since this will be
17256
    * satisfied by the derivation process.
17257
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
17258
    */
17259
    /*
17260
    * SPEC st-restrict-facets 3:
17261
    * "The {facets} of R are the union of S and the {facets}
17262
    * of B, eliminating duplicates. To eliminate duplicates,
17263
    * when a facet of the same kind occurs in both S and the
17264
    * {facets} of B, the one in the {facets} of B is not
17265
    * included, with the exception of enumeration and pattern
17266
    * facets, for which multiple occurrences with distinct values
17267
    * are allowed."
17268
    */
17269
17270
0
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
17271
0
  return (0);
17272
17273
0
    last = type->facetSet;
17274
0
    if (last != NULL)
17275
0
  while (last->next != NULL)
17276
0
      last = last->next;
17277
17278
0
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17279
0
  facet = cur->facet;
17280
0
  switch (facet->type) {
17281
0
      case XML_SCHEMA_FACET_LENGTH:
17282
0
    flength = facet; break;
17283
0
      case XML_SCHEMA_FACET_MINLENGTH:
17284
0
    fminlen = facet; break;
17285
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17286
0
    fmininc = facet; break;
17287
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17288
0
    fminexc = facet; break;
17289
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17290
0
    fmaxlen = facet; break;
17291
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17292
0
    fmaxinc = facet; break;
17293
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17294
0
    fmaxexc = facet; break;
17295
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17296
0
    ftotdig = facet; break;
17297
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17298
0
    ffracdig = facet; break;
17299
0
      default:
17300
0
    break;
17301
0
  }
17302
0
    }
17303
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17304
0
  facet = cur->facet;
17305
0
  switch (facet->type) {
17306
0
      case XML_SCHEMA_FACET_LENGTH:
17307
0
    bflength = facet; break;
17308
0
      case XML_SCHEMA_FACET_MINLENGTH:
17309
0
    bfminlen = facet; break;
17310
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17311
0
    bfmininc = facet; break;
17312
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17313
0
    bfminexc = facet; break;
17314
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17315
0
    bfmaxlen = facet; break;
17316
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17317
0
    bfmaxinc = facet; break;
17318
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17319
0
    bfmaxexc = facet; break;
17320
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17321
0
    bftotdig = facet; break;
17322
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17323
0
    bffracdig = facet; break;
17324
0
      default:
17325
0
    break;
17326
0
  }
17327
0
    }
17328
    /*
17329
    * length and minLength or maxLength (2.2) + (3.2)
17330
    */
17331
0
    if (flength && (fminlen || fmaxlen)) {
17332
0
  FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17333
0
      "either of 'minLength' or 'maxLength' to be specified on "
17334
0
      "the same type definition")
17335
0
    }
17336
    /*
17337
    * Mutual exclusions in the same derivation step.
17338
    */
17339
0
    if ((fmaxinc) && (fmaxexc)) {
17340
  /*
17341
  * SCC "maxInclusive and maxExclusive"
17342
  */
17343
0
  FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17344
0
    }
17345
0
    if ((fmininc) && (fminexc)) {
17346
  /*
17347
  * SCC "minInclusive and minExclusive"
17348
  */
17349
0
  FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17350
0
    }
17351
17352
0
    if (flength && bflength) {
17353
  /*
17354
  * SCC "length valid restriction"
17355
  * The values have to be equal.
17356
  */
17357
0
  res = xmlSchemaCompareValues(flength->val, bflength->val);
17358
0
  if (res == -2)
17359
0
      goto internal_error;
17360
0
  if (res != 0)
17361
0
      xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17362
0
  if ((res != 0) && (bflength->fixed)) {
17363
0
      FACET_RESTR_FIXED_ERR(flength)
17364
0
  }
17365
17366
0
    }
17367
0
    if (fminlen && bfminlen) {
17368
  /*
17369
  * SCC "minLength valid restriction"
17370
  * minLength >= BASE minLength
17371
  */
17372
0
  res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17373
0
  if (res == -2)
17374
0
      goto internal_error;
17375
0
  if (res == -1)
17376
0
      xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17377
0
  if ((res != 0) && (bfminlen->fixed)) {
17378
0
      FACET_RESTR_FIXED_ERR(fminlen)
17379
0
  }
17380
0
    }
17381
0
    if (fmaxlen && bfmaxlen) {
17382
  /*
17383
  * SCC "maxLength valid restriction"
17384
  * maxLength <= BASE minLength
17385
  */
17386
0
  res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17387
0
  if (res == -2)
17388
0
      goto internal_error;
17389
0
  if (res == 1)
17390
0
      xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17391
0
  if ((res != 0) && (bfmaxlen->fixed)) {
17392
0
      FACET_RESTR_FIXED_ERR(fmaxlen)
17393
0
  }
17394
0
    }
17395
    /*
17396
    * SCC "length and minLength or maxLength"
17397
    */
17398
0
    if (! flength)
17399
0
  flength = bflength;
17400
0
    if (flength) {
17401
0
  if (! fminlen)
17402
0
      fminlen = bfminlen;
17403
0
  if (fminlen) {
17404
      /* (1.1) length >= minLength */
17405
0
      res = xmlSchemaCompareValues(flength->val, fminlen->val);
17406
0
      if (res == -2)
17407
0
    goto internal_error;
17408
0
      if (res == -1)
17409
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17410
0
  }
17411
0
  if (! fmaxlen)
17412
0
      fmaxlen = bfmaxlen;
17413
0
  if (fmaxlen) {
17414
      /* (2.1) length <= maxLength */
17415
0
      res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17416
0
      if (res == -2)
17417
0
    goto internal_error;
17418
0
      if (res == 1)
17419
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17420
0
  }
17421
0
    }
17422
0
    if (fmaxinc) {
17423
  /*
17424
  * "maxInclusive"
17425
  */
17426
0
  if (fmininc) {
17427
      /* SCC "maxInclusive >= minInclusive" */
17428
0
      res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17429
0
      if (res == -2)
17430
0
    goto internal_error;
17431
0
      if (res == -1) {
17432
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17433
0
      }
17434
0
  }
17435
  /*
17436
  * SCC "maxInclusive valid restriction"
17437
  */
17438
0
  if (bfmaxinc) {
17439
      /* maxInclusive <= BASE maxInclusive */
17440
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17441
0
      if (res == -2)
17442
0
    goto internal_error;
17443
0
      if (res == 1)
17444
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17445
0
      if ((res != 0) && (bfmaxinc->fixed)) {
17446
0
    FACET_RESTR_FIXED_ERR(fmaxinc)
17447
0
      }
17448
0
  }
17449
0
  if (bfmaxexc) {
17450
      /* maxInclusive < BASE maxExclusive */
17451
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17452
0
      if (res == -2)
17453
0
    goto internal_error;
17454
0
      if (res != -1) {
17455
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17456
0
      }
17457
0
  }
17458
0
  if (bfmininc) {
17459
      /* maxInclusive >= BASE minInclusive */
17460
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17461
0
      if (res == -2)
17462
0
    goto internal_error;
17463
0
      if (res == -1) {
17464
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17465
0
      }
17466
0
  }
17467
0
  if (bfminexc) {
17468
      /* maxInclusive > BASE minExclusive */
17469
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17470
0
      if (res == -2)
17471
0
    goto internal_error;
17472
0
      if (res != 1) {
17473
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17474
0
      }
17475
0
  }
17476
0
    }
17477
0
    if (fmaxexc) {
17478
  /*
17479
  * "maxExclusive >= minExclusive"
17480
  */
17481
0
  if (fminexc) {
17482
0
      res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17483
0
      if (res == -2)
17484
0
    goto internal_error;
17485
0
      if (res == -1) {
17486
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17487
0
      }
17488
0
  }
17489
  /*
17490
  * "maxExclusive valid restriction"
17491
  */
17492
0
  if (bfmaxexc) {
17493
      /* maxExclusive <= BASE maxExclusive */
17494
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17495
0
      if (res == -2)
17496
0
    goto internal_error;
17497
0
      if (res == 1) {
17498
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17499
0
      }
17500
0
      if ((res != 0) && (bfmaxexc->fixed)) {
17501
0
    FACET_RESTR_FIXED_ERR(fmaxexc)
17502
0
      }
17503
0
  }
17504
0
  if (bfmaxinc) {
17505
      /* maxExclusive <= BASE maxInclusive */
17506
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17507
0
      if (res == -2)
17508
0
    goto internal_error;
17509
0
      if (res == 1) {
17510
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17511
0
      }
17512
0
  }
17513
0
  if (bfmininc) {
17514
      /* maxExclusive > BASE minInclusive */
17515
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17516
0
      if (res == -2)
17517
0
    goto internal_error;
17518
0
      if (res != 1) {
17519
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17520
0
      }
17521
0
  }
17522
0
  if (bfminexc) {
17523
      /* maxExclusive > BASE minExclusive */
17524
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17525
0
      if (res == -2)
17526
0
    goto internal_error;
17527
0
      if (res != 1) {
17528
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17529
0
      }
17530
0
  }
17531
0
    }
17532
0
    if (fminexc) {
17533
  /*
17534
  * "minExclusive < maxInclusive"
17535
  */
17536
0
  if (fmaxinc) {
17537
0
      res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17538
0
      if (res == -2)
17539
0
    goto internal_error;
17540
0
      if (res != -1) {
17541
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17542
0
      }
17543
0
  }
17544
  /*
17545
  * "minExclusive valid restriction"
17546
  */
17547
0
  if (bfminexc) {
17548
      /* minExclusive >= BASE minExclusive */
17549
0
      res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17550
0
      if (res == -2)
17551
0
    goto internal_error;
17552
0
      if (res == -1) {
17553
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17554
0
      }
17555
0
      if ((res != 0) && (bfminexc->fixed)) {
17556
0
    FACET_RESTR_FIXED_ERR(fminexc)
17557
0
      }
17558
0
  }
17559
0
  if (bfmaxinc) {
17560
      /* minExclusive <= BASE maxInclusive */
17561
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17562
0
      if (res == -2)
17563
0
    goto internal_error;
17564
0
      if (res == 1) {
17565
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17566
0
      }
17567
0
  }
17568
0
  if (bfmininc) {
17569
      /* minExclusive >= BASE minInclusive */
17570
0
      res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17571
0
      if (res == -2)
17572
0
    goto internal_error;
17573
0
      if (res == -1) {
17574
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17575
0
      }
17576
0
  }
17577
0
  if (bfmaxexc) {
17578
      /* minExclusive < BASE maxExclusive */
17579
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17580
0
      if (res == -2)
17581
0
    goto internal_error;
17582
0
      if (res != -1) {
17583
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17584
0
      }
17585
0
  }
17586
0
    }
17587
0
    if (fmininc) {
17588
  /*
17589
  * "minInclusive < maxExclusive"
17590
  */
17591
0
  if (fmaxexc) {
17592
0
      res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17593
0
      if (res == -2)
17594
0
    goto internal_error;
17595
0
      if (res != -1) {
17596
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17597
0
      }
17598
0
  }
17599
  /*
17600
  * "minExclusive valid restriction"
17601
  */
17602
0
  if (bfmininc) {
17603
      /* minInclusive >= BASE minInclusive */
17604
0
      res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17605
0
      if (res == -2)
17606
0
    goto internal_error;
17607
0
      if (res == -1) {
17608
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17609
0
      }
17610
0
      if ((res != 0) && (bfmininc->fixed)) {
17611
0
    FACET_RESTR_FIXED_ERR(fmininc)
17612
0
      }
17613
0
  }
17614
0
  if (bfmaxinc) {
17615
      /* minInclusive <= BASE maxInclusive */
17616
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17617
0
      if (res == -2)
17618
0
    goto internal_error;
17619
0
      if (res == 1) {
17620
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17621
0
      }
17622
0
  }
17623
0
  if (bfminexc) {
17624
      /* minInclusive > BASE minExclusive */
17625
0
      res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17626
0
      if (res == -2)
17627
0
    goto internal_error;
17628
0
      if (res != 1)
17629
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17630
0
  }
17631
0
  if (bfmaxexc) {
17632
      /* minInclusive < BASE maxExclusive */
17633
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17634
0
      if (res == -2)
17635
0
    goto internal_error;
17636
0
      if (res != -1)
17637
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17638
0
  }
17639
0
    }
17640
0
    if (ftotdig && bftotdig) {
17641
  /*
17642
  * SCC " totalDigits valid restriction"
17643
  * totalDigits <= BASE totalDigits
17644
  */
17645
0
  res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17646
0
  if (res == -2)
17647
0
      goto internal_error;
17648
0
  if (res == 1)
17649
0
      xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17650
0
      -1, 1, 1);
17651
0
  if ((res != 0) && (bftotdig->fixed)) {
17652
0
      FACET_RESTR_FIXED_ERR(ftotdig)
17653
0
  }
17654
0
    }
17655
0
    if (ffracdig && bffracdig) {
17656
  /*
17657
  * SCC  "fractionDigits valid restriction"
17658
  * fractionDigits <= BASE fractionDigits
17659
  */
17660
0
  res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17661
0
  if (res == -2)
17662
0
      goto internal_error;
17663
0
  if (res == 1)
17664
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17665
0
      -1, 1, 1);
17666
0
  if ((res != 0) && (bffracdig->fixed)) {
17667
0
      FACET_RESTR_FIXED_ERR(ffracdig)
17668
0
  }
17669
0
    }
17670
    /*
17671
    * SCC "fractionDigits less than or equal to totalDigits"
17672
    */
17673
0
    if (! ftotdig)
17674
0
  ftotdig = bftotdig;
17675
0
    if (! ffracdig)
17676
0
  ffracdig = bffracdig;
17677
0
    if (ftotdig && ffracdig) {
17678
0
  res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17679
0
  if (res == -2)
17680
0
      goto internal_error;
17681
0
  if (res == 1)
17682
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17683
0
    -1, 1, 0);
17684
0
    }
17685
    /*
17686
    * *Enumerations* won' be added here, since only the first set
17687
    * of enumerations in the ancestor-or-self axis is used
17688
    * for validation, plus we need to use the base type of those
17689
    * enumerations for whitespace.
17690
    *
17691
    * *Patterns*: won't be add here, since they are ORed at
17692
    * type level and ANDed at ancestor level. This will
17693
    * happen during validation by walking the base axis
17694
    * of the type.
17695
    */
17696
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17697
0
  bfacet = cur->facet;
17698
  /*
17699
  * Special handling of enumerations and patterns.
17700
  * TODO: hmm, they should not appear in the set, so remove this.
17701
  */
17702
0
  if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17703
0
      (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17704
0
      continue;
17705
  /*
17706
  * Search for a duplicate facet in the current type.
17707
  */
17708
0
  link = type->facetSet;
17709
  /* err = 0; */
17710
  /* fixedErr = 0; */
17711
0
  while (link != NULL) {
17712
0
      facet = link->facet;
17713
0
      if (facet->type == bfacet->type) {
17714
0
    switch (facet->type) {
17715
0
        case XML_SCHEMA_FACET_WHITESPACE:
17716
      /*
17717
      * The whitespace must be stronger.
17718
      */
17719
0
      if (facet->whitespace < bfacet->whitespace) {
17720
0
          FACET_RESTR_ERR(facet,
17721
0
        "The 'whitespace' value has to be equal to "
17722
0
        "or stronger than the 'whitespace' value of "
17723
0
        "the base type")
17724
0
      }
17725
0
      if ((bfacet->fixed) &&
17726
0
          (facet->whitespace != bfacet->whitespace)) {
17727
0
          FACET_RESTR_FIXED_ERR(facet)
17728
0
      }
17729
0
      break;
17730
0
        default:
17731
0
      break;
17732
0
    }
17733
    /* Duplicate found. */
17734
0
    break;
17735
0
      }
17736
0
      link = link->next;
17737
0
  }
17738
  /*
17739
  * If no duplicate was found: add the base types's facet
17740
  * to the set.
17741
  */
17742
0
  if (link == NULL) {
17743
0
      link = (xmlSchemaFacetLinkPtr)
17744
0
    xmlMalloc(sizeof(xmlSchemaFacetLink));
17745
0
      if (link == NULL) {
17746
0
    xmlSchemaPErrMemory(pctxt);
17747
0
    return (-1);
17748
0
      }
17749
0
      link->facet = cur->facet;
17750
0
      link->next = NULL;
17751
0
      if (last == NULL)
17752
0
    type->facetSet = link;
17753
0
      else
17754
0
    last->next = link;
17755
0
      last = link;
17756
0
  }
17757
17758
0
    }
17759
17760
0
    return (0);
17761
0
internal_error:
17762
0
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17763
0
  "an error occurred");
17764
0
    return (-1);
17765
0
}
17766
17767
static int
17768
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17769
               xmlSchemaTypePtr type)
17770
0
{
17771
0
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17772
    /*
17773
    * The actual value is then formed by replacing any union type
17774
    * definition in the `explicit members` with the members of their
17775
    * {member type definitions}, in order.
17776
    *
17777
    * TODO: There's a bug entry at
17778
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17779
    * which indicates that we'll keep the union types the future.
17780
    */
17781
0
    link = type->memberTypes;
17782
0
    while (link != NULL) {
17783
17784
0
  if (WXS_IS_TYPE_NOT_FIXED(link->type))
17785
0
      xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17786
17787
0
  if (WXS_IS_UNION(link->type)) {
17788
0
      subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17789
0
      if (subLink != NULL) {
17790
0
    link->type = subLink->type;
17791
0
    if (subLink->next != NULL) {
17792
0
        lastLink = link->next;
17793
0
        subLink = subLink->next;
17794
0
        prevLink = link;
17795
0
        while (subLink != NULL) {
17796
0
      newLink = (xmlSchemaTypeLinkPtr)
17797
0
          xmlMalloc(sizeof(xmlSchemaTypeLink));
17798
0
      if (newLink == NULL) {
17799
0
          xmlSchemaPErrMemory(pctxt);
17800
0
          return (-1);
17801
0
      }
17802
0
      newLink->type = subLink->type;
17803
0
      prevLink->next = newLink;
17804
0
      prevLink = newLink;
17805
0
      newLink->next = lastLink;
17806
17807
0
      subLink = subLink->next;
17808
0
        }
17809
0
    }
17810
0
      }
17811
0
  }
17812
0
  link = link->next;
17813
0
    }
17814
0
    return (0);
17815
0
}
17816
17817
static void
17818
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17819
0
{
17820
0
    int has = 0, needVal = 0, normVal = 0;
17821
17822
0
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17823
0
    if (has) {
17824
0
  needVal = (type->baseType->flags &
17825
0
      XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17826
0
  normVal = (type->baseType->flags &
17827
0
      XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17828
0
    }
17829
0
    if (type->facets != NULL) {
17830
0
  xmlSchemaFacetPtr fac;
17831
17832
0
  for (fac = type->facets; fac != NULL; fac = fac->next) {
17833
0
      switch (fac->type) {
17834
0
    case XML_SCHEMA_FACET_WHITESPACE:
17835
0
        break;
17836
0
    case XML_SCHEMA_FACET_PATTERN:
17837
0
        normVal = 1;
17838
0
        has = 1;
17839
0
        break;
17840
0
    case XML_SCHEMA_FACET_ENUMERATION:
17841
0
        needVal = 1;
17842
0
        normVal = 1;
17843
0
        has = 1;
17844
0
        break;
17845
0
    default:
17846
0
        has = 1;
17847
0
        break;
17848
0
      }
17849
0
  }
17850
0
    }
17851
0
    if (normVal)
17852
0
  type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17853
0
    if (needVal)
17854
0
  type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17855
0
    if (has)
17856
0
  type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17857
17858
0
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17859
0
  xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17860
  /*
17861
  * OPTIMIZE VAL TODO: Some facets need a computed value.
17862
  */
17863
0
  if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17864
0
      (prim->builtInType != XML_SCHEMAS_STRING)) {
17865
0
      type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17866
0
  }
17867
0
    }
17868
0
}
17869
17870
static int
17871
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17872
0
{
17873
17874
17875
    /*
17876
    * Evaluate the whitespace-facet value.
17877
    */
17878
0
    if (WXS_IS_LIST(type)) {
17879
0
  type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17880
0
  return (0);
17881
0
    } else if (WXS_IS_UNION(type))
17882
0
  return (0);
17883
17884
0
    if (type->facetSet != NULL) {
17885
0
  xmlSchemaFacetLinkPtr lin;
17886
17887
0
  for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17888
0
      if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17889
0
    switch (lin->facet->whitespace) {
17890
0
    case XML_SCHEMAS_FACET_PRESERVE:
17891
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17892
0
        break;
17893
0
    case XML_SCHEMAS_FACET_REPLACE:
17894
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17895
0
        break;
17896
0
    case XML_SCHEMAS_FACET_COLLAPSE:
17897
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17898
0
        break;
17899
0
    default:
17900
0
        return (-1);
17901
0
    }
17902
0
    return (0);
17903
0
      }
17904
0
  }
17905
0
    }
17906
    /*
17907
    * For all `atomic` datatypes other than string (and types `derived`
17908
    * by `restriction` from it) the value of whiteSpace is fixed to
17909
    * collapse
17910
    */
17911
0
    {
17912
0
  xmlSchemaTypePtr anc;
17913
17914
0
  for (anc = type->baseType; anc != NULL &&
17915
0
    anc->builtInType != XML_SCHEMAS_ANYTYPE;
17916
0
    anc = anc->baseType) {
17917
17918
0
      if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17919
0
    if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17920
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17921
17922
0
    } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17923
0
        (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17924
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17925
17926
0
    } else
17927
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17928
0
    break;
17929
0
      }
17930
0
  }
17931
0
    }
17932
0
    return (0);
17933
0
}
17934
17935
static int
17936
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17937
        xmlSchemaTypePtr type)
17938
0
{
17939
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17940
0
  return(0);
17941
0
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17942
0
  return(0);
17943
0
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17944
17945
0
    if (WXS_IS_LIST(type)) {
17946
  /*
17947
  * Corresponds to <simpleType><list>...
17948
  */
17949
0
  if (type->subtypes == NULL) {
17950
      /*
17951
      * This one is really needed, so get out.
17952
      */
17953
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17954
0
    "list type has no item-type assigned");
17955
0
      return(-1);
17956
0
  }
17957
0
    } else if (WXS_IS_UNION(type)) {
17958
  /*
17959
  * Corresponds to <simpleType><union>...
17960
  */
17961
0
  if (type->memberTypes == NULL) {
17962
      /*
17963
      * This one is really needed, so get out.
17964
      */
17965
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17966
0
    "union type has no member-types assigned");
17967
0
      return(-1);
17968
0
  }
17969
0
    } else {
17970
  /*
17971
  * Corresponds to <simpleType><restriction>...
17972
  */
17973
0
  if (type->baseType == NULL) {
17974
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17975
0
    "type has no base-type assigned");
17976
0
      return(-1);
17977
0
  }
17978
0
  if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17979
0
      if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17980
0
    return(-1);
17981
  /*
17982
  * Variety
17983
  * If the <restriction> alternative is chosen, then the
17984
  * {variety} of the {base type definition}.
17985
  */
17986
0
  if (WXS_IS_ATOMIC(type->baseType))
17987
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17988
0
  else if (WXS_IS_LIST(type->baseType)) {
17989
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17990
      /*
17991
      * Inherit the itemType.
17992
      */
17993
0
      type->subtypes = type->baseType->subtypes;
17994
0
  } else if (WXS_IS_UNION(type->baseType)) {
17995
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17996
      /*
17997
      * NOTE that we won't assign the memberTypes of the base,
17998
      * since this will make trouble when freeing them; we will
17999
      * use a lookup function to access them instead.
18000
      */
18001
0
  }
18002
0
    }
18003
0
    return(0);
18004
0
}
18005
18006
/*
18007
* 3.14.6 Constraints on Simple Type Definition Schema Components
18008
*/
18009
static int
18010
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18011
         xmlSchemaTypePtr type)
18012
0
{
18013
0
    int res, olderrs = pctxt->nberrors;
18014
18015
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18016
0
  return(-1);
18017
18018
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18019
0
  return(0);
18020
18021
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18022
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18023
18024
0
    if (type->baseType == NULL) {
18025
0
  PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18026
0
      "missing baseType");
18027
0
  goto exit_failure;
18028
0
    }
18029
0
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18030
0
  xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18031
    /*
18032
    * If a member type of a union is a union itself, we need to substitute
18033
    * that member type for its member types.
18034
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18035
    * types in WXS 1.1.
18036
    */
18037
0
    if ((type->memberTypes != NULL) &&
18038
0
  (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18039
0
  return(-1);
18040
    /*
18041
    * SPEC src-simple-type 1
18042
    * "The corresponding simple type definition, if any, must satisfy
18043
    * the conditions set out in Constraints on Simple Type Definition
18044
    * Schema Components ($3.14.6)."
18045
    */
18046
    /*
18047
    * Schema Component Constraint: Simple Type Definition Properties Correct
18048
    * (st-props-correct)
18049
    */
18050
0
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18051
0
    HFAILURE HERROR
18052
    /*
18053
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18054
    * (cos-st-restricts)
18055
    */
18056
0
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18057
0
    HFAILURE HERROR
18058
    /*
18059
    * TODO: Removed the error report, since it got annoying to get an
18060
    * extra error report, if anything failed until now.
18061
    * Enable this if needed.
18062
    *
18063
    * xmlSchemaPErr(ctxt, type->node,
18064
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18065
    *    "Simple type '%s' does not satisfy the constraints "
18066
    *    "on simple type definitions.\n",
18067
    *    type->name, NULL);
18068
    */
18069
    /*
18070
    * Schema Component Constraint: Simple Type Restriction (Facets)
18071
    * (st-restrict-facets)
18072
    */
18073
0
    res = xmlSchemaCheckFacetValues(type, pctxt);
18074
0
    HFAILURE HERROR
18075
0
    if ((type->facetSet != NULL) ||
18076
0
  (type->baseType->facetSet != NULL)) {
18077
0
  res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18078
0
  HFAILURE HERROR
18079
0
    }
18080
    /*
18081
    * Whitespace value.
18082
    */
18083
0
    res = xmlSchemaTypeFixupWhitespace(type);
18084
0
    HFAILURE HERROR
18085
0
    xmlSchemaTypeFixupOptimFacets(type);
18086
18087
0
exit_error:
18088
0
    if (olderrs != pctxt->nberrors)
18089
0
  return(pctxt->err);
18090
0
    return(0);
18091
18092
0
exit_failure:
18093
0
    return(-1);
18094
0
}
18095
18096
static int
18097
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18098
        xmlSchemaTypePtr type)
18099
0
{
18100
0
    int res = 0, olderrs = pctxt->nberrors;
18101
0
    xmlSchemaTypePtr baseType = type->baseType;
18102
18103
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18104
0
  return(0);
18105
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18106
0
    if (baseType == NULL) {
18107
0
  PERROR_INT("xmlSchemaFixupComplexType",
18108
0
      "missing baseType");
18109
0
  goto exit_failure;
18110
0
    }
18111
    /*
18112
    * Fixup the base type.
18113
    */
18114
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
18115
0
  xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18116
0
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18117
  /*
18118
  * Skip fixup if the base type is invalid.
18119
  * TODO: Generate a warning!
18120
  */
18121
0
  return(0);
18122
0
    }
18123
    /*
18124
    * This basically checks if the base type can be derived.
18125
    */
18126
0
    res = xmlSchemaCheckSRCCT(pctxt, type);
18127
0
    HFAILURE HERROR
18128
    /*
18129
    * Fixup the content type.
18130
    */
18131
0
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18132
  /*
18133
  * Corresponds to <complexType><simpleContent>...
18134
  */
18135
0
  if ((WXS_IS_COMPLEX(baseType)) &&
18136
0
      (baseType->contentTypeDef != NULL) &&
18137
0
      (WXS_IS_RESTRICTION(type))) {
18138
0
      xmlSchemaTypePtr contentBase, content;
18139
#ifdef ENABLE_NAMED_LOCALS
18140
      char buf[30];
18141
      const xmlChar *tmpname;
18142
#endif
18143
      /*
18144
      * SPEC (1) If <restriction> + base type is <complexType>,
18145
      * "whose own {content type} is a simple type..."
18146
      */
18147
0
      if (type->contentTypeDef != NULL) {
18148
    /*
18149
    * SPEC (1.1) "the simple type definition corresponding to the
18150
    * <simpleType> among the [children] of <restriction> if there
18151
    * is one;"
18152
    * Note that this "<simpleType> among the [children]" was put
18153
    * into ->contentTypeDef during parsing.
18154
    */
18155
0
    contentBase = type->contentTypeDef;
18156
0
    type->contentTypeDef = NULL;
18157
0
      } else {
18158
    /*
18159
    * (1.2) "...otherwise (<restriction> has no <simpleType>
18160
    * among its [children]), the simple type definition which
18161
    * is the {content type} of the ... base type."
18162
    */
18163
0
    contentBase = baseType->contentTypeDef;
18164
0
      }
18165
      /*
18166
      * SPEC
18167
      * "... a simple type definition which restricts the simple
18168
      * type definition identified in clause 1.1 or clause 1.2
18169
      * with a set of facet components"
18170
      *
18171
      * Create the anonymous simple type, which will be the content
18172
      * type of the complex type.
18173
      */
18174
#ifdef ENABLE_NAMED_LOCALS
18175
      snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18176
      tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18177
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18178
    XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18179
    type->node, 0);
18180
#else
18181
0
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18182
0
    XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18183
0
    type->node, 0);
18184
0
#endif
18185
0
      if (content == NULL)
18186
0
    goto exit_failure;
18187
      /*
18188
      * We will use the same node as for the <complexType>
18189
      * to have it somehow anchored in the schema doc.
18190
      */
18191
0
      content->type = XML_SCHEMA_TYPE_SIMPLE;
18192
0
      content->baseType = contentBase;
18193
      /*
18194
      * Move the facets, previously anchored on the
18195
      * complexType during parsing.
18196
      */
18197
0
      content->facets = type->facets;
18198
0
      type->facets = NULL;
18199
0
      content->facetSet = type->facetSet;
18200
0
      type->facetSet = NULL;
18201
18202
0
      type->contentTypeDef = content;
18203
0
      if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18204
0
    xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18205
      /*
18206
      * Fixup the newly created type. We don't need to check
18207
      * for circularity here.
18208
      */
18209
0
      res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18210
0
      HFAILURE HERROR
18211
0
      res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18212
0
      HFAILURE HERROR
18213
18214
0
  } else if ((WXS_IS_COMPLEX(baseType)) &&
18215
0
      (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18216
0
      (WXS_IS_RESTRICTION(type))) {
18217
      /*
18218
      * SPEC (2) If <restriction> + base is a mixed <complexType> with
18219
      * an emptiable particle, then a simple type definition which
18220
      * restricts the <restriction>'s <simpleType> child.
18221
      */
18222
0
      if ((type->contentTypeDef == NULL) ||
18223
0
    (type->contentTypeDef->baseType == NULL)) {
18224
    /*
18225
    * TODO: Check if this ever happens.
18226
    */
18227
0
    xmlSchemaPCustomErr(pctxt,
18228
0
        XML_SCHEMAP_INTERNAL,
18229
0
        WXS_BASIC_CAST type, NULL,
18230
0
        "Internal error: xmlSchemaTypeFixup, "
18231
0
        "complex type '%s': the <simpleContent><restriction> "
18232
0
        "is missing a <simpleType> child, but was not caught "
18233
0
        "by xmlSchemaCheckSRCCT()", type->name);
18234
0
    goto exit_failure;
18235
0
      }
18236
0
  } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18237
      /*
18238
      * SPEC (3) If <extension> + base is <complexType> with
18239
      * <simpleType> content, "...then the {content type} of that
18240
      * complex type definition"
18241
      */
18242
0
      if (baseType->contentTypeDef == NULL) {
18243
    /*
18244
    * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18245
    * should have caught this already.
18246
    */
18247
0
    xmlSchemaPCustomErr(pctxt,
18248
0
        XML_SCHEMAP_INTERNAL,
18249
0
        WXS_BASIC_CAST type, NULL,
18250
0
        "Internal error: xmlSchemaTypeFixup, "
18251
0
        "complex type '%s': the <extension>ed base type is "
18252
0
        "a complex type with no simple content type",
18253
0
        type->name);
18254
0
    goto exit_failure;
18255
0
      }
18256
0
      type->contentTypeDef = baseType->contentTypeDef;
18257
0
  } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18258
      /*
18259
      * SPEC (4) <extension> + base is <simpleType>
18260
      * "... then that simple type definition"
18261
      */
18262
0
      type->contentTypeDef = baseType;
18263
0
  } else {
18264
      /*
18265
      * TODO: Check if this ever happens.
18266
      */
18267
0
      xmlSchemaPCustomErr(pctxt,
18268
0
    XML_SCHEMAP_INTERNAL,
18269
0
    WXS_BASIC_CAST type, NULL,
18270
0
    "Internal error: xmlSchemaTypeFixup, "
18271
0
    "complex type '%s' with <simpleContent>: unhandled "
18272
0
    "derivation case", type->name);
18273
0
      goto exit_failure;
18274
0
  }
18275
0
    } else {
18276
0
  int dummySequence = 0;
18277
0
  xmlSchemaParticlePtr particle =
18278
0
      (xmlSchemaParticlePtr) type->subtypes;
18279
  /*
18280
  * Corresponds to <complexType><complexContent>...
18281
  *
18282
  * NOTE that the effective mixed was already set during parsing of
18283
  * <complexType> and <complexContent>; its flag value is
18284
  * XML_SCHEMAS_TYPE_MIXED.
18285
  *
18286
  * Compute the "effective content":
18287
  * (2.1.1) + (2.1.2) + (2.1.3)
18288
  */
18289
0
  if ((particle == NULL) ||
18290
0
      ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18291
0
      ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18292
0
      (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18293
0
      ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18294
0
      (particle->minOccurs == 0))) &&
18295
0
      ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18296
0
      if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18297
    /*
18298
    * SPEC (2.1.4) "If the `effective mixed` is true, then
18299
    * a particle whose properties are as follows:..."
18300
    *
18301
    * Empty sequence model group with
18302
    * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18303
    * NOTE that we sill assign it the <complexType> node to
18304
    * somehow anchor it in the doc.
18305
    */
18306
0
    if ((particle == NULL) ||
18307
0
        (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18308
        /*
18309
        * Create the particle.
18310
        */
18311
0
        particle = xmlSchemaAddParticle(pctxt,
18312
0
      type->node, 1, 1);
18313
0
        if (particle == NULL)
18314
0
      goto exit_failure;
18315
        /*
18316
        * Create the model group.
18317
        */ /* URGENT TODO: avoid adding to pending items. */
18318
0
        particle->children = (xmlSchemaTreeItemPtr)
18319
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18320
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18321
0
        if (particle->children == NULL)
18322
0
      goto exit_failure;
18323
18324
0
        type->subtypes = (xmlSchemaTypePtr) particle;
18325
0
    }
18326
0
    dummySequence = 1;
18327
0
    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18328
0
      } else {
18329
    /*
18330
    * SPEC (2.1.5) "otherwise empty"
18331
    */
18332
0
    type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18333
0
      }
18334
0
  } else {
18335
      /*
18336
      * SPEC (2.2) "otherwise the particle corresponding to the
18337
      * <all>, <choice>, <group> or <sequence> among the
18338
      * [children]."
18339
      */
18340
0
      type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18341
0
  }
18342
  /*
18343
  * Compute the "content type".
18344
  */
18345
0
  if (WXS_IS_RESTRICTION(type)) {
18346
      /*
18347
      * SPEC (3.1) "If <restriction>..."
18348
      * (3.1.1) + (3.1.2) */
18349
0
      if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18350
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18351
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18352
0
      }
18353
0
  } else {
18354
      /*
18355
      * SPEC (3.2) "If <extension>..."
18356
      */
18357
0
      if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18358
    /*
18359
    * SPEC (3.2.1)
18360
    * "If the `effective content` is empty, then the
18361
    *  {content type} of the [...] base ..."
18362
    */
18363
0
    type->contentType = baseType->contentType;
18364
0
    type->subtypes = baseType->subtypes;
18365
    /*
18366
    * Fixes bug #347316:
18367
    * This is the case when the base type has a simple
18368
    * type definition as content.
18369
    */
18370
0
    type->contentTypeDef = baseType->contentTypeDef;
18371
    /*
18372
    * NOTE that the effective mixed is ignored here.
18373
    */
18374
0
      } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18375
    /*
18376
    * SPEC (3.2.2)
18377
    */
18378
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18379
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18380
0
      } else {
18381
    /*
18382
    * SPEC (3.2.3)
18383
    */
18384
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18385
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18386
        /*
18387
        * "A model group whose {compositor} is sequence and whose
18388
        * {particles} are..."
18389
        */
18390
0
    if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18391
0
        (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18392
0
        ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18393
0
      XML_SCHEMA_TYPE_ALL))
18394
0
    {
18395
        /*
18396
        * SPEC cos-all-limited (1)
18397
        */
18398
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18399
      /* TODO: error code */
18400
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18401
0
      WXS_ITEM_NODE(type), NULL,
18402
0
      "The type has an 'all' model group in its "
18403
0
      "{content type} and thus cannot be derived from "
18404
0
      "a non-empty type, since this would produce a "
18405
0
      "'sequence' model group containing the 'all' "
18406
0
      "model group; 'all' model groups are not "
18407
0
      "allowed to appear inside other model groups",
18408
0
      NULL, NULL);
18409
18410
0
    } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18411
0
        (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18412
0
        ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18413
0
      XML_SCHEMA_TYPE_ALL))
18414
0
    {
18415
        /*
18416
        * SPEC cos-all-limited (1)
18417
        */
18418
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18419
      /* TODO: error code */
18420
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18421
0
      WXS_ITEM_NODE(type), NULL,
18422
0
      "A type cannot be derived by extension from a type "
18423
0
      "which has an 'all' model group in its "
18424
0
      "{content type}, since this would produce a "
18425
0
      "'sequence' model group containing the 'all' "
18426
0
      "model group; 'all' model groups are not "
18427
0
      "allowed to appear inside other model groups",
18428
0
      NULL, NULL);
18429
18430
0
    } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
18431
0
        xmlSchemaTreeItemPtr effectiveContent =
18432
0
      (xmlSchemaTreeItemPtr) type->subtypes;
18433
        /*
18434
        * Create the particle.
18435
        */
18436
0
        particle = xmlSchemaAddParticle(pctxt,
18437
0
      type->node, 1, 1);
18438
0
        if (particle == NULL)
18439
0
      goto exit_failure;
18440
        /*
18441
        * Create the "sequence" model group.
18442
        */
18443
0
        particle->children = (xmlSchemaTreeItemPtr)
18444
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18445
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18446
0
        if (particle->children == NULL)
18447
0
      goto exit_failure;
18448
0
        WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18449
        /*
18450
        * SPEC "the particle of the {content type} of
18451
        * the ... base ..."
18452
        * Create a duplicate of the base type's particle
18453
        * and assign its "term" to it.
18454
        */
18455
0
        particle->children->children =
18456
0
      (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18457
0
      type->node,
18458
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18459
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18460
0
        if (particle->children->children == NULL)
18461
0
      goto exit_failure;
18462
0
        particle = (xmlSchemaParticlePtr)
18463
0
      particle->children->children;
18464
0
        particle->children =
18465
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18466
        /*
18467
        * SPEC "followed by the `effective content`."
18468
        */
18469
0
        particle->next = effectiveContent;
18470
        /*
18471
        * This all will result in:
18472
        * new-particle
18473
        *   --> new-sequence(
18474
        *         new-particle
18475
        *           --> base-model,
18476
        *         this-particle
18477
        *         --> this-model
18478
        *     )
18479
        */
18480
0
    } else {
18481
        /*
18482
        * This is the case when there is already an empty
18483
        * <sequence> with minOccurs==maxOccurs==1.
18484
        * Just add the base types's content type.
18485
        * NOTE that, although we miss to add an intermediate
18486
        * <sequence>, this should produce no difference to
18487
        * neither the regex compilation of the content model,
18488
        * nor to the complex type constraints.
18489
        */
18490
0
        particle->children->children =
18491
0
      (xmlSchemaTreeItemPtr) baseType->subtypes;
18492
0
    }
18493
0
      }
18494
0
  }
18495
0
    }
18496
    /*
18497
    * Now fixup attribute uses:
18498
    *   - expand attr. group references
18499
    *     - intersect attribute wildcards
18500
    *   - inherit attribute uses of the base type
18501
    *   - inherit or union attr. wildcards if extending
18502
    *   - apply attr. use prohibitions if restricting
18503
    */
18504
0
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18505
0
    HFAILURE HERROR
18506
    /*
18507
    * Apply the complex type component constraints; this will not
18508
    * check attributes, since this is done in
18509
    * xmlSchemaFixupTypeAttributeUses().
18510
    */
18511
0
    res = xmlSchemaCheckCTComponent(pctxt, type);
18512
0
    HFAILURE HERROR
18513
18514
0
    if (olderrs != pctxt->nberrors)
18515
0
  return(pctxt->err);
18516
0
    else
18517
0
  return(0);
18518
18519
0
exit_error:
18520
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18521
0
    return(pctxt->err);
18522
18523
0
exit_failure:
18524
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18525
0
    return(-1);
18526
0
}
18527
18528
18529
/**
18530
 * xmlSchemaTypeFixup:
18531
 * @typeDecl:  the schema type definition
18532
 * @ctxt:  the schema parser context
18533
 *
18534
 * Fixes the content model of the type.
18535
 * URGENT TODO: We need an int result!
18536
 */
18537
static int
18538
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18539
                   xmlSchemaAbstractCtxtPtr actxt)
18540
0
{
18541
0
    if (type == NULL)
18542
0
        return(0);
18543
0
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18544
0
  AERROR_INT("xmlSchemaTypeFixup",
18545
0
      "this function needs a parser context");
18546
0
  return(-1);
18547
0
    }
18548
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18549
0
  return(0);
18550
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18551
0
  return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18552
0
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18553
0
  return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18554
0
    return(0);
18555
0
}
18556
18557
/**
18558
 * xmlSchemaCheckFacet:
18559
 * @facet:  the facet
18560
 * @typeDecl:  the schema type definition
18561
 * @pctxt:  the schema parser context or NULL
18562
 * @name: the optional name of the type
18563
 *
18564
 * Checks and computes the values of facets.
18565
 *
18566
 * Returns 0 if valid, a positive error code if not valid and
18567
 *         -1 in case of an internal or API error.
18568
 */
18569
int
18570
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18571
                    xmlSchemaTypePtr typeDecl,
18572
                    xmlSchemaParserCtxtPtr pctxt,
18573
        const xmlChar * name ATTRIBUTE_UNUSED)
18574
0
{
18575
0
    int ret = 0, ctxtGiven;
18576
18577
0
    if ((facet == NULL) || (typeDecl == NULL))
18578
0
        return(-1);
18579
    /*
18580
    * TODO: will the parser context be given if used from
18581
    * the relaxNG module?
18582
    */
18583
0
    if (pctxt == NULL)
18584
0
  ctxtGiven = 0;
18585
0
    else
18586
0
  ctxtGiven = 1;
18587
18588
0
    switch (facet->type) {
18589
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
18590
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
18591
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
18592
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18593
0
  case XML_SCHEMA_FACET_ENUMERATION: {
18594
                /*
18595
                 * Okay we need to validate the value
18596
                 * at that point.
18597
                 */
18598
0
    xmlSchemaTypePtr base;
18599
18600
    /* 4.3.5.5 Constraints on enumeration Schema Components
18601
    * Schema Component Constraint: enumeration valid restriction
18602
    * It is an `error` if any member of {value} is not in the
18603
    * `value space` of {base type definition}.
18604
    *
18605
    * minInclusive, maxInclusive, minExclusive, maxExclusive:
18606
    * The value `must` be in the
18607
    * `value space` of the `base type`.
18608
    */
18609
    /*
18610
    * This function is intended to deliver a compiled value
18611
    * on the facet. In this implementation of XML Schemata the
18612
    * type holding a facet, won't be a built-in type.
18613
    * Thus to ensure that other API
18614
    * calls (relaxng) do work, if the given type is a built-in
18615
    * type, we will assume that the given built-in type *is
18616
    * already* the base type.
18617
    */
18618
0
    if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18619
0
        base = typeDecl->baseType;
18620
0
        if (base == NULL) {
18621
0
      PERROR_INT("xmlSchemaCheckFacet",
18622
0
          "a type user derived type has no base type");
18623
0
      return (-1);
18624
0
        }
18625
0
    } else
18626
0
        base = typeDecl;
18627
18628
0
    if (! ctxtGiven) {
18629
        /*
18630
        * A context is needed if called from RelaxNG.
18631
        */
18632
0
        pctxt = xmlSchemaNewParserCtxt("*");
18633
0
        if (pctxt == NULL)
18634
0
      return (-1);
18635
0
    }
18636
    /*
18637
    * NOTE: This call does not check the content nodes,
18638
    * since they are not available:
18639
    * facet->node is just the node holding the facet
18640
    * definition, *not* the attribute holding the *value*
18641
    * of the facet.
18642
    */
18643
0
    ret = xmlSchemaVCheckCVCSimpleType(
18644
0
        ACTXT_CAST pctxt, facet->node, base,
18645
0
        facet->value, &(facet->val), 1, 1, 0);
18646
0
                if (ret != 0) {
18647
0
        if (ret < 0) {
18648
      /* No error message for RelaxNG. */
18649
0
      if (ctxtGiven) {
18650
0
          xmlSchemaCustomErr(ACTXT_CAST pctxt,
18651
0
        XML_SCHEMAP_INTERNAL, facet->node, NULL,
18652
0
        "Internal error: xmlSchemaCheckFacet, "
18653
0
        "failed to validate the value '%s' of the "
18654
0
        "facet '%s' against the base type",
18655
0
        facet->value, xmlSchemaFacetTypeToString(facet->type));
18656
0
      }
18657
0
      goto internal_error;
18658
0
        }
18659
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18660
        /* No error message for RelaxNG. */
18661
0
        if (ctxtGiven) {
18662
0
      xmlChar *str = NULL;
18663
18664
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18665
0
          ret, facet->node, WXS_BASIC_CAST facet,
18666
0
          "The value '%s' of the facet does not validate "
18667
0
          "against the base type '%s'",
18668
0
          facet->value,
18669
0
          xmlSchemaFormatQName(&str,
18670
0
        base->targetNamespace, base->name));
18671
0
      FREE_AND_NULL(str);
18672
0
        }
18673
0
        goto exit;
18674
0
                } else if (facet->val == NULL) {
18675
0
        if (ctxtGiven) {
18676
0
      PERROR_INT("xmlSchemaCheckFacet",
18677
0
          "value was not computed");
18678
0
        }
18679
        /* TODO */
18680
0
    }
18681
0
                break;
18682
0
            }
18683
0
        case XML_SCHEMA_FACET_PATTERN:
18684
0
            facet->regexp = xmlRegexpCompile(facet->value);
18685
0
            if (facet->regexp == NULL) {
18686
0
    ret = XML_SCHEMAP_REGEXP_INVALID;
18687
    /* No error message for RelaxNG. */
18688
0
    if (ctxtGiven) {
18689
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18690
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18691
0
      "The value '%s' of the facet 'pattern' is not a "
18692
0
      "valid regular expression",
18693
0
      facet->value, NULL);
18694
0
    }
18695
0
            }
18696
0
            break;
18697
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
18698
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
18699
0
        case XML_SCHEMA_FACET_LENGTH:
18700
0
        case XML_SCHEMA_FACET_MAXLENGTH:
18701
0
        case XML_SCHEMA_FACET_MINLENGTH:
18702
18703
0
      if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18704
0
    ret = xmlSchemaValidatePredefinedType(
18705
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18706
0
        facet->value, &(facet->val));
18707
0
      } else {
18708
0
    ret = xmlSchemaValidatePredefinedType(
18709
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18710
0
        facet->value, &(facet->val));
18711
0
      }
18712
0
      if (ret != 0) {
18713
0
    if (ret < 0) {
18714
        /* No error message for RelaxNG. */
18715
0
        if (ctxtGiven) {
18716
0
      PERROR_INT("xmlSchemaCheckFacet",
18717
0
          "validating facet value");
18718
0
        }
18719
0
        goto internal_error;
18720
0
    }
18721
0
    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18722
    /* No error message for RelaxNG. */
18723
0
    if (ctxtGiven) {
18724
        /* error code */
18725
0
        xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18726
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18727
0
      "The value '%s' of the facet '%s' is not a valid '%s'",
18728
0
      facet->value,
18729
0
      xmlSchemaFacetTypeToString(facet->type),
18730
0
      (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18731
0
          BAD_CAST "nonNegativeInteger" :
18732
0
          BAD_CAST "positiveInteger",
18733
0
      NULL);
18734
0
    }
18735
0
      }
18736
0
      break;
18737
18738
0
        case XML_SCHEMA_FACET_WHITESPACE:{
18739
0
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18740
0
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18741
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18742
0
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18743
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18744
0
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18745
0
                } else {
18746
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18747
                    /* No error message for RelaxNG. */
18748
0
        if (ctxtGiven) {
18749
      /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18750
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18751
0
          ret, facet->node, WXS_BASIC_CAST typeDecl,
18752
0
          "The value '%s' of the facet 'whitespace' is not "
18753
0
          "valid", facet->value, NULL);
18754
0
                    }
18755
0
                }
18756
0
            }
18757
0
        default:
18758
0
            break;
18759
0
    }
18760
0
exit:
18761
0
    if ((! ctxtGiven) && (pctxt != NULL))
18762
0
  xmlSchemaFreeParserCtxt(pctxt);
18763
0
    return (ret);
18764
0
internal_error:
18765
0
    if ((! ctxtGiven) && (pctxt != NULL))
18766
0
  xmlSchemaFreeParserCtxt(pctxt);
18767
0
    return (-1);
18768
0
}
18769
18770
/**
18771
 * xmlSchemaCheckFacetValues:
18772
 * @typeDecl:  the schema type definition
18773
 * @ctxt:  the schema parser context
18774
 *
18775
 * Checks the default values types, especially for facets
18776
 */
18777
static int
18778
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18779
        xmlSchemaParserCtxtPtr pctxt)
18780
0
{
18781
0
    int res, olderrs = pctxt->nberrors;
18782
0
    const xmlChar *name = typeDecl->name;
18783
    /*
18784
    * NOTE: It is intended to use the facets list, instead
18785
    * of facetSet.
18786
    */
18787
0
    if (typeDecl->facets != NULL) {
18788
0
  xmlSchemaFacetPtr facet = typeDecl->facets;
18789
18790
  /*
18791
  * Temporarily assign the "schema" to the validation context
18792
  * of the parser context. This is needed for NOTATION validation.
18793
  */
18794
0
  if (pctxt->vctxt == NULL) {
18795
0
      if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18796
0
    return(-1);
18797
0
  }
18798
0
  pctxt->vctxt->schema = pctxt->schema;
18799
0
  while (facet != NULL) {
18800
0
      res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18801
0
      HFAILURE
18802
0
      facet = facet->next;
18803
0
  }
18804
0
  pctxt->vctxt->schema = NULL;
18805
0
    }
18806
0
    if (olderrs != pctxt->nberrors)
18807
0
  return(pctxt->err);
18808
0
    return(0);
18809
0
exit_failure:
18810
0
    return(-1);
18811
0
}
18812
18813
/**
18814
 * xmlSchemaGetCircModelGrDefRef:
18815
 * @ctxtMGroup: the searched model group
18816
 * @selfMGroup: the second searched model group
18817
 * @particle: the first particle
18818
 *
18819
 * This one is intended to be used by
18820
 * xmlSchemaCheckGroupDefCircular only.
18821
 *
18822
 * Returns the particle with the circular model group definition reference,
18823
 * otherwise NULL.
18824
 */
18825
static xmlSchemaTreeItemPtr
18826
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18827
            xmlSchemaTreeItemPtr particle)
18828
0
{
18829
0
    xmlSchemaTreeItemPtr circ = NULL;
18830
0
    xmlSchemaTreeItemPtr term;
18831
0
    xmlSchemaModelGroupDefPtr gdef;
18832
18833
0
    for (; particle != NULL; particle = particle->next) {
18834
0
  term = particle->children;
18835
0
  if (term == NULL)
18836
0
      continue;
18837
0
  switch (term->type) {
18838
0
      case XML_SCHEMA_TYPE_GROUP:
18839
0
    gdef = (xmlSchemaModelGroupDefPtr) term;
18840
0
    if (gdef == groupDef)
18841
0
        return (particle);
18842
    /*
18843
    * Mark this model group definition to avoid infinite
18844
    * recursion on circular references not yet examined.
18845
    */
18846
0
    if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18847
0
        continue;
18848
0
    if (gdef->children != NULL) {
18849
0
        gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18850
0
        circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18851
0
      gdef->children->children);
18852
0
        gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18853
0
        if (circ != NULL)
18854
0
      return (circ);
18855
0
    }
18856
0
    break;
18857
0
      case XML_SCHEMA_TYPE_SEQUENCE:
18858
0
      case XML_SCHEMA_TYPE_CHOICE:
18859
0
      case XML_SCHEMA_TYPE_ALL:
18860
0
    circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18861
0
    if (circ != NULL)
18862
0
        return (circ);
18863
0
    break;
18864
0
      default:
18865
0
    break;
18866
0
  }
18867
0
    }
18868
0
    return (NULL);
18869
0
}
18870
18871
/**
18872
 * xmlSchemaCheckGroupDefCircular:
18873
 * @item:  the model group definition
18874
 * @ctxt:  the parser context
18875
 * @name:  the name
18876
 *
18877
 * Checks for circular references to model group definitions.
18878
 */
18879
static void
18880
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18881
             xmlSchemaParserCtxtPtr ctxt)
18882
0
{
18883
    /*
18884
    * Schema Component Constraint: Model Group Correct
18885
    * 2 Circular groups are disallowed. That is, within the {particles}
18886
    * of a group there must not be at any depth a particle whose {term}
18887
    * is the group itself.
18888
    */
18889
0
    if ((item == NULL) ||
18890
0
  (item->type != XML_SCHEMA_TYPE_GROUP) ||
18891
0
  (item->children == NULL))
18892
0
  return;
18893
0
    {
18894
0
  xmlSchemaTreeItemPtr circ;
18895
18896
0
  circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18897
0
  if (circ != NULL) {
18898
0
      xmlChar *str = NULL;
18899
      /*
18900
      * TODO: The error report is not adequate: this constraint
18901
      * is defined for model groups but not definitions, but since
18902
      * there cannot be any circular model groups without a model group
18903
      * definition (if not using a construction API), we check those
18904
      * definitions only.
18905
      */
18906
0
      xmlSchemaPCustomErr(ctxt,
18907
0
    XML_SCHEMAP_MG_PROPS_CORRECT_2,
18908
0
    NULL, WXS_ITEM_NODE(circ),
18909
0
    "Circular reference to the model group definition '%s' "
18910
0
    "defined", xmlSchemaFormatQName(&str,
18911
0
        item->targetNamespace, item->name));
18912
0
      FREE_AND_NULL(str)
18913
      /*
18914
      * NOTE: We will cut the reference to avoid further
18915
      * confusion of the processor. This is a fatal error.
18916
      */
18917
0
      circ->children = NULL;
18918
0
  }
18919
0
    }
18920
0
}
18921
18922
/**
18923
 * xmlSchemaModelGroupToModelGroupDefFixup:
18924
 * @ctxt:  the parser context
18925
 * @mg:  the model group
18926
 *
18927
 * Assigns the model group of model group definitions to the "term"
18928
 * of the referencing particle.
18929
 * In xmlSchemaResolveModelGroupParticleReferences the model group
18930
 * definitions were assigned to the "term", since needed for the
18931
 * circularity check.
18932
 *
18933
 * Schema Component Constraint:
18934
 *     All Group Limited (cos-all-limited) (1.2)
18935
 */
18936
static void
18937
xmlSchemaModelGroupToModelGroupDefFixup(
18938
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18939
    xmlSchemaModelGroupPtr mg)
18940
0
{
18941
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18942
18943
0
    while (particle != NULL) {
18944
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18945
0
      ((WXS_PARTICLE_TERM(particle))->type !=
18946
0
    XML_SCHEMA_TYPE_GROUP))
18947
0
  {
18948
0
      particle = WXS_PTC_CAST particle->next;
18949
0
      continue;
18950
0
  }
18951
0
  if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18952
      /*
18953
      * TODO: Remove the particle.
18954
      */
18955
0
      WXS_PARTICLE_TERM(particle) = NULL;
18956
0
      particle = WXS_PTC_CAST particle->next;
18957
0
      continue;
18958
0
  }
18959
  /*
18960
  * Assign the model group to the {term} of the particle.
18961
  */
18962
0
  WXS_PARTICLE_TERM(particle) =
18963
0
      WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18964
18965
0
  particle = WXS_PTC_CAST particle->next;
18966
0
    }
18967
0
}
18968
18969
/**
18970
 * xmlSchemaCheckAttrGroupCircularRecur:
18971
 * @ctxtGr: the searched attribute group
18972
 * @attr: the current attribute list to be processed
18973
 *
18974
 * This one is intended to be used by
18975
 * xmlSchemaCheckAttrGroupCircular only.
18976
 *
18977
 * Returns the circular attribute group reference, otherwise NULL.
18978
 */
18979
static xmlSchemaQNameRefPtr
18980
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
18981
             xmlSchemaItemListPtr list)
18982
0
{
18983
0
    xmlSchemaAttributeGroupPtr gr;
18984
0
    xmlSchemaQNameRefPtr ref, circ;
18985
0
    int i;
18986
    /*
18987
    * We will search for an attribute group reference which
18988
    * references the context attribute group.
18989
    */
18990
0
    for (i = 0; i < list->nbItems; i++) {
18991
0
  ref = list->items[i];
18992
0
  if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18993
0
      (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
18994
0
      (ref->item != NULL))
18995
0
  {
18996
0
      gr = WXS_ATTR_GROUP_CAST ref->item;
18997
0
      if (gr == ctxtGr)
18998
0
    return(ref);
18999
0
      if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19000
0
    continue;
19001
      /*
19002
      * Mark as visited to avoid infinite recursion on
19003
      * circular references not yet examined.
19004
      */
19005
0
      if ((gr->attrUses) &&
19006
0
    (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19007
0
      {
19008
0
    gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19009
0
    circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19010
0
        (xmlSchemaItemListPtr) gr->attrUses);
19011
0
    gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19012
0
    if (circ != NULL)
19013
0
        return (circ);
19014
0
      }
19015
19016
0
  }
19017
0
    }
19018
0
    return (NULL);
19019
0
}
19020
19021
/**
19022
 * xmlSchemaCheckAttrGroupCircular:
19023
 * attrGr:  the attribute group definition
19024
 * @ctxt:  the parser context
19025
 * @name:  the name
19026
 *
19027
 * Checks for circular references of attribute groups.
19028
 */
19029
static int
19030
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19031
        xmlSchemaParserCtxtPtr ctxt)
19032
0
{
19033
    /*
19034
    * Schema Representation Constraint:
19035
    * Attribute Group Definition Representation OK
19036
    * 3 Circular group reference is disallowed outside <redefine>.
19037
    * That is, unless this element information item's parent is
19038
    * <redefine>, then among the [children], if any, there must
19039
    * not be an <attributeGroup> with ref [attribute] which resolves
19040
    * to the component corresponding to this <attributeGroup>. Indirect
19041
    * circularity is also ruled out. That is, when QName resolution
19042
    * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19043
    * any <attributeGroup>s with a ref [attribute] among the [children],
19044
    * it must not be the case that a `QName` is encountered at any depth
19045
    * which resolves to the component corresponding to this <attributeGroup>.
19046
    */
19047
0
    if (attrGr->attrUses == NULL)
19048
0
  return(0);
19049
0
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19050
0
  return(0);
19051
0
    else {
19052
0
  xmlSchemaQNameRefPtr circ;
19053
19054
0
  circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19055
0
      (xmlSchemaItemListPtr) attrGr->attrUses);
19056
0
  if (circ != NULL) {
19057
0
      xmlChar *str = NULL;
19058
      /*
19059
      * TODO: Report the referenced attr group as QName.
19060
      */
19061
0
      xmlSchemaPCustomErr(ctxt,
19062
0
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19063
0
    NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19064
0
    "Circular reference to the attribute group '%s' "
19065
0
    "defined", xmlSchemaGetComponentQName(&str, attrGr));
19066
0
      FREE_AND_NULL(str);
19067
      /*
19068
      * NOTE: We will cut the reference to avoid further
19069
      * confusion of the processor.
19070
      * BADSPEC TODO: The spec should define how to process in this case.
19071
      */
19072
0
      circ->item = NULL;
19073
0
      return(ctxt->err);
19074
0
  }
19075
0
    }
19076
0
    return(0);
19077
0
}
19078
19079
static int
19080
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19081
          xmlSchemaAttributeGroupPtr attrGr);
19082
19083
/**
19084
 * xmlSchemaExpandAttributeGroupRefs:
19085
 * @pctxt: the parser context
19086
 * @node: the node of the component holding the attribute uses
19087
 * @completeWild: the intersected wildcard to be returned
19088
 * @list: the attribute uses
19089
 *
19090
 * Substitutes contained attribute group references
19091
 * for their attribute uses. Wildcards are intersected.
19092
 * Attribute use prohibitions are removed from the list
19093
 * and returned via the @prohibs list.
19094
 * Pointlessness of attr. prohibs, if a matching attr. decl
19095
 * is existent a well, are checked.
19096
 */
19097
static int
19098
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19099
          xmlSchemaBasicItemPtr item,
19100
          xmlSchemaWildcardPtr *completeWild,
19101
          xmlSchemaItemListPtr list,
19102
          xmlSchemaItemListPtr prohibs)
19103
0
{
19104
0
    xmlSchemaAttributeGroupPtr gr;
19105
0
    xmlSchemaAttributeUsePtr use;
19106
0
    xmlSchemaItemListPtr sublist;
19107
0
    int i, j;
19108
0
    int created = (*completeWild == NULL) ? 0 : 1;
19109
19110
0
    if (prohibs)
19111
0
  prohibs->nbItems = 0;
19112
19113
0
    for (i = 0; i < list->nbItems; i++) {
19114
0
  use = list->items[i];
19115
19116
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19117
0
      if (prohibs == NULL) {
19118
0
    PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19119
0
        "unexpected attr prohibition found");
19120
0
    return(-1);
19121
0
      }
19122
      /*
19123
      * Remove from attribute uses.
19124
      */
19125
0
      if (xmlSchemaItemListRemove(list, i) == -1)
19126
0
    return(-1);
19127
0
      i--;
19128
      /*
19129
      * Note that duplicate prohibitions were already
19130
      * handled at parsing time.
19131
      */
19132
      /*
19133
      * Add to list of prohibitions.
19134
      */
19135
0
      xmlSchemaItemListAddSize(prohibs, 2, use);
19136
0
      continue;
19137
0
  }
19138
0
  if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19139
0
      ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19140
0
  {
19141
0
      if ((WXS_QNAME_CAST use)->item == NULL)
19142
0
    return(-1);
19143
0
      gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19144
      /*
19145
      * Expand the referenced attr. group.
19146
      * TODO: remove this, this is done in a previous step, so
19147
      * already done here.
19148
      */
19149
0
      if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19150
0
    if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19151
0
        return(-1);
19152
0
      }
19153
      /*
19154
      * Build the 'complete' wildcard; i.e. intersect multiple
19155
      * wildcards.
19156
      */
19157
0
      if (gr->attributeWildcard != NULL) {
19158
0
    if (*completeWild == NULL) {
19159
0
        *completeWild = gr->attributeWildcard;
19160
0
    } else {
19161
0
        if (! created) {
19162
0
      xmlSchemaWildcardPtr tmpWild;
19163
19164
       /*
19165
      * Copy the first encountered wildcard as context,
19166
      * except for the annotation.
19167
      *
19168
      * Although the complete wildcard might not correspond
19169
      * to any node in the schema, we will anchor it on
19170
      * the node of the owner component.
19171
      */
19172
0
      tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19173
0
          XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19174
0
          WXS_ITEM_NODE(item));
19175
0
      if (tmpWild == NULL)
19176
0
          return(-1);
19177
0
      if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19178
0
          tmpWild, *completeWild) == -1)
19179
0
          return (-1);
19180
0
      tmpWild->processContents = (*completeWild)->processContents;
19181
0
      *completeWild = tmpWild;
19182
0
      created = 1;
19183
0
        }
19184
19185
0
        if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19186
0
      gr->attributeWildcard) == -1)
19187
0
      return(-1);
19188
0
    }
19189
0
      }
19190
      /*
19191
      * Just remove the reference if the referenced group does not
19192
      * contain any attribute uses.
19193
      */
19194
0
      sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19195
0
      if ((sublist == NULL) || sublist->nbItems == 0) {
19196
0
    if (xmlSchemaItemListRemove(list, i) == -1)
19197
0
        return(-1);
19198
0
    i--;
19199
0
    continue;
19200
0
      }
19201
      /*
19202
      * Add the attribute uses.
19203
      */
19204
0
      list->items[i] = sublist->items[0];
19205
0
      if (sublist->nbItems != 1) {
19206
0
    for (j = 1; j < sublist->nbItems; j++) {
19207
0
        i++;
19208
0
        if (xmlSchemaItemListInsert(list,
19209
0
          sublist->items[j], i) == -1)
19210
0
      return(-1);
19211
0
    }
19212
0
      }
19213
0
  }
19214
19215
0
    }
19216
    /*
19217
    * Handle pointless prohibitions of declared attributes.
19218
    */
19219
0
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19220
0
  xmlSchemaAttributeUseProhibPtr prohib;
19221
19222
0
  for (i = prohibs->nbItems -1; i >= 0; i--) {
19223
0
      prohib = prohibs->items[i];
19224
0
      for (j = 0; j < list->nbItems; j++) {
19225
0
    use = list->items[j];
19226
19227
0
    if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19228
0
        (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19229
0
    {
19230
0
        xmlChar *str = NULL;
19231
19232
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19233
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19234
0
      prohib->node, NULL,
19235
0
      "Skipping pointless attribute use prohibition "
19236
0
      "'%s', since a corresponding attribute use "
19237
0
      "exists already in the type definition",
19238
0
      xmlSchemaFormatQName(&str,
19239
0
          prohib->targetNamespace, prohib->name),
19240
0
      NULL, NULL);
19241
0
        FREE_AND_NULL(str);
19242
        /*
19243
        * Remove the prohibition.
19244
        */
19245
0
        if (xmlSchemaItemListRemove(prohibs, i) == -1)
19246
0
      return(-1);
19247
0
        break;
19248
0
    }
19249
0
      }
19250
0
  }
19251
0
    }
19252
0
    return(0);
19253
0
}
19254
19255
/**
19256
 * xmlSchemaAttributeGroupExpandRefs:
19257
 * @pctxt:  the parser context
19258
 * @attrGr:  the attribute group definition
19259
 *
19260
 * Computation of:
19261
 * {attribute uses} property
19262
 * {attribute wildcard} property
19263
 *
19264
 * Substitutes contained attribute group references
19265
 * for their attribute uses. Wildcards are intersected.
19266
 */
19267
static int
19268
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19269
          xmlSchemaAttributeGroupPtr attrGr)
19270
0
{
19271
0
    if ((attrGr->attrUses == NULL) ||
19272
0
  (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19273
0
  return(0);
19274
19275
0
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19276
0
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19277
0
  &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19278
0
  return(-1);
19279
0
    return(0);
19280
0
}
19281
19282
/**
19283
 * xmlSchemaAttributeGroupExpandRefs:
19284
 * @pctxt:  the parser context
19285
 * @attrGr:  the attribute group definition
19286
 *
19287
 * Substitutes contained attribute group references
19288
 * for their attribute uses. Wildcards are intersected.
19289
 *
19290
 * Schema Component Constraint:
19291
 *    Attribute Group Definition Properties Correct (ag-props-correct)
19292
 */
19293
static int
19294
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19295
          xmlSchemaAttributeGroupPtr attrGr)
19296
0
{
19297
    /*
19298
    * SPEC ag-props-correct
19299
    * (1) "The values of the properties of an attribute group definition
19300
    * must be as described in the property tableau in The Attribute
19301
    * Group Definition Schema Component ($3.6.1), modulo the impact of
19302
    * Missing Sub-components ($5.3);"
19303
    */
19304
19305
0
    if ((attrGr->attrUses != NULL) &&
19306
0
  (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19307
0
    {
19308
0
  xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19309
0
  xmlSchemaAttributeUsePtr use, tmp;
19310
0
  int i, j, hasId = 0;
19311
19312
0
  for (i = uses->nbItems -1; i >= 0; i--) {
19313
0
      use = uses->items[i];
19314
      /*
19315
      * SPEC ag-props-correct
19316
      * (2) "Two distinct members of the {attribute uses} must not have
19317
      * {attribute declaration}s both of whose {name}s match and whose
19318
      * {target namespace}s are identical."
19319
      */
19320
0
      if (i > 0) {
19321
0
    for (j = i -1; j >= 0; j--) {
19322
0
        tmp = uses->items[j];
19323
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
19324
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
19325
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
19326
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
19327
0
        {
19328
0
      xmlChar *str = NULL;
19329
19330
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19331
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19332
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19333
0
          "Duplicate %s",
19334
0
          xmlSchemaGetComponentDesignation(&str, use),
19335
0
          NULL);
19336
0
      FREE_AND_NULL(str);
19337
      /*
19338
      * Remove the duplicate.
19339
      */
19340
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19341
0
          return(-1);
19342
0
      goto next_use;
19343
0
        }
19344
0
    }
19345
0
      }
19346
      /*
19347
      * SPEC ag-props-correct
19348
      * (3) "Two distinct members of the {attribute uses} must not have
19349
      * {attribute declaration}s both of whose {type definition}s are or
19350
      * are derived from ID."
19351
      * TODO: Does 'derived' include member-types of unions?
19352
      */
19353
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19354
0
    if (xmlSchemaIsDerivedFromBuiltInType(
19355
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19356
0
    {
19357
0
        if (hasId) {
19358
0
      xmlChar *str = NULL;
19359
19360
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19361
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19362
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19363
0
          "There must not exist more than one attribute "
19364
0
          "declaration of type 'xs:ID' "
19365
0
          "(or derived from 'xs:ID'). The %s violates this "
19366
0
          "constraint",
19367
0
          xmlSchemaGetComponentDesignation(&str, use),
19368
0
          NULL);
19369
0
      FREE_AND_NULL(str);
19370
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19371
0
          return(-1);
19372
0
        }
19373
0
        hasId = 1;
19374
0
    }
19375
0
      }
19376
0
next_use: {}
19377
0
  }
19378
0
    }
19379
0
    return(0);
19380
0
}
19381
19382
/**
19383
 * xmlSchemaResolveAttrGroupReferences:
19384
 * @attrgrpDecl:  the schema attribute definition
19385
 * @ctxt:  the schema parser context
19386
 * @name:  the attribute name
19387
 *
19388
 * Resolves references to attribute group definitions.
19389
 */
19390
static int
19391
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19392
            xmlSchemaParserCtxtPtr ctxt)
19393
0
{
19394
0
    xmlSchemaAttributeGroupPtr group;
19395
19396
0
    if (ref->item != NULL)
19397
0
        return(0);
19398
0
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
19399
0
  ref->name,
19400
0
  ref->targetNamespace);
19401
0
    if (group == NULL) {
19402
0
  xmlSchemaPResCompAttrErr(ctxt,
19403
0
      XML_SCHEMAP_SRC_RESOLVE,
19404
0
      NULL, ref->node,
19405
0
      "ref", ref->name, ref->targetNamespace,
19406
0
      ref->itemType, NULL);
19407
0
  return(ctxt->err);
19408
0
    }
19409
0
    ref->item = WXS_BASIC_CAST group;
19410
0
    return(0);
19411
0
}
19412
19413
/**
19414
 * xmlSchemaCheckAttrPropsCorrect:
19415
 * @item:  an schema attribute declaration/use
19416
 * @ctxt:  a schema parser context
19417
 * @name:  the name of the attribute
19418
 *
19419
 *
19420
 * Schema Component Constraint:
19421
 *    Attribute Declaration Properties Correct (a-props-correct)
19422
 *
19423
 * Validates the value constraints of an attribute declaration/use.
19424
 * NOTE that this needs the simple type definitions to be already
19425
 *   built and checked.
19426
 */
19427
static int
19428
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19429
             xmlSchemaAttributePtr attr)
19430
0
{
19431
19432
    /*
19433
    * SPEC a-props-correct (1)
19434
    * "The values of the properties of an attribute declaration must
19435
    * be as described in the property tableau in The Attribute
19436
    * Declaration Schema Component ($3.2.1), modulo the impact of
19437
    * Missing Sub-components ($5.3)."
19438
    */
19439
19440
0
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
19441
0
  return(0);
19442
19443
0
    if (attr->defValue != NULL) {
19444
0
  int ret;
19445
19446
  /*
19447
  * SPEC a-props-correct (3)
19448
  * "If the {type definition} is or is derived from ID then there
19449
  * must not be a {value constraint}."
19450
  */
19451
0
  if (xmlSchemaIsDerivedFromBuiltInType(
19452
0
      WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19453
0
  {
19454
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19455
0
    XML_SCHEMAP_A_PROPS_CORRECT_3,
19456
0
    NULL, WXS_BASIC_CAST attr,
19457
0
    "Value constraints are not allowed if the type definition "
19458
0
    "is or is derived from xs:ID",
19459
0
    NULL, NULL);
19460
0
      return(pctxt->err);
19461
0
  }
19462
  /*
19463
  * SPEC a-props-correct (2)
19464
  * "if there is a {value constraint}, the canonical lexical
19465
  * representation of its value must be `valid` with respect
19466
  * to the {type definition} as defined in String Valid ($3.14.4)."
19467
  * TODO: Don't care about the *canonical* stuff here, this requirement
19468
  * will be removed in WXS 1.1 anyway.
19469
  */
19470
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19471
0
      attr->node, WXS_ATTR_TYPEDEF(attr),
19472
0
      attr->defValue, &(attr->defVal),
19473
0
      1, 1, 0);
19474
0
  if (ret != 0) {
19475
0
      if (ret < 0) {
19476
0
    PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19477
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19478
0
    return(-1);
19479
0
      }
19480
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19481
0
    XML_SCHEMAP_A_PROPS_CORRECT_2,
19482
0
    NULL, WXS_BASIC_CAST attr,
19483
0
    "The value of the value constraint is not valid",
19484
0
    NULL, NULL);
19485
0
      return(pctxt->err);
19486
0
  }
19487
0
    }
19488
19489
0
    return(0);
19490
0
}
19491
19492
static xmlSchemaElementPtr
19493
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19494
         xmlSchemaElementPtr ancestor)
19495
0
{
19496
0
    xmlSchemaElementPtr ret;
19497
19498
0
    if (WXS_SUBST_HEAD(ancestor) == NULL)
19499
0
  return (NULL);
19500
0
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19501
0
  return (ancestor);
19502
19503
0
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19504
0
  return (NULL);
19505
0
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19506
0
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19507
0
  WXS_SUBST_HEAD(ancestor));
19508
0
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19509
19510
0
    return (ret);
19511
0
}
19512
19513
/**
19514
 * xmlSchemaCheckElemPropsCorrect:
19515
 * @ctxt:  a schema parser context
19516
 * @decl: the element declaration
19517
 * @name:  the name of the attribute
19518
 *
19519
 * Schema Component Constraint:
19520
 * Element Declaration Properties Correct (e-props-correct)
19521
 *
19522
 * STATUS:
19523
 *   missing: (6)
19524
 */
19525
static int
19526
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19527
             xmlSchemaElementPtr elemDecl)
19528
0
{
19529
0
    int ret = 0;
19530
0
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19531
    /*
19532
    * SPEC (1) "The values of the properties of an element declaration
19533
    * must be as described in the property tableau in The Element
19534
    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19535
    * Sub-components ($5.3)."
19536
    */
19537
0
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19538
0
  xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19539
19540
0
  xmlSchemaCheckElementDeclComponent(head, pctxt);
19541
  /*
19542
  * SPEC (3) "If there is a non-`absent` {substitution group
19543
  * affiliation}, then {scope} must be global."
19544
  */
19545
0
  if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19546
0
      xmlSchemaPCustomErr(pctxt,
19547
0
    XML_SCHEMAP_E_PROPS_CORRECT_3,
19548
0
    WXS_BASIC_CAST elemDecl, NULL,
19549
0
    "Only global element declarations can have a "
19550
0
    "substitution group affiliation", NULL);
19551
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19552
0
  }
19553
  /*
19554
  * TODO: SPEC (6) "Circular substitution groups are disallowed.
19555
  * That is, it must not be possible to return to an element declaration
19556
  * by repeatedly following the {substitution group affiliation}
19557
  * property."
19558
  */
19559
0
  if (head == elemDecl)
19560
0
      circ = head;
19561
0
  else if (WXS_SUBST_HEAD(head) != NULL)
19562
0
      circ = xmlSchemaCheckSubstGroupCircular(head, head);
19563
0
  else
19564
0
      circ = NULL;
19565
0
  if (circ != NULL) {
19566
0
      xmlChar *strA = NULL, *strB = NULL;
19567
19568
0
      xmlSchemaPCustomErrExt(pctxt,
19569
0
    XML_SCHEMAP_E_PROPS_CORRECT_6,
19570
0
    WXS_BASIC_CAST circ, NULL,
19571
0
    "The element declaration '%s' defines a circular "
19572
0
    "substitution group to element declaration '%s'",
19573
0
    xmlSchemaGetComponentQName(&strA, circ),
19574
0
    xmlSchemaGetComponentQName(&strB, head),
19575
0
    NULL);
19576
0
      FREE_AND_NULL(strA)
19577
0
      FREE_AND_NULL(strB)
19578
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19579
0
  }
19580
  /*
19581
  * SPEC (4) "If there is a {substitution group affiliation},
19582
  * the {type definition}
19583
  * of the element declaration must be validly derived from the {type
19584
  * definition} of the {substitution group affiliation}, given the value
19585
  * of the {substitution group exclusions} of the {substitution group
19586
  * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19587
  * (if the {type definition} is complex) or as defined in
19588
  * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19589
  * simple)."
19590
  *
19591
  * NOTE: {substitution group exclusions} means the values of the
19592
  * attribute "final".
19593
  */
19594
19595
0
  if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19596
0
      int set = 0;
19597
19598
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19599
0
    set |= SUBSET_EXTENSION;
19600
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19601
0
    set |= SUBSET_RESTRICTION;
19602
19603
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19604
0
    WXS_ELEM_TYPEDEF(head), set) != 0) {
19605
0
    xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19606
19607
0
    ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19608
0
    xmlSchemaPCustomErrExt(pctxt,
19609
0
        XML_SCHEMAP_E_PROPS_CORRECT_4,
19610
0
        WXS_BASIC_CAST elemDecl, NULL,
19611
0
        "The type definition '%s' was "
19612
0
        "either rejected by the substitution group "
19613
0
        "affiliation '%s', or not validly derived from its type "
19614
0
        "definition '%s'",
19615
0
        xmlSchemaGetComponentQName(&strA, typeDef),
19616
0
        xmlSchemaGetComponentQName(&strB, head),
19617
0
        xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19618
0
    FREE_AND_NULL(strA)
19619
0
    FREE_AND_NULL(strB)
19620
0
    FREE_AND_NULL(strC)
19621
0
      }
19622
0
  }
19623
0
    }
19624
    /*
19625
    * SPEC (5) "If the {type definition} or {type definition}'s
19626
    * {content type}
19627
    * is or is derived from ID then there must not be a {value constraint}.
19628
    * Note: The use of ID as a type definition for elements goes beyond
19629
    * XML 1.0, and should be avoided if backwards compatibility is desired"
19630
    */
19631
0
    if ((elemDecl->value != NULL) &&
19632
0
  ((WXS_IS_SIMPLE(typeDef) &&
19633
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19634
0
   (WXS_IS_COMPLEX(typeDef) &&
19635
0
    WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19636
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19637
0
      XML_SCHEMAS_ID)))) {
19638
19639
0
  ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19640
0
  xmlSchemaPCustomErr(pctxt,
19641
0
      XML_SCHEMAP_E_PROPS_CORRECT_5,
19642
0
      WXS_BASIC_CAST elemDecl, NULL,
19643
0
      "The type definition (or type definition's content type) is or "
19644
0
      "is derived from ID; value constraints are not allowed in "
19645
0
      "conjunction with such a type definition", NULL);
19646
0
    } else if (elemDecl->value != NULL) {
19647
0
  int vcret;
19648
0
  xmlNodePtr node = NULL;
19649
19650
  /*
19651
  * SPEC (2) "If there is a {value constraint}, the canonical lexical
19652
  * representation of its value must be `valid` with respect to the
19653
  * {type definition} as defined in Element Default Valid (Immediate)
19654
  * ($3.3.6)."
19655
  */
19656
0
  if (typeDef == NULL) {
19657
0
      xmlSchemaPErr(pctxt, elemDecl->node,
19658
0
    XML_SCHEMAP_INTERNAL,
19659
0
    "Internal error: xmlSchemaCheckElemPropsCorrect, "
19660
0
    "type is missing... skipping validation of "
19661
0
    "the value constraint", NULL, NULL);
19662
0
      return (-1);
19663
0
  }
19664
0
  if (elemDecl->node != NULL) {
19665
0
      if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19666
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19667
0
        BAD_CAST "fixed");
19668
0
      else
19669
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19670
0
        BAD_CAST "default");
19671
0
  }
19672
0
  vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19673
0
      typeDef, elemDecl->value, &(elemDecl->defVal));
19674
0
  if (vcret != 0) {
19675
0
      if (vcret < 0) {
19676
0
    PERROR_INT("xmlSchemaElemCheckValConstr",
19677
0
        "failed to validate the value constraint of an "
19678
0
        "element declaration");
19679
0
    return (-1);
19680
0
      }
19681
0
      return (vcret);
19682
0
  }
19683
0
    }
19684
19685
0
    return (ret);
19686
0
}
19687
19688
/**
19689
 * xmlSchemaCheckElemSubstGroup:
19690
 * @ctxt:  a schema parser context
19691
 * @decl: the element declaration
19692
 * @name:  the name of the attribute
19693
 *
19694
 * Schema Component Constraint:
19695
 * Substitution Group (cos-equiv-class)
19696
 *
19697
 * In Libxml2 the subst. groups will be precomputed, in terms of that
19698
 * a list will be built for each subst. group head, holding all direct
19699
 * referents to this head.
19700
 * NOTE that this function needs:
19701
 *   1. circular subst. groups to be checked beforehand
19702
 *   2. the declaration's type to be derived from the head's type
19703
 *
19704
 * STATUS:
19705
 *
19706
 */
19707
static void
19708
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19709
           xmlSchemaElementPtr elemDecl)
19710
0
{
19711
0
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19712
  /* SPEC (1) "Its {abstract} is false." */
19713
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19714
0
  return;
19715
0
    {
19716
0
  xmlSchemaElementPtr head;
19717
0
  xmlSchemaTypePtr headType, type;
19718
0
  int set, methSet;
19719
  /*
19720
  * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19721
  * {disallowed substitutions} as the blocking constraint, as defined in
19722
  * Substitution Group OK (Transitive) ($3.3.6)."
19723
  */
19724
0
  for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19725
0
      head = WXS_SUBST_HEAD(head)) {
19726
0
      set = 0;
19727
0
      methSet = 0;
19728
      /*
19729
      * The blocking constraints.
19730
      */
19731
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19732
0
    continue;
19733
0
      headType = head->subtypes;
19734
0
      type = elemDecl->subtypes;
19735
0
      if (headType == type)
19736
0
    goto add_member;
19737
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19738
0
    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19739
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19740
0
    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19741
      /*
19742
      * SPEC: Substitution Group OK (Transitive) (2.3)
19743
      * "The set of all {derivation method}s involved in the
19744
      * derivation of D's {type definition} from C's {type definition}
19745
      * does not intersect with the union of the blocking constraint,
19746
      * C's {prohibited substitutions} (if C is complex, otherwise the
19747
      * empty set) and the {prohibited substitutions} (respectively the
19748
      * empty set) of any intermediate {type definition}s in the
19749
      * derivation of D's {type definition} from C's {type definition}."
19750
      */
19751
      /*
19752
      * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19753
      * subst.head axis, the methSet does not need to be computed for
19754
      * the full depth over and over.
19755
      */
19756
      /*
19757
      * The set of all {derivation method}s involved in the derivation
19758
      */
19759
0
      while ((type != NULL) && (type != headType) &&
19760
0
                   (type != type->baseType)) {
19761
0
    if ((WXS_IS_EXTENSION(type)) &&
19762
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19763
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19764
19765
0
    if (WXS_IS_RESTRICTION(type) &&
19766
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19767
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19768
19769
0
    type = type->baseType;
19770
0
      }
19771
      /*
19772
      * The {prohibited substitutions} of all intermediate types +
19773
      * the head's type.
19774
      */
19775
0
      type = elemDecl->subtypes->baseType;
19776
0
      while (type != NULL) {
19777
0
    if (WXS_IS_COMPLEX(type)) {
19778
0
        if ((type->flags &
19779
0
          XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19780
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19781
0
        set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19782
0
        if ((type->flags &
19783
0
          XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19784
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19785
0
        set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19786
0
    } else
19787
0
        break;
19788
0
    if (type == headType)
19789
0
        break;
19790
0
    type = type->baseType;
19791
0
      }
19792
0
      if ((set != 0) &&
19793
0
    (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19794
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19795
0
    ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19796
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19797
0
    continue;
19798
0
      }
19799
0
add_member:
19800
0
      xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19801
0
      if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19802
0
    head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19803
0
  }
19804
0
    }
19805
0
}
19806
19807
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19808
/**
19809
 * xmlSchemaCheckElementDeclComponent
19810
 * @pctxt: the schema parser context
19811
 * @ctxtComponent: the context component (an element declaration)
19812
 * @ctxtParticle: the first particle of the context component
19813
 * @searchParticle: the element declaration particle to be analysed
19814
 *
19815
 * Schema Component Constraint: Element Declarations Consistent
19816
 */
19817
static int
19818
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19819
            xmlSchemaBasicItemPtr ctxtComponent,
19820
            xmlSchemaParticlePtr ctxtParticle,
19821
            xmlSchemaParticlePtr searchParticle,
19822
            xmlSchemaParticlePtr curParticle,
19823
            int search)
19824
{
19825
    return(0);
19826
19827
    int ret = 0;
19828
    xmlSchemaParticlePtr cur = curParticle;
19829
    if (curParticle == NULL) {
19830
  return(0);
19831
    }
19832
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19833
  /*
19834
  * Just return in this case. A missing "term" of the particle
19835
  * might arise due to an invalid "term" component.
19836
  */
19837
  return(0);
19838
    }
19839
    while (cur != NULL) {
19840
  switch (WXS_PARTICLE_TERM(cur)->type) {
19841
      case XML_SCHEMA_TYPE_ANY:
19842
    break;
19843
      case XML_SCHEMA_TYPE_ELEMENT:
19844
    if (search == 0) {
19845
        ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19846
      ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19847
        if (ret != 0)
19848
      return(ret);
19849
    } else {
19850
        xmlSchemaElementPtr elem =
19851
      WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19852
        /*
19853
        * SPEC Element Declarations Consistent:
19854
        * "If the {particles} contains, either directly,
19855
        * indirectly (that is, within the {particles} of a
19856
        * contained model group, recursively) or `implicitly`
19857
        * two or more element declaration particles with
19858
        * the same {name} and {target namespace}, then
19859
        * all their type definitions must be the same
19860
        * top-level definition [...]"
19861
        */
19862
        if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19863
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19864
      xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19865
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19866
        {
19867
      xmlChar *strA = NULL, *strB = NULL;
19868
19869
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19870
          /* TODO: error code */
19871
          XML_SCHEMAP_COS_NONAMBIG,
19872
          WXS_ITEM_NODE(cur), NULL,
19873
          "In the content model of %s, there are multiple "
19874
          "element declarations for '%s' with different "
19875
          "type definitions",
19876
          xmlSchemaGetComponentDesignation(&strA,
19877
        ctxtComponent),
19878
          xmlSchemaFormatQName(&strB,
19879
        WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19880
        WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19881
      FREE_AND_NULL(strA);
19882
      FREE_AND_NULL(strB);
19883
      return(XML_SCHEMAP_COS_NONAMBIG);
19884
        }
19885
    }
19886
    break;
19887
      case XML_SCHEMA_TYPE_SEQUENCE: {
19888
    break;
19889
    }
19890
      case XML_SCHEMA_TYPE_CHOICE:{
19891
    /*
19892
    xmlSchemaTreeItemPtr sub;
19893
19894
    sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19895
    while (sub != NULL) {
19896
        ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19897
      ctxtParticle, ctxtElem);
19898
        if (ret != 0)
19899
      return(ret);
19900
        sub = sub->next;
19901
    }
19902
    */
19903
    break;
19904
    }
19905
      case XML_SCHEMA_TYPE_ALL:
19906
    break;
19907
      case XML_SCHEMA_TYPE_GROUP:
19908
    break;
19909
      default:
19910
    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19911
        "xmlSchemaCheckElementDeclConsistent",
19912
        "found unexpected term of type '%s' in content model",
19913
        WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19914
    return(-1);
19915
  }
19916
  cur = (xmlSchemaParticlePtr) cur->next;
19917
    }
19918
19919
exit:
19920
    return(ret);
19921
}
19922
#endif
19923
19924
/**
19925
 * xmlSchemaCheckElementDeclComponent
19926
 * @item:  an schema element declaration/particle
19927
 * @ctxt:  a schema parser context
19928
 * @name:  the name of the attribute
19929
 *
19930
 * Validates the value constraints of an element declaration.
19931
 * Adds substitution group members.
19932
 */
19933
static void
19934
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19935
           xmlSchemaParserCtxtPtr ctxt)
19936
0
{
19937
0
    if (elemDecl == NULL)
19938
0
  return;
19939
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19940
0
  return;
19941
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19942
0
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19943
  /*
19944
  * Adds substitution group members.
19945
  */
19946
0
  xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19947
0
    }
19948
0
}
19949
19950
/**
19951
 * xmlSchemaResolveModelGroupParticleReferences:
19952
 * @particle:  a particle component
19953
 * @ctxt:  a parser context
19954
 *
19955
 * Resolves references of a model group's {particles} to
19956
 * model group definitions and to element declarations.
19957
 */
19958
static void
19959
xmlSchemaResolveModelGroupParticleReferences(
19960
    xmlSchemaParserCtxtPtr ctxt,
19961
    xmlSchemaModelGroupPtr mg)
19962
0
{
19963
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19964
0
    xmlSchemaQNameRefPtr ref;
19965
0
    xmlSchemaBasicItemPtr refItem;
19966
19967
    /*
19968
    * URGENT TODO: Test this.
19969
    */
19970
0
    while (particle != NULL) {
19971
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19972
0
      ((WXS_PARTICLE_TERM(particle))->type !=
19973
0
    XML_SCHEMA_EXTRA_QNAMEREF))
19974
0
  {
19975
0
      goto next_particle;
19976
0
  }
19977
0
  ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
19978
  /*
19979
  * Resolve the reference.
19980
  * NULL the {term} by default.
19981
  */
19982
0
  particle->children = NULL;
19983
19984
0
  refItem = xmlSchemaGetNamedComponent(ctxt->schema,
19985
0
      ref->itemType, ref->name, ref->targetNamespace);
19986
0
  if (refItem == NULL) {
19987
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
19988
0
    NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
19989
0
    ref->targetNamespace, ref->itemType, NULL);
19990
      /* TODO: remove the particle. */
19991
0
      goto next_particle;
19992
0
  }
19993
0
  if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
19994
0
      if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
19995
    /* TODO: remove the particle. */
19996
0
    goto next_particle;
19997
      /*
19998
      * NOTE that we will assign the model group definition
19999
      * itself to the "term" of the particle. This will ease
20000
      * the check for circular model group definitions. After
20001
      * that the "term" will be assigned the model group of the
20002
      * model group definition.
20003
      */
20004
0
      if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20005
0
        XML_SCHEMA_TYPE_ALL) {
20006
    /*
20007
    * SPEC cos-all-limited (1)
20008
    * SPEC cos-all-limited (1.2)
20009
    * "It appears only as the value of one or both of the
20010
    * following properties:"
20011
    * (1.1) "the {model group} property of a model group
20012
    *        definition."
20013
    * (1.2) "the {term} property of a particle [... of] the "
20014
    * {content type} of a complex type definition."
20015
    */
20016
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20017
        /* TODO: error code */
20018
0
        XML_SCHEMAP_COS_ALL_LIMITED,
20019
0
        WXS_ITEM_NODE(particle), NULL,
20020
0
        "A model group definition is referenced, but "
20021
0
        "it contains an 'all' model group, which "
20022
0
        "cannot be contained by model groups",
20023
0
        NULL, NULL);
20024
    /* TODO: remove the particle. */
20025
0
    goto next_particle;
20026
0
      }
20027
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20028
0
  } else {
20029
      /*
20030
      * TODO: Are referenced element declarations the only
20031
      * other components we expect here?
20032
      */
20033
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20034
0
  }
20035
0
next_particle:
20036
0
  particle = WXS_PTC_CAST particle->next;
20037
0
    }
20038
0
}
20039
20040
static int
20041
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20042
           xmlSchemaValPtr y)
20043
0
{
20044
0
    xmlSchemaTypePtr tx, ty, ptx, pty;
20045
0
    int ret;
20046
20047
0
    while (x != NULL) {
20048
  /* Same types. */
20049
0
  tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20050
0
  ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20051
0
  ptx = xmlSchemaGetPrimitiveType(tx);
20052
0
  pty = xmlSchemaGetPrimitiveType(ty);
20053
  /*
20054
  * (1) if a datatype T' is `derived` by `restriction` from an
20055
  * atomic datatype T then the `value space` of T' is a subset of
20056
  * the `value space` of T. */
20057
  /*
20058
  * (2) if datatypes T' and T'' are `derived` by `restriction`
20059
  * from a common atomic ancestor T then the `value space`s of T'
20060
  * and T'' may overlap.
20061
  */
20062
0
  if (ptx != pty)
20063
0
      return(0);
20064
  /*
20065
  * We assume computed values to be normalized, so do a fast
20066
  * string comparison for string based types.
20067
  */
20068
0
  if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20069
0
      WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20070
0
      if (! xmlStrEqual(
20071
0
    xmlSchemaValueGetAsString(x),
20072
0
    xmlSchemaValueGetAsString(y)))
20073
0
    return (0);
20074
0
  } else {
20075
0
      ret = xmlSchemaCompareValuesWhtsp(
20076
0
    x, XML_SCHEMA_WHITESPACE_PRESERVE,
20077
0
    y, XML_SCHEMA_WHITESPACE_PRESERVE);
20078
0
      if (ret == -2)
20079
0
    return(-1);
20080
0
      if (ret != 0)
20081
0
    return(0);
20082
0
  }
20083
  /*
20084
  * Lists.
20085
  */
20086
0
  x = xmlSchemaValueGetNext(x);
20087
0
  if (x != NULL) {
20088
0
      y = xmlSchemaValueGetNext(y);
20089
0
      if (y == NULL)
20090
0
    return (0);
20091
0
  } else if (xmlSchemaValueGetNext(y) != NULL)
20092
0
      return (0);
20093
0
  else
20094
0
      return (1);
20095
0
    }
20096
0
    return (0);
20097
0
}
20098
20099
/**
20100
 * xmlSchemaResolveAttrUseReferences:
20101
 * @item:  an attribute use
20102
 * @ctxt:  a parser context
20103
 *
20104
 * Resolves the referenced attribute declaration.
20105
 */
20106
static int
20107
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20108
          xmlSchemaParserCtxtPtr ctxt)
20109
0
{
20110
0
    if ((ctxt == NULL) || (ause == NULL))
20111
0
  return(-1);
20112
0
    if ((ause->attrDecl == NULL) ||
20113
0
  (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20114
0
  return(0);
20115
20116
0
    {
20117
0
  xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20118
20119
  /*
20120
  * TODO: Evaluate, what errors could occur if the declaration is not
20121
  * found.
20122
  */
20123
0
  ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20124
0
      ref->name, ref->targetNamespace);
20125
0
        if (ause->attrDecl == NULL) {
20126
0
      xmlSchemaPResCompAttrErr(ctxt,
20127
0
    XML_SCHEMAP_SRC_RESOLVE,
20128
0
    WXS_BASIC_CAST ause, ause->node,
20129
0
    "ref", ref->name, ref->targetNamespace,
20130
0
    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20131
0
            return(ctxt->err);;
20132
0
        }
20133
0
    }
20134
0
    return(0);
20135
0
}
20136
20137
/**
20138
 * xmlSchemaCheckAttrUsePropsCorrect:
20139
 * @ctxt:  a parser context
20140
 * @use:  an attribute use
20141
 *
20142
 * Schema Component Constraint:
20143
 * Attribute Use Correct (au-props-correct)
20144
 *
20145
 */
20146
static int
20147
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20148
           xmlSchemaAttributeUsePtr use)
20149
0
{
20150
0
    if ((ctxt == NULL) || (use == NULL))
20151
0
  return(-1);
20152
0
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20153
0
  ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20154
0
  return(0);
20155
20156
    /*
20157
    * SPEC au-props-correct (1)
20158
    * "The values of the properties of an attribute use must be as
20159
    * described in the property tableau in The Attribute Use Schema
20160
    * Component ($3.5.1), modulo the impact of Missing
20161
    * Sub-components ($5.3)."
20162
    */
20163
20164
0
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20165
0
  ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20166
0
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20167
0
    {
20168
0
  xmlSchemaPCustomErr(ctxt,
20169
0
      XML_SCHEMAP_AU_PROPS_CORRECT_2,
20170
0
      WXS_BASIC_CAST use, NULL,
20171
0
      "The attribute declaration has a 'fixed' value constraint "
20172
0
      ", thus the attribute use must also have a 'fixed' value "
20173
0
      "constraint",
20174
0
      NULL);
20175
0
  return(ctxt->err);
20176
0
    }
20177
    /*
20178
    * Compute and check the value constraint's value.
20179
    */
20180
0
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20181
0
  int ret;
20182
  /*
20183
  * TODO: The spec seems to be missing a check of the
20184
  * value constraint of the attribute use. We will do it here.
20185
  */
20186
  /*
20187
  * SPEC a-props-correct (3)
20188
  */
20189
0
  if (xmlSchemaIsDerivedFromBuiltInType(
20190
0
      WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20191
0
  {
20192
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20193
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20194
0
    NULL, WXS_BASIC_CAST use,
20195
0
    "Value constraints are not allowed if the type definition "
20196
0
    "is or is derived from xs:ID",
20197
0
    NULL, NULL);
20198
0
      return(ctxt->err);
20199
0
  }
20200
20201
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20202
0
      use->node, WXS_ATTRUSE_TYPEDEF(use),
20203
0
      use->defValue, &(use->defVal),
20204
0
      1, 1, 0);
20205
0
  if (ret != 0) {
20206
0
      if (ret < 0) {
20207
0
    PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20208
0
        "calling xmlSchemaVCheckCVCSimpleType()");
20209
0
    return(-1);
20210
0
      }
20211
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20212
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20213
0
    NULL, WXS_BASIC_CAST use,
20214
0
    "The value of the value constraint is not valid",
20215
0
    NULL, NULL);
20216
0
      return(ctxt->err);
20217
0
  }
20218
0
    }
20219
    /*
20220
    * SPEC au-props-correct (2)
20221
    * "If the {attribute declaration} has a fixed
20222
    * {value constraint}, then if the attribute use itself has a
20223
    * {value constraint}, it must also be fixed and its value must match
20224
    * that of the {attribute declaration}'s {value constraint}."
20225
    */
20226
0
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20227
0
  (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20228
0
    {
20229
0
  if (! xmlSchemaAreValuesEqual(use->defVal,
20230
0
    (WXS_ATTRUSE_DECL(use))->defVal))
20231
0
  {
20232
0
      xmlSchemaPCustomErr(ctxt,
20233
0
    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20234
0
    WXS_BASIC_CAST use, NULL,
20235
0
    "The 'fixed' value constraint of the attribute use "
20236
0
    "must match the attribute declaration's value "
20237
0
    "constraint '%s'",
20238
0
    (WXS_ATTRUSE_DECL(use))->defValue);
20239
0
  }
20240
0
  return(ctxt->err);
20241
0
    }
20242
0
    return(0);
20243
0
}
20244
20245
20246
20247
20248
/**
20249
 * xmlSchemaResolveAttrTypeReferences:
20250
 * @item:  an attribute declaration
20251
 * @ctxt:  a parser context
20252
 *
20253
 * Resolves the referenced type definition component.
20254
 */
20255
static int
20256
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20257
           xmlSchemaParserCtxtPtr ctxt)
20258
0
{
20259
    /*
20260
    * The simple type definition corresponding to the <simpleType> element
20261
    * information item in the [children], if present, otherwise the simple
20262
    * type definition `resolved` to by the `actual value` of the type
20263
    * [attribute], if present, otherwise the `simple ur-type definition`.
20264
    */
20265
0
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20266
0
  return(0);
20267
0
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20268
0
    if (item->subtypes != NULL)
20269
0
        return(0);
20270
0
    if (item->typeName != NULL) {
20271
0
        xmlSchemaTypePtr type;
20272
20273
0
  type = xmlSchemaGetType(ctxt->schema, item->typeName,
20274
0
      item->typeNs);
20275
0
  if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20276
0
      xmlSchemaPResCompAttrErr(ctxt,
20277
0
    XML_SCHEMAP_SRC_RESOLVE,
20278
0
    WXS_BASIC_CAST item, item->node,
20279
0
    "type", item->typeName, item->typeNs,
20280
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
20281
0
      return(ctxt->err);
20282
0
  } else
20283
0
      item->subtypes = type;
20284
20285
0
    } else {
20286
  /*
20287
  * The type defaults to the xs:anySimpleType.
20288
  */
20289
0
  item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20290
0
    }
20291
0
    return(0);
20292
0
}
20293
20294
/**
20295
 * xmlSchemaResolveIDCKeyReferences:
20296
 * @idc:  the identity-constraint definition
20297
 * @ctxt:  the schema parser context
20298
 * @name:  the attribute name
20299
 *
20300
 * Resolve keyRef references to key/unique IDCs.
20301
 * Schema Component Constraint:
20302
 *   Identity-constraint Definition Properties Correct (c-props-correct)
20303
 */
20304
static int
20305
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20306
        xmlSchemaParserCtxtPtr pctxt)
20307
0
{
20308
0
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20309
0
        return(0);
20310
0
    if (idc->ref->name != NULL) {
20311
0
  idc->ref->item = (xmlSchemaBasicItemPtr)
20312
0
      xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20313
0
    idc->ref->targetNamespace);
20314
0
        if (idc->ref->item == NULL) {
20315
      /*
20316
      * TODO: It is actually not an error to fail to resolve
20317
      * at this stage. BUT we need to be that strict!
20318
      */
20319
0
      xmlSchemaPResCompAttrErr(pctxt,
20320
0
    XML_SCHEMAP_SRC_RESOLVE,
20321
0
    WXS_BASIC_CAST idc, idc->node,
20322
0
    "refer", idc->ref->name,
20323
0
    idc->ref->targetNamespace,
20324
0
    XML_SCHEMA_TYPE_IDC_KEY, NULL);
20325
0
            return(pctxt->err);
20326
0
  } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20327
      /*
20328
      * SPEC c-props-correct (1)
20329
      */
20330
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20331
0
    XML_SCHEMAP_C_PROPS_CORRECT,
20332
0
    NULL, WXS_BASIC_CAST idc,
20333
0
    "The keyref references a keyref",
20334
0
    NULL, NULL);
20335
0
      idc->ref->item = NULL;
20336
0
      return(pctxt->err);
20337
0
  } else {
20338
0
      if (idc->nbFields !=
20339
0
    ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20340
0
    xmlChar *str = NULL;
20341
0
    xmlSchemaIDCPtr refer;
20342
20343
0
    refer = (xmlSchemaIDCPtr) idc->ref->item;
20344
    /*
20345
    * SPEC c-props-correct(2)
20346
    * "If the {identity-constraint category} is keyref,
20347
    * the cardinality of the {fields} must equal that of
20348
    * the {fields} of the {referenced key}.
20349
    */
20350
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20351
0
        XML_SCHEMAP_C_PROPS_CORRECT,
20352
0
        NULL, WXS_BASIC_CAST idc,
20353
0
        "The cardinality of the keyref differs from the "
20354
0
        "cardinality of the referenced key/unique '%s'",
20355
0
        xmlSchemaFormatQName(&str, refer->targetNamespace,
20356
0
      refer->name),
20357
0
        NULL);
20358
0
    FREE_AND_NULL(str)
20359
0
    return(pctxt->err);
20360
0
      }
20361
0
  }
20362
0
    }
20363
0
    return(0);
20364
0
}
20365
20366
static int
20367
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20368
               xmlSchemaParserCtxtPtr pctxt)
20369
0
{
20370
0
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20371
0
  prohib->targetNamespace) == NULL) {
20372
20373
0
  xmlSchemaPResCompAttrErr(pctxt,
20374
0
      XML_SCHEMAP_SRC_RESOLVE,
20375
0
      NULL, prohib->node,
20376
0
      "ref", prohib->name, prohib->targetNamespace,
20377
0
      XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20378
0
  return(XML_SCHEMAP_SRC_RESOLVE);
20379
0
    }
20380
0
    return(0);
20381
0
}
20382
20383
0
#define WXS_REDEFINED_TYPE(c) \
20384
0
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20385
20386
0
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20387
0
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20388
20389
0
#define WXS_REDEFINED_ATTR_GROUP(c) \
20390
0
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20391
20392
static int
20393
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20394
0
{
20395
0
    int err = 0;
20396
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20397
0
    xmlSchemaBasicItemPtr prev, item;
20398
0
    int wasRedefined;
20399
20400
0
    if (redef == NULL)
20401
0
  return(0);
20402
20403
0
    do {
20404
0
  item = redef->item;
20405
  /*
20406
  * First try to locate the redefined component in the
20407
  * schema graph starting with the redefined schema.
20408
  * NOTE: According to this schema bug entry:
20409
  *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20410
  *   it's not clear if the referenced component needs to originate
20411
  *   from the <redefine>d schema _document_ or the schema; the latter
20412
  *   would include all imported and included sub-schemas of the
20413
  *   <redefine>d schema. Currently the latter approach is used.
20414
  *   SUPPLEMENT: It seems that the WG moves towards the latter
20415
  *   approach, so we are doing it right.
20416
  *
20417
  */
20418
0
  prev = xmlSchemaFindRedefCompInGraph(
20419
0
      redef->targetBucket, item->type,
20420
0
      redef->refName, redef->refTargetNs);
20421
0
  if (prev == NULL) {
20422
0
      xmlChar *str = NULL;
20423
0
      xmlNodePtr node;
20424
20425
      /*
20426
      * SPEC src-redefine:
20427
      * (6.2.1) "The `actual value` of its own name attribute plus
20428
      * target namespace must successfully `resolve` to a model
20429
      * group definition in I."
20430
      * (7.2.1) "The `actual value` of its own name attribute plus
20431
      * target namespace must successfully `resolve` to an attribute
20432
      * group definition in I."
20433
20434
      *
20435
      * Note that, if we are redefining with the use of references
20436
      * to components, the spec assumes the src-resolve to be used;
20437
      * but this won't assure that we search only *inside* the
20438
      * redefined schema.
20439
      */
20440
0
      if (redef->reference)
20441
0
    node = WXS_ITEM_NODE(redef->reference);
20442
0
      else
20443
0
    node = WXS_ITEM_NODE(item);
20444
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20445
    /*
20446
    * TODO: error code.
20447
    * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20448
    * reference kind.
20449
    */
20450
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20451
0
    "The %s '%s' to be redefined could not be found in "
20452
0
    "the redefined schema",
20453
0
    WXS_ITEM_TYPE_NAME(item),
20454
0
    xmlSchemaFormatQName(&str, redef->refTargetNs,
20455
0
        redef->refName));
20456
0
      FREE_AND_NULL(str);
20457
0
      err = pctxt->err;
20458
0
      redef = redef->next;
20459
0
      continue;
20460
0
  }
20461
  /*
20462
  * TODO: Obtaining and setting the redefinition state is really
20463
  * clumsy.
20464
  */
20465
0
  wasRedefined = 0;
20466
0
  switch (item->type) {
20467
0
      case XML_SCHEMA_TYPE_COMPLEX:
20468
0
      case XML_SCHEMA_TYPE_SIMPLE:
20469
0
    if ((WXS_TYPE_CAST prev)->flags &
20470
0
        XML_SCHEMAS_TYPE_REDEFINED)
20471
0
    {
20472
0
        wasRedefined = 1;
20473
0
        break;
20474
0
    }
20475
    /* Mark it as redefined. */
20476
0
    (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20477
    /*
20478
    * Assign the redefined type to the
20479
    * base type of the redefining type.
20480
    * TODO: How
20481
    */
20482
0
    ((xmlSchemaTypePtr) item)->baseType =
20483
0
        (xmlSchemaTypePtr) prev;
20484
0
    break;
20485
0
      case XML_SCHEMA_TYPE_GROUP:
20486
0
    if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20487
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20488
0
    {
20489
0
        wasRedefined = 1;
20490
0
        break;
20491
0
    }
20492
    /* Mark it as redefined. */
20493
0
    (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20494
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20495
0
    if (redef->reference != NULL) {
20496
        /*
20497
        * Overwrite the QName-reference with the
20498
        * referenced model group def.
20499
        */
20500
0
        (WXS_PTC_CAST redef->reference)->children =
20501
0
      WXS_TREE_CAST prev;
20502
0
    }
20503
0
    redef->target = prev;
20504
0
    break;
20505
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20506
0
    if ((WXS_ATTR_GROUP_CAST prev)->flags &
20507
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED)
20508
0
    {
20509
0
        wasRedefined = 1;
20510
0
        break;
20511
0
    }
20512
0
    (WXS_ATTR_GROUP_CAST prev)->flags |=
20513
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED;
20514
0
    if (redef->reference != NULL) {
20515
        /*
20516
        * Assign the redefined attribute group to the
20517
        * QName-reference component.
20518
        * This is the easy case, since we will just
20519
        * expand the redefined group.
20520
        */
20521
0
        (WXS_QNAME_CAST redef->reference)->item = prev;
20522
0
        redef->target = NULL;
20523
0
    } else {
20524
        /*
20525
        * This is the complicated case: we need
20526
        * to apply src-redefine (7.2.2) at a later
20527
        * stage, i.e. when attribute group references
20528
        * have been expanded and simple types have
20529
        * been fixed.
20530
        */
20531
0
        redef->target = prev;
20532
0
    }
20533
0
    break;
20534
0
      default:
20535
0
    PERROR_INT("xmlSchemaResolveRedefReferences",
20536
0
        "Unexpected redefined component type");
20537
0
    return(-1);
20538
0
  }
20539
0
  if (wasRedefined) {
20540
0
      xmlChar *str = NULL;
20541
0
      xmlNodePtr node;
20542
20543
0
      if (redef->reference)
20544
0
    node = WXS_ITEM_NODE(redef->reference);
20545
0
      else
20546
0
    node = WXS_ITEM_NODE(redef->item);
20547
20548
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20549
    /* TODO: error code. */
20550
0
    XML_SCHEMAP_SRC_REDEFINE,
20551
0
    node, NULL,
20552
0
    "The referenced %s was already redefined. Multiple "
20553
0
    "redefinition of the same component is not supported",
20554
0
    xmlSchemaGetComponentDesignation(&str, prev),
20555
0
    NULL);
20556
0
      FREE_AND_NULL(str)
20557
0
      err = pctxt->err;
20558
0
      redef = redef->next;
20559
0
      continue;
20560
0
  }
20561
0
  redef = redef->next;
20562
0
    } while (redef != NULL);
20563
20564
0
    return(err);
20565
0
}
20566
20567
static int
20568
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20569
0
{
20570
0
    int err = 0;
20571
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20572
0
    xmlSchemaBasicItemPtr item;
20573
20574
0
    if (redef == NULL)
20575
0
  return(0);
20576
20577
0
    do {
20578
0
  if (redef->target == NULL) {
20579
0
      redef = redef->next;
20580
0
      continue;
20581
0
  }
20582
0
  item = redef->item;
20583
20584
0
  switch (item->type) {
20585
0
      case XML_SCHEMA_TYPE_SIMPLE:
20586
0
      case XML_SCHEMA_TYPE_COMPLEX:
20587
    /*
20588
    * Since the spec wants the {name} of the redefined
20589
    * type to be 'absent', we'll NULL it.
20590
    */
20591
0
    (WXS_TYPE_CAST redef->target)->name = NULL;
20592
20593
    /*
20594
    * TODO: Seems like there's nothing more to do. The normal
20595
    * inheritance mechanism is used. But not 100% sure.
20596
    */
20597
0
    break;
20598
0
      case XML_SCHEMA_TYPE_GROUP:
20599
    /*
20600
    * URGENT TODO:
20601
    * SPEC src-redefine:
20602
    * (6.2.2) "The {model group} of the model group definition
20603
    * which corresponds to it per XML Representation of Model
20604
    * Group Definition Schema Components ($3.7.2) must be a
20605
    * `valid restriction` of the {model group} of that model
20606
    * group definition in I, as defined in Particle Valid
20607
    * (Restriction) ($3.9.6)."
20608
    */
20609
0
    break;
20610
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20611
    /*
20612
    * SPEC src-redefine:
20613
    * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20614
    * the attribute group definition which corresponds to it
20615
    * per XML Representation of Attribute Group Definition Schema
20616
    * Components ($3.6.2) must be `valid restrictions` of the
20617
    * {attribute uses} and {attribute wildcard} of that attribute
20618
    * group definition in I, as defined in clause 2, clause 3 and
20619
    * clause 4 of Derivation Valid (Restriction, Complex)
20620
    * ($3.4.6) (where references to the base type definition are
20621
    * understood as references to the attribute group definition
20622
    * in I)."
20623
    */
20624
0
    err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20625
0
        XML_SCHEMA_ACTION_REDEFINE,
20626
0
        item, redef->target,
20627
0
        (WXS_ATTR_GROUP_CAST item)->attrUses,
20628
0
        (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20629
0
        (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20630
0
        (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20631
0
    if (err == -1)
20632
0
        return(-1);
20633
0
    break;
20634
0
      default:
20635
0
    break;
20636
0
  }
20637
0
  redef = redef->next;
20638
0
    } while (redef != NULL);
20639
0
    return(0);
20640
0
}
20641
20642
20643
static int
20644
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20645
           xmlSchemaBucketPtr bucket)
20646
0
{
20647
0
    xmlSchemaBasicItemPtr item;
20648
0
    int err;
20649
0
    xmlHashTablePtr *table;
20650
0
    const xmlChar *name;
20651
0
    int i;
20652
20653
0
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20654
0
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20655
0
  table = &(WXS_IMPBUCKET((c))->schema->slot); \
20656
0
    else \
20657
0
  table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20658
20659
    /*
20660
    * Add global components to the schema's hash tables.
20661
    * This is the place where duplicate components will be
20662
    * detected.
20663
    * TODO: I think normally we should support imports of the
20664
    *   same namespace from multiple locations. We don't do currently,
20665
    *   but if we do then according to:
20666
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20667
    *   we would need, if imported directly, to import redefined
20668
    *   components as well to be able to catch clashing components.
20669
    *   (I hope I'll still know what this means after some months :-()
20670
    */
20671
0
    if (bucket == NULL)
20672
0
  return(-1);
20673
0
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20674
0
  return(0);
20675
0
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20676
20677
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
20678
0
  item = bucket->globals->items[i];
20679
0
  table = NULL;
20680
0
  switch (item->type) {
20681
0
      case XML_SCHEMA_TYPE_COMPLEX:
20682
0
      case XML_SCHEMA_TYPE_SIMPLE:
20683
0
    if (WXS_REDEFINED_TYPE(item))
20684
0
        continue;
20685
0
    name = (WXS_TYPE_CAST item)->name;
20686
0
    WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20687
0
    break;
20688
0
      case XML_SCHEMA_TYPE_ELEMENT:
20689
0
    name = (WXS_ELEM_CAST item)->name;
20690
0
    WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20691
0
    break;
20692
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20693
0
    name = (WXS_ATTR_CAST item)->name;
20694
0
    WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20695
0
    break;
20696
0
      case XML_SCHEMA_TYPE_GROUP:
20697
0
    if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20698
0
        continue;
20699
0
    name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20700
0
    WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20701
0
    break;
20702
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20703
0
    if (WXS_REDEFINED_ATTR_GROUP(item))
20704
0
        continue;
20705
0
    name = (WXS_ATTR_GROUP_CAST item)->name;
20706
0
    WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20707
0
    break;
20708
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20709
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20710
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20711
0
    name = (WXS_IDC_CAST item)->name;
20712
0
    WXS_GET_GLOBAL_HASH(bucket, idcDef)
20713
0
    break;
20714
0
      case XML_SCHEMA_TYPE_NOTATION:
20715
0
    name = ((xmlSchemaNotationPtr) item)->name;
20716
0
    WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20717
0
    break;
20718
0
      default:
20719
0
    PERROR_INT("xmlSchemaAddComponents",
20720
0
        "Unexpected global component type");
20721
0
    continue;
20722
0
  }
20723
0
  if (*table == NULL) {
20724
0
      *table = xmlHashCreateDict(10, pctxt->dict);
20725
0
      if (*table == NULL) {
20726
0
    PERROR_INT("xmlSchemaAddComponents",
20727
0
        "failed to create a component hash table");
20728
0
    return(-1);
20729
0
      }
20730
0
  }
20731
0
  err = xmlHashAddEntry(*table, name, item);
20732
0
  if (err != 0) {
20733
0
      xmlChar *str = NULL;
20734
20735
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20736
0
    XML_SCHEMAP_REDEFINED_TYPE,
20737
0
    WXS_ITEM_NODE(item),
20738
0
    WXS_BASIC_CAST item,
20739
0
    "A global %s '%s' does already exist",
20740
0
    WXS_ITEM_TYPE_NAME(item),
20741
0
    xmlSchemaGetComponentQName(&str, item));
20742
0
      FREE_AND_NULL(str);
20743
0
  }
20744
0
    }
20745
    /*
20746
    * Process imported/included schemas.
20747
    */
20748
0
    if (bucket->relations != NULL) {
20749
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
20750
0
  do {
20751
0
      if ((rel->bucket != NULL) &&
20752
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20753
0
    if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20754
0
        return(-1);
20755
0
      }
20756
0
      rel = rel->next;
20757
0
  } while (rel != NULL);
20758
0
    }
20759
0
    return(0);
20760
0
}
20761
20762
static int
20763
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20764
       xmlSchemaBucketPtr rootBucket)
20765
0
{
20766
0
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20767
0
    xmlSchemaTreeItemPtr item, *items;
20768
0
    int nbItems, i, ret = 0;
20769
0
    xmlSchemaBucketPtr oldbucket = con->bucket;
20770
0
    xmlSchemaElementPtr elemDecl;
20771
20772
0
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20773
20774
0
    if ((con->pending == NULL) ||
20775
0
  (con->pending->nbItems == 0))
20776
0
  return(0);
20777
20778
    /*
20779
    * Since xmlSchemaFixupComplexType() will create new particles
20780
    * (local components), and those particle components need a bucket
20781
    * on the constructor, we'll assure here that the constructor has
20782
    * a bucket.
20783
    * TODO: Think about storing locals _only_ on the main bucket.
20784
    */
20785
0
    if (con->bucket == NULL)
20786
0
  con->bucket = rootBucket;
20787
20788
    /* TODO:
20789
    * SPEC (src-redefine):
20790
    * (6.2) "If it has no such self-reference, then all of the
20791
    * following must be true:"
20792
20793
    * (6.2.2) The {model group} of the model group definition which
20794
    * corresponds to it per XML Representation of Model Group
20795
    * Definition Schema Components ($3.7.2) must be a `valid
20796
    * restriction` of the {model group} of that model group definition
20797
    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20798
    */
20799
0
    xmlSchemaCheckSRCRedefineFirst(pctxt);
20800
20801
    /*
20802
    * Add global components to the schemata's hash tables.
20803
    */
20804
0
    xmlSchemaAddComponents(pctxt, rootBucket);
20805
20806
0
    pctxt->ctxtType = NULL;
20807
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
20808
0
    nbItems = con->pending->nbItems;
20809
    /*
20810
    * Now that we have parsed *all* the schema document(s) and converted
20811
    * them to schema components, we can resolve references, apply component
20812
    * constraints, create the FSA from the content model, etc.
20813
    */
20814
    /*
20815
    * Resolve references of..
20816
    *
20817
    * 1. element declarations:
20818
    *   - the type definition
20819
    *   - the substitution group affiliation
20820
    * 2. simple/complex types:
20821
    *   - the base type definition
20822
    *   - the memberTypes of union types
20823
    *   - the itemType of list types
20824
    * 3. attributes declarations and attribute uses:
20825
    *   - the type definition
20826
    *   - if an attribute use, then the attribute declaration
20827
    * 4. attribute group references:
20828
    *   - the attribute group definition
20829
    * 5. particles:
20830
    *   - the term of the particle (e.g. a model group)
20831
    * 6. IDC key-references:
20832
    *   - the referenced IDC 'key' or 'unique' definition
20833
    * 7. Attribute prohibitions which had a "ref" attribute.
20834
    */
20835
0
    for (i = 0; i < nbItems; i++) {
20836
0
  item = items[i];
20837
0
  switch (item->type) {
20838
0
      case XML_SCHEMA_TYPE_ELEMENT:
20839
0
    xmlSchemaResolveElementReferences(
20840
0
        (xmlSchemaElementPtr) item, pctxt);
20841
0
    FIXHFAILURE;
20842
0
    break;
20843
0
      case XML_SCHEMA_TYPE_COMPLEX:
20844
0
      case XML_SCHEMA_TYPE_SIMPLE:
20845
0
    xmlSchemaResolveTypeReferences(
20846
0
        (xmlSchemaTypePtr) item, pctxt);
20847
0
    FIXHFAILURE;
20848
0
    break;
20849
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20850
0
    xmlSchemaResolveAttrTypeReferences(
20851
0
        (xmlSchemaAttributePtr) item, pctxt);
20852
0
    FIXHFAILURE;
20853
0
    break;
20854
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20855
0
    xmlSchemaResolveAttrUseReferences(
20856
0
        (xmlSchemaAttributeUsePtr) item, pctxt);
20857
0
    FIXHFAILURE;
20858
0
    break;
20859
0
      case XML_SCHEMA_EXTRA_QNAMEREF:
20860
0
    if ((WXS_QNAME_CAST item)->itemType ==
20861
0
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20862
0
    {
20863
0
        xmlSchemaResolveAttrGroupReferences(
20864
0
      WXS_QNAME_CAST item, pctxt);
20865
0
    }
20866
0
    FIXHFAILURE;
20867
0
    break;
20868
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20869
0
      case XML_SCHEMA_TYPE_CHOICE:
20870
0
      case XML_SCHEMA_TYPE_ALL:
20871
0
    xmlSchemaResolveModelGroupParticleReferences(pctxt,
20872
0
        WXS_MODEL_GROUP_CAST item);
20873
0
    FIXHFAILURE;
20874
0
    break;
20875
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20876
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20877
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20878
0
    xmlSchemaResolveIDCKeyReferences(
20879
0
        (xmlSchemaIDCPtr) item, pctxt);
20880
0
    FIXHFAILURE;
20881
0
    break;
20882
0
      case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20883
    /*
20884
    * Handle attribute prohibition which had a
20885
    * "ref" attribute.
20886
    */
20887
0
    xmlSchemaResolveAttrUseProhibReferences(
20888
0
        WXS_ATTR_PROHIB_CAST item, pctxt);
20889
0
    FIXHFAILURE;
20890
0
    break;
20891
0
      default:
20892
0
    break;
20893
0
  }
20894
0
    }
20895
0
    if (pctxt->nberrors != 0)
20896
0
  goto exit_error;
20897
20898
    /*
20899
    * Now that all references are resolved we
20900
    * can check for circularity of...
20901
    * 1. the base axis of type definitions
20902
    * 2. nested model group definitions
20903
    * 3. nested attribute group definitions
20904
    * TODO: check for circular substitution groups.
20905
    */
20906
0
    for (i = 0; i < nbItems; i++) {
20907
0
  item = items[i];
20908
  /*
20909
  * Let's better stop on the first error here.
20910
  */
20911
0
  switch (item->type) {
20912
0
      case XML_SCHEMA_TYPE_COMPLEX:
20913
0
      case XML_SCHEMA_TYPE_SIMPLE:
20914
0
    xmlSchemaCheckTypeDefCircular(
20915
0
        (xmlSchemaTypePtr) item, pctxt);
20916
0
    FIXHFAILURE;
20917
0
    if (pctxt->nberrors != 0)
20918
0
        goto exit_error;
20919
0
    break;
20920
0
      case XML_SCHEMA_TYPE_GROUP:
20921
0
    xmlSchemaCheckGroupDefCircular(
20922
0
        (xmlSchemaModelGroupDefPtr) item, pctxt);
20923
0
    FIXHFAILURE;
20924
0
    if (pctxt->nberrors != 0)
20925
0
        goto exit_error;
20926
0
    break;
20927
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20928
0
    xmlSchemaCheckAttrGroupCircular(
20929
0
        (xmlSchemaAttributeGroupPtr) item, pctxt);
20930
0
    FIXHFAILURE;
20931
0
    if (pctxt->nberrors != 0)
20932
0
        goto exit_error;
20933
0
    break;
20934
0
      default:
20935
0
    break;
20936
0
  }
20937
0
    }
20938
0
    if (pctxt->nberrors != 0)
20939
0
  goto exit_error;
20940
    /*
20941
    * Model group definition references:
20942
    * Such a reference is reflected by a particle at the component
20943
    * level. Until now the 'term' of such particles pointed
20944
    * to the model group definition; this was done, in order to
20945
    * ease circularity checks. Now we need to set the 'term' of
20946
    * such particles to the model group of the model group definition.
20947
    */
20948
0
    for (i = 0; i < nbItems; i++) {
20949
0
  item = items[i];
20950
0
  switch (item->type) {
20951
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20952
0
      case XML_SCHEMA_TYPE_CHOICE:
20953
0
    xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20954
0
        WXS_MODEL_GROUP_CAST item);
20955
0
    break;
20956
0
      default:
20957
0
    break;
20958
0
  }
20959
0
    }
20960
0
    if (pctxt->nberrors != 0)
20961
0
  goto exit_error;
20962
    /*
20963
    * Expand attribute group references of attribute group definitions.
20964
    */
20965
0
    for (i = 0; i < nbItems; i++) {
20966
0
  item = items[i];
20967
0
  switch (item->type) {
20968
0
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20969
0
    if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20970
0
        WXS_ATTR_GROUP_HAS_REFS(item))
20971
0
    {
20972
0
        xmlSchemaAttributeGroupExpandRefs(pctxt,
20973
0
      WXS_ATTR_GROUP_CAST item);
20974
0
        FIXHFAILURE;
20975
0
    }
20976
0
    break;
20977
0
      default:
20978
0
    break;
20979
0
  }
20980
0
    }
20981
0
    if (pctxt->nberrors != 0)
20982
0
  goto exit_error;
20983
    /*
20984
    * First compute the variety of simple types. This is needed as
20985
    * a separate step, since otherwise we won't be able to detect
20986
    * circular union types in all cases.
20987
    */
20988
0
    for (i = 0; i < nbItems; i++) {
20989
0
  item = items[i];
20990
0
  switch (item->type) {
20991
0
            case XML_SCHEMA_TYPE_SIMPLE:
20992
0
    if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
20993
0
        xmlSchemaFixupSimpleTypeStageOne(pctxt,
20994
0
      (xmlSchemaTypePtr) item);
20995
0
        FIXHFAILURE;
20996
0
    }
20997
0
    break;
20998
0
      default:
20999
0
    break;
21000
0
  }
21001
0
    }
21002
0
    if (pctxt->nberrors != 0)
21003
0
  goto exit_error;
21004
    /*
21005
    * Detect circular union types. Note that this needs the variety to
21006
    * be already computed.
21007
    */
21008
0
    for (i = 0; i < nbItems; i++) {
21009
0
  item = items[i];
21010
0
  switch (item->type) {
21011
0
            case XML_SCHEMA_TYPE_SIMPLE:
21012
0
    if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21013
0
        xmlSchemaCheckUnionTypeDefCircular(pctxt,
21014
0
      (xmlSchemaTypePtr) item);
21015
0
        FIXHFAILURE;
21016
0
    }
21017
0
    break;
21018
0
      default:
21019
0
    break;
21020
0
  }
21021
0
    }
21022
0
    if (pctxt->nberrors != 0)
21023
0
  goto exit_error;
21024
21025
    /*
21026
    * Do the complete type fixup for simple types.
21027
    */
21028
0
    for (i = 0; i < nbItems; i++) {
21029
0
  item = items[i];
21030
0
  switch (item->type) {
21031
0
            case XML_SCHEMA_TYPE_SIMPLE:
21032
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21033
0
        xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21034
0
        FIXHFAILURE;
21035
0
    }
21036
0
    break;
21037
0
      default:
21038
0
    break;
21039
0
  }
21040
0
    }
21041
0
    if (pctxt->nberrors != 0)
21042
0
  goto exit_error;
21043
    /*
21044
    * At this point we need build and check all simple types.
21045
    */
21046
    /*
21047
    * Apply constraints for attribute declarations.
21048
    */
21049
0
    for (i = 0; i < nbItems; i++) {
21050
0
  item = items[i];
21051
0
  switch (item->type) {
21052
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21053
0
    xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21054
0
    FIXHFAILURE;
21055
0
    break;
21056
0
      default:
21057
0
    break;
21058
0
  }
21059
0
    }
21060
0
    if (pctxt->nberrors != 0)
21061
0
  goto exit_error;
21062
    /*
21063
    * Apply constraints for attribute uses.
21064
    */
21065
0
    for (i = 0; i < nbItems; i++) {
21066
0
  item = items[i];
21067
0
  switch (item->type) {
21068
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21069
0
    if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21070
0
        xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21071
0
      WXS_ATTR_USE_CAST item);
21072
0
        FIXHFAILURE;
21073
0
    }
21074
0
    break;
21075
0
      default:
21076
0
    break;
21077
0
  }
21078
0
    }
21079
0
    if (pctxt->nberrors != 0)
21080
0
  goto exit_error;
21081
21082
    /*
21083
    * Apply constraints for attribute group definitions.
21084
    */
21085
0
    for (i = 0; i < nbItems; i++) {
21086
0
  item = items[i];
21087
0
  switch (item->type) {
21088
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21089
0
      if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21090
0
    ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21091
0
      {
21092
0
    xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21093
0
    FIXHFAILURE;
21094
0
      }
21095
0
      break;
21096
0
  default:
21097
0
      break;
21098
0
  }
21099
0
    }
21100
0
    if (pctxt->nberrors != 0)
21101
0
  goto exit_error;
21102
21103
    /*
21104
    * Apply constraints for redefinitions.
21105
    */
21106
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21107
0
  xmlSchemaCheckSRCRedefineSecond(pctxt);
21108
0
    if (pctxt->nberrors != 0)
21109
0
  goto exit_error;
21110
21111
    /*
21112
    * Complex types are built and checked.
21113
    */
21114
0
    for (i = 0; i < nbItems; i++) {
21115
0
  item = con->pending->items[i];
21116
0
  switch (item->type) {
21117
0
      case XML_SCHEMA_TYPE_COMPLEX:
21118
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21119
0
        xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21120
0
        FIXHFAILURE;
21121
0
    }
21122
0
    break;
21123
0
      default:
21124
0
    break;
21125
0
  }
21126
0
    }
21127
0
    if (pctxt->nberrors != 0)
21128
0
  goto exit_error;
21129
21130
    /*
21131
    * The list could have changed, since xmlSchemaFixupComplexType()
21132
    * will create particles and model groups in some cases.
21133
    */
21134
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
21135
0
    nbItems = con->pending->nbItems;
21136
21137
    /*
21138
    * Apply some constraints for element declarations.
21139
    */
21140
0
    for (i = 0; i < nbItems; i++) {
21141
0
  item = items[i];
21142
0
  switch (item->type) {
21143
0
      case XML_SCHEMA_TYPE_ELEMENT:
21144
0
    elemDecl = (xmlSchemaElementPtr) item;
21145
21146
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21147
0
    {
21148
0
        xmlSchemaCheckElementDeclComponent(
21149
0
      (xmlSchemaElementPtr) elemDecl, pctxt);
21150
0
        FIXHFAILURE;
21151
0
    }
21152
21153
#ifdef WXS_ELEM_DECL_CONS_ENABLED
21154
    /*
21155
    * Schema Component Constraint: Element Declarations Consistent
21156
    * Apply this constraint to local types of element declarations.
21157
    */
21158
    if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21159
        (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21160
        (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21161
    {
21162
        xmlSchemaCheckElementDeclConsistent(pctxt,
21163
      WXS_BASIC_CAST elemDecl,
21164
      WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21165
      NULL, NULL, 0);
21166
    }
21167
#endif
21168
0
    break;
21169
0
      default:
21170
0
    break;
21171
0
  }
21172
0
    }
21173
0
    if (pctxt->nberrors != 0)
21174
0
  goto exit_error;
21175
21176
    /*
21177
    * Finally we can build the automaton from the content model of
21178
    * complex types.
21179
    */
21180
21181
0
    for (i = 0; i < nbItems; i++) {
21182
0
  item = items[i];
21183
0
  switch (item->type) {
21184
0
      case XML_SCHEMA_TYPE_COMPLEX:
21185
0
    xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21186
    /* FIXHFAILURE; */
21187
0
    break;
21188
0
      default:
21189
0
    break;
21190
0
  }
21191
0
    }
21192
0
    if (pctxt->nberrors != 0)
21193
0
  goto exit_error;
21194
    /*
21195
    * URGENT TODO: cos-element-consistent
21196
    */
21197
0
    goto exit;
21198
21199
0
exit_error:
21200
0
    ret = pctxt->err;
21201
0
    goto exit;
21202
21203
0
exit_failure:
21204
0
    ret = -1;
21205
21206
0
exit:
21207
    /*
21208
    * Reset the constructor. This is needed for XSI acquisition, since
21209
    * those items will be processed over and over again for every XSI
21210
    * if not cleared here.
21211
    */
21212
0
    con->bucket = oldbucket;
21213
0
    con->pending->nbItems = 0;
21214
0
    if (con->substGroups != NULL) {
21215
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21216
0
  con->substGroups = NULL;
21217
0
    }
21218
0
    if (con->redefs != NULL) {
21219
0
  xmlSchemaRedefListFree(con->redefs);
21220
0
  con->redefs = NULL;
21221
0
    }
21222
0
    return(ret);
21223
0
}
21224
/**
21225
 * xmlSchemaParse:
21226
 * @ctxt:  a schema validation context
21227
 *
21228
 * parse a schema definition resource and build an internal
21229
 * XML Schema structure which can be used to validate instances.
21230
 *
21231
 * Returns the internal XML Schema structure built from the resource or
21232
 *         NULL in case of error
21233
 */
21234
xmlSchemaPtr
21235
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21236
0
{
21237
0
    xmlSchemaPtr mainSchema = NULL;
21238
0
    xmlSchemaBucketPtr bucket = NULL;
21239
0
    int res;
21240
21241
    /*
21242
    * This one is used if the schema to be parsed was specified via
21243
    * the API; i.e. not automatically by the validated instance document.
21244
    */
21245
21246
0
    if (xmlSchemaInitTypes() < 0)
21247
0
        return (NULL);
21248
21249
0
    if (ctxt == NULL)
21250
0
        return (NULL);
21251
21252
    /* TODO: Init the context. Is this all we need?*/
21253
0
    ctxt->nberrors = 0;
21254
0
    ctxt->err = 0;
21255
0
    ctxt->counter = 0;
21256
21257
    /* Create the *main* schema. */
21258
0
    mainSchema = xmlSchemaNewSchema(ctxt);
21259
0
    if (mainSchema == NULL)
21260
0
  goto exit_failure;
21261
    /*
21262
    * Create the schema constructor.
21263
    */
21264
0
    if (ctxt->constructor == NULL) {
21265
0
  ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21266
0
  if (ctxt->constructor == NULL)
21267
0
      goto exit_failure;
21268
  /* Take ownership of the constructor to be able to free it. */
21269
0
  ctxt->ownsConstructor = 1;
21270
0
    }
21271
0
    ctxt->constructor->mainSchema = mainSchema;
21272
    /*
21273
    * Locate and add the schema document.
21274
    */
21275
0
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21276
0
  ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21277
0
  NULL, NULL, &bucket);
21278
0
    if (res == -1)
21279
0
  goto exit_failure;
21280
0
    if (res != 0)
21281
0
  goto exit;
21282
21283
0
    if (bucket == NULL) {
21284
  /* TODO: Error code, actually we failed to *locate* the schema. */
21285
0
  if (ctxt->URL)
21286
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21287
0
    NULL, NULL,
21288
0
    "Failed to locate the main schema resource at '%s'",
21289
0
    ctxt->URL, NULL);
21290
0
  else
21291
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21292
0
    NULL, NULL,
21293
0
    "Failed to locate the main schema resource",
21294
0
        NULL, NULL);
21295
0
  goto exit;
21296
0
    }
21297
    /* Then do the parsing for good. */
21298
0
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21299
0
  goto exit_failure;
21300
0
    if (ctxt->nberrors != 0)
21301
0
  goto exit;
21302
21303
0
    mainSchema->doc = bucket->doc;
21304
0
    mainSchema->preserve = ctxt->preserve;
21305
21306
0
    ctxt->schema = mainSchema;
21307
21308
0
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21309
0
  goto exit_failure;
21310
21311
    /*
21312
    * TODO: This is not nice, since we cannot distinguish from the
21313
    * result if there was an internal error or not.
21314
    */
21315
0
exit:
21316
0
    if (ctxt->nberrors != 0) {
21317
0
  if (mainSchema) {
21318
0
      xmlSchemaFree(mainSchema);
21319
0
      mainSchema = NULL;
21320
0
  }
21321
0
  if (ctxt->constructor) {
21322
0
      xmlSchemaConstructionCtxtFree(ctxt->constructor);
21323
0
      ctxt->constructor = NULL;
21324
0
      ctxt->ownsConstructor = 0;
21325
0
  }
21326
0
    }
21327
0
    ctxt->schema = NULL;
21328
0
    return(mainSchema);
21329
0
exit_failure:
21330
    /*
21331
    * Quite verbose, but should catch internal errors, which were
21332
    * not communicated.
21333
    */
21334
0
    if (mainSchema) {
21335
0
        xmlSchemaFree(mainSchema);
21336
0
  mainSchema = NULL;
21337
0
    }
21338
0
    if (ctxt->constructor) {
21339
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
21340
0
  ctxt->constructor = NULL;
21341
0
  ctxt->ownsConstructor = 0;
21342
0
    }
21343
0
    PERROR_INT2("xmlSchemaParse",
21344
0
  "An internal error occurred");
21345
0
    ctxt->schema = NULL;
21346
0
    return(NULL);
21347
0
}
21348
21349
/**
21350
 * xmlSchemaSetParserErrors:
21351
 * @ctxt:  a schema validation context
21352
 * @err:  the error callback
21353
 * @warn:  the warning callback
21354
 * @ctx:  contextual data for the callbacks
21355
 *
21356
 * DEPRECATED: Use xmlSchemaSetParserStructuredErrors.
21357
 *
21358
 * Set the callback functions used to handle errors for a validation context
21359
 */
21360
void
21361
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21362
                         xmlSchemaValidityErrorFunc err,
21363
                         xmlSchemaValidityWarningFunc warn, void *ctx)
21364
0
{
21365
0
    if (ctxt == NULL)
21366
0
        return;
21367
0
    ctxt->error = err;
21368
0
    ctxt->warning = warn;
21369
0
    ctxt->errCtxt = ctx;
21370
0
    if (ctxt->vctxt != NULL)
21371
0
  xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21372
0
}
21373
21374
/**
21375
 * xmlSchemaSetParserStructuredErrors:
21376
 * @ctxt:  a schema parser context
21377
 * @serror:  the structured error function
21378
 * @ctx: the functions context
21379
 *
21380
 * Set the structured error callback
21381
 */
21382
void
21383
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21384
           xmlStructuredErrorFunc serror,
21385
           void *ctx)
21386
0
{
21387
0
    if (ctxt == NULL)
21388
0
  return;
21389
0
    ctxt->serror = serror;
21390
0
    ctxt->errCtxt = ctx;
21391
0
    if (ctxt->vctxt != NULL)
21392
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21393
0
}
21394
21395
/**
21396
 * xmlSchemaGetParserErrors:
21397
 * @ctxt:  a XMl-Schema parser context
21398
 * @err: the error callback result
21399
 * @warn: the warning callback result
21400
 * @ctx: contextual data for the callbacks result
21401
 *
21402
 * Get the callback information used to handle errors for a parser context
21403
 *
21404
 * Returns -1 in case of failure, 0 otherwise
21405
 */
21406
int
21407
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21408
       xmlSchemaValidityErrorFunc * err,
21409
       xmlSchemaValidityWarningFunc * warn, void **ctx)
21410
0
{
21411
0
  if (ctxt == NULL)
21412
0
    return(-1);
21413
0
  if (err != NULL)
21414
0
    *err = ctxt->error;
21415
0
  if (warn != NULL)
21416
0
    *warn = ctxt->warning;
21417
0
  if (ctx != NULL)
21418
0
    *ctx = ctxt->errCtxt;
21419
0
  return(0);
21420
0
}
21421
21422
/**
21423
 * xmlSchemaSetResourceLoader:
21424
 * @ctxt:  schema parser
21425
 * @loader:  resource loader
21426
 * @data:  user data which will be passed to the loader
21427
 *
21428
 * Register a callback function that will be called to load documents
21429
 * or external entities.
21430
 *
21431
 * Available since 2.14.0.
21432
 */
21433
void
21434
xmlSchemaSetResourceLoader(xmlSchemaParserCtxtPtr ctxt,
21435
0
                           xmlResourceLoader loader, void *data) {
21436
0
    if (ctxt == NULL)
21437
0
        return;
21438
0
    ctxt->resourceLoader = loader;
21439
0
    ctxt->resourceCtxt = data;
21440
0
}
21441
21442
/**
21443
 * xmlSchemaFacetTypeToString:
21444
 * @type:  the facet type
21445
 *
21446
 * Convert the xmlSchemaTypeType to a char string.
21447
 *
21448
 * Returns the char string representation of the facet type if the
21449
 *     type is a facet and an "Internal Error" string otherwise.
21450
 */
21451
static const xmlChar *
21452
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21453
0
{
21454
0
    switch (type) {
21455
0
        case XML_SCHEMA_FACET_PATTERN:
21456
0
            return (BAD_CAST "pattern");
21457
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21458
0
            return (BAD_CAST "maxExclusive");
21459
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
21460
0
            return (BAD_CAST "maxInclusive");
21461
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
21462
0
            return (BAD_CAST "minExclusive");
21463
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
21464
0
            return (BAD_CAST "minInclusive");
21465
0
        case XML_SCHEMA_FACET_WHITESPACE:
21466
0
            return (BAD_CAST "whiteSpace");
21467
0
        case XML_SCHEMA_FACET_ENUMERATION:
21468
0
            return (BAD_CAST "enumeration");
21469
0
        case XML_SCHEMA_FACET_LENGTH:
21470
0
            return (BAD_CAST "length");
21471
0
        case XML_SCHEMA_FACET_MAXLENGTH:
21472
0
            return (BAD_CAST "maxLength");
21473
0
        case XML_SCHEMA_FACET_MINLENGTH:
21474
0
            return (BAD_CAST "minLength");
21475
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
21476
0
            return (BAD_CAST "totalDigits");
21477
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
21478
0
            return (BAD_CAST "fractionDigits");
21479
0
        default:
21480
0
            break;
21481
0
    }
21482
0
    return (BAD_CAST "Internal Error");
21483
0
}
21484
21485
static xmlSchemaWhitespaceValueType
21486
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21487
0
{
21488
    /*
21489
    * The normalization type can be changed only for types which are derived
21490
    * from xsd:string.
21491
    */
21492
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
21493
  /*
21494
  * Note that we assume a whitespace of preserve for anySimpleType.
21495
  */
21496
0
  if ((type->builtInType == XML_SCHEMAS_STRING) ||
21497
0
      (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21498
0
      return(XML_SCHEMA_WHITESPACE_PRESERVE);
21499
0
  else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21500
0
      return(XML_SCHEMA_WHITESPACE_REPLACE);
21501
0
  else {
21502
      /*
21503
      * For all `atomic` datatypes other than string (and types `derived`
21504
      * by `restriction` from it) the value of whiteSpace is fixed to
21505
      * collapse
21506
      * Note that this includes built-in list datatypes.
21507
      */
21508
0
      return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21509
0
  }
21510
0
    } else if (WXS_IS_LIST(type)) {
21511
  /*
21512
  * For list types the facet "whiteSpace" is fixed to "collapse".
21513
  */
21514
0
  return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21515
0
    } else if (WXS_IS_UNION(type)) {
21516
0
  return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21517
0
    } else if (WXS_IS_ATOMIC(type)) {
21518
0
  if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21519
0
      return (XML_SCHEMA_WHITESPACE_PRESERVE);
21520
0
  else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21521
0
      return (XML_SCHEMA_WHITESPACE_REPLACE);
21522
0
  else
21523
0
      return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21524
0
    }
21525
0
    return (-1);
21526
0
}
21527
21528
/************************************************************************
21529
 *                  *
21530
 *      Simple type validation        *
21531
 *                  *
21532
 ************************************************************************/
21533
21534
21535
/************************************************************************
21536
 *                  *
21537
 *      DOM Validation code       *
21538
 *                  *
21539
 ************************************************************************/
21540
21541
/**
21542
 * xmlSchemaAssembleByLocation:
21543
 * @pctxt:  a schema parser context
21544
 * @vctxt:  a schema validation context
21545
 * @schema: the existing schema
21546
 * @node: the node that fired the assembling
21547
 * @nsName: the namespace name of the new schema
21548
 * @location: the location of the schema
21549
 *
21550
 * Expands an existing schema by an additional schema.
21551
 *
21552
 * Returns 0 if the new schema is correct, a positive error code
21553
 * number otherwise and -1 in case of an internal or API error.
21554
 */
21555
static int
21556
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21557
          xmlSchemaPtr schema,
21558
          xmlNodePtr node,
21559
          const xmlChar *nsName,
21560
          const xmlChar *location)
21561
0
{
21562
0
    int ret = 0;
21563
0
    xmlSchemaParserCtxtPtr pctxt;
21564
0
    xmlSchemaBucketPtr bucket = NULL;
21565
21566
0
    if ((vctxt == NULL) || (schema == NULL))
21567
0
  return (-1);
21568
21569
0
    if (vctxt->pctxt == NULL) {
21570
0
  VERROR_INT("xmlSchemaAssembleByLocation",
21571
0
      "no parser context available");
21572
0
  return(-1);
21573
0
    }
21574
0
    pctxt = vctxt->pctxt;
21575
0
    if (pctxt->constructor == NULL) {
21576
0
  PERROR_INT("xmlSchemaAssembleByLocation",
21577
0
      "no constructor");
21578
0
  return(-1);
21579
0
    }
21580
    /*
21581
    * Acquire the schema document.
21582
    */
21583
0
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21584
0
  location, node);
21585
    /*
21586
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21587
    * the process will automatically change this to
21588
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21589
    */
21590
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21591
0
  location, NULL, NULL, 0, node, NULL, nsName,
21592
0
  &bucket);
21593
0
    if (ret != 0)
21594
0
  return(ret);
21595
0
    if (bucket == NULL) {
21596
  /*
21597
  * Generate a warning that the document could not be located.
21598
  */
21599
0
  xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21600
0
      node, NULL,
21601
0
      "The document at location '%s' could not be acquired",
21602
0
      location, NULL, NULL);
21603
0
  return(ret);
21604
0
    }
21605
    /*
21606
    * The first located schema will be handled as if all other
21607
    * schemas imported by XSI were imported by this first schema.
21608
    */
21609
0
    if ((bucket != NULL) &&
21610
0
  (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21611
0
  WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21612
    /*
21613
    * TODO: Is this handled like an import? I.e. is it not an error
21614
    * if the schema cannot be located?
21615
    */
21616
0
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21617
0
  return(0);
21618
    /*
21619
    * We will reuse the parser context for every schema imported
21620
    * directly via XSI. So reset the context.
21621
    */
21622
0
    pctxt->nberrors = 0;
21623
0
    pctxt->err = 0;
21624
0
    pctxt->doc = bucket->doc;
21625
21626
0
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21627
0
    if (ret == -1) {
21628
0
  pctxt->doc = NULL;
21629
0
  goto exit_failure;
21630
0
    }
21631
    /* Paranoid error channelling. */
21632
0
    if ((ret == 0) && (pctxt->nberrors != 0))
21633
0
  ret = pctxt->err;
21634
0
    if (pctxt->nberrors == 0) {
21635
  /*
21636
  * Only bother to fixup pending components, if there was
21637
  * no error yet.
21638
  * For every XSI acquired schema (and its sub-schemata) we will
21639
  * fixup the components.
21640
  */
21641
0
  xmlSchemaFixupComponents(pctxt, bucket);
21642
0
  ret = pctxt->err;
21643
  /*
21644
  * Not nice, but we need somehow to channel the schema parser
21645
  * error to the validation context.
21646
  */
21647
0
  if ((ret != 0) && (vctxt->err == 0))
21648
0
      vctxt->err = ret;
21649
0
  vctxt->nberrors += pctxt->nberrors;
21650
0
    } else {
21651
  /* Add to validation error sum. */
21652
0
  vctxt->nberrors += pctxt->nberrors;
21653
0
    }
21654
0
    pctxt->doc = NULL;
21655
0
    return(ret);
21656
0
exit_failure:
21657
0
    pctxt->doc = NULL;
21658
0
    return (-1);
21659
0
}
21660
21661
static xmlSchemaAttrInfoPtr
21662
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21663
       int metaType)
21664
0
{
21665
0
    if (vctxt->nbAttrInfos == 0)
21666
0
  return (NULL);
21667
0
    {
21668
0
  int i;
21669
0
  xmlSchemaAttrInfoPtr iattr;
21670
21671
0
  for (i = 0; i < vctxt->nbAttrInfos; i++) {
21672
0
      iattr = vctxt->attrInfos[i];
21673
0
      if (iattr->metaType == metaType)
21674
0
    return (iattr);
21675
0
  }
21676
21677
0
    }
21678
0
    return (NULL);
21679
0
}
21680
21681
/**
21682
 * xmlSchemaAssembleByXSI:
21683
 * @vctxt:  a schema validation context
21684
 *
21685
 * Expands an existing schema by an additional schema using
21686
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21687
 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21688
 * must be set to 1.
21689
 *
21690
 * Returns 0 if the new schema is correct, a positive error code
21691
 * number otherwise and -1 in case of an internal or API error.
21692
 */
21693
static int
21694
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21695
0
{
21696
0
    const xmlChar *cur, *end;
21697
0
    const xmlChar *nsname = NULL, *location;
21698
0
    int ret = 0;
21699
0
    xmlSchemaAttrInfoPtr iattr;
21700
21701
    /*
21702
    * Parse the value; we will assume an even number of values
21703
    * to be given (this is how Xerces and XSV work).
21704
    *
21705
    * URGENT TODO: !! This needs to work for both
21706
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
21707
    * element !!
21708
    */
21709
0
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21710
0
  XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21711
0
    if (iattr == NULL)
21712
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21713
0
  XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21714
0
    if (iattr == NULL)
21715
0
  return (0);
21716
0
    cur = iattr->value;
21717
0
    do {
21718
  /*
21719
  * TODO: Move the string parsing mechanism away from here.
21720
  */
21721
0
  if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21722
      /*
21723
      * Get the namespace name.
21724
      */
21725
0
      while (IS_BLANK_CH(*cur))
21726
0
    cur++;
21727
0
      end = cur;
21728
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21729
0
    end++;
21730
0
      if (end == cur)
21731
0
    break;
21732
      /* TODO: Don't use the schema's dict. */
21733
0
      nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21734
0
      cur = end;
21735
0
  }
21736
  /*
21737
  * Get the URI.
21738
  */
21739
0
  while (IS_BLANK_CH(*cur))
21740
0
      cur++;
21741
0
  end = cur;
21742
0
  while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21743
0
      end++;
21744
0
  if (end == cur) {
21745
0
      if (iattr->metaType ==
21746
0
    XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21747
0
      {
21748
    /*
21749
    * If using @schemaLocation then tuples are expected.
21750
    * I.e. the namespace name *and* the document's URI.
21751
    */
21752
0
    xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21753
0
        iattr->node, NULL,
21754
0
        "The value must consist of tuples: the target namespace "
21755
0
        "name and the document's URI", NULL, NULL, NULL);
21756
0
      }
21757
0
      break;
21758
0
  }
21759
  /* TODO: Don't use the schema's dict. */
21760
0
  location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21761
0
  cur = end;
21762
0
  ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21763
0
      iattr->node, nsname, location);
21764
0
  if (ret == -1) {
21765
0
      VERROR_INT("xmlSchemaAssembleByXSI",
21766
0
    "assembling schemata");
21767
0
      return (-1);
21768
0
  }
21769
0
    } while (*cur != 0);
21770
0
    return (ret);
21771
0
}
21772
21773
static const xmlChar *
21774
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21775
       const xmlChar *prefix)
21776
0
{
21777
0
    if (vctxt->sax != NULL) {
21778
0
  int i, j;
21779
0
  xmlSchemaNodeInfoPtr inode;
21780
21781
0
  for (i = vctxt->depth; i >= 0; i--) {
21782
0
      if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21783
0
    inode = vctxt->elemInfos[i];
21784
0
    for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21785
0
        if (((prefix == NULL) &&
21786
0
          (inode->nsBindings[j] == NULL)) ||
21787
0
      ((prefix != NULL) && xmlStrEqual(prefix,
21788
0
          inode->nsBindings[j]))) {
21789
21790
      /*
21791
      * Note that the namespace bindings are already
21792
      * in a string dict.
21793
      */
21794
0
      return (inode->nsBindings[j+1]);
21795
0
        }
21796
0
    }
21797
0
      }
21798
0
  }
21799
0
  return (NULL);
21800
0
#ifdef LIBXML_READER_ENABLED
21801
0
    } else if (vctxt->reader != NULL) {
21802
0
  xmlChar *nsName;
21803
21804
0
  nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21805
0
  if (nsName != NULL) {
21806
0
      const xmlChar *ret;
21807
21808
0
      ret = xmlDictLookup(vctxt->dict, nsName, -1);
21809
0
      xmlFree(nsName);
21810
0
      return (ret);
21811
0
  } else
21812
0
      return (NULL);
21813
0
#endif
21814
0
    } else {
21815
0
  xmlNsPtr ns;
21816
21817
0
  if ((vctxt->inode->node == NULL) ||
21818
0
      (vctxt->inode->node->doc == NULL)) {
21819
0
      VERROR_INT("xmlSchemaLookupNamespace",
21820
0
    "no node or node's doc available");
21821
0
      return (NULL);
21822
0
  }
21823
0
  ns = xmlSearchNs(vctxt->inode->node->doc,
21824
0
      vctxt->inode->node, prefix);
21825
0
  if (ns != NULL)
21826
0
      return (ns->href);
21827
0
  return (NULL);
21828
0
    }
21829
0
}
21830
21831
/*
21832
* This one works on the schema of the validation context.
21833
*/
21834
static int
21835
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21836
        xmlSchemaPtr schema,
21837
        xmlNodePtr node,
21838
        const xmlChar *value,
21839
        xmlSchemaValPtr *val,
21840
        int valNeeded)
21841
0
{
21842
0
    int ret;
21843
21844
0
    if (vctxt && (vctxt->schema == NULL)) {
21845
0
  VERROR_INT("xmlSchemaValidateNotation",
21846
0
      "a schema is needed on the validation context");
21847
0
  return (-1);
21848
0
    }
21849
0
    ret = xmlValidateQName(value, 1);
21850
0
    if (ret != 0)
21851
0
  return (ret);
21852
0
    {
21853
0
  xmlChar *localName = NULL;
21854
0
  xmlChar *prefix = NULL;
21855
21856
0
  localName = xmlSplitQName2(value, &prefix);
21857
0
  if (prefix != NULL) {
21858
0
      const xmlChar *nsName = NULL;
21859
21860
0
      if (vctxt != NULL)
21861
0
    nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21862
0
      else if (node != NULL) {
21863
0
    xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21864
0
    if (ns != NULL)
21865
0
        nsName = ns->href;
21866
0
      } else {
21867
0
    xmlFree(prefix);
21868
0
    xmlFree(localName);
21869
0
    return (1);
21870
0
      }
21871
0
      if (nsName == NULL) {
21872
0
    xmlFree(prefix);
21873
0
    xmlFree(localName);
21874
0
    return (1);
21875
0
      }
21876
0
      if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21877
0
    if ((valNeeded) && (val != NULL)) {
21878
0
        (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21879
0
                   xmlStrdup(nsName));
21880
0
        if (*val == NULL)
21881
0
      ret = -1;
21882
0
    }
21883
0
      } else
21884
0
    ret = 1;
21885
0
      xmlFree(prefix);
21886
0
      xmlFree(localName);
21887
0
  } else {
21888
0
      if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21889
0
    if (valNeeded && (val != NULL)) {
21890
0
        (*val) = xmlSchemaNewNOTATIONValue(
21891
0
      BAD_CAST xmlStrdup(value), NULL);
21892
0
        if (*val == NULL)
21893
0
      ret = -1;
21894
0
    }
21895
0
      } else
21896
0
    return (1);
21897
0
  }
21898
0
    }
21899
0
    return (ret);
21900
0
}
21901
21902
static int
21903
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21904
           const xmlChar* lname,
21905
           const xmlChar* nsname)
21906
0
{
21907
0
    int i;
21908
21909
0
    lname = xmlDictLookup(vctxt->dict, lname, -1);
21910
0
    if (lname == NULL)
21911
0
  return(-1);
21912
0
    if (nsname != NULL) {
21913
0
  nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21914
0
  if (nsname == NULL)
21915
0
      return(-1);
21916
0
    }
21917
0
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21918
0
  if ((vctxt->nodeQNames->items [i] == lname) &&
21919
0
      (vctxt->nodeQNames->items[i +1] == nsname))
21920
      /* Already there */
21921
0
      return(i);
21922
0
    }
21923
    /* Add new entry. */
21924
0
    i = vctxt->nodeQNames->nbItems;
21925
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21926
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21927
0
    return(i);
21928
0
}
21929
21930
/************************************************************************
21931
 *                  *
21932
 *  Validation of identity-constraints (IDC)                            *
21933
 *                  *
21934
 ************************************************************************/
21935
21936
/**
21937
 * xmlSchemaAugmentIDC:
21938
 * @idcDef: the IDC definition
21939
 *
21940
 * Creates an augmented IDC definition item.
21941
 *
21942
 * Returns the item, or NULL on internal errors.
21943
 */
21944
static void
21945
xmlSchemaAugmentIDC(void *payload, void *data,
21946
                    const xmlChar *name ATTRIBUTE_UNUSED)
21947
0
{
21948
0
    xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
21949
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21950
0
    xmlSchemaIDCAugPtr aidc;
21951
21952
0
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21953
0
    if (aidc == NULL) {
21954
0
  xmlSchemaVErrMemory(vctxt);
21955
0
  return;
21956
0
    }
21957
0
    aidc->keyrefDepth = -1;
21958
0
    aidc->def = idcDef;
21959
0
    aidc->next = NULL;
21960
0
    if (vctxt->aidcs == NULL)
21961
0
  vctxt->aidcs = aidc;
21962
0
    else {
21963
0
  aidc->next = vctxt->aidcs;
21964
0
  vctxt->aidcs = aidc;
21965
0
    }
21966
    /*
21967
    * Save if we have keyrefs at all.
21968
    */
21969
0
    if ((vctxt->hasKeyrefs == 0) &&
21970
0
  (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21971
0
  vctxt->hasKeyrefs = 1;
21972
0
}
21973
21974
/**
21975
 * xmlSchemaAugmentImportedIDC:
21976
 * @imported: the imported schema
21977
 *
21978
 * Creates an augmented IDC definition for the imported schema.
21979
 */
21980
static void
21981
xmlSchemaAugmentImportedIDC(void *payload, void *data,
21982
0
                            const xmlChar *name ATTRIBUTE_UNUSED) {
21983
0
    xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
21984
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21985
0
    if (imported->schema->idcDef != NULL) {
21986
0
      xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
21987
0
    }
21988
0
}
21989
21990
/**
21991
 * xmlSchemaIDCNewBinding:
21992
 * @idcDef: the IDC definition of this binding
21993
 *
21994
 * Creates a new IDC binding.
21995
 *
21996
 * Returns the new IDC binding, NULL on internal errors.
21997
 */
21998
static xmlSchemaPSVIIDCBindingPtr
21999
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22000
0
{
22001
0
    xmlSchemaPSVIIDCBindingPtr ret;
22002
22003
0
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22004
0
      sizeof(xmlSchemaPSVIIDCBinding));
22005
0
    if (ret == NULL) {
22006
0
  xmlSchemaVErrMemory(NULL);
22007
0
  return (NULL);
22008
0
    }
22009
0
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22010
0
    ret->definition = idcDef;
22011
0
    return (ret);
22012
0
}
22013
22014
/**
22015
 * xmlSchemaIDCStoreNodeTableItem:
22016
 * @vctxt: the WXS validation context
22017
 * @item: the IDC node table item
22018
 *
22019
 * The validation context is used to store IDC node table items.
22020
 * They are stored to avoid copying them if IDC node-tables are merged
22021
 * with corresponding parent IDC node-tables (bubbling).
22022
 *
22023
 * Returns 0 if succeeded, -1 on internal errors.
22024
 */
22025
static int
22026
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22027
             xmlSchemaPSVIIDCNodePtr item)
22028
0
{
22029
    /*
22030
    * Add to global list.
22031
    */
22032
0
    if (vctxt->idcNodes == NULL) {
22033
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22034
0
      xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22035
0
  if (vctxt->idcNodes == NULL) {
22036
0
      xmlSchemaVErrMemory(vctxt);
22037
0
      return (-1);
22038
0
  }
22039
0
  vctxt->sizeIdcNodes = 20;
22040
0
    } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22041
0
  vctxt->sizeIdcNodes *= 2;
22042
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22043
0
      xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22044
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
22045
0
  if (vctxt->idcNodes == NULL) {
22046
0
      xmlSchemaVErrMemory(vctxt);
22047
0
      return (-1);
22048
0
  }
22049
0
    }
22050
0
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22051
22052
0
    return (0);
22053
0
}
22054
22055
/**
22056
 * xmlSchemaIDCStoreKey:
22057
 * @vctxt: the WXS validation context
22058
 * @item: the IDC key
22059
 *
22060
 * The validation context is used to store an IDC key.
22061
 *
22062
 * Returns 0 if succeeded, -1 on internal errors.
22063
 */
22064
static int
22065
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22066
         xmlSchemaPSVIIDCKeyPtr key)
22067
0
{
22068
    /*
22069
    * Add to global list.
22070
    */
22071
0
    if (vctxt->idcKeys == NULL) {
22072
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22073
0
      xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22074
0
  if (vctxt->idcKeys == NULL) {
22075
0
      xmlSchemaVErrMemory(vctxt);
22076
0
      return (-1);
22077
0
  }
22078
0
  vctxt->sizeIdcKeys = 40;
22079
0
    } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22080
0
  vctxt->sizeIdcKeys *= 2;
22081
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22082
0
      xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22083
0
      sizeof(xmlSchemaPSVIIDCKeyPtr));
22084
0
  if (vctxt->idcKeys == NULL) {
22085
0
      xmlSchemaVErrMemory(vctxt);
22086
0
      return (-1);
22087
0
  }
22088
0
    }
22089
0
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22090
22091
0
    return (0);
22092
0
}
22093
22094
/**
22095
 * xmlSchemaIDCAppendNodeTableItem:
22096
 * @bind: the IDC binding
22097
 * @ntItem: the node-table item
22098
 *
22099
 * Appends the IDC node-table item to the binding.
22100
 *
22101
 * Returns 0 on success and -1 on internal errors.
22102
 */
22103
static int
22104
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22105
        xmlSchemaPSVIIDCNodePtr ntItem)
22106
0
{
22107
0
    if (bind->nodeTable == NULL) {
22108
0
  bind->sizeNodes = 10;
22109
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22110
0
      xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22111
0
  if (bind->nodeTable == NULL) {
22112
0
      xmlSchemaVErrMemory(NULL);
22113
0
      return(-1);
22114
0
  }
22115
0
    } else if (bind->sizeNodes <= bind->nbNodes) {
22116
0
  bind->sizeNodes *= 2;
22117
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22118
0
      xmlRealloc(bind->nodeTable, bind->sizeNodes *
22119
0
    sizeof(xmlSchemaPSVIIDCNodePtr));
22120
0
  if (bind->nodeTable == NULL) {
22121
0
      xmlSchemaVErrMemory(NULL);
22122
0
      return(-1);
22123
0
  }
22124
0
    }
22125
0
    bind->nodeTable[bind->nbNodes++] = ntItem;
22126
0
    return(0);
22127
0
}
22128
22129
/**
22130
 * xmlSchemaIDCAcquireBinding:
22131
 * @vctxt: the WXS validation context
22132
 * @matcher: the IDC matcher
22133
 *
22134
 * Looks up an PSVI IDC binding, for the IDC definition and
22135
 * of the given matcher. If none found, a new one is created
22136
 * and added to the IDC table.
22137
 *
22138
 * Returns an IDC binding or NULL on internal errors.
22139
 */
22140
static xmlSchemaPSVIIDCBindingPtr
22141
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22142
        xmlSchemaIDCMatcherPtr matcher)
22143
0
{
22144
0
    xmlSchemaNodeInfoPtr ielem;
22145
22146
0
    ielem = vctxt->elemInfos[matcher->depth];
22147
22148
0
    if (ielem->idcTable == NULL) {
22149
0
  ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22150
0
  if (ielem->idcTable == NULL)
22151
0
      return (NULL);
22152
0
  return(ielem->idcTable);
22153
0
    } else {
22154
0
  xmlSchemaPSVIIDCBindingPtr bind = NULL;
22155
22156
0
  bind = ielem->idcTable;
22157
0
  do {
22158
0
      if (bind->definition == matcher->aidc->def)
22159
0
    return(bind);
22160
0
      if (bind->next == NULL) {
22161
0
    bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22162
0
    if (bind->next == NULL)
22163
0
        return (NULL);
22164
0
    return(bind->next);
22165
0
      }
22166
0
      bind = bind->next;
22167
0
  } while (bind != NULL);
22168
0
    }
22169
0
    return (NULL);
22170
0
}
22171
22172
static xmlSchemaItemListPtr
22173
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22174
           xmlSchemaIDCMatcherPtr matcher)
22175
0
{
22176
0
    if (matcher->targets == NULL)
22177
0
  matcher->targets = xmlSchemaItemListCreate();
22178
0
    return(matcher->targets);
22179
0
}
22180
22181
/**
22182
 * xmlSchemaIDCFreeKey:
22183
 * @key: the IDC key
22184
 *
22185
 * Frees an IDC key together with its compiled value.
22186
 */
22187
static void
22188
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22189
0
{
22190
0
    if (key->val != NULL)
22191
0
  xmlSchemaFreeValue(key->val);
22192
0
    xmlFree(key);
22193
0
}
22194
22195
/**
22196
 * xmlSchemaIDCFreeBinding:
22197
 *
22198
 * Frees an IDC binding. Note that the node table-items
22199
 * are not freed.
22200
 */
22201
static void
22202
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22203
0
{
22204
0
    if (bind->nodeTable != NULL)
22205
0
  xmlFree(bind->nodeTable);
22206
0
    if (bind->dupls != NULL)
22207
0
  xmlSchemaItemListFree(bind->dupls);
22208
0
    xmlFree(bind);
22209
0
}
22210
22211
/**
22212
 * xmlSchemaIDCFreeIDCTable:
22213
 * @bind: the first IDC binding in the list
22214
 *
22215
 * Frees an IDC table, i.e. all the IDC bindings in the list.
22216
 */
22217
static void
22218
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22219
0
{
22220
0
    xmlSchemaPSVIIDCBindingPtr prev;
22221
22222
0
    while (bind != NULL) {
22223
0
  prev = bind;
22224
0
  bind = bind->next;
22225
0
  xmlSchemaIDCFreeBinding(prev);
22226
0
    }
22227
0
}
22228
22229
static void
22230
xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
22231
0
{
22232
0
    xmlIDCHashEntryPtr e = payload, n;
22233
0
    while (e) {
22234
0
  n = e->next;
22235
0
  xmlFree(e);
22236
0
  e = n;
22237
0
    }
22238
0
}
22239
22240
/**
22241
 * xmlSchemaIDCFreeMatcherList:
22242
 * @matcher: the first IDC matcher in the list
22243
 *
22244
 * Frees a list of IDC matchers.
22245
 */
22246
static void
22247
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22248
0
{
22249
0
    xmlSchemaIDCMatcherPtr next;
22250
22251
0
    while (matcher != NULL) {
22252
0
  next = matcher->next;
22253
0
  if (matcher->keySeqs != NULL) {
22254
0
      int i;
22255
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22256
0
    if (matcher->keySeqs[i] != NULL)
22257
0
        xmlFree(matcher->keySeqs[i]);
22258
0
      xmlFree(matcher->keySeqs);
22259
0
  }
22260
0
  if (matcher->targets != NULL) {
22261
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22262
0
    int i;
22263
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22264
    /*
22265
    * Node-table items for keyrefs are not stored globally
22266
    * to the validation context, since they are not bubbled.
22267
    * We need to free them here.
22268
    */
22269
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22270
0
        idcNode =
22271
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22272
0
        xmlFree(idcNode->keys);
22273
0
        xmlFree(idcNode);
22274
0
    }
22275
0
      }
22276
0
      xmlSchemaItemListFree(matcher->targets);
22277
0
  }
22278
0
  if (matcher->htab != NULL)
22279
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22280
0
  xmlFree(matcher);
22281
0
  matcher = next;
22282
0
    }
22283
0
}
22284
22285
/**
22286
 * xmlSchemaIDCReleaseMatcherList:
22287
 * @vctxt: the WXS validation context
22288
 * @matcher: the first IDC matcher in the list
22289
 *
22290
 * Caches a list of IDC matchers for reuse.
22291
 */
22292
static void
22293
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22294
             xmlSchemaIDCMatcherPtr matcher)
22295
0
{
22296
0
    xmlSchemaIDCMatcherPtr next;
22297
22298
0
    while (matcher != NULL) {
22299
0
  next = matcher->next;
22300
0
  if (matcher->keySeqs != NULL) {
22301
0
      int i;
22302
      /*
22303
      * Don't free the array, but only the content.
22304
      */
22305
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22306
0
    if (matcher->keySeqs[i] != NULL) {
22307
0
        xmlFree(matcher->keySeqs[i]);
22308
0
        matcher->keySeqs[i] = NULL;
22309
0
    }
22310
0
  }
22311
0
  if (matcher->targets) {
22312
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22313
0
    int i;
22314
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22315
    /*
22316
    * Node-table items for keyrefs are not stored globally
22317
    * to the validation context, since they are not bubbled.
22318
    * We need to free them here.
22319
    */
22320
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22321
0
        idcNode =
22322
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22323
0
        xmlFree(idcNode->keys);
22324
0
        xmlFree(idcNode);
22325
0
    }
22326
0
      }
22327
0
      xmlSchemaItemListFree(matcher->targets);
22328
0
      matcher->targets = NULL;
22329
0
  }
22330
0
  if (matcher->htab != NULL) {
22331
0
      xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22332
0
      matcher->htab = NULL;
22333
0
  }
22334
0
  matcher->next = NULL;
22335
  /*
22336
  * Cache the matcher.
22337
  */
22338
0
  if (vctxt->idcMatcherCache != NULL)
22339
0
      matcher->nextCached = vctxt->idcMatcherCache;
22340
0
  vctxt->idcMatcherCache = matcher;
22341
22342
0
  matcher = next;
22343
0
    }
22344
0
}
22345
22346
/**
22347
 * xmlSchemaIDCAddStateObject:
22348
 * @vctxt: the WXS validation context
22349
 * @matcher: the IDC matcher
22350
 * @sel: the XPath information
22351
 * @parent: the parent "selector" state object if any
22352
 * @type: "selector" or "field"
22353
 *
22354
 * Creates/reuses and activates state objects for the given
22355
 * XPath information; if the XPath expression consists of unions,
22356
 * multiple state objects are created for every unioned expression.
22357
 *
22358
 * Returns 0 on success and -1 on internal errors.
22359
 */
22360
static int
22361
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22362
      xmlSchemaIDCMatcherPtr matcher,
22363
      xmlSchemaIDCSelectPtr sel,
22364
      int type)
22365
0
{
22366
0
    xmlSchemaIDCStateObjPtr sto;
22367
22368
    /*
22369
    * Reuse the state objects from the pool.
22370
    */
22371
0
    if (vctxt->xpathStatePool != NULL) {
22372
0
  sto = vctxt->xpathStatePool;
22373
0
  vctxt->xpathStatePool = sto->next;
22374
0
  sto->next = NULL;
22375
0
    } else {
22376
  /*
22377
  * Create a new state object.
22378
  */
22379
0
  sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22380
0
  if (sto == NULL) {
22381
0
      xmlSchemaVErrMemory(NULL);
22382
0
      return (-1);
22383
0
  }
22384
0
  memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22385
0
    }
22386
    /*
22387
    * Add to global list.
22388
    */
22389
0
    if (vctxt->xpathStates != NULL)
22390
0
  sto->next = vctxt->xpathStates;
22391
0
    vctxt->xpathStates = sto;
22392
22393
    /*
22394
    * Free the old xpath validation context.
22395
    */
22396
0
    if (sto->xpathCtxt != NULL)
22397
0
  xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22398
22399
    /*
22400
    * Create a new XPath (pattern) validation context.
22401
    */
22402
0
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22403
0
  (xmlPatternPtr) sel->xpathComp);
22404
0
    if (sto->xpathCtxt == NULL) {
22405
0
  VERROR_INT("xmlSchemaIDCAddStateObject",
22406
0
      "failed to create an XPath validation context");
22407
0
  return (-1);
22408
0
    }
22409
0
    sto->type = type;
22410
0
    sto->depth = vctxt->depth;
22411
0
    sto->matcher = matcher;
22412
0
    sto->sel = sel;
22413
0
    sto->nbHistory = 0;
22414
22415
0
    return (0);
22416
0
}
22417
22418
/**
22419
 * xmlSchemaXPathEvaluate:
22420
 * @vctxt: the WXS validation context
22421
 * @nodeType: the nodeType of the current node
22422
 *
22423
 * Evaluates all active XPath state objects.
22424
 *
22425
 * Returns the number of IC "field" state objects which resolved to
22426
 * this node, 0 if none resolved and -1 on internal errors.
22427
 */
22428
static int
22429
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22430
           xmlElementType nodeType)
22431
0
{
22432
0
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22433
0
    int res, resolved = 0, depth = vctxt->depth;
22434
22435
0
    if (vctxt->xpathStates == NULL)
22436
0
  return (0);
22437
22438
0
    if (nodeType == XML_ATTRIBUTE_NODE)
22439
0
  depth++;
22440
    /*
22441
    * Process all active XPath state objects.
22442
    */
22443
0
    first = vctxt->xpathStates;
22444
0
    sto = first;
22445
0
    while (sto != head) {
22446
0
  if (nodeType == XML_ELEMENT_NODE)
22447
0
      res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22448
0
    vctxt->inode->localName, vctxt->inode->nsName);
22449
0
  else
22450
0
      res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22451
0
    vctxt->inode->localName, vctxt->inode->nsName);
22452
22453
0
  if (res == -1) {
22454
0
      VERROR_INT("xmlSchemaXPathEvaluate",
22455
0
    "calling xmlStreamPush()");
22456
0
      return (-1);
22457
0
  }
22458
0
  if (res == 0)
22459
0
      goto next_sto;
22460
  /*
22461
  * Full match.
22462
  */
22463
  /*
22464
  * Register a match in the state object history.
22465
  */
22466
0
  if (sto->history == NULL) {
22467
0
      sto->history = (int *) xmlMalloc(5 * sizeof(int));
22468
0
      if (sto->history == NULL) {
22469
0
    xmlSchemaVErrMemory(NULL);
22470
0
    return(-1);
22471
0
      }
22472
0
      sto->sizeHistory = 5;
22473
0
  } else if (sto->sizeHistory <= sto->nbHistory) {
22474
0
      sto->sizeHistory *= 2;
22475
0
      sto->history = (int *) xmlRealloc(sto->history,
22476
0
    sto->sizeHistory * sizeof(int));
22477
0
      if (sto->history == NULL) {
22478
0
    xmlSchemaVErrMemory(NULL);
22479
0
    return(-1);
22480
0
      }
22481
0
  }
22482
0
  sto->history[sto->nbHistory++] = depth;
22483
22484
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22485
0
      xmlSchemaIDCSelectPtr sel;
22486
      /*
22487
      * Activate state objects for the IDC fields of
22488
      * the IDC selector.
22489
      */
22490
0
      sel = sto->matcher->aidc->def->fields;
22491
0
      while (sel != NULL) {
22492
0
    if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22493
0
        sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22494
0
        return (-1);
22495
0
    sel = sel->next;
22496
0
      }
22497
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22498
      /*
22499
      * An IDC key node was found by the IDC field.
22500
      */
22501
      /*
22502
      * Notify that the character value of this node is
22503
      * needed.
22504
      */
22505
0
      if (resolved == 0) {
22506
0
    if ((vctxt->inode->flags &
22507
0
        XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22508
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22509
0
      }
22510
0
      resolved++;
22511
0
  }
22512
0
next_sto:
22513
0
  if (sto->next == NULL) {
22514
      /*
22515
      * Evaluate field state objects created on this node as well.
22516
      */
22517
0
      head = first;
22518
0
      sto = vctxt->xpathStates;
22519
0
  } else
22520
0
      sto = sto->next;
22521
0
    }
22522
0
    return (resolved);
22523
0
}
22524
22525
static const xmlChar *
22526
xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22527
        xmlChar **buf,
22528
        xmlSchemaPSVIIDCKeyPtr *seq,
22529
        int count, int for_hash)
22530
0
{
22531
0
    int i, res;
22532
0
    xmlChar *value = NULL;
22533
22534
0
    *buf = xmlStrdup(BAD_CAST "[");
22535
0
    for (i = 0; i < count; i++) {
22536
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
22537
0
  if (!for_hash)
22538
0
      res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22539
0
        xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22540
0
        &value);
22541
0
  else {
22542
0
      res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22543
0
  }
22544
0
  if (res == 0)
22545
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
22546
0
  else {
22547
0
      VERROR_INT("xmlSchemaFormatIDCKeySequence",
22548
0
    "failed to compute a canonical value");
22549
0
      *buf = xmlStrcat(*buf, BAD_CAST "???");
22550
0
  }
22551
0
  if (i < count -1)
22552
0
      *buf = xmlStrcat(*buf, BAD_CAST "', ");
22553
0
  else
22554
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
22555
0
  if (value != NULL) {
22556
0
      xmlFree(value);
22557
0
      value = NULL;
22558
0
  }
22559
0
    }
22560
0
    *buf = xmlStrcat(*buf, BAD_CAST "]");
22561
22562
0
    return (BAD_CAST *buf);
22563
0
}
22564
22565
static const xmlChar *
22566
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22567
            xmlChar **buf,
22568
            xmlSchemaPSVIIDCKeyPtr *seq,
22569
            int count)
22570
0
{
22571
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22572
0
}
22573
22574
static const xmlChar *
22575
xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22576
       xmlChar **buf,
22577
       xmlSchemaPSVIIDCKeyPtr *seq,
22578
       int count)
22579
0
{
22580
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22581
0
}
22582
22583
/**
22584
 * xmlSchemaXPathPop:
22585
 * @vctxt: the WXS validation context
22586
 *
22587
 * Pops all XPath states.
22588
 *
22589
 * Returns 0 on success and -1 on internal errors.
22590
 */
22591
static int
22592
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22593
0
{
22594
0
    xmlSchemaIDCStateObjPtr sto;
22595
0
    int res;
22596
22597
0
    if (vctxt->xpathStates == NULL)
22598
0
  return(0);
22599
0
    sto = vctxt->xpathStates;
22600
0
    do {
22601
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22602
0
  if (res == -1)
22603
0
      return (-1);
22604
0
  sto = sto->next;
22605
0
    } while (sto != NULL);
22606
0
    return(0);
22607
0
}
22608
22609
/**
22610
 * xmlSchemaXPathProcessHistory:
22611
 * @vctxt: the WXS validation context
22612
 * @type: the simple/complex type of the current node if any at all
22613
 * @val: the precompiled value
22614
 *
22615
 * Processes and pops the history items of the IDC state objects.
22616
 * IDC key-sequences are validated/created on IDC bindings.
22617
 *
22618
 * Returns 0 on success and -1 on internal errors.
22619
 */
22620
static int
22621
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22622
           int depth)
22623
0
{
22624
0
    xmlSchemaIDCStateObjPtr sto, nextsto;
22625
0
    int res, matchDepth;
22626
0
    xmlSchemaPSVIIDCKeyPtr key = NULL;
22627
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22628
22629
0
    if (vctxt->xpathStates == NULL)
22630
0
  return (0);
22631
0
    sto = vctxt->xpathStates;
22632
22633
    /*
22634
    * Evaluate the state objects.
22635
    */
22636
0
    while (sto != NULL) {
22637
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22638
0
  if (res == -1) {
22639
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22640
0
    "calling xmlStreamPop()");
22641
0
      return (-1);
22642
0
  }
22643
0
  if (sto->nbHistory == 0)
22644
0
      goto deregister_check;
22645
22646
0
  matchDepth = sto->history[sto->nbHistory -1];
22647
22648
  /*
22649
  * Only matches at the current depth are of interest.
22650
  */
22651
0
  if (matchDepth != depth) {
22652
0
      sto = sto->next;
22653
0
      continue;
22654
0
  }
22655
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22656
      /*
22657
      * NOTE: According to
22658
      *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22659
      *   ... the simple-content of complex types is also allowed.
22660
      */
22661
22662
0
      if (WXS_IS_COMPLEX(type)) {
22663
0
    if (WXS_HAS_SIMPLE_CONTENT(type)) {
22664
        /*
22665
        * Sanity check for complex types with simple content.
22666
        */
22667
0
        simpleType = type->contentTypeDef;
22668
0
        if (simpleType == NULL) {
22669
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22670
0
          "field resolves to a CT with simple content "
22671
0
          "but the CT is missing the ST definition");
22672
0
      return (-1);
22673
0
        }
22674
0
    } else
22675
0
        simpleType = NULL;
22676
0
      } else
22677
0
    simpleType = type;
22678
0
      if (simpleType == NULL) {
22679
0
    xmlChar *str = NULL;
22680
22681
    /*
22682
    * Not qualified if the field resolves to a node of non
22683
    * simple type.
22684
    */
22685
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22686
0
        XML_SCHEMAV_CVC_IDC, NULL,
22687
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22688
0
        "The XPath '%s' of a field of %s does evaluate to a node of "
22689
0
        "non-simple type",
22690
0
        sto->sel->xpath,
22691
0
        xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22692
0
    FREE_AND_NULL(str);
22693
0
    sto->nbHistory--;
22694
0
    goto deregister_check;
22695
0
      }
22696
22697
0
      if ((key == NULL) && (vctxt->inode->val == NULL)) {
22698
    /*
22699
    * Failed to provide the normalized value; maybe
22700
    * the value was invalid.
22701
    */
22702
0
    VERROR(XML_SCHEMAV_CVC_IDC,
22703
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22704
0
        "Warning: No precomputed value available, the value "
22705
0
        "was either invalid or something strange happened");
22706
0
    sto->nbHistory--;
22707
0
    goto deregister_check;
22708
0
      } else {
22709
0
    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22710
0
    xmlSchemaPSVIIDCKeyPtr *keySeq;
22711
0
    int pos, idx;
22712
22713
    /*
22714
    * The key will be anchored on the matcher's list of
22715
    * key-sequences. The position in this list is determined
22716
    * by the target node's depth relative to the matcher's
22717
    * depth of creation (i.e. the depth of the scope element).
22718
    *
22719
    * Element        Depth    Pos   List-entries
22720
    * <scope>          0              NULL
22721
    *   <bar>          1              NULL
22722
    *     <target/>    2       2      target
22723
    *   <bar>
22724
                * </scope>
22725
    *
22726
    * The size of the list is only dependent on the depth of
22727
    * the tree.
22728
    * An entry will be NULLed in selector_leave, i.e. when
22729
    * we hit the target's
22730
    */
22731
0
    pos = sto->depth - matcher->depth;
22732
0
    idx = sto->sel->index;
22733
22734
    /*
22735
    * Create/grow the array of key-sequences.
22736
    */
22737
0
    if (matcher->keySeqs == NULL) {
22738
0
        if (pos > 9)
22739
0
      matcher->sizeKeySeqs = pos * 2;
22740
0
        else
22741
0
      matcher->sizeKeySeqs = 10;
22742
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22743
0
      xmlMalloc(matcher->sizeKeySeqs *
22744
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22745
0
        if (matcher->keySeqs == NULL) {
22746
0
      xmlSchemaVErrMemory(NULL);
22747
0
      return(-1);
22748
0
        }
22749
0
        memset(matcher->keySeqs, 0,
22750
0
      matcher->sizeKeySeqs *
22751
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22752
0
    } else if (pos >= matcher->sizeKeySeqs) {
22753
0
        int i = matcher->sizeKeySeqs;
22754
22755
0
        matcher->sizeKeySeqs = pos * 2;
22756
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22757
0
      xmlRealloc(matcher->keySeqs,
22758
0
      matcher->sizeKeySeqs *
22759
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22760
0
        if (matcher->keySeqs == NULL) {
22761
0
      xmlSchemaVErrMemory(NULL);
22762
0
      return (-1);
22763
0
        }
22764
        /*
22765
        * The array needs to be NULLed.
22766
        * TODO: Use memset?
22767
        */
22768
0
        for (; i < matcher->sizeKeySeqs; i++)
22769
0
      matcher->keySeqs[i] = NULL;
22770
0
    }
22771
22772
    /*
22773
    * Get/create the key-sequence.
22774
    */
22775
0
    keySeq = matcher->keySeqs[pos];
22776
0
    if (keySeq == NULL) {
22777
0
        goto create_sequence;
22778
0
    } else if (keySeq[idx] != NULL) {
22779
0
        xmlChar *str = NULL;
22780
        /*
22781
        * cvc-identity-constraint:
22782
        * 3 For each node in the `target node set` all
22783
        * of the {fields}, with that node as the context
22784
        * node, evaluate to either an empty node-set or
22785
        * a node-set with exactly one member, which must
22786
        * have a simple type.
22787
        *
22788
        * The key was already set; report an error.
22789
        */
22790
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22791
0
      XML_SCHEMAV_CVC_IDC, NULL,
22792
0
      WXS_BASIC_CAST matcher->aidc->def,
22793
0
      "The XPath '%s' of a field of %s evaluates to a "
22794
0
      "node-set with more than one member",
22795
0
      sto->sel->xpath,
22796
0
      xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22797
0
        FREE_AND_NULL(str);
22798
0
        sto->nbHistory--;
22799
0
        goto deregister_check;
22800
0
    } else
22801
0
        goto create_key;
22802
22803
0
create_sequence:
22804
    /*
22805
    * Create a key-sequence.
22806
    */
22807
0
    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22808
0
        matcher->aidc->def->nbFields *
22809
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22810
0
    if (keySeq == NULL) {
22811
0
        xmlSchemaVErrMemory(NULL);
22812
0
        return(-1);
22813
0
    }
22814
0
    memset(keySeq, 0, matcher->aidc->def->nbFields *
22815
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22816
0
    matcher->keySeqs[pos] = keySeq;
22817
0
create_key:
22818
    /*
22819
    * Create a key once per node only.
22820
    */
22821
0
    if (key == NULL) {
22822
0
        key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22823
0
      sizeof(xmlSchemaPSVIIDCKey));
22824
0
        if (key == NULL) {
22825
0
      xmlSchemaVErrMemory(NULL);
22826
0
      xmlFree(keySeq);
22827
0
      matcher->keySeqs[pos] = NULL;
22828
0
      return(-1);
22829
0
        }
22830
        /*
22831
        * Consume the compiled value.
22832
        */
22833
0
        key->type = simpleType;
22834
0
        key->val = vctxt->inode->val;
22835
0
        vctxt->inode->val = NULL;
22836
        /*
22837
        * Store the key in a global list.
22838
        */
22839
0
        if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22840
0
      xmlSchemaIDCFreeKey(key);
22841
0
      return (-1);
22842
0
        }
22843
0
    }
22844
0
    keySeq[idx] = key;
22845
0
      }
22846
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22847
22848
0
      xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22849
      /* xmlSchemaPSVIIDCBindingPtr bind; */
22850
0
      xmlSchemaPSVIIDCNodePtr ntItem;
22851
0
      xmlSchemaIDCMatcherPtr matcher;
22852
0
      xmlSchemaIDCPtr idc;
22853
0
      xmlSchemaItemListPtr targets;
22854
0
      int pos, i, j, nbKeys;
22855
      /*
22856
      * Here we have the following scenario:
22857
      * An IDC 'selector' state object resolved to a target node,
22858
      * during the time this target node was in the
22859
      * ancestor-or-self axis, the 'field' state object(s) looked
22860
      * out for matching nodes to create a key-sequence for this
22861
      * target node. Now we are back to this target node and need
22862
      * to put the key-sequence, together with the target node
22863
      * itself, into the node-table of the corresponding IDC
22864
      * binding.
22865
      */
22866
0
      matcher = sto->matcher;
22867
0
      idc = matcher->aidc->def;
22868
0
      nbKeys = idc->nbFields;
22869
0
      pos = depth - matcher->depth;
22870
      /*
22871
      * Check if the matcher has any key-sequences at all, plus
22872
      * if it has a key-sequence for the current target node.
22873
      */
22874
0
      if ((matcher->keySeqs == NULL) ||
22875
0
    (matcher->sizeKeySeqs <= pos)) {
22876
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22877
0
        goto selector_key_error;
22878
0
    else
22879
0
        goto selector_leave;
22880
0
      }
22881
22882
0
      keySeq = &(matcher->keySeqs[pos]);
22883
0
      if (*keySeq == NULL) {
22884
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22885
0
        goto selector_key_error;
22886
0
    else
22887
0
        goto selector_leave;
22888
0
      }
22889
22890
0
      for (i = 0; i < nbKeys; i++) {
22891
0
    if ((*keySeq)[i] == NULL) {
22892
        /*
22893
        * Not qualified, if not all fields did resolve.
22894
        */
22895
0
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22896
      /*
22897
      * All fields of a "key" IDC must resolve.
22898
      */
22899
0
      goto selector_key_error;
22900
0
        }
22901
0
        goto selector_leave;
22902
0
    }
22903
0
      }
22904
      /*
22905
      * All fields did resolve.
22906
      */
22907
22908
      /*
22909
      * 4.1 If the {identity-constraint category} is unique(/key),
22910
      * then no two members of the `qualified node set` have
22911
      * `key-sequences` whose members are pairwise equal, as
22912
      * defined by Equal in [XML Schemas: Datatypes].
22913
      *
22914
      * Get the IDC binding from the matcher and check for
22915
      * duplicate key-sequences.
22916
      */
22917
#if 0
22918
      bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22919
#endif
22920
0
      targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22921
0
      if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22922
0
    (targets->nbItems != 0)) {
22923
0
    xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22924
0
    xmlIDCHashEntryPtr e;
22925
22926
0
    res = 0;
22927
22928
0
    if (!matcher->htab)
22929
0
        e = NULL;
22930
0
    else {
22931
0
        xmlChar *value = NULL;
22932
0
        xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
22933
0
        e = xmlHashLookup(matcher->htab, value);
22934
0
        FREE_AND_NULL(value);
22935
0
    }
22936
22937
    /*
22938
    * Compare the key-sequences, key by key.
22939
    */
22940
0
    for (;e; e = e->next) {
22941
0
        bkeySeq =
22942
0
      ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
22943
0
        for (j = 0; j < nbKeys; j++) {
22944
0
      ckey = (*keySeq)[j];
22945
0
      bkey = bkeySeq[j];
22946
0
      res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22947
0
      if (res == -1) {
22948
0
          return (-1);
22949
0
      } else if (res == 0) {
22950
          /*
22951
          * One of the keys differs, so the key-sequence
22952
          * won't be equal; get out.
22953
          */
22954
0
          break;
22955
0
      }
22956
0
        }
22957
0
        if (res == 1) {
22958
      /*
22959
      * Duplicate key-sequence found.
22960
      */
22961
0
      break;
22962
0
        }
22963
0
    }
22964
0
    if (e) {
22965
0
        xmlChar *str = NULL, *strB = NULL;
22966
        /*
22967
        * TODO: Try to report the key-sequence.
22968
        */
22969
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22970
0
      XML_SCHEMAV_CVC_IDC, NULL,
22971
0
      WXS_BASIC_CAST idc,
22972
0
      "Duplicate key-sequence %s in %s",
22973
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
22974
0
          (*keySeq), nbKeys),
22975
0
      xmlSchemaGetIDCDesignation(&strB, idc));
22976
0
        FREE_AND_NULL(str);
22977
0
        FREE_AND_NULL(strB);
22978
0
        goto selector_leave;
22979
0
    }
22980
0
      }
22981
      /*
22982
      * Add a node-table item to the IDC binding.
22983
      */
22984
0
      ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
22985
0
    sizeof(xmlSchemaPSVIIDCNode));
22986
0
      if (ntItem == NULL) {
22987
0
    xmlSchemaVErrMemory(NULL);
22988
0
    xmlFree(*keySeq);
22989
0
    *keySeq = NULL;
22990
0
    return(-1);
22991
0
      }
22992
0
      memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
22993
22994
      /*
22995
      * Store the node-table item in a global list.
22996
      */
22997
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22998
0
    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
22999
0
        xmlFree(ntItem);
23000
0
        xmlFree(*keySeq);
23001
0
        *keySeq = NULL;
23002
0
        return (-1);
23003
0
    }
23004
0
    ntItem->nodeQNameID = -1;
23005
0
      } else {
23006
    /*
23007
    * Save a cached QName for this node on the IDC node, to be
23008
    * able to report it, even if the node is not saved.
23009
    */
23010
0
    ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23011
0
        vctxt->inode->localName, vctxt->inode->nsName);
23012
0
    if (ntItem->nodeQNameID == -1) {
23013
0
        xmlFree(ntItem);
23014
0
        xmlFree(*keySeq);
23015
0
        *keySeq = NULL;
23016
0
        return (-1);
23017
0
    }
23018
0
      }
23019
      /*
23020
      * Init the node-table item: Save the node, position and
23021
      * consume the key-sequence.
23022
      */
23023
0
      ntItem->node = vctxt->node;
23024
0
      ntItem->nodeLine = vctxt->inode->nodeLine;
23025
0
      ntItem->keys = *keySeq;
23026
0
      *keySeq = NULL;
23027
#if 0
23028
      if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23029
#endif
23030
0
      if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23031
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23032
        /*
23033
        * Free the item, since keyref items won't be
23034
        * put on a global list.
23035
        */
23036
0
        xmlFree(ntItem->keys);
23037
0
        xmlFree(ntItem);
23038
0
    }
23039
0
    return (-1);
23040
0
      }
23041
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23042
0
    xmlChar *value = NULL;
23043
0
    xmlIDCHashEntryPtr r, e;
23044
0
    if (!matcher->htab)
23045
0
      matcher->htab = xmlHashCreate(4);
23046
0
    xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23047
0
    e = xmlMalloc(sizeof *e);
23048
0
    e->index = targets->nbItems - 1;
23049
0
    r = xmlHashLookup(matcher->htab, value);
23050
0
    if (r) {
23051
0
        e->next = r->next;
23052
0
        r->next = e;
23053
0
    } else {
23054
0
        e->next = NULL;
23055
0
        xmlHashAddEntry(matcher->htab, value, e);
23056
0
    }
23057
0
    FREE_AND_NULL(value);
23058
0
      }
23059
23060
0
      goto selector_leave;
23061
0
selector_key_error:
23062
0
      {
23063
0
    xmlChar *str = NULL;
23064
    /*
23065
    * 4.2.1 (KEY) The `target node set` and the
23066
    * `qualified node set` are equal, that is, every
23067
    * member of the `target node set` is also a member
23068
    * of the `qualified node set` and vice versa.
23069
    */
23070
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
23071
0
        XML_SCHEMAV_CVC_IDC, NULL,
23072
0
        WXS_BASIC_CAST idc,
23073
0
        "Not all fields of %s evaluate to a node",
23074
0
        xmlSchemaGetIDCDesignation(&str, idc), NULL);
23075
0
    FREE_AND_NULL(str);
23076
0
      }
23077
0
selector_leave:
23078
      /*
23079
      * Free the key-sequence if not added to the IDC table.
23080
      */
23081
0
      if ((keySeq != NULL) && (*keySeq != NULL)) {
23082
0
    xmlFree(*keySeq);
23083
0
    *keySeq = NULL;
23084
0
      }
23085
0
  } /* if selector */
23086
23087
0
  sto->nbHistory--;
23088
23089
0
deregister_check:
23090
  /*
23091
  * Deregister state objects if they reach the depth of creation.
23092
  */
23093
0
  if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23094
0
      if (vctxt->xpathStates != sto) {
23095
0
    VERROR_INT("xmlSchemaXPathProcessHistory",
23096
0
        "The state object to be removed is not the first "
23097
0
        "in the list");
23098
0
      }
23099
0
      nextsto = sto->next;
23100
      /*
23101
      * Unlink from the list of active XPath state objects.
23102
      */
23103
0
      vctxt->xpathStates = sto->next;
23104
0
      sto->next = vctxt->xpathStatePool;
23105
      /*
23106
      * Link it to the pool of reusable state objects.
23107
      */
23108
0
      vctxt->xpathStatePool = sto;
23109
0
      sto = nextsto;
23110
0
  } else
23111
0
      sto = sto->next;
23112
0
    } /* while (sto != NULL) */
23113
0
    return (0);
23114
0
}
23115
23116
/**
23117
 * xmlSchemaIDCRegisterMatchers:
23118
 * @vctxt: the WXS validation context
23119
 * @elemDecl: the element declaration
23120
 *
23121
 * Creates helper objects to evaluate IDC selectors/fields
23122
 * successively.
23123
 *
23124
 * Returns 0 if OK and -1 on internal errors.
23125
 */
23126
static int
23127
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23128
           xmlSchemaElementPtr elemDecl)
23129
0
{
23130
0
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
23131
0
    xmlSchemaIDCPtr idc, refIdc;
23132
0
    xmlSchemaIDCAugPtr aidc;
23133
23134
0
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23135
0
    if (idc == NULL)
23136
0
  return (0);
23137
23138
0
    if (vctxt->inode->idcMatchers != NULL) {
23139
0
  VERROR_INT("xmlSchemaIDCRegisterMatchers",
23140
0
      "The chain of IDC matchers is expected to be empty");
23141
0
  return (-1);
23142
0
    }
23143
0
    do {
23144
0
  if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23145
      /*
23146
      * Since IDCs bubbles are expensive we need to know the
23147
      * depth at which the bubbles should stop; this will be
23148
      * the depth of the top-most keyref IDC. If no keyref
23149
      * references a key/unique IDC, the keyrefDepth will
23150
      * be -1, indicating that no bubbles are needed.
23151
      */
23152
0
      refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23153
0
      if (refIdc != NULL) {
23154
    /*
23155
    * Remember that we have keyrefs on this node.
23156
    */
23157
0
    vctxt->inode->hasKeyrefs = 1;
23158
    /*
23159
    * Lookup the referenced augmented IDC info.
23160
    */
23161
0
    aidc = vctxt->aidcs;
23162
0
    while (aidc != NULL) {
23163
0
        if (aidc->def == refIdc)
23164
0
      break;
23165
0
        aidc = aidc->next;
23166
0
    }
23167
0
    if (aidc == NULL) {
23168
0
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
23169
0
      "Could not find an augmented IDC item for an IDC "
23170
0
      "definition");
23171
0
        return (-1);
23172
0
    }
23173
0
    if ((aidc->keyrefDepth == -1) ||
23174
0
        (vctxt->depth < aidc->keyrefDepth))
23175
0
        aidc->keyrefDepth = vctxt->depth;
23176
0
      }
23177
0
  }
23178
  /*
23179
  * Lookup the augmented IDC item for the IDC definition.
23180
  */
23181
0
  aidc = vctxt->aidcs;
23182
0
  while (aidc != NULL) {
23183
0
      if (aidc->def == idc)
23184
0
    break;
23185
0
      aidc = aidc->next;
23186
0
  }
23187
0
  if (aidc == NULL) {
23188
0
      VERROR_INT("xmlSchemaIDCRegisterMatchers",
23189
0
    "Could not find an augmented IDC item for an IDC definition");
23190
0
      return (-1);
23191
0
  }
23192
  /*
23193
  * Create an IDC matcher for every IDC definition.
23194
  */
23195
0
  if (vctxt->idcMatcherCache != NULL) {
23196
      /*
23197
      * Reuse a cached matcher.
23198
      */
23199
0
      matcher = vctxt->idcMatcherCache;
23200
0
      vctxt->idcMatcherCache = matcher->nextCached;
23201
0
      matcher->nextCached = NULL;
23202
0
  } else {
23203
0
      matcher = (xmlSchemaIDCMatcherPtr)
23204
0
    xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23205
0
      if (matcher == NULL) {
23206
0
    xmlSchemaVErrMemory(vctxt);
23207
0
    return (-1);
23208
0
      }
23209
0
      memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23210
0
  }
23211
0
  if (last == NULL)
23212
0
      vctxt->inode->idcMatchers = matcher;
23213
0
  else
23214
0
      last->next = matcher;
23215
0
  last = matcher;
23216
23217
0
  matcher->type = IDC_MATCHER;
23218
0
  matcher->depth = vctxt->depth;
23219
0
  matcher->aidc = aidc;
23220
0
  matcher->idcType = aidc->def->type;
23221
  /*
23222
  * Init the automaton state object.
23223
  */
23224
0
  if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23225
0
      idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23226
0
      return (-1);
23227
23228
0
  idc = idc->next;
23229
0
    } while (idc != NULL);
23230
0
    return (0);
23231
0
}
23232
23233
static int
23234
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23235
         xmlSchemaNodeInfoPtr ielem)
23236
0
{
23237
0
    xmlSchemaPSVIIDCBindingPtr bind;
23238
0
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23239
0
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23240
0
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23241
23242
0
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23243
    /* vctxt->createIDCNodeTables */
23244
0
    while (matcher != NULL) {
23245
  /*
23246
  * Skip keyref IDCs and empty IDC target-lists.
23247
  */
23248
0
  if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23249
0
      WXS_ILIST_IS_EMPTY(matcher->targets))
23250
0
  {
23251
0
      matcher = matcher->next;
23252
0
      continue;
23253
0
  }
23254
  /*
23255
  * If we _want_ the IDC node-table to be created in any case
23256
  * then do so. Otherwise create them only if keyrefs need them.
23257
  */
23258
0
  if ((! vctxt->createIDCNodeTables) &&
23259
0
      ((matcher->aidc->keyrefDepth == -1) ||
23260
0
       (matcher->aidc->keyrefDepth > vctxt->depth)))
23261
0
  {
23262
0
      matcher = matcher->next;
23263
0
      continue;
23264
0
  }
23265
  /*
23266
  * Get/create the IDC binding on this element for the IDC definition.
23267
  */
23268
0
  bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23269
0
  if (bind == NULL)
23270
0
     goto internal_error;
23271
23272
0
  if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23273
0
      dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23274
0
      nbDupls = bind->dupls->nbItems;
23275
0
  } else {
23276
0
      dupls = NULL;
23277
0
      nbDupls = 0;
23278
0
  }
23279
0
  if (bind->nodeTable != NULL) {
23280
0
      nbNodeTable = bind->nbNodes;
23281
0
  } else {
23282
0
      nbNodeTable = 0;
23283
0
  }
23284
23285
0
  if ((nbNodeTable == 0) && (nbDupls == 0)) {
23286
      /*
23287
      * Transfer all IDC target-nodes to the IDC node-table.
23288
      */
23289
0
      bind->nodeTable =
23290
0
    (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23291
0
      bind->sizeNodes = matcher->targets->sizeItems;
23292
0
      bind->nbNodes = matcher->targets->nbItems;
23293
23294
0
      matcher->targets->items = NULL;
23295
0
      matcher->targets->sizeItems = 0;
23296
0
      matcher->targets->nbItems = 0;
23297
0
      if (matcher->htab) {
23298
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23299
0
    matcher->htab = NULL;
23300
0
      }
23301
0
  } else {
23302
      /*
23303
      * Compare the key-sequences and add to the IDC node-table.
23304
      */
23305
0
      nbTargets = matcher->targets->nbItems;
23306
0
      targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23307
0
      nbFields = matcher->aidc->def->nbFields;
23308
0
      i = 0;
23309
0
      do {
23310
0
    keys = targets[i]->keys;
23311
0
    if (nbDupls) {
23312
        /*
23313
        * Search in already found duplicates first.
23314
        */
23315
0
        j = 0;
23316
0
        do {
23317
0
      if (nbFields == 1) {
23318
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23319
0
        dupls[j]->keys[0]->val);
23320
0
          if (res == -1)
23321
0
        goto internal_error;
23322
0
          if (res == 1) {
23323
        /*
23324
        * Equal key-sequence.
23325
        */
23326
0
        goto next_target;
23327
0
          }
23328
0
      } else {
23329
0
          res = 0;
23330
0
          ntkeys = dupls[j]->keys;
23331
0
          for (k = 0; k < nbFields; k++) {
23332
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23333
0
            ntkeys[k]->val);
23334
0
        if (res == -1)
23335
0
            goto internal_error;
23336
0
        if (res == 0) {
23337
            /*
23338
            * One of the keys differs.
23339
            */
23340
0
            break;
23341
0
        }
23342
0
          }
23343
0
          if (res == 1) {
23344
        /*
23345
        * Equal key-sequence found.
23346
        */
23347
0
        goto next_target;
23348
0
          }
23349
0
      }
23350
0
      j++;
23351
0
        } while (j < nbDupls);
23352
0
    }
23353
0
    if (nbNodeTable) {
23354
0
        j = 0;
23355
0
        do {
23356
0
      if (nbFields == 1) {
23357
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23358
0
        bind->nodeTable[j]->keys[0]->val);
23359
0
          if (res == -1)
23360
0
        goto internal_error;
23361
0
          if (res == 0) {
23362
        /*
23363
        * The key-sequence differs.
23364
        */
23365
0
        goto next_node_table_entry;
23366
0
          }
23367
0
      } else {
23368
0
          res = 0;
23369
0
          ntkeys = bind->nodeTable[j]->keys;
23370
0
          for (k = 0; k < nbFields; k++) {
23371
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23372
0
            ntkeys[k]->val);
23373
0
        if (res == -1)
23374
0
            goto internal_error;
23375
0
        if (res == 0) {
23376
            /*
23377
            * One of the keys differs.
23378
            */
23379
0
            goto next_node_table_entry;
23380
0
        }
23381
0
          }
23382
0
      }
23383
      /*
23384
      * Add the duplicate to the list of duplicates.
23385
      */
23386
0
      if (bind->dupls == NULL) {
23387
0
          bind->dupls = xmlSchemaItemListCreate();
23388
0
          if (bind->dupls == NULL)
23389
0
        goto internal_error;
23390
0
      }
23391
0
      if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23392
0
          goto internal_error;
23393
      /*
23394
      * Remove the duplicate entry from the IDC node-table.
23395
      */
23396
0
      bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23397
0
      bind->nbNodes--;
23398
23399
0
      goto next_target;
23400
23401
0
next_node_table_entry:
23402
0
      j++;
23403
0
        } while (j < nbNodeTable);
23404
0
    }
23405
    /*
23406
    * If everything is fine, then add the IDC target-node to
23407
    * the IDC node-table.
23408
    */
23409
0
    if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23410
0
        goto internal_error;
23411
23412
0
next_target:
23413
0
    i++;
23414
0
      } while (i < nbTargets);
23415
0
  }
23416
0
  matcher = matcher->next;
23417
0
    }
23418
0
    return(0);
23419
23420
0
internal_error:
23421
0
    return(-1);
23422
0
}
23423
23424
/**
23425
 * xmlSchemaBubbleIDCNodeTables:
23426
 * @depth: the current tree depth
23427
 *
23428
 * Merges IDC bindings of an element at @depth into the corresponding IDC
23429
 * bindings of its parent element. If a duplicate note-table entry is found,
23430
 * both, the parent node-table entry and child entry are discarded from the
23431
 * node-table of the parent.
23432
 *
23433
 * Returns 0 if OK and -1 on internal errors.
23434
 */
23435
static int
23436
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23437
0
{
23438
0
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23439
0
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23440
0
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23441
0
    xmlSchemaIDCAugPtr aidc;
23442
0
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23443
23444
0
    bind = vctxt->inode->idcTable;
23445
0
    if (bind == NULL) {
23446
  /* Fine, no table, no bubbles. */
23447
0
  return (0);
23448
0
    }
23449
23450
0
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23451
    /*
23452
    * Walk all bindings; create new or add to existing bindings.
23453
    * Remove duplicate key-sequences.
23454
    */
23455
0
    while (bind != NULL) {
23456
23457
0
  if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23458
0
      goto next_binding;
23459
  /*
23460
  * Check if the key/unique IDC table needs to be bubbled.
23461
  */
23462
0
  if (! vctxt->createIDCNodeTables) {
23463
0
      aidc = vctxt->aidcs;
23464
0
      do {
23465
0
    if (aidc->def == bind->definition) {
23466
0
        if ((aidc->keyrefDepth == -1) ||
23467
0
      (aidc->keyrefDepth >= vctxt->depth)) {
23468
0
      goto next_binding;
23469
0
        }
23470
0
        break;
23471
0
    }
23472
0
    aidc = aidc->next;
23473
0
      } while (aidc != NULL);
23474
0
  }
23475
23476
0
  if (parTable != NULL)
23477
0
      parBind = *parTable;
23478
  /*
23479
  * Search a matching parent binding for the
23480
  * IDC definition.
23481
  */
23482
0
  while (parBind != NULL) {
23483
0
      if (parBind->definition == bind->definition)
23484
0
    break;
23485
0
      parBind = parBind->next;
23486
0
  }
23487
23488
0
  if (parBind != NULL) {
23489
      /*
23490
      * Compare every node-table entry of the child node,
23491
      * i.e. the key-sequence within, ...
23492
      */
23493
0
      oldNum = parBind->nbNodes; /* Skip newly added items. */
23494
23495
0
      if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23496
0
    oldDupls = parBind->dupls->nbItems;
23497
0
    dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23498
0
      } else {
23499
0
    dupls = NULL;
23500
0
    oldDupls = 0;
23501
0
      }
23502
23503
0
      parNodes = parBind->nodeTable;
23504
0
      nbFields = bind->definition->nbFields;
23505
23506
0
      for (i = 0; i < bind->nbNodes; i++) {
23507
0
    node = bind->nodeTable[i];
23508
0
    if (node == NULL)
23509
0
        continue;
23510
    /*
23511
    * ...with every key-sequence of the parent node, already
23512
    * evaluated to be a duplicate key-sequence.
23513
    */
23514
0
    if (oldDupls) {
23515
0
        j = 0;
23516
0
        while (j < oldDupls) {
23517
0
      if (nbFields == 1) {
23518
0
          ret = xmlSchemaAreValuesEqual(
23519
0
        node->keys[0]->val,
23520
0
        dupls[j]->keys[0]->val);
23521
0
          if (ret == -1)
23522
0
        goto internal_error;
23523
0
          if (ret == 0) {
23524
0
        j++;
23525
0
        continue;
23526
0
          }
23527
0
      } else {
23528
0
          parNode = dupls[j];
23529
0
          for (k = 0; k < nbFields; k++) {
23530
0
        ret = xmlSchemaAreValuesEqual(
23531
0
            node->keys[k]->val,
23532
0
            parNode->keys[k]->val);
23533
0
        if (ret == -1)
23534
0
            goto internal_error;
23535
0
        if (ret == 0)
23536
0
            break;
23537
0
          }
23538
0
      }
23539
0
      if (ret == 1)
23540
          /* Duplicate found. */
23541
0
          break;
23542
0
      j++;
23543
0
        }
23544
0
        if (j != oldDupls) {
23545
      /* Duplicate found. Skip this entry. */
23546
0
      continue;
23547
0
        }
23548
0
    }
23549
    /*
23550
    * ... and with every key-sequence of the parent node.
23551
    */
23552
0
    if (oldNum) {
23553
0
        j = 0;
23554
0
        while (j < oldNum) {
23555
0
      parNode = parNodes[j];
23556
0
      if (nbFields == 1) {
23557
0
          ret = xmlSchemaAreValuesEqual(
23558
0
        node->keys[0]->val,
23559
0
        parNode->keys[0]->val);
23560
0
          if (ret == -1)
23561
0
        goto internal_error;
23562
0
          if (ret == 0) {
23563
0
        j++;
23564
0
        continue;
23565
0
          }
23566
0
      } else {
23567
0
          for (k = 0; k < nbFields; k++) {
23568
0
        ret = xmlSchemaAreValuesEqual(
23569
0
            node->keys[k]->val,
23570
0
            parNode->keys[k]->val);
23571
0
        if (ret == -1)
23572
0
            goto internal_error;
23573
0
        if (ret == 0)
23574
0
            break;
23575
0
          }
23576
0
      }
23577
0
      if (ret == 1)
23578
          /* Duplicate found. */
23579
0
          break;
23580
0
      j++;
23581
0
        }
23582
0
        if (j != oldNum) {
23583
      /*
23584
      * Handle duplicates. Move the duplicate in
23585
      * the parent's node-table to the list of
23586
      * duplicates.
23587
      */
23588
0
      oldNum--;
23589
0
      parBind->nbNodes--;
23590
      /*
23591
      * Move last old item to pos of duplicate.
23592
      */
23593
0
      parNodes[j] = parNodes[oldNum];
23594
23595
0
      if (parBind->nbNodes != oldNum) {
23596
          /*
23597
          * If new items exist, move last new item to
23598
          * last of old items.
23599
          */
23600
0
          parNodes[oldNum] =
23601
0
        parNodes[parBind->nbNodes];
23602
0
      }
23603
0
      if (parBind->dupls == NULL) {
23604
0
          parBind->dupls = xmlSchemaItemListCreate();
23605
0
          if (parBind->dupls == NULL)
23606
0
        goto internal_error;
23607
0
      }
23608
0
      xmlSchemaItemListAdd(parBind->dupls, parNode);
23609
0
        } else {
23610
      /*
23611
      * Add the node-table entry (node and key-sequence) of
23612
      * the child node to the node table of the parent node.
23613
      */
23614
0
      if (parBind->nodeTable == NULL) {
23615
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23616
0
        xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23617
0
          if (parBind->nodeTable == NULL) {
23618
0
        xmlSchemaVErrMemory(NULL);
23619
0
        goto internal_error;
23620
0
          }
23621
0
          parBind->sizeNodes = 1;
23622
0
      } else if (parBind->nbNodes >= parBind->sizeNodes) {
23623
0
          parBind->sizeNodes *= 2;
23624
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23625
0
        xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23626
0
        sizeof(xmlSchemaPSVIIDCNodePtr));
23627
0
          if (parBind->nodeTable == NULL) {
23628
0
        xmlSchemaVErrMemory(NULL);
23629
0
        goto internal_error;
23630
0
          }
23631
0
      }
23632
0
      parNodes = parBind->nodeTable;
23633
      /*
23634
      * Append the new node-table entry to the 'new node-table
23635
      * entries' section.
23636
      */
23637
0
      parNodes[parBind->nbNodes++] = node;
23638
0
        }
23639
23640
0
    }
23641
23642
0
      }
23643
0
  } else {
23644
      /*
23645
      * No binding for the IDC was found: create a new one and
23646
      * copy all node-tables.
23647
      */
23648
0
      parBind = xmlSchemaIDCNewBinding(bind->definition);
23649
0
      if (parBind == NULL)
23650
0
    goto internal_error;
23651
23652
      /*
23653
      * TODO: Hmm, how to optimize the initial number of
23654
      * allocated entries?
23655
      */
23656
0
      if (bind->nbNodes != 0) {
23657
    /*
23658
    * Add all IDC node-table entries.
23659
    */
23660
0
    if (! vctxt->psviExposeIDCNodeTables) {
23661
        /*
23662
        * Just move the entries.
23663
        * NOTE: this is quite save here, since
23664
        * all the keyref lookups have already been
23665
        * performed.
23666
        */
23667
0
        parBind->nodeTable = bind->nodeTable;
23668
0
        bind->nodeTable = NULL;
23669
0
        parBind->sizeNodes = bind->sizeNodes;
23670
0
        bind->sizeNodes = 0;
23671
0
        parBind->nbNodes = bind->nbNodes;
23672
0
        bind->nbNodes = 0;
23673
0
    } else {
23674
        /*
23675
        * Copy the entries.
23676
        */
23677
0
        parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23678
0
      xmlMalloc(bind->nbNodes *
23679
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
23680
0
        if (parBind->nodeTable == NULL) {
23681
0
      xmlSchemaVErrMemory(NULL);
23682
0
      xmlSchemaIDCFreeBinding(parBind);
23683
0
      goto internal_error;
23684
0
        }
23685
0
        parBind->sizeNodes = bind->nbNodes;
23686
0
        parBind->nbNodes = bind->nbNodes;
23687
0
        memcpy(parBind->nodeTable, bind->nodeTable,
23688
0
      bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23689
0
    }
23690
0
      }
23691
0
      if (bind->dupls) {
23692
    /*
23693
    * Move the duplicates.
23694
    */
23695
0
    if (parBind->dupls != NULL)
23696
0
        xmlSchemaItemListFree(parBind->dupls);
23697
0
    parBind->dupls = bind->dupls;
23698
0
    bind->dupls = NULL;
23699
0
      }
23700
0
            if (parTable != NULL) {
23701
0
                if (*parTable == NULL)
23702
0
                    *parTable = parBind;
23703
0
                else {
23704
0
                    parBind->next = *parTable;
23705
0
                    *parTable = parBind;
23706
0
                }
23707
0
            }
23708
0
  }
23709
23710
0
next_binding:
23711
0
  bind = bind->next;
23712
0
    }
23713
0
    return (0);
23714
23715
0
internal_error:
23716
0
    return(-1);
23717
0
}
23718
23719
/**
23720
 * xmlSchemaCheckCVCIDCKeyRef:
23721
 * @vctxt: the WXS validation context
23722
 * @elemDecl: the element declaration
23723
 *
23724
 * Check the cvc-idc-keyref constraints.
23725
 */
23726
static int
23727
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23728
0
{
23729
0
    xmlSchemaIDCMatcherPtr matcher;
23730
0
    xmlSchemaPSVIIDCBindingPtr bind;
23731
23732
0
    matcher = vctxt->inode->idcMatchers;
23733
    /*
23734
    * Find a keyref.
23735
    */
23736
0
    while (matcher != NULL) {
23737
0
  if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23738
0
      matcher->targets &&
23739
0
      matcher->targets->nbItems)
23740
0
  {
23741
0
      int i, j, k, res, nbFields, hasDupls;
23742
0
      xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23743
0
      xmlSchemaPSVIIDCNodePtr refNode = NULL;
23744
0
      xmlHashTablePtr table = NULL;
23745
23746
0
      nbFields = matcher->aidc->def->nbFields;
23747
23748
      /*
23749
      * Find the IDC node-table for the referenced IDC key/unique.
23750
      */
23751
0
      bind = vctxt->inode->idcTable;
23752
0
      while (bind != NULL) {
23753
0
    if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23754
0
        bind->definition)
23755
0
        break;
23756
0
    bind = bind->next;
23757
0
      }
23758
0
      hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23759
      /*
23760
      * Search for a matching key-sequences.
23761
      */
23762
0
      if (bind) {
23763
0
    table = xmlHashCreate(bind->nbNodes * 2);
23764
0
    for (j = 0; j < bind->nbNodes; j++) {
23765
0
        xmlChar *value;
23766
0
        xmlIDCHashEntryPtr r, e;
23767
0
        keys = bind->nodeTable[j]->keys;
23768
0
        xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
23769
0
        e = xmlMalloc(sizeof *e);
23770
0
        e->index = j;
23771
0
        r = xmlHashLookup(table, value);
23772
0
        if (r) {
23773
0
      e->next = r->next;
23774
0
      r->next = e;
23775
0
        } else {
23776
0
      e->next = NULL;
23777
0
      xmlHashAddEntry(table, value, e);
23778
0
        }
23779
0
        FREE_AND_NULL(value);
23780
0
    }
23781
0
      }
23782
0
      for (i = 0; i < matcher->targets->nbItems; i++) {
23783
0
    res = 0;
23784
0
    refNode = matcher->targets->items[i];
23785
0
    if (bind != NULL) {
23786
0
        xmlChar *value;
23787
0
        xmlIDCHashEntryPtr e;
23788
0
        refKeys = refNode->keys;
23789
0
        xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
23790
0
        e = xmlHashLookup(table, value);
23791
0
        FREE_AND_NULL(value);
23792
0
        res = 0;
23793
0
        for (;e; e = e->next) {
23794
0
      keys = bind->nodeTable[e->index]->keys;
23795
0
      for (k = 0; k < nbFields; k++) {
23796
0
          res = xmlSchemaAreValuesEqual(keys[k]->val,
23797
0
                refKeys[k]->val);
23798
0
          if (res == 0)
23799
0
              break;
23800
0
          else if (res == -1) {
23801
0
        return (-1);
23802
0
          }
23803
0
      }
23804
0
      if (res == 1) {
23805
          /*
23806
           * Match found.
23807
           */
23808
0
          break;
23809
0
      }
23810
0
        }
23811
0
        if ((res == 0) && hasDupls) {
23812
      /*
23813
      * Search in duplicates
23814
      */
23815
0
      for (j = 0; j < bind->dupls->nbItems; j++) {
23816
0
          keys = ((xmlSchemaPSVIIDCNodePtr)
23817
0
        bind->dupls->items[j])->keys;
23818
0
          for (k = 0; k < nbFields; k++) {
23819
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23820
0
            refKeys[k]->val);
23821
0
        if (res == 0)
23822
0
            break;
23823
0
        else if (res == -1) {
23824
0
            return (-1);
23825
0
        }
23826
0
          }
23827
0
          if (res == 1) {
23828
        /*
23829
        * Match in duplicates found.
23830
        */
23831
0
        xmlChar *str = NULL, *strB = NULL;
23832
0
        xmlSchemaKeyrefErr(vctxt,
23833
0
            XML_SCHEMAV_CVC_IDC, refNode,
23834
0
            (xmlSchemaTypePtr) matcher->aidc->def,
23835
0
            "More than one match found for "
23836
0
            "key-sequence %s of keyref '%s'",
23837
0
            xmlSchemaFormatIDCKeySequence(vctxt, &str,
23838
0
          refNode->keys, nbFields),
23839
0
            xmlSchemaGetComponentQName(&strB,
23840
0
          matcher->aidc->def));
23841
0
        FREE_AND_NULL(str);
23842
0
        FREE_AND_NULL(strB);
23843
0
        break;
23844
0
          }
23845
0
      }
23846
0
        }
23847
0
    }
23848
23849
0
    if (res == 0) {
23850
0
        xmlChar *str = NULL, *strB = NULL;
23851
0
        xmlSchemaKeyrefErr(vctxt,
23852
0
      XML_SCHEMAV_CVC_IDC, refNode,
23853
0
      (xmlSchemaTypePtr) matcher->aidc->def,
23854
0
      "No match found for key-sequence %s of keyref '%s'",
23855
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
23856
0
          refNode->keys, nbFields),
23857
0
      xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23858
0
        FREE_AND_NULL(str);
23859
0
        FREE_AND_NULL(strB);
23860
0
    }
23861
0
      }
23862
0
      if (table) {
23863
0
    xmlHashFree(table, xmlFreeIDCHashEntry);
23864
0
      }
23865
0
  }
23866
0
  matcher = matcher->next;
23867
0
    }
23868
    /* TODO: Return an error if any error encountered. */
23869
0
    return (0);
23870
0
}
23871
23872
/************************************************************************
23873
 *                  *
23874
 *      XML Reader validation code                      *
23875
 *                  *
23876
 ************************************************************************/
23877
23878
static xmlSchemaAttrInfoPtr
23879
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23880
0
{
23881
0
    xmlSchemaAttrInfoPtr iattr;
23882
    /*
23883
    * Grow/create list of attribute infos.
23884
    */
23885
0
    if (vctxt->attrInfos == NULL) {
23886
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23887
0
      xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23888
0
  vctxt->sizeAttrInfos = 1;
23889
0
  if (vctxt->attrInfos == NULL) {
23890
0
      xmlSchemaVErrMemory(vctxt);
23891
0
      return (NULL);
23892
0
  }
23893
0
    } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23894
0
  vctxt->sizeAttrInfos++;
23895
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23896
0
      xmlRealloc(vctxt->attrInfos,
23897
0
    vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23898
0
  if (vctxt->attrInfos == NULL) {
23899
0
      xmlSchemaVErrMemory(vctxt);
23900
0
      return (NULL);
23901
0
  }
23902
0
    } else {
23903
0
  iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23904
0
  if (iattr->localName != NULL) {
23905
0
      VERROR_INT("xmlSchemaGetFreshAttrInfo",
23906
0
    "attr info not cleared");
23907
0
      return (NULL);
23908
0
  }
23909
0
  iattr->nodeType = XML_ATTRIBUTE_NODE;
23910
0
  return (iattr);
23911
0
    }
23912
    /*
23913
    * Create an attribute info.
23914
    */
23915
0
    iattr = (xmlSchemaAttrInfoPtr)
23916
0
  xmlMalloc(sizeof(xmlSchemaAttrInfo));
23917
0
    if (iattr == NULL) {
23918
0
  xmlSchemaVErrMemory(vctxt);
23919
0
  return (NULL);
23920
0
    }
23921
0
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23922
0
    iattr->nodeType = XML_ATTRIBUTE_NODE;
23923
0
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23924
23925
0
    return (iattr);
23926
0
}
23927
23928
static int
23929
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23930
      xmlNodePtr attrNode,
23931
      int nodeLine,
23932
      const xmlChar *localName,
23933
      const xmlChar *nsName,
23934
      int ownedNames,
23935
      xmlChar *value,
23936
      int ownedValue)
23937
0
{
23938
0
    xmlSchemaAttrInfoPtr attr;
23939
23940
0
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
23941
0
    if (attr == NULL) {
23942
0
  VERROR_INT("xmlSchemaPushAttribute",
23943
0
      "calling xmlSchemaGetFreshAttrInfo()");
23944
0
  return (-1);
23945
0
    }
23946
0
    attr->node = attrNode;
23947
0
    attr->nodeLine = nodeLine;
23948
0
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23949
0
    attr->localName = localName;
23950
0
    attr->nsName = nsName;
23951
0
    if (ownedNames)
23952
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23953
    /*
23954
    * Evaluate if it's an XSI attribute.
23955
    */
23956
0
    if (nsName != NULL) {
23957
0
  if (xmlStrEqual(localName, BAD_CAST "nil")) {
23958
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23959
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23960
0
      }
23961
0
  } else if (xmlStrEqual(localName, BAD_CAST "type")) {
23962
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23963
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23964
0
      }
23965
0
  } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23966
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23967
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23968
0
      }
23969
0
  } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23970
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23971
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23972
0
      }
23973
0
  } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23974
0
      attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23975
0
  }
23976
0
    }
23977
0
    attr->value = value;
23978
0
    if (ownedValue)
23979
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23980
0
    if (attr->metaType != 0)
23981
0
  attr->state = XML_SCHEMAS_ATTR_META;
23982
0
    return (0);
23983
0
}
23984
23985
/**
23986
 * xmlSchemaClearElemInfo:
23987
 * @vctxt: the WXS validation context
23988
 * @ielem: the element information item
23989
 */
23990
static void
23991
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23992
           xmlSchemaNodeInfoPtr ielem)
23993
0
{
23994
0
    ielem->hasKeyrefs = 0;
23995
0
    ielem->appliedXPath = 0;
23996
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23997
0
  FREE_AND_NULL(ielem->localName);
23998
0
  FREE_AND_NULL(ielem->nsName);
23999
0
    } else {
24000
0
  ielem->localName = NULL;
24001
0
  ielem->nsName = NULL;
24002
0
    }
24003
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24004
0
  FREE_AND_NULL(ielem->value);
24005
0
    } else {
24006
0
  ielem->value = NULL;
24007
0
    }
24008
0
    if (ielem->val != NULL) {
24009
  /*
24010
  * PSVI TODO: Be careful not to free it when the value is
24011
  * exposed via PSVI.
24012
  */
24013
0
  xmlSchemaFreeValue(ielem->val);
24014
0
  ielem->val = NULL;
24015
0
    }
24016
0
    if (ielem->idcMatchers != NULL) {
24017
  /*
24018
  * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24019
  *   Does it work?
24020
  */
24021
0
  xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24022
#if 0
24023
  xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24024
#endif
24025
0
  ielem->idcMatchers = NULL;
24026
0
    }
24027
0
    if (ielem->idcTable != NULL) {
24028
  /*
24029
  * OPTIMIZE TODO: Use a pool of IDC tables??.
24030
  */
24031
0
  xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24032
0
  ielem->idcTable = NULL;
24033
0
    }
24034
0
    if (ielem->regexCtxt != NULL) {
24035
0
  xmlRegFreeExecCtxt(ielem->regexCtxt);
24036
0
  ielem->regexCtxt = NULL;
24037
0
    }
24038
0
    if (ielem->nsBindings != NULL) {
24039
0
  xmlFree((xmlChar **)ielem->nsBindings);
24040
0
  ielem->nsBindings = NULL;
24041
0
  ielem->nbNsBindings = 0;
24042
0
  ielem->sizeNsBindings = 0;
24043
0
    }
24044
0
}
24045
24046
/**
24047
 * xmlSchemaGetFreshElemInfo:
24048
 * @vctxt: the schema validation context
24049
 *
24050
 * Creates/reuses and initializes the element info item for
24051
 * the current tree depth.
24052
 *
24053
 * Returns the element info item or NULL on API or internal errors.
24054
 */
24055
static xmlSchemaNodeInfoPtr
24056
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24057
0
{
24058
0
    xmlSchemaNodeInfoPtr info = NULL;
24059
24060
0
    if (vctxt->depth > vctxt->sizeElemInfos) {
24061
0
  VERROR_INT("xmlSchemaGetFreshElemInfo",
24062
0
      "inconsistent depth encountered");
24063
0
  return (NULL);
24064
0
    }
24065
0
    if (vctxt->elemInfos == NULL) {
24066
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24067
0
      xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24068
0
  if (vctxt->elemInfos == NULL) {
24069
0
      xmlSchemaVErrMemory(vctxt);
24070
0
      return (NULL);
24071
0
  }
24072
0
  memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24073
0
  vctxt->sizeElemInfos = 10;
24074
0
    } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24075
0
  int i = vctxt->sizeElemInfos;
24076
24077
0
  vctxt->sizeElemInfos *= 2;
24078
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24079
0
      xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24080
0
      sizeof(xmlSchemaNodeInfoPtr));
24081
0
  if (vctxt->elemInfos == NULL) {
24082
0
      xmlSchemaVErrMemory(vctxt);
24083
0
      return (NULL);
24084
0
  }
24085
  /*
24086
  * We need the new memory to be NULLed.
24087
  * TODO: Use memset instead?
24088
  */
24089
0
  for (; i < vctxt->sizeElemInfos; i++)
24090
0
      vctxt->elemInfos[i] = NULL;
24091
0
    } else
24092
0
  info = vctxt->elemInfos[vctxt->depth];
24093
24094
0
    if (info == NULL) {
24095
0
  info = (xmlSchemaNodeInfoPtr)
24096
0
      xmlMalloc(sizeof(xmlSchemaNodeInfo));
24097
0
  if (info == NULL) {
24098
0
      xmlSchemaVErrMemory(vctxt);
24099
0
      return (NULL);
24100
0
  }
24101
0
  vctxt->elemInfos[vctxt->depth] = info;
24102
0
    } else {
24103
0
  if (info->localName != NULL) {
24104
0
      VERROR_INT("xmlSchemaGetFreshElemInfo",
24105
0
    "elem info has not been cleared");
24106
0
      return (NULL);
24107
0
  }
24108
0
    }
24109
0
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
24110
0
    info->nodeType = XML_ELEMENT_NODE;
24111
0
    info->depth = vctxt->depth;
24112
24113
0
    return (info);
24114
0
}
24115
24116
0
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24117
0
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24118
0
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24119
24120
static int
24121
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24122
      xmlNodePtr node,
24123
      xmlSchemaTypePtr type,
24124
      xmlSchemaValType valType,
24125
      const xmlChar * value,
24126
      xmlSchemaValPtr val,
24127
      unsigned long length,
24128
      int fireErrors)
24129
0
{
24130
0
    int ret, error = 0, found;
24131
24132
0
    xmlSchemaTypePtr tmpType;
24133
0
    xmlSchemaFacetLinkPtr facetLink;
24134
0
    xmlSchemaFacetPtr facet;
24135
0
    unsigned long len = 0;
24136
0
    xmlSchemaWhitespaceValueType ws;
24137
24138
    /*
24139
    * In Libxml2, derived built-in types have currently no explicit facets.
24140
    */
24141
0
    if (type->type == XML_SCHEMA_TYPE_BASIC)
24142
0
  return (0);
24143
24144
    /*
24145
    * NOTE: Do not jump away, if the facetSet of the given type is
24146
    * empty: until now, "pattern" and "enumeration" facets of the
24147
    * *base types* need to be checked as well.
24148
    */
24149
0
    if (type->facetSet == NULL)
24150
0
  goto pattern_and_enum;
24151
24152
0
    if (! WXS_IS_ATOMIC(type)) {
24153
0
  if (WXS_IS_LIST(type))
24154
0
      goto WXS_IS_LIST;
24155
0
  else
24156
0
      goto pattern_and_enum;
24157
0
    }
24158
24159
    /*
24160
    * Whitespace handling is only of importance for string-based
24161
    * types.
24162
    */
24163
0
    tmpType = xmlSchemaGetPrimitiveType(type);
24164
0
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24165
0
  WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24166
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24167
0
    } else
24168
0
  ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24169
24170
    /*
24171
    * If the value was not computed (for string or
24172
    * anySimpleType based types), then use the provided
24173
    * type.
24174
    */
24175
0
    if (val != NULL)
24176
0
  valType = xmlSchemaGetValType(val);
24177
24178
0
    ret = 0;
24179
0
    for (facetLink = type->facetSet; facetLink != NULL;
24180
0
  facetLink = facetLink->next) {
24181
  /*
24182
  * Skip the pattern "whiteSpace": it is used to
24183
  * format the character content beforehand.
24184
  */
24185
0
  switch (facetLink->facet->type) {
24186
0
      case XML_SCHEMA_FACET_WHITESPACE:
24187
0
      case XML_SCHEMA_FACET_PATTERN:
24188
0
      case XML_SCHEMA_FACET_ENUMERATION:
24189
0
    continue;
24190
0
      case XML_SCHEMA_FACET_LENGTH:
24191
0
      case XML_SCHEMA_FACET_MINLENGTH:
24192
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24193
0
    ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24194
0
        valType, value, val, &len, ws);
24195
0
    break;
24196
0
      default:
24197
0
    ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24198
0
        valType, value, val, ws);
24199
0
    break;
24200
0
  }
24201
0
  if (ret < 0) {
24202
0
      AERROR_INT("xmlSchemaValidateFacets",
24203
0
    "validating against a atomic type facet");
24204
0
      return (-1);
24205
0
  } else if (ret > 0) {
24206
0
      if (fireErrors)
24207
0
    xmlSchemaFacetErr(actxt, ret, node,
24208
0
    value, len, type, facetLink->facet, NULL, NULL, NULL);
24209
0
      else
24210
0
    return (ret);
24211
0
      if (error == 0)
24212
0
    error = ret;
24213
0
  }
24214
0
  ret = 0;
24215
0
    }
24216
24217
0
WXS_IS_LIST:
24218
0
    if (! WXS_IS_LIST(type))
24219
0
  goto pattern_and_enum;
24220
    /*
24221
    * "length", "minLength" and "maxLength" of list types.
24222
    */
24223
0
    ret = 0;
24224
0
    for (facetLink = type->facetSet; facetLink != NULL;
24225
0
  facetLink = facetLink->next) {
24226
24227
0
  switch (facetLink->facet->type) {
24228
0
      case XML_SCHEMA_FACET_LENGTH:
24229
0
      case XML_SCHEMA_FACET_MINLENGTH:
24230
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24231
0
    ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24232
0
        value, length, NULL);
24233
0
    break;
24234
0
      default:
24235
0
    continue;
24236
0
  }
24237
0
  if (ret < 0) {
24238
0
      AERROR_INT("xmlSchemaValidateFacets",
24239
0
    "validating against a list type facet");
24240
0
      return (-1);
24241
0
  } else if (ret > 0) {
24242
0
      if (fireErrors)
24243
0
    xmlSchemaFacetErr(actxt, ret, node,
24244
0
    value, length, type, facetLink->facet, NULL, NULL, NULL);
24245
0
      else
24246
0
    return (ret);
24247
0
      if (error == 0)
24248
0
    error = ret;
24249
0
  }
24250
0
  ret = 0;
24251
0
    }
24252
24253
0
pattern_and_enum:
24254
0
    found = 0;
24255
    /*
24256
    * Process enumerations. Facet values are in the value space
24257
    * of the defining type's base type. This seems to be a bug in the
24258
    * XML Schema 1.0 spec. Use the whitespace type of the base type.
24259
    * Only the first set of enumerations in the ancestor-or-self axis
24260
    * is used for validation.
24261
    */
24262
0
    ret = 0;
24263
0
    tmpType = type;
24264
0
    do {
24265
0
        for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24266
0
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24267
0
                continue;
24268
0
            found = 1;
24269
0
            ret = xmlSchemaAreValuesEqual(facet->val, val);
24270
0
            if (ret == 1)
24271
0
                break;
24272
0
            else if (ret < 0) {
24273
0
                AERROR_INT("xmlSchemaValidateFacets",
24274
0
                    "validating against an enumeration facet");
24275
0
                return (-1);
24276
0
            }
24277
0
        }
24278
0
        if (ret != 0)
24279
0
            break;
24280
        /*
24281
        * Break on the first set of enumerations. Any additional
24282
        *  enumerations which might be existent on the ancestors
24283
        *  of the current type are restricted by this set; thus
24284
        *  *must* *not* be taken into account.
24285
        */
24286
0
        if (found)
24287
0
            break;
24288
0
        tmpType = tmpType->baseType;
24289
0
    } while ((tmpType != NULL) &&
24290
0
        (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24291
0
    if (found && (ret == 0)) {
24292
0
        ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24293
0
        if (fireErrors) {
24294
0
            xmlSchemaFacetErr(actxt, ret, node,
24295
0
                value, 0, type, NULL, NULL, NULL, NULL);
24296
0
        } else
24297
0
            return (ret);
24298
0
        if (error == 0)
24299
0
            error = ret;
24300
0
    }
24301
24302
    /*
24303
    * Process patters. Pattern facets are ORed at type level
24304
    * and ANDed if derived. Walk the base type axis.
24305
    */
24306
0
    tmpType = type;
24307
0
    facet = NULL;
24308
0
    do {
24309
0
        found = 0;
24310
0
        for (facetLink = tmpType->facetSet; facetLink != NULL;
24311
0
            facetLink = facetLink->next) {
24312
0
            if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24313
0
                continue;
24314
0
            found = 1;
24315
            /*
24316
            * NOTE that for patterns, @value needs to be the
24317
            * normalized value.
24318
            */
24319
0
            ret = xmlRegexpExec(facetLink->facet->regexp, value);
24320
0
            if (ret == 1)
24321
0
                break;
24322
0
            else if (ret < 0) {
24323
0
                AERROR_INT("xmlSchemaValidateFacets",
24324
0
                    "validating against a pattern facet");
24325
0
                return (-1);
24326
0
            } else {
24327
                /*
24328
                * Save the last non-validating facet.
24329
                */
24330
0
                facet = facetLink->facet;
24331
0
            }
24332
0
        }
24333
0
        if (found && (ret != 1)) {
24334
0
            ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24335
0
            if (fireErrors) {
24336
0
                xmlSchemaFacetErr(actxt, ret, node,
24337
0
                    value, 0, type, facet, NULL, NULL, NULL);
24338
0
            } else
24339
0
                return (ret);
24340
0
            if (error == 0)
24341
0
                error = ret;
24342
0
            break;
24343
0
        }
24344
0
        tmpType = tmpType->baseType;
24345
0
    } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24346
24347
0
    return (error);
24348
0
}
24349
24350
static xmlChar *
24351
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24352
      const xmlChar *value)
24353
0
{
24354
0
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24355
0
  case XML_SCHEMA_WHITESPACE_COLLAPSE:
24356
0
      return (xmlSchemaCollapseString(value));
24357
0
  case XML_SCHEMA_WHITESPACE_REPLACE:
24358
0
      return (xmlSchemaWhiteSpaceReplace(value));
24359
0
  default:
24360
0
      return (NULL);
24361
0
    }
24362
0
}
24363
24364
static int
24365
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24366
           const xmlChar *value,
24367
           xmlSchemaValPtr *val,
24368
           int valNeeded)
24369
0
{
24370
0
    int ret;
24371
0
    xmlChar *stripped;
24372
0
    const xmlChar *nsName;
24373
0
    xmlChar *local, *prefix = NULL;
24374
24375
0
    ret = xmlValidateQName(value, 1);
24376
0
    if (ret != 0) {
24377
0
  if (ret == -1) {
24378
0
      VERROR_INT("xmlSchemaValidateQName",
24379
0
    "calling xmlValidateQName()");
24380
0
      return (-1);
24381
0
  }
24382
0
  return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24383
0
    }
24384
    /*
24385
    * NOTE: xmlSplitQName2 will always return a duplicated
24386
    * strings.
24387
    */
24388
    /* TODO: Export and use xmlSchemaStrip instead */
24389
0
    stripped = xmlSchemaCollapseString(value);
24390
0
    local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24391
0
    xmlFree(stripped);
24392
0
    if (local == NULL)
24393
0
  local = xmlStrdup(value);
24394
    /*
24395
    * OPTIMIZE TODO: Use flags for:
24396
    *  - is there any namespace binding?
24397
    *  - is there a default namespace?
24398
    */
24399
0
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24400
24401
0
    if (prefix != NULL) {
24402
0
  xmlFree(prefix);
24403
  /*
24404
  * A namespace must be found if the prefix is
24405
  * NOT NULL.
24406
  */
24407
0
  if (nsName == NULL) {
24408
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24409
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24410
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24411
0
    "The QName value '%s' has no "
24412
0
    "corresponding namespace declaration in "
24413
0
    "scope", value, NULL);
24414
0
      if (local != NULL)
24415
0
    xmlFree(local);
24416
0
      return (ret);
24417
0
  }
24418
0
    }
24419
0
    if (valNeeded && val) {
24420
0
  if (nsName != NULL)
24421
0
      *val = xmlSchemaNewQNameValue(
24422
0
    BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24423
0
  else
24424
0
      *val = xmlSchemaNewQNameValue(NULL,
24425
0
    BAD_CAST local);
24426
0
    } else
24427
0
  xmlFree(local);
24428
0
    return (0);
24429
0
}
24430
24431
/*
24432
* cvc-simple-type
24433
*/
24434
static int
24435
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24436
           xmlNodePtr node,
24437
           xmlSchemaTypePtr type,
24438
           const xmlChar *value,
24439
           xmlSchemaValPtr *retVal,
24440
           int fireErrors,
24441
           int normalize,
24442
           int isNormalized)
24443
0
{
24444
0
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
24445
0
    xmlSchemaValPtr val = NULL;
24446
    /* xmlSchemaWhitespaceValueType ws; */
24447
0
    xmlChar *normValue = NULL;
24448
24449
0
#define NORMALIZE(atype) \
24450
0
    if ((! isNormalized) && \
24451
0
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24452
0
  normValue = xmlSchemaNormalizeValue(atype, value); \
24453
0
  if (normValue != NULL) \
24454
0
      value = normValue; \
24455
0
  isNormalized = 1; \
24456
0
    }
24457
24458
0
    if ((retVal != NULL) && (*retVal != NULL)) {
24459
0
  xmlSchemaFreeValue(*retVal);
24460
0
  *retVal = NULL;
24461
0
    }
24462
    /*
24463
    * 3.14.4 Simple Type Definition Validation Rules
24464
    * Validation Rule: String Valid
24465
    */
24466
    /*
24467
    * 1 It is schema-valid with respect to that definition as defined
24468
    * by Datatype Valid in [XML Schemas: Datatypes].
24469
    */
24470
    /*
24471
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24472
    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24473
    * the string must be a `declared entity name`.
24474
    */
24475
    /*
24476
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24477
    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24478
    * then every whitespace-delimited substring of the string must be a `declared
24479
    * entity name`.
24480
    */
24481
    /*
24482
    * 2.3 otherwise no further condition applies.
24483
    */
24484
0
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24485
0
  valNeeded = 1;
24486
0
    if (value == NULL)
24487
0
  value = BAD_CAST "";
24488
0
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24489
0
  xmlSchemaTypePtr biType; /* The built-in type. */
24490
  /*
24491
  * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24492
  * a literal in the `lexical space` of {base type definition}"
24493
  */
24494
  /*
24495
  * Whitespace-normalize.
24496
  */
24497
0
  NORMALIZE(type);
24498
0
  if (type->type != XML_SCHEMA_TYPE_BASIC) {
24499
      /*
24500
      * Get the built-in type.
24501
      */
24502
0
      biType = type->baseType;
24503
0
      while ((biType != NULL) &&
24504
0
    (biType->type != XML_SCHEMA_TYPE_BASIC))
24505
0
    biType = biType->baseType;
24506
24507
0
      if (biType == NULL) {
24508
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24509
0
        "could not get the built-in type");
24510
0
    goto internal_error;
24511
0
      }
24512
0
  } else
24513
0
      biType = type;
24514
  /*
24515
  * NOTATIONs need to be processed here, since they need
24516
  * to lookup in the hashtable of NOTATION declarations of the schema.
24517
  */
24518
0
  if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24519
0
      switch (biType->builtInType) {
24520
0
    case XML_SCHEMAS_NOTATION:
24521
0
        ret = xmlSchemaValidateNotation(
24522
0
      (xmlSchemaValidCtxtPtr) actxt,
24523
0
      ((xmlSchemaValidCtxtPtr) actxt)->schema,
24524
0
      NULL, value, &val, valNeeded);
24525
0
        break;
24526
0
    case XML_SCHEMAS_QNAME:
24527
0
        ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24528
0
      value, &val, valNeeded);
24529
0
        break;
24530
0
    default:
24531
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24532
0
        if (valNeeded)
24533
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24534
0
          value, &val, node);
24535
0
        else
24536
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24537
0
          value, NULL, node);
24538
0
        break;
24539
0
      }
24540
0
  } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24541
0
      switch (biType->builtInType) {
24542
0
    case XML_SCHEMAS_NOTATION:
24543
0
        ret = xmlSchemaValidateNotation(NULL,
24544
0
      ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24545
0
      value, &val, valNeeded);
24546
0
        break;
24547
0
    default:
24548
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24549
0
        if (valNeeded)
24550
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24551
0
          value, &val, node);
24552
0
        else
24553
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24554
0
          value, NULL, node);
24555
0
        break;
24556
0
      }
24557
0
  } else {
24558
      /*
24559
      * Validation via a public API is not implemented yet.
24560
      */
24561
0
      goto internal_error;
24562
0
  }
24563
0
  if (ret != 0) {
24564
0
      if (ret < 0) {
24565
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24566
0
        "validating against a built-in type");
24567
0
    goto internal_error;
24568
0
      }
24569
0
      if (WXS_IS_LIST(type))
24570
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24571
0
      else
24572
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24573
0
  }
24574
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24575
      /*
24576
      * Check facets.
24577
      */
24578
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24579
0
    (xmlSchemaValType) biType->builtInType, value, val,
24580
0
    0, fireErrors);
24581
0
      if (ret != 0) {
24582
0
    if (ret < 0) {
24583
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24584
0
      "validating facets of atomic simple type");
24585
0
        goto internal_error;
24586
0
    }
24587
0
    if (WXS_IS_LIST(type))
24588
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24589
0
    else
24590
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24591
0
      }
24592
0
  }
24593
0
  else if (fireErrors && (ret > 0))
24594
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24595
0
    } else if (WXS_IS_LIST(type)) {
24596
24597
0
  xmlSchemaTypePtr itemType;
24598
0
  const xmlChar *cur, *end;
24599
0
  xmlChar *tmpValue = NULL;
24600
0
  unsigned long len = 0;
24601
0
  xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24602
  /* 1.2.2 if {variety} is `list` then the string must be a sequence
24603
  * of white space separated tokens, each of which `match`es a literal
24604
  * in the `lexical space` of {item type definition}
24605
  */
24606
  /*
24607
  * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24608
  * the list type has an enum or pattern facet.
24609
  */
24610
0
  NORMALIZE(type);
24611
  /*
24612
  * VAL TODO: Optimize validation of empty values.
24613
  * VAL TODO: We do not have computed values for lists.
24614
  */
24615
0
  itemType = WXS_LIST_ITEMTYPE(type);
24616
0
  cur = value;
24617
0
  do {
24618
0
      while (IS_BLANK_CH(*cur))
24619
0
    cur++;
24620
0
      end = cur;
24621
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24622
0
    end++;
24623
0
      if (end == cur)
24624
0
    break;
24625
0
      tmpValue = xmlStrndup(cur, end - cur);
24626
0
      len++;
24627
24628
0
      if (valNeeded)
24629
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24630
0
        tmpValue, &curVal, fireErrors, 0, 1);
24631
0
      else
24632
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24633
0
        tmpValue, NULL, fireErrors, 0, 1);
24634
0
      FREE_AND_NULL(tmpValue);
24635
0
      if (curVal != NULL) {
24636
    /*
24637
    * Add to list of computed values.
24638
    */
24639
0
    if (val == NULL)
24640
0
        val = curVal;
24641
0
    else
24642
0
        xmlSchemaValueAppend(prevVal, curVal);
24643
0
    prevVal = curVal;
24644
0
    curVal = NULL;
24645
0
      }
24646
0
      if (ret != 0) {
24647
0
    if (ret < 0) {
24648
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24649
0
      "validating an item of list simple type");
24650
0
        goto internal_error;
24651
0
    }
24652
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24653
0
    break;
24654
0
      }
24655
0
      cur = end;
24656
0
  } while (*cur != 0);
24657
0
  FREE_AND_NULL(tmpValue);
24658
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24659
      /*
24660
      * Apply facets (pattern, enumeration).
24661
      */
24662
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24663
0
    XML_SCHEMAS_UNKNOWN, value, val,
24664
0
    len, fireErrors);
24665
0
      if (ret != 0) {
24666
0
    if (ret < 0) {
24667
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24668
0
      "validating facets of list simple type");
24669
0
        goto internal_error;
24670
0
    }
24671
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24672
0
      }
24673
0
  }
24674
0
  if (fireErrors && (ret > 0)) {
24675
      /*
24676
      * Report the normalized value.
24677
      */
24678
0
      normalize = 1;
24679
0
      NORMALIZE(type);
24680
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24681
0
  }
24682
0
    } else if (WXS_IS_UNION(type)) {
24683
0
  xmlSchemaTypeLinkPtr memberLink;
24684
  /*
24685
  * TODO: For all datatypes `derived` by `union`  whiteSpace does
24686
  * not apply directly; however, the normalization behavior of `union`
24687
  * types is controlled by the value of whiteSpace on that one of the
24688
  * `memberTypes` against which the `union` is successfully validated.
24689
  *
24690
  * This means that the value is normalized by the first validating
24691
  * member type, then the facets of the union type are applied. This
24692
  * needs changing of the value!
24693
  */
24694
24695
  /*
24696
  * 1.2.3 if {variety} is `union` then the string must `match` a
24697
  * literal in the `lexical space` of at least one member of
24698
  * {member type definitions}
24699
  */
24700
0
  memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24701
0
  if (memberLink == NULL) {
24702
0
      AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24703
0
    "union simple type has no member types");
24704
0
      goto internal_error;
24705
0
  }
24706
  /*
24707
  * Always normalize union type values, since we currently
24708
  * cannot store the whitespace information with the value
24709
  * itself; otherwise a later value-comparison would be
24710
  * not possible.
24711
  */
24712
0
  while (memberLink != NULL) {
24713
0
      if (valNeeded)
24714
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24715
0
        memberLink->type, value, &val, 0, 1, 0);
24716
0
      else
24717
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24718
0
        memberLink->type, value, NULL, 0, 1, 0);
24719
0
      if (ret <= 0)
24720
0
    break;
24721
0
      memberLink = memberLink->next;
24722
0
  }
24723
0
  if (ret != 0) {
24724
0
      if (ret < 0) {
24725
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24726
0
        "validating members of union simple type");
24727
0
    goto internal_error;
24728
0
      }
24729
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24730
0
  }
24731
  /*
24732
  * Apply facets (pattern, enumeration).
24733
  */
24734
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24735
      /*
24736
      * The normalization behavior of `union` types is controlled by
24737
      * the value of whiteSpace on that one of the `memberTypes`
24738
      * against which the `union` is successfully validated.
24739
      */
24740
0
      NORMALIZE(memberLink->type);
24741
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24742
0
    XML_SCHEMAS_UNKNOWN, value, val,
24743
0
    0, fireErrors);
24744
0
      if (ret != 0) {
24745
0
    if (ret < 0) {
24746
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24747
0
      "validating facets of union simple type");
24748
0
        goto internal_error;
24749
0
    }
24750
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24751
0
      }
24752
0
  }
24753
0
  if (fireErrors && (ret > 0))
24754
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24755
0
    }
24756
24757
0
    if (normValue != NULL)
24758
0
  xmlFree(normValue);
24759
0
    if (ret == 0) {
24760
0
  if (retVal != NULL)
24761
0
      *retVal = val;
24762
0
  else if (val != NULL)
24763
0
      xmlSchemaFreeValue(val);
24764
0
    } else if (val != NULL)
24765
0
  xmlSchemaFreeValue(val);
24766
0
    return (ret);
24767
0
internal_error:
24768
0
    if (normValue != NULL)
24769
0
  xmlFree(normValue);
24770
0
    if (val != NULL)
24771
0
  xmlSchemaFreeValue(val);
24772
0
    return (-1);
24773
0
}
24774
24775
static int
24776
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24777
         const xmlChar *value,
24778
         const xmlChar **nsName,
24779
         const xmlChar **localName)
24780
0
{
24781
0
    int ret = 0;
24782
24783
0
    if ((nsName == NULL) || (localName == NULL))
24784
0
  return (-1);
24785
0
    *nsName = NULL;
24786
0
    *localName = NULL;
24787
24788
0
    ret = xmlValidateQName(value, 1);
24789
0
    if (ret == -1)
24790
0
  return (-1);
24791
0
    if (ret > 0) {
24792
0
  xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24793
0
      XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24794
0
      value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24795
0
  return (1);
24796
0
    }
24797
0
    {
24798
0
  xmlChar *local = NULL;
24799
0
  xmlChar *prefix;
24800
24801
  /*
24802
  * NOTE: xmlSplitQName2 will return a duplicated
24803
  * string.
24804
  */
24805
0
  local = xmlSplitQName2(value, &prefix);
24806
0
  if (local == NULL)
24807
0
      *localName = xmlDictLookup(vctxt->dict, value, -1);
24808
0
  else {
24809
0
      *localName = xmlDictLookup(vctxt->dict, local, -1);
24810
0
      xmlFree(local);
24811
0
  }
24812
24813
0
  *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24814
24815
0
  if (prefix != NULL) {
24816
0
      xmlFree(prefix);
24817
      /*
24818
      * A namespace must be found if the prefix is NOT NULL.
24819
      */
24820
0
      if (*nsName == NULL) {
24821
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24822
0
        XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24823
0
        WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24824
0
        "The QName value '%s' has no "
24825
0
        "corresponding namespace declaration in scope",
24826
0
        value, NULL);
24827
0
    return (2);
24828
0
      }
24829
0
  }
24830
0
    }
24831
0
    return (0);
24832
0
}
24833
24834
static int
24835
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24836
      xmlSchemaAttrInfoPtr iattr,
24837
      xmlSchemaTypePtr *localType,
24838
      xmlSchemaElementPtr elemDecl)
24839
0
{
24840
0
    int ret = 0;
24841
    /*
24842
    * cvc-elt (3.3.4) : (4)
24843
    * AND
24844
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
24845
    *   (1.2.1.2.1) - (1.2.1.2.4)
24846
    * Handle 'xsi:type'.
24847
    */
24848
0
    if (localType == NULL)
24849
0
  return (-1);
24850
0
    *localType = NULL;
24851
0
    if (iattr == NULL)
24852
0
  return (0);
24853
0
    else {
24854
0
  const xmlChar *nsName = NULL, *local = NULL;
24855
  /*
24856
  * TODO: We should report a *warning* that the type was overridden
24857
  * by the instance.
24858
  */
24859
0
  ACTIVATE_ATTRIBUTE(iattr);
24860
  /*
24861
  * (cvc-elt) (3.3.4) : (4.1)
24862
  * (cvc-assess-elt) (1.2.1.2.2)
24863
  */
24864
0
  ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24865
0
      &nsName, &local);
24866
0
  if (ret != 0) {
24867
0
      if (ret < 0) {
24868
0
    VERROR_INT("xmlSchemaValidateElementByDeclaration",
24869
0
        "calling xmlSchemaQNameExpand() to validate the "
24870
0
        "attribute 'xsi:type'");
24871
0
    goto internal_error;
24872
0
      }
24873
0
      goto exit;
24874
0
  }
24875
  /*
24876
  * (cvc-elt) (3.3.4) : (4.2)
24877
  * (cvc-assess-elt) (1.2.1.2.3)
24878
  */
24879
0
  *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24880
0
  if (*localType == NULL) {
24881
0
      xmlChar *str = NULL;
24882
24883
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
24884
0
    XML_SCHEMAV_CVC_ELT_4_2, NULL,
24885
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24886
0
    "The QName value '%s' of the xsi:type attribute does not "
24887
0
    "resolve to a type definition",
24888
0
    xmlSchemaFormatQName(&str, nsName, local), NULL);
24889
0
      FREE_AND_NULL(str);
24890
0
      ret = vctxt->err;
24891
0
      goto exit;
24892
0
  }
24893
0
  if (elemDecl != NULL) {
24894
0
      int set = 0;
24895
24896
      /*
24897
      * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24898
      * "The `local type definition` must be validly
24899
      * derived from the {type definition} given the union of
24900
      * the {disallowed substitutions} and the {type definition}'s
24901
      * {prohibited substitutions}, as defined in
24902
      * Type Derivation OK (Complex) ($3.4.6)
24903
      * (if it is a complex type definition),
24904
      * or given {disallowed substitutions} as defined in Type
24905
      * Derivation OK (Simple) ($3.14.6) (if it is a simple type
24906
      * definition)."
24907
      *
24908
      * {disallowed substitutions}: the "block" on the element decl.
24909
      * {prohibited substitutions}: the "block" on the type def.
24910
      */
24911
      /*
24912
      * OPTIMIZE TODO: We could map types already evaluated
24913
      * to be validly derived from other types to avoid checking
24914
      * this over and over for the same types.
24915
      */
24916
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24917
0
    (elemDecl->subtypes->flags &
24918
0
        XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24919
0
    set |= SUBSET_EXTENSION;
24920
24921
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24922
0
    (elemDecl->subtypes->flags &
24923
0
        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24924
0
    set |= SUBSET_RESTRICTION;
24925
24926
      /*
24927
      * REMOVED and CHANGED since this produced a parser context
24928
      * which adds to the string dict of the schema. So this would
24929
      * change the schema and we don't want this. We don't need
24930
      * the parser context anymore.
24931
      *
24932
      * if ((vctxt->pctxt == NULL) &&
24933
      * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24934
      *     return (-1);
24935
      */
24936
24937
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24938
0
    elemDecl->subtypes, set) != 0) {
24939
0
    xmlChar *str = NULL;
24940
24941
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24942
0
        XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24943
0
        "The type definition '%s', specified by xsi:type, is "
24944
0
        "blocked or not validly derived from the type definition "
24945
0
        "of the element declaration",
24946
0
        xmlSchemaFormatQName(&str,
24947
0
      (*localType)->targetNamespace,
24948
0
      (*localType)->name),
24949
0
        NULL);
24950
0
    FREE_AND_NULL(str);
24951
0
    ret = vctxt->err;
24952
0
    *localType = NULL;
24953
0
      }
24954
0
  }
24955
0
    }
24956
0
exit:
24957
0
    ACTIVATE_ELEM;
24958
0
    return (ret);
24959
0
internal_error:
24960
0
    ACTIVATE_ELEM;
24961
0
    return (-1);
24962
0
}
24963
24964
static int
24965
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24966
0
{
24967
0
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24968
0
    xmlSchemaTypePtr actualType;
24969
24970
    /*
24971
    * cvc-elt (3.3.4) : 1
24972
    */
24973
0
    if (elemDecl == NULL) {
24974
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24975
0
      "No matching declaration available");
24976
0
        return (vctxt->err);
24977
0
    }
24978
0
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
24979
    /*
24980
    * cvc-elt (3.3.4) : 2
24981
    */
24982
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24983
0
  VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24984
0
      "The element declaration is abstract");
24985
0
        return (vctxt->err);
24986
0
    }
24987
0
    if (actualType == NULL) {
24988
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24989
0
      "The type definition is absent");
24990
0
  return (XML_SCHEMAV_CVC_TYPE_1);
24991
0
    }
24992
0
    if (vctxt->nbAttrInfos != 0) {
24993
0
  int ret;
24994
0
  xmlSchemaAttrInfoPtr iattr;
24995
  /*
24996
  * cvc-elt (3.3.4) : 3
24997
  * Handle 'xsi:nil'.
24998
  */
24999
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25000
0
      XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25001
0
  if (iattr) {
25002
0
      ACTIVATE_ATTRIBUTE(iattr);
25003
      /*
25004
      * Validate the value.
25005
      */
25006
0
      ret = xmlSchemaVCheckCVCSimpleType(
25007
0
    ACTXT_CAST vctxt, NULL,
25008
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25009
0
    iattr->value, &(iattr->val), 1, 0, 0);
25010
0
      ACTIVATE_ELEM;
25011
0
      if (ret < 0) {
25012
0
    VERROR_INT("xmlSchemaValidateElemDecl",
25013
0
        "calling xmlSchemaVCheckCVCSimpleType() to "
25014
0
        "validate the attribute 'xsi:nil'");
25015
0
    return (-1);
25016
0
      }
25017
0
      if (ret == 0) {
25018
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25019
        /*
25020
        * cvc-elt (3.3.4) : 3.1
25021
        */
25022
0
        VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25023
0
      "The element is not 'nillable'");
25024
        /* Does not return an error on purpose. */
25025
0
    } else {
25026
0
        if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25027
      /*
25028
      * cvc-elt (3.3.4) : 3.2.2
25029
      */
25030
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25031
0
          (elemDecl->value != NULL)) {
25032
0
          VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25033
0
        "The element cannot be 'nilled' because "
25034
0
        "there is a fixed value constraint defined "
25035
0
        "for it");
25036
           /* Does not return an error on purpose. */
25037
0
      } else
25038
0
          vctxt->inode->flags |=
25039
0
        XML_SCHEMA_ELEM_INFO_NILLED;
25040
0
        }
25041
0
    }
25042
0
      }
25043
0
  }
25044
  /*
25045
  * cvc-elt (3.3.4) : 4
25046
  * Handle 'xsi:type'.
25047
  */
25048
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25049
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25050
0
  if (iattr) {
25051
0
      xmlSchemaTypePtr localType = NULL;
25052
25053
0
      ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25054
0
    elemDecl);
25055
0
      if (ret != 0) {
25056
0
    if (ret == -1) {
25057
0
        VERROR_INT("xmlSchemaValidateElemDecl",
25058
0
      "calling xmlSchemaProcessXSIType() to "
25059
0
      "process the attribute 'xsi:type'");
25060
0
        return (-1);
25061
0
    }
25062
    /* Does not return an error on purpose. */
25063
0
      }
25064
0
      if (localType != NULL) {
25065
0
    vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25066
0
    actualType = localType;
25067
0
      }
25068
0
  }
25069
0
    }
25070
    /*
25071
    * IDC: Register identity-constraint XPath matchers.
25072
    */
25073
0
    if ((elemDecl->idcs != NULL) &&
25074
0
  (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25075
0
      return (-1);
25076
    /*
25077
    * No actual type definition.
25078
    */
25079
0
    if (actualType == NULL) {
25080
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25081
0
      "The type definition is absent");
25082
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25083
0
    }
25084
    /*
25085
    * Remember the actual type definition.
25086
    */
25087
0
    vctxt->inode->typeDef = actualType;
25088
25089
0
    return (0);
25090
0
}
25091
25092
static int
25093
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25094
0
{
25095
0
    xmlSchemaAttrInfoPtr iattr;
25096
0
    int ret = 0, i;
25097
25098
    /*
25099
    * SPEC cvc-type (3.1.1)
25100
    * "The attributes of must be empty, excepting those whose namespace
25101
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25102
    * whose local name is one of type, nil, schemaLocation or
25103
    * noNamespaceSchemaLocation."
25104
    */
25105
0
    if (vctxt->nbAttrInfos == 0)
25106
0
  return (0);
25107
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25108
0
  iattr = vctxt->attrInfos[i];
25109
0
  if (! iattr->metaType) {
25110
0
      ACTIVATE_ATTRIBUTE(iattr)
25111
0
      xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25112
0
    XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25113
0
      ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25114
0
        }
25115
0
    }
25116
0
    ACTIVATE_ELEM
25117
0
    return (ret);
25118
0
}
25119
25120
/*
25121
* Cleanup currently used attribute infos.
25122
*/
25123
static void
25124
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25125
0
{
25126
0
    int i;
25127
0
    xmlSchemaAttrInfoPtr attr;
25128
25129
0
    if (vctxt->nbAttrInfos == 0)
25130
0
  return;
25131
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25132
0
  attr = vctxt->attrInfos[i];
25133
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25134
0
      if (attr->localName != NULL)
25135
0
    xmlFree((xmlChar *) attr->localName);
25136
0
      if (attr->nsName != NULL)
25137
0
    xmlFree((xmlChar *) attr->nsName);
25138
0
  }
25139
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25140
0
      if (attr->value != NULL)
25141
0
    xmlFree((xmlChar *) attr->value);
25142
0
  }
25143
0
  if (attr->val != NULL) {
25144
0
      xmlSchemaFreeValue(attr->val);
25145
0
      attr->val = NULL;
25146
0
  }
25147
0
  memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25148
0
    }
25149
0
    vctxt->nbAttrInfos = 0;
25150
0
}
25151
25152
/*
25153
* 3.4.4 Complex Type Definition Validation Rules
25154
*   Element Locally Valid (Complex Type) (cvc-complex-type)
25155
* 3.2.4 Attribute Declaration Validation Rules
25156
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
25157
*   Attribute Locally Valid (Use) (cvc-au)
25158
*
25159
* Only "assessed" attribute information items will be visible to
25160
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25161
*/
25162
static int
25163
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25164
0
{
25165
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef;
25166
0
    xmlSchemaItemListPtr attrUseList;
25167
0
    xmlSchemaAttributeUsePtr attrUse = NULL;
25168
0
    xmlSchemaAttributePtr attrDecl = NULL;
25169
0
    xmlSchemaAttrInfoPtr iattr, tmpiattr;
25170
0
    int i, j, found, nbAttrs, nbUses;
25171
0
    int xpathRes = 0, res, wildIDs = 0, fixed;
25172
0
    xmlNodePtr defAttrOwnerElem = NULL;
25173
25174
    /*
25175
    * SPEC (cvc-attribute)
25176
    * (1) "The declaration must not be `absent` (see Missing
25177
    * Sub-components ($5.3) for how this can fail to be
25178
    * the case)."
25179
    * (2) "Its {type definition} must not be absent."
25180
    *
25181
    * NOTE (1) + (2): This is not handled here, since we currently do not
25182
    * allow validation against schemas which have missing sub-components.
25183
    *
25184
    * SPEC (cvc-complex-type)
25185
    * (3) "For each attribute information item in the element information
25186
    * item's [attributes] excepting those whose [namespace name] is
25187
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25188
    * [local name] is one of type, nil, schemaLocation or
25189
    * noNamespaceSchemaLocation, the appropriate case among the following
25190
    * must be true:
25191
    *
25192
    */
25193
0
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25194
    /*
25195
    * @nbAttrs is the number of attributes present in the instance.
25196
    */
25197
0
    nbAttrs = vctxt->nbAttrInfos;
25198
0
    if (attrUseList != NULL)
25199
0
  nbUses = attrUseList->nbItems;
25200
0
    else
25201
0
  nbUses = 0;
25202
0
    for (i = 0; i < nbUses; i++) {
25203
0
        found = 0;
25204
0
  attrUse = attrUseList->items[i];
25205
0
  attrDecl = WXS_ATTRUSE_DECL(attrUse);
25206
0
        for (j = 0; j < nbAttrs; j++) {
25207
0
      iattr = vctxt->attrInfos[j];
25208
      /*
25209
      * SPEC (cvc-complex-type) (3)
25210
      * Skip meta attributes.
25211
      */
25212
0
      if (iattr->metaType)
25213
0
    continue;
25214
0
      if (iattr->localName[0] != attrDecl->name[0])
25215
0
    continue;
25216
0
      if (!xmlStrEqual(iattr->localName, attrDecl->name))
25217
0
    continue;
25218
0
      if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25219
0
    continue;
25220
0
      found = 1;
25221
      /*
25222
      * SPEC (cvc-complex-type)
25223
      * (3.1) "If there is among the {attribute uses} an attribute
25224
      * use with an {attribute declaration} whose {name} matches
25225
      * the attribute information item's [local name] and whose
25226
      * {target namespace} is identical to the attribute information
25227
      * item's [namespace name] (where an `absent` {target namespace}
25228
      * is taken to be identical to a [namespace name] with no value),
25229
      * then the attribute information must be `valid` with respect
25230
      * to that attribute use as per Attribute Locally Valid (Use)
25231
      * ($3.5.4). In this case the {attribute declaration} of that
25232
      * attribute use is the `context-determined declaration` for the
25233
      * attribute information item with respect to Schema-Validity
25234
      * Assessment (Attribute) ($3.2.4) and
25235
      * Assessment Outcome (Attribute) ($3.2.5).
25236
      */
25237
0
      iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25238
0
      iattr->use = attrUse;
25239
      /*
25240
      * Context-determined declaration.
25241
      */
25242
0
      iattr->decl = attrDecl;
25243
0
      iattr->typeDef = attrDecl->subtypes;
25244
0
      break;
25245
0
  }
25246
25247
0
  if (found)
25248
0
      continue;
25249
25250
0
  if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25251
      /*
25252
      * Handle non-existent, required attributes.
25253
      *
25254
      * SPEC (cvc-complex-type)
25255
      * (4) "The {attribute declaration} of each attribute use in
25256
      * the {attribute uses} whose {required} is true matches one
25257
      * of the attribute information items in the element information
25258
      * item's [attributes] as per clause 3.1 above."
25259
      */
25260
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25261
0
      if (tmpiattr == NULL) {
25262
0
    VERROR_INT(
25263
0
        "xmlSchemaVAttributesComplex",
25264
0
        "calling xmlSchemaGetFreshAttrInfo()");
25265
0
    return (-1);
25266
0
      }
25267
0
      tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25268
0
      tmpiattr->use = attrUse;
25269
0
      tmpiattr->decl = attrDecl;
25270
0
  } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25271
0
      ((attrUse->defValue != NULL) ||
25272
0
       (attrDecl->defValue != NULL))) {
25273
      /*
25274
      * Handle non-existent, optional, default/fixed attributes.
25275
      */
25276
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25277
0
      if (tmpiattr == NULL) {
25278
0
    VERROR_INT(
25279
0
        "xmlSchemaVAttributesComplex",
25280
0
        "calling xmlSchemaGetFreshAttrInfo()");
25281
0
    return (-1);
25282
0
      }
25283
0
      tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25284
0
      tmpiattr->use = attrUse;
25285
0
      tmpiattr->decl = attrDecl;
25286
0
      tmpiattr->typeDef = attrDecl->subtypes;
25287
0
      tmpiattr->localName = attrDecl->name;
25288
0
      tmpiattr->nsName = attrDecl->targetNamespace;
25289
0
  }
25290
0
    }
25291
25292
0
    if (vctxt->nbAttrInfos == 0)
25293
0
  return (0);
25294
    /*
25295
    * Validate against the wildcard.
25296
    */
25297
0
    if (type->attributeWildcard != NULL) {
25298
  /*
25299
  * SPEC (cvc-complex-type)
25300
  * (3.2.1) "There must be an {attribute wildcard}."
25301
  */
25302
0
  for (i = 0; i < nbAttrs; i++) {
25303
0
      iattr = vctxt->attrInfos[i];
25304
      /*
25305
      * SPEC (cvc-complex-type) (3)
25306
      * Skip meta attributes.
25307
      */
25308
0
      if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25309
0
    continue;
25310
      /*
25311
      * SPEC (cvc-complex-type)
25312
      * (3.2.2) "The attribute information item must be `valid` with
25313
      * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25314
      *
25315
      * SPEC Item Valid (Wildcard) (cvc-wildcard)
25316
      * "... its [namespace name] must be `valid` with respect to
25317
      * the wildcard constraint, as defined in Wildcard allows
25318
      * Namespace Name ($3.10.4)."
25319
      */
25320
0
      if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25321
0
        iattr->nsName) == 0) {
25322
    /*
25323
    * Handle processContents.
25324
    *
25325
    * SPEC (cvc-wildcard):
25326
    * processContents | context-determined declaration:
25327
    * "strict"          "mustFind"
25328
    * "lax"             "none"
25329
    * "skip"            "skip"
25330
    */
25331
0
    if (type->attributeWildcard->processContents ==
25332
0
        XML_SCHEMAS_ANY_SKIP) {
25333
         /*
25334
        * context-determined declaration = "skip"
25335
        *
25336
        * SPEC PSVI Assessment Outcome (Attribute)
25337
        * [validity] = "notKnown"
25338
        * [validation attempted] = "none"
25339
        */
25340
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25341
0
        continue;
25342
0
    }
25343
    /*
25344
    * Find an attribute declaration.
25345
    */
25346
0
    iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25347
0
        iattr->localName, iattr->nsName);
25348
0
    if (iattr->decl != NULL) {
25349
0
        iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25350
        /*
25351
        * SPEC (cvc-complex-type)
25352
        * (5) "Let [Definition:]  the wild IDs be the set of
25353
        * all attribute information item to which clause 3.2
25354
        * applied and whose `validation` resulted in a
25355
        * `context-determined declaration` of mustFind or no
25356
        * `context-determined declaration` at all, and whose
25357
        * [local name] and [namespace name] resolve (as
25358
        * defined by QName resolution (Instance) ($3.15.4)) to
25359
        * an attribute declaration whose {type definition} is
25360
        * or is derived from ID. Then all of the following
25361
        * must be true:"
25362
        */
25363
0
        iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25364
0
        if (xmlSchemaIsDerivedFromBuiltInType(
25365
0
      iattr->typeDef, XML_SCHEMAS_ID)) {
25366
      /*
25367
      * SPEC (5.1) "There must be no more than one
25368
      * item in `wild IDs`."
25369
      */
25370
0
      if (wildIDs != 0) {
25371
          /* VAL TODO */
25372
0
          iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25373
0
          continue;
25374
0
      }
25375
0
      wildIDs++;
25376
      /*
25377
      * SPEC (cvc-complex-type)
25378
      * (5.2) "If `wild IDs` is non-empty, there must not
25379
      * be any attribute uses among the {attribute uses}
25380
      * whose {attribute declaration}'s {type definition}
25381
      * is or is derived from ID."
25382
      */
25383
0
                        if (attrUseList != NULL) {
25384
0
                            for (j = 0; j < attrUseList->nbItems; j++) {
25385
0
                                if (xmlSchemaIsDerivedFromBuiltInType(
25386
0
                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25387
0
                                    XML_SCHEMAS_ID)) {
25388
                                    /* URGENT VAL TODO: implement */
25389
0
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25390
0
                                    break;
25391
0
                                }
25392
0
                            }
25393
0
                        }
25394
0
        }
25395
0
    } else if (type->attributeWildcard->processContents ==
25396
0
        XML_SCHEMAS_ANY_LAX) {
25397
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25398
        /*
25399
        * SPEC PSVI Assessment Outcome (Attribute)
25400
        * [validity] = "notKnown"
25401
        * [validation attempted] = "none"
25402
        */
25403
0
    } else {
25404
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25405
0
    }
25406
0
      }
25407
0
  }
25408
0
    }
25409
25410
0
    if (vctxt->nbAttrInfos == 0)
25411
0
  return (0);
25412
25413
    /*
25414
    * Get the owner element; needed for creation of default attributes.
25415
    * This fixes bug #341337, reported by David Grohmann.
25416
    */
25417
0
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25418
0
  xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25419
0
  if (ielem && ielem->node && ielem->node->doc)
25420
0
      defAttrOwnerElem = ielem->node;
25421
0
    }
25422
    /*
25423
    * Validate values, create default attributes, evaluate IDCs.
25424
    */
25425
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25426
0
  iattr = vctxt->attrInfos[i];
25427
  /*
25428
  * VAL TODO: Note that we won't try to resolve IDCs to
25429
  * "lax" and "skip" validated attributes. Check what to
25430
  * do in this case.
25431
  */
25432
0
  if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25433
0
      (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25434
0
      continue;
25435
  /*
25436
  * VAL TODO: What to do if the type definition is missing?
25437
  */
25438
0
  if (iattr->typeDef == NULL) {
25439
0
      iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25440
0
      continue;
25441
0
  }
25442
25443
0
  ACTIVATE_ATTRIBUTE(iattr);
25444
0
  fixed = 0;
25445
0
  xpathRes = 0;
25446
25447
0
  if (vctxt->xpathStates != NULL) {
25448
      /*
25449
      * Evaluate IDCs.
25450
      */
25451
0
      xpathRes = xmlSchemaXPathEvaluate(vctxt,
25452
0
    XML_ATTRIBUTE_NODE);
25453
0
      if (xpathRes == -1) {
25454
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25455
0
        "calling xmlSchemaXPathEvaluate()");
25456
0
    goto internal_error;
25457
0
      }
25458
0
  }
25459
25460
0
  if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25461
      /*
25462
      * Default/fixed attributes.
25463
      * We need the value only if we need to resolve IDCs or
25464
      * will create default attributes.
25465
      */
25466
0
      if ((xpathRes) || (defAttrOwnerElem)) {
25467
0
    if (iattr->use->defValue != NULL) {
25468
0
        iattr->value = (xmlChar *) iattr->use->defValue;
25469
0
        iattr->val = iattr->use->defVal;
25470
0
    } else {
25471
0
        iattr->value = (xmlChar *) iattr->decl->defValue;
25472
0
        iattr->val = iattr->decl->defVal;
25473
0
    }
25474
    /*
25475
    * IDCs will consume the precomputed default value,
25476
    * so we need to clone it.
25477
    */
25478
0
    if (iattr->val == NULL) {
25479
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25480
0
      "default/fixed value on an attribute use was "
25481
0
      "not precomputed");
25482
0
        goto internal_error;
25483
0
    }
25484
0
    iattr->val = xmlSchemaCopyValue(iattr->val);
25485
0
    if (iattr->val == NULL) {
25486
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25487
0
      "calling xmlSchemaCopyValue()");
25488
0
        goto internal_error;
25489
0
    }
25490
0
      }
25491
      /*
25492
      * PSVI: Add the default attribute to the current element.
25493
      * VAL TODO: Should we use the *normalized* value? This currently
25494
      *   uses the *initial* value.
25495
      */
25496
25497
0
      if (defAttrOwnerElem) {
25498
0
    xmlChar *normValue;
25499
0
    const xmlChar *value;
25500
25501
0
    value = iattr->value;
25502
    /*
25503
    * Normalize the value.
25504
    */
25505
0
    normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25506
0
        iattr->value);
25507
0
    if (normValue != NULL)
25508
0
        value = BAD_CAST normValue;
25509
25510
0
    if (iattr->nsName == NULL) {
25511
0
        if (xmlNewProp(defAttrOwnerElem,
25512
0
      iattr->localName, value) == NULL) {
25513
0
      VERROR_INT("xmlSchemaVAttributesComplex",
25514
0
          "calling xmlNewProp()");
25515
0
      if (normValue != NULL)
25516
0
          xmlFree(normValue);
25517
0
      goto internal_error;
25518
0
        }
25519
0
    } else {
25520
0
        xmlNsPtr ns;
25521
25522
0
        ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25523
0
      defAttrOwnerElem, iattr->nsName);
25524
0
        if (ns == NULL) {
25525
0
      xmlChar prefix[13];
25526
0
      int counter = 0;
25527
25528
      /*
25529
      * Create a namespace declaration on the validation
25530
      * root node if no namespace declaration is in scope.
25531
      */
25532
0
      do {
25533
0
          snprintf((char *) prefix, 13, "p%d", counter++);
25534
0
          ns = xmlSearchNs(defAttrOwnerElem->doc,
25535
0
        defAttrOwnerElem, BAD_CAST prefix);
25536
0
          if (counter > 1000) {
25537
0
        VERROR_INT(
25538
0
            "xmlSchemaVAttributesComplex",
25539
0
            "could not compute a ns prefix for a "
25540
0
            "default/fixed attribute");
25541
0
        if (normValue != NULL)
25542
0
            xmlFree(normValue);
25543
0
        goto internal_error;
25544
0
          }
25545
0
      } while (ns != NULL);
25546
0
      ns = xmlNewNs(vctxt->validationRoot,
25547
0
          iattr->nsName, BAD_CAST prefix);
25548
0
        }
25549
        /*
25550
        * TODO:
25551
        * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25552
        * If we have QNames: do we need to ensure there's a
25553
        * prefix defined for the QName?
25554
        */
25555
0
        xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25556
0
    }
25557
0
    if (normValue != NULL)
25558
0
        xmlFree(normValue);
25559
0
      }
25560
      /*
25561
      * Go directly to IDC evaluation.
25562
      */
25563
0
      goto eval_idcs;
25564
0
  }
25565
  /*
25566
  * Validate the value.
25567
  */
25568
0
  if (vctxt->value != NULL) {
25569
      /*
25570
      * Free last computed value; just for safety reasons.
25571
      */
25572
0
      xmlSchemaFreeValue(vctxt->value);
25573
0
      vctxt->value = NULL;
25574
0
  }
25575
  /*
25576
  * Note that the attribute *use* can be unavailable, if
25577
  * the attribute was a wild attribute.
25578
  */
25579
0
  if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25580
0
      ((iattr->use != NULL) &&
25581
0
       (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25582
0
      fixed = 1;
25583
0
  else
25584
0
      fixed = 0;
25585
  /*
25586
  * SPEC (cvc-attribute)
25587
  * (3) "The item's `normalized value` must be locally `valid`
25588
  * with respect to that {type definition} as per
25589
  * String Valid ($3.14.4)."
25590
  *
25591
  * VAL TODO: Do we already have the
25592
  * "normalized attribute value" here?
25593
  */
25594
0
  if (xpathRes || fixed) {
25595
0
      iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25596
      /*
25597
      * Request a computed value.
25598
      */
25599
0
      res = xmlSchemaVCheckCVCSimpleType(
25600
0
    ACTXT_CAST vctxt,
25601
0
    iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25602
0
    1, 1, 0);
25603
0
  } else {
25604
0
      res = xmlSchemaVCheckCVCSimpleType(
25605
0
    ACTXT_CAST vctxt,
25606
0
    iattr->node, iattr->typeDef, iattr->value, NULL,
25607
0
    1, 0, 0);
25608
0
  }
25609
25610
0
  if (res != 0) {
25611
0
      if (res == -1) {
25612
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25613
0
        "calling xmlSchemaStreamValidateSimpleTypeValue()");
25614
0
    goto internal_error;
25615
0
      }
25616
0
      iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25617
      /*
25618
      * SPEC PSVI Assessment Outcome (Attribute)
25619
      * [validity] = "invalid"
25620
      */
25621
0
      goto eval_idcs;
25622
0
  }
25623
25624
0
  if (fixed) {
25625
      /*
25626
      * SPEC Attribute Locally Valid (Use) (cvc-au)
25627
      * "For an attribute information item to be `valid`
25628
      * with respect to an attribute use its *normalized*
25629
      * value must match the *canonical* lexical
25630
      * representation of the attribute use's {value
25631
      * constraint}value, if it is present and fixed."
25632
      *
25633
      * VAL TODO: The requirement for the *canonical* value
25634
      * will be removed in XML Schema 1.1.
25635
      */
25636
      /*
25637
      * SPEC Attribute Locally Valid (cvc-attribute)
25638
      * (4) "The item's *actual* value must match the *value* of
25639
      * the {value constraint}, if it is present and fixed."
25640
      */
25641
0
      if (iattr->val == NULL) {
25642
    /* VAL TODO: A value was not precomputed. */
25643
0
    goto eval_idcs;
25644
0
      }
25645
0
      if ((iattr->use != NULL) &&
25646
0
    (iattr->use->defValue != NULL)) {
25647
0
    if (iattr->use->defVal == NULL) {
25648
        /* VAL TODO: A default value was not precomputed. */
25649
0
        goto eval_idcs;
25650
0
    }
25651
0
    iattr->vcValue = iattr->use->defValue;
25652
    /*
25653
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25654
        (xmlSchemaWhitespaceValueType) ws,
25655
        attr->use->defVal,
25656
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25657
    */
25658
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25659
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25660
0
      } else {
25661
0
    if (iattr->decl->defVal == NULL) {
25662
        /* VAL TODO: A default value was not precomputed. */
25663
0
        goto eval_idcs;
25664
0
    }
25665
0
    iattr->vcValue = iattr->decl->defValue;
25666
    /*
25667
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25668
        (xmlSchemaWhitespaceValueType) ws,
25669
        attrDecl->defVal,
25670
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25671
    */
25672
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25673
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25674
0
      }
25675
      /*
25676
      * [validity] = "valid"
25677
      */
25678
0
  }
25679
0
eval_idcs:
25680
  /*
25681
  * Evaluate IDCs.
25682
  */
25683
0
  if (xpathRes) {
25684
0
      if (xmlSchemaXPathProcessHistory(vctxt,
25685
0
    vctxt->depth +1) == -1) {
25686
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25687
0
        "calling xmlSchemaXPathEvaluate()");
25688
0
    goto internal_error;
25689
0
      }
25690
0
  } else if (vctxt->xpathStates != NULL)
25691
0
      xmlSchemaXPathPop(vctxt);
25692
0
    }
25693
25694
    /*
25695
    * Report errors.
25696
    */
25697
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25698
0
  iattr = vctxt->attrInfos[i];
25699
0
  if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25700
0
      (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25701
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25702
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25703
0
      continue;
25704
0
  ACTIVATE_ATTRIBUTE(iattr);
25705
0
  switch (iattr->state) {
25706
0
      case XML_SCHEMAS_ATTR_ERR_MISSING: {
25707
0
        xmlChar *str = NULL;
25708
0
        ACTIVATE_ELEM;
25709
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
25710
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25711
0
      "The attribute '%s' is required but missing",
25712
0
      xmlSchemaFormatQName(&str,
25713
0
          iattr->decl->targetNamespace,
25714
0
          iattr->decl->name),
25715
0
      NULL);
25716
0
        FREE_AND_NULL(str)
25717
0
        break;
25718
0
    }
25719
0
      case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25720
0
    VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25721
0
        "The type definition is absent");
25722
0
    break;
25723
0
      case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25724
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25725
0
        XML_SCHEMAV_CVC_AU, NULL, NULL,
25726
0
        "The value '%s' does not match the fixed "
25727
0
        "value constraint '%s'",
25728
0
        iattr->value, iattr->vcValue);
25729
0
    break;
25730
0
      case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25731
0
    VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25732
0
        "No matching global attribute declaration available, but "
25733
0
        "demanded by the strict wildcard");
25734
0
    break;
25735
0
      case XML_SCHEMAS_ATTR_UNKNOWN:
25736
0
    if (iattr->metaType)
25737
0
        break;
25738
    /*
25739
    * MAYBE VAL TODO: One might report different error messages
25740
    * for the following errors.
25741
    */
25742
0
    if (type->attributeWildcard == NULL) {
25743
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25744
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25745
0
    } else {
25746
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25747
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25748
0
    }
25749
0
    break;
25750
0
      default:
25751
0
    break;
25752
0
  }
25753
0
    }
25754
25755
0
    ACTIVATE_ELEM;
25756
0
    return (0);
25757
0
internal_error:
25758
0
    ACTIVATE_ELEM;
25759
0
    return (-1);
25760
0
}
25761
25762
static int
25763
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25764
            int *skip)
25765
0
{
25766
0
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25767
    /*
25768
    * The namespace of the element was already identified to be
25769
    * matching the wildcard.
25770
    */
25771
0
    if ((skip == NULL) || (wild == NULL) ||
25772
0
  (wild->type != XML_SCHEMA_TYPE_ANY)) {
25773
0
  VERROR_INT("xmlSchemaValidateElemWildcard",
25774
0
      "bad arguments");
25775
0
  return (-1);
25776
0
    }
25777
0
    *skip = 0;
25778
0
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25779
  /*
25780
  * URGENT VAL TODO: Either we need to position the stream to the
25781
  * next sibling, or walk the whole subtree.
25782
  */
25783
0
  *skip = 1;
25784
0
  return (0);
25785
0
    }
25786
0
    {
25787
0
  xmlSchemaElementPtr decl = NULL;
25788
25789
0
  decl = xmlSchemaGetElem(vctxt->schema,
25790
0
      vctxt->inode->localName, vctxt->inode->nsName);
25791
0
  if (decl != NULL) {
25792
0
      vctxt->inode->decl = decl;
25793
0
      return (0);
25794
0
  }
25795
0
    }
25796
0
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25797
  /* VAL TODO: Change to proper error code. */
25798
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25799
0
      "No matching global element declaration available, but "
25800
0
      "demanded by the strict wildcard");
25801
0
  return (vctxt->err);
25802
0
    }
25803
0
    if (vctxt->nbAttrInfos != 0) {
25804
0
  xmlSchemaAttrInfoPtr iattr;
25805
  /*
25806
  * SPEC Validation Rule: Schema-Validity Assessment (Element)
25807
  * (1.2.1.2.1) - (1.2.1.2.3 )
25808
  *
25809
  * Use the xsi:type attribute for the type definition.
25810
  */
25811
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25812
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25813
0
  if (iattr != NULL) {
25814
0
      if (xmlSchemaProcessXSIType(vctxt, iattr,
25815
0
    &(vctxt->inode->typeDef), NULL) == -1) {
25816
0
    VERROR_INT("xmlSchemaValidateElemWildcard",
25817
0
        "calling xmlSchemaProcessXSIType() to "
25818
0
        "process the attribute 'xsi:nil'");
25819
0
    return (-1);
25820
0
      }
25821
      /*
25822
      * Don't return an error on purpose.
25823
      */
25824
0
      return (0);
25825
0
  }
25826
0
    }
25827
    /*
25828
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
25829
    *
25830
    * Fallback to "anyType".
25831
    */
25832
0
    vctxt->inode->typeDef =
25833
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25834
0
    return (0);
25835
0
}
25836
25837
/*
25838
* xmlSchemaCheckCOSValidDefault:
25839
*
25840
* This will be called if: not nilled, no content and a default/fixed
25841
* value is provided.
25842
*/
25843
25844
static int
25845
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25846
            const xmlChar *value,
25847
            xmlSchemaValPtr *val)
25848
0
{
25849
0
    int ret = 0;
25850
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25851
25852
    /*
25853
    * cos-valid-default:
25854
    * Schema Component Constraint: Element Default Valid (Immediate)
25855
    * For a string to be a valid default with respect to a type
25856
    * definition the appropriate case among the following must be true:
25857
    */
25858
0
    if WXS_IS_COMPLEX(inode->typeDef) {
25859
  /*
25860
  * Complex type.
25861
  *
25862
  * SPEC (2.1) "its {content type} must be a simple type definition
25863
  * or mixed."
25864
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
25865
  * type}'s particle must be `emptiable` as defined by
25866
  * Particle Emptiable ($3.9.6)."
25867
  */
25868
0
  if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25869
0
      ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25870
0
       (! WXS_EMPTIABLE(inode->typeDef)))) {
25871
0
      ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25872
      /* NOTE that this covers (2.2.2) as well. */
25873
0
      VERROR(ret, NULL,
25874
0
    "For a string to be a valid default, the type definition "
25875
0
    "must be a simple type or a complex type with simple content "
25876
0
    "or mixed content and a particle emptiable");
25877
0
      return(ret);
25878
0
  }
25879
0
    }
25880
    /*
25881
    * 1 If the type definition is a simple type definition, then the string
25882
    * must be `valid` with respect to that definition as defined by String
25883
    * Valid ($3.14.4).
25884
    *
25885
    * AND
25886
    *
25887
    * 2.2.1 If the {content type} is a simple type definition, then the
25888
    * string must be `valid` with respect to that simple type definition
25889
    * as defined by String Valid ($3.14.4).
25890
    */
25891
0
    if (WXS_IS_SIMPLE(inode->typeDef)) {
25892
25893
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25894
0
      NULL, inode->typeDef, value, val, 1, 1, 0);
25895
25896
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25897
25898
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25899
0
      NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25900
0
    }
25901
0
    if (ret < 0) {
25902
0
  VERROR_INT("xmlSchemaCheckCOSValidDefault",
25903
0
      "calling xmlSchemaVCheckCVCSimpleType()");
25904
0
    }
25905
0
    return (ret);
25906
0
}
25907
25908
static void
25909
xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
25910
             const xmlChar * name ATTRIBUTE_UNUSED,
25911
             void *transdata, void *inputdata)
25912
0
{
25913
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
25914
0
    xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
25915
0
    inode->decl = item;
25916
0
}
25917
25918
static int
25919
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25920
0
{
25921
0
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25922
0
    if (vctxt->inode == NULL) {
25923
0
  VERROR_INT("xmlSchemaValidatorPushElem",
25924
0
      "calling xmlSchemaGetFreshElemInfo()");
25925
0
  return (-1);
25926
0
    }
25927
0
    vctxt->nbAttrInfos = 0;
25928
0
    return (0);
25929
0
}
25930
25931
static int
25932
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25933
           xmlSchemaNodeInfoPtr inode,
25934
           xmlSchemaTypePtr type,
25935
           const xmlChar *value)
25936
0
{
25937
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25938
0
  return (xmlSchemaVCheckCVCSimpleType(
25939
0
      ACTXT_CAST vctxt, NULL,
25940
0
      type, value, &(inode->val), 1, 1, 0));
25941
0
    else
25942
0
  return (xmlSchemaVCheckCVCSimpleType(
25943
0
      ACTXT_CAST vctxt, NULL,
25944
0
      type, value, NULL, 1, 0, 0));
25945
0
}
25946
25947
25948
25949
/*
25950
* Process END of element.
25951
*/
25952
static int
25953
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25954
0
{
25955
0
    int ret = 0;
25956
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25957
25958
0
    if (vctxt->nbAttrInfos != 0)
25959
0
  xmlSchemaClearAttrInfos(vctxt);
25960
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25961
  /*
25962
  * This element was not expected;
25963
  * we will not validate child elements of broken parents.
25964
  * Skip validation of all content of the parent.
25965
  */
25966
0
  vctxt->skipDepth = vctxt->depth -1;
25967
0
  goto end_elem;
25968
0
    }
25969
0
    if ((inode->typeDef == NULL) ||
25970
0
  (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25971
  /*
25972
  * 1. the type definition might be missing if the element was
25973
  *    error prone
25974
  * 2. it might be abstract.
25975
  */
25976
0
  goto end_elem;
25977
0
    }
25978
    /*
25979
    * Check the content model.
25980
    */
25981
0
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
25982
0
  (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
25983
25984
  /*
25985
  * Workaround for "anyType".
25986
  */
25987
0
  if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
25988
0
      goto character_content;
25989
25990
0
  if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
25991
0
      xmlChar *values[10];
25992
0
      int terminal, nbval = 10, nbneg;
25993
25994
0
      if (inode->regexCtxt == NULL) {
25995
    /*
25996
    * Create the regex context.
25997
    */
25998
0
    inode->regexCtxt =
25999
0
        xmlRegNewExecCtxt(inode->typeDef->contModel,
26000
0
        xmlSchemaVContentModelCallback, vctxt);
26001
0
    if (inode->regexCtxt == NULL) {
26002
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26003
0
      "failed to create a regex context");
26004
0
        goto internal_error;
26005
0
    }
26006
0
      }
26007
26008
      /*
26009
       * Do not check further content if the node has been nilled
26010
       */
26011
0
      if (INODE_NILLED(inode)) {
26012
0
    ret = 0;
26013
0
                goto skip_nilled;
26014
0
      }
26015
26016
      /*
26017
      * Get hold of the still expected content, since a further
26018
      * call to xmlRegExecPushString() will lose this information.
26019
      */
26020
0
      xmlRegExecNextValues(inode->regexCtxt,
26021
0
    &nbval, &nbneg, &values[0], &terminal);
26022
0
      ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26023
0
      if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26024
    /*
26025
    * Still missing something.
26026
    */
26027
0
    ret = 1;
26028
0
    inode->flags |=
26029
0
        XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26030
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26031
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26032
0
        "Missing child element(s)",
26033
0
        nbval, nbneg, values);
26034
0
      } else {
26035
    /*
26036
    * Content model is satisfied.
26037
    */
26038
0
    ret = 0;
26039
0
      }
26040
26041
0
  }
26042
0
    }
26043
26044
0
skip_nilled:
26045
26046
0
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26047
0
  goto end_elem;
26048
26049
0
character_content:
26050
26051
0
    if (vctxt->value != NULL) {
26052
0
  xmlSchemaFreeValue(vctxt->value);
26053
0
  vctxt->value = NULL;
26054
0
    }
26055
    /*
26056
    * Check character content.
26057
    */
26058
0
    if (inode->decl == NULL) {
26059
  /*
26060
  * Speedup if no declaration exists.
26061
  */
26062
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26063
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26064
0
    inode, inode->typeDef, inode->value);
26065
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26066
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26067
0
    inode, inode->typeDef->contentTypeDef,
26068
0
    inode->value);
26069
0
  }
26070
0
  if (ret < 0) {
26071
0
      VERROR_INT("xmlSchemaValidatorPopElem",
26072
0
    "calling xmlSchemaVCheckCVCSimpleType()");
26073
0
      goto internal_error;
26074
0
  }
26075
0
  goto end_elem;
26076
0
    }
26077
    /*
26078
    * cvc-elt (3.3.4) : 5
26079
    * The appropriate case among the following must be true:
26080
    */
26081
    /*
26082
    * cvc-elt (3.3.4) : 5.1
26083
    * If the declaration has a {value constraint},
26084
    * the item has neither element nor character [children] and
26085
    * clause 3.2 has not applied, then all of the following must be true:
26086
    */
26087
0
    if ((inode->decl->value != NULL) &&
26088
0
  (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26089
0
  (! INODE_NILLED(inode))) {
26090
  /*
26091
  * cvc-elt (3.3.4) : 5.1.1
26092
  * If the `actual type definition` is a `local type definition`
26093
  * then the canonical lexical representation of the {value constraint}
26094
  * value must be a valid default for the `actual type definition` as
26095
  * defined in Element Default Valid (Immediate) ($3.3.6).
26096
  */
26097
  /*
26098
  * NOTE: 'local' above means types acquired by xsi:type.
26099
  * NOTE: Although the *canonical* value is stated, it is not
26100
  * relevant if canonical or not. Additionally XML Schema 1.1
26101
  * will removed this requirement as well.
26102
  */
26103
0
  if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26104
26105
0
      ret = xmlSchemaCheckCOSValidDefault(vctxt,
26106
0
    inode->decl->value, &(inode->val));
26107
0
      if (ret != 0) {
26108
0
    if (ret < 0) {
26109
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26110
0
      "calling xmlSchemaCheckCOSValidDefault()");
26111
0
        goto internal_error;
26112
0
    }
26113
0
    goto end_elem;
26114
0
      }
26115
      /*
26116
      * Stop here, to avoid redundant validation of the value
26117
      * (see following).
26118
      */
26119
0
      goto default_psvi;
26120
0
  }
26121
  /*
26122
  * cvc-elt (3.3.4) : 5.1.2
26123
  * The element information item with the canonical lexical
26124
  * representation of the {value constraint} value used as its
26125
  * `normalized value` must be `valid` with respect to the
26126
  * `actual type definition` as defined by Element Locally Valid (Type)
26127
  * ($3.3.4).
26128
  */
26129
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26130
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26131
0
    inode, inode->typeDef, inode->decl->value);
26132
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26133
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26134
0
    inode, inode->typeDef->contentTypeDef,
26135
0
    inode->decl->value);
26136
0
  }
26137
0
  if (ret != 0) {
26138
0
      if (ret < 0) {
26139
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26140
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26141
0
    goto internal_error;
26142
0
      }
26143
0
      goto end_elem;
26144
0
  }
26145
26146
0
default_psvi:
26147
  /*
26148
  * PSVI: Create a text node on the instance element.
26149
  */
26150
0
  if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26151
0
      (inode->node != NULL)) {
26152
0
      xmlNodePtr textChild;
26153
0
      xmlChar *normValue;
26154
      /*
26155
      * VAL TODO: Normalize the value.
26156
      */
26157
0
      normValue = xmlSchemaNormalizeValue(inode->typeDef,
26158
0
    inode->decl->value);
26159
0
      if (normValue != NULL) {
26160
0
    textChild = xmlNewDocText(inode->node->doc,
26161
0
                        BAD_CAST normValue);
26162
0
    xmlFree(normValue);
26163
0
      } else
26164
0
    textChild = xmlNewDocText(inode->node->doc,
26165
0
                        inode->decl->value);
26166
0
      if (textChild == NULL) {
26167
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26168
0
        "calling xmlNewDocText()");
26169
0
    goto internal_error;
26170
0
      } else
26171
0
    xmlAddChild(inode->node, textChild);
26172
0
  }
26173
26174
0
    } else if (! INODE_NILLED(inode)) {
26175
  /*
26176
  * 5.2.1 The element information item must be `valid` with respect
26177
  * to the `actual type definition` as defined by Element Locally
26178
  * Valid (Type) ($3.3.4).
26179
  */
26180
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26181
       /*
26182
      * SPEC (cvc-type) (3.1)
26183
      * "If the type definition is a simple type definition, ..."
26184
      * (3.1.3) "If clause 3.2 of Element Locally Valid
26185
      * (Element) ($3.3.4) did not apply, then the `normalized value`
26186
      * must be `valid` with respect to the type definition as defined
26187
      * by String Valid ($3.14.4).
26188
      */
26189
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26190
0
        inode, inode->typeDef, inode->value);
26191
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26192
      /*
26193
      * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26194
      * definition, then the element information item must be
26195
      * `valid` with respect to the type definition as per
26196
      * Element Locally Valid (Complex Type) ($3.4.4);"
26197
      *
26198
      * SPEC (cvc-complex-type) (2.2)
26199
      * "If the {content type} is a simple type definition, ...
26200
      * the `normalized value` of the element information item is
26201
      * `valid` with respect to that simple type definition as
26202
      * defined by String Valid ($3.14.4)."
26203
      */
26204
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26205
0
    inode, inode->typeDef->contentTypeDef, inode->value);
26206
0
  }
26207
0
  if (ret != 0) {
26208
0
      if (ret < 0) {
26209
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26210
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26211
0
    goto internal_error;
26212
0
      }
26213
0
      goto end_elem;
26214
0
  }
26215
  /*
26216
  * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26217
  * not applied, all of the following must be true:
26218
  */
26219
0
  if ((inode->decl->value != NULL) &&
26220
0
      (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26221
26222
      /*
26223
      * TODO: We will need a computed value, when comparison is
26224
      * done on computed values.
26225
      */
26226
      /*
26227
      * 5.2.2.1 The element information item must have no element
26228
      * information item [children].
26229
      */
26230
0
      if (inode->flags &
26231
0
        XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26232
0
    ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26233
0
    VERROR(ret, NULL,
26234
0
        "The content must not contain element nodes since "
26235
0
        "there is a fixed value constraint");
26236
0
    goto end_elem;
26237
0
      } else {
26238
    /*
26239
    * 5.2.2.2 The appropriate case among the following must
26240
    * be true:
26241
    */
26242
0
    if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26243
        /*
26244
        * 5.2.2.2.1 If the {content type} of the `actual type
26245
        * definition` is mixed, then the *initial value* of the
26246
        * item must match the canonical lexical representation
26247
        * of the {value constraint} value.
26248
        *
26249
        * ... the *initial value* of an element information
26250
        * item is the string composed of, in order, the
26251
        * [character code] of each character information item in
26252
        * the [children] of that element information item.
26253
        */
26254
0
        if (! xmlStrEqual(inode->value, inode->decl->value)){
26255
      /*
26256
      * VAL TODO: Report invalid & expected values as well.
26257
      * VAL TODO: Implement the canonical stuff.
26258
      */
26259
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26260
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26261
0
          ret, NULL, NULL,
26262
0
          "The initial value '%s' does not match the fixed "
26263
0
          "value constraint '%s'",
26264
0
          inode->value, inode->decl->value);
26265
0
      goto end_elem;
26266
0
        }
26267
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26268
        /*
26269
        * 5.2.2.2.2 If the {content type} of the `actual type
26270
        * definition` is a simple type definition, then the
26271
        * *actual value* of the item must match the canonical
26272
        * lexical representation of the {value constraint} value.
26273
        */
26274
        /*
26275
        * VAL TODO: *actual value* is the normalized value, impl.
26276
        *           this.
26277
        * VAL TODO: Report invalid & expected values as well.
26278
        * VAL TODO: Implement a comparison with the computed values.
26279
        */
26280
0
        if (! xmlStrEqual(inode->value,
26281
0
          inode->decl->value)) {
26282
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26283
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26284
0
          ret, NULL, NULL,
26285
0
          "The actual value '%s' does not match the fixed "
26286
0
          "value constraint '%s'",
26287
0
          inode->value,
26288
0
          inode->decl->value);
26289
0
      goto end_elem;
26290
0
        }
26291
0
    }
26292
0
      }
26293
0
  }
26294
0
    }
26295
26296
0
end_elem:
26297
0
    if (vctxt->depth < 0) {
26298
  /* TODO: raise error? */
26299
0
  return (0);
26300
0
    }
26301
0
    if (vctxt->depth == vctxt->skipDepth)
26302
0
  vctxt->skipDepth = -1;
26303
    /*
26304
    * Evaluate the history of XPath state objects.
26305
    */
26306
0
    if (inode->appliedXPath &&
26307
0
  (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26308
0
  goto internal_error;
26309
    /*
26310
    * MAYBE TODO:
26311
    * SPEC (6) "The element information item must be `valid` with
26312
    * respect to each of the {identity-constraint definitions} as per
26313
    * Identity-constraint Satisfied ($3.11.4)."
26314
    */
26315
    /*
26316
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26317
    *   need to be built in any case.
26318
    *   We will currently build IDC node-tables and bubble them only if
26319
    *   keyrefs do exist.
26320
    */
26321
26322
    /*
26323
    * Add the current IDC target-nodes to the IDC node-tables.
26324
    */
26325
0
    if ((inode->idcMatchers != NULL) &&
26326
0
  (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26327
0
    {
26328
0
  if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26329
0
      goto internal_error;
26330
0
    }
26331
    /*
26332
    * Validate IDC keyrefs.
26333
    */
26334
0
    if (vctxt->inode->hasKeyrefs)
26335
0
  if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26336
0
      goto internal_error;
26337
    /*
26338
    * Merge/free the IDC table.
26339
    */
26340
0
    if (inode->idcTable != NULL) {
26341
0
  if ((vctxt->depth > 0) &&
26342
0
      (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26343
0
  {
26344
      /*
26345
      * Merge the IDC node table with the table of the parent node.
26346
      */
26347
0
      if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26348
0
    goto internal_error;
26349
0
  }
26350
0
    }
26351
    /*
26352
    * Clear the current ielem.
26353
    * VAL TODO: Don't free the PSVI IDC tables if they are
26354
    * requested for the PSVI.
26355
    */
26356
0
    xmlSchemaClearElemInfo(vctxt, inode);
26357
    /*
26358
    * Skip further processing if we are on the validation root.
26359
    */
26360
0
    if (vctxt->depth == 0) {
26361
0
  vctxt->depth--;
26362
0
  vctxt->inode = NULL;
26363
0
  return (0);
26364
0
    }
26365
    /*
26366
    * Reset the keyrefDepth if needed.
26367
    */
26368
0
    if (vctxt->aidcs != NULL) {
26369
0
  xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26370
0
  do {
26371
0
      if (aidc->keyrefDepth == vctxt->depth) {
26372
    /*
26373
    * A 'keyrefDepth' of a key/unique IDC matches the current
26374
    * depth, this means that we are leaving the scope of the
26375
    * top-most keyref IDC which refers to this IDC.
26376
    */
26377
0
    aidc->keyrefDepth = -1;
26378
0
      }
26379
0
      aidc = aidc->next;
26380
0
  } while (aidc != NULL);
26381
0
    }
26382
0
    vctxt->depth--;
26383
0
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
26384
    /*
26385
    * VAL TODO: 7 If the element information item is the `validation root`, it must be
26386
    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26387
    */
26388
0
    return (ret);
26389
26390
0
internal_error:
26391
0
    vctxt->err = -1;
26392
0
    return (-1);
26393
0
}
26394
26395
/*
26396
* 3.4.4 Complex Type Definition Validation Rules
26397
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26398
*/
26399
static int
26400
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26401
0
{
26402
0
    xmlSchemaNodeInfoPtr pielem;
26403
0
    xmlSchemaTypePtr ptype;
26404
0
    int ret = 0;
26405
26406
0
    if (vctxt->depth <= 0) {
26407
0
  VERROR_INT("xmlSchemaValidateChildElem",
26408
0
      "not intended for the validation root");
26409
0
  return (-1);
26410
0
    }
26411
0
    pielem = vctxt->elemInfos[vctxt->depth -1];
26412
0
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26413
0
  pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26414
    /*
26415
    * Handle 'nilled' elements.
26416
    */
26417
0
    if (INODE_NILLED(pielem)) {
26418
  /*
26419
  * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26420
  */
26421
0
  ACTIVATE_PARENT_ELEM;
26422
0
  ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26423
0
  VERROR(ret, NULL,
26424
0
      "Neither character nor element content is allowed, "
26425
0
      "because the element was 'nilled'");
26426
0
  ACTIVATE_ELEM;
26427
0
  goto unexpected_elem;
26428
0
    }
26429
26430
0
    ptype = pielem->typeDef;
26431
26432
0
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26433
  /*
26434
  * Workaround for "anyType": we have currently no content model
26435
  * assigned for "anyType", so handle it explicitly.
26436
  * "anyType" has an unbounded, lax "any" wildcard.
26437
  */
26438
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26439
0
      vctxt->inode->localName,
26440
0
      vctxt->inode->nsName);
26441
26442
0
  if (vctxt->inode->decl == NULL) {
26443
0
      xmlSchemaAttrInfoPtr iattr;
26444
      /*
26445
      * Process "xsi:type".
26446
      * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26447
      */
26448
0
      iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26449
0
    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26450
0
      if (iattr != NULL) {
26451
0
    ret = xmlSchemaProcessXSIType(vctxt, iattr,
26452
0
        &(vctxt->inode->typeDef), NULL);
26453
0
    if (ret != 0) {
26454
0
        if (ret == -1) {
26455
0
      VERROR_INT("xmlSchemaValidateChildElem",
26456
0
          "calling xmlSchemaProcessXSIType() to "
26457
0
          "process the attribute 'xsi:nil'");
26458
0
      return (-1);
26459
0
        }
26460
0
        return (ret);
26461
0
    }
26462
0
      } else {
26463
     /*
26464
     * Fallback to "anyType".
26465
     *
26466
     * SPEC (cvc-assess-elt)
26467
     * "If the item cannot be `strictly assessed`, [...]
26468
     * an element information item's schema validity may be laxly
26469
     * assessed if its `context-determined declaration` is not
26470
     * skip by `validating` with respect to the `ur-type
26471
     * definition` as per Element Locally Valid (Type) ($3.3.4)."
26472
    */
26473
0
    vctxt->inode->typeDef =
26474
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26475
0
      }
26476
0
  }
26477
0
  return (0);
26478
0
    }
26479
26480
0
    switch (ptype->contentType) {
26481
0
  case XML_SCHEMA_CONTENT_EMPTY:
26482
      /*
26483
      * SPEC (2.1) "If the {content type} is empty, then the
26484
      * element information item has no character or element
26485
      * information item [children]."
26486
      */
26487
0
      ACTIVATE_PARENT_ELEM
26488
0
      ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26489
0
      VERROR(ret, NULL,
26490
0
    "Element content is not allowed, "
26491
0
    "because the content type is empty");
26492
0
      ACTIVATE_ELEM
26493
0
      goto unexpected_elem;
26494
0
      break;
26495
26496
0
  case XML_SCHEMA_CONTENT_MIXED:
26497
0
        case XML_SCHEMA_CONTENT_ELEMENTS: {
26498
0
      xmlRegExecCtxtPtr regexCtxt;
26499
0
      xmlChar *values[10];
26500
0
      int terminal, nbval = 10, nbneg;
26501
26502
      /* VAL TODO: Optimized "anyType" validation.*/
26503
26504
0
      if (ptype->contModel == NULL) {
26505
0
    VERROR_INT("xmlSchemaValidateChildElem",
26506
0
        "type has elem content but no content model");
26507
0
    return (-1);
26508
0
      }
26509
      /*
26510
      * Safety belt for evaluation if the cont. model was already
26511
      * examined to be invalid.
26512
      */
26513
0
      if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26514
0
    VERROR_INT("xmlSchemaValidateChildElem",
26515
0
        "validating elem, but elem content is already invalid");
26516
0
    return (-1);
26517
0
      }
26518
26519
0
      regexCtxt = pielem->regexCtxt;
26520
0
      if (regexCtxt == NULL) {
26521
    /*
26522
    * Create the regex context.
26523
    */
26524
0
    regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26525
0
        xmlSchemaVContentModelCallback, vctxt);
26526
0
    if (regexCtxt == NULL) {
26527
0
        VERROR_INT("xmlSchemaValidateChildElem",
26528
0
      "failed to create a regex context");
26529
0
        return (-1);
26530
0
    }
26531
0
    pielem->regexCtxt = regexCtxt;
26532
0
      }
26533
26534
      /*
26535
      * SPEC (2.4) "If the {content type} is element-only or mixed,
26536
      * then the sequence of the element information item's
26537
      * element information item [children], if any, taken in
26538
      * order, is `valid` with respect to the {content type}'s
26539
      * particle, as defined in Element Sequence Locally Valid
26540
      * (Particle) ($3.9.4)."
26541
      */
26542
0
      ret = xmlRegExecPushString2(regexCtxt,
26543
0
    vctxt->inode->localName,
26544
0
    vctxt->inode->nsName,
26545
0
    vctxt->inode);
26546
0
      if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26547
0
    VERROR_INT("xmlSchemaValidateChildElem",
26548
0
        "calling xmlRegExecPushString2()");
26549
0
    return (-1);
26550
0
      }
26551
0
      if (ret < 0) {
26552
0
    xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26553
0
        &values[0], &terminal);
26554
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26555
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26556
0
        "This element is not expected",
26557
0
        nbval, nbneg, values);
26558
0
    ret = vctxt->err;
26559
0
    goto unexpected_elem;
26560
0
      } else
26561
0
    ret = 0;
26562
0
  }
26563
0
      break;
26564
0
  case XML_SCHEMA_CONTENT_SIMPLE:
26565
0
  case XML_SCHEMA_CONTENT_BASIC:
26566
0
      ACTIVATE_PARENT_ELEM
26567
0
      if (WXS_IS_COMPLEX(ptype)) {
26568
    /*
26569
    * SPEC (cvc-complex-type) (2.2)
26570
    * "If the {content type} is a simple type definition, then
26571
    * the element information item has no element information
26572
    * item [children], ..."
26573
    */
26574
0
    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26575
0
    VERROR(ret, NULL, "Element content is not allowed, "
26576
0
        "because the content type is a simple type definition");
26577
0
      } else {
26578
    /*
26579
    * SPEC (cvc-type) (3.1.2) "The element information item must
26580
    * have no element information item [children]."
26581
    */
26582
0
    ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26583
0
    VERROR(ret, NULL, "Element content is not allowed, "
26584
0
        "because the type definition is simple");
26585
0
      }
26586
0
      ACTIVATE_ELEM
26587
0
      ret = vctxt->err;
26588
0
      goto unexpected_elem;
26589
0
      break;
26590
26591
0
  default:
26592
0
      break;
26593
0
    }
26594
0
    return (ret);
26595
0
unexpected_elem:
26596
    /*
26597
    * Pop this element and set the skipDepth to skip
26598
    * all further content of the parent element.
26599
    */
26600
0
    vctxt->skipDepth = vctxt->depth;
26601
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26602
0
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26603
0
    return (ret);
26604
0
}
26605
26606
0
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26607
0
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26608
0
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26609
26610
static int
26611
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26612
      int nodeType, const xmlChar *value, int len,
26613
      int mode, int *consumed)
26614
0
{
26615
    /*
26616
    * Unfortunately we have to duplicate the text sometimes.
26617
    * OPTIMIZE: Maybe we could skip it, if:
26618
    *   1. content type is simple
26619
    *   2. whitespace is "collapse"
26620
    *   3. it consists of whitespace only
26621
    *
26622
    * Process character content.
26623
    */
26624
0
    if (consumed != NULL)
26625
0
  *consumed = 0;
26626
0
    if (INODE_NILLED(vctxt->inode)) {
26627
  /*
26628
  * SPEC cvc-elt (3.3.4 - 3.2.1)
26629
  * "The element information item must have no character or
26630
  * element information item [children]."
26631
  */
26632
0
  VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26633
0
      "Neither character nor element content is allowed "
26634
0
      "because the element is 'nilled'");
26635
0
  return (vctxt->err);
26636
0
    }
26637
    /*
26638
    * SPEC (2.1) "If the {content type} is empty, then the
26639
    * element information item has no character or element
26640
    * information item [children]."
26641
    */
26642
0
    if (vctxt->inode->typeDef->contentType ==
26643
0
      XML_SCHEMA_CONTENT_EMPTY) {
26644
0
  VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26645
0
      "Character content is not allowed, "
26646
0
      "because the content type is empty");
26647
0
  return (vctxt->err);
26648
0
    }
26649
26650
0
    if (vctxt->inode->typeDef->contentType ==
26651
0
      XML_SCHEMA_CONTENT_ELEMENTS) {
26652
0
  if ((nodeType != XML_TEXT_NODE) ||
26653
0
      (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26654
      /*
26655
      * SPEC cvc-complex-type (2.3)
26656
      * "If the {content type} is element-only, then the
26657
      * element information item has no character information
26658
      * item [children] other than those whose [character
26659
      * code] is defined as a white space in [XML 1.0 (Second
26660
      * Edition)]."
26661
      */
26662
0
      VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26663
0
    "Character content other than whitespace is not allowed "
26664
0
    "because the content type is 'element-only'");
26665
0
      return (vctxt->err);
26666
0
  }
26667
0
  return (0);
26668
0
    }
26669
26670
0
    if ((value == NULL) || (value[0] == 0))
26671
0
  return (0);
26672
    /*
26673
    * Save the value.
26674
    * NOTE that even if the content type is *mixed*, we need the
26675
    * *initial value* for default/fixed value constraints.
26676
    */
26677
0
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26678
0
  ((vctxt->inode->decl == NULL) ||
26679
0
  (vctxt->inode->decl->value == NULL)))
26680
0
  return (0);
26681
26682
0
    if (vctxt->inode->value == NULL) {
26683
  /*
26684
  * Set the value.
26685
  */
26686
0
  switch (mode) {
26687
0
      case XML_SCHEMA_PUSH_TEXT_PERSIST:
26688
    /*
26689
    * When working on a tree.
26690
    */
26691
0
    vctxt->inode->value = value;
26692
0
    break;
26693
0
      case XML_SCHEMA_PUSH_TEXT_CREATED:
26694
    /*
26695
    * When working with the reader.
26696
    * The value will be freed by the element info.
26697
    */
26698
0
    vctxt->inode->value = value;
26699
0
    if (consumed != NULL)
26700
0
        *consumed = 1;
26701
0
    vctxt->inode->flags |=
26702
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26703
0
    break;
26704
0
      case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26705
    /*
26706
    * When working with SAX.
26707
    * The value will be freed by the element info.
26708
    */
26709
0
    if (len != -1)
26710
0
        vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26711
0
    else
26712
0
        vctxt->inode->value = BAD_CAST xmlStrdup(value);
26713
0
    vctxt->inode->flags |=
26714
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26715
0
    break;
26716
0
      default:
26717
0
    break;
26718
0
  }
26719
0
    } else {
26720
0
  if (len < 0)
26721
0
      len = xmlStrlen(value);
26722
  /*
26723
  * Concat the value.
26724
  */
26725
0
  if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26726
0
      vctxt->inode->value = BAD_CAST xmlStrncat(
26727
0
    (xmlChar *) vctxt->inode->value, value, len);
26728
0
  } else {
26729
0
      vctxt->inode->value =
26730
0
    BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26731
0
      vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26732
0
  }
26733
0
    }
26734
26735
0
    return (0);
26736
0
}
26737
26738
static int
26739
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26740
0
{
26741
0
    int ret = 0;
26742
26743
0
    if ((vctxt->skipDepth != -1) &&
26744
0
  (vctxt->depth >= vctxt->skipDepth)) {
26745
0
  VERROR_INT("xmlSchemaValidateElem",
26746
0
      "in skip-state");
26747
0
  goto internal_error;
26748
0
    }
26749
0
    if (vctxt->xsiAssemble) {
26750
  /*
26751
  * We will stop validation if there was an error during
26752
  * dynamic schema construction.
26753
  * Note that we simply set @skipDepth to 0, this could
26754
  * mean that a streaming document via SAX would be
26755
  * still read to the end but it won't be validated any more.
26756
  * TODO: If we are sure how to stop the validation at once
26757
  *   for all input scenarios, then this should be changed to
26758
  *   instantly stop the validation.
26759
  */
26760
0
  ret = xmlSchemaAssembleByXSI(vctxt);
26761
0
  if (ret != 0) {
26762
0
      if (ret == -1)
26763
0
    goto internal_error;
26764
0
      vctxt->skipDepth = 0;
26765
0
      return(ret);
26766
0
  }
26767
        /*
26768
         * Augment the IDC definitions for the main schema and all imported ones
26769
         * NOTE: main schema is the first in the imported list
26770
         */
26771
0
        xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
26772
0
                    vctxt);
26773
0
    }
26774
0
    if (vctxt->depth > 0) {
26775
  /*
26776
  * Validate this element against the content model
26777
  * of the parent.
26778
  */
26779
0
  ret = xmlSchemaValidateChildElem(vctxt);
26780
0
  if (ret != 0) {
26781
0
      if (ret < 0) {
26782
0
    VERROR_INT("xmlSchemaValidateElem",
26783
0
        "calling xmlSchemaStreamValidateChildElement()");
26784
0
    goto internal_error;
26785
0
      }
26786
0
      goto exit;
26787
0
  }
26788
0
  if (vctxt->depth == vctxt->skipDepth)
26789
0
      goto exit;
26790
0
  if ((vctxt->inode->decl == NULL) &&
26791
0
      (vctxt->inode->typeDef == NULL)) {
26792
0
      VERROR_INT("xmlSchemaValidateElem",
26793
0
    "the child element was valid but neither the "
26794
0
    "declaration nor the type was set");
26795
0
      goto internal_error;
26796
0
  }
26797
0
    } else {
26798
  /*
26799
  * Get the declaration of the validation root.
26800
  */
26801
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26802
0
      vctxt->inode->localName,
26803
0
      vctxt->inode->nsName);
26804
0
  if (vctxt->inode->decl == NULL) {
26805
0
      ret = XML_SCHEMAV_CVC_ELT_1;
26806
0
      VERROR(ret, NULL,
26807
0
    "No matching global declaration available "
26808
0
    "for the validation root");
26809
0
      goto exit;
26810
0
  }
26811
0
    }
26812
26813
0
    if (vctxt->inode->decl == NULL)
26814
0
  goto type_validation;
26815
26816
0
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26817
0
  int skip;
26818
  /*
26819
  * Wildcards.
26820
  */
26821
0
  ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26822
0
  if (ret != 0) {
26823
0
      if (ret < 0) {
26824
0
    VERROR_INT("xmlSchemaValidateElem",
26825
0
        "calling xmlSchemaValidateElemWildcard()");
26826
0
    goto internal_error;
26827
0
      }
26828
0
      goto exit;
26829
0
  }
26830
0
  if (skip) {
26831
0
      vctxt->skipDepth = vctxt->depth;
26832
0
      goto exit;
26833
0
  }
26834
  /*
26835
  * The declaration might be set by the wildcard validation,
26836
  * when the processContents is "lax" or "strict".
26837
  */
26838
0
  if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26839
      /*
26840
      * Clear the "decl" field to not confuse further processing.
26841
      */
26842
0
      vctxt->inode->decl = NULL;
26843
0
      goto type_validation;
26844
0
  }
26845
0
    }
26846
    /*
26847
    * Validate against the declaration.
26848
    */
26849
0
    ret = xmlSchemaValidateElemDecl(vctxt);
26850
0
    if (ret != 0) {
26851
0
  if (ret < 0) {
26852
0
      VERROR_INT("xmlSchemaValidateElem",
26853
0
    "calling xmlSchemaValidateElemDecl()");
26854
0
      goto internal_error;
26855
0
  }
26856
0
  goto exit;
26857
0
    }
26858
    /*
26859
    * Validate against the type definition.
26860
    */
26861
0
type_validation:
26862
26863
0
    if (vctxt->inode->typeDef == NULL) {
26864
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26865
0
  ret = XML_SCHEMAV_CVC_TYPE_1;
26866
0
  VERROR(ret, NULL,
26867
0
      "The type definition is absent");
26868
0
  goto exit;
26869
0
    }
26870
0
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26871
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26872
0
  ret = XML_SCHEMAV_CVC_TYPE_2;
26873
0
      VERROR(ret, NULL,
26874
0
      "The type definition is abstract");
26875
0
  goto exit;
26876
0
    }
26877
    /*
26878
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
26879
    * during validation against the declaration. This must be done
26880
    * _before_ attribute validation.
26881
    */
26882
0
    if (vctxt->xpathStates != NULL) {
26883
0
  ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26884
0
  vctxt->inode->appliedXPath = 1;
26885
0
  if (ret == -1) {
26886
0
      VERROR_INT("xmlSchemaValidateElem",
26887
0
    "calling xmlSchemaXPathEvaluate()");
26888
0
      goto internal_error;
26889
0
  }
26890
0
    }
26891
    /*
26892
    * Validate attributes.
26893
    */
26894
0
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26895
0
  if ((vctxt->nbAttrInfos != 0) ||
26896
0
      (vctxt->inode->typeDef->attrUses != NULL)) {
26897
26898
0
      ret = xmlSchemaVAttributesComplex(vctxt);
26899
0
  }
26900
0
    } else if (vctxt->nbAttrInfos != 0) {
26901
26902
0
  ret = xmlSchemaVAttributesSimple(vctxt);
26903
0
    }
26904
    /*
26905
    * Clear registered attributes.
26906
    */
26907
0
    if (vctxt->nbAttrInfos != 0)
26908
0
  xmlSchemaClearAttrInfos(vctxt);
26909
0
    if (ret == -1) {
26910
0
  VERROR_INT("xmlSchemaValidateElem",
26911
0
      "calling attributes validation");
26912
0
  goto internal_error;
26913
0
    }
26914
    /*
26915
    * Don't return an error if attributes are invalid on purpose.
26916
    */
26917
0
    ret = 0;
26918
26919
0
exit:
26920
0
    if (ret != 0)
26921
0
  vctxt->skipDepth = vctxt->depth;
26922
0
    return (ret);
26923
0
internal_error:
26924
0
    return (-1);
26925
0
}
26926
26927
#ifdef XML_SCHEMA_READER_ENABLED
26928
static int
26929
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26930
{
26931
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26932
    int depth, nodeType, ret = 0, consumed;
26933
    xmlSchemaNodeInfoPtr ielem;
26934
26935
    vctxt->depth = -1;
26936
    ret = xmlTextReaderRead(vctxt->reader);
26937
    /*
26938
    * Move to the document element.
26939
    */
26940
    while (ret == 1) {
26941
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26942
  if (nodeType == XML_ELEMENT_NODE)
26943
      goto root_found;
26944
  ret = xmlTextReaderRead(vctxt->reader);
26945
    }
26946
    goto exit;
26947
26948
root_found:
26949
26950
    do {
26951
  depth = xmlTextReaderDepth(vctxt->reader);
26952
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26953
26954
  if (nodeType == XML_ELEMENT_NODE) {
26955
26956
      vctxt->depth++;
26957
      if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26958
    VERROR_INT("xmlSchemaVReaderWalk",
26959
        "calling xmlSchemaValidatorPushElem()");
26960
    goto internal_error;
26961
      }
26962
      ielem = vctxt->inode;
26963
      ielem->localName = xmlTextReaderLocalName(vctxt->reader);
26964
      ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
26965
      ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
26966
      /*
26967
      * Is the element empty?
26968
      */
26969
      ret = xmlTextReaderIsEmptyElement(vctxt->reader);
26970
      if (ret == -1) {
26971
    VERROR_INT("xmlSchemaVReaderWalk",
26972
        "calling xmlTextReaderIsEmptyElement()");
26973
    goto internal_error;
26974
      }
26975
      if (ret) {
26976
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
26977
      }
26978
      /*
26979
      * Register attributes.
26980
      */
26981
      vctxt->nbAttrInfos = 0;
26982
      ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
26983
      if (ret == -1) {
26984
    VERROR_INT("xmlSchemaVReaderWalk",
26985
        "calling xmlTextReaderMoveToFirstAttribute()");
26986
    goto internal_error;
26987
      }
26988
      if (ret == 1) {
26989
    do {
26990
        /*
26991
        * VAL TODO: How do we know that the reader works on a
26992
        * node tree, to be able to pass a node here?
26993
        */
26994
        if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
26995
      (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
26996
      xmlTextReaderNamespaceUri(vctxt->reader), 1,
26997
      xmlTextReaderValue(vctxt->reader), 1) == -1) {
26998
26999
      VERROR_INT("xmlSchemaVReaderWalk",
27000
          "calling xmlSchemaValidatorPushAttribute()");
27001
      goto internal_error;
27002
        }
27003
        ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27004
        if (ret == -1) {
27005
      VERROR_INT("xmlSchemaVReaderWalk",
27006
          "calling xmlTextReaderMoveToFirstAttribute()");
27007
      goto internal_error;
27008
        }
27009
    } while (ret == 1);
27010
    /*
27011
    * Back to element position.
27012
    */
27013
    ret = xmlTextReaderMoveToElement(vctxt->reader);
27014
    if (ret == -1) {
27015
        VERROR_INT("xmlSchemaVReaderWalk",
27016
      "calling xmlTextReaderMoveToElement()");
27017
        goto internal_error;
27018
    }
27019
      }
27020
      /*
27021
      * Validate the element.
27022
      */
27023
      ret= xmlSchemaValidateElem(vctxt);
27024
      if (ret != 0) {
27025
    if (ret == -1) {
27026
        VERROR_INT("xmlSchemaVReaderWalk",
27027
      "calling xmlSchemaValidateElem()");
27028
        goto internal_error;
27029
    }
27030
    goto exit;
27031
      }
27032
      if (vctxt->depth == vctxt->skipDepth) {
27033
    int curDepth;
27034
    /*
27035
    * Skip all content.
27036
    */
27037
    if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27038
        ret = xmlTextReaderRead(vctxt->reader);
27039
        curDepth = xmlTextReaderDepth(vctxt->reader);
27040
        while ((ret == 1) && (curDepth != depth)) {
27041
      ret = xmlTextReaderRead(vctxt->reader);
27042
      curDepth = xmlTextReaderDepth(vctxt->reader);
27043
        }
27044
        if (ret < 0) {
27045
      /*
27046
      * VAL TODO: A reader error occurred; what to do here?
27047
      */
27048
      ret = 1;
27049
      goto exit;
27050
        }
27051
    }
27052
    goto leave_elem;
27053
      }
27054
      /*
27055
      * READER VAL TODO: Is an END_ELEM really never called
27056
      * if the elem is empty?
27057
      */
27058
      if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27059
    goto leave_elem;
27060
  } else if (nodeType == END_ELEM) {
27061
      /*
27062
      * Process END of element.
27063
      */
27064
leave_elem:
27065
      ret = xmlSchemaValidatorPopElem(vctxt);
27066
      if (ret != 0) {
27067
    if (ret < 0) {
27068
        VERROR_INT("xmlSchemaVReaderWalk",
27069
      "calling xmlSchemaValidatorPopElem()");
27070
        goto internal_error;
27071
    }
27072
    goto exit;
27073
      }
27074
      if (vctxt->depth >= 0)
27075
    ielem = vctxt->inode;
27076
      else
27077
    ielem = NULL;
27078
  } else if ((nodeType == XML_TEXT_NODE) ||
27079
      (nodeType == XML_CDATA_SECTION_NODE) ||
27080
      (nodeType == WHTSP) ||
27081
      (nodeType == SIGN_WHTSP)) {
27082
      /*
27083
      * Process character content.
27084
      */
27085
      xmlChar *value;
27086
27087
      if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27088
    nodeType = XML_TEXT_NODE;
27089
27090
      value = xmlTextReaderValue(vctxt->reader);
27091
      ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27092
    -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27093
      if (! consumed)
27094
    xmlFree(value);
27095
      if (ret == -1) {
27096
    VERROR_INT("xmlSchemaVReaderWalk",
27097
        "calling xmlSchemaVPushText()");
27098
    goto internal_error;
27099
      }
27100
  } else if ((nodeType == XML_ENTITY_NODE) ||
27101
      (nodeType == XML_ENTITY_REF_NODE)) {
27102
      /*
27103
      * VAL TODO: What to do with entities?
27104
      */
27105
      TODO
27106
  }
27107
  /*
27108
  * Read next node.
27109
  */
27110
  ret = xmlTextReaderRead(vctxt->reader);
27111
    } while (ret == 1);
27112
27113
exit:
27114
    return (ret);
27115
internal_error:
27116
    return (-1);
27117
}
27118
#endif
27119
27120
/************************************************************************
27121
 *                  *
27122
 *      SAX validation handlers       *
27123
 *                  *
27124
 ************************************************************************/
27125
27126
/*
27127
* Process text content.
27128
*/
27129
static void
27130
xmlSchemaSAXHandleText(void *ctx,
27131
           const xmlChar * ch,
27132
           int len)
27133
0
{
27134
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27135
27136
0
    if (vctxt->depth < 0)
27137
0
  return;
27138
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27139
0
  return;
27140
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27141
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27142
0
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27143
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27144
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27145
0
      "calling xmlSchemaVPushText()");
27146
0
  vctxt->err = -1;
27147
0
  xmlStopParser(vctxt->parserCtxt);
27148
0
    }
27149
0
}
27150
27151
/*
27152
* Process CDATA content.
27153
*/
27154
static void
27155
xmlSchemaSAXHandleCDataSection(void *ctx,
27156
           const xmlChar * ch,
27157
           int len)
27158
0
{
27159
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27160
27161
0
    if (vctxt->depth < 0)
27162
0
  return;
27163
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27164
0
  return;
27165
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27166
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27167
0
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27168
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27169
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27170
0
      "calling xmlSchemaVPushText()");
27171
0
  vctxt->err = -1;
27172
0
  xmlStopParser(vctxt->parserCtxt);
27173
0
    }
27174
0
}
27175
27176
static void
27177
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27178
          const xmlChar * name ATTRIBUTE_UNUSED)
27179
0
{
27180
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27181
27182
0
    if (vctxt->depth < 0)
27183
0
  return;
27184
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27185
0
  return;
27186
    /* SAX VAL TODO: What to do here? */
27187
0
}
27188
27189
static void
27190
xmlSchemaSAXHandleStartElementNs(void *ctx,
27191
         const xmlChar * localname,
27192
         const xmlChar * prefix ATTRIBUTE_UNUSED,
27193
         const xmlChar * URI,
27194
         int nb_namespaces,
27195
         const xmlChar ** namespaces,
27196
         int nb_attributes,
27197
         int nb_defaulted ATTRIBUTE_UNUSED,
27198
         const xmlChar ** attributes)
27199
0
{
27200
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27201
0
    int ret;
27202
0
    xmlSchemaNodeInfoPtr ielem;
27203
0
    int i, j;
27204
27205
    /*
27206
    * SAX VAL TODO: What to do with nb_defaulted?
27207
    */
27208
    /*
27209
    * Skip elements if inside a "skip" wildcard or invalid.
27210
    */
27211
0
    vctxt->depth++;
27212
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27213
0
  return;
27214
    /*
27215
    * Push the element.
27216
    */
27217
0
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27218
0
  VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27219
0
      "calling xmlSchemaValidatorPushElem()");
27220
0
  goto internal_error;
27221
0
    }
27222
0
    ielem = vctxt->inode;
27223
    /*
27224
    * TODO: Is this OK?
27225
    */
27226
0
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27227
0
    ielem->localName = localname;
27228
0
    ielem->nsName = URI;
27229
0
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27230
    /*
27231
    * Register namespaces on the elem info.
27232
    */
27233
0
    if (nb_namespaces != 0) {
27234
  /*
27235
  * Although the parser builds its own namespace list,
27236
  * we have no access to it, so we'll use an own one.
27237
  */
27238
0
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27239
      /*
27240
      * Store prefix and namespace name.
27241
      */
27242
0
      if (ielem->nsBindings == NULL) {
27243
0
    ielem->nsBindings =
27244
0
        (const xmlChar **) xmlMalloc(10 *
27245
0
      sizeof(const xmlChar *));
27246
0
    if (ielem->nsBindings == NULL) {
27247
0
        xmlSchemaVErrMemory(vctxt);
27248
0
        goto internal_error;
27249
0
    }
27250
0
    ielem->nbNsBindings = 0;
27251
0
    ielem->sizeNsBindings = 5;
27252
0
      } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27253
0
    ielem->sizeNsBindings *= 2;
27254
0
    ielem->nsBindings =
27255
0
        (const xmlChar **) xmlRealloc(
27256
0
      (void *) ielem->nsBindings,
27257
0
      ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27258
0
    if (ielem->nsBindings == NULL) {
27259
0
        xmlSchemaVErrMemory(vctxt);
27260
0
        goto internal_error;
27261
0
    }
27262
0
      }
27263
27264
0
      ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27265
0
      if (namespaces[j+1][0] == 0) {
27266
    /*
27267
    * Handle xmlns="".
27268
    */
27269
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27270
0
      } else
27271
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27272
0
        namespaces[j+1];
27273
0
      ielem->nbNsBindings++;
27274
0
  }
27275
0
    }
27276
    /*
27277
    * Register attributes.
27278
    * SAX VAL TODO: We are not adding namespace declaration
27279
    * attributes yet.
27280
    */
27281
0
    if (nb_attributes != 0) {
27282
0
  int valueLen, k, l;
27283
0
  xmlChar *value;
27284
27285
0
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27286
      /*
27287
      * Duplicate the value, changing any &#38; to a literal ampersand.
27288
      *
27289
      * libxml2 differs from normal SAX here in that it escapes all ampersands
27290
      * as &#38; instead of delivering the raw converted string. Changing the
27291
      * behavior at this point would break applications that use this API, so
27292
      * we are forced to work around it.
27293
      */
27294
0
      valueLen = attributes[j+4] - attributes[j+3];
27295
0
      value = xmlMalloc(valueLen + 1);
27296
0
      if (value == NULL) {
27297
0
    xmlSchemaVErrMemory(vctxt);
27298
0
    goto internal_error;
27299
0
      }
27300
0
      for (k = 0, l = 0; k < valueLen; l++) {
27301
0
    if (k < valueLen - 4 &&
27302
0
        attributes[j+3][k+0] == '&' &&
27303
0
        attributes[j+3][k+1] == '#' &&
27304
0
        attributes[j+3][k+2] == '3' &&
27305
0
        attributes[j+3][k+3] == '8' &&
27306
0
        attributes[j+3][k+4] == ';') {
27307
0
        value[l] = '&';
27308
0
        k += 5;
27309
0
    } else {
27310
0
        value[l] = attributes[j+3][k];
27311
0
        k++;
27312
0
    }
27313
0
      }
27314
0
      value[l] = '\0';
27315
      /*
27316
      * TODO: Set the node line.
27317
      */
27318
0
      ret = xmlSchemaValidatorPushAttribute(vctxt,
27319
0
    NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27320
0
    value, 1);
27321
0
      if (ret == -1) {
27322
0
    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27323
0
        "calling xmlSchemaValidatorPushAttribute()");
27324
0
    goto internal_error;
27325
0
      }
27326
0
  }
27327
0
    }
27328
    /*
27329
    * Validate the element.
27330
    */
27331
0
    ret = xmlSchemaValidateElem(vctxt);
27332
0
    if (ret != 0) {
27333
0
  if (ret == -1) {
27334
0
      VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27335
0
    "calling xmlSchemaValidateElem()");
27336
0
      goto internal_error;
27337
0
  }
27338
0
  goto exit;
27339
0
    }
27340
27341
0
exit:
27342
0
    return;
27343
0
internal_error:
27344
0
    vctxt->err = -1;
27345
0
    xmlStopParser(vctxt->parserCtxt);
27346
0
}
27347
27348
static void
27349
xmlSchemaSAXHandleEndElementNs(void *ctx,
27350
             const xmlChar * localname ATTRIBUTE_UNUSED,
27351
             const xmlChar * prefix ATTRIBUTE_UNUSED,
27352
             const xmlChar * URI ATTRIBUTE_UNUSED)
27353
0
{
27354
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27355
0
    int res;
27356
27357
    /*
27358
    * Skip elements if inside a "skip" wildcard or if invalid.
27359
    */
27360
0
    if (vctxt->skipDepth != -1) {
27361
0
  if (vctxt->depth > vctxt->skipDepth) {
27362
0
      vctxt->depth--;
27363
0
      return;
27364
0
  } else
27365
0
      vctxt->skipDepth = -1;
27366
0
    }
27367
    /*
27368
    * SAX VAL TODO: Just a temporary check.
27369
    */
27370
0
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27371
0
  (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27372
0
  VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27373
0
      "elem pop mismatch");
27374
0
    }
27375
0
    res = xmlSchemaValidatorPopElem(vctxt);
27376
0
    if (res != 0) {
27377
0
  if (res < 0) {
27378
0
      VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27379
0
    "calling xmlSchemaValidatorPopElem()");
27380
0
      goto internal_error;
27381
0
  }
27382
0
  goto exit;
27383
0
    }
27384
0
exit:
27385
0
    return;
27386
0
internal_error:
27387
0
    vctxt->err = -1;
27388
0
    xmlStopParser(vctxt->parserCtxt);
27389
0
}
27390
27391
/************************************************************************
27392
 *                  *
27393
 *      Validation interfaces       *
27394
 *                  *
27395
 ************************************************************************/
27396
27397
/**
27398
 * xmlSchemaNewValidCtxt:
27399
 * @schema:  a precompiled XML Schemas
27400
 *
27401
 * Create an XML Schemas validation context based on the given schema.
27402
 *
27403
 * Returns the validation context or NULL in case of error
27404
 */
27405
xmlSchemaValidCtxtPtr
27406
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27407
0
{
27408
0
    xmlSchemaValidCtxtPtr ret;
27409
27410
0
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27411
0
    if (ret == NULL) {
27412
0
        xmlSchemaVErrMemory(NULL);
27413
0
        return (NULL);
27414
0
    }
27415
0
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27416
0
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27417
0
    ret->dict = xmlDictCreate();
27418
0
    ret->nodeQNames = xmlSchemaItemListCreate();
27419
0
    ret->schema = schema;
27420
0
    return (ret);
27421
0
}
27422
27423
/**
27424
 * xmlSchemaValidateSetFilename:
27425
 * @vctxt: the schema validation context
27426
 * @filename: the file name
27427
 *
27428
 * Workaround to provide file error reporting information when this is
27429
 * not provided by current APIs
27430
 */
27431
void
27432
0
xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27433
0
    if (vctxt == NULL)
27434
0
        return;
27435
0
    if (vctxt->filename != NULL)
27436
0
        xmlFree(vctxt->filename);
27437
0
    if (filename != NULL)
27438
0
        vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27439
0
    else
27440
0
        vctxt->filename = NULL;
27441
0
}
27442
27443
/**
27444
 * xmlSchemaClearValidCtxt:
27445
 * @vctxt: the schema validation context
27446
 *
27447
 * Free the resources associated to the schema validation context;
27448
 * leaves some fields alive intended for reuse of the context.
27449
 */
27450
static void
27451
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27452
0
{
27453
0
    if (vctxt == NULL)
27454
0
        return;
27455
27456
    /*
27457
    * TODO: Should we clear the flags?
27458
    *   Might be problematic if one reuses the context
27459
    *   and assumes that the options remain the same.
27460
    */
27461
0
    vctxt->flags = 0;
27462
0
    vctxt->validationRoot = NULL;
27463
0
    vctxt->doc = NULL;
27464
0
#ifdef LIBXML_READER_ENABLED
27465
0
    vctxt->reader = NULL;
27466
0
#endif
27467
0
    vctxt->hasKeyrefs = 0;
27468
27469
0
    if (vctxt->value != NULL) {
27470
0
        xmlSchemaFreeValue(vctxt->value);
27471
0
  vctxt->value = NULL;
27472
0
    }
27473
    /*
27474
    * Augmented IDC information.
27475
    */
27476
0
    if (vctxt->aidcs != NULL) {
27477
0
  xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27478
0
  do {
27479
0
      next = cur->next;
27480
0
      xmlFree(cur);
27481
0
      cur = next;
27482
0
  } while (cur != NULL);
27483
0
  vctxt->aidcs = NULL;
27484
0
    }
27485
27486
0
    if (vctxt->idcNodes != NULL) {
27487
0
  int i;
27488
0
  xmlSchemaPSVIIDCNodePtr item;
27489
27490
0
  for (i = 0; i < vctxt->nbIdcNodes; i++) {
27491
0
      item = vctxt->idcNodes[i];
27492
0
      xmlFree(item->keys);
27493
0
      xmlFree(item);
27494
0
  }
27495
0
  xmlFree(vctxt->idcNodes);
27496
0
  vctxt->idcNodes = NULL;
27497
0
  vctxt->nbIdcNodes = 0;
27498
0
  vctxt->sizeIdcNodes = 0;
27499
0
    }
27500
27501
0
    if (vctxt->idcKeys != NULL) {
27502
0
  int i;
27503
0
  for (i = 0; i < vctxt->nbIdcKeys; i++)
27504
0
      xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27505
0
  xmlFree(vctxt->idcKeys);
27506
0
  vctxt->idcKeys = NULL;
27507
0
  vctxt->nbIdcKeys = 0;
27508
0
  vctxt->sizeIdcKeys = 0;
27509
0
    }
27510
27511
    /*
27512
    * Note that we won't delete the XPath state pool here.
27513
    */
27514
0
    if (vctxt->xpathStates != NULL) {
27515
0
  xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27516
0
  vctxt->xpathStates = NULL;
27517
0
    }
27518
    /*
27519
    * Attribute info.
27520
    */
27521
0
    if (vctxt->nbAttrInfos != 0) {
27522
0
  xmlSchemaClearAttrInfos(vctxt);
27523
0
    }
27524
    /*
27525
    * Element info.
27526
    */
27527
0
    if (vctxt->elemInfos != NULL) {
27528
0
  int i;
27529
0
  xmlSchemaNodeInfoPtr ei;
27530
27531
0
  for (i = 0; i < vctxt->sizeElemInfos; i++) {
27532
0
      ei = vctxt->elemInfos[i];
27533
0
      if (ei == NULL)
27534
0
    break;
27535
0
      xmlSchemaClearElemInfo(vctxt, ei);
27536
0
  }
27537
0
    }
27538
0
    xmlSchemaItemListClear(vctxt->nodeQNames);
27539
    /* Recreate the dict. */
27540
0
    xmlDictFree(vctxt->dict);
27541
    /*
27542
    * TODO: Is is save to recreate it? Do we have a scenario
27543
    * where the user provides the dict?
27544
    */
27545
0
    vctxt->dict = xmlDictCreate();
27546
27547
0
    if (vctxt->filename != NULL) {
27548
0
        xmlFree(vctxt->filename);
27549
0
  vctxt->filename = NULL;
27550
0
    }
27551
27552
    /*
27553
     * Note that some cleanup functions can move items to the cache,
27554
     * so the cache shouldn't be freed too early.
27555
     */
27556
0
    if (vctxt->idcMatcherCache != NULL) {
27557
0
  xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27558
27559
0
  while (matcher) {
27560
0
      tmp = matcher;
27561
0
      matcher = matcher->nextCached;
27562
0
      xmlSchemaIDCFreeMatcherList(tmp);
27563
0
  }
27564
0
  vctxt->idcMatcherCache = NULL;
27565
0
    }
27566
0
}
27567
27568
/**
27569
 * xmlSchemaFreeValidCtxt:
27570
 * @ctxt:  the schema validation context
27571
 *
27572
 * Free the resources associated to the schema validation context
27573
 */
27574
void
27575
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27576
0
{
27577
0
    if (ctxt == NULL)
27578
0
        return;
27579
0
    if (ctxt->value != NULL)
27580
0
        xmlSchemaFreeValue(ctxt->value);
27581
0
    if (ctxt->pctxt != NULL)
27582
0
  xmlSchemaFreeParserCtxt(ctxt->pctxt);
27583
0
    if (ctxt->idcNodes != NULL) {
27584
0
  int i;
27585
0
  xmlSchemaPSVIIDCNodePtr item;
27586
27587
0
  for (i = 0; i < ctxt->nbIdcNodes; i++) {
27588
0
      item = ctxt->idcNodes[i];
27589
0
      xmlFree(item->keys);
27590
0
      xmlFree(item);
27591
0
  }
27592
0
  xmlFree(ctxt->idcNodes);
27593
0
    }
27594
0
    if (ctxt->idcKeys != NULL) {
27595
0
  int i;
27596
0
  for (i = 0; i < ctxt->nbIdcKeys; i++)
27597
0
      xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27598
0
  xmlFree(ctxt->idcKeys);
27599
0
    }
27600
27601
0
    if (ctxt->xpathStates != NULL) {
27602
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27603
0
  ctxt->xpathStates = NULL;
27604
0
    }
27605
0
    if (ctxt->xpathStatePool != NULL) {
27606
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27607
0
  ctxt->xpathStatePool = NULL;
27608
0
    }
27609
27610
    /*
27611
    * Augmented IDC information.
27612
    */
27613
0
    if (ctxt->aidcs != NULL) {
27614
0
  xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27615
0
  do {
27616
0
      next = cur->next;
27617
0
      xmlFree(cur);
27618
0
      cur = next;
27619
0
  } while (cur != NULL);
27620
0
    }
27621
0
    if (ctxt->attrInfos != NULL) {
27622
0
  int i;
27623
0
  xmlSchemaAttrInfoPtr attr;
27624
27625
  /* Just a paranoid call to the cleanup. */
27626
0
  if (ctxt->nbAttrInfos != 0)
27627
0
      xmlSchemaClearAttrInfos(ctxt);
27628
0
  for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27629
0
      attr = ctxt->attrInfos[i];
27630
0
      xmlFree(attr);
27631
0
  }
27632
0
  xmlFree(ctxt->attrInfos);
27633
0
    }
27634
0
    if (ctxt->elemInfos != NULL) {
27635
0
  int i;
27636
0
  xmlSchemaNodeInfoPtr ei;
27637
27638
0
  for (i = 0; i < ctxt->sizeElemInfos; i++) {
27639
0
      ei = ctxt->elemInfos[i];
27640
0
      if (ei == NULL)
27641
0
    break;
27642
0
      xmlSchemaClearElemInfo(ctxt, ei);
27643
0
      xmlFree(ei);
27644
0
  }
27645
0
  xmlFree(ctxt->elemInfos);
27646
0
    }
27647
0
    if (ctxt->nodeQNames != NULL)
27648
0
  xmlSchemaItemListFree(ctxt->nodeQNames);
27649
0
    if (ctxt->dict != NULL)
27650
0
  xmlDictFree(ctxt->dict);
27651
0
    if (ctxt->filename != NULL)
27652
0
  xmlFree(ctxt->filename);
27653
0
    xmlFree(ctxt);
27654
0
}
27655
27656
/**
27657
 * xmlSchemaIsValid:
27658
 * @ctxt: the schema validation context
27659
 *
27660
 * Check if any error was detected during validation.
27661
 *
27662
 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27663
 *         of internal error.
27664
 */
27665
int
27666
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27667
0
{
27668
0
    if (ctxt == NULL)
27669
0
        return(-1);
27670
0
    return(ctxt->err == 0);
27671
0
}
27672
27673
/**
27674
 * xmlSchemaSetValidErrors:
27675
 * @ctxt:  a schema validation context
27676
 * @err:  the error function
27677
 * @warn: the warning function
27678
 * @ctx: the functions context
27679
 *
27680
 * DEPRECATED: Use xmlSchemaSetValidStructuredErrors.
27681
 *
27682
 * Set the error and warning callback information
27683
 */
27684
void
27685
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27686
                        xmlSchemaValidityErrorFunc err,
27687
                        xmlSchemaValidityWarningFunc warn, void *ctx)
27688
0
{
27689
0
    if (ctxt == NULL)
27690
0
        return;
27691
0
    ctxt->error = err;
27692
0
    ctxt->warning = warn;
27693
0
    ctxt->errCtxt = ctx;
27694
0
    if (ctxt->pctxt != NULL)
27695
0
  xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27696
0
}
27697
27698
/**
27699
 * xmlSchemaSetValidStructuredErrors:
27700
 * @ctxt:  a schema validation context
27701
 * @serror:  the structured error function
27702
 * @ctx: the functions context
27703
 *
27704
 * Set the structured error callback
27705
 */
27706
void
27707
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27708
          xmlStructuredErrorFunc serror, void *ctx)
27709
0
{
27710
0
    if (ctxt == NULL)
27711
0
        return;
27712
0
    ctxt->serror = serror;
27713
0
    ctxt->error = NULL;
27714
0
    ctxt->warning = NULL;
27715
0
    ctxt->errCtxt = ctx;
27716
0
    if (ctxt->pctxt != NULL)
27717
0
  xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27718
0
}
27719
27720
/**
27721
 * xmlSchemaGetValidErrors:
27722
 * @ctxt: a XML-Schema validation context
27723
 * @err: the error function result
27724
 * @warn: the warning function result
27725
 * @ctx: the functions context result
27726
 *
27727
 * Get the error and warning callback information
27728
 *
27729
 * Returns -1 in case of error and 0 otherwise
27730
 */
27731
int
27732
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27733
      xmlSchemaValidityErrorFunc * err,
27734
      xmlSchemaValidityWarningFunc * warn, void **ctx)
27735
0
{
27736
0
  if (ctxt == NULL)
27737
0
    return (-1);
27738
0
  if (err != NULL)
27739
0
    *err = ctxt->error;
27740
0
  if (warn != NULL)
27741
0
    *warn = ctxt->warning;
27742
0
  if (ctx != NULL)
27743
0
    *ctx = ctxt->errCtxt;
27744
0
  return (0);
27745
0
}
27746
27747
27748
/**
27749
 * xmlSchemaSetValidOptions:
27750
 * @ctxt: a schema validation context
27751
 * @options: a combination of xmlSchemaValidOption
27752
 *
27753
 * Sets the options to be used during the validation.
27754
 *
27755
 * Returns 0 in case of success, -1 in case of an
27756
 * API error.
27757
 */
27758
int
27759
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27760
       int options)
27761
27762
0
{
27763
0
    int i;
27764
27765
0
    if (ctxt == NULL)
27766
0
  return (-1);
27767
    /*
27768
    * WARNING: Change the start value if adding to the
27769
    * xmlSchemaValidOption.
27770
    * TODO: Is there an other, more easy to maintain,
27771
    * way?
27772
    */
27773
0
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
27774
0
        if (options & 1<<i)
27775
0
      return (-1);
27776
0
    }
27777
0
    ctxt->options = options;
27778
0
    return (0);
27779
0
}
27780
27781
/**
27782
 * xmlSchemaValidCtxtGetOptions:
27783
 * @ctxt: a schema validation context
27784
 *
27785
 * Get the validation context options.
27786
 *
27787
 * Returns the option combination or -1 on error.
27788
 */
27789
int
27790
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27791
27792
0
{
27793
0
    if (ctxt == NULL)
27794
0
  return (-1);
27795
0
    else
27796
0
  return (ctxt->options);
27797
0
}
27798
27799
static int
27800
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27801
0
{
27802
0
    xmlAttrPtr attr;
27803
0
    int ret = 0;
27804
0
    xmlSchemaNodeInfoPtr ielem = NULL;
27805
0
    xmlNodePtr node, valRoot;
27806
0
    const xmlChar *nsName;
27807
27808
    /* DOC VAL TODO: Move this to the start function. */
27809
0
    if (vctxt->validationRoot != NULL)
27810
0
        valRoot = vctxt->validationRoot;
27811
0
    else
27812
0
  valRoot = xmlDocGetRootElement(vctxt->doc);
27813
0
    if (valRoot == NULL) {
27814
  /* VAL TODO: Error code? */
27815
0
  VERROR(1, NULL, "The document has no document element");
27816
0
  return (1);
27817
0
    }
27818
0
    vctxt->depth = -1;
27819
0
    vctxt->validationRoot = valRoot;
27820
0
    node = valRoot;
27821
0
    while (node != NULL) {
27822
0
  if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27823
0
      goto next_sibling;
27824
0
  if (node->type == XML_ELEMENT_NODE) {
27825
27826
      /*
27827
      * Init the node-info.
27828
      */
27829
0
      vctxt->depth++;
27830
0
      if (xmlSchemaValidatorPushElem(vctxt) == -1)
27831
0
    goto internal_error;
27832
0
      ielem = vctxt->inode;
27833
0
      ielem->node = node;
27834
0
      ielem->nodeLine = node->line;
27835
0
      ielem->localName = node->name;
27836
0
      if (node->ns != NULL)
27837
0
    ielem->nsName = node->ns->href;
27838
0
      ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27839
      /*
27840
      * Register attributes.
27841
      * DOC VAL TODO: We do not register namespace declaration
27842
      * attributes yet.
27843
      */
27844
0
      vctxt->nbAttrInfos = 0;
27845
0
      if (node->properties != NULL) {
27846
0
    attr = node->properties;
27847
0
    do {
27848
0
        if (attr->ns != NULL)
27849
0
      nsName = attr->ns->href;
27850
0
        else
27851
0
      nsName = NULL;
27852
0
        ret = xmlSchemaValidatorPushAttribute(vctxt,
27853
0
      (xmlNodePtr) attr,
27854
      /*
27855
      * Note that we give it the line number of the
27856
      * parent element.
27857
      */
27858
0
      ielem->nodeLine,
27859
0
      attr->name, nsName, 0,
27860
0
      xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27861
0
        if (ret == -1) {
27862
0
      VERROR_INT("xmlSchemaDocWalk",
27863
0
          "calling xmlSchemaValidatorPushAttribute()");
27864
0
      goto internal_error;
27865
0
        }
27866
0
        attr = attr->next;
27867
0
    } while (attr);
27868
0
      }
27869
      /*
27870
      * Validate the element.
27871
      */
27872
0
      ret = xmlSchemaValidateElem(vctxt);
27873
0
      if (ret != 0) {
27874
0
    if (ret == -1) {
27875
0
        VERROR_INT("xmlSchemaDocWalk",
27876
0
      "calling xmlSchemaValidateElem()");
27877
0
        goto internal_error;
27878
0
    }
27879
    /*
27880
    * Don't stop validation; just skip the content
27881
    * of this element.
27882
    */
27883
0
    goto leave_node;
27884
0
      }
27885
0
      if ((vctxt->skipDepth != -1) &&
27886
0
    (vctxt->depth >= vctxt->skipDepth))
27887
0
    goto leave_node;
27888
0
  } else if ((node->type == XML_TEXT_NODE) ||
27889
0
      (node->type == XML_CDATA_SECTION_NODE)) {
27890
      /*
27891
      * Process character content.
27892
      */
27893
0
      if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27894
0
    ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27895
0
      ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27896
0
    -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27897
0
      if (ret < 0) {
27898
0
    VERROR_INT("xmlSchemaVDocWalk",
27899
0
        "calling xmlSchemaVPushText()");
27900
0
    goto internal_error;
27901
0
      }
27902
      /*
27903
      * DOC VAL TODO: Should we skip further validation of the
27904
      * element content here?
27905
      */
27906
0
  } else if ((node->type == XML_ENTITY_NODE) ||
27907
0
      (node->type == XML_ENTITY_REF_NODE)) {
27908
      /*
27909
      * DOC VAL TODO: What to do with entities?
27910
      */
27911
0
      VERROR_INT("xmlSchemaVDocWalk",
27912
0
    "there is at least one entity reference in the node-tree "
27913
0
    "currently being validated. Processing of entities with "
27914
0
    "this XML Schema processor is not supported (yet). Please "
27915
0
    "substitute entities before validation.");
27916
0
      goto internal_error;
27917
0
  } else {
27918
0
      goto leave_node;
27919
      /*
27920
      * DOC VAL TODO: XInclude nodes, etc.
27921
      */
27922
0
  }
27923
  /*
27924
  * Walk the doc.
27925
  */
27926
0
  if (node->children != NULL) {
27927
0
      node = node->children;
27928
0
      continue;
27929
0
  }
27930
0
leave_node:
27931
0
  if (node->type == XML_ELEMENT_NODE) {
27932
      /*
27933
      * Leaving the scope of an element.
27934
      */
27935
0
      if (node != vctxt->inode->node) {
27936
0
    VERROR_INT("xmlSchemaVDocWalk",
27937
0
        "element position mismatch");
27938
0
    goto internal_error;
27939
0
      }
27940
0
      ret = xmlSchemaValidatorPopElem(vctxt);
27941
0
      if (ret != 0) {
27942
0
    if (ret < 0) {
27943
0
        VERROR_INT("xmlSchemaVDocWalk",
27944
0
      "calling xmlSchemaValidatorPopElem()");
27945
0
        goto internal_error;
27946
0
    }
27947
0
      }
27948
0
      if (node == valRoot)
27949
0
    goto exit;
27950
0
  }
27951
0
next_sibling:
27952
0
  if (node->next != NULL)
27953
0
      node = node->next;
27954
0
  else {
27955
0
      node = node->parent;
27956
0
      goto leave_node;
27957
0
  }
27958
0
    }
27959
27960
0
exit:
27961
0
    return (ret);
27962
0
internal_error:
27963
0
    return (-1);
27964
0
}
27965
27966
static int
27967
0
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27968
    /*
27969
    * Some initialization.
27970
    */
27971
0
    vctxt->err = 0;
27972
0
    vctxt->nberrors = 0;
27973
0
    vctxt->depth = -1;
27974
0
    vctxt->skipDepth = -1;
27975
0
    vctxt->hasKeyrefs = 0;
27976
#ifdef ENABLE_IDC_NODE_TABLES_TEST
27977
    vctxt->createIDCNodeTables = 1;
27978
#else
27979
0
    vctxt->createIDCNodeTables = 0;
27980
0
#endif
27981
    /*
27982
    * Create a schema + parser if necessary.
27983
    */
27984
0
    if (vctxt->schema == NULL) {
27985
0
  xmlSchemaParserCtxtPtr pctxt;
27986
27987
0
  vctxt->xsiAssemble = 1;
27988
  /*
27989
  * If not schema was given then we will create a schema
27990
  * dynamically using XSI schema locations.
27991
  *
27992
  * Create the schema parser context.
27993
  */
27994
0
  if ((vctxt->pctxt == NULL) &&
27995
0
     (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27996
0
     return (-1);
27997
0
  pctxt = vctxt->pctxt;
27998
0
  pctxt->xsiAssemble = 1;
27999
  /*
28000
  * Create the schema.
28001
  */
28002
0
  vctxt->schema = xmlSchemaNewSchema(pctxt);
28003
0
  if (vctxt->schema == NULL)
28004
0
      return (-1);
28005
  /*
28006
  * Create the schema construction context.
28007
  */
28008
0
  pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
28009
0
  if (pctxt->constructor == NULL)
28010
0
      return(-1);
28011
0
  pctxt->constructor->mainSchema = vctxt->schema;
28012
  /*
28013
  * Take ownership of the constructor to be able to free it.
28014
  */
28015
0
  pctxt->ownsConstructor = 1;
28016
0
    }
28017
    /*
28018
    * Augment the IDC definitions for the main schema and all imported ones
28019
    * NOTE: main schema if the first in the imported list
28020
    */
28021
0
    xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
28022
0
                vctxt);
28023
28024
0
    return(0);
28025
0
}
28026
28027
static void
28028
0
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28029
0
    if (vctxt->xsiAssemble) {
28030
0
  if (vctxt->schema != NULL) {
28031
0
      xmlSchemaFree(vctxt->schema);
28032
0
      vctxt->schema = NULL;
28033
0
  }
28034
0
    }
28035
0
    xmlSchemaClearValidCtxt(vctxt);
28036
0
}
28037
28038
static int
28039
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28040
0
{
28041
0
    int ret = 0;
28042
28043
0
    if (xmlSchemaPreRun(vctxt) < 0)
28044
0
        return(-1);
28045
28046
0
    if (vctxt->doc != NULL) {
28047
  /*
28048
   * Tree validation.
28049
   */
28050
0
  ret = xmlSchemaVDocWalk(vctxt);
28051
0
#ifdef LIBXML_READER_ENABLED
28052
0
    } else if (vctxt->reader != NULL) {
28053
  /*
28054
   * XML Reader validation.
28055
   */
28056
#ifdef XML_SCHEMA_READER_ENABLED
28057
  ret = xmlSchemaVReaderWalk(vctxt);
28058
#endif
28059
0
#endif
28060
0
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28061
  /*
28062
   * SAX validation.
28063
   */
28064
0
  ret = xmlParseDocument(vctxt->parserCtxt);
28065
0
    } else {
28066
0
  VERROR_INT("xmlSchemaVStart",
28067
0
      "no instance to validate");
28068
0
  ret = -1;
28069
0
    }
28070
28071
0
    xmlSchemaPostRun(vctxt);
28072
0
    if (ret == 0)
28073
0
  ret = vctxt->err;
28074
0
    return (ret);
28075
0
}
28076
28077
/**
28078
 * xmlSchemaValidateOneElement:
28079
 * @ctxt:  a schema validation context
28080
 * @elem:  an element node
28081
 *
28082
 * Validate a branch of a tree, starting with the given @elem.
28083
 *
28084
 * Returns 0 if the element and its subtree is valid, a positive error
28085
 * code number otherwise and -1 in case of an internal or API error.
28086
 */
28087
int
28088
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28089
0
{
28090
0
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28091
0
  return (-1);
28092
28093
0
    if (ctxt->schema == NULL)
28094
0
  return (-1);
28095
28096
0
    ctxt->doc = elem->doc;
28097
0
    ctxt->node = elem;
28098
0
    ctxt->validationRoot = elem;
28099
0
    return(xmlSchemaVStart(ctxt));
28100
0
}
28101
28102
/**
28103
 * xmlSchemaValidateDoc:
28104
 * @ctxt:  a schema validation context
28105
 * @doc:  a parsed document tree
28106
 *
28107
 * Validate a document tree in memory.
28108
 *
28109
 * Returns 0 if the document is schemas valid, a positive error code
28110
 *     number otherwise and -1 in case of internal or API error.
28111
 */
28112
int
28113
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28114
0
{
28115
0
    if ((ctxt == NULL) || (doc == NULL))
28116
0
        return (-1);
28117
28118
0
    ctxt->doc = doc;
28119
0
    ctxt->node = xmlDocGetRootElement(doc);
28120
0
    if (ctxt->node == NULL) {
28121
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
28122
0
      XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28123
0
      (xmlNodePtr) doc, NULL,
28124
0
      "The document has no document element", NULL, NULL);
28125
0
        return (ctxt->err);
28126
0
    }
28127
0
    ctxt->validationRoot = ctxt->node;
28128
0
    return (xmlSchemaVStart(ctxt));
28129
0
}
28130
28131
28132
/************************************************************************
28133
 *                  *
28134
 *    Function and data for SAX streaming API     *
28135
 *                  *
28136
 ************************************************************************/
28137
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28138
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28139
28140
struct _xmlSchemaSplitSAXData {
28141
    xmlSAXHandlerPtr      user_sax;
28142
    void                 *user_data;
28143
    xmlSchemaValidCtxtPtr ctxt;
28144
    xmlSAXHandlerPtr      schemas_sax;
28145
};
28146
28147
0
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28148
28149
struct _xmlSchemaSAXPlug {
28150
    unsigned int magic;
28151
28152
    /* the original callbacks information */
28153
    xmlSAXHandlerPtr     *user_sax_ptr;
28154
    xmlSAXHandlerPtr      user_sax;
28155
    void                **user_data_ptr;
28156
    void                 *user_data;
28157
28158
    /* the block plugged back and validation information */
28159
    xmlSAXHandler         schemas_sax;
28160
    xmlSchemaValidCtxtPtr ctxt;
28161
};
28162
28163
/* All those functions just bounces to the user provided SAX handlers */
28164
static void
28165
internalSubsetSplit(void *ctx, const xmlChar *name,
28166
         const xmlChar *ExternalID, const xmlChar *SystemID)
28167
0
{
28168
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28169
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28170
0
        (ctxt->user_sax->internalSubset != NULL))
28171
0
  ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28172
0
                                 SystemID);
28173
0
}
28174
28175
static int
28176
isStandaloneSplit(void *ctx)
28177
0
{
28178
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28179
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28180
0
        (ctxt->user_sax->isStandalone != NULL))
28181
0
  return(ctxt->user_sax->isStandalone(ctxt->user_data));
28182
0
    return(0);
28183
0
}
28184
28185
static int
28186
hasInternalSubsetSplit(void *ctx)
28187
0
{
28188
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28189
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28190
0
        (ctxt->user_sax->hasInternalSubset != NULL))
28191
0
  return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28192
0
    return(0);
28193
0
}
28194
28195
static int
28196
hasExternalSubsetSplit(void *ctx)
28197
0
{
28198
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28199
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28200
0
        (ctxt->user_sax->hasExternalSubset != NULL))
28201
0
  return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28202
0
    return(0);
28203
0
}
28204
28205
static void
28206
externalSubsetSplit(void *ctx, const xmlChar *name,
28207
         const xmlChar *ExternalID, const xmlChar *SystemID)
28208
0
{
28209
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28210
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28211
0
        (ctxt->user_sax->externalSubset != NULL))
28212
0
  ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28213
0
                                 SystemID);
28214
0
}
28215
28216
static xmlParserInputPtr
28217
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28218
0
{
28219
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28220
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28221
0
        (ctxt->user_sax->resolveEntity != NULL))
28222
0
  return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28223
0
                                       systemId));
28224
0
    return(NULL);
28225
0
}
28226
28227
static xmlEntityPtr
28228
getEntitySplit(void *ctx, const xmlChar *name)
28229
0
{
28230
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28231
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28232
0
        (ctxt->user_sax->getEntity != NULL))
28233
0
  return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28234
0
    return(NULL);
28235
0
}
28236
28237
static xmlEntityPtr
28238
getParameterEntitySplit(void *ctx, const xmlChar *name)
28239
0
{
28240
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28241
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28242
0
        (ctxt->user_sax->getParameterEntity != NULL))
28243
0
  return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28244
0
    return(NULL);
28245
0
}
28246
28247
28248
static void
28249
entityDeclSplit(void *ctx, const xmlChar *name, int type,
28250
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28251
0
{
28252
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28253
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28254
0
        (ctxt->user_sax->entityDecl != NULL))
28255
0
  ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28256
0
                             systemId, content);
28257
0
}
28258
28259
static void
28260
attributeDeclSplit(void *ctx, const xmlChar * elem,
28261
                   const xmlChar * name, int type, int def,
28262
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
28263
0
{
28264
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28265
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28266
0
        (ctxt->user_sax->attributeDecl != NULL)) {
28267
0
  ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28268
0
                                def, defaultValue, tree);
28269
0
    } else {
28270
0
  xmlFreeEnumeration(tree);
28271
0
    }
28272
0
}
28273
28274
static void
28275
elementDeclSplit(void *ctx, const xmlChar *name, int type,
28276
      xmlElementContentPtr content)
28277
0
{
28278
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28279
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28280
0
        (ctxt->user_sax->elementDecl != NULL))
28281
0
  ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28282
0
}
28283
28284
static void
28285
notationDeclSplit(void *ctx, const xmlChar *name,
28286
       const xmlChar *publicId, const xmlChar *systemId)
28287
0
{
28288
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28289
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28290
0
        (ctxt->user_sax->notationDecl != NULL))
28291
0
  ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28292
0
                               systemId);
28293
0
}
28294
28295
static void
28296
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28297
       const xmlChar *publicId, const xmlChar *systemId,
28298
       const xmlChar *notationName)
28299
0
{
28300
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28301
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28302
0
        (ctxt->user_sax->unparsedEntityDecl != NULL))
28303
0
  ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28304
0
                                     systemId, notationName);
28305
0
}
28306
28307
static void
28308
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28309
0
{
28310
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28311
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28312
0
        (ctxt->user_sax->setDocumentLocator != NULL))
28313
0
  ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28314
0
}
28315
28316
static void
28317
startDocumentSplit(void *ctx)
28318
0
{
28319
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28320
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28321
0
        (ctxt->user_sax->startDocument != NULL))
28322
0
  ctxt->user_sax->startDocument(ctxt->user_data);
28323
0
}
28324
28325
static void
28326
endDocumentSplit(void *ctx)
28327
0
{
28328
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28329
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28330
0
        (ctxt->user_sax->endDocument != NULL))
28331
0
  ctxt->user_sax->endDocument(ctxt->user_data);
28332
0
}
28333
28334
static void
28335
processingInstructionSplit(void *ctx, const xmlChar *target,
28336
                      const xmlChar *data)
28337
0
{
28338
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28339
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28340
0
        (ctxt->user_sax->processingInstruction != NULL))
28341
0
  ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28342
0
}
28343
28344
static void
28345
commentSplit(void *ctx, const xmlChar *value)
28346
0
{
28347
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28348
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28349
0
        (ctxt->user_sax->comment != NULL))
28350
0
  ctxt->user_sax->comment(ctxt->user_data, value);
28351
0
}
28352
28353
/*
28354
 * Varargs error callbacks to the user application, harder ...
28355
 */
28356
28357
static void
28358
0
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28359
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28360
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28361
0
        (ctxt->user_sax->warning != NULL)) {
28362
  /* TODO */
28363
0
    }
28364
0
}
28365
static void
28366
0
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28367
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28368
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28369
0
        (ctxt->user_sax->error != NULL)) {
28370
  /* TODO */
28371
0
    }
28372
0
}
28373
static void
28374
0
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28375
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28376
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28377
0
        (ctxt->user_sax->fatalError != NULL)) {
28378
  /* TODO */
28379
0
    }
28380
0
}
28381
28382
/*
28383
 * Those are function where both the user handler and the schemas handler
28384
 * need to be called.
28385
 */
28386
static void
28387
charactersSplit(void *ctx, const xmlChar *ch, int len)
28388
0
{
28389
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28390
0
    if (ctxt == NULL)
28391
0
        return;
28392
0
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28393
0
  ctxt->user_sax->characters(ctxt->user_data, ch, len);
28394
0
    if (ctxt->ctxt != NULL)
28395
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28396
0
}
28397
28398
static void
28399
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28400
0
{
28401
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28402
0
    if (ctxt == NULL)
28403
0
        return;
28404
0
    if ((ctxt->user_sax != NULL) &&
28405
0
        (ctxt->user_sax->ignorableWhitespace != NULL))
28406
0
  ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28407
0
    if (ctxt->ctxt != NULL)
28408
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28409
0
}
28410
28411
static void
28412
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28413
0
{
28414
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28415
0
    if (ctxt == NULL)
28416
0
        return;
28417
0
    if ((ctxt->user_sax != NULL) &&
28418
0
        (ctxt->user_sax->cdataBlock != NULL))
28419
0
  ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28420
0
    if (ctxt->ctxt != NULL)
28421
0
  xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28422
0
}
28423
28424
static void
28425
referenceSplit(void *ctx, const xmlChar *name)
28426
0
{
28427
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28428
0
    if (ctxt == NULL)
28429
0
        return;
28430
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28431
0
        (ctxt->user_sax->reference != NULL))
28432
0
  ctxt->user_sax->reference(ctxt->user_data, name);
28433
0
    if (ctxt->ctxt != NULL)
28434
0
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
28435
0
}
28436
28437
static void
28438
startElementNsSplit(void *ctx, const xmlChar * localname,
28439
        const xmlChar * prefix, const xmlChar * URI,
28440
        int nb_namespaces, const xmlChar ** namespaces,
28441
        int nb_attributes, int nb_defaulted,
28442
0
        const xmlChar ** attributes) {
28443
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28444
0
    if (ctxt == NULL)
28445
0
        return;
28446
0
    if ((ctxt->user_sax != NULL) &&
28447
0
        (ctxt->user_sax->startElementNs != NULL))
28448
0
  ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28449
0
                                 URI, nb_namespaces, namespaces,
28450
0
               nb_attributes, nb_defaulted,
28451
0
               attributes);
28452
0
    if (ctxt->ctxt != NULL)
28453
0
  xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28454
0
                                   URI, nb_namespaces, namespaces,
28455
0
           nb_attributes, nb_defaulted,
28456
0
           attributes);
28457
0
}
28458
28459
static void
28460
endElementNsSplit(void *ctx, const xmlChar * localname,
28461
0
        const xmlChar * prefix, const xmlChar * URI) {
28462
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28463
0
    if (ctxt == NULL)
28464
0
        return;
28465
0
    if ((ctxt->user_sax != NULL) &&
28466
0
        (ctxt->user_sax->endElementNs != NULL))
28467
0
  ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28468
0
    if (ctxt->ctxt != NULL)
28469
0
  xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28470
0
}
28471
28472
/**
28473
 * xmlSchemaSAXPlug:
28474
 * @ctxt:  a schema validation context
28475
 * @sax:  a pointer to the original xmlSAXHandlerPtr
28476
 * @user_data:  a pointer to the original SAX user data pointer
28477
 *
28478
 * Plug a SAX based validation layer in a SAX parsing event flow.
28479
 * The original @saxptr and @dataptr data are replaced by new pointers
28480
 * but the calls to the original will be maintained.
28481
 *
28482
 * Returns a pointer to a data structure needed to unplug the validation layer
28483
 *         or NULL in case of errors.
28484
 */
28485
xmlSchemaSAXPlugPtr
28486
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28487
     xmlSAXHandlerPtr *sax, void **user_data)
28488
0
{
28489
0
    xmlSchemaSAXPlugPtr ret;
28490
0
    xmlSAXHandlerPtr old_sax;
28491
28492
0
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28493
0
        return(NULL);
28494
28495
    /*
28496
     * We only allow to plug into SAX2 event streams
28497
     */
28498
0
    old_sax = *sax;
28499
0
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28500
0
        return(NULL);
28501
0
    if ((old_sax != NULL) &&
28502
0
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28503
0
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28504
0
        return(NULL);
28505
28506
    /*
28507
     * everything seems right allocate the local data needed for that layer
28508
     */
28509
0
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28510
0
    if (ret == NULL) {
28511
0
        return(NULL);
28512
0
    }
28513
0
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28514
0
    ret->magic = XML_SAX_PLUG_MAGIC;
28515
0
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28516
0
    ret->ctxt = ctxt;
28517
0
    ret->user_sax_ptr = sax;
28518
0
    ret->user_sax = old_sax;
28519
0
    if (old_sax == NULL) {
28520
        /*
28521
   * go direct, no need for the split block and functions.
28522
   */
28523
0
  ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28524
0
  ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28525
  /*
28526
   * Note that we use the same text-function for both, to prevent
28527
   * the parser from testing for ignorable whitespace.
28528
   */
28529
0
  ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28530
0
  ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28531
28532
0
  ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28533
0
  ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28534
28535
0
  ret->user_data = ctxt;
28536
0
  *user_data = ctxt;
28537
0
    } else {
28538
       /*
28539
        * for each callback unused by Schemas initialize it to the Split
28540
  * routine only if non NULL in the user block, this can speed up
28541
  * things at the SAX level.
28542
  */
28543
0
        if (old_sax->internalSubset != NULL)
28544
0
            ret->schemas_sax.internalSubset = internalSubsetSplit;
28545
0
        if (old_sax->isStandalone != NULL)
28546
0
            ret->schemas_sax.isStandalone = isStandaloneSplit;
28547
0
        if (old_sax->hasInternalSubset != NULL)
28548
0
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28549
0
        if (old_sax->hasExternalSubset != NULL)
28550
0
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28551
0
        if (old_sax->resolveEntity != NULL)
28552
0
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
28553
0
        if (old_sax->getEntity != NULL)
28554
0
            ret->schemas_sax.getEntity = getEntitySplit;
28555
0
        if (old_sax->entityDecl != NULL)
28556
0
            ret->schemas_sax.entityDecl = entityDeclSplit;
28557
0
        if (old_sax->notationDecl != NULL)
28558
0
            ret->schemas_sax.notationDecl = notationDeclSplit;
28559
0
        if (old_sax->attributeDecl != NULL)
28560
0
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
28561
0
        if (old_sax->elementDecl != NULL)
28562
0
            ret->schemas_sax.elementDecl = elementDeclSplit;
28563
0
        if (old_sax->unparsedEntityDecl != NULL)
28564
0
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28565
0
        if (old_sax->setDocumentLocator != NULL)
28566
0
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28567
0
        if (old_sax->startDocument != NULL)
28568
0
            ret->schemas_sax.startDocument = startDocumentSplit;
28569
0
        if (old_sax->endDocument != NULL)
28570
0
            ret->schemas_sax.endDocument = endDocumentSplit;
28571
0
        if (old_sax->processingInstruction != NULL)
28572
0
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
28573
0
        if (old_sax->comment != NULL)
28574
0
            ret->schemas_sax.comment = commentSplit;
28575
0
        if (old_sax->warning != NULL)
28576
0
            ret->schemas_sax.warning = warningSplit;
28577
0
        if (old_sax->error != NULL)
28578
0
            ret->schemas_sax.error = errorSplit;
28579
0
        if (old_sax->fatalError != NULL)
28580
0
            ret->schemas_sax.fatalError = fatalErrorSplit;
28581
0
        if (old_sax->getParameterEntity != NULL)
28582
0
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28583
0
        if (old_sax->externalSubset != NULL)
28584
0
            ret->schemas_sax.externalSubset = externalSubsetSplit;
28585
28586
  /*
28587
   * the 6 schemas callback have to go to the splitter functions
28588
   * Note that we use the same text-function for ignorableWhitespace
28589
   * if possible, to prevent the parser from testing for ignorable
28590
   * whitespace.
28591
   */
28592
0
        ret->schemas_sax.characters = charactersSplit;
28593
0
  if ((old_sax->ignorableWhitespace != NULL) &&
28594
0
      (old_sax->ignorableWhitespace != old_sax->characters))
28595
0
      ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28596
0
  else
28597
0
      ret->schemas_sax.ignorableWhitespace = charactersSplit;
28598
0
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
28599
0
        ret->schemas_sax.reference = referenceSplit;
28600
0
        ret->schemas_sax.startElementNs = startElementNsSplit;
28601
0
        ret->schemas_sax.endElementNs = endElementNsSplit;
28602
28603
0
  ret->user_data_ptr = user_data;
28604
0
  ret->user_data = *user_data;
28605
0
  *user_data = ret;
28606
0
    }
28607
28608
    /*
28609
     * plug the pointers back.
28610
     */
28611
0
    *sax = &(ret->schemas_sax);
28612
0
    ctxt->sax = *sax;
28613
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28614
0
    xmlSchemaPreRun(ctxt);
28615
0
    return(ret);
28616
0
}
28617
28618
/**
28619
 * xmlSchemaSAXUnplug:
28620
 * @plug:  a data structure returned by xmlSchemaSAXPlug
28621
 *
28622
 * Unplug a SAX based validation layer in a SAX parsing event flow.
28623
 * The original pointers used in the call are restored.
28624
 *
28625
 * Returns 0 in case of success and -1 in case of failure.
28626
 */
28627
int
28628
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28629
0
{
28630
0
    xmlSAXHandlerPtr *sax;
28631
0
    void **user_data;
28632
28633
0
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28634
0
        return(-1);
28635
0
    plug->magic = 0;
28636
28637
0
    xmlSchemaPostRun(plug->ctxt);
28638
    /* restore the data */
28639
0
    sax = plug->user_sax_ptr;
28640
0
    *sax = plug->user_sax;
28641
0
    if (plug->user_sax != NULL) {
28642
0
  user_data = plug->user_data_ptr;
28643
0
  *user_data = plug->user_data;
28644
0
    }
28645
28646
    /* free and return */
28647
0
    xmlFree(plug);
28648
0
    return(0);
28649
0
}
28650
28651
/**
28652
 * xmlSchemaValidateSetLocator:
28653
 * @vctxt: a schema validation context
28654
 * @f: the locator function pointer
28655
 * @ctxt: the locator context
28656
 *
28657
 * Allows to set a locator function to the validation context,
28658
 * which will be used to provide file and line information since
28659
 * those are not provided as part of the SAX validation flow
28660
 * Setting @f to NULL disable the locator.
28661
 */
28662
28663
void
28664
xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
28665
                            xmlSchemaValidityLocatorFunc f,
28666
          void *ctxt)
28667
0
{
28668
0
    if (vctxt == NULL) return;
28669
0
    vctxt->locFunc = f;
28670
0
    vctxt->locCtxt = ctxt;
28671
0
}
28672
28673
/**
28674
 * xmlSchemaValidateStreamLocator:
28675
 * @ctx: the xmlTextReaderPtr used
28676
 * @file: returned file information
28677
 * @line: returned line information
28678
 *
28679
 * Internal locator function for the readers
28680
 *
28681
 * Returns 0 in case the Schema validation could be (de)activated and
28682
 *         -1 in case of error.
28683
 */
28684
static int
28685
xmlSchemaValidateStreamLocator(void *ctx, const char **file,
28686
0
                               unsigned long *line) {
28687
0
    xmlParserCtxtPtr ctxt;
28688
28689
0
    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
28690
0
        return(-1);
28691
28692
0
    if (file != NULL)
28693
0
        *file = NULL;
28694
0
    if (line != NULL)
28695
0
        *line = 0;
28696
28697
0
    ctxt = (xmlParserCtxtPtr) ctx;
28698
0
    if (ctxt->input != NULL) {
28699
0
       if (file != NULL)
28700
0
           *file = ctxt->input->filename;
28701
0
       if (line != NULL)
28702
0
           *line = ctxt->input->line;
28703
0
       return(0);
28704
0
    }
28705
0
    return(-1);
28706
0
}
28707
28708
/**
28709
 * xmlSchemaValidateStreamInternal:
28710
 * @ctxt:  a schema validation context
28711
 * @pctxt:  a parser context
28712
 *
28713
 * Returns 0 if the document is schemas valid, a positive error code
28714
 *     number otherwise and -1 in case of internal or API error.
28715
 */
28716
static int
28717
xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
28718
0
                                 xmlParserCtxtPtr pctxt) {
28719
0
    xmlSchemaSAXPlugPtr plug = NULL;
28720
0
    int ret;
28721
28722
0
    pctxt->linenumbers = 1;
28723
0
    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
28724
28725
0
    ctxt->parserCtxt = pctxt;
28726
0
    ctxt->input = pctxt->input->buf;
28727
28728
    /*
28729
     * Plug the validation and launch the parsing
28730
     */
28731
0
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28732
0
    if (plug == NULL) {
28733
0
        ret = -1;
28734
0
  goto done;
28735
0
    }
28736
0
    ctxt->input = pctxt->input->buf;
28737
0
    ctxt->sax = pctxt->sax;
28738
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28739
0
    ret = xmlSchemaVStart(ctxt);
28740
28741
0
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28742
0
  ret = ctxt->parserCtxt->errNo;
28743
0
  if (ret == 0)
28744
0
      ret = 1;
28745
0
    }
28746
28747
0
done:
28748
0
    ctxt->parserCtxt = NULL;
28749
0
    ctxt->sax = NULL;
28750
0
    ctxt->input = NULL;
28751
0
    if (plug != NULL) {
28752
0
        xmlSchemaSAXUnplug(plug);
28753
0
    }
28754
0
    return (ret);
28755
0
}
28756
28757
/**
28758
 * xmlSchemaValidateStream:
28759
 * @ctxt:  a schema validation context
28760
 * @input:  the input to use for reading the data
28761
 * @enc:  an optional encoding information
28762
 * @sax:  a SAX handler for the resulting events
28763
 * @user_data:  the context to provide to the SAX handler.
28764
 *
28765
 * Validate an input based on a flow of SAX event from the parser
28766
 * and forward the events to the @sax handler with the provided @user_data
28767
 * the user provided @sax handler must be a SAX2 one.
28768
 *
28769
 * Returns 0 if the document is schemas valid, a positive error code
28770
 *     number otherwise and -1 in case of internal or API error.
28771
 */
28772
int
28773
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28774
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
28775
                        xmlSAXHandlerPtr sax, void *user_data)
28776
0
{
28777
0
    xmlParserCtxtPtr pctxt = NULL;
28778
0
    xmlParserInputPtr inputStream = NULL;
28779
0
    int ret;
28780
28781
0
    if ((ctxt == NULL) || (input == NULL))
28782
0
        return (-1);
28783
28784
    /*
28785
     * prepare the parser
28786
     */
28787
0
    if (sax != NULL) {
28788
0
        pctxt = xmlNewSAXParserCtxt(sax, user_data);
28789
0
        if (pctxt == NULL)
28790
0
            return (-1);
28791
0
    } else {
28792
0
        pctxt = xmlNewParserCtxt();
28793
0
        if (pctxt == NULL)
28794
0
            return (-1);
28795
        /* We really want pctxt->sax to be NULL here. */
28796
0
        xmlFree(pctxt->sax);
28797
0
        pctxt->sax = NULL;
28798
0
    }
28799
#if 0
28800
    if (options)
28801
        xmlCtxtUseOptions(pctxt, options);
28802
#endif
28803
28804
0
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28805
0
    if (inputStream == NULL) {
28806
0
        ret = -1;
28807
0
  goto done;
28808
0
    }
28809
0
    if (inputPush(pctxt, inputStream) < 0) {
28810
0
        xmlFreeInputStream(inputStream);
28811
0
        ret = -1;
28812
0
        goto done;
28813
0
    }
28814
28815
0
    ctxt->enc = enc;
28816
28817
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28818
28819
0
done:
28820
    /* cleanup */
28821
0
    if (pctxt != NULL) {
28822
0
  xmlFreeParserCtxt(pctxt);
28823
0
    }
28824
0
    return (ret);
28825
0
}
28826
28827
/**
28828
 * xmlSchemaValidateFile:
28829
 * @ctxt: a schema validation context
28830
 * @filename: the URI of the instance
28831
 * @options: a future set of options, currently unused
28832
 *
28833
 * Do a schemas validation of the given resource, it will use the
28834
 * SAX streamable validation internally.
28835
 *
28836
 * Returns 0 if the document is valid, a positive error code
28837
 *     number otherwise and -1 in case of an internal or API error.
28838
 */
28839
int
28840
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28841
                      const char * filename,
28842
          int options ATTRIBUTE_UNUSED)
28843
0
{
28844
0
    int ret;
28845
0
    xmlParserCtxtPtr pctxt = NULL;
28846
28847
0
    if ((ctxt == NULL) || (filename == NULL))
28848
0
        return (-1);
28849
28850
0
    pctxt = xmlCreateURLParserCtxt(filename, 0);
28851
0
    if (pctxt == NULL)
28852
0
  return (-1);
28853
    /* We really want pctxt->sax to be NULL here. */
28854
0
    xmlFree(pctxt->sax);
28855
0
    pctxt->sax = NULL;
28856
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28857
0
    xmlFreeParserCtxt(pctxt);
28858
0
    return (ret);
28859
0
}
28860
28861
/**
28862
 * xmlSchemaValidCtxtGetParserCtxt:
28863
 * @ctxt: a schema validation context
28864
 *
28865
 * allow access to the parser context of the schema validation context
28866
 *
28867
 * Returns the parser context of the schema validation context or NULL
28868
 *         in case of error.
28869
 */
28870
xmlParserCtxtPtr
28871
xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28872
0
{
28873
0
    if (ctxt == NULL)
28874
0
        return(NULL);
28875
0
    return (ctxt->parserCtxt);
28876
0
}
28877
28878
#endif /* LIBXML_SCHEMAS_ENABLED */