Coverage Report

Created: 2025-11-11 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tinysparql/subprojects/libxml2-2.13.1/xmlschemas.c
Line
Count
Source
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
633
/**
634
 * xmlSchemaQNameRef:
635
 *
636
 * A component reference item (not a schema component)
637
 * (Extends xmlSchemaBasicItem)
638
 */
639
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
640
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
641
struct _xmlSchemaQNameRef {
642
    xmlSchemaTypeType type;
643
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
644
    xmlSchemaTypeType itemType;
645
    const xmlChar *name;
646
    const xmlChar *targetNamespace;
647
    xmlNodePtr node;
648
};
649
650
/**
651
 * xmlSchemaParticle:
652
 *
653
 * A particle component.
654
 * (Extends xmlSchemaTreeItem)
655
 */
656
typedef struct _xmlSchemaParticle xmlSchemaParticle;
657
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
658
struct _xmlSchemaParticle {
659
    xmlSchemaTypeType type;
660
    xmlSchemaAnnotPtr annot;
661
    xmlSchemaTreeItemPtr next; /* next particle */
662
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
663
  a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
664
        etc.) */
665
    int minOccurs;
666
    int maxOccurs;
667
    xmlNodePtr node;
668
};
669
670
/**
671
 * xmlSchemaModelGroup:
672
 *
673
 * A model group component.
674
 * (Extends xmlSchemaTreeItem)
675
 */
676
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
677
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
678
struct _xmlSchemaModelGroup {
679
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
680
    xmlSchemaAnnotPtr annot;
681
    xmlSchemaTreeItemPtr next; /* not used */
682
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
683
    xmlNodePtr node;
684
};
685
686
0
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
687
0
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
688
/**
689
 * xmlSchemaModelGroupDef:
690
 *
691
 * A model group definition component.
692
 * (Extends xmlSchemaTreeItem)
693
 */
694
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
695
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
696
struct _xmlSchemaModelGroupDef {
697
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
698
    xmlSchemaAnnotPtr annot;
699
    xmlSchemaTreeItemPtr next; /* not used */
700
    xmlSchemaTreeItemPtr children; /* the "model group" */
701
    const xmlChar *name;
702
    const xmlChar *targetNamespace;
703
    xmlNodePtr node;
704
    int flags;
705
};
706
707
typedef struct _xmlSchemaIDC xmlSchemaIDC;
708
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
709
710
/**
711
 * xmlSchemaIDCSelect:
712
 *
713
 * The identity-constraint "field" and "selector" item, holding the
714
 * XPath expression.
715
 */
716
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
717
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
718
struct _xmlSchemaIDCSelect {
719
    xmlSchemaIDCSelectPtr next;
720
    xmlSchemaIDCPtr idc;
721
    int index; /* an index position if significant for IDC key-sequences */
722
    const xmlChar *xpath; /* the XPath expression */
723
    void *xpathComp; /* the compiled XPath expression */
724
};
725
726
/**
727
 * xmlSchemaIDC:
728
 *
729
 * The identity-constraint definition component.
730
 * (Extends xmlSchemaAnnotItem)
731
 */
732
733
struct _xmlSchemaIDC {
734
    xmlSchemaTypeType type;
735
    xmlSchemaAnnotPtr annot;
736
    xmlSchemaIDCPtr next;
737
    xmlNodePtr node;
738
    const xmlChar *name;
739
    const xmlChar *targetNamespace;
740
    xmlSchemaIDCSelectPtr selector;
741
    xmlSchemaIDCSelectPtr fields;
742
    int nbFields;
743
    xmlSchemaQNameRefPtr ref;
744
};
745
746
/**
747
 * xmlSchemaIDCAug:
748
 *
749
 * The augmented IDC information used for validation.
750
 */
751
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
752
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
753
struct _xmlSchemaIDCAug {
754
    xmlSchemaIDCAugPtr next; /* next in a list */
755
    xmlSchemaIDCPtr def; /* the IDC definition */
756
    int keyrefDepth; /* the lowest tree level to which IDC
757
                        tables need to be bubbled upwards */
758
};
759
760
/**
761
 * xmlSchemaPSVIIDCKeySequence:
762
 *
763
 * The key sequence of a node table item.
764
 */
765
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
766
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
767
struct _xmlSchemaPSVIIDCKey {
768
    xmlSchemaTypePtr type;
769
    xmlSchemaValPtr val;
770
};
771
772
/**
773
 * xmlSchemaPSVIIDCNode:
774
 *
775
 * The node table item of a node table.
776
 */
777
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
778
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
779
struct _xmlSchemaPSVIIDCNode {
780
    xmlNodePtr node;
781
    xmlSchemaPSVIIDCKeyPtr *keys;
782
    int nodeLine;
783
    int nodeQNameID;
784
785
};
786
787
/**
788
 * xmlSchemaPSVIIDCBinding:
789
 *
790
 * The identity-constraint binding item of the [identity-constraint table].
791
 */
792
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
793
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
794
struct _xmlSchemaPSVIIDCBinding {
795
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
796
    xmlSchemaIDCPtr definition; /* the IDC definition */
797
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
798
    int nbNodes; /* number of entries in the node table */
799
    int sizeNodes; /* size of the node table */
800
    xmlSchemaItemListPtr dupls;
801
};
802
803
804
0
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
805
0
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
806
807
#define XPATH_STATE_OBJ_MATCHES -2
808
#define XPATH_STATE_OBJ_BLOCKED -3
809
810
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
811
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
812
813
/**
814
 * xmlSchemaIDCStateObj:
815
 *
816
 * The state object used to evaluate XPath expressions.
817
 */
818
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
819
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
820
struct _xmlSchemaIDCStateObj {
821
    int type;
822
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
823
    int depth; /* depth of creation */
824
    int *history; /* list of (depth, state-id) tuples */
825
    int nbHistory;
826
    int sizeHistory;
827
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
828
                                       matcher */
829
    xmlSchemaIDCSelectPtr sel;
830
    void *xpathCtxt;
831
};
832
833
0
#define IDC_MATCHER 0
834
835
/**
836
 * xmlSchemaIDCMatcher:
837
 *
838
 * Used to evaluate IDC selectors (and fields).
839
 */
840
struct _xmlSchemaIDCMatcher {
841
    int type;
842
    int depth; /* the tree depth at creation time */
843
    xmlSchemaIDCMatcherPtr next; /* next in the list */
844
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
845
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
846
    int idcType;
847
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
848
                                         elements */
849
    int sizeKeySeqs;
850
    xmlSchemaItemListPtr targets; /* list of target-node
851
                                     (xmlSchemaPSVIIDCNodePtr) entries */
852
    xmlHashTablePtr htab;
853
};
854
855
/*
856
* Element info flags.
857
*/
858
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
859
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
860
0
#define XML_SCHEMA_ELEM_INFO_NILLED        1<<2
861
0
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        1<<3
862
863
0
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
864
0
#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
865
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
866
867
0
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
868
0
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
869
0
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
870
0
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
871
872
/**
873
 * xmlSchemaNodeInfo:
874
 *
875
 * Holds information of an element node.
876
 */
877
struct _xmlSchemaNodeInfo {
878
    int nodeType;
879
    xmlNodePtr node;
880
    int nodeLine;
881
    const xmlChar *localName;
882
    const xmlChar *nsName;
883
    const xmlChar *value;
884
    xmlSchemaValPtr val; /* the pre-computed value if any */
885
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
886
887
    int flags; /* combination of node info flags */
888
889
    int valNeeded;
890
    int normVal;
891
892
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
893
    int depth;
894
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
895
                                            for the scope element*/
896
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
897
                                           element */
898
    xmlRegExecCtxtPtr regexCtxt;
899
900
    const xmlChar **nsBindings; /* Namespace bindings on this element */
901
    int nbNsBindings;
902
    int sizeNsBindings;
903
904
    int hasKeyrefs;
905
    int appliedXPath; /* Indicates that an XPath has been applied. */
906
};
907
908
0
#define XML_SCHEMAS_ATTR_UNKNOWN 1
909
0
#define XML_SCHEMAS_ATTR_ASSESSED 2
910
#define XML_SCHEMAS_ATTR_PROHIBITED 3
911
0
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
912
0
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
913
0
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
914
0
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
915
0
#define XML_SCHEMAS_ATTR_DEFAULT 8
916
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
917
0
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
918
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
919
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
920
0
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
921
0
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
922
0
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
923
0
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
924
0
#define XML_SCHEMAS_ATTR_META 17
925
/*
926
* @metaType values of xmlSchemaAttrInfo.
927
*/
928
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
929
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
930
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
931
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
932
0
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
933
934
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
935
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
936
struct _xmlSchemaAttrInfo {
937
    int nodeType;
938
    xmlNodePtr node;
939
    int nodeLine;
940
    const xmlChar *localName;
941
    const xmlChar *nsName;
942
    const xmlChar *value;
943
    xmlSchemaValPtr val; /* the pre-computed value if any */
944
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
945
    int flags; /* combination of node info flags */
946
947
    xmlSchemaAttributePtr decl; /* the attribute declaration */
948
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
949
    int state;
950
    int metaType;
951
    const xmlChar *vcValue; /* the value constraint value */
952
    xmlSchemaNodeInfoPtr parent;
953
};
954
955
956
0
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
957
/**
958
 * xmlSchemaValidCtxt:
959
 *
960
 * A Schemas validation context
961
 */
962
struct _xmlSchemaValidCtxt {
963
    int type;
964
    void *errCtxt;             /* user specific data block */
965
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
966
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
967
    xmlStructuredErrorFunc serror;
968
969
    xmlSchemaPtr schema;        /* The schema in use */
970
    xmlDocPtr doc;
971
    xmlParserInputBufferPtr input;
972
    xmlCharEncoding enc;
973
    xmlSAXHandlerPtr sax;
974
    xmlParserCtxtPtr parserCtxt;
975
    void *user_data; /* TODO: What is this for? */
976
    char *filename;
977
978
    int err;
979
    int nberrors;
980
981
    xmlNodePtr node;
982
    xmlNodePtr cur;
983
    /* xmlSchemaTypePtr type; */
984
985
    xmlRegExecCtxtPtr regexp;
986
    xmlSchemaValPtr value;
987
988
    int valueWS;
989
    int options;
990
    xmlNodePtr validationRoot;
991
    xmlSchemaParserCtxtPtr pctxt;
992
    int xsiAssemble;
993
994
    int depth;
995
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
996
    int sizeElemInfos;
997
    xmlSchemaNodeInfoPtr inode; /* the current element information */
998
999
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1000
1001
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1002
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1003
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1004
1005
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1006
    int nbIdcNodes;
1007
    int sizeIdcNodes;
1008
1009
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1010
    int nbIdcKeys;
1011
    int sizeIdcKeys;
1012
1013
    int flags;
1014
1015
    xmlDictPtr dict;
1016
1017
#ifdef LIBXML_READER_ENABLED
1018
    xmlTextReaderPtr reader;
1019
#endif
1020
1021
    xmlSchemaAttrInfoPtr *attrInfos;
1022
    int nbAttrInfos;
1023
    int sizeAttrInfos;
1024
1025
    int skipDepth;
1026
    xmlSchemaItemListPtr nodeQNames;
1027
    int hasKeyrefs;
1028
    int createIDCNodeTables;
1029
    int psviExposeIDCNodeTables;
1030
1031
    /* Locator for error reporting in streaming mode */
1032
    xmlSchemaValidityLocatorFunc locFunc;
1033
    void *locCtxt;
1034
};
1035
1036
/**
1037
 * xmlSchemaSubstGroup:
1038
 *
1039
 *
1040
 */
1041
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1042
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1043
struct _xmlSchemaSubstGroup {
1044
    xmlSchemaElementPtr head;
1045
    xmlSchemaItemListPtr members;
1046
};
1047
1048
/**
1049
 * xmlIDCHashEntry:
1050
 *
1051
 * an entry in hash tables to quickly look up keys/uniques
1052
 */
1053
typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1054
typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1055
struct _xmlIDCHashEntry {
1056
    xmlIDCHashEntryPtr next; /* next item with same hash */
1057
    int index;               /* index into associated item list */
1058
};
1059
1060
/************************************************************************
1061
 *                  *
1062
 *      Some predeclarations        *
1063
 *                  *
1064
 ************************************************************************/
1065
1066
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1067
                                 xmlSchemaPtr schema,
1068
                                 xmlNodePtr node);
1069
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1070
                                 xmlSchemaPtr schema,
1071
                                 xmlNodePtr node);
1072
static int
1073
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1074
                   xmlSchemaAbstractCtxtPtr ctxt);
1075
static const xmlChar *
1076
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1077
static int
1078
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1079
                     xmlNodePtr node);
1080
static int
1081
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1082
                       xmlSchemaParserCtxtPtr ctxt);
1083
static void
1084
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1085
static xmlSchemaWhitespaceValueType
1086
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1087
static xmlSchemaTreeItemPtr
1088
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1089
       xmlNodePtr node, xmlSchemaTypeType type,
1090
       int withParticle);
1091
static const xmlChar *
1092
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1093
static xmlSchemaTypeLinkPtr
1094
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1095
static void
1096
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1097
         const char *funcName,
1098
         const char *message) LIBXML_ATTR_FORMAT(3,0);
1099
static int
1100
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1101
           xmlSchemaTypePtr type,
1102
           xmlSchemaTypePtr baseType,
1103
           int subset);
1104
static void
1105
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1106
           xmlSchemaParserCtxtPtr ctxt);
1107
static void
1108
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1109
static xmlSchemaQNameRefPtr
1110
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1111
        xmlSchemaPtr schema,
1112
        xmlNodePtr node);
1113
1114
/************************************************************************
1115
 *                  *
1116
 *      Helper functions              *
1117
 *                  *
1118
 ************************************************************************/
1119
1120
/**
1121
 * xmlSchemaItemTypeToStr:
1122
 * @type: the type of the schema item
1123
 *
1124
 * Returns the component name of a schema item.
1125
 */
1126
static const xmlChar *
1127
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1128
0
{
1129
0
    switch (type) {
1130
0
  case XML_SCHEMA_TYPE_BASIC:
1131
0
      return(BAD_CAST "simple type definition");
1132
0
  case XML_SCHEMA_TYPE_SIMPLE:
1133
0
      return(BAD_CAST "simple type definition");
1134
0
  case XML_SCHEMA_TYPE_COMPLEX:
1135
0
      return(BAD_CAST "complex type definition");
1136
0
  case XML_SCHEMA_TYPE_ELEMENT:
1137
0
      return(BAD_CAST "element declaration");
1138
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1139
0
      return(BAD_CAST "attribute use");
1140
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1141
0
      return(BAD_CAST "attribute declaration");
1142
0
  case XML_SCHEMA_TYPE_GROUP:
1143
0
      return(BAD_CAST "model group definition");
1144
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1145
0
      return(BAD_CAST "attribute group definition");
1146
0
  case XML_SCHEMA_TYPE_NOTATION:
1147
0
      return(BAD_CAST "notation declaration");
1148
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1149
0
      return(BAD_CAST "model group (sequence)");
1150
0
  case XML_SCHEMA_TYPE_CHOICE:
1151
0
      return(BAD_CAST "model group (choice)");
1152
0
  case XML_SCHEMA_TYPE_ALL:
1153
0
      return(BAD_CAST "model group (all)");
1154
0
  case XML_SCHEMA_TYPE_PARTICLE:
1155
0
      return(BAD_CAST "particle");
1156
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1157
0
      return(BAD_CAST "unique identity-constraint");
1158
      /* return(BAD_CAST "IDC (unique)"); */
1159
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1160
0
      return(BAD_CAST "key identity-constraint");
1161
      /* return(BAD_CAST "IDC (key)"); */
1162
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1163
0
      return(BAD_CAST "keyref identity-constraint");
1164
      /* return(BAD_CAST "IDC (keyref)"); */
1165
0
  case XML_SCHEMA_TYPE_ANY:
1166
0
      return(BAD_CAST "wildcard (any)");
1167
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1168
0
      return(BAD_CAST "[helper component] QName reference");
1169
0
  case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1170
0
      return(BAD_CAST "[helper component] attribute use prohibition");
1171
0
  default:
1172
0
      return(BAD_CAST "Not a schema component");
1173
0
    }
1174
0
}
1175
1176
/**
1177
 * xmlSchemaGetComponentTypeStr:
1178
 * @type: the type of the schema item
1179
 *
1180
 * Returns the component name of a schema item.
1181
 */
1182
static const xmlChar *
1183
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1184
0
{
1185
0
    switch (item->type) {
1186
0
  case XML_SCHEMA_TYPE_BASIC:
1187
0
      if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1188
0
    return(BAD_CAST "complex type definition");
1189
0
      else
1190
0
    return(BAD_CAST "simple type definition");
1191
0
  default:
1192
0
      return(xmlSchemaItemTypeToStr(item->type));
1193
0
    }
1194
0
}
1195
1196
/**
1197
 * xmlSchemaGetComponentNode:
1198
 * @item: a schema component
1199
 *
1200
 * Returns node associated with the schema component.
1201
 * NOTE that such a node need not be available; plus, a component's
1202
 * node need not to reflect the component directly, since there is no
1203
 * one-to-one relationship between the XML Schema representation and
1204
 * the component representation.
1205
 */
1206
static xmlNodePtr
1207
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1208
0
{
1209
0
    switch (item->type) {
1210
0
  case XML_SCHEMA_TYPE_ELEMENT:
1211
0
      return (((xmlSchemaElementPtr) item)->node);
1212
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1213
0
      return (((xmlSchemaAttributePtr) item)->node);
1214
0
  case XML_SCHEMA_TYPE_COMPLEX:
1215
0
  case XML_SCHEMA_TYPE_SIMPLE:
1216
0
      return (((xmlSchemaTypePtr) item)->node);
1217
0
  case XML_SCHEMA_TYPE_ANY:
1218
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1219
0
      return (((xmlSchemaWildcardPtr) item)->node);
1220
0
  case XML_SCHEMA_TYPE_PARTICLE:
1221
0
      return (((xmlSchemaParticlePtr) item)->node);
1222
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1223
0
  case XML_SCHEMA_TYPE_CHOICE:
1224
0
  case XML_SCHEMA_TYPE_ALL:
1225
0
      return (((xmlSchemaModelGroupPtr) item)->node);
1226
0
  case XML_SCHEMA_TYPE_GROUP:
1227
0
      return (((xmlSchemaModelGroupDefPtr) item)->node);
1228
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1229
0
      return (((xmlSchemaAttributeGroupPtr) item)->node);
1230
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1231
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1232
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1233
0
      return (((xmlSchemaIDCPtr) item)->node);
1234
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1235
0
      return(((xmlSchemaQNameRefPtr) item)->node);
1236
  /* TODO: What to do with NOTATIONs?
1237
  case XML_SCHEMA_TYPE_NOTATION:
1238
      return (((xmlSchemaNotationPtr) item)->node);
1239
  */
1240
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1241
0
      return (((xmlSchemaAttributeUsePtr) item)->node);
1242
0
  default:
1243
0
      return (NULL);
1244
0
    }
1245
0
}
1246
1247
#if 0
1248
/**
1249
 * xmlSchemaGetNextComponent:
1250
 * @item: a schema component
1251
 *
1252
 * Returns the next sibling of the schema component.
1253
 */
1254
static xmlSchemaBasicItemPtr
1255
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1256
{
1257
    switch (item->type) {
1258
  case XML_SCHEMA_TYPE_ELEMENT:
1259
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1260
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1261
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1262
  case XML_SCHEMA_TYPE_COMPLEX:
1263
  case XML_SCHEMA_TYPE_SIMPLE:
1264
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1265
  case XML_SCHEMA_TYPE_ANY:
1266
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1267
      return (NULL);
1268
  case XML_SCHEMA_TYPE_PARTICLE:
1269
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1270
  case XML_SCHEMA_TYPE_SEQUENCE:
1271
  case XML_SCHEMA_TYPE_CHOICE:
1272
  case XML_SCHEMA_TYPE_ALL:
1273
      return (NULL);
1274
  case XML_SCHEMA_TYPE_GROUP:
1275
      return (NULL);
1276
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1277
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1278
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1279
  case XML_SCHEMA_TYPE_IDC_KEY:
1280
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1281
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1282
  default:
1283
      return (NULL);
1284
    }
1285
}
1286
#endif
1287
1288
1289
/**
1290
 * xmlSchemaFormatQName:
1291
 * @buf: the string buffer
1292
 * @namespaceName:  the namespace name
1293
 * @localName: the local name
1294
 *
1295
 * Returns the given QName in the format "{namespaceName}localName" or
1296
 * just "localName" if @namespaceName is NULL.
1297
 *
1298
 * Returns the localName if @namespaceName is NULL, a formatted
1299
 * string otherwise.
1300
 */
1301
static const xmlChar*
1302
xmlSchemaFormatQName(xmlChar **buf,
1303
         const xmlChar *namespaceName,
1304
         const xmlChar *localName)
1305
0
{
1306
0
    FREE_AND_NULL(*buf)
1307
0
    if (namespaceName != NULL) {
1308
0
  *buf = xmlStrdup(BAD_CAST "{");
1309
0
  *buf = xmlStrcat(*buf, namespaceName);
1310
0
  *buf = xmlStrcat(*buf, BAD_CAST "}");
1311
0
    }
1312
0
    if (localName != NULL) {
1313
0
  if (namespaceName == NULL)
1314
0
      return(localName);
1315
0
  *buf = xmlStrcat(*buf, localName);
1316
0
    } else {
1317
0
  *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1318
0
    }
1319
0
    return ((const xmlChar *) *buf);
1320
0
}
1321
1322
static const xmlChar*
1323
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1324
0
{
1325
0
    if (ns != NULL)
1326
0
  return (xmlSchemaFormatQName(buf, ns->href, localName));
1327
0
    else
1328
0
  return (xmlSchemaFormatQName(buf, NULL, localName));
1329
0
}
1330
1331
static const xmlChar *
1332
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1333
0
{
1334
0
    if (item == NULL) {
1335
0
        return (NULL);
1336
0
    }
1337
0
    switch (item->type) {
1338
0
  case XML_SCHEMA_TYPE_ELEMENT:
1339
0
      return (((xmlSchemaElementPtr) item)->name);
1340
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1341
0
      return (((xmlSchemaAttributePtr) item)->name);
1342
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1343
0
      return (((xmlSchemaAttributeGroupPtr) item)->name);
1344
0
  case XML_SCHEMA_TYPE_BASIC:
1345
0
  case XML_SCHEMA_TYPE_SIMPLE:
1346
0
  case XML_SCHEMA_TYPE_COMPLEX:
1347
0
      return (((xmlSchemaTypePtr) item)->name);
1348
0
  case XML_SCHEMA_TYPE_GROUP:
1349
0
      return (((xmlSchemaModelGroupDefPtr) item)->name);
1350
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1351
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1352
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1353
0
      return (((xmlSchemaIDCPtr) item)->name);
1354
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1355
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1356
0
    return(xmlSchemaGetComponentName(
1357
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1358
0
      } else
1359
0
    return(NULL);
1360
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1361
0
      return (((xmlSchemaQNameRefPtr) item)->name);
1362
0
  case XML_SCHEMA_TYPE_NOTATION:
1363
0
      return (((xmlSchemaNotationPtr) item)->name);
1364
0
  default:
1365
      /*
1366
      * Other components cannot have names.
1367
      */
1368
0
      break;
1369
0
    }
1370
0
    return (NULL);
1371
0
}
1372
1373
0
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1374
0
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1375
/*
1376
static const xmlChar *
1377
xmlSchemaGetQNameRefName(void *ref)
1378
{
1379
    return(((xmlSchemaQNameRefPtr) ref)->name);
1380
}
1381
1382
static const xmlChar *
1383
xmlSchemaGetQNameRefTargetNs(void *ref)
1384
{
1385
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1386
}
1387
*/
1388
1389
static const xmlChar *
1390
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1391
0
{
1392
0
    if (item == NULL) {
1393
0
        return (NULL);
1394
0
    }
1395
0
    switch (item->type) {
1396
0
  case XML_SCHEMA_TYPE_ELEMENT:
1397
0
      return (((xmlSchemaElementPtr) item)->targetNamespace);
1398
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1399
0
      return (((xmlSchemaAttributePtr) item)->targetNamespace);
1400
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1401
0
      return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1402
0
  case XML_SCHEMA_TYPE_BASIC:
1403
0
      return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1404
0
  case XML_SCHEMA_TYPE_SIMPLE:
1405
0
  case XML_SCHEMA_TYPE_COMPLEX:
1406
0
      return (((xmlSchemaTypePtr) item)->targetNamespace);
1407
0
  case XML_SCHEMA_TYPE_GROUP:
1408
0
      return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1409
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1410
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1411
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1412
0
      return (((xmlSchemaIDCPtr) item)->targetNamespace);
1413
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1414
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1415
0
    return(xmlSchemaGetComponentTargetNs(
1416
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1417
0
      }
1418
      /* TODO: Will returning NULL break something? */
1419
0
      break;
1420
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1421
0
      return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1422
0
  case XML_SCHEMA_TYPE_NOTATION:
1423
0
      return (((xmlSchemaNotationPtr) item)->targetNamespace);
1424
0
  default:
1425
      /*
1426
      * Other components cannot have names.
1427
      */
1428
0
      break;
1429
0
    }
1430
0
    return (NULL);
1431
0
}
1432
1433
static const xmlChar*
1434
xmlSchemaGetComponentQName(xmlChar **buf,
1435
         void *item)
1436
0
{
1437
0
    return (xmlSchemaFormatQName(buf,
1438
0
  xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1439
0
  xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1440
0
}
1441
1442
static const xmlChar*
1443
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1444
0
{
1445
0
    xmlChar *str = NULL;
1446
1447
0
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1448
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1449
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1450
0
  (xmlSchemaBasicItemPtr) item));
1451
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1452
0
    FREE_AND_NULL(str);
1453
0
    return(*buf);
1454
0
}
1455
1456
static const xmlChar*
1457
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1458
0
{
1459
0
    return(xmlSchemaGetComponentDesignation(buf, idc));
1460
0
}
1461
1462
/**
1463
 * xmlSchemaWildcardPCToString:
1464
 * @pc: the type of processContents
1465
 *
1466
 * Returns a string representation of the type of
1467
 * processContents.
1468
 */
1469
static const xmlChar *
1470
xmlSchemaWildcardPCToString(int pc)
1471
0
{
1472
0
    switch (pc) {
1473
0
  case XML_SCHEMAS_ANY_SKIP:
1474
0
      return (BAD_CAST "skip");
1475
0
  case XML_SCHEMAS_ANY_LAX:
1476
0
      return (BAD_CAST "lax");
1477
0
  case XML_SCHEMAS_ANY_STRICT:
1478
0
      return (BAD_CAST "strict");
1479
0
  default:
1480
0
      return (BAD_CAST "invalid process contents");
1481
0
    }
1482
0
}
1483
1484
/**
1485
 * xmlSchemaGetCanonValueWhtspExt:
1486
 * @val: the precomputed value
1487
 * @retValue: the returned value
1488
 * @ws: the whitespace type of the value
1489
 * @for_hash: non-zero if this is supposed to generate a string for hashing
1490
 *
1491
 * Get a the canonical representation of the value.
1492
 * The caller has to free the returned retValue.
1493
 *
1494
 * Returns 0 if the value could be built and -1 in case of
1495
 *         API errors or if the value type is not supported yet.
1496
 */
1497
static int
1498
xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1499
               xmlSchemaWhitespaceValueType ws,
1500
               xmlChar **retValue,
1501
         int for_hash)
1502
0
{
1503
0
    int list;
1504
0
    xmlSchemaValType valType;
1505
0
    const xmlChar *value, *value2 = NULL;
1506
1507
1508
0
    if ((retValue == NULL) || (val == NULL))
1509
0
  return (-1);
1510
0
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1511
0
    *retValue = NULL;
1512
0
    do {
1513
0
  value = NULL;
1514
0
  valType = xmlSchemaGetValType(val);
1515
0
  switch (valType) {
1516
0
      case XML_SCHEMAS_STRING:
1517
0
      case XML_SCHEMAS_NORMSTRING:
1518
0
      case XML_SCHEMAS_ANYSIMPLETYPE:
1519
0
    value = xmlSchemaValueGetAsString(val);
1520
0
    if (value != NULL) {
1521
0
        if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1522
0
      value2 = xmlSchemaCollapseString(value);
1523
0
        else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1524
0
      value2 = xmlSchemaWhiteSpaceReplace(value);
1525
0
        if (value2 != NULL)
1526
0
      value = value2;
1527
0
    }
1528
0
    break;
1529
0
      default:
1530
0
    if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1531
0
        if (value2 != NULL)
1532
0
      xmlFree((xmlChar *) value2);
1533
0
        goto internal_error;
1534
0
    }
1535
0
    if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1536
        /* We can mostly use the canonical value for hashing,
1537
           except in the case of decimal.  There the canonical
1538
           representation requires a trailing '.0' even for
1539
           non-fractional numbers, but for the derived integer
1540
           types it forbids any decimal point.  Nevertheless they
1541
           compare equal if the value is equal.  We need to generate
1542
           the same hash value for this to work, and it's easiest
1543
           to just cut off the useless '.0' suffix for the
1544
           decimal type.  */
1545
0
        int len = xmlStrlen(value2);
1546
0
        if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1547
0
          ((xmlChar*)value2)[len-2] = 0;
1548
0
    }
1549
0
    value = value2;
1550
0
  }
1551
0
  if (*retValue == NULL)
1552
0
      if (value == NULL) {
1553
0
    if (! list)
1554
0
        *retValue = xmlStrdup(BAD_CAST "");
1555
0
      } else
1556
0
    *retValue = xmlStrdup(value);
1557
0
  else if (value != NULL) {
1558
      /* List. */
1559
0
      *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1560
0
      *retValue = xmlStrcat((xmlChar *) *retValue, value);
1561
0
  }
1562
0
  FREE_AND_NULL(value2)
1563
0
  val = xmlSchemaValueGetNext(val);
1564
0
    } while (val != NULL);
1565
1566
0
    return (0);
1567
0
internal_error:
1568
0
    if (*retValue != NULL)
1569
0
  xmlFree((xmlChar *) (*retValue));
1570
0
    if (value2 != NULL)
1571
0
  xmlFree((xmlChar *) value2);
1572
0
    return (-1);
1573
0
}
1574
1575
static int
1576
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1577
             xmlSchemaWhitespaceValueType ws,
1578
             xmlChar **retValue)
1579
0
{
1580
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1581
0
}
1582
1583
static int
1584
xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1585
         xmlChar **retValue)
1586
0
{
1587
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1588
0
              retValue, 1);
1589
0
}
1590
1591
/**
1592
 * xmlSchemaFormatItemForReport:
1593
 * @buf: the string buffer
1594
 * @itemDes: the designation of the item
1595
 * @itemName: the name of the item
1596
 * @item: the item as an object
1597
 * @itemNode: the node of the item
1598
 * @local: the local name
1599
 * @parsing: if the function is used during the parse
1600
 *
1601
 * Returns a representation of the given item used
1602
 * for error reports.
1603
 *
1604
 * The following order is used to build the resulting
1605
 * designation if the arguments are not NULL:
1606
 * 1a. If itemDes not NULL -> itemDes
1607
 * 1b. If (itemDes not NULL) and (itemName not NULL)
1608
 *     -> itemDes + itemName
1609
 * 2. If the preceding was NULL and (item not NULL) -> item
1610
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1611
 *
1612
 * If the itemNode is an attribute node, the name of the attribute
1613
 * will be appended to the result.
1614
 *
1615
 * Returns the formatted string and sets @buf to the resulting value.
1616
 */
1617
static xmlChar*
1618
xmlSchemaFormatItemForReport(xmlChar **buf,
1619
         const xmlChar *itemDes,
1620
         xmlSchemaBasicItemPtr item,
1621
         xmlNodePtr itemNode)
1622
0
{
1623
0
    xmlChar *str = NULL;
1624
0
    int named = 1;
1625
1626
0
    if (*buf != NULL) {
1627
0
  xmlFree(*buf);
1628
0
  *buf = NULL;
1629
0
    }
1630
1631
0
    if (itemDes != NULL) {
1632
0
  *buf = xmlStrdup(itemDes);
1633
0
    } else if (item != NULL) {
1634
0
  switch (item->type) {
1635
0
  case XML_SCHEMA_TYPE_BASIC: {
1636
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1637
1638
0
      if (WXS_IS_ATOMIC(type))
1639
0
    *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1640
0
      else if (WXS_IS_LIST(type))
1641
0
    *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1642
0
      else if (WXS_IS_UNION(type))
1643
0
    *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1644
0
      else
1645
0
    *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1646
0
      *buf = xmlStrcat(*buf, type->name);
1647
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1648
0
      }
1649
0
      break;
1650
0
  case XML_SCHEMA_TYPE_SIMPLE: {
1651
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1652
1653
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1654
0
    *buf = xmlStrdup(BAD_CAST"");
1655
0
      } else {
1656
0
    *buf = xmlStrdup(BAD_CAST "local ");
1657
0
      }
1658
0
      if (WXS_IS_ATOMIC(type))
1659
0
    *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1660
0
      else if (WXS_IS_LIST(type))
1661
0
    *buf = xmlStrcat(*buf, BAD_CAST "list type");
1662
0
      else if (WXS_IS_UNION(type))
1663
0
    *buf = xmlStrcat(*buf, BAD_CAST "union type");
1664
0
      else
1665
0
    *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1666
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1667
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1668
0
    *buf = xmlStrcat(*buf, type->name);
1669
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1670
0
      }
1671
0
      }
1672
0
      break;
1673
0
  case XML_SCHEMA_TYPE_COMPLEX: {
1674
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1675
1676
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1677
0
    *buf = xmlStrdup(BAD_CAST "");
1678
0
      else
1679
0
    *buf = xmlStrdup(BAD_CAST "local ");
1680
0
      *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1681
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1682
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1683
0
    *buf = xmlStrcat(*buf, type->name);
1684
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1685
0
      }
1686
0
      }
1687
0
      break;
1688
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1689
0
    xmlSchemaAttributeUsePtr ause;
1690
1691
0
    ause = WXS_ATTR_USE_CAST item;
1692
0
    *buf = xmlStrdup(BAD_CAST "attribute use ");
1693
0
    if (WXS_ATTRUSE_DECL(ause) != NULL) {
1694
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1695
0
        *buf = xmlStrcat(*buf,
1696
0
      xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1697
0
        FREE_AND_NULL(str)
1698
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1699
0
    } else {
1700
0
        *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1701
0
    }
1702
0
      }
1703
0
      break;
1704
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
1705
0
    xmlSchemaAttributePtr attr;
1706
1707
0
    attr = (xmlSchemaAttributePtr) item;
1708
0
    *buf = xmlStrdup(BAD_CAST "attribute decl.");
1709
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1710
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1711
0
        attr->targetNamespace, attr->name));
1712
0
    FREE_AND_NULL(str)
1713
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1714
0
      }
1715
0
      break;
1716
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1717
0
      xmlSchemaGetComponentDesignation(buf, item);
1718
0
      break;
1719
0
  case XML_SCHEMA_TYPE_ELEMENT: {
1720
0
    xmlSchemaElementPtr elem;
1721
1722
0
    elem = (xmlSchemaElementPtr) item;
1723
0
    *buf = xmlStrdup(BAD_CAST "element decl.");
1724
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1725
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1726
0
        elem->targetNamespace, elem->name));
1727
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1728
0
      }
1729
0
      break;
1730
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1731
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1732
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1733
0
      if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1734
0
    *buf = xmlStrdup(BAD_CAST "unique '");
1735
0
      else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1736
0
    *buf = xmlStrdup(BAD_CAST "key '");
1737
0
      else
1738
0
    *buf = xmlStrdup(BAD_CAST "keyRef '");
1739
0
      *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1740
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1741
0
      break;
1742
0
  case XML_SCHEMA_TYPE_ANY:
1743
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1744
0
      *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1745
0
        ((xmlSchemaWildcardPtr) item)->processContents));
1746
0
      *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1747
0
      break;
1748
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
1749
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
1750
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
1751
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1752
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
1753
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
1754
0
  case XML_SCHEMA_FACET_PATTERN:
1755
0
  case XML_SCHEMA_FACET_ENUMERATION:
1756
0
  case XML_SCHEMA_FACET_WHITESPACE:
1757
0
  case XML_SCHEMA_FACET_LENGTH:
1758
0
  case XML_SCHEMA_FACET_MAXLENGTH:
1759
0
  case XML_SCHEMA_FACET_MINLENGTH:
1760
0
      *buf = xmlStrdup(BAD_CAST "facet '");
1761
0
      *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1762
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1763
0
      break;
1764
0
  case XML_SCHEMA_TYPE_GROUP: {
1765
0
    *buf = xmlStrdup(BAD_CAST "model group def.");
1766
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1767
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1768
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1769
0
    FREE_AND_NULL(str)
1770
0
      }
1771
0
      break;
1772
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1773
0
  case XML_SCHEMA_TYPE_CHOICE:
1774
0
  case XML_SCHEMA_TYPE_ALL:
1775
0
  case XML_SCHEMA_TYPE_PARTICLE:
1776
0
      *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1777
0
      break;
1778
0
  case XML_SCHEMA_TYPE_NOTATION: {
1779
0
    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1780
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1781
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1782
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1783
0
    FREE_AND_NULL(str);
1784
0
      }
1785
            /* Falls through. */
1786
0
  default:
1787
0
      named = 0;
1788
0
  }
1789
0
    } else
1790
0
  named = 0;
1791
1792
0
    if ((named == 0) && (itemNode != NULL)) {
1793
0
  xmlNodePtr elem;
1794
1795
0
  if (itemNode->type == XML_ATTRIBUTE_NODE)
1796
0
      elem = itemNode->parent;
1797
0
  else
1798
0
      elem = itemNode;
1799
0
  *buf = xmlStrdup(BAD_CAST "Element '");
1800
0
  if (elem->ns != NULL) {
1801
0
      *buf = xmlStrcat(*buf,
1802
0
    xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1803
0
      FREE_AND_NULL(str)
1804
0
  } else
1805
0
      *buf = xmlStrcat(*buf, elem->name);
1806
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1807
1808
0
    }
1809
0
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1810
0
  *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1811
0
  if (itemNode->ns != NULL) {
1812
0
      *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1813
0
    itemNode->ns->href, itemNode->name));
1814
0
      FREE_AND_NULL(str)
1815
0
  } else
1816
0
      *buf = xmlStrcat(*buf, itemNode->name);
1817
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1818
0
    }
1819
0
    FREE_AND_NULL(str)
1820
1821
0
    return (xmlEscapeFormatString(buf));
1822
0
}
1823
1824
/**
1825
 * xmlSchemaFormatFacetEnumSet:
1826
 * @buf: the string buffer
1827
 * @type: the type holding the enumeration facets
1828
 *
1829
 * Builds a string consisting of all enumeration elements.
1830
 *
1831
 * Returns a string of all enumeration elements.
1832
 */
1833
static const xmlChar *
1834
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1835
          xmlChar **buf, xmlSchemaTypePtr type)
1836
0
{
1837
0
    xmlSchemaFacetPtr facet;
1838
0
    xmlSchemaWhitespaceValueType ws;
1839
0
    xmlChar *value = NULL;
1840
0
    int res, found = 0;
1841
1842
0
    if (*buf != NULL)
1843
0
  xmlFree(*buf);
1844
0
    *buf = NULL;
1845
1846
0
    do {
1847
  /*
1848
  * Use the whitespace type of the base type.
1849
  */
1850
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1851
0
  for (facet = type->facets; facet != NULL; facet = facet->next) {
1852
0
      if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1853
0
    continue;
1854
0
      found = 1;
1855
0
      res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1856
0
    ws, &value);
1857
0
      if (res == -1) {
1858
0
    xmlSchemaInternalErr(actxt,
1859
0
        "xmlSchemaFormatFacetEnumSet",
1860
0
        "compute the canonical lexical representation");
1861
0
    if (*buf != NULL)
1862
0
        xmlFree(*buf);
1863
0
    *buf = NULL;
1864
0
    return (NULL);
1865
0
      }
1866
0
      if (*buf == NULL)
1867
0
    *buf = xmlStrdup(BAD_CAST "'");
1868
0
      else
1869
0
    *buf = xmlStrcat(*buf, BAD_CAST ", '");
1870
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
1871
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1872
0
      if (value != NULL) {
1873
0
    xmlFree((xmlChar *)value);
1874
0
    value = NULL;
1875
0
      }
1876
0
  }
1877
  /*
1878
  * The enumeration facet of a type restricts the enumeration
1879
  * facet of the ancestor type; i.e., such restricted enumerations
1880
  * do not belong to the set of the given type. Thus we break
1881
  * on the first found enumeration.
1882
  */
1883
0
  if (found)
1884
0
      break;
1885
0
  type = type->baseType;
1886
0
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1887
1888
0
    return ((const xmlChar *) *buf);
1889
0
}
1890
1891
/************************************************************************
1892
 *                  *
1893
 *      Error functions               *
1894
 *                  *
1895
 ************************************************************************/
1896
1897
/**
1898
 * xmlSchemaPErrMemory:
1899
 * @node: a context node
1900
 * @extra:  extra information
1901
 *
1902
 * Handle an out of memory condition
1903
 */
1904
static void
1905
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt)
1906
0
{
1907
0
    xmlGenericErrorFunc channel = NULL;
1908
0
    xmlStructuredErrorFunc schannel = NULL;
1909
0
    void *data = NULL;
1910
1911
0
    if (ctxt != NULL) {
1912
0
        ctxt->nberrors++;
1913
0
        ctxt->err = XML_ERR_NO_MEMORY;
1914
0
        channel = ctxt->error;
1915
0
        schannel = ctxt->serror;
1916
0
        data = ctxt->errCtxt;
1917
0
    }
1918
1919
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASP, NULL);
1920
0
}
1921
1922
static void LIBXML_ATTR_FORMAT(11,12)
1923
xmlSchemaPErrFull(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1924
                  xmlErrorLevel level, const char *file, int line,
1925
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
1926
0
                  int col, const char *msg, ...) {
1927
0
    xmlGenericErrorFunc channel = NULL;
1928
0
    xmlStructuredErrorFunc schannel = NULL;
1929
0
    void *data = NULL;
1930
0
    int res;
1931
0
    va_list ap;
1932
1933
0
    if (ctxt != NULL) {
1934
        /* Don't overwrite memory errors */
1935
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
1936
0
            return;
1937
1938
0
        if (level == XML_ERR_WARNING) {
1939
0
            channel = ctxt->warning;
1940
0
        } else {
1941
0
            ctxt->nberrors++;
1942
0
            ctxt->err = code;
1943
0
            channel = ctxt->error;
1944
0
        }
1945
0
        data = ctxt->errCtxt;
1946
0
        schannel = ctxt->serror;
1947
0
    }
1948
1949
0
    if ((channel == NULL) && (schannel == NULL)) {
1950
0
        channel = xmlGenericError;
1951
0
        data = xmlGenericErrorContext;
1952
0
    }
1953
1954
0
    va_start(ap, msg);
1955
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
1956
0
                         XML_FROM_SCHEMASP, code, level, file, line,
1957
0
                         (const char *) str1,
1958
0
                         (const char *) str2,
1959
0
                         (const char *) str3,
1960
0
                         0, col, msg, ap);
1961
0
    va_end(ap);
1962
1963
0
    if (res < 0)
1964
0
        xmlSchemaPErrMemory(ctxt);
1965
0
}
1966
1967
/**
1968
 * xmlSchemaPErr:
1969
 * @ctxt: the parsing context
1970
 * @node: the context node
1971
 * @error: the error code
1972
 * @msg: the error message
1973
 * @str1: extra data
1974
 * @str2: extra data
1975
 *
1976
 * Handle a parser error
1977
 */
1978
static void LIBXML_ATTR_FORMAT(4,0)
1979
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1980
              const char *msg, const xmlChar * str1, const xmlChar * str2)
1981
0
{
1982
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
1983
0
                      str1, str2, NULL, 0, msg, str1, str2);
1984
0
}
1985
1986
/**
1987
 * xmlSchemaPErr2:
1988
 * @ctxt: the parsing context
1989
 * @node: the context node
1990
 * @node: the current child
1991
 * @error: the error code
1992
 * @msg: the error message
1993
 * @str1: extra data
1994
 * @str2: extra data
1995
 *
1996
 * Handle a parser error
1997
 */
1998
static void LIBXML_ATTR_FORMAT(5,0)
1999
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
2000
               xmlNodePtr child, int error,
2001
               const char *msg, const xmlChar * str1, const xmlChar * str2)
2002
0
{
2003
0
    if (child != NULL)
2004
0
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
2005
0
    else
2006
0
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
2007
0
}
2008
2009
2010
/**
2011
 * xmlSchemaPErrExt:
2012
 * @ctxt: the parsing context
2013
 * @node: the context node
2014
 * @error: the error code
2015
 * @strData1: extra data
2016
 * @strData2: extra data
2017
 * @strData3: extra data
2018
 * @msg: the message
2019
 * @str1:  extra parameter for the message display
2020
 * @str2:  extra parameter for the message display
2021
 * @str3:  extra parameter for the message display
2022
 * @str4:  extra parameter for the message display
2023
 * @str5:  extra parameter for the message display
2024
 *
2025
 * Handle a parser error
2026
 */
2027
static void LIBXML_ATTR_FORMAT(7,0)
2028
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
2029
    const xmlChar * strData1, const xmlChar * strData2,
2030
    const xmlChar * strData3, const char *msg, const xmlChar * str1,
2031
    const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2032
    const xmlChar * str5)
2033
0
{
2034
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
2035
0
                      strData1, strData2, strData3, 0,
2036
0
                      msg, str1, str2, str3, str4, str5);
2037
0
}
2038
2039
/************************************************************************
2040
 *                  *
2041
 *      Allround error functions      *
2042
 *                  *
2043
 ************************************************************************/
2044
2045
/**
2046
 * xmlSchemaVTypeErrMemory:
2047
 * @node: a context node
2048
 * @extra:  extra information
2049
 *
2050
 * Handle an out of memory condition
2051
 */
2052
static void
2053
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt)
2054
0
{
2055
0
    xmlGenericErrorFunc channel = NULL;
2056
0
    xmlStructuredErrorFunc schannel = NULL;
2057
0
    void *data = NULL;
2058
2059
0
    if (ctxt != NULL) {
2060
0
        ctxt->nberrors++;
2061
0
        ctxt->err = XML_ERR_NO_MEMORY;
2062
0
        channel = ctxt->error;
2063
0
        schannel = ctxt->serror;
2064
0
        data = ctxt->errCtxt;
2065
0
    }
2066
2067
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASV, NULL);
2068
0
}
2069
2070
static void LIBXML_ATTR_FORMAT(11,12)
2071
xmlSchemaVErrFull(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int code,
2072
                  xmlErrorLevel level, const char *file, int line,
2073
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
2074
0
                  int col, const char *msg, ...) {
2075
0
    xmlGenericErrorFunc channel = NULL;
2076
0
    xmlStructuredErrorFunc schannel = NULL;
2077
0
    void *data = NULL;
2078
0
    int res;
2079
0
    va_list ap;
2080
2081
0
    if (ctxt != NULL) {
2082
        /* Don't overwrite memory errors */
2083
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
2084
0
            return;
2085
2086
0
        if (level == XML_ERR_WARNING) {
2087
0
            channel = ctxt->warning;
2088
0
        } else {
2089
0
            ctxt->nberrors++;
2090
0
            ctxt->err = code;
2091
0
            channel = ctxt->error;
2092
0
        }
2093
0
        data = ctxt->errCtxt;
2094
0
        schannel = ctxt->serror;
2095
0
    }
2096
2097
0
    if ((channel == NULL) && (schannel == NULL)) {
2098
0
        channel = xmlGenericError;
2099
0
        data = xmlGenericErrorContext;
2100
0
    }
2101
2102
0
    va_start(ap, msg);
2103
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
2104
0
                         XML_FROM_SCHEMASV, code, level, file, line,
2105
0
                         (const char *) str1,
2106
0
                         (const char *) str2,
2107
0
                         (const char *) str3,
2108
0
                         0, col, msg, ap);
2109
0
    va_end(ap);
2110
2111
0
    if (res < 0)
2112
0
        xmlSchemaVErrMemory(ctxt);
2113
0
}
2114
2115
#define WXS_ERROR_TYPE_ERROR 1
2116
#define WXS_ERROR_TYPE_WARNING 2
2117
/**
2118
 * xmlSchemaErr4Line:
2119
 * @ctxt: the validation context
2120
 * @errorLevel: the error level
2121
 * @error: the error code
2122
 * @node: the context node
2123
 * @line: the line number
2124
 * @msg: the error message
2125
 * @str1: extra data
2126
 * @str2: extra data
2127
 * @str3: extra data
2128
 * @str4: extra data
2129
 *
2130
 * Handle a validation error
2131
 */
2132
static void LIBXML_ATTR_FORMAT(6,0)
2133
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2134
      xmlErrorLevel errorLevel,
2135
      int code, xmlNodePtr node, int line, const char *msg,
2136
      const xmlChar *str1, const xmlChar *str2,
2137
      const xmlChar *str3, const xmlChar *str4)
2138
0
{
2139
0
    if (ctxt != NULL) {
2140
0
  if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2141
0
      xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2142
0
      const char *file = NULL;
2143
0
      int col = 0;
2144
2145
      /*
2146
      * Error node. If we specify a line number, then
2147
      * do not channel any node to the error function.
2148
      */
2149
0
      if (line == 0) {
2150
0
    if ((node == NULL) &&
2151
0
        (vctxt->depth >= 0) &&
2152
0
        (vctxt->inode != NULL)) {
2153
0
        node = vctxt->inode->node;
2154
0
    }
2155
    /*
2156
    * Get filename and line if no node-tree.
2157
    */
2158
0
    if ((node == NULL) &&
2159
0
        (vctxt->parserCtxt != NULL) &&
2160
0
        (vctxt->parserCtxt->input != NULL)) {
2161
0
        file = vctxt->parserCtxt->input->filename;
2162
0
                    if (vctxt->inode != NULL) {
2163
0
            line = vctxt->inode->nodeLine;
2164
0
                        col = 0;
2165
0
                    } else {
2166
                        /* This is inaccurate. */
2167
0
            line = vctxt->parserCtxt->input->line;
2168
0
            col = vctxt->parserCtxt->input->col;
2169
0
                    }
2170
0
    }
2171
0
      } else {
2172
    /*
2173
    * Override the given node's (if any) position
2174
    * and channel only the given line number.
2175
    */
2176
0
    node = NULL;
2177
    /*
2178
    * Get filename.
2179
    */
2180
0
    if (vctxt->doc != NULL)
2181
0
        file = (const char *) vctxt->doc->URL;
2182
0
    else if ((vctxt->parserCtxt != NULL) &&
2183
0
        (vctxt->parserCtxt->input != NULL))
2184
0
        file = vctxt->parserCtxt->input->filename;
2185
0
      }
2186
0
      if (vctxt->locFunc != NULL) {
2187
0
          if ((file == NULL) || (line == 0)) {
2188
0
        unsigned long l;
2189
0
        const char *f;
2190
0
        vctxt->locFunc(vctxt->locCtxt, &f, &l);
2191
0
        if (file == NULL)
2192
0
            file = f;
2193
0
        if (line == 0)
2194
0
            line = (int) l;
2195
0
    }
2196
0
      }
2197
0
      if ((file == NULL) && (vctxt->filename != NULL))
2198
0
          file = vctxt->filename;
2199
2200
0
            xmlSchemaVErrFull(vctxt, node, code, errorLevel,
2201
0
                              file, line, str1, str2, str3, col,
2202
0
                              msg, str1, str2, str3, str4);
2203
0
  } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2204
0
      xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2205
2206
0
            xmlSchemaPErrFull(pctxt, node, code, errorLevel,
2207
0
                              NULL, 0, str1, str2, str3, 0,
2208
0
                              msg, str1, str2, str3, str4);
2209
0
  }
2210
0
    }
2211
0
}
2212
2213
/**
2214
 * xmlSchemaErr3:
2215
 * @ctxt: the validation context
2216
 * @node: the context node
2217
 * @error: the error code
2218
 * @msg: the error message
2219
 * @str1: extra data
2220
 * @str2: extra data
2221
 * @str3: extra data
2222
 *
2223
 * Handle a validation error
2224
 */
2225
static void LIBXML_ATTR_FORMAT(4,0)
2226
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2227
        int error, xmlNodePtr node, const char *msg,
2228
        const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2229
0
{
2230
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2231
0
  msg, str1, str2, str3, NULL);
2232
0
}
2233
2234
static void LIBXML_ATTR_FORMAT(4,0)
2235
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2236
        int error, xmlNodePtr node, const char *msg,
2237
        const xmlChar *str1, const xmlChar *str2,
2238
        const xmlChar *str3, const xmlChar *str4)
2239
0
{
2240
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2241
0
  msg, str1, str2, str3, str4);
2242
0
}
2243
2244
static void LIBXML_ATTR_FORMAT(4,0)
2245
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2246
       int error, xmlNodePtr node, const char *msg,
2247
       const xmlChar *str1, const xmlChar *str2)
2248
0
{
2249
0
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2250
0
}
2251
2252
static xmlChar *
2253
xmlSchemaFormatNodeForError(xmlChar ** msg,
2254
          xmlSchemaAbstractCtxtPtr actxt,
2255
          xmlNodePtr node)
2256
0
{
2257
0
    xmlChar *str = NULL;
2258
2259
0
    *msg = NULL;
2260
0
    if ((node != NULL) &&
2261
0
  (node->type != XML_ELEMENT_NODE) &&
2262
0
  (node->type != XML_ATTRIBUTE_NODE))
2263
0
    {
2264
  /*
2265
  * Don't try to format other nodes than element and
2266
  * attribute nodes.
2267
  * Play safe and return an empty string.
2268
  */
2269
0
  *msg = xmlStrdup(BAD_CAST "");
2270
0
  return(*msg);
2271
0
    }
2272
0
    if (node != NULL) {
2273
  /*
2274
  * Work on tree nodes.
2275
  */
2276
0
  if (node->type == XML_ATTRIBUTE_NODE) {
2277
0
      xmlNodePtr elem = node->parent;
2278
2279
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2280
0
      if (elem->ns != NULL)
2281
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2282
0
        elem->ns->href, elem->name));
2283
0
      else
2284
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2285
0
        NULL, elem->name));
2286
0
      FREE_AND_NULL(str);
2287
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2288
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2289
0
  } else {
2290
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2291
0
  }
2292
0
  if (node->ns != NULL)
2293
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2294
0
      node->ns->href, node->name));
2295
0
  else
2296
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2297
0
      NULL, node->name));
2298
0
  FREE_AND_NULL(str);
2299
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2300
0
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2301
0
  xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2302
  /*
2303
  * Work on node infos.
2304
  */
2305
0
  if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2306
0
      xmlSchemaNodeInfoPtr ielem =
2307
0
    vctxt->elemInfos[vctxt->depth];
2308
2309
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2310
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2311
0
    ielem->nsName, ielem->localName));
2312
0
      FREE_AND_NULL(str);
2313
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2314
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2315
0
  } else {
2316
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2317
0
  }
2318
0
  *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2319
0
      vctxt->inode->nsName, vctxt->inode->localName));
2320
0
  FREE_AND_NULL(str);
2321
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2322
0
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2323
  /*
2324
  * Hmm, no node while parsing?
2325
  * Return an empty string, in case NULL will break something.
2326
  */
2327
0
  *msg = xmlStrdup(BAD_CAST "");
2328
0
    } else {
2329
  /* TODO */
2330
0
  return (NULL);
2331
0
    }
2332
2333
    /*
2334
     * xmlSchemaFormatItemForReport() also returns an escaped format
2335
     * string, so do this before calling it below (in the future).
2336
     */
2337
0
    xmlEscapeFormatString(msg);
2338
2339
    /*
2340
    * VAL TODO: The output of the given schema component is currently
2341
    * disabled.
2342
    */
2343
#if 0
2344
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2345
  *msg = xmlStrcat(*msg, BAD_CAST " [");
2346
  *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2347
      NULL, type, NULL, 0));
2348
  FREE_AND_NULL(str)
2349
  *msg = xmlStrcat(*msg, BAD_CAST "]");
2350
    }
2351
#endif
2352
0
    return (*msg);
2353
0
}
2354
2355
static void LIBXML_ATTR_FORMAT(3,0)
2356
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2357
         const char *funcName,
2358
         const char *message,
2359
         const xmlChar *str1,
2360
         const xmlChar *str2)
2361
0
{
2362
0
    xmlChar *msg = NULL;
2363
2364
0
    if (actxt == NULL)
2365
0
        return;
2366
0
    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2367
0
    msg = xmlStrcat(msg, BAD_CAST message);
2368
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2369
2370
0
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2371
0
  xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2372
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2373
0
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2374
0
  xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2375
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2376
2377
0
    FREE_AND_NULL(msg)
2378
0
}
2379
2380
static void LIBXML_ATTR_FORMAT(3,0)
2381
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2382
         const char *funcName,
2383
         const char *message)
2384
0
{
2385
0
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2386
0
}
2387
2388
#if 0
2389
static void LIBXML_ATTR_FORMAT(3,0)
2390
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2391
         const char *funcName,
2392
         const char *message,
2393
         const xmlChar *str1,
2394
         const xmlChar *str2)
2395
{
2396
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2397
  str1, str2);
2398
}
2399
#endif
2400
2401
static void LIBXML_ATTR_FORMAT(5,0)
2402
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2403
       xmlParserErrors error,
2404
       xmlNodePtr node,
2405
       xmlSchemaBasicItemPtr item,
2406
       const char *message,
2407
       const xmlChar *str1, const xmlChar *str2,
2408
       const xmlChar *str3, const xmlChar *str4)
2409
0
{
2410
0
    xmlChar *msg = NULL;
2411
2412
0
    if ((node == NULL) && (item != NULL) &&
2413
0
  (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2414
0
  node = WXS_ITEM_NODE(item);
2415
0
  xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2416
0
  msg = xmlStrcat(msg, BAD_CAST ": ");
2417
0
    } else
2418
0
  xmlSchemaFormatNodeForError(&msg, actxt, node);
2419
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2420
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2421
0
    xmlSchemaErr4(actxt, error, node,
2422
0
  (const char *) msg, str1, str2, str3, str4);
2423
0
    FREE_AND_NULL(msg)
2424
0
}
2425
2426
static void LIBXML_ATTR_FORMAT(5,0)
2427
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2428
       xmlParserErrors error,
2429
       xmlNodePtr node,
2430
       xmlSchemaBasicItemPtr item,
2431
       const char *message,
2432
       const xmlChar *str1,
2433
       const xmlChar *str2)
2434
0
{
2435
0
    xmlSchemaCustomErr4(actxt, error, node, item,
2436
0
  message, str1, str2, NULL, NULL);
2437
0
}
2438
2439
2440
2441
static void LIBXML_ATTR_FORMAT(5,0)
2442
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2443
       xmlParserErrors error,
2444
       xmlNodePtr node,
2445
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2446
       const char *message,
2447
       const xmlChar *str1,
2448
       const xmlChar *str2,
2449
       const xmlChar *str3)
2450
0
{
2451
0
    xmlChar *msg = NULL;
2452
2453
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2454
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2455
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2456
2457
    /* URGENT TODO: Set the error code to something sane. */
2458
0
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2459
0
  (const char *) msg, str1, str2, str3, NULL);
2460
2461
0
    FREE_AND_NULL(msg)
2462
0
}
2463
2464
2465
2466
static void LIBXML_ATTR_FORMAT(5,0)
2467
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2468
       xmlParserErrors error,
2469
       xmlSchemaPSVIIDCNodePtr idcNode,
2470
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2471
       const char *message,
2472
       const xmlChar *str1,
2473
       const xmlChar *str2)
2474
0
{
2475
0
    xmlChar *msg = NULL, *qname = NULL;
2476
2477
0
    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2478
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2479
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2480
0
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2481
0
  error, NULL, idcNode->nodeLine, (const char *) msg,
2482
0
  xmlSchemaFormatQName(&qname,
2483
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2484
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2485
0
  str1, str2, NULL);
2486
0
    FREE_AND_NULL(qname);
2487
0
    FREE_AND_NULL(msg);
2488
0
}
2489
2490
static int
2491
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2492
         xmlNodePtr node)
2493
0
{
2494
0
    if (node != NULL)
2495
0
  return (node->type);
2496
0
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2497
0
  (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2498
0
  return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2499
0
    return (-1);
2500
0
}
2501
2502
static int
2503
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2504
0
{
2505
0
    switch (item->type) {
2506
0
  case XML_SCHEMA_TYPE_COMPLEX:
2507
0
  case XML_SCHEMA_TYPE_SIMPLE:
2508
0
      if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2509
0
    return(1);
2510
0
      break;
2511
0
  case XML_SCHEMA_TYPE_GROUP:
2512
0
      return (1);
2513
0
  case XML_SCHEMA_TYPE_ELEMENT:
2514
0
      if ( ((xmlSchemaElementPtr) item)->flags &
2515
0
    XML_SCHEMAS_ELEM_GLOBAL)
2516
0
    return(1);
2517
0
      break;
2518
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
2519
0
      if ( ((xmlSchemaAttributePtr) item)->flags &
2520
0
    XML_SCHEMAS_ATTR_GLOBAL)
2521
0
    return(1);
2522
0
      break;
2523
  /* Note that attribute groups are always global. */
2524
0
  default:
2525
0
      return(1);
2526
0
    }
2527
0
    return (0);
2528
0
}
2529
2530
static void
2531
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2532
           xmlParserErrors error,
2533
           xmlNodePtr node,
2534
           const xmlChar *value,
2535
           xmlSchemaTypePtr type,
2536
           int displayValue)
2537
0
{
2538
0
    xmlChar *msg = NULL;
2539
2540
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2541
2542
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2543
0
      XML_ATTRIBUTE_NODE))
2544
0
  msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2545
0
    else
2546
0
  msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2547
0
      "value of ");
2548
2549
0
    if (! xmlSchemaIsGlobalItem(type))
2550
0
  msg = xmlStrcat(msg, BAD_CAST "the local ");
2551
0
    else
2552
0
  msg = xmlStrcat(msg, BAD_CAST "the ");
2553
2554
0
    if (WXS_IS_ATOMIC(type))
2555
0
  msg = xmlStrcat(msg, BAD_CAST "atomic type");
2556
0
    else if (WXS_IS_LIST(type))
2557
0
  msg = xmlStrcat(msg, BAD_CAST "list type");
2558
0
    else if (WXS_IS_UNION(type))
2559
0
  msg = xmlStrcat(msg, BAD_CAST "union type");
2560
2561
0
    if (xmlSchemaIsGlobalItem(type)) {
2562
0
  xmlChar *str = NULL;
2563
0
  msg = xmlStrcat(msg, BAD_CAST " '");
2564
0
  if (type->builtInType != 0) {
2565
0
      msg = xmlStrcat(msg, BAD_CAST "xs:");
2566
0
      str = xmlStrdup(type->name);
2567
0
  } else {
2568
0
      const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2569
0
      if (!str)
2570
0
    str = xmlStrdup(qName);
2571
0
  }
2572
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2573
0
  msg = xmlStrcat(msg, BAD_CAST "'");
2574
0
  FREE_AND_NULL(str);
2575
0
    }
2576
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2577
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2578
0
      XML_ATTRIBUTE_NODE))
2579
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2580
0
    else
2581
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2582
0
    FREE_AND_NULL(msg)
2583
0
}
2584
2585
static const xmlChar *
2586
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2587
            xmlSchemaNodeInfoPtr ni,
2588
            xmlNodePtr node)
2589
0
{
2590
0
    if (node != NULL) {
2591
0
  if (node->ns != NULL)
2592
0
      return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2593
0
  else
2594
0
      return (xmlSchemaFormatQName(str, NULL, node->name));
2595
0
    } else if (ni != NULL)
2596
0
  return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2597
0
    return (NULL);
2598
0
}
2599
2600
static void
2601
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2602
      xmlParserErrors error,
2603
      xmlSchemaAttrInfoPtr ni,
2604
      xmlNodePtr node)
2605
0
{
2606
0
    xmlChar *msg = NULL, *str = NULL;
2607
2608
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2609
0
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2610
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2611
0
  xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2612
0
  NULL);
2613
0
    FREE_AND_NULL(str)
2614
0
    FREE_AND_NULL(msg)
2615
0
}
2616
2617
static void LIBXML_ATTR_FORMAT(5,0)
2618
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2619
            xmlParserErrors error,
2620
            xmlNodePtr node,
2621
      xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2622
      const char *message,
2623
      int nbval,
2624
      int nbneg,
2625
      xmlChar **values)
2626
0
{
2627
0
    xmlChar *str = NULL, *msg = NULL;
2628
0
    xmlChar *localName, *nsName;
2629
0
    const xmlChar *cur, *end;
2630
0
    int i;
2631
2632
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2633
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2634
0
    msg = xmlStrcat(msg, BAD_CAST ".");
2635
    /*
2636
    * Note that is does not make sense to report that we have a
2637
    * wildcard here, since the wildcard might be unfolded into
2638
    * multiple transitions.
2639
    */
2640
0
    if (nbval + nbneg > 0) {
2641
0
  if (nbval + nbneg > 1) {
2642
0
      str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2643
0
  } else
2644
0
      str = xmlStrdup(BAD_CAST " Expected is ( ");
2645
0
  nsName = NULL;
2646
2647
0
  for (i = 0; i < nbval + nbneg; i++) {
2648
0
      cur = values[i];
2649
0
      if (cur == NULL)
2650
0
          continue;
2651
0
      if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2652
0
          (cur[3] == ' ')) {
2653
0
    cur += 4;
2654
0
    str = xmlStrcat(str, BAD_CAST "##other");
2655
0
      }
2656
      /*
2657
      * Get the local name.
2658
      */
2659
0
      localName = NULL;
2660
2661
0
      end = cur;
2662
0
      if (*end == '*') {
2663
0
    localName = xmlStrdup(BAD_CAST "*");
2664
0
    end++;
2665
0
      } else {
2666
0
    while ((*end != 0) && (*end != '|'))
2667
0
        end++;
2668
0
    localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2669
0
      }
2670
0
      if (*end != 0) {
2671
0
    end++;
2672
    /*
2673
    * Skip "*|*" if they come with negated expressions, since
2674
    * they represent the same negated wildcard.
2675
    */
2676
0
    if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2677
        /*
2678
        * Get the namespace name.
2679
        */
2680
0
        cur = end;
2681
0
        if (*end == '*') {
2682
0
      nsName = xmlStrdup(BAD_CAST "{*}");
2683
0
        } else {
2684
0
      while (*end != 0)
2685
0
          end++;
2686
2687
0
      if (i >= nbval)
2688
0
          nsName = xmlStrdup(BAD_CAST "{##other:");
2689
0
      else
2690
0
          nsName = xmlStrdup(BAD_CAST "{");
2691
2692
0
      nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2693
0
      nsName = xmlStrcat(nsName, BAD_CAST "}");
2694
0
        }
2695
0
        str = xmlStrcat(str, BAD_CAST nsName);
2696
0
        FREE_AND_NULL(nsName)
2697
0
    } else {
2698
0
        FREE_AND_NULL(localName);
2699
0
        continue;
2700
0
    }
2701
0
      }
2702
0
      str = xmlStrcat(str, BAD_CAST localName);
2703
0
      FREE_AND_NULL(localName);
2704
2705
0
      if (i < nbval + nbneg -1)
2706
0
    str = xmlStrcat(str, BAD_CAST ", ");
2707
0
  }
2708
0
  str = xmlStrcat(str, BAD_CAST " ).\n");
2709
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2710
0
  FREE_AND_NULL(str)
2711
0
    } else
2712
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
2713
0
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2714
0
    xmlFree(msg);
2715
0
}
2716
2717
static void LIBXML_ATTR_FORMAT(8,0)
2718
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2719
      xmlParserErrors error,
2720
      xmlNodePtr node,
2721
      const xmlChar *value,
2722
      unsigned long length,
2723
      xmlSchemaTypePtr type,
2724
      xmlSchemaFacetPtr facet,
2725
      const char *message,
2726
      const xmlChar *str1,
2727
      const xmlChar *str2)
2728
0
{
2729
0
    xmlChar *str = NULL, *msg = NULL;
2730
0
    xmlSchemaTypeType facetType;
2731
0
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2732
2733
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2734
0
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2735
0
  facetType = XML_SCHEMA_FACET_ENUMERATION;
2736
  /*
2737
  * If enumerations are validated, one must not expect the
2738
  * facet to be given.
2739
  */
2740
0
    } else
2741
0
  facetType = facet->type;
2742
0
    msg = xmlStrcat(msg, BAD_CAST "[");
2743
0
    msg = xmlStrcat(msg, BAD_CAST "facet '");
2744
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2745
0
    msg = xmlStrcat(msg, BAD_CAST "'] ");
2746
0
    if (message == NULL) {
2747
  /*
2748
  * Use a default message.
2749
  */
2750
0
  if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2751
0
      (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2752
0
      (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2753
2754
0
      char len[25], actLen[25];
2755
2756
      /* FIXME, TODO: What is the max expected string length of the
2757
      * this value?
2758
      */
2759
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2760
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2761
0
      else
2762
0
    msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2763
2764
0
      snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2765
0
      snprintf(actLen, 24, "%lu", length);
2766
2767
0
      if (facetType == XML_SCHEMA_FACET_LENGTH)
2768
0
    msg = xmlStrcat(msg,
2769
0
    BAD_CAST "this differs from the allowed length of '%s'.\n");
2770
0
      else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2771
0
    msg = xmlStrcat(msg,
2772
0
    BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2773
0
      else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2774
0
    msg = xmlStrcat(msg,
2775
0
    BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2776
2777
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2778
0
    xmlSchemaErr3(actxt, error, node, (const char *) msg,
2779
0
        value, (const xmlChar *) actLen, (const xmlChar *) len);
2780
0
      else
2781
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2782
0
        (const xmlChar *) actLen, (const xmlChar *) len);
2783
2784
0
  } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2785
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2786
0
    "of the set {%s}.\n");
2787
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2788
0
    xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2789
0
  } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2790
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2791
0
    "by the pattern '%s'.\n");
2792
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2793
0
    facet->value);
2794
0
  } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2795
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2796
0
    "minimum value allowed ('%s').\n");
2797
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2798
0
    facet->value);
2799
0
  } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2800
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2801
0
    "maximum value allowed ('%s').\n");
2802
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2803
0
    facet->value);
2804
0
  } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2805
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2806
0
    "'%s'.\n");
2807
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2808
0
    facet->value);
2809
0
  } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2810
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2811
0
    "'%s'.\n");
2812
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2813
0
    facet->value);
2814
0
  } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2815
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2816
0
    "digits than are allowed ('%s').\n");
2817
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2818
0
    facet->value);
2819
0
  } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2820
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2821
0
    "digits than are allowed ('%s').\n");
2822
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2823
0
    facet->value);
2824
0
  } else if (nodeType == XML_ATTRIBUTE_NODE) {
2825
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2826
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2827
0
  } else {
2828
0
      msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2829
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2830
0
  }
2831
0
    } else {
2832
0
  msg = xmlStrcat(msg, (const xmlChar *) message);
2833
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
2834
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2835
0
    }
2836
0
    FREE_AND_NULL(str)
2837
0
    xmlFree(msg);
2838
0
}
2839
2840
#define VERROR(err, type, msg) \
2841
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2842
2843
0
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2844
2845
0
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2846
0
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2847
2848
0
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2849
2850
2851
/**
2852
 * xmlSchemaPMissingAttrErr:
2853
 * @ctxt: the schema validation context
2854
 * @ownerItem: the owner as a schema object
2855
 * @ownerElem: the owner as an element node
2856
 * @node: the parent element node of the missing attribute node
2857
 * @type: the corresponding type of the attribute node
2858
 *
2859
 * Reports an illegal attribute.
2860
 */
2861
static void
2862
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2863
       xmlParserErrors error,
2864
       xmlSchemaBasicItemPtr ownerItem,
2865
       xmlNodePtr ownerElem,
2866
       const char *name,
2867
       const char *message)
2868
0
{
2869
0
    xmlChar *des = NULL;
2870
2871
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2872
2873
0
    if (message != NULL)
2874
0
  xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2875
0
    else
2876
0
  xmlSchemaPErr(ctxt, ownerElem, error,
2877
0
      "%s: The attribute '%s' is required but missing.\n",
2878
0
      BAD_CAST des, BAD_CAST name);
2879
0
    FREE_AND_NULL(des);
2880
0
}
2881
2882
2883
/**
2884
 * xmlSchemaPResCompAttrErr:
2885
 * @ctxt: the schema validation context
2886
 * @error: the error code
2887
 * @ownerItem: the owner as a schema object
2888
 * @ownerElem: the owner as an element node
2889
 * @name: the name of the attribute holding the QName
2890
 * @refName: the referenced local name
2891
 * @refURI: the referenced namespace URI
2892
 * @message: optional message
2893
 *
2894
 * Used to report QName attribute values that failed to resolve
2895
 * to schema components.
2896
 */
2897
static void
2898
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2899
       xmlParserErrors error,
2900
       xmlSchemaBasicItemPtr ownerItem,
2901
       xmlNodePtr ownerElem,
2902
       const char *name,
2903
       const xmlChar *refName,
2904
       const xmlChar *refURI,
2905
       xmlSchemaTypeType refType,
2906
       const char *refTypeStr)
2907
0
{
2908
0
    xmlChar *des = NULL, *strA = NULL;
2909
2910
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2911
0
    if (refTypeStr == NULL)
2912
0
  refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2913
0
    xmlSchemaPErrExt(ctxt, ownerElem, error,
2914
0
      NULL, NULL, NULL,
2915
0
      "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2916
0
      "%s.\n", BAD_CAST des, BAD_CAST name,
2917
0
      xmlSchemaFormatQName(&strA, refURI, refName),
2918
0
      BAD_CAST refTypeStr, NULL);
2919
0
    FREE_AND_NULL(des)
2920
0
    FREE_AND_NULL(strA)
2921
0
}
2922
2923
/**
2924
 * xmlSchemaPCustomAttrErr:
2925
 * @ctxt: the schema parser context
2926
 * @error: the error code
2927
 * @ownerDes: the designation of the owner
2928
 * @ownerItem: the owner as a schema object
2929
 * @attr: the illegal attribute node
2930
 *
2931
 * Reports an illegal attribute during the parse.
2932
 */
2933
static void
2934
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2935
      xmlParserErrors error,
2936
      xmlChar **ownerDes,
2937
      xmlSchemaBasicItemPtr ownerItem,
2938
      xmlAttrPtr attr,
2939
      const char *msg)
2940
0
{
2941
0
    xmlChar *des = NULL;
2942
2943
0
    if (ownerDes == NULL)
2944
0
  xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2945
0
    else if (*ownerDes == NULL) {
2946
0
  xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2947
0
  des = *ownerDes;
2948
0
    } else
2949
0
  des = *ownerDes;
2950
0
    if (attr == NULL) {
2951
0
  xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2952
0
      "%s, attribute '%s': %s.\n",
2953
0
      BAD_CAST des, (const xmlChar *) "Unknown",
2954
0
      (const xmlChar *) msg, NULL, NULL);
2955
0
    } else {
2956
0
  xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2957
0
      "%s, attribute '%s': %s.\n",
2958
0
      BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2959
0
    }
2960
0
    if (ownerDes == NULL)
2961
0
  FREE_AND_NULL(des);
2962
0
}
2963
2964
/**
2965
 * xmlSchemaPIllegalAttrErr:
2966
 * @ctxt: the schema parser context
2967
 * @error: the error code
2968
 * @ownerItem: the attribute's owner item
2969
 * @attr: the illegal attribute node
2970
 *
2971
 * Reports an illegal attribute during the parse.
2972
 */
2973
static void
2974
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2975
       xmlParserErrors error,
2976
       xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2977
       xmlAttrPtr attr)
2978
0
{
2979
0
    xmlChar *strA = NULL, *strB = NULL;
2980
2981
0
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2982
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2983
0
  "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2984
0
  xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2985
0
  NULL, NULL);
2986
0
    FREE_AND_NULL(strA);
2987
0
    FREE_AND_NULL(strB);
2988
0
}
2989
2990
/**
2991
 * xmlSchemaPCustomErr:
2992
 * @ctxt: the schema parser context
2993
 * @error: the error code
2994
 * @itemDes: the designation of the schema item
2995
 * @item: the schema item
2996
 * @itemElem: the node of the schema item
2997
 * @message: the error message
2998
 * @str1: an optional param for the error message
2999
 * @str2: an optional param for the error message
3000
 * @str3: an optional param for the error message
3001
 *
3002
 * Reports an error during parsing.
3003
 */
3004
static void LIBXML_ATTR_FORMAT(5,0)
3005
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
3006
        xmlParserErrors error,
3007
        xmlSchemaBasicItemPtr item,
3008
        xmlNodePtr itemElem,
3009
        const char *message,
3010
        const xmlChar *str1,
3011
        const xmlChar *str2,
3012
        const xmlChar *str3)
3013
0
{
3014
0
    xmlChar *des = NULL, *msg = NULL;
3015
3016
0
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
3017
0
    msg = xmlStrdup(BAD_CAST "%s: ");
3018
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3019
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3020
0
    if ((itemElem == NULL) && (item != NULL))
3021
0
  itemElem = WXS_ITEM_NODE(item);
3022
0
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3023
0
  (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3024
0
    FREE_AND_NULL(des);
3025
0
    FREE_AND_NULL(msg);
3026
0
}
3027
3028
/**
3029
 * xmlSchemaPCustomErr:
3030
 * @ctxt: the schema parser context
3031
 * @error: the error code
3032
 * @itemDes: the designation of the schema item
3033
 * @item: the schema item
3034
 * @itemElem: the node of the schema item
3035
 * @message: the error message
3036
 * @str1: the optional param for the error message
3037
 *
3038
 * Reports an error during parsing.
3039
 */
3040
static void LIBXML_ATTR_FORMAT(5,0)
3041
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3042
        xmlParserErrors error,
3043
        xmlSchemaBasicItemPtr item,
3044
        xmlNodePtr itemElem,
3045
        const char *message,
3046
        const xmlChar *str1)
3047
0
{
3048
0
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3049
0
  str1, NULL, NULL);
3050
0
}
3051
3052
/**
3053
 * xmlSchemaPAttrUseErr:
3054
 * @ctxt: the schema parser context
3055
 * @error: the error code
3056
 * @itemDes: the designation of the schema type
3057
 * @item: the schema type
3058
 * @itemElem: the node of the schema type
3059
 * @attr: the invalid schema attribute
3060
 * @message: the error message
3061
 * @str1: the optional param for the error message
3062
 *
3063
 * Reports an attribute use error during parsing.
3064
 */
3065
static void LIBXML_ATTR_FORMAT(6,0)
3066
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3067
        xmlParserErrors error,
3068
        xmlNodePtr node,
3069
        xmlSchemaBasicItemPtr ownerItem,
3070
        const xmlSchemaAttributeUsePtr attruse,
3071
        const char *message,
3072
        const xmlChar *str1, const xmlChar *str2,
3073
        const xmlChar *str3,const xmlChar *str4)
3074
0
{
3075
0
    xmlChar *str = NULL, *msg = NULL;
3076
3077
0
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3078
0
    msg = xmlStrcat(msg, BAD_CAST ", ");
3079
0
    msg = xmlStrcat(msg,
3080
0
  BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3081
0
  WXS_BASIC_CAST attruse, NULL));
3082
0
    FREE_AND_NULL(str);
3083
0
    msg = xmlStrcat(msg, BAD_CAST ": ");
3084
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3085
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3086
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3087
0
  (const char *) msg, str1, str2, str3, str4);
3088
0
    xmlFree(msg);
3089
0
}
3090
3091
/**
3092
 * xmlSchemaPIllegalFacetAtomicErr:
3093
 * @ctxt: the schema parser context
3094
 * @error: the error code
3095
 * @type: the schema type
3096
 * @baseType: the base type of type
3097
 * @facet: the illegal facet
3098
 *
3099
 * Reports an illegal facet for atomic simple types.
3100
 */
3101
static void
3102
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3103
        xmlParserErrors error,
3104
        xmlSchemaTypePtr type,
3105
        xmlSchemaTypePtr baseType,
3106
        xmlSchemaFacetPtr facet)
3107
0
{
3108
0
    xmlChar *des = NULL, *strT = NULL;
3109
3110
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3111
0
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3112
0
  "%s: The facet '%s' is not allowed on types derived from the "
3113
0
  "type %s.\n",
3114
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3115
0
  xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3116
0
  NULL, NULL);
3117
0
    FREE_AND_NULL(des);
3118
0
    FREE_AND_NULL(strT);
3119
0
}
3120
3121
/**
3122
 * xmlSchemaPIllegalFacetListUnionErr:
3123
 * @ctxt: the schema parser context
3124
 * @error: the error code
3125
 * @itemDes: the designation of the schema item involved
3126
 * @item: the schema item involved
3127
 * @facet: the illegal facet
3128
 *
3129
 * Reports an illegal facet for <list> and <union>.
3130
 */
3131
static void
3132
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3133
        xmlParserErrors error,
3134
        xmlSchemaTypePtr type,
3135
        xmlSchemaFacetPtr facet)
3136
0
{
3137
0
    xmlChar *des = NULL;
3138
3139
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3140
0
  type->node);
3141
0
    xmlSchemaPErr(ctxt, type->node, error,
3142
0
  "%s: The facet '%s' is not allowed.\n",
3143
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3144
0
    FREE_AND_NULL(des);
3145
0
}
3146
3147
/**
3148
 * xmlSchemaPMutualExclAttrErr:
3149
 * @ctxt: the schema validation context
3150
 * @error: the error code
3151
 * @elemDes: the designation of the parent element node
3152
 * @attr: the bad attribute node
3153
 * @type: the corresponding type of the attribute node
3154
 *
3155
 * Reports an illegal attribute.
3156
 */
3157
static void
3158
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3159
       xmlParserErrors error,
3160
       xmlSchemaBasicItemPtr ownerItem,
3161
       xmlAttrPtr attr,
3162
       const char *name1,
3163
       const char *name2)
3164
0
{
3165
0
    xmlChar *des = NULL;
3166
3167
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3168
0
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3169
0
  "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3170
0
  BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3171
0
    FREE_AND_NULL(des);
3172
0
}
3173
3174
/**
3175
 * xmlSchemaPSimpleTypeErr:
3176
 * @ctxt:  the schema validation context
3177
 * @error: the error code
3178
 * @type: the type specifier
3179
 * @ownerItem: the schema object if existent
3180
 * @node: the validated node
3181
 * @value: the validated value
3182
 *
3183
 * Reports a simple type validation error.
3184
 * TODO: Should this report the value of an element as well?
3185
 */
3186
static void LIBXML_ATTR_FORMAT(8,0)
3187
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3188
      xmlParserErrors error,
3189
      xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3190
      xmlNodePtr node,
3191
      xmlSchemaTypePtr type,
3192
      const char *expected,
3193
      const xmlChar *value,
3194
      const char *message,
3195
      const xmlChar *str1,
3196
      const xmlChar *str2)
3197
0
{
3198
0
    xmlChar *msg = NULL;
3199
3200
0
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3201
0
    if (message == NULL) {
3202
  /*
3203
  * Use default messages.
3204
  */
3205
0
  if (type != NULL) {
3206
0
      if (node->type == XML_ATTRIBUTE_NODE)
3207
0
    msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3208
0
      else
3209
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3210
0
    "valid value of ");
3211
0
      if (! xmlSchemaIsGlobalItem(type))
3212
0
    msg = xmlStrcat(msg, BAD_CAST "the local ");
3213
0
      else
3214
0
    msg = xmlStrcat(msg, BAD_CAST "the ");
3215
3216
0
      if (WXS_IS_ATOMIC(type))
3217
0
    msg = xmlStrcat(msg, BAD_CAST "atomic type");
3218
0
      else if (WXS_IS_LIST(type))
3219
0
    msg = xmlStrcat(msg, BAD_CAST "list type");
3220
0
      else if (WXS_IS_UNION(type))
3221
0
    msg = xmlStrcat(msg, BAD_CAST "union type");
3222
3223
0
      if (xmlSchemaIsGlobalItem(type)) {
3224
0
    xmlChar *str = NULL;
3225
0
    msg = xmlStrcat(msg, BAD_CAST " '");
3226
0
    if (type->builtInType != 0) {
3227
0
        msg = xmlStrcat(msg, BAD_CAST "xs:");
3228
0
        str = xmlStrdup(type->name);
3229
0
    } else {
3230
0
        const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3231
0
        if (!str)
3232
0
      str = xmlStrdup(qName);
3233
0
    }
3234
0
    msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3235
0
    msg = xmlStrcat(msg, BAD_CAST "'.");
3236
0
    FREE_AND_NULL(str);
3237
0
      }
3238
0
  } else {
3239
0
      if (node->type == XML_ATTRIBUTE_NODE)
3240
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3241
0
      else
3242
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3243
0
    "valid.");
3244
0
  }
3245
0
  if (expected) {
3246
0
      xmlChar *expectedEscaped = xmlCharStrdup(expected);
3247
0
      msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3248
0
      msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3249
0
      FREE_AND_NULL(expectedEscaped);
3250
0
      msg = xmlStrcat(msg, BAD_CAST "'.\n");
3251
0
  } else
3252
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
3253
0
  if (node->type == XML_ATTRIBUTE_NODE)
3254
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3255
0
  else
3256
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3257
0
    } else {
3258
0
  msg = xmlStrcat(msg, BAD_CAST message);
3259
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
3260
0
  xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3261
0
       (const char*) msg, str1, str2, NULL, NULL, NULL);
3262
0
    }
3263
    /* Cleanup. */
3264
0
    FREE_AND_NULL(msg)
3265
0
}
3266
3267
/**
3268
 * xmlSchemaPContentErr:
3269
 * @ctxt: the schema parser context
3270
 * @error: the error code
3271
 * @ownerItem: the owner item of the holder of the content
3272
 * @ownerElem: the node of the holder of the content
3273
 * @child: the invalid child node
3274
 * @message: the optional error message
3275
 * @content: the optional string describing the correct content
3276
 *
3277
 * Reports an error concerning the content of a schema element.
3278
 */
3279
static void
3280
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3281
         xmlParserErrors error,
3282
         xmlSchemaBasicItemPtr ownerItem,
3283
         xmlNodePtr ownerElem,
3284
         xmlNodePtr child,
3285
         const char *message,
3286
         const char *content)
3287
0
{
3288
0
    xmlChar *des = NULL;
3289
3290
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3291
0
    if (message != NULL)
3292
0
  xmlSchemaPErr2(ctxt, ownerElem, child, error,
3293
0
      "%s: %s.\n",
3294
0
      BAD_CAST des, BAD_CAST message);
3295
0
    else {
3296
0
  if (content != NULL) {
3297
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3298
0
    "%s: The content is not valid. Expected is %s.\n",
3299
0
    BAD_CAST des, BAD_CAST content);
3300
0
  } else {
3301
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3302
0
    "%s: The content is not valid.\n",
3303
0
    BAD_CAST des, NULL);
3304
0
  }
3305
0
    }
3306
0
    FREE_AND_NULL(des)
3307
0
}
3308
3309
/************************************************************************
3310
 *                  *
3311
 *      Streamable error functions                      *
3312
 *                  *
3313
 ************************************************************************/
3314
3315
3316
3317
3318
/************************************************************************
3319
 *                  *
3320
 *      Validation helper functions     *
3321
 *                  *
3322
 ************************************************************************/
3323
3324
3325
/************************************************************************
3326
 *                  *
3327
 *      Allocation functions        *
3328
 *                  *
3329
 ************************************************************************/
3330
3331
/**
3332
 * xmlSchemaNewSchemaForParserCtxt:
3333
 * @ctxt:  a schema validation context
3334
 *
3335
 * Allocate a new Schema structure.
3336
 *
3337
 * Returns the newly allocated structure or NULL in case or error
3338
 */
3339
static xmlSchemaPtr
3340
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3341
0
{
3342
0
    xmlSchemaPtr ret;
3343
3344
0
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3345
0
    if (ret == NULL) {
3346
0
        xmlSchemaPErrMemory(ctxt);
3347
0
        return (NULL);
3348
0
    }
3349
0
    memset(ret, 0, sizeof(xmlSchema));
3350
0
    ret->dict = ctxt->dict;
3351
0
    xmlDictReference(ret->dict);
3352
3353
0
    return (ret);
3354
0
}
3355
3356
/**
3357
 * xmlSchemaNewFacet:
3358
 *
3359
 * Allocate a new Facet structure.
3360
 *
3361
 * Returns the newly allocated structure or NULL in case or error
3362
 */
3363
xmlSchemaFacetPtr
3364
xmlSchemaNewFacet(void)
3365
0
{
3366
0
    xmlSchemaFacetPtr ret;
3367
3368
0
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3369
0
    if (ret == NULL) {
3370
0
        return (NULL);
3371
0
    }
3372
0
    memset(ret, 0, sizeof(xmlSchemaFacet));
3373
3374
0
    return (ret);
3375
0
}
3376
3377
/**
3378
 * xmlSchemaNewAnnot:
3379
 * @ctxt:  a schema validation context
3380
 * @node:  a node
3381
 *
3382
 * Allocate a new annotation structure.
3383
 *
3384
 * Returns the newly allocated structure or NULL in case or error
3385
 */
3386
static xmlSchemaAnnotPtr
3387
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3388
0
{
3389
0
    xmlSchemaAnnotPtr ret;
3390
3391
0
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3392
0
    if (ret == NULL) {
3393
0
        xmlSchemaPErrMemory(ctxt);
3394
0
        return (NULL);
3395
0
    }
3396
0
    memset(ret, 0, sizeof(xmlSchemaAnnot));
3397
0
    ret->content = node;
3398
0
    return (ret);
3399
0
}
3400
3401
static xmlSchemaItemListPtr
3402
xmlSchemaItemListCreate(void)
3403
0
{
3404
0
    xmlSchemaItemListPtr ret;
3405
3406
0
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3407
0
    if (ret == NULL) {
3408
0
  xmlSchemaPErrMemory(NULL);
3409
0
  return (NULL);
3410
0
    }
3411
0
    memset(ret, 0, sizeof(xmlSchemaItemList));
3412
0
    return (ret);
3413
0
}
3414
3415
static void
3416
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3417
0
{
3418
0
    if (list->items != NULL) {
3419
0
  xmlFree(list->items);
3420
0
  list->items = NULL;
3421
0
    }
3422
0
    list->nbItems = 0;
3423
0
    list->sizeItems = 0;
3424
0
}
3425
3426
static int
3427
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3428
0
{
3429
0
    if (list->sizeItems <= list->nbItems) {
3430
0
        void **tmp;
3431
0
        size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3432
3433
0
  tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3434
0
  if (tmp == NULL) {
3435
0
      xmlSchemaPErrMemory(NULL);
3436
0
      return(-1);
3437
0
  }
3438
0
        list->items = tmp;
3439
0
  list->sizeItems = newSize;
3440
0
    }
3441
0
    list->items[list->nbItems++] = item;
3442
0
    return(0);
3443
0
}
3444
3445
static int
3446
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3447
       int initialSize,
3448
       void *item)
3449
0
{
3450
0
    if (list->items == NULL) {
3451
0
  if (initialSize <= 0)
3452
0
      initialSize = 1;
3453
0
  list->items = (void **) xmlMalloc(
3454
0
      initialSize * sizeof(void *));
3455
0
  if (list->items == NULL) {
3456
0
      xmlSchemaPErrMemory(NULL);
3457
0
      return(-1);
3458
0
  }
3459
0
  list->sizeItems = initialSize;
3460
0
    } else if (list->sizeItems <= list->nbItems) {
3461
0
        void **tmp;
3462
3463
0
  list->sizeItems *= 2;
3464
0
  tmp = (void **) xmlRealloc(list->items,
3465
0
      list->sizeItems * sizeof(void *));
3466
0
  if (tmp == NULL) {
3467
0
      xmlSchemaPErrMemory(NULL);
3468
0
      list->sizeItems /= 2;
3469
0
      return(-1);
3470
0
  }
3471
0
        list->items = tmp;
3472
0
    }
3473
0
    list->items[list->nbItems++] = item;
3474
0
    return(0);
3475
0
}
3476
3477
static int
3478
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3479
0
{
3480
0
    if (list->sizeItems <= list->nbItems) {
3481
0
        void **tmp;
3482
0
        size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3483
3484
0
  tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3485
0
  if (tmp == NULL) {
3486
0
      xmlSchemaPErrMemory(NULL);
3487
0
      return(-1);
3488
0
  }
3489
0
        list->items = tmp;
3490
0
  list->sizeItems = newSize;
3491
0
    }
3492
    /*
3493
    * Just append if the index is greater/equal than the item count.
3494
    */
3495
0
    if (idx >= list->nbItems) {
3496
0
  list->items[list->nbItems++] = item;
3497
0
    } else {
3498
0
  int i;
3499
0
  for (i = list->nbItems; i > idx; i--)
3500
0
      list->items[i] = list->items[i-1];
3501
0
  list->items[idx] = item;
3502
0
  list->nbItems++;
3503
0
    }
3504
0
    return(0);
3505
0
}
3506
3507
#if 0 /* enable if ever needed */
3508
static int
3509
xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3510
          int initialSize,
3511
          void *item,
3512
          int idx)
3513
{
3514
    if (list->items == NULL) {
3515
  if (initialSize <= 0)
3516
      initialSize = 1;
3517
  list->items = (void **) xmlMalloc(
3518
      initialSize * sizeof(void *));
3519
  if (list->items == NULL) {
3520
      xmlSchemaPErrMemory(NULL);
3521
      return(-1);
3522
  }
3523
  list->sizeItems = initialSize;
3524
    } else if (list->sizeItems <= list->nbItems) {
3525
  list->sizeItems *= 2;
3526
  list->items = (void **) xmlRealloc(list->items,
3527
      list->sizeItems * sizeof(void *));
3528
  if (list->items == NULL) {
3529
      xmlSchemaPErrMemory(NULL);
3530
      list->sizeItems = 0;
3531
      return(-1);
3532
  }
3533
    }
3534
    /*
3535
    * Just append if the index is greater/equal than the item count.
3536
    */
3537
    if (idx >= list->nbItems) {
3538
  list->items[list->nbItems++] = item;
3539
    } else {
3540
  int i;
3541
  for (i = list->nbItems; i > idx; i--)
3542
      list->items[i] = list->items[i-1];
3543
  list->items[idx] = item;
3544
  list->nbItems++;
3545
    }
3546
    return(0);
3547
}
3548
#endif
3549
3550
static int
3551
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3552
0
{
3553
0
    int i;
3554
0
    if ((list->items == NULL) || (idx >= list->nbItems))
3555
0
  return(-1);
3556
3557
0
    if (list->nbItems == 1) {
3558
  /* TODO: Really free the list? */
3559
0
  xmlFree(list->items);
3560
0
  list->items = NULL;
3561
0
  list->nbItems = 0;
3562
0
  list->sizeItems = 0;
3563
0
    } else if (list->nbItems -1 == idx) {
3564
0
  list->nbItems--;
3565
0
    } else {
3566
0
  for (i = idx; i < list->nbItems -1; i++)
3567
0
      list->items[i] = list->items[i+1];
3568
0
  list->nbItems--;
3569
0
    }
3570
0
    return(0);
3571
0
}
3572
3573
/**
3574
 * xmlSchemaItemListFree:
3575
 * @annot:  a schema type structure
3576
 *
3577
 * Deallocate a annotation structure
3578
 */
3579
static void
3580
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3581
0
{
3582
0
    if (list == NULL)
3583
0
  return;
3584
0
    if (list->items != NULL)
3585
0
  xmlFree(list->items);
3586
0
    xmlFree(list);
3587
0
}
3588
3589
static void
3590
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3591
0
{
3592
0
    if (bucket == NULL)
3593
0
  return;
3594
0
    if (bucket->globals != NULL) {
3595
0
  xmlSchemaComponentListFree(bucket->globals);
3596
0
  xmlSchemaItemListFree(bucket->globals);
3597
0
    }
3598
0
    if (bucket->locals != NULL) {
3599
0
  xmlSchemaComponentListFree(bucket->locals);
3600
0
  xmlSchemaItemListFree(bucket->locals);
3601
0
    }
3602
0
    if (bucket->relations != NULL) {
3603
0
  xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3604
0
  do {
3605
0
      prev = cur;
3606
0
      cur = cur->next;
3607
0
      xmlFree(prev);
3608
0
  } while (cur != NULL);
3609
0
    }
3610
0
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3611
0
  xmlFreeDoc(bucket->doc);
3612
0
    }
3613
0
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3614
0
  if (WXS_IMPBUCKET(bucket)->schema != NULL)
3615
0
      xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3616
0
    }
3617
0
    xmlFree(bucket);
3618
0
}
3619
3620
static void
3621
xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3622
0
{
3623
0
    xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3624
0
}
3625
3626
static xmlSchemaBucketPtr
3627
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3628
       int type, const xmlChar *targetNamespace)
3629
0
{
3630
0
    xmlSchemaBucketPtr ret;
3631
0
    int size;
3632
0
    xmlSchemaPtr mainSchema;
3633
3634
0
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3635
0
  PERROR_INT("xmlSchemaBucketCreate",
3636
0
      "no main schema on constructor");
3637
0
  return(NULL);
3638
0
    }
3639
0
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3640
    /* Create the schema bucket. */
3641
0
    if (WXS_IS_BUCKET_INCREDEF(type))
3642
0
  size = sizeof(xmlSchemaInclude);
3643
0
    else
3644
0
  size = sizeof(xmlSchemaImport);
3645
0
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3646
0
    if (ret == NULL) {
3647
0
  xmlSchemaPErrMemory(NULL);
3648
0
  return(NULL);
3649
0
    }
3650
0
    memset(ret, 0, size);
3651
0
    ret->targetNamespace = targetNamespace;
3652
0
    ret->type = type;
3653
0
    ret->globals = xmlSchemaItemListCreate();
3654
0
    if (ret->globals == NULL) {
3655
0
  xmlSchemaBucketFree(ret);
3656
0
  return(NULL);
3657
0
    }
3658
0
    ret->locals = xmlSchemaItemListCreate();
3659
0
    if (ret->locals == NULL) {
3660
0
  xmlSchemaBucketFree(ret);
3661
0
  return(NULL);
3662
0
    }
3663
    /*
3664
    * The following will assure that only the first bucket is marked as
3665
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3666
    * For each following import buckets an xmlSchema will be created.
3667
    * An xmlSchema will be created for every distinct targetNamespace.
3668
    * We assign the targetNamespace to the schemata here.
3669
    */
3670
0
    if (! WXS_HAS_BUCKETS(pctxt)) {
3671
0
  if (WXS_IS_BUCKET_INCREDEF(type)) {
3672
0
      PERROR_INT("xmlSchemaBucketCreate",
3673
0
    "first bucket but it's an include or redefine");
3674
0
      xmlSchemaBucketFree(ret);
3675
0
      return(NULL);
3676
0
  }
3677
  /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3678
0
  ret->type = XML_SCHEMA_SCHEMA_MAIN;
3679
  /* Point to the *main* schema. */
3680
0
  WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3681
0
  WXS_IMPBUCKET(ret)->schema = mainSchema;
3682
  /*
3683
  * Ensure that the main schema gets a targetNamespace.
3684
  */
3685
0
  mainSchema->targetNamespace = targetNamespace;
3686
0
    } else {
3687
0
  if (type == XML_SCHEMA_SCHEMA_MAIN) {
3688
0
      PERROR_INT("xmlSchemaBucketCreate",
3689
0
    "main bucket but it's not the first one");
3690
0
      xmlSchemaBucketFree(ret);
3691
0
      return(NULL);
3692
0
  } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3693
      /*
3694
      * Create a schema for imports and assign the
3695
      * targetNamespace.
3696
      */
3697
0
      WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3698
0
      if (WXS_IMPBUCKET(ret)->schema == NULL) {
3699
0
    xmlSchemaBucketFree(ret);
3700
0
    return(NULL);
3701
0
      }
3702
0
      WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3703
0
  }
3704
0
    }
3705
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3706
0
  int res;
3707
  /*
3708
  * Imports go into the "schemasImports" slot of the main *schema*.
3709
  * Note that we create an import entry for the main schema as well; i.e.,
3710
  * even if there's only one schema, we'll get an import.
3711
  */
3712
0
  if (mainSchema->schemasImports == NULL) {
3713
0
      mainSchema->schemasImports = xmlHashCreateDict(5,
3714
0
    WXS_CONSTRUCTOR(pctxt)->dict);
3715
0
      if (mainSchema->schemasImports == NULL) {
3716
0
    xmlSchemaBucketFree(ret);
3717
0
    return(NULL);
3718
0
      }
3719
0
  }
3720
0
  if (targetNamespace == NULL)
3721
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3722
0
    XML_SCHEMAS_NO_NAMESPACE, ret);
3723
0
  else
3724
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3725
0
    targetNamespace, ret);
3726
0
  if (res != 0) {
3727
0
      PERROR_INT("xmlSchemaBucketCreate",
3728
0
    "failed to add the schema bucket to the hash");
3729
0
      xmlSchemaBucketFree(ret);
3730
0
      return(NULL);
3731
0
  }
3732
0
    } else {
3733
  /* Set the @ownerImport of an include bucket. */
3734
0
  if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3735
0
      WXS_INCBUCKET(ret)->ownerImport =
3736
0
    WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3737
0
  else
3738
0
      WXS_INCBUCKET(ret)->ownerImport =
3739
0
    WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3740
3741
  /* Includes got into the "includes" slot of the *main* schema. */
3742
0
  if (mainSchema->includes == NULL) {
3743
0
      mainSchema->includes = xmlSchemaItemListCreate();
3744
0
      if (mainSchema->includes == NULL) {
3745
0
    xmlSchemaBucketFree(ret);
3746
0
    return(NULL);
3747
0
      }
3748
0
  }
3749
0
  if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
3750
0
      xmlSchemaBucketFree(ret);
3751
0
      return(NULL);
3752
0
        }
3753
0
    }
3754
    /*
3755
    * Add to list of all buckets; this is used for lookup
3756
    * during schema construction time only.
3757
    */
3758
0
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3759
0
  return(NULL);
3760
0
    return(ret);
3761
0
}
3762
3763
static int
3764
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3765
0
{
3766
0
    if (*list == NULL) {
3767
0
  *list = xmlSchemaItemListCreate();
3768
0
  if (*list == NULL)
3769
0
      return(-1);
3770
0
    }
3771
0
    return(xmlSchemaItemListAddSize(*list, initialSize, item));
3772
0
}
3773
3774
/**
3775
 * xmlSchemaFreeAnnot:
3776
 * @annot:  a schema type structure
3777
 *
3778
 * Deallocate a annotation structure
3779
 */
3780
static void
3781
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3782
0
{
3783
0
    if (annot == NULL)
3784
0
        return;
3785
0
    if (annot->next == NULL) {
3786
0
  xmlFree(annot);
3787
0
    } else {
3788
0
  xmlSchemaAnnotPtr prev;
3789
3790
0
  do {
3791
0
      prev = annot;
3792
0
      annot = annot->next;
3793
0
      xmlFree(prev);
3794
0
  } while (annot != NULL);
3795
0
    }
3796
0
}
3797
3798
/**
3799
 * xmlSchemaFreeNotation:
3800
 * @schema:  a schema notation structure
3801
 *
3802
 * Deallocate a Schema Notation structure.
3803
 */
3804
static void
3805
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3806
0
{
3807
0
    if (nota == NULL)
3808
0
        return;
3809
0
    if (nota->annot != NULL)
3810
0
  xmlSchemaFreeAnnot(nota->annot);
3811
0
    xmlFree(nota);
3812
0
}
3813
3814
/**
3815
 * xmlSchemaFreeAttribute:
3816
 * @attr:  an attribute declaration
3817
 *
3818
 * Deallocates an attribute declaration structure.
3819
 */
3820
static void
3821
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3822
0
{
3823
0
    if (attr == NULL)
3824
0
        return;
3825
0
    if (attr->annot != NULL)
3826
0
  xmlSchemaFreeAnnot(attr->annot);
3827
0
    if (attr->defVal != NULL)
3828
0
  xmlSchemaFreeValue(attr->defVal);
3829
0
    xmlFree(attr);
3830
0
}
3831
3832
/**
3833
 * xmlSchemaFreeAttributeUse:
3834
 * @use:  an attribute use
3835
 *
3836
 * Deallocates an attribute use structure.
3837
 */
3838
static void
3839
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3840
0
{
3841
0
    if (use == NULL)
3842
0
        return;
3843
0
    if (use->annot != NULL)
3844
0
  xmlSchemaFreeAnnot(use->annot);
3845
0
    if (use->defVal != NULL)
3846
0
  xmlSchemaFreeValue(use->defVal);
3847
0
    xmlFree(use);
3848
0
}
3849
3850
/**
3851
 * xmlSchemaFreeAttributeUseProhib:
3852
 * @prohib:  an attribute use prohibition
3853
 *
3854
 * Deallocates an attribute use structure.
3855
 */
3856
static void
3857
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3858
0
{
3859
0
    if (prohib == NULL)
3860
0
        return;
3861
0
    xmlFree(prohib);
3862
0
}
3863
3864
/**
3865
 * xmlSchemaFreeWildcardNsSet:
3866
 * set:  a schema wildcard namespace
3867
 *
3868
 * Deallocates a list of wildcard constraint structures.
3869
 */
3870
static void
3871
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3872
0
{
3873
0
    xmlSchemaWildcardNsPtr next;
3874
3875
0
    while (set != NULL) {
3876
0
  next = set->next;
3877
0
  xmlFree(set);
3878
0
  set = next;
3879
0
    }
3880
0
}
3881
3882
/**
3883
 * xmlSchemaFreeWildcard:
3884
 * @wildcard:  a wildcard structure
3885
 *
3886
 * Deallocates a wildcard structure.
3887
 */
3888
void
3889
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3890
0
{
3891
0
    if (wildcard == NULL)
3892
0
        return;
3893
0
    if (wildcard->annot != NULL)
3894
0
        xmlSchemaFreeAnnot(wildcard->annot);
3895
0
    if (wildcard->nsSet != NULL)
3896
0
  xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3897
0
    if (wildcard->negNsSet != NULL)
3898
0
  xmlFree(wildcard->negNsSet);
3899
0
    xmlFree(wildcard);
3900
0
}
3901
3902
/**
3903
 * xmlSchemaFreeAttributeGroup:
3904
 * @schema:  a schema attribute group structure
3905
 *
3906
 * Deallocate a Schema Attribute Group structure.
3907
 */
3908
static void
3909
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3910
0
{
3911
0
    if (attrGr == NULL)
3912
0
        return;
3913
0
    if (attrGr->annot != NULL)
3914
0
        xmlSchemaFreeAnnot(attrGr->annot);
3915
0
    if (attrGr->attrUses != NULL)
3916
0
  xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3917
0
    xmlFree(attrGr);
3918
0
}
3919
3920
/**
3921
 * xmlSchemaFreeQNameRef:
3922
 * @item: a QName reference structure
3923
 *
3924
 * Deallocatea a QName reference structure.
3925
 */
3926
static void
3927
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3928
0
{
3929
0
    xmlFree(item);
3930
0
}
3931
3932
/**
3933
 * xmlSchemaFreeTypeLinkList:
3934
 * @alink: a type link
3935
 *
3936
 * Deallocate a list of types.
3937
 */
3938
static void
3939
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3940
0
{
3941
0
    xmlSchemaTypeLinkPtr next;
3942
3943
0
    while (link != NULL) {
3944
0
  next = link->next;
3945
0
  xmlFree(link);
3946
0
  link = next;
3947
0
    }
3948
0
}
3949
3950
static void
3951
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3952
0
{
3953
0
    xmlSchemaIDCStateObjPtr next;
3954
0
    while (sto != NULL) {
3955
0
  next = sto->next;
3956
0
  if (sto->history != NULL)
3957
0
      xmlFree(sto->history);
3958
0
  if (sto->xpathCtxt != NULL)
3959
0
      xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3960
0
  xmlFree(sto);
3961
0
  sto = next;
3962
0
    }
3963
0
}
3964
3965
/**
3966
 * xmlSchemaFreeIDC:
3967
 * @idc: a identity-constraint definition
3968
 *
3969
 * Deallocates an identity-constraint definition.
3970
 */
3971
static void
3972
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3973
0
{
3974
0
    xmlSchemaIDCSelectPtr cur, prev;
3975
3976
0
    if (idcDef == NULL)
3977
0
  return;
3978
0
    if (idcDef->annot != NULL)
3979
0
        xmlSchemaFreeAnnot(idcDef->annot);
3980
    /* Selector */
3981
0
    if (idcDef->selector != NULL) {
3982
0
  if (idcDef->selector->xpathComp != NULL)
3983
0
      xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3984
0
  xmlFree(idcDef->selector);
3985
0
    }
3986
    /* Fields */
3987
0
    if (idcDef->fields != NULL) {
3988
0
  cur = idcDef->fields;
3989
0
  do {
3990
0
      prev = cur;
3991
0
      cur = cur->next;
3992
0
      if (prev->xpathComp != NULL)
3993
0
    xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3994
0
      xmlFree(prev);
3995
0
  } while (cur != NULL);
3996
0
    }
3997
0
    xmlFree(idcDef);
3998
0
}
3999
4000
/**
4001
 * xmlSchemaFreeElement:
4002
 * @schema:  a schema element structure
4003
 *
4004
 * Deallocate a Schema Element structure.
4005
 */
4006
static void
4007
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
4008
0
{
4009
0
    if (elem == NULL)
4010
0
        return;
4011
0
    if (elem->annot != NULL)
4012
0
        xmlSchemaFreeAnnot(elem->annot);
4013
0
    if (elem->contModel != NULL)
4014
0
        xmlRegFreeRegexp(elem->contModel);
4015
0
    if (elem->defVal != NULL)
4016
0
  xmlSchemaFreeValue(elem->defVal);
4017
0
    xmlFree(elem);
4018
0
}
4019
4020
/**
4021
 * xmlSchemaFreeFacet:
4022
 * @facet:  a schema facet structure
4023
 *
4024
 * Deallocate a Schema Facet structure.
4025
 */
4026
void
4027
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4028
0
{
4029
0
    if (facet == NULL)
4030
0
        return;
4031
0
    if (facet->val != NULL)
4032
0
        xmlSchemaFreeValue(facet->val);
4033
0
    if (facet->regexp != NULL)
4034
0
        xmlRegFreeRegexp(facet->regexp);
4035
0
    if (facet->annot != NULL)
4036
0
        xmlSchemaFreeAnnot(facet->annot);
4037
0
    xmlFree(facet);
4038
0
}
4039
4040
/**
4041
 * xmlSchemaFreeType:
4042
 * @type:  a schema type structure
4043
 *
4044
 * Deallocate a Schema Type structure.
4045
 */
4046
void
4047
xmlSchemaFreeType(xmlSchemaTypePtr type)
4048
0
{
4049
0
    if (type == NULL)
4050
0
        return;
4051
0
    if (type->annot != NULL)
4052
0
        xmlSchemaFreeAnnot(type->annot);
4053
0
    if (type->facets != NULL) {
4054
0
        xmlSchemaFacetPtr facet, next;
4055
4056
0
        facet = type->facets;
4057
0
        while (facet != NULL) {
4058
0
            next = facet->next;
4059
0
            xmlSchemaFreeFacet(facet);
4060
0
            facet = next;
4061
0
        }
4062
0
    }
4063
0
    if (type->attrUses != NULL)
4064
0
  xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4065
0
    if (type->memberTypes != NULL)
4066
0
  xmlSchemaFreeTypeLinkList(type->memberTypes);
4067
0
    if (type->facetSet != NULL) {
4068
0
  xmlSchemaFacetLinkPtr next, link;
4069
4070
0
  link = type->facetSet;
4071
0
  do {
4072
0
      next = link->next;
4073
0
      xmlFree(link);
4074
0
      link = next;
4075
0
  } while (link != NULL);
4076
0
    }
4077
0
    if (type->contModel != NULL)
4078
0
        xmlRegFreeRegexp(type->contModel);
4079
0
    xmlFree(type);
4080
0
}
4081
4082
/**
4083
 * xmlSchemaFreeModelGroupDef:
4084
 * @item:  a schema model group definition
4085
 *
4086
 * Deallocates a schema model group definition.
4087
 */
4088
static void
4089
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4090
0
{
4091
0
    if (item->annot != NULL)
4092
0
  xmlSchemaFreeAnnot(item->annot);
4093
0
    xmlFree(item);
4094
0
}
4095
4096
/**
4097
 * xmlSchemaFreeModelGroup:
4098
 * @item:  a schema model group
4099
 *
4100
 * Deallocates a schema model group structure.
4101
 */
4102
static void
4103
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4104
0
{
4105
0
    if (item->annot != NULL)
4106
0
  xmlSchemaFreeAnnot(item->annot);
4107
0
    xmlFree(item);
4108
0
}
4109
4110
static void
4111
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4112
0
{
4113
0
    if ((list == NULL) || (list->nbItems == 0))
4114
0
  return;
4115
0
    {
4116
0
  xmlSchemaTreeItemPtr item;
4117
0
  xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4118
0
  int i;
4119
4120
0
  for (i = 0; i < list->nbItems; i++) {
4121
0
      item = items[i];
4122
0
      if (item == NULL)
4123
0
    continue;
4124
0
      switch (item->type) {
4125
0
    case XML_SCHEMA_TYPE_SIMPLE:
4126
0
    case XML_SCHEMA_TYPE_COMPLEX:
4127
0
        xmlSchemaFreeType((xmlSchemaTypePtr) item);
4128
0
        break;
4129
0
    case XML_SCHEMA_TYPE_ATTRIBUTE:
4130
0
        xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4131
0
        break;
4132
0
    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4133
0
        xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4134
0
        break;
4135
0
    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4136
0
        xmlSchemaFreeAttributeUseProhib(
4137
0
      (xmlSchemaAttributeUseProhibPtr) item);
4138
0
        break;
4139
0
    case XML_SCHEMA_TYPE_ELEMENT:
4140
0
        xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4141
0
        break;
4142
0
    case XML_SCHEMA_TYPE_PARTICLE:
4143
0
        if (item->annot != NULL)
4144
0
      xmlSchemaFreeAnnot(item->annot);
4145
0
        xmlFree(item);
4146
0
        break;
4147
0
    case XML_SCHEMA_TYPE_SEQUENCE:
4148
0
    case XML_SCHEMA_TYPE_CHOICE:
4149
0
    case XML_SCHEMA_TYPE_ALL:
4150
0
        xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4151
0
        break;
4152
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4153
0
        xmlSchemaFreeAttributeGroup(
4154
0
      (xmlSchemaAttributeGroupPtr) item);
4155
0
        break;
4156
0
    case XML_SCHEMA_TYPE_GROUP:
4157
0
        xmlSchemaFreeModelGroupDef(
4158
0
      (xmlSchemaModelGroupDefPtr) item);
4159
0
        break;
4160
0
    case XML_SCHEMA_TYPE_ANY:
4161
0
    case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4162
0
        xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4163
0
        break;
4164
0
    case XML_SCHEMA_TYPE_IDC_KEY:
4165
0
    case XML_SCHEMA_TYPE_IDC_UNIQUE:
4166
0
    case XML_SCHEMA_TYPE_IDC_KEYREF:
4167
0
        xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4168
0
        break;
4169
0
    case XML_SCHEMA_TYPE_NOTATION:
4170
0
        xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4171
0
        break;
4172
0
    case XML_SCHEMA_EXTRA_QNAMEREF:
4173
0
        xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4174
0
        break;
4175
0
    default:
4176
        /* TODO: This should never be hit. */
4177
0
        break;
4178
0
      }
4179
0
  }
4180
0
  list->nbItems = 0;
4181
0
    }
4182
0
}
4183
4184
/**
4185
 * xmlSchemaFree:
4186
 * @schema:  a schema structure
4187
 *
4188
 * Deallocate a Schema structure.
4189
 */
4190
void
4191
xmlSchemaFree(xmlSchemaPtr schema)
4192
0
{
4193
0
    if (schema == NULL)
4194
0
        return;
4195
    /*
4196
    * Note that those slots are not responsible for freeing
4197
    * schema components anymore; this will now be done by
4198
    * the schema buckets.
4199
    */
4200
0
    if (schema->notaDecl != NULL)
4201
0
        xmlHashFree(schema->notaDecl, NULL);
4202
0
    if (schema->attrDecl != NULL)
4203
0
        xmlHashFree(schema->attrDecl, NULL);
4204
0
    if (schema->attrgrpDecl != NULL)
4205
0
        xmlHashFree(schema->attrgrpDecl, NULL);
4206
0
    if (schema->elemDecl != NULL)
4207
0
        xmlHashFree(schema->elemDecl, NULL);
4208
0
    if (schema->typeDecl != NULL)
4209
0
        xmlHashFree(schema->typeDecl, NULL);
4210
0
    if (schema->groupDecl != NULL)
4211
0
        xmlHashFree(schema->groupDecl, NULL);
4212
0
    if (schema->idcDef != NULL)
4213
0
        xmlHashFree(schema->idcDef, NULL);
4214
4215
0
    if (schema->schemasImports != NULL)
4216
0
  xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4217
0
    if (schema->includes != NULL) {
4218
0
  xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4219
0
  int i;
4220
0
  for (i = 0; i < list->nbItems; i++) {
4221
0
      xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4222
0
  }
4223
0
  xmlSchemaItemListFree(list);
4224
0
    }
4225
0
    if (schema->annot != NULL)
4226
0
        xmlSchemaFreeAnnot(schema->annot);
4227
    /* Never free the doc here, since this will be done by the buckets. */
4228
4229
0
    xmlDictFree(schema->dict);
4230
0
    xmlFree(schema);
4231
0
}
4232
4233
/************************************************************************
4234
 *                  *
4235
 *      Debug functions         *
4236
 *                  *
4237
 ************************************************************************/
4238
4239
#ifdef LIBXML_OUTPUT_ENABLED
4240
4241
static void
4242
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4243
4244
/**
4245
 * xmlSchemaElementDump:
4246
 * @elem:  an element
4247
 * @output:  the file output
4248
 *
4249
 * Dump the element
4250
 */
4251
static void
4252
xmlSchemaElementDump(void *payload, void *data,
4253
                     const xmlChar * name ATTRIBUTE_UNUSED,
4254
         const xmlChar * namespace ATTRIBUTE_UNUSED,
4255
                     const xmlChar * context ATTRIBUTE_UNUSED)
4256
0
{
4257
0
    xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4258
0
    FILE *output = (FILE *) data;
4259
0
    if (elem == NULL)
4260
0
        return;
4261
4262
4263
0
    fprintf(output, "Element");
4264
0
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4265
0
  fprintf(output, " (global)");
4266
0
    fprintf(output, ": '%s' ", elem->name);
4267
0
    if (namespace != NULL)
4268
0
  fprintf(output, "ns '%s'", namespace);
4269
0
    fprintf(output, "\n");
4270
#if 0
4271
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4272
  fprintf(output, "  min %d ", elem->minOccurs);
4273
        if (elem->maxOccurs >= UNBOUNDED)
4274
            fprintf(output, "max: unbounded\n");
4275
        else if (elem->maxOccurs != 1)
4276
            fprintf(output, "max: %d\n", elem->maxOccurs);
4277
        else
4278
            fprintf(output, "\n");
4279
    }
4280
#endif
4281
    /*
4282
    * Misc other properties.
4283
    */
4284
0
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4285
0
  (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4286
0
  (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4287
0
  (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4288
0
  fprintf(output, "  props: ");
4289
0
  if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4290
0
      fprintf(output, "[fixed] ");
4291
0
  if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4292
0
      fprintf(output, "[default] ");
4293
0
  if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4294
0
      fprintf(output, "[abstract] ");
4295
0
  if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4296
0
      fprintf(output, "[nillable] ");
4297
0
  fprintf(output, "\n");
4298
0
    }
4299
    /*
4300
    * Default/fixed value.
4301
    */
4302
0
    if (elem->value != NULL)
4303
0
  fprintf(output, "  value: '%s'\n", elem->value);
4304
    /*
4305
    * Type.
4306
    */
4307
0
    if (elem->namedType != NULL) {
4308
0
  fprintf(output, "  type: '%s' ", elem->namedType);
4309
0
  if (elem->namedTypeNs != NULL)
4310
0
      fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4311
0
  else
4312
0
      fprintf(output, "\n");
4313
0
    } else if (elem->subtypes != NULL) {
4314
  /*
4315
  * Dump local types.
4316
  */
4317
0
  xmlSchemaTypeDump(elem->subtypes, output);
4318
0
    }
4319
    /*
4320
    * Substitution group.
4321
    */
4322
0
    if (elem->substGroup != NULL) {
4323
0
  fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4324
0
  if (elem->substGroupNs != NULL)
4325
0
      fprintf(output, "ns '%s'\n", elem->substGroupNs);
4326
0
  else
4327
0
      fprintf(output, "\n");
4328
0
    }
4329
0
}
4330
4331
/**
4332
 * xmlSchemaAnnotDump:
4333
 * @output:  the file output
4334
 * @annot:  a annotation
4335
 *
4336
 * Dump the annotation
4337
 */
4338
static void
4339
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4340
0
{
4341
0
    xmlChar *content;
4342
4343
0
    if (annot == NULL)
4344
0
        return;
4345
4346
0
    content = xmlNodeGetContent(annot->content);
4347
0
    if (content != NULL) {
4348
0
        fprintf(output, "  Annot: %s\n", content);
4349
0
        xmlFree(content);
4350
0
    } else
4351
0
        fprintf(output, "  Annot: empty\n");
4352
0
}
4353
4354
/**
4355
 * xmlSchemaContentModelDump:
4356
 * @particle: the schema particle
4357
 * @output: the file output
4358
 * @depth: the depth used for indentation
4359
 *
4360
 * Dump a SchemaType structure
4361
 */
4362
static void
4363
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4364
0
{
4365
0
    xmlChar *str = NULL;
4366
0
    xmlSchemaTreeItemPtr term;
4367
0
    char shift[100];
4368
0
    int i;
4369
4370
0
    if (particle == NULL)
4371
0
  return;
4372
0
    for (i = 0;((i < depth) && (i < 25));i++)
4373
0
        shift[2 * i] = shift[2 * i + 1] = ' ';
4374
0
    shift[2 * i] = shift[2 * i + 1] = 0;
4375
0
    fprintf(output, "%s", shift);
4376
0
    if (particle->children == NULL) {
4377
0
  fprintf(output, "MISSING particle term\n");
4378
0
  return;
4379
0
    }
4380
0
    term = particle->children;
4381
0
    if (term == NULL) {
4382
0
  fprintf(output, "(NULL)");
4383
0
    } else {
4384
0
  switch (term->type) {
4385
0
      case XML_SCHEMA_TYPE_ELEMENT:
4386
0
    fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4387
0
        ((xmlSchemaElementPtr)term)->targetNamespace,
4388
0
        ((xmlSchemaElementPtr)term)->name));
4389
0
    FREE_AND_NULL(str);
4390
0
    break;
4391
0
      case XML_SCHEMA_TYPE_SEQUENCE:
4392
0
    fprintf(output, "SEQUENCE");
4393
0
    break;
4394
0
      case XML_SCHEMA_TYPE_CHOICE:
4395
0
    fprintf(output, "CHOICE");
4396
0
    break;
4397
0
      case XML_SCHEMA_TYPE_ALL:
4398
0
    fprintf(output, "ALL");
4399
0
    break;
4400
0
      case XML_SCHEMA_TYPE_ANY:
4401
0
    fprintf(output, "ANY");
4402
0
    break;
4403
0
      default:
4404
0
    fprintf(output, "UNKNOWN\n");
4405
0
    return;
4406
0
  }
4407
0
    }
4408
0
    if (particle->minOccurs != 1)
4409
0
  fprintf(output, " min: %d", particle->minOccurs);
4410
0
    if (particle->maxOccurs >= UNBOUNDED)
4411
0
  fprintf(output, " max: unbounded");
4412
0
    else if (particle->maxOccurs != 1)
4413
0
  fprintf(output, " max: %d", particle->maxOccurs);
4414
0
    fprintf(output, "\n");
4415
0
    if (term &&
4416
0
  ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4417
0
   (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4418
0
   (term->type == XML_SCHEMA_TYPE_ALL)) &&
4419
0
   (term->children != NULL)) {
4420
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4421
0
      output, depth +1);
4422
0
    }
4423
0
    if (particle->next != NULL)
4424
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4425
0
    output, depth);
4426
0
}
4427
4428
/**
4429
 * xmlSchemaAttrUsesDump:
4430
 * @uses:  attribute uses list
4431
 * @output:  the file output
4432
 *
4433
 * Dumps a list of attribute use components.
4434
 */
4435
static void
4436
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4437
0
{
4438
0
    xmlSchemaAttributeUsePtr use;
4439
0
    xmlSchemaAttributeUseProhibPtr prohib;
4440
0
    xmlSchemaQNameRefPtr ref;
4441
0
    const xmlChar *name, *tns;
4442
0
    xmlChar *str = NULL;
4443
0
    int i;
4444
4445
0
    if ((uses == NULL) || (uses->nbItems == 0))
4446
0
        return;
4447
4448
0
    fprintf(output, "  attributes:\n");
4449
0
    for (i = 0; i < uses->nbItems; i++) {
4450
0
  use = uses->items[i];
4451
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4452
0
      fprintf(output, "  [prohibition] ");
4453
0
      prohib = (xmlSchemaAttributeUseProhibPtr) use;
4454
0
      name = prohib->name;
4455
0
      tns = prohib->targetNamespace;
4456
0
  } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4457
0
      fprintf(output, "  [reference] ");
4458
0
      ref = (xmlSchemaQNameRefPtr) use;
4459
0
      name = ref->name;
4460
0
      tns = ref->targetNamespace;
4461
0
  } else {
4462
0
      fprintf(output, "  [use] ");
4463
0
      name = WXS_ATTRUSE_DECL_NAME(use);
4464
0
      tns = WXS_ATTRUSE_DECL_TNS(use);
4465
0
  }
4466
0
  fprintf(output, "'%s'\n",
4467
0
      (const char *) xmlSchemaFormatQName(&str, tns, name));
4468
0
  FREE_AND_NULL(str);
4469
0
    }
4470
0
}
4471
4472
/**
4473
 * xmlSchemaTypeDump:
4474
 * @output:  the file output
4475
 * @type:  a type structure
4476
 *
4477
 * Dump a SchemaType structure
4478
 */
4479
static void
4480
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4481
0
{
4482
0
    if (type == NULL) {
4483
0
        fprintf(output, "Type: NULL\n");
4484
0
        return;
4485
0
    }
4486
0
    fprintf(output, "Type: ");
4487
0
    if (type->name != NULL)
4488
0
        fprintf(output, "'%s' ", type->name);
4489
0
    else
4490
0
        fprintf(output, "(no name) ");
4491
0
    if (type->targetNamespace != NULL)
4492
0
  fprintf(output, "ns '%s' ", type->targetNamespace);
4493
0
    switch (type->type) {
4494
0
        case XML_SCHEMA_TYPE_BASIC:
4495
0
            fprintf(output, "[basic] ");
4496
0
            break;
4497
0
        case XML_SCHEMA_TYPE_SIMPLE:
4498
0
            fprintf(output, "[simple] ");
4499
0
            break;
4500
0
        case XML_SCHEMA_TYPE_COMPLEX:
4501
0
            fprintf(output, "[complex] ");
4502
0
            break;
4503
0
        case XML_SCHEMA_TYPE_SEQUENCE:
4504
0
            fprintf(output, "[sequence] ");
4505
0
            break;
4506
0
        case XML_SCHEMA_TYPE_CHOICE:
4507
0
            fprintf(output, "[choice] ");
4508
0
            break;
4509
0
        case XML_SCHEMA_TYPE_ALL:
4510
0
            fprintf(output, "[all] ");
4511
0
            break;
4512
0
        case XML_SCHEMA_TYPE_UR:
4513
0
            fprintf(output, "[ur] ");
4514
0
            break;
4515
0
        case XML_SCHEMA_TYPE_RESTRICTION:
4516
0
            fprintf(output, "[restriction] ");
4517
0
            break;
4518
0
        case XML_SCHEMA_TYPE_EXTENSION:
4519
0
            fprintf(output, "[extension] ");
4520
0
            break;
4521
0
        default:
4522
0
            fprintf(output, "[unknown type %d] ", type->type);
4523
0
            break;
4524
0
    }
4525
0
    fprintf(output, "content: ");
4526
0
    switch (type->contentType) {
4527
0
        case XML_SCHEMA_CONTENT_UNKNOWN:
4528
0
            fprintf(output, "[unknown] ");
4529
0
            break;
4530
0
        case XML_SCHEMA_CONTENT_EMPTY:
4531
0
            fprintf(output, "[empty] ");
4532
0
            break;
4533
0
        case XML_SCHEMA_CONTENT_ELEMENTS:
4534
0
            fprintf(output, "[element] ");
4535
0
            break;
4536
0
        case XML_SCHEMA_CONTENT_MIXED:
4537
0
            fprintf(output, "[mixed] ");
4538
0
            break;
4539
0
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4540
  /* not used. */
4541
0
            break;
4542
0
        case XML_SCHEMA_CONTENT_BASIC:
4543
0
            fprintf(output, "[basic] ");
4544
0
            break;
4545
0
        case XML_SCHEMA_CONTENT_SIMPLE:
4546
0
            fprintf(output, "[simple] ");
4547
0
            break;
4548
0
        case XML_SCHEMA_CONTENT_ANY:
4549
0
            fprintf(output, "[any] ");
4550
0
            break;
4551
0
    }
4552
0
    fprintf(output, "\n");
4553
0
    if (type->base != NULL) {
4554
0
        fprintf(output, "  base type: '%s'", type->base);
4555
0
  if (type->baseNs != NULL)
4556
0
      fprintf(output, " ns '%s'\n", type->baseNs);
4557
0
  else
4558
0
      fprintf(output, "\n");
4559
0
    }
4560
0
    if (type->attrUses != NULL)
4561
0
  xmlSchemaAttrUsesDump(type->attrUses, output);
4562
0
    if (type->annot != NULL)
4563
0
        xmlSchemaAnnotDump(output, type->annot);
4564
0
#ifdef DUMP_CONTENT_MODEL
4565
0
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4566
0
  (type->subtypes != NULL)) {
4567
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4568
0
      output, 1);
4569
0
    }
4570
0
#endif
4571
0
}
4572
4573
static void
4574
xmlSchemaTypeDumpEntry(void *type, void *output,
4575
                       const xmlChar *name ATTRIBUTE_UNUSED)
4576
0
{
4577
0
    xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4578
0
}
4579
4580
/**
4581
 * xmlSchemaDump:
4582
 * @output:  the file output
4583
 * @schema:  a schema structure
4584
 *
4585
 * Dump a Schema structure.
4586
 */
4587
void
4588
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4589
0
{
4590
0
    if (output == NULL)
4591
0
        return;
4592
0
    if (schema == NULL) {
4593
0
        fprintf(output, "Schemas: NULL\n");
4594
0
        return;
4595
0
    }
4596
0
    fprintf(output, "Schemas: ");
4597
0
    if (schema->name != NULL)
4598
0
        fprintf(output, "%s, ", schema->name);
4599
0
    else
4600
0
        fprintf(output, "no name, ");
4601
0
    if (schema->targetNamespace != NULL)
4602
0
        fprintf(output, "%s", (const char *) schema->targetNamespace);
4603
0
    else
4604
0
        fprintf(output, "no target namespace");
4605
0
    fprintf(output, "\n");
4606
0
    if (schema->annot != NULL)
4607
0
        xmlSchemaAnnotDump(output, schema->annot);
4608
0
    xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4609
0
    xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4610
0
}
4611
4612
#endif /* LIBXML_OUTPUT_ENABLED */
4613
4614
/************************************************************************
4615
 *                  *
4616
 *      Utilities         *
4617
 *                  *
4618
 ************************************************************************/
4619
4620
/**
4621
 * xmlSchemaGetPropNode:
4622
 * @node: the element node
4623
 * @name: the name of the attribute
4624
 *
4625
 * Seeks an attribute with a name of @name in
4626
 * no namespace.
4627
 *
4628
 * Returns the attribute or NULL if not present.
4629
 */
4630
static xmlAttrPtr
4631
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4632
0
{
4633
0
    xmlAttrPtr prop;
4634
4635
0
    if ((node == NULL) || (name == NULL))
4636
0
  return(NULL);
4637
0
    prop = node->properties;
4638
0
    while (prop != NULL) {
4639
0
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4640
0
      return(prop);
4641
0
  prop = prop->next;
4642
0
    }
4643
0
    return (NULL);
4644
0
}
4645
4646
/**
4647
 * xmlSchemaGetPropNodeNs:
4648
 * @node: the element node
4649
 * @uri: the uri
4650
 * @name: the name of the attribute
4651
 *
4652
 * Seeks an attribute with a local name of @name and
4653
 * a namespace URI of @uri.
4654
 *
4655
 * Returns the attribute or NULL if not present.
4656
 */
4657
static xmlAttrPtr
4658
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4659
0
{
4660
0
    xmlAttrPtr prop;
4661
4662
0
    if ((node == NULL) || (name == NULL))
4663
0
  return(NULL);
4664
0
    prop = node->properties;
4665
0
    while (prop != NULL) {
4666
0
  if ((prop->ns != NULL) &&
4667
0
      xmlStrEqual(prop->name, BAD_CAST name) &&
4668
0
      xmlStrEqual(prop->ns->href, BAD_CAST uri))
4669
0
      return(prop);
4670
0
  prop = prop->next;
4671
0
    }
4672
0
    return (NULL);
4673
0
}
4674
4675
static const xmlChar *
4676
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4677
0
{
4678
0
    xmlChar *val;
4679
0
    const xmlChar *ret;
4680
4681
0
    val = xmlNodeGetContent(node);
4682
0
    if (val == NULL)
4683
0
  val = xmlStrdup((xmlChar *)"");
4684
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4685
0
    xmlFree(val);
4686
0
    if (ret == NULL)
4687
0
        xmlSchemaPErrMemory(ctxt);
4688
0
    return(ret);
4689
0
}
4690
4691
static const xmlChar *
4692
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4693
0
{
4694
0
    return((const xmlChar*) xmlNodeGetContent(node));
4695
0
}
4696
4697
/**
4698
 * xmlSchemaGetProp:
4699
 * @ctxt: the parser context
4700
 * @node: the node
4701
 * @name: the property name
4702
 *
4703
 * Read a attribute value and internalize the string
4704
 *
4705
 * Returns the string or NULL if not present.
4706
 */
4707
static const xmlChar *
4708
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4709
                 const char *name)
4710
0
{
4711
0
    xmlChar *val;
4712
0
    const xmlChar *ret;
4713
4714
0
    val = xmlGetNoNsProp(node, BAD_CAST name);
4715
0
    if (val == NULL)
4716
0
        return(NULL);
4717
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4718
0
    xmlFree(val);
4719
0
    return(ret);
4720
0
}
4721
4722
/************************************************************************
4723
 *                  *
4724
 *      Parsing functions       *
4725
 *                  *
4726
 ************************************************************************/
4727
4728
#define WXS_FIND_GLOBAL_ITEM(slot)      \
4729
0
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4730
0
  ret = xmlHashLookup(schema->slot, name); \
4731
0
  if (ret != NULL) goto exit; \
4732
0
    } \
4733
0
    if (xmlHashSize(schema->schemasImports) > 1) { \
4734
0
  xmlSchemaImportPtr import; \
4735
0
  if (nsName == NULL) \
4736
0
      import = xmlHashLookup(schema->schemasImports, \
4737
0
    XML_SCHEMAS_NO_NAMESPACE); \
4738
0
  else \
4739
0
      import = xmlHashLookup(schema->schemasImports, nsName); \
4740
0
  if (import == NULL) \
4741
0
      goto exit; \
4742
0
  ret = xmlHashLookup(import->schema->slot, name); \
4743
0
    }
4744
4745
/**
4746
 * xmlSchemaGetElem:
4747
 * @schema:  the schema context
4748
 * @name:  the element name
4749
 * @ns:  the element namespace
4750
 *
4751
 * Lookup a global element declaration in the schema.
4752
 *
4753
 * Returns the element declaration or NULL if not found.
4754
 */
4755
static xmlSchemaElementPtr
4756
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4757
                 const xmlChar * nsName)
4758
0
{
4759
0
    xmlSchemaElementPtr ret = NULL;
4760
4761
0
    if ((name == NULL) || (schema == NULL))
4762
0
        return(NULL);
4763
0
    if (schema != NULL) {
4764
0
  WXS_FIND_GLOBAL_ITEM(elemDecl)
4765
0
    }
4766
0
exit:
4767
0
    return (ret);
4768
0
}
4769
4770
/**
4771
 * xmlSchemaGetType:
4772
 * @schema:  the main schema
4773
 * @name:  the type's name
4774
 * nsName:  the type's namespace
4775
 *
4776
 * Lookup a type in the schemas or the predefined types
4777
 *
4778
 * Returns the group definition or NULL if not found.
4779
 */
4780
static xmlSchemaTypePtr
4781
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4782
                 const xmlChar * nsName)
4783
0
{
4784
0
    xmlSchemaTypePtr ret = NULL;
4785
4786
0
    if (name == NULL)
4787
0
        return (NULL);
4788
    /* First try the built-in types. */
4789
0
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4790
0
  ret = xmlSchemaGetPredefinedType(name, nsName);
4791
0
  if (ret != NULL)
4792
0
      goto exit;
4793
  /*
4794
  * Note that we try the parsed schemas as well here
4795
  * since one might have parsed the S4S, which contain more
4796
  * than the built-in types.
4797
  * TODO: Can we optimize this?
4798
  */
4799
0
    }
4800
0
    if (schema != NULL) {
4801
0
  WXS_FIND_GLOBAL_ITEM(typeDecl)
4802
0
    }
4803
0
exit:
4804
4805
0
    return (ret);
4806
0
}
4807
4808
/**
4809
 * xmlSchemaGetAttributeDecl:
4810
 * @schema:  the context of the schema
4811
 * @name:  the name of the attribute
4812
 * @ns:  the target namespace of the attribute
4813
 *
4814
 * Lookup a an attribute in the schema or imported schemas
4815
 *
4816
 * Returns the attribute declaration or NULL if not found.
4817
 */
4818
static xmlSchemaAttributePtr
4819
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4820
                 const xmlChar * nsName)
4821
0
{
4822
0
    xmlSchemaAttributePtr ret = NULL;
4823
4824
0
    if ((name == NULL) || (schema == NULL))
4825
0
        return (NULL);
4826
0
    if (schema != NULL) {
4827
0
  WXS_FIND_GLOBAL_ITEM(attrDecl)
4828
0
    }
4829
0
exit:
4830
0
    return (ret);
4831
0
}
4832
4833
/**
4834
 * xmlSchemaGetAttributeGroup:
4835
 * @schema:  the context of the schema
4836
 * @name:  the name of the attribute group
4837
 * @ns:  the target namespace of the attribute group
4838
 *
4839
 * Lookup a an attribute group in the schema or imported schemas
4840
 *
4841
 * Returns the attribute group definition or NULL if not found.
4842
 */
4843
static xmlSchemaAttributeGroupPtr
4844
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4845
                 const xmlChar * nsName)
4846
0
{
4847
0
    xmlSchemaAttributeGroupPtr ret = NULL;
4848
4849
0
    if ((name == NULL) || (schema == NULL))
4850
0
        return (NULL);
4851
0
    if (schema != NULL) {
4852
0
  WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4853
0
    }
4854
0
exit:
4855
    /* TODO:
4856
    if ((ret != NULL) && (ret->redef != NULL)) {
4857
  * Return the last redefinition. *
4858
  ret = ret->redef;
4859
    }
4860
    */
4861
0
    return (ret);
4862
0
}
4863
4864
/**
4865
 * xmlSchemaGetGroup:
4866
 * @schema:  the context of the schema
4867
 * @name:  the name of the group
4868
 * @ns:  the target namespace of the group
4869
 *
4870
 * Lookup a group in the schema or imported schemas
4871
 *
4872
 * Returns the group definition or NULL if not found.
4873
 */
4874
static xmlSchemaModelGroupDefPtr
4875
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4876
                 const xmlChar * nsName)
4877
0
{
4878
0
    xmlSchemaModelGroupDefPtr ret = NULL;
4879
4880
0
    if ((name == NULL) || (schema == NULL))
4881
0
        return (NULL);
4882
0
    if (schema != NULL) {
4883
0
  WXS_FIND_GLOBAL_ITEM(groupDecl)
4884
0
    }
4885
0
exit:
4886
4887
0
    return (ret);
4888
0
}
4889
4890
static xmlSchemaNotationPtr
4891
xmlSchemaGetNotation(xmlSchemaPtr schema,
4892
         const xmlChar *name,
4893
         const xmlChar *nsName)
4894
0
{
4895
0
    xmlSchemaNotationPtr ret = NULL;
4896
4897
0
    if ((name == NULL) || (schema == NULL))
4898
0
        return (NULL);
4899
0
    if (schema != NULL) {
4900
0
  WXS_FIND_GLOBAL_ITEM(notaDecl)
4901
0
    }
4902
0
exit:
4903
0
    return (ret);
4904
0
}
4905
4906
static xmlSchemaIDCPtr
4907
xmlSchemaGetIDC(xmlSchemaPtr schema,
4908
    const xmlChar *name,
4909
    const xmlChar *nsName)
4910
0
{
4911
0
    xmlSchemaIDCPtr ret = NULL;
4912
4913
0
    if ((name == NULL) || (schema == NULL))
4914
0
        return (NULL);
4915
0
    if (schema != NULL) {
4916
0
  WXS_FIND_GLOBAL_ITEM(idcDef)
4917
0
    }
4918
0
exit:
4919
0
    return (ret);
4920
0
}
4921
4922
/**
4923
 * xmlSchemaGetNamedComponent:
4924
 * @schema:  the schema
4925
 * @name:  the name of the group
4926
 * @ns:  the target namespace of the group
4927
 *
4928
 * Lookup a group in the schema or imported schemas
4929
 *
4930
 * Returns the group definition or NULL if not found.
4931
 */
4932
static xmlSchemaBasicItemPtr
4933
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4934
         xmlSchemaTypeType itemType,
4935
         const xmlChar *name,
4936
         const xmlChar *targetNs)
4937
0
{
4938
0
    switch (itemType) {
4939
0
  case XML_SCHEMA_TYPE_GROUP:
4940
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4941
0
    name, targetNs));
4942
0
  case XML_SCHEMA_TYPE_ELEMENT:
4943
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4944
0
    name, targetNs));
4945
0
  default:
4946
      /* TODO */
4947
0
      return (NULL);
4948
0
    }
4949
0
}
4950
4951
/************************************************************************
4952
 *                  *
4953
 *      Parsing functions       *
4954
 *                  *
4955
 ************************************************************************/
4956
4957
#define IS_BLANK_NODE(n)            \
4958
0
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4959
4960
/**
4961
 * xmlSchemaIsBlank:
4962
 * @str:  a string
4963
 * @len: the length of the string or -1
4964
 *
4965
 * Check if a string is ignorable
4966
 *
4967
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4968
 */
4969
static int
4970
xmlSchemaIsBlank(xmlChar * str, int len)
4971
0
{
4972
0
    if (str == NULL)
4973
0
        return (1);
4974
0
    if (len < 0) {
4975
0
  while (*str != 0) {
4976
0
      if (!(IS_BLANK_CH(*str)))
4977
0
    return (0);
4978
0
      str++;
4979
0
  }
4980
0
    } else while ((*str != 0) && (len != 0)) {
4981
0
  if (!(IS_BLANK_CH(*str)))
4982
0
      return (0);
4983
0
  str++;
4984
0
  len--;
4985
0
    }
4986
4987
0
    return (1);
4988
0
}
4989
4990
0
#define WXS_COMP_NAME(c, t) ((t) (c))->name
4991
0
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
4992
/*
4993
* xmlSchemaFindRedefCompInGraph:
4994
* ATTENTION TODO: This uses pointer comp. for strings.
4995
*/
4996
static xmlSchemaBasicItemPtr
4997
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
4998
            xmlSchemaTypeType type,
4999
            const xmlChar *name,
5000
            const xmlChar *nsName)
5001
0
{
5002
0
    xmlSchemaBasicItemPtr ret;
5003
0
    int i;
5004
5005
0
    if ((bucket == NULL) || (name == NULL))
5006
0
  return(NULL);
5007
0
    if ((bucket->globals == NULL) ||
5008
0
  (bucket->globals->nbItems == 0))
5009
0
  goto subschemas;
5010
    /*
5011
    * Search in global components.
5012
    */
5013
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
5014
0
  ret = bucket->globals->items[i];
5015
0
  if (ret->type == type) {
5016
0
      switch (type) {
5017
0
    case XML_SCHEMA_TYPE_COMPLEX:
5018
0
    case XML_SCHEMA_TYPE_SIMPLE:
5019
0
        if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5020
0
      (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5021
0
      nsName))
5022
0
        {
5023
0
      return(ret);
5024
0
        }
5025
0
        break;
5026
0
    case XML_SCHEMA_TYPE_GROUP:
5027
0
        if ((WXS_COMP_NAME(ret,
5028
0
          xmlSchemaModelGroupDefPtr) == name) &&
5029
0
      (WXS_COMP_TNS(ret,
5030
0
          xmlSchemaModelGroupDefPtr) == nsName))
5031
0
        {
5032
0
      return(ret);
5033
0
        }
5034
0
        break;
5035
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5036
0
        if ((WXS_COMP_NAME(ret,
5037
0
          xmlSchemaAttributeGroupPtr) == name) &&
5038
0
      (WXS_COMP_TNS(ret,
5039
0
          xmlSchemaAttributeGroupPtr) == nsName))
5040
0
        {
5041
0
      return(ret);
5042
0
        }
5043
0
        break;
5044
0
    default:
5045
        /* Should not be hit. */
5046
0
        return(NULL);
5047
0
      }
5048
0
  }
5049
0
    }
5050
0
subschemas:
5051
    /*
5052
    * Process imported/included schemas.
5053
    */
5054
0
    if (bucket->relations != NULL) {
5055
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
5056
5057
  /*
5058
  * TODO: Marking the bucket will not avoid multiple searches
5059
  * in the same schema, but avoids at least circularity.
5060
  */
5061
0
  bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5062
0
  do {
5063
0
      if ((rel->bucket != NULL) &&
5064
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5065
0
    ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5066
0
        type, name, nsName);
5067
0
    if (ret != NULL)
5068
0
        return(ret);
5069
0
      }
5070
0
      rel = rel->next;
5071
0
  } while (rel != NULL);
5072
0
   bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5073
0
    }
5074
0
    return(NULL);
5075
0
}
5076
5077
/**
5078
 * xmlSchemaAddNotation:
5079
 * @ctxt:  a schema parser context
5080
 * @schema:  the schema being built
5081
 * @name:  the item name
5082
 *
5083
 * Add an XML schema annotation declaration
5084
 * *WARNING* this interface is highly subject to change
5085
 *
5086
 * Returns the new structure or NULL in case of error
5087
 */
5088
static xmlSchemaNotationPtr
5089
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5090
                     const xmlChar *name, const xmlChar *nsName,
5091
         xmlNodePtr node ATTRIBUTE_UNUSED)
5092
0
{
5093
0
    xmlSchemaNotationPtr ret = NULL;
5094
5095
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5096
0
        return (NULL);
5097
5098
0
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5099
0
    if (ret == NULL) {
5100
0
        xmlSchemaPErrMemory(ctxt);
5101
0
        return (NULL);
5102
0
    }
5103
0
    memset(ret, 0, sizeof(xmlSchemaNotation));
5104
0
    ret->type = XML_SCHEMA_TYPE_NOTATION;
5105
0
    ret->name = name;
5106
0
    ret->targetNamespace = nsName;
5107
    /* TODO: do we need the node to be set?
5108
    * ret->node = node;*/
5109
0
    WXS_ADD_GLOBAL(ctxt, ret);
5110
0
    return (ret);
5111
0
}
5112
5113
/**
5114
 * xmlSchemaAddAttribute:
5115
 * @ctxt:  a schema parser context
5116
 * @schema:  the schema being built
5117
 * @name:  the item name
5118
 * @namespace:  the namespace
5119
 *
5120
 * Add an XML schema Attribute declaration
5121
 * *WARNING* this interface is highly subject to change
5122
 *
5123
 * Returns the new structure or NULL in case of error
5124
 */
5125
static xmlSchemaAttributePtr
5126
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5127
                      const xmlChar * name, const xmlChar * nsName,
5128
          xmlNodePtr node, int topLevel)
5129
0
{
5130
0
    xmlSchemaAttributePtr ret = NULL;
5131
5132
0
    if ((ctxt == NULL) || (schema == NULL))
5133
0
        return (NULL);
5134
5135
0
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5136
0
    if (ret == NULL) {
5137
0
        xmlSchemaPErrMemory(ctxt);
5138
0
        return (NULL);
5139
0
    }
5140
0
    memset(ret, 0, sizeof(xmlSchemaAttribute));
5141
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5142
0
    ret->node = node;
5143
0
    ret->name = name;
5144
0
    ret->targetNamespace = nsName;
5145
5146
0
    if (topLevel)
5147
0
  WXS_ADD_GLOBAL(ctxt, ret);
5148
0
    else
5149
0
  WXS_ADD_LOCAL(ctxt, ret);
5150
0
    WXS_ADD_PENDING(ctxt, ret);
5151
0
    return (ret);
5152
0
}
5153
5154
/**
5155
 * xmlSchemaAddAttributeUse:
5156
 * @ctxt:  a schema parser context
5157
 * @schema:  the schema being built
5158
 * @name:  the item name
5159
 * @namespace:  the namespace
5160
 *
5161
 * Add an XML schema Attribute declaration
5162
 * *WARNING* this interface is highly subject to change
5163
 *
5164
 * Returns the new structure or NULL in case of error
5165
 */
5166
static xmlSchemaAttributeUsePtr
5167
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5168
       xmlNodePtr node)
5169
0
{
5170
0
    xmlSchemaAttributeUsePtr ret = NULL;
5171
5172
0
    if (pctxt == NULL)
5173
0
        return (NULL);
5174
5175
0
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5176
0
    if (ret == NULL) {
5177
0
        xmlSchemaPErrMemory(pctxt);
5178
0
        return (NULL);
5179
0
    }
5180
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5181
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5182
0
    ret->node = node;
5183
5184
0
    WXS_ADD_LOCAL(pctxt, ret);
5185
0
    return (ret);
5186
0
}
5187
5188
/*
5189
* xmlSchemaAddRedef:
5190
*
5191
* Adds a redefinition information. This is used at a later stage to:
5192
* resolve references to the redefined components and to check constraints.
5193
*/
5194
static xmlSchemaRedefPtr
5195
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5196
      xmlSchemaBucketPtr targetBucket,
5197
      void *item,
5198
      const xmlChar *refName,
5199
      const xmlChar *refTargetNs)
5200
0
{
5201
0
    xmlSchemaRedefPtr ret;
5202
5203
0
    ret = (xmlSchemaRedefPtr)
5204
0
  xmlMalloc(sizeof(xmlSchemaRedef));
5205
0
    if (ret == NULL) {
5206
0
  xmlSchemaPErrMemory(pctxt);
5207
0
  return (NULL);
5208
0
    }
5209
0
    memset(ret, 0, sizeof(xmlSchemaRedef));
5210
0
    ret->item = item;
5211
0
    ret->targetBucket = targetBucket;
5212
0
    ret->refName = refName;
5213
0
    ret->refTargetNs = refTargetNs;
5214
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5215
0
  WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5216
0
    else
5217
0
  WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5218
0
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5219
5220
0
    return (ret);
5221
0
}
5222
5223
/**
5224
 * xmlSchemaAddAttributeGroupDefinition:
5225
 * @ctxt:  a schema parser context
5226
 * @schema:  the schema being built
5227
 * @name:  the item name
5228
 * @nsName:  the target namespace
5229
 * @node: the corresponding node
5230
 *
5231
 * Add an XML schema Attribute Group definition.
5232
 *
5233
 * Returns the new structure or NULL in case of error
5234
 */
5235
static xmlSchemaAttributeGroupPtr
5236
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5237
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5238
         const xmlChar *name,
5239
         const xmlChar *nsName,
5240
         xmlNodePtr node)
5241
0
{
5242
0
    xmlSchemaAttributeGroupPtr ret = NULL;
5243
5244
0
    if ((pctxt == NULL) || (name == NULL))
5245
0
        return (NULL);
5246
5247
0
    ret = (xmlSchemaAttributeGroupPtr)
5248
0
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5249
0
    if (ret == NULL) {
5250
0
  xmlSchemaPErrMemory(pctxt);
5251
0
  return (NULL);
5252
0
    }
5253
0
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5254
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5255
0
    ret->name = name;
5256
0
    ret->targetNamespace = nsName;
5257
0
    ret->node = node;
5258
5259
    /* TODO: Remove the flag. */
5260
0
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5261
0
    if (pctxt->isRedefine) {
5262
0
  pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5263
0
      ret, name, nsName);
5264
0
  if (pctxt->redef == NULL) {
5265
0
      xmlFree(ret);
5266
0
      return(NULL);
5267
0
  }
5268
0
  pctxt->redefCounter = 0;
5269
0
    }
5270
0
    WXS_ADD_GLOBAL(pctxt, ret);
5271
0
    WXS_ADD_PENDING(pctxt, ret);
5272
0
    return (ret);
5273
0
}
5274
5275
/**
5276
 * xmlSchemaAddElement:
5277
 * @ctxt:  a schema parser context
5278
 * @schema:  the schema being built
5279
 * @name:  the type name
5280
 * @namespace:  the type namespace
5281
 *
5282
 * Add an XML schema Element declaration
5283
 * *WARNING* this interface is highly subject to change
5284
 *
5285
 * Returns the new structure or NULL in case of error
5286
 */
5287
static xmlSchemaElementPtr
5288
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5289
                    const xmlChar * name, const xmlChar * nsName,
5290
        xmlNodePtr node, int topLevel)
5291
0
{
5292
0
    xmlSchemaElementPtr ret = NULL;
5293
5294
0
    if ((ctxt == NULL) || (name == NULL))
5295
0
        return (NULL);
5296
5297
0
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5298
0
    if (ret == NULL) {
5299
0
        xmlSchemaPErrMemory(ctxt);
5300
0
        return (NULL);
5301
0
    }
5302
0
    memset(ret, 0, sizeof(xmlSchemaElement));
5303
0
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5304
0
    ret->name = name;
5305
0
    ret->targetNamespace = nsName;
5306
0
    ret->node = node;
5307
5308
0
    if (topLevel)
5309
0
  WXS_ADD_GLOBAL(ctxt, ret);
5310
0
    else
5311
0
  WXS_ADD_LOCAL(ctxt, ret);
5312
0
    WXS_ADD_PENDING(ctxt, ret);
5313
0
    return (ret);
5314
0
}
5315
5316
/**
5317
 * xmlSchemaAddType:
5318
 * @ctxt:  a schema parser context
5319
 * @schema:  the schema being built
5320
 * @name:  the item name
5321
 * @namespace:  the namespace
5322
 *
5323
 * Add an XML schema item
5324
 * *WARNING* this interface is highly subject to change
5325
 *
5326
 * Returns the new structure or NULL in case of error
5327
 */
5328
static xmlSchemaTypePtr
5329
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5330
     xmlSchemaTypeType type,
5331
                 const xmlChar * name, const xmlChar * nsName,
5332
     xmlNodePtr node, int topLevel)
5333
0
{
5334
0
    xmlSchemaTypePtr ret = NULL;
5335
5336
0
    if ((ctxt == NULL) || (schema == NULL))
5337
0
        return (NULL);
5338
5339
0
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5340
0
    if (ret == NULL) {
5341
0
        xmlSchemaPErrMemory(ctxt);
5342
0
        return (NULL);
5343
0
    }
5344
0
    memset(ret, 0, sizeof(xmlSchemaType));
5345
0
    ret->type = type;
5346
0
    ret->name = name;
5347
0
    ret->targetNamespace = nsName;
5348
0
    ret->node = node;
5349
0
    if (topLevel) {
5350
0
  if (ctxt->isRedefine) {
5351
0
      ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5352
0
    ret, name, nsName);
5353
0
      if (ctxt->redef == NULL) {
5354
0
    xmlFree(ret);
5355
0
    return(NULL);
5356
0
      }
5357
0
      ctxt->redefCounter = 0;
5358
0
  }
5359
0
  WXS_ADD_GLOBAL(ctxt, ret);
5360
0
    } else
5361
0
  WXS_ADD_LOCAL(ctxt, ret);
5362
0
    WXS_ADD_PENDING(ctxt, ret);
5363
0
    return (ret);
5364
0
}
5365
5366
static xmlSchemaQNameRefPtr
5367
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5368
         xmlSchemaTypeType refType,
5369
         const xmlChar *refName,
5370
         const xmlChar *refNs)
5371
0
{
5372
0
    xmlSchemaQNameRefPtr ret;
5373
5374
0
    ret = (xmlSchemaQNameRefPtr)
5375
0
  xmlMalloc(sizeof(xmlSchemaQNameRef));
5376
0
    if (ret == NULL) {
5377
0
  xmlSchemaPErrMemory(pctxt);
5378
0
  return (NULL);
5379
0
    }
5380
0
    ret->node = NULL;
5381
0
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5382
0
    ret->name = refName;
5383
0
    ret->targetNamespace = refNs;
5384
0
    ret->item = NULL;
5385
0
    ret->itemType = refType;
5386
    /*
5387
    * Store the reference item in the schema.
5388
    */
5389
0
    WXS_ADD_LOCAL(pctxt, ret);
5390
0
    return (ret);
5391
0
}
5392
5393
static xmlSchemaAttributeUseProhibPtr
5394
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5395
0
{
5396
0
    xmlSchemaAttributeUseProhibPtr ret;
5397
5398
0
    ret = (xmlSchemaAttributeUseProhibPtr)
5399
0
  xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5400
0
    if (ret == NULL) {
5401
0
  xmlSchemaPErrMemory(pctxt);
5402
0
  return (NULL);
5403
0
    }
5404
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5405
0
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5406
0
    WXS_ADD_LOCAL(pctxt, ret);
5407
0
    return (ret);
5408
0
}
5409
5410
5411
/**
5412
 * xmlSchemaAddModelGroup:
5413
 * @ctxt:  a schema parser context
5414
 * @schema:  the schema being built
5415
 * @type: the "compositor" type of the model group
5416
 * @node: the node in the schema doc
5417
 *
5418
 * Adds a schema model group
5419
 * *WARNING* this interface is highly subject to change
5420
 *
5421
 * Returns the new structure or NULL in case of error
5422
 */
5423
static xmlSchemaModelGroupPtr
5424
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5425
           xmlSchemaPtr schema,
5426
           xmlSchemaTypeType type,
5427
           xmlNodePtr node)
5428
0
{
5429
0
    xmlSchemaModelGroupPtr ret = NULL;
5430
5431
0
    if ((ctxt == NULL) || (schema == NULL))
5432
0
        return (NULL);
5433
5434
0
    ret = (xmlSchemaModelGroupPtr)
5435
0
  xmlMalloc(sizeof(xmlSchemaModelGroup));
5436
0
    if (ret == NULL) {
5437
0
  xmlSchemaPErrMemory(ctxt);
5438
0
  return (NULL);
5439
0
    }
5440
0
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5441
0
    ret->type = type;
5442
0
    ret->node = node;
5443
0
    WXS_ADD_LOCAL(ctxt, ret);
5444
0
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5445
0
  (type == XML_SCHEMA_TYPE_CHOICE))
5446
0
  WXS_ADD_PENDING(ctxt, ret);
5447
0
    return (ret);
5448
0
}
5449
5450
5451
/**
5452
 * xmlSchemaAddParticle:
5453
 * @ctxt:  a schema parser context
5454
 * @schema:  the schema being built
5455
 * @node: the corresponding node in the schema doc
5456
 * @min: the minOccurs
5457
 * @max: the maxOccurs
5458
 *
5459
 * Adds an XML schema particle component.
5460
 * *WARNING* this interface is highly subject to change
5461
 *
5462
 * Returns the new structure or NULL in case of error
5463
 */
5464
static xmlSchemaParticlePtr
5465
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5466
         xmlNodePtr node, int min, int max)
5467
0
{
5468
0
    xmlSchemaParticlePtr ret = NULL;
5469
0
    if (ctxt == NULL)
5470
0
        return (NULL);
5471
5472
0
    ret = (xmlSchemaParticlePtr)
5473
0
  xmlMalloc(sizeof(xmlSchemaParticle));
5474
0
    if (ret == NULL) {
5475
0
  xmlSchemaPErrMemory(ctxt);
5476
0
  return (NULL);
5477
0
    }
5478
0
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5479
0
    ret->annot = NULL;
5480
0
    ret->node = node;
5481
0
    ret->minOccurs = min;
5482
0
    ret->maxOccurs = max;
5483
0
    ret->next = NULL;
5484
0
    ret->children = NULL;
5485
5486
0
    WXS_ADD_LOCAL(ctxt, ret);
5487
    /*
5488
    * Note that addition to pending components will be done locally
5489
    * to the specific parsing function, since the most particles
5490
    * need not to be fixed up (i.e. the reference to be resolved).
5491
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5492
    */
5493
0
    return (ret);
5494
0
}
5495
5496
/**
5497
 * xmlSchemaAddModelGroupDefinition:
5498
 * @ctxt:  a schema validation context
5499
 * @schema:  the schema being built
5500
 * @name:  the group name
5501
 *
5502
 * Add an XML schema Group definition
5503
 *
5504
 * Returns the new structure or NULL in case of error
5505
 */
5506
static xmlSchemaModelGroupDefPtr
5507
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5508
         xmlSchemaPtr schema,
5509
         const xmlChar *name,
5510
         const xmlChar *nsName,
5511
         xmlNodePtr node)
5512
0
{
5513
0
    xmlSchemaModelGroupDefPtr ret = NULL;
5514
5515
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5516
0
        return (NULL);
5517
5518
0
    ret = (xmlSchemaModelGroupDefPtr)
5519
0
  xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5520
0
    if (ret == NULL) {
5521
0
        xmlSchemaPErrMemory(ctxt);
5522
0
        return (NULL);
5523
0
    }
5524
0
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5525
0
    ret->name = name;
5526
0
    ret->type = XML_SCHEMA_TYPE_GROUP;
5527
0
    ret->node = node;
5528
0
    ret->targetNamespace = nsName;
5529
5530
0
    if (ctxt->isRedefine) {
5531
0
  ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5532
0
      ret, name, nsName);
5533
0
  if (ctxt->redef == NULL) {
5534
0
      xmlFree(ret);
5535
0
      return(NULL);
5536
0
  }
5537
0
  ctxt->redefCounter = 0;
5538
0
    }
5539
0
    WXS_ADD_GLOBAL(ctxt, ret);
5540
0
    WXS_ADD_PENDING(ctxt, ret);
5541
0
    return (ret);
5542
0
}
5543
5544
/**
5545
 * xmlSchemaNewWildcardNs:
5546
 * @ctxt:  a schema validation context
5547
 *
5548
 * Creates a new wildcard namespace constraint.
5549
 *
5550
 * Returns the new structure or NULL in case of error
5551
 */
5552
static xmlSchemaWildcardNsPtr
5553
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5554
0
{
5555
0
    xmlSchemaWildcardNsPtr ret;
5556
5557
0
    ret = (xmlSchemaWildcardNsPtr)
5558
0
  xmlMalloc(sizeof(xmlSchemaWildcardNs));
5559
0
    if (ret == NULL) {
5560
0
  xmlSchemaPErrMemory(ctxt);
5561
0
  return (NULL);
5562
0
    }
5563
0
    ret->value = NULL;
5564
0
    ret->next = NULL;
5565
0
    return (ret);
5566
0
}
5567
5568
static xmlSchemaIDCPtr
5569
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5570
                  const xmlChar *name, const xmlChar *nsName,
5571
      int category, xmlNodePtr node)
5572
0
{
5573
0
    xmlSchemaIDCPtr ret = NULL;
5574
5575
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5576
0
        return (NULL);
5577
5578
0
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5579
0
    if (ret == NULL) {
5580
0
        xmlSchemaPErrMemory(ctxt);
5581
0
        return (NULL);
5582
0
    }
5583
0
    memset(ret, 0, sizeof(xmlSchemaIDC));
5584
    /* The target namespace of the parent element declaration. */
5585
0
    ret->targetNamespace = nsName;
5586
0
    ret->name = name;
5587
0
    ret->type = category;
5588
0
    ret->node = node;
5589
5590
0
    WXS_ADD_GLOBAL(ctxt, ret);
5591
    /*
5592
    * Only keyrefs need to be fixup up.
5593
    */
5594
0
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5595
0
  WXS_ADD_PENDING(ctxt, ret);
5596
0
    return (ret);
5597
0
}
5598
5599
/**
5600
 * xmlSchemaAddWildcard:
5601
 * @ctxt:  a schema validation context
5602
 * @schema: a schema
5603
 *
5604
 * Adds a wildcard.
5605
 * It corresponds to a xsd:anyAttribute and xsd:any.
5606
 *
5607
 * Returns the new structure or NULL in case of error
5608
 */
5609
static xmlSchemaWildcardPtr
5610
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5611
         xmlSchemaTypeType type, xmlNodePtr node)
5612
0
{
5613
0
    xmlSchemaWildcardPtr ret = NULL;
5614
5615
0
    if ((ctxt == NULL) || (schema == NULL))
5616
0
        return (NULL);
5617
5618
0
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5619
0
    if (ret == NULL) {
5620
0
        xmlSchemaPErrMemory(ctxt);
5621
0
        return (NULL);
5622
0
    }
5623
0
    memset(ret, 0, sizeof(xmlSchemaWildcard));
5624
0
    ret->type = type;
5625
0
    ret->node = node;
5626
0
    WXS_ADD_LOCAL(ctxt, ret);
5627
0
    return (ret);
5628
0
}
5629
5630
static void
5631
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5632
0
{
5633
0
    if (group == NULL)
5634
0
  return;
5635
0
    if (group->members != NULL)
5636
0
  xmlSchemaItemListFree(group->members);
5637
0
    xmlFree(group);
5638
0
}
5639
5640
static void
5641
xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5642
0
{
5643
0
    xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5644
0
}
5645
5646
static xmlSchemaSubstGroupPtr
5647
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5648
           xmlSchemaElementPtr head)
5649
0
{
5650
0
    xmlSchemaSubstGroupPtr ret;
5651
5652
    /* Init subst group hash. */
5653
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5654
0
  WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5655
0
  if (WXS_SUBST_GROUPS(pctxt) == NULL)
5656
0
      return(NULL);
5657
0
    }
5658
    /* Create a new substitution group. */
5659
0
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5660
0
    if (ret == NULL) {
5661
0
  xmlSchemaPErrMemory(NULL);
5662
0
  return(NULL);
5663
0
    }
5664
0
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5665
0
    ret->head = head;
5666
    /* Create list of members. */
5667
0
    ret->members = xmlSchemaItemListCreate();
5668
0
    if (ret->members == NULL) {
5669
0
  xmlSchemaSubstGroupFree(ret);
5670
0
  return(NULL);
5671
0
    }
5672
    /* Add subst group to hash. */
5673
0
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5674
0
  head->name, head->targetNamespace, ret) != 0) {
5675
0
  PERROR_INT("xmlSchemaSubstGroupAdd",
5676
0
      "failed to add a new substitution container");
5677
0
  xmlSchemaSubstGroupFree(ret);
5678
0
  return(NULL);
5679
0
    }
5680
0
    return(ret);
5681
0
}
5682
5683
static xmlSchemaSubstGroupPtr
5684
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5685
           xmlSchemaElementPtr head)
5686
0
{
5687
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5688
0
  return(NULL);
5689
0
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5690
0
  head->name, head->targetNamespace));
5691
5692
0
}
5693
5694
/**
5695
 * xmlSchemaAddElementSubstitutionMember:
5696
 * @pctxt:  a schema parser context
5697
 * @head:  the head of the substitution group
5698
 * @member: the new member of the substitution group
5699
 *
5700
 * Allocate a new annotation structure.
5701
 *
5702
 * Returns the newly allocated structure or NULL in case or error
5703
 */
5704
static int
5705
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5706
              xmlSchemaElementPtr head,
5707
              xmlSchemaElementPtr member)
5708
0
{
5709
0
    xmlSchemaSubstGroupPtr substGroup = NULL;
5710
5711
0
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5712
0
  return (-1);
5713
5714
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5715
0
    if (substGroup == NULL)
5716
0
  substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5717
0
    if (substGroup == NULL)
5718
0
  return(-1);
5719
0
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5720
0
  return(-1);
5721
0
    return(0);
5722
0
}
5723
5724
/************************************************************************
5725
 *                  *
5726
 *    Utilities for parsing         *
5727
 *                  *
5728
 ************************************************************************/
5729
5730
/**
5731
 * xmlSchemaPValAttrNodeQNameValue:
5732
 * @ctxt:  a schema parser context
5733
 * @schema: the schema context
5734
 * @ownerItem: the parent as a schema object
5735
 * @value:  the QName value
5736
 * @uri:  the resulting namespace URI if found
5737
 * @local: the resulting local part if found, the attribute value otherwise
5738
 *
5739
 * Extracts the local name and the URI of a QName value and validates it.
5740
 * This one is intended to be used on attribute values that
5741
 * should resolve to schema components.
5742
 *
5743
 * Returns 0, in case the QName is valid, a positive error code
5744
 * if not valid and -1 if an internal error occurs.
5745
 */
5746
static int
5747
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5748
               xmlSchemaPtr schema,
5749
               xmlSchemaBasicItemPtr ownerItem,
5750
               xmlAttrPtr attr,
5751
               const xmlChar *value,
5752
               const xmlChar **uri,
5753
               const xmlChar **local)
5754
0
{
5755
0
    const xmlChar *pref;
5756
0
    xmlNsPtr ns;
5757
0
    int len, ret;
5758
5759
0
    *uri = NULL;
5760
0
    *local = NULL;
5761
0
    ret = xmlValidateQName(value, 1);
5762
0
    if (ret > 0) {
5763
0
  xmlSchemaPSimpleTypeErr(ctxt,
5764
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5765
0
      ownerItem, (xmlNodePtr) attr,
5766
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5767
0
      NULL, value, NULL, NULL, NULL);
5768
0
  *local = value;
5769
0
  return (ctxt->err);
5770
0
    } else if (ret < 0)
5771
0
  return (-1);
5772
5773
0
    if (!strchr((char *) value, ':')) {
5774
0
  ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5775
0
  if (ns && ns->href && ns->href[0])
5776
0
      *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5777
0
  else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5778
      /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5779
      * parser context. */
5780
      /*
5781
      * This one takes care of included schemas with no
5782
      * target namespace.
5783
      */
5784
0
      *uri = ctxt->targetNamespace;
5785
0
  }
5786
0
  *local = xmlDictLookup(ctxt->dict, value, -1);
5787
0
  return (0);
5788
0
    }
5789
    /*
5790
    * At this point xmlSplitQName3 has to return a local name.
5791
    */
5792
0
    *local = xmlSplitQName3(value, &len);
5793
0
    *local = xmlDictLookup(ctxt->dict, *local, -1);
5794
0
    pref = xmlDictLookup(ctxt->dict, value, len);
5795
0
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5796
0
    if (ns == NULL) {
5797
0
  xmlSchemaPSimpleTypeErr(ctxt,
5798
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5799
0
      ownerItem, (xmlNodePtr) attr,
5800
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5801
0
      "The value '%s' of simple type 'xs:QName' has no "
5802
0
      "corresponding namespace declaration in scope", value, NULL);
5803
0
  return (ctxt->err);
5804
0
    } else {
5805
0
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5806
0
    }
5807
0
    return (0);
5808
0
}
5809
5810
/**
5811
 * xmlSchemaPValAttrNodeQName:
5812
 * @ctxt:  a schema parser context
5813
 * @schema: the schema context
5814
 * @ownerItem: the owner as a schema object
5815
 * @attr:  the attribute node
5816
 * @uri:  the resulting namespace URI if found
5817
 * @local: the resulting local part if found, the attribute value otherwise
5818
 *
5819
 * Extracts and validates the QName of an attribute value.
5820
 * This one is intended to be used on attribute values that
5821
 * should resolve to schema components.
5822
 *
5823
 * Returns 0, in case the QName is valid, a positive error code
5824
 * if not valid and -1 if an internal error occurs.
5825
 */
5826
static int
5827
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5828
               xmlSchemaPtr schema,
5829
               xmlSchemaBasicItemPtr ownerItem,
5830
               xmlAttrPtr attr,
5831
               const xmlChar **uri,
5832
               const xmlChar **local)
5833
0
{
5834
0
    const xmlChar *value;
5835
5836
0
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5837
0
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5838
0
  ownerItem, attr, value, uri, local));
5839
0
}
5840
5841
/**
5842
 * xmlSchemaPValAttrQName:
5843
 * @ctxt:  a schema parser context
5844
 * @schema: the schema context
5845
 * @ownerItem: the owner as a schema object
5846
 * @ownerElem:  the parent node of the attribute
5847
 * @name:  the name of the attribute
5848
 * @uri:  the resulting namespace URI if found
5849
 * @local: the resulting local part if found, the attribute value otherwise
5850
 *
5851
 * Extracts and validates the QName of an attribute value.
5852
 *
5853
 * Returns 0, in case the QName is valid, a positive error code
5854
 * if not valid and -1 if an internal error occurs.
5855
 */
5856
static int
5857
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5858
           xmlSchemaPtr schema,
5859
           xmlSchemaBasicItemPtr ownerItem,
5860
           xmlNodePtr ownerElem,
5861
           const char *name,
5862
           const xmlChar **uri,
5863
           const xmlChar **local)
5864
0
{
5865
0
    xmlAttrPtr attr;
5866
5867
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
5868
0
    if (attr == NULL) {
5869
0
  *local = NULL;
5870
0
  *uri = NULL;
5871
0
  return (0);
5872
0
    }
5873
0
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5874
0
  ownerItem, attr, uri, local));
5875
0
}
5876
5877
/**
5878
 * xmlSchemaPValAttrID:
5879
 * @ctxt:  a schema parser context
5880
 *
5881
 * Extracts and validates the ID of an attribute value.
5882
 *
5883
 * Returns 0, in case the ID is valid, a positive error code
5884
 * if not valid and -1 if an internal error occurs.
5885
 */
5886
static int
5887
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5888
0
{
5889
0
    int ret;
5890
0
    const xmlChar *value;
5891
5892
0
    if (attr == NULL)
5893
0
  return(0);
5894
0
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5895
0
    ret = xmlValidateNCName(value, 1);
5896
0
    if (ret == 0) {
5897
  /*
5898
  * NOTE: the IDness might have already be declared in the DTD
5899
  */
5900
0
  if (attr->atype != XML_ATTRIBUTE_ID) {
5901
0
      xmlChar *strip;
5902
0
            int res;
5903
5904
      /*
5905
      * TODO: Use xmlSchemaStrip here; it's not exported at this
5906
      * moment.
5907
      */
5908
0
      strip = xmlSchemaCollapseString(value);
5909
0
      if (strip != NULL) {
5910
0
    xmlFree((xmlChar *) value);
5911
0
    value = strip;
5912
0
      }
5913
0
      res = xmlAddIDSafe(attr, value);
5914
0
            if (res < 0) {
5915
0
                xmlSchemaPErrMemory(ctxt);
5916
0
      } else if (res == 0) {
5917
0
    ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5918
0
    xmlSchemaPSimpleTypeErr(ctxt,
5919
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5920
0
        NULL, (xmlNodePtr) attr,
5921
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5922
0
        NULL, NULL, "Duplicate value '%s' of simple "
5923
0
        "type 'xs:ID'", value, NULL);
5924
0
      }
5925
0
  }
5926
0
    } else if (ret > 0) {
5927
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5928
0
  xmlSchemaPSimpleTypeErr(ctxt,
5929
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5930
0
      NULL, (xmlNodePtr) attr,
5931
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5932
0
      NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
5933
0
      "not a valid 'xs:NCName'",
5934
0
      value, NULL);
5935
0
    }
5936
0
    if (value != NULL)
5937
0
  xmlFree((xmlChar *)value);
5938
5939
0
    return (ret);
5940
0
}
5941
5942
static int
5943
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5944
        xmlNodePtr ownerElem,
5945
        const xmlChar *name)
5946
0
{
5947
0
    xmlAttrPtr attr;
5948
5949
0
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5950
0
    if (attr == NULL)
5951
0
  return(0);
5952
0
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
5953
5954
0
}
5955
5956
/**
5957
 * xmlGetMaxOccurs:
5958
 * @ctxt:  a schema validation context
5959
 * @node:  a subtree containing XML Schema information
5960
 *
5961
 * Get the maxOccurs property
5962
 *
5963
 * Returns the default if not found, or the value
5964
 */
5965
static int
5966
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5967
    int min, int max, int def, const char *expected)
5968
0
{
5969
0
    const xmlChar *val, *cur;
5970
0
    int ret = 0;
5971
0
    xmlAttrPtr attr;
5972
5973
0
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
5974
0
    if (attr == NULL)
5975
0
  return (def);
5976
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5977
0
    if (val == NULL)
5978
0
        return (def);
5979
5980
0
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
5981
0
  if (max != UNBOUNDED) {
5982
0
      xmlSchemaPSimpleTypeErr(ctxt,
5983
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5984
    /* XML_SCHEMAP_INVALID_MINOCCURS, */
5985
0
    NULL, (xmlNodePtr) attr, NULL, expected,
5986
0
    val, NULL, NULL, NULL);
5987
0
      return (def);
5988
0
  } else
5989
0
      return (UNBOUNDED);  /* encoding it with -1 might be another option */
5990
0
    }
5991
5992
0
    cur = val;
5993
0
    while (IS_BLANK_CH(*cur))
5994
0
        cur++;
5995
0
    if (*cur == 0) {
5996
0
        xmlSchemaPSimpleTypeErr(ctxt,
5997
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5998
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5999
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6000
0
      val, NULL, NULL, NULL);
6001
0
  return (def);
6002
0
    }
6003
0
    while ((*cur >= '0') && (*cur <= '9')) {
6004
0
        if (ret > INT_MAX / 10) {
6005
0
            ret = INT_MAX;
6006
0
        } else {
6007
0
            int digit = *cur - '0';
6008
0
            ret *= 10;
6009
0
            if (ret > INT_MAX - digit)
6010
0
                ret = INT_MAX;
6011
0
            else
6012
0
                ret += digit;
6013
0
        }
6014
0
        cur++;
6015
0
    }
6016
0
    while (IS_BLANK_CH(*cur))
6017
0
        cur++;
6018
    /*
6019
    * TODO: Restrict the maximal value to Integer.
6020
    */
6021
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6022
0
  xmlSchemaPSimpleTypeErr(ctxt,
6023
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6024
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6025
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6026
0
      val, NULL, NULL, NULL);
6027
0
        return (def);
6028
0
    }
6029
0
    return (ret);
6030
0
}
6031
6032
/**
6033
 * xmlGetMinOccurs:
6034
 * @ctxt:  a schema validation context
6035
 * @node:  a subtree containing XML Schema information
6036
 *
6037
 * Get the minOccurs property
6038
 *
6039
 * Returns the default if not found, or the value
6040
 */
6041
static int
6042
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6043
    int min, int max, int def, const char *expected)
6044
0
{
6045
0
    const xmlChar *val, *cur;
6046
0
    int ret = 0;
6047
0
    xmlAttrPtr attr;
6048
6049
0
    attr = xmlSchemaGetPropNode(node, "minOccurs");
6050
0
    if (attr == NULL)
6051
0
  return (def);
6052
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6053
0
    if (val == NULL)
6054
0
  return (def);
6055
0
    cur = val;
6056
0
    while (IS_BLANK_CH(*cur))
6057
0
        cur++;
6058
0
    if (*cur == 0) {
6059
0
        xmlSchemaPSimpleTypeErr(ctxt,
6060
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6061
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6062
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6063
0
      val, NULL, NULL, NULL);
6064
0
        return (def);
6065
0
    }
6066
0
    while ((*cur >= '0') && (*cur <= '9')) {
6067
0
        if (ret > INT_MAX / 10) {
6068
0
            ret = INT_MAX;
6069
0
        } else {
6070
0
            int digit = *cur - '0';
6071
0
            ret *= 10;
6072
0
            if (ret > INT_MAX - digit)
6073
0
                ret = INT_MAX;
6074
0
            else
6075
0
                ret += digit;
6076
0
        }
6077
0
        cur++;
6078
0
    }
6079
0
    while (IS_BLANK_CH(*cur))
6080
0
        cur++;
6081
    /*
6082
    * TODO: Restrict the maximal value to Integer.
6083
    */
6084
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6085
0
  xmlSchemaPSimpleTypeErr(ctxt,
6086
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6087
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6088
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6089
0
      val, NULL, NULL, NULL);
6090
0
        return (def);
6091
0
    }
6092
0
    return (ret);
6093
0
}
6094
6095
/**
6096
 * xmlSchemaPGetBoolNodeValue:
6097
 * @ctxt:  a schema validation context
6098
 * @ownerItem:  the owner as a schema item
6099
 * @node: the node holding the value
6100
 *
6101
 * Converts a boolean string value into 1 or 0.
6102
 *
6103
 * Returns 0 or 1.
6104
 */
6105
static int
6106
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6107
         xmlSchemaBasicItemPtr ownerItem,
6108
         xmlNodePtr node)
6109
0
{
6110
0
    xmlChar *value = NULL;
6111
0
    int res = 0;
6112
6113
0
    value = xmlNodeGetContent(node);
6114
    /*
6115
    * 3.2.2.1 Lexical representation
6116
    * An instance of a datatype that is defined as `boolean`
6117
    * can have the following legal literals {true, false, 1, 0}.
6118
    */
6119
0
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6120
0
        res = 1;
6121
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6122
0
        res = 0;
6123
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6124
0
  res = 1;
6125
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6126
0
        res = 0;
6127
0
    else {
6128
0
        xmlSchemaPSimpleTypeErr(ctxt,
6129
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6130
0
      ownerItem, node,
6131
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6132
0
      NULL, BAD_CAST value,
6133
0
      NULL, NULL, NULL);
6134
0
    }
6135
0
    if (value != NULL)
6136
0
  xmlFree(value);
6137
0
    return (res);
6138
0
}
6139
6140
/**
6141
 * xmlGetBooleanProp:
6142
 * @ctxt:  a schema validation context
6143
 * @node:  a subtree containing XML Schema information
6144
 * @name:  the attribute name
6145
 * @def:  the default value
6146
 *
6147
 * Evaluate if a boolean property is set
6148
 *
6149
 * Returns the default if not found, 0 if found to be false,
6150
 * 1 if found to be true
6151
 */
6152
static int
6153
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6154
      xmlNodePtr node,
6155
                  const char *name, int def)
6156
0
{
6157
0
    const xmlChar *val;
6158
6159
0
    val = xmlSchemaGetProp(ctxt, node, name);
6160
0
    if (val == NULL)
6161
0
        return (def);
6162
    /*
6163
    * 3.2.2.1 Lexical representation
6164
    * An instance of a datatype that is defined as `boolean`
6165
    * can have the following legal literals {true, false, 1, 0}.
6166
    */
6167
0
    if (xmlStrEqual(val, BAD_CAST "true"))
6168
0
        def = 1;
6169
0
    else if (xmlStrEqual(val, BAD_CAST "false"))
6170
0
        def = 0;
6171
0
    else if (xmlStrEqual(val, BAD_CAST "1"))
6172
0
  def = 1;
6173
0
    else if (xmlStrEqual(val, BAD_CAST "0"))
6174
0
        def = 0;
6175
0
    else {
6176
0
        xmlSchemaPSimpleTypeErr(ctxt,
6177
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6178
0
      NULL,
6179
0
      (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6180
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6181
0
      NULL, val, NULL, NULL, NULL);
6182
0
    }
6183
0
    return (def);
6184
0
}
6185
6186
/************************************************************************
6187
 *                  *
6188
 *    Schema extraction from an Infoset     *
6189
 *                  *
6190
 ************************************************************************/
6191
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6192
                                                 ctxt, xmlSchemaPtr schema,
6193
                                                 xmlNodePtr node,
6194
             int topLevel);
6195
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6196
                                                  ctxt,
6197
                                                  xmlSchemaPtr schema,
6198
                                                  xmlNodePtr node,
6199
              int topLevel);
6200
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6201
                                                  ctxt,
6202
                                                  xmlSchemaPtr schema,
6203
                                                  xmlNodePtr node,
6204
              xmlSchemaTypeType parentType);
6205
static xmlSchemaBasicItemPtr
6206
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6207
           xmlSchemaPtr schema,
6208
           xmlNodePtr node,
6209
           xmlSchemaItemListPtr uses,
6210
           int parentType);
6211
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6212
                                           xmlSchemaPtr schema,
6213
                                           xmlNodePtr node);
6214
static xmlSchemaWildcardPtr
6215
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6216
                           xmlSchemaPtr schema, xmlNodePtr node);
6217
6218
/**
6219
 * xmlSchemaPValAttrNodeValue:
6220
 *
6221
 * @pctxt:  a schema parser context
6222
 * @ownerItem: the schema object owner if existent
6223
 * @attr:  the schema attribute node being validated
6224
 * @value: the value
6225
 * @type: the built-in type to be validated against
6226
 *
6227
 * Validates a value against the given built-in type.
6228
 * This one is intended to be used internally for validation
6229
 * of schema attribute values during parsing of the schema.
6230
 *
6231
 * Returns 0 if the value is valid, a positive error code
6232
 * number otherwise and -1 in case of an internal or API error.
6233
 */
6234
static int
6235
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6236
         xmlSchemaBasicItemPtr ownerItem,
6237
         xmlAttrPtr attr,
6238
         const xmlChar *value,
6239
         xmlSchemaTypePtr type)
6240
0
{
6241
6242
0
    int ret = 0;
6243
6244
    /*
6245
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6246
    * one is really meant to be used internally, so better not.
6247
    */
6248
0
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6249
0
  return (-1);
6250
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6251
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6252
0
      "the given type is not a built-in type");
6253
0
  return (-1);
6254
0
    }
6255
0
    switch (type->builtInType) {
6256
0
  case XML_SCHEMAS_NCNAME:
6257
0
  case XML_SCHEMAS_QNAME:
6258
0
  case XML_SCHEMAS_ANYURI:
6259
0
  case XML_SCHEMAS_TOKEN:
6260
0
  case XML_SCHEMAS_LANGUAGE:
6261
0
      ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6262
0
    (xmlNodePtr) attr);
6263
0
      break;
6264
0
  default: {
6265
0
      PERROR_INT("xmlSchemaPValAttrNodeValue",
6266
0
    "validation using the given type is not supported while "
6267
0
    "parsing a schema");
6268
0
      return (-1);
6269
0
  }
6270
0
    }
6271
    /*
6272
    * TODO: Should we use the S4S error codes instead?
6273
    */
6274
0
    if (ret < 0) {
6275
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6276
0
      "failed to validate a schema attribute value");
6277
0
  return (-1);
6278
0
    } else if (ret > 0) {
6279
0
  if (WXS_IS_LIST(type))
6280
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6281
0
  else
6282
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6283
0
  xmlSchemaPSimpleTypeErr(pctxt,
6284
0
      ret, ownerItem, (xmlNodePtr) attr,
6285
0
      type, NULL, value, NULL, NULL, NULL);
6286
0
    }
6287
0
    return (ret);
6288
0
}
6289
6290
/**
6291
 * xmlSchemaPValAttrNode:
6292
 *
6293
 * @ctxt:  a schema parser context
6294
 * @ownerItem: the schema object owner if existent
6295
 * @attr:  the schema attribute node being validated
6296
 * @type: the built-in type to be validated against
6297
 * @value: the resulting value if any
6298
 *
6299
 * Extracts and validates a value against the given built-in type.
6300
 * This one is intended to be used internally for validation
6301
 * of schema attribute values during parsing of the schema.
6302
 *
6303
 * Returns 0 if the value is valid, a positive error code
6304
 * number otherwise and -1 in case of an internal or API error.
6305
 */
6306
static int
6307
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6308
         xmlSchemaBasicItemPtr ownerItem,
6309
         xmlAttrPtr attr,
6310
         xmlSchemaTypePtr type,
6311
         const xmlChar **value)
6312
0
{
6313
0
    const xmlChar *val;
6314
6315
0
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6316
0
  return (-1);
6317
6318
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6319
0
    if (value != NULL)
6320
0
  *value = val;
6321
6322
0
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6323
0
  val, type));
6324
0
}
6325
6326
/**
6327
 * xmlSchemaPValAttr:
6328
 *
6329
 * @ctxt:  a schema parser context
6330
 * @node: the element node of the attribute
6331
 * @ownerItem: the schema object owner if existent
6332
 * @ownerElem: the owner element node
6333
 * @name:  the name of the schema attribute node
6334
 * @type: the built-in type to be validated against
6335
 * @value: the resulting value if any
6336
 *
6337
 * Extracts and validates a value against the given built-in type.
6338
 * This one is intended to be used internally for validation
6339
 * of schema attribute values during parsing of the schema.
6340
 *
6341
 * Returns 0 if the value is valid, a positive error code
6342
 * number otherwise and -1 in case of an internal or API error.
6343
 */
6344
static int
6345
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6346
           xmlSchemaBasicItemPtr ownerItem,
6347
           xmlNodePtr ownerElem,
6348
           const char *name,
6349
           xmlSchemaTypePtr type,
6350
           const xmlChar **value)
6351
0
{
6352
0
    xmlAttrPtr attr;
6353
6354
0
    if ((ctxt == NULL) || (type == NULL)) {
6355
0
  if (value != NULL)
6356
0
      *value = NULL;
6357
0
  return (-1);
6358
0
    }
6359
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6360
0
  if (value != NULL)
6361
0
      *value = NULL;
6362
0
  xmlSchemaPErr(ctxt, ownerElem,
6363
0
      XML_SCHEMAP_INTERNAL,
6364
0
      "Internal error: xmlSchemaPValAttr, the given "
6365
0
      "type '%s' is not a built-in type.\n",
6366
0
      type->name, NULL);
6367
0
  return (-1);
6368
0
    }
6369
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
6370
0
    if (attr == NULL) {
6371
0
  if (value != NULL)
6372
0
      *value = NULL;
6373
0
  return (0);
6374
0
    }
6375
0
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6376
0
  type, value));
6377
0
}
6378
6379
static int
6380
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6381
      xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6382
      xmlNodePtr node,
6383
      xmlAttrPtr attr,
6384
      const xmlChar *namespaceName)
6385
0
{
6386
    /* TODO: Pointer comparison instead? */
6387
0
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6388
0
  return (0);
6389
0
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
6390
0
  return (0);
6391
    /*
6392
    * Check if the referenced namespace was <import>ed.
6393
    */
6394
0
    if (WXS_BUCKET(pctxt)->relations != NULL) {
6395
0
  xmlSchemaSchemaRelationPtr rel;
6396
6397
0
  rel = WXS_BUCKET(pctxt)->relations;
6398
0
  do {
6399
0
      if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6400
0
    xmlStrEqual(namespaceName, rel->importNamespace))
6401
0
    return (0);
6402
0
      rel = rel->next;
6403
0
  } while (rel != NULL);
6404
0
    }
6405
    /*
6406
    * No matching <import>ed namespace found.
6407
    */
6408
0
    {
6409
0
  xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6410
6411
0
  if (namespaceName == NULL)
6412
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6413
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6414
0
    "References from this schema to components in no "
6415
0
    "namespace are not allowed, since not indicated by an "
6416
0
    "import statement", NULL, NULL);
6417
0
  else
6418
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6419
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6420
0
    "References from this schema to components in the "
6421
0
    "namespace '%s' are not allowed, since not indicated by an "
6422
0
    "import statement", namespaceName, NULL);
6423
0
    }
6424
0
    return (XML_SCHEMAP_SRC_RESOLVE);
6425
0
}
6426
6427
/**
6428
 * xmlSchemaParseLocalAttributes:
6429
 * @ctxt:  a schema validation context
6430
 * @schema:  the schema being built
6431
 * @node:  a subtree containing XML Schema information
6432
 * @type:  the hosting type where the attributes will be anchored
6433
 *
6434
 * Parses attribute uses and attribute declarations and
6435
 * attribute group references.
6436
 */
6437
static int
6438
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6439
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
6440
      int parentType, int *hasRefs)
6441
0
{
6442
0
    void *item;
6443
6444
0
    while ((IS_SCHEMA((*child), "attribute")) ||
6445
0
           (IS_SCHEMA((*child), "attributeGroup"))) {
6446
0
        if (IS_SCHEMA((*child), "attribute")) {
6447
0
      item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6448
0
    *list, parentType);
6449
0
        } else {
6450
0
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6451
0
      if ((item != NULL) && (hasRefs != NULL))
6452
0
    *hasRefs = 1;
6453
0
        }
6454
0
  if (item != NULL) {
6455
0
      if (*list == NULL) {
6456
    /* TODO: Customize grow factor. */
6457
0
    *list = xmlSchemaItemListCreate();
6458
0
    if (*list == NULL)
6459
0
        return(-1);
6460
0
      }
6461
0
      if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6462
0
    return(-1);
6463
0
  }
6464
0
        *child = (*child)->next;
6465
0
    }
6466
0
    return (0);
6467
0
}
6468
6469
/**
6470
 * xmlSchemaParseAnnotation:
6471
 * @ctxt:  a schema validation context
6472
 * @schema:  the schema being built
6473
 * @node:  a subtree containing XML Schema information
6474
 *
6475
 * parse a XML schema Attribute declaration
6476
 * *WARNING* this interface is highly subject to change
6477
 *
6478
 * Returns -1 in case of error, 0 if the declaration is improper and
6479
 *         1 in case of success.
6480
 */
6481
static xmlSchemaAnnotPtr
6482
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6483
0
{
6484
0
    xmlSchemaAnnotPtr ret;
6485
0
    xmlNodePtr child = NULL;
6486
0
    xmlAttrPtr attr;
6487
0
    int barked = 0;
6488
6489
    /*
6490
    * INFO: S4S completed.
6491
    */
6492
    /*
6493
    * id = ID
6494
    * {any attributes with non-schema namespace . . .}>
6495
    * Content: (appinfo | documentation)*
6496
    */
6497
0
    if ((ctxt == NULL) || (node == NULL))
6498
0
        return (NULL);
6499
0
    if (needed)
6500
0
  ret = xmlSchemaNewAnnot(ctxt, node);
6501
0
    else
6502
0
  ret = NULL;
6503
0
    attr = node->properties;
6504
0
    while (attr != NULL) {
6505
0
  if (((attr->ns == NULL) &&
6506
0
      (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6507
0
      ((attr->ns != NULL) &&
6508
0
      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6509
6510
0
      xmlSchemaPIllegalAttrErr(ctxt,
6511
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6512
0
  }
6513
0
  attr = attr->next;
6514
0
    }
6515
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6516
    /*
6517
    * And now for the children...
6518
    */
6519
0
    child = node->children;
6520
0
    while (child != NULL) {
6521
0
  if (IS_SCHEMA(child, "appinfo")) {
6522
      /* TODO: make available the content of "appinfo". */
6523
      /*
6524
      * source = anyURI
6525
      * {any attributes with non-schema namespace . . .}>
6526
      * Content: ({any})*
6527
      */
6528
0
      attr = child->properties;
6529
0
      while (attr != NULL) {
6530
0
    if (((attr->ns == NULL) &&
6531
0
         (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6532
0
         ((attr->ns != NULL) &&
6533
0
          xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6534
6535
0
        xmlSchemaPIllegalAttrErr(ctxt,
6536
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6537
0
    }
6538
0
    attr = attr->next;
6539
0
      }
6540
0
      xmlSchemaPValAttr(ctxt, NULL, child, "source",
6541
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6542
0
      child = child->next;
6543
0
  } else if (IS_SCHEMA(child, "documentation")) {
6544
      /* TODO: make available the content of "documentation". */
6545
      /*
6546
      * source = anyURI
6547
      * {any attributes with non-schema namespace . . .}>
6548
      * Content: ({any})*
6549
      */
6550
0
      attr = child->properties;
6551
0
      while (attr != NULL) {
6552
0
    if (attr->ns == NULL) {
6553
0
        if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6554
0
      xmlSchemaPIllegalAttrErr(ctxt,
6555
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6556
0
        }
6557
0
    } else {
6558
0
        if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6559
0
      (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6560
0
      (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6561
6562
0
      xmlSchemaPIllegalAttrErr(ctxt,
6563
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6564
0
        }
6565
0
    }
6566
0
    attr = attr->next;
6567
0
      }
6568
      /*
6569
      * Attribute "xml:lang".
6570
      */
6571
0
      attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6572
0
      if (attr != NULL)
6573
0
    xmlSchemaPValAttrNode(ctxt, NULL, attr,
6574
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6575
0
      child = child->next;
6576
0
  } else {
6577
0
      if (!barked)
6578
0
    xmlSchemaPContentErr(ctxt,
6579
0
        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6580
0
        NULL, node, child, NULL, "(appinfo | documentation)*");
6581
0
      barked = 1;
6582
0
      child = child->next;
6583
0
  }
6584
0
    }
6585
6586
0
    return (ret);
6587
0
}
6588
6589
/**
6590
 * xmlSchemaParseFacet:
6591
 * @ctxt:  a schema validation context
6592
 * @schema:  the schema being built
6593
 * @node:  a subtree containing XML Schema information
6594
 *
6595
 * parse a XML schema Facet declaration
6596
 * *WARNING* this interface is highly subject to change
6597
 *
6598
 * Returns the new type structure or NULL in case of error
6599
 */
6600
static xmlSchemaFacetPtr
6601
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6602
                    xmlNodePtr node)
6603
0
{
6604
0
    xmlSchemaFacetPtr facet;
6605
0
    xmlNodePtr child = NULL;
6606
0
    const xmlChar *value;
6607
6608
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6609
0
        return (NULL);
6610
6611
0
    facet = xmlSchemaNewFacet();
6612
0
    if (facet == NULL) {
6613
0
        xmlSchemaPErrMemory(ctxt);
6614
0
        return (NULL);
6615
0
    }
6616
0
    facet->node = node;
6617
0
    value = xmlSchemaGetProp(ctxt, node, "value");
6618
0
    if (value == NULL) {
6619
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6620
0
                       "Facet %s has no value\n", node->name, NULL);
6621
0
        xmlSchemaFreeFacet(facet);
6622
0
        return (NULL);
6623
0
    }
6624
0
    if (IS_SCHEMA(node, "minInclusive")) {
6625
0
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6626
0
    } else if (IS_SCHEMA(node, "minExclusive")) {
6627
0
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6628
0
    } else if (IS_SCHEMA(node, "maxInclusive")) {
6629
0
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6630
0
    } else if (IS_SCHEMA(node, "maxExclusive")) {
6631
0
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6632
0
    } else if (IS_SCHEMA(node, "totalDigits")) {
6633
0
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6634
0
    } else if (IS_SCHEMA(node, "fractionDigits")) {
6635
0
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6636
0
    } else if (IS_SCHEMA(node, "pattern")) {
6637
0
        facet->type = XML_SCHEMA_FACET_PATTERN;
6638
0
    } else if (IS_SCHEMA(node, "enumeration")) {
6639
0
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
6640
0
    } else if (IS_SCHEMA(node, "whiteSpace")) {
6641
0
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
6642
0
    } else if (IS_SCHEMA(node, "length")) {
6643
0
        facet->type = XML_SCHEMA_FACET_LENGTH;
6644
0
    } else if (IS_SCHEMA(node, "maxLength")) {
6645
0
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6646
0
    } else if (IS_SCHEMA(node, "minLength")) {
6647
0
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
6648
0
    } else {
6649
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6650
0
                       "Unknown facet type %s\n", node->name, NULL);
6651
0
        xmlSchemaFreeFacet(facet);
6652
0
        return (NULL);
6653
0
    }
6654
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6655
0
    facet->value = value;
6656
0
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6657
0
  (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6658
0
  const xmlChar *fixed;
6659
6660
0
  fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6661
0
  if (fixed != NULL) {
6662
0
      if (xmlStrEqual(fixed, BAD_CAST "true"))
6663
0
    facet->fixed = 1;
6664
0
  }
6665
0
    }
6666
0
    child = node->children;
6667
6668
0
    if (IS_SCHEMA(child, "annotation")) {
6669
0
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6670
0
        child = child->next;
6671
0
    }
6672
0
    if (child != NULL) {
6673
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6674
0
                       "Facet %s has unexpected child content\n",
6675
0
                       node->name, NULL);
6676
0
    }
6677
0
    return (facet);
6678
0
}
6679
6680
/**
6681
 * xmlSchemaParseWildcardNs:
6682
 * @ctxt:  a schema parser context
6683
 * @wildc:  the wildcard, already created
6684
 * @node:  a subtree containing XML Schema information
6685
 *
6686
 * Parses the attribute "processContents" and "namespace"
6687
 * of a xsd:anyAttribute and xsd:any.
6688
 * *WARNING* this interface is highly subject to change
6689
 *
6690
 * Returns 0 if everything goes fine, a positive error code
6691
 * if something is not valid and -1 if an internal error occurs.
6692
 */
6693
static int
6694
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6695
       xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6696
       xmlSchemaWildcardPtr wildc,
6697
       xmlNodePtr node)
6698
0
{
6699
0
    const xmlChar *pc, *ns, *dictnsItem;
6700
0
    int ret = 0;
6701
0
    xmlChar *nsItem;
6702
0
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6703
0
    xmlAttrPtr attr;
6704
6705
0
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
6706
0
    if ((pc == NULL)
6707
0
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6708
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6709
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6710
0
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6711
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6712
0
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
6713
0
    } else {
6714
0
        xmlSchemaPSimpleTypeErr(ctxt,
6715
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6716
0
      NULL, node,
6717
0
      NULL, "(strict | skip | lax)", pc,
6718
0
      NULL, NULL, NULL);
6719
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6720
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6721
0
    }
6722
    /*
6723
     * Build the namespace constraints.
6724
     */
6725
0
    attr = xmlSchemaGetPropNode(node, "namespace");
6726
0
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6727
0
    if (ns == NULL)
6728
0
        return (-1);
6729
0
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6730
0
  wildc->any = 1;
6731
0
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6732
0
  wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6733
0
  if (wildc->negNsSet == NULL) {
6734
0
      return (-1);
6735
0
  }
6736
0
  wildc->negNsSet->value = ctxt->targetNamespace;
6737
0
    } else {
6738
0
  const xmlChar *end, *cur;
6739
6740
0
  cur = ns;
6741
0
  do {
6742
0
      while (IS_BLANK_CH(*cur))
6743
0
    cur++;
6744
0
      end = cur;
6745
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6746
0
    end++;
6747
0
      if (end == cur)
6748
0
    break;
6749
0
      nsItem = xmlStrndup(cur, end - cur);
6750
0
      if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6751
0
        (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6752
0
    xmlSchemaPSimpleTypeErr(ctxt,
6753
0
        XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6754
0
        NULL, (xmlNodePtr) attr,
6755
0
        NULL,
6756
0
        "((##any | ##other) | List of (xs:anyURI | "
6757
0
        "(##targetNamespace | ##local)))",
6758
0
        nsItem, NULL, NULL, NULL);
6759
0
    ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6760
0
      } else {
6761
0
    if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6762
0
        dictnsItem = ctxt->targetNamespace;
6763
0
    } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6764
0
        dictnsItem = NULL;
6765
0
    } else {
6766
        /*
6767
        * Validate the item (anyURI).
6768
        */
6769
0
        xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6770
0
      nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6771
0
        dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6772
0
    }
6773
    /*
6774
    * Avoid duplicate namespaces.
6775
    */
6776
0
    tmp = wildc->nsSet;
6777
0
    while (tmp != NULL) {
6778
0
        if (dictnsItem == tmp->value)
6779
0
      break;
6780
0
        tmp = tmp->next;
6781
0
    }
6782
0
    if (tmp == NULL) {
6783
0
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6784
0
        if (tmp == NULL) {
6785
0
      xmlFree(nsItem);
6786
0
      return (-1);
6787
0
        }
6788
0
        tmp->value = dictnsItem;
6789
0
        tmp->next = NULL;
6790
0
        if (wildc->nsSet == NULL)
6791
0
      wildc->nsSet = tmp;
6792
0
        else if (lastNs != NULL)
6793
0
      lastNs->next = tmp;
6794
0
        lastNs = tmp;
6795
0
    }
6796
6797
0
      }
6798
0
      xmlFree(nsItem);
6799
0
      cur = end;
6800
0
  } while (*cur != 0);
6801
0
    }
6802
0
    return (ret);
6803
0
}
6804
6805
static int
6806
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6807
         xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6808
         xmlNodePtr node,
6809
         int minOccurs,
6810
0
         int maxOccurs) {
6811
6812
0
    if ((maxOccurs == 0) && ( minOccurs == 0))
6813
0
  return (0);
6814
0
    if (maxOccurs != UNBOUNDED) {
6815
  /*
6816
  * TODO: Maybe we should better not create the particle,
6817
  * if min/max is invalid, since it could confuse the build of the
6818
  * content model.
6819
  */
6820
  /*
6821
  * 3.9.6 Schema Component Constraint: Particle Correct
6822
  *
6823
  */
6824
0
  if (maxOccurs < 1) {
6825
      /*
6826
      * 2.2 {max occurs} must be greater than or equal to 1.
6827
      */
6828
0
      xmlSchemaPCustomAttrErr(ctxt,
6829
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6830
0
    NULL, NULL,
6831
0
    xmlSchemaGetPropNode(node, "maxOccurs"),
6832
0
    "The value must be greater than or equal to 1");
6833
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6834
0
  } else if (minOccurs > maxOccurs) {
6835
      /*
6836
      * 2.1 {min occurs} must not be greater than {max occurs}.
6837
      */
6838
0
      xmlSchemaPCustomAttrErr(ctxt,
6839
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6840
0
    NULL, NULL,
6841
0
    xmlSchemaGetPropNode(node, "minOccurs"),
6842
0
    "The value must not be greater than the value of 'maxOccurs'");
6843
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6844
0
  }
6845
0
    }
6846
0
    return (0);
6847
0
}
6848
6849
/**
6850
 * xmlSchemaParseAny:
6851
 * @ctxt:  a schema validation context
6852
 * @schema:  the schema being built
6853
 * @node:  a subtree containing XML Schema information
6854
 *
6855
 * Parsea a XML schema <any> element. A particle and wildcard
6856
 * will be created (except if minOccurs==maxOccurs==0, in this case
6857
 * nothing will be created).
6858
 * *WARNING* this interface is highly subject to change
6859
 *
6860
 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6861
 */
6862
static xmlSchemaParticlePtr
6863
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6864
                  xmlNodePtr node)
6865
0
{
6866
0
    xmlSchemaParticlePtr particle;
6867
0
    xmlNodePtr child = NULL;
6868
0
    xmlSchemaWildcardPtr wild;
6869
0
    int min, max;
6870
0
    xmlAttrPtr attr;
6871
0
    xmlSchemaAnnotPtr annot = NULL;
6872
6873
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6874
0
        return (NULL);
6875
    /*
6876
    * Check for illegal attributes.
6877
    */
6878
0
    attr = node->properties;
6879
0
    while (attr != NULL) {
6880
0
  if (attr->ns == NULL) {
6881
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6882
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
6883
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
6884
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6885
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6886
0
    xmlSchemaPIllegalAttrErr(ctxt,
6887
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6888
0
      }
6889
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6890
0
      xmlSchemaPIllegalAttrErr(ctxt,
6891
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6892
0
  }
6893
0
  attr = attr->next;
6894
0
    }
6895
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6896
    /*
6897
    * minOccurs/maxOccurs.
6898
    */
6899
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
6900
0
  "(xs:nonNegativeInteger | unbounded)");
6901
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
6902
0
  "xs:nonNegativeInteger");
6903
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
6904
    /*
6905
    * Create & parse the wildcard.
6906
    */
6907
0
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6908
0
    if (wild == NULL)
6909
0
  return (NULL);
6910
0
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6911
    /*
6912
    * And now for the children...
6913
    */
6914
0
    child = node->children;
6915
0
    if (IS_SCHEMA(child, "annotation")) {
6916
0
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6917
0
        child = child->next;
6918
0
    }
6919
0
    if (child != NULL) {
6920
0
  xmlSchemaPContentErr(ctxt,
6921
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6922
0
      NULL, node, child,
6923
0
      NULL, "(annotation?)");
6924
0
    }
6925
    /*
6926
    * No component if minOccurs==maxOccurs==0.
6927
    */
6928
0
    if ((min == 0) && (max == 0)) {
6929
  /* Don't free the wildcard, since it's already on the list. */
6930
0
  return (NULL);
6931
0
    }
6932
    /*
6933
    * Create the particle.
6934
    */
6935
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
6936
0
    if (particle == NULL)
6937
0
        return (NULL);
6938
0
    particle->annot = annot;
6939
0
    particle->children = (xmlSchemaTreeItemPtr) wild;
6940
6941
0
    return (particle);
6942
0
}
6943
6944
/**
6945
 * xmlSchemaParseNotation:
6946
 * @ctxt:  a schema validation context
6947
 * @schema:  the schema being built
6948
 * @node:  a subtree containing XML Schema information
6949
 *
6950
 * parse a XML schema Notation declaration
6951
 *
6952
 * Returns the new structure or NULL in case of error
6953
 */
6954
static xmlSchemaNotationPtr
6955
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6956
                       xmlNodePtr node)
6957
0
{
6958
0
    const xmlChar *name;
6959
0
    xmlSchemaNotationPtr ret;
6960
0
    xmlNodePtr child = NULL;
6961
6962
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6963
0
        return (NULL);
6964
0
    name = xmlSchemaGetProp(ctxt, node, "name");
6965
0
    if (name == NULL) {
6966
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6967
0
                       "Notation has no name\n", NULL, NULL);
6968
0
        return (NULL);
6969
0
    }
6970
0
    ret = xmlSchemaAddNotation(ctxt, schema, name,
6971
0
  ctxt->targetNamespace, node);
6972
0
    if (ret == NULL)
6973
0
        return (NULL);
6974
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6975
6976
0
    child = node->children;
6977
0
    if (IS_SCHEMA(child, "annotation")) {
6978
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6979
0
        child = child->next;
6980
0
    }
6981
0
    if (child != NULL) {
6982
0
  xmlSchemaPContentErr(ctxt,
6983
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6984
0
      NULL, node, child,
6985
0
      NULL, "(annotation?)");
6986
0
    }
6987
6988
0
    return (ret);
6989
0
}
6990
6991
/**
6992
 * xmlSchemaParseAnyAttribute:
6993
 * @ctxt:  a schema validation context
6994
 * @schema:  the schema being built
6995
 * @node:  a subtree containing XML Schema information
6996
 *
6997
 * parse a XML schema AnyAttribute declaration
6998
 * *WARNING* this interface is highly subject to change
6999
 *
7000
 * Returns a wildcard or NULL.
7001
 */
7002
static xmlSchemaWildcardPtr
7003
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7004
                           xmlSchemaPtr schema, xmlNodePtr node)
7005
0
{
7006
0
    xmlSchemaWildcardPtr ret;
7007
0
    xmlNodePtr child = NULL;
7008
0
    xmlAttrPtr attr;
7009
7010
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7011
0
        return (NULL);
7012
7013
0
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7014
0
  node);
7015
0
    if (ret == NULL) {
7016
0
        return (NULL);
7017
0
    }
7018
    /*
7019
    * Check for illegal attributes.
7020
    */
7021
0
    attr = node->properties;
7022
0
    while (attr != NULL) {
7023
0
  if (attr->ns == NULL) {
7024
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7025
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7026
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7027
0
    xmlSchemaPIllegalAttrErr(ctxt,
7028
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7029
0
      }
7030
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7031
0
      xmlSchemaPIllegalAttrErr(ctxt,
7032
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7033
0
  }
7034
0
  attr = attr->next;
7035
0
    }
7036
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7037
    /*
7038
    * Parse the namespace list.
7039
    */
7040
0
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7041
0
  return (NULL);
7042
    /*
7043
    * And now for the children...
7044
    */
7045
0
    child = node->children;
7046
0
    if (IS_SCHEMA(child, "annotation")) {
7047
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7048
0
        child = child->next;
7049
0
    }
7050
0
    if (child != NULL) {
7051
0
  xmlSchemaPContentErr(ctxt,
7052
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7053
0
      NULL, node, child,
7054
0
      NULL, "(annotation?)");
7055
0
    }
7056
7057
0
    return (ret);
7058
0
}
7059
7060
7061
/**
7062
 * xmlSchemaParseAttribute:
7063
 * @ctxt:  a schema validation context
7064
 * @schema:  the schema being built
7065
 * @node:  a subtree containing XML Schema information
7066
 *
7067
 * parse a XML schema Attribute declaration
7068
 * *WARNING* this interface is highly subject to change
7069
 *
7070
 * Returns the attribute declaration.
7071
 */
7072
static xmlSchemaBasicItemPtr
7073
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7074
           xmlSchemaPtr schema,
7075
           xmlNodePtr node,
7076
           xmlSchemaItemListPtr uses,
7077
           int parentType)
7078
0
{
7079
0
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
7080
0
    xmlSchemaAttributeUsePtr use = NULL;
7081
0
    xmlNodePtr child = NULL;
7082
0
    xmlAttrPtr attr;
7083
0
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7084
0
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7085
0
    int nberrors, hasForm = 0, defValueType = 0;
7086
7087
0
#define WXS_ATTR_DEF_VAL_DEFAULT 1
7088
0
#define WXS_ATTR_DEF_VAL_FIXED 2
7089
7090
    /*
7091
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7092
     */
7093
7094
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7095
0
        return (NULL);
7096
0
    attr = xmlSchemaGetPropNode(node, "ref");
7097
0
    if (attr != NULL) {
7098
0
  if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7099
0
      NULL, attr, &tmpNs, &tmpName) != 0) {
7100
0
      return (NULL);
7101
0
  }
7102
0
  if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7103
0
      return(NULL);
7104
0
  isRef = 1;
7105
0
    }
7106
0
    nberrors = pctxt->nberrors;
7107
    /*
7108
    * Check for illegal attributes.
7109
    */
7110
0
    attr = node->properties;
7111
0
    while (attr != NULL) {
7112
0
  if (attr->ns == NULL) {
7113
0
      if (isRef) {
7114
0
    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7115
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7116
0
        goto attr_next;
7117
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7118
0
        goto attr_next;
7119
0
    }
7120
0
      } else {
7121
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7122
0
        goto attr_next;
7123
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7124
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7125
0
        goto attr_next;
7126
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7127
0
        xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7128
0
      attr, &tmpNs, &tmpName);
7129
0
        goto attr_next;
7130
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7131
        /*
7132
        * Evaluate the target namespace
7133
        */
7134
0
        hasForm = 1;
7135
0
        attrValue = xmlSchemaGetNodeContent(pctxt,
7136
0
      (xmlNodePtr) attr);
7137
0
        if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7138
0
      ns = pctxt->targetNamespace;
7139
0
        } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7140
0
        {
7141
0
      xmlSchemaPSimpleTypeErr(pctxt,
7142
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7143
0
          NULL, (xmlNodePtr) attr,
7144
0
          NULL, "(qualified | unqualified)",
7145
0
          attrValue, NULL, NULL, NULL);
7146
0
        }
7147
0
        goto attr_next;
7148
0
    }
7149
0
      }
7150
0
      if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7151
7152
0
    attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7153
    /* TODO: Maybe we need to normalize the value beforehand. */
7154
0
    if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7155
0
        occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7156
0
    else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7157
0
        occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7158
0
    else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7159
0
        occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7160
0
    else {
7161
0
        xmlSchemaPSimpleTypeErr(pctxt,
7162
0
      XML_SCHEMAP_INVALID_ATTR_USE,
7163
0
      NULL, (xmlNodePtr) attr,
7164
0
      NULL, "(optional | prohibited | required)",
7165
0
      attrValue, NULL, NULL, NULL);
7166
0
    }
7167
0
    goto attr_next;
7168
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7169
    /*
7170
    * 3.2.3 : 1
7171
    * default and fixed must not both be present.
7172
    */
7173
0
    if (defValue) {
7174
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7175
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7176
0
      NULL, attr, "default", "fixed");
7177
0
    } else {
7178
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7179
0
        defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7180
0
    }
7181
0
    goto attr_next;
7182
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7183
    /*
7184
    * 3.2.3 : 1
7185
    * default and fixed must not both be present.
7186
    */
7187
0
    if (defValue) {
7188
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7189
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7190
0
      NULL, attr, "default", "fixed");
7191
0
    } else {
7192
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7193
0
        defValueType = WXS_ATTR_DEF_VAL_FIXED;
7194
0
    }
7195
0
    goto attr_next;
7196
0
      }
7197
0
  } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7198
0
      goto attr_next;
7199
7200
0
  xmlSchemaPIllegalAttrErr(pctxt,
7201
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7202
7203
0
attr_next:
7204
0
  attr = attr->next;
7205
0
    }
7206
    /*
7207
    * 3.2.3 : 2
7208
    * If default and use are both present, use must have
7209
    * the actual value optional.
7210
    */
7211
0
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7212
0
  (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7213
0
  xmlSchemaPSimpleTypeErr(pctxt,
7214
0
      XML_SCHEMAP_SRC_ATTRIBUTE_2,
7215
0
      NULL, node, NULL,
7216
0
      "(optional | prohibited | required)", NULL,
7217
0
      "The value of the attribute 'use' must be 'optional' "
7218
0
      "if the attribute 'default' is present",
7219
0
      NULL, NULL);
7220
0
    }
7221
    /*
7222
    * We want correct attributes.
7223
    */
7224
0
    if (nberrors != pctxt->nberrors)
7225
0
  return(NULL);
7226
0
    if (! isRef) {
7227
0
  xmlSchemaAttributePtr attrDecl;
7228
7229
  /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7230
0
  if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7231
0
      ns = pctxt->targetNamespace;
7232
  /*
7233
  * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7234
  * TODO: Move this to the component layer.
7235
  */
7236
0
  if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7237
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7238
0
    XML_SCHEMAP_NO_XSI,
7239
0
    node, NULL,
7240
0
    "The target namespace must not match '%s'",
7241
0
    xmlSchemaInstanceNs, NULL);
7242
0
  }
7243
0
  attr = xmlSchemaGetPropNode(node, "name");
7244
0
  if (attr == NULL) {
7245
0
      xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7246
0
    NULL, node, "name", NULL);
7247
0
      return (NULL);
7248
0
  }
7249
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7250
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7251
0
      return (NULL);
7252
0
  }
7253
  /*
7254
  * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7255
  * TODO: Move this to the component layer.
7256
  */
7257
0
  if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7258
0
      xmlSchemaPSimpleTypeErr(pctxt,
7259
0
    XML_SCHEMAP_NO_XMLNS,
7260
0
    NULL, (xmlNodePtr) attr,
7261
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7262
0
    "The value of the attribute must not match 'xmlns'",
7263
0
    NULL, NULL);
7264
0
      return (NULL);
7265
0
  }
7266
0
  if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7267
0
      goto check_children;
7268
  /*
7269
  * Create the attribute use component.
7270
  */
7271
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7272
0
  if (use == NULL)
7273
0
      return(NULL);
7274
0
  use->occurs = occurs;
7275
  /*
7276
  * Create the attribute declaration.
7277
  */
7278
0
  attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7279
0
  if (attrDecl == NULL)
7280
0
      return (NULL);
7281
0
  if (tmpName != NULL) {
7282
0
      attrDecl->typeName = tmpName;
7283
0
      attrDecl->typeNs = tmpNs;
7284
0
  }
7285
0
  use->attrDecl = attrDecl;
7286
  /*
7287
  * Value constraint.
7288
  */
7289
0
  if (defValue != NULL) {
7290
0
      attrDecl->defValue = defValue;
7291
0
      if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7292
0
    attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7293
0
  }
7294
0
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7295
0
  xmlSchemaQNameRefPtr ref;
7296
7297
  /*
7298
  * Create the attribute use component.
7299
  */
7300
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7301
0
  if (use == NULL)
7302
0
      return(NULL);
7303
  /*
7304
  * We need to resolve the reference at later stage.
7305
  */
7306
0
  WXS_ADD_PENDING(pctxt, use);
7307
0
  use->occurs = occurs;
7308
  /*
7309
  * Create a QName reference to the attribute declaration.
7310
  */
7311
0
  ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7312
0
      tmpName, tmpNs);
7313
0
  if (ref == NULL)
7314
0
      return(NULL);
7315
  /*
7316
  * Assign the reference. This will be substituted for the
7317
  * referenced attribute declaration when the QName is resolved.
7318
  */
7319
0
  use->attrDecl = WXS_ATTR_CAST ref;
7320
  /*
7321
  * Value constraint.
7322
  */
7323
0
  if (defValue != NULL)
7324
0
      use->defValue = defValue;
7325
0
  if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7326
0
      use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7327
0
    }
7328
7329
0
check_children:
7330
    /*
7331
    * And now for the children...
7332
    */
7333
0
    child = node->children;
7334
0
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7335
0
  xmlSchemaAttributeUseProhibPtr prohib;
7336
7337
0
  if (IS_SCHEMA(child, "annotation")) {
7338
0
      xmlSchemaParseAnnotation(pctxt, child, 0);
7339
0
      child = child->next;
7340
0
  }
7341
0
  if (child != NULL) {
7342
0
      xmlSchemaPContentErr(pctxt,
7343
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7344
0
    NULL, node, child, NULL,
7345
0
    "(annotation?)");
7346
0
  }
7347
  /*
7348
  * Check for pointlessness of attribute prohibitions.
7349
  */
7350
0
  if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7351
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7352
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7353
0
    node, NULL,
7354
0
    "Skipping attribute use prohibition, since it is "
7355
0
    "pointless inside an <attributeGroup>",
7356
0
    NULL, NULL, NULL);
7357
0
      return(NULL);
7358
0
  } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7359
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7360
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7361
0
    node, NULL,
7362
0
    "Skipping attribute use prohibition, since it is "
7363
0
    "pointless when extending a type",
7364
0
    NULL, NULL, NULL);
7365
0
      return(NULL);
7366
0
  }
7367
0
  if (! isRef) {
7368
0
      tmpName = name;
7369
0
      tmpNs = ns;
7370
0
  }
7371
  /*
7372
  * Check for duplicate attribute prohibitions.
7373
  */
7374
0
  if (uses) {
7375
0
      int i;
7376
7377
0
      for (i = 0; i < uses->nbItems; i++) {
7378
0
    use = uses->items[i];
7379
0
    if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7380
0
        (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7381
0
        (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7382
0
    {
7383
0
        xmlChar *str = NULL;
7384
7385
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7386
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7387
0
      node, NULL,
7388
0
      "Skipping duplicate attribute use prohibition '%s'",
7389
0
      xmlSchemaFormatQName(&str, tmpNs, tmpName),
7390
0
      NULL, NULL);
7391
0
        FREE_AND_NULL(str)
7392
0
        return(NULL);
7393
0
    }
7394
0
      }
7395
0
  }
7396
  /*
7397
  * Create the attribute prohibition helper component.
7398
  */
7399
0
  prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7400
0
  if (prohib == NULL)
7401
0
      return(NULL);
7402
0
  prohib->node = node;
7403
0
  prohib->name = tmpName;
7404
0
  prohib->targetNamespace = tmpNs;
7405
0
  if (isRef) {
7406
      /*
7407
      * We need at least to resolve to the attribute declaration.
7408
      */
7409
0
      WXS_ADD_PENDING(pctxt, prohib);
7410
0
  }
7411
0
  return(WXS_BASIC_CAST prohib);
7412
0
    } else {
7413
0
  if (IS_SCHEMA(child, "annotation")) {
7414
      /*
7415
      * TODO: Should this go into the attr decl?
7416
      */
7417
0
      use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7418
0
      child = child->next;
7419
0
  }
7420
0
  if (isRef) {
7421
0
      if (child != NULL) {
7422
0
    if (IS_SCHEMA(child, "simpleType"))
7423
        /*
7424
        * 3.2.3 : 3.2
7425
        * If ref is present, then all of <simpleType>,
7426
        * form and type must be absent.
7427
        */
7428
0
        xmlSchemaPContentErr(pctxt,
7429
0
      XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7430
0
      NULL, node, child, NULL,
7431
0
      "(annotation?)");
7432
0
    else
7433
0
        xmlSchemaPContentErr(pctxt,
7434
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7435
0
      NULL, node, child, NULL,
7436
0
      "(annotation?)");
7437
0
      }
7438
0
  } else {
7439
0
      if (IS_SCHEMA(child, "simpleType")) {
7440
0
    if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7441
        /*
7442
        * 3.2.3 : 4
7443
        * type and <simpleType> must not both be present.
7444
        */
7445
0
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7446
0
      NULL, node, child,
7447
0
      "The attribute 'type' and the <simpleType> child "
7448
0
      "are mutually exclusive", NULL);
7449
0
    } else
7450
0
        WXS_ATTRUSE_TYPEDEF(use) =
7451
0
      xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7452
0
    child = child->next;
7453
0
      }
7454
0
      if (child != NULL)
7455
0
    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7456
0
    NULL, node, child, NULL,
7457
0
    "(annotation?, simpleType?)");
7458
0
  }
7459
0
    }
7460
0
    return (WXS_BASIC_CAST use);
7461
0
}
7462
7463
7464
static xmlSchemaAttributePtr
7465
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7466
            xmlSchemaPtr schema,
7467
            xmlNodePtr node)
7468
0
{
7469
0
    const xmlChar *attrValue;
7470
0
    xmlSchemaAttributePtr ret;
7471
0
    xmlNodePtr child = NULL;
7472
0
    xmlAttrPtr attr;
7473
7474
    /*
7475
     * Note that the w3c spec assumes the schema to be validated with schema
7476
     * for schemas beforehand.
7477
     *
7478
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7479
     */
7480
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7481
0
        return (NULL);
7482
    /*
7483
    * 3.2.3 : 3.1
7484
    * One of ref or name must be present, but not both
7485
    */
7486
0
    attr = xmlSchemaGetPropNode(node, "name");
7487
0
    if (attr == NULL) {
7488
0
  xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7489
0
      NULL, node, "name", NULL);
7490
0
  return (NULL);
7491
0
    }
7492
0
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7493
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7494
0
  return (NULL);
7495
0
    }
7496
    /*
7497
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7498
    * TODO: Move this to the component layer.
7499
    */
7500
0
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7501
0
  xmlSchemaPSimpleTypeErr(pctxt,
7502
0
      XML_SCHEMAP_NO_XMLNS,
7503
0
      NULL, (xmlNodePtr) attr,
7504
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7505
0
      "The value of the attribute must not match 'xmlns'",
7506
0
      NULL, NULL);
7507
0
  return (NULL);
7508
0
    }
7509
    /*
7510
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7511
    * TODO: Move this to the component layer.
7512
    *       Or better leave it here and add it to the component layer
7513
    *       if we have a schema construction API.
7514
    */
7515
0
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7516
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
7517
0
      XML_SCHEMAP_NO_XSI, node, NULL,
7518
0
      "The target namespace must not match '%s'",
7519
0
      xmlSchemaInstanceNs, NULL);
7520
0
    }
7521
7522
0
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7523
0
  pctxt->targetNamespace, node, 1);
7524
0
    if (ret == NULL)
7525
0
  return (NULL);
7526
0
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7527
7528
    /*
7529
    * Check for illegal attributes.
7530
    */
7531
0
    attr = node->properties;
7532
0
    while (attr != NULL) {
7533
0
  if (attr->ns == NULL) {
7534
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7535
0
    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7536
0
    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7537
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7538
0
    (!xmlStrEqual(attr->name, BAD_CAST "type")))
7539
0
      {
7540
0
    xmlSchemaPIllegalAttrErr(pctxt,
7541
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7542
0
      }
7543
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7544
0
      xmlSchemaPIllegalAttrErr(pctxt,
7545
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7546
0
  }
7547
0
  attr = attr->next;
7548
0
    }
7549
0
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
7550
0
  node, "type", &ret->typeNs, &ret->typeName);
7551
7552
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7553
    /*
7554
    * Attribute "fixed".
7555
    */
7556
0
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7557
0
    if (ret->defValue != NULL)
7558
0
  ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7559
    /*
7560
    * Attribute "default".
7561
    */
7562
0
    attr = xmlSchemaGetPropNode(node, "default");
7563
0
    if (attr != NULL) {
7564
  /*
7565
  * 3.2.3 : 1
7566
  * default and fixed must not both be present.
7567
  */
7568
0
  if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7569
0
      xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7570
0
    WXS_BASIC_CAST ret, attr, "default", "fixed");
7571
0
  } else
7572
0
      ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7573
0
    }
7574
    /*
7575
    * And now for the children...
7576
    */
7577
0
    child = node->children;
7578
0
    if (IS_SCHEMA(child, "annotation")) {
7579
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7580
0
        child = child->next;
7581
0
    }
7582
0
    if (IS_SCHEMA(child, "simpleType")) {
7583
0
  if (ret->typeName != NULL) {
7584
      /*
7585
      * 3.2.3 : 4
7586
      * type and <simpleType> must not both be present.
7587
      */
7588
0
      xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7589
0
    NULL, node, child,
7590
0
    "The attribute 'type' and the <simpleType> child "
7591
0
    "are mutually exclusive", NULL);
7592
0
  } else
7593
0
      ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7594
0
  child = child->next;
7595
0
    }
7596
0
    if (child != NULL)
7597
0
  xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7598
0
      NULL, node, child, NULL,
7599
0
      "(annotation?, simpleType?)");
7600
7601
0
    return (ret);
7602
0
}
7603
7604
/**
7605
 * xmlSchemaParseAttributeGroupRef:
7606
 * @ctxt:  a schema validation context
7607
 * @schema:  the schema being built
7608
 * @node:  a subtree containing XML Schema information
7609
 *
7610
 * Parse an attribute group definition reference.
7611
 * Note that a reference to an attribute group does not
7612
 * correspond to any component at all.
7613
 * *WARNING* this interface is highly subject to change
7614
 *
7615
 * Returns the attribute group or NULL in case of error.
7616
 */
7617
static xmlSchemaQNameRefPtr
7618
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7619
        xmlSchemaPtr schema,
7620
        xmlNodePtr node)
7621
0
{
7622
0
    xmlSchemaQNameRefPtr ret;
7623
0
    xmlNodePtr child = NULL;
7624
0
    xmlAttrPtr attr;
7625
0
    const xmlChar *refNs = NULL, *ref = NULL;
7626
7627
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7628
0
        return (NULL);
7629
7630
0
    attr = xmlSchemaGetPropNode(node, "ref");
7631
0
    if (attr == NULL) {
7632
0
  xmlSchemaPMissingAttrErr(pctxt,
7633
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7634
0
      NULL, node, "ref", NULL);
7635
0
  return (NULL);
7636
0
    }
7637
0
    xmlSchemaPValAttrNodeQName(pctxt, schema,
7638
0
  NULL, attr, &refNs, &ref);
7639
0
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7640
0
  return(NULL);
7641
7642
    /*
7643
    * Check for illegal attributes.
7644
    */
7645
0
    attr = node->properties;
7646
0
    while (attr != NULL) {
7647
0
  if (attr->ns == NULL) {
7648
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7649
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7650
0
      {
7651
0
    xmlSchemaPIllegalAttrErr(pctxt,
7652
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7653
0
      }
7654
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7655
0
      xmlSchemaPIllegalAttrErr(pctxt,
7656
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7657
0
  }
7658
0
  attr = attr->next;
7659
0
    }
7660
    /* Attribute ID */
7661
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7662
7663
    /*
7664
    * And now for the children...
7665
    */
7666
0
    child = node->children;
7667
0
    if (IS_SCHEMA(child, "annotation")) {
7668
  /*
7669
  * TODO: We do not have a place to store the annotation, do we?
7670
  */
7671
0
        xmlSchemaParseAnnotation(pctxt, child, 0);
7672
0
        child = child->next;
7673
0
    }
7674
0
    if (child != NULL) {
7675
0
  xmlSchemaPContentErr(pctxt,
7676
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7677
0
      NULL, node, child, NULL,
7678
0
      "(annotation?)");
7679
0
    }
7680
7681
    /*
7682
    * Handle attribute group redefinitions.
7683
    */
7684
0
    if (pctxt->isRedefine && pctxt->redef &&
7685
0
  (pctxt->redef->item->type ==
7686
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7687
0
  (ref == pctxt->redef->refName) &&
7688
0
  (refNs == pctxt->redef->refTargetNs))
7689
0
    {
7690
  /*
7691
  * SPEC src-redefine:
7692
  * (7.1) "If it has an <attributeGroup> among its contents
7693
  * the `actual value` of whose ref [attribute] is the same
7694
  * as the `actual value` of its own name attribute plus
7695
  * target namespace, then it must have exactly one such group."
7696
  */
7697
0
  if (pctxt->redefCounter != 0) {
7698
0
      xmlChar *str = NULL;
7699
7700
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7701
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7702
0
    "The redefining attribute group definition "
7703
0
    "'%s' must not contain more than one "
7704
0
    "reference to the redefined definition",
7705
0
    xmlSchemaFormatQName(&str, refNs, ref), NULL);
7706
0
      FREE_AND_NULL(str);
7707
0
      return(NULL);
7708
0
  }
7709
0
  pctxt->redefCounter++;
7710
  /*
7711
  * URGENT TODO: How to ensure that the reference will not be
7712
  * handled by the normal component resolution mechanism?
7713
  */
7714
0
  ret = xmlSchemaNewQNameRef(pctxt,
7715
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7716
0
  if (ret == NULL)
7717
0
      return(NULL);
7718
0
  ret->node = node;
7719
0
  pctxt->redef->reference = WXS_BASIC_CAST ret;
7720
0
    } else {
7721
  /*
7722
  * Create a QName-reference helper component. We will substitute this
7723
  * component for the attribute uses of the referenced attribute group
7724
  * definition.
7725
  */
7726
0
  ret = xmlSchemaNewQNameRef(pctxt,
7727
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7728
0
  if (ret == NULL)
7729
0
      return(NULL);
7730
0
  ret->node = node;
7731
  /* Add to pending items, to be able to resolve the reference. */
7732
0
  WXS_ADD_PENDING(pctxt, ret);
7733
0
    }
7734
0
    return (ret);
7735
0
}
7736
7737
/**
7738
 * xmlSchemaParseAttributeGroupDefinition:
7739
 * @pctxt:  a schema validation context
7740
 * @schema:  the schema being built
7741
 * @node:  a subtree containing XML Schema information
7742
 *
7743
 * parse a XML schema Attribute Group declaration
7744
 * *WARNING* this interface is highly subject to change
7745
 *
7746
 * Returns the attribute group definition or NULL in case of error.
7747
 */
7748
static xmlSchemaAttributeGroupPtr
7749
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7750
               xmlSchemaPtr schema,
7751
               xmlNodePtr node)
7752
0
{
7753
0
    const xmlChar *name;
7754
0
    xmlSchemaAttributeGroupPtr ret;
7755
0
    xmlNodePtr child = NULL;
7756
0
    xmlAttrPtr attr;
7757
0
    int hasRefs = 0;
7758
7759
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7760
0
        return (NULL);
7761
7762
0
    attr = xmlSchemaGetPropNode(node, "name");
7763
0
    if (attr == NULL) {
7764
0
  xmlSchemaPMissingAttrErr(pctxt,
7765
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7766
0
      NULL, node, "name", NULL);
7767
0
  return (NULL);
7768
0
    }
7769
    /*
7770
    * The name is crucial, exit if invalid.
7771
    */
7772
0
    if (xmlSchemaPValAttrNode(pctxt,
7773
0
  NULL, attr,
7774
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7775
0
  return (NULL);
7776
0
    }
7777
0
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7778
0
  name, pctxt->targetNamespace, node);
7779
0
    if (ret == NULL)
7780
0
  return (NULL);
7781
    /*
7782
    * Check for illegal attributes.
7783
    */
7784
0
    attr = node->properties;
7785
0
    while (attr != NULL) {
7786
0
  if (attr->ns == NULL) {
7787
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7788
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7789
0
      {
7790
0
    xmlSchemaPIllegalAttrErr(pctxt,
7791
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7792
0
      }
7793
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7794
0
      xmlSchemaPIllegalAttrErr(pctxt,
7795
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7796
0
  }
7797
0
  attr = attr->next;
7798
0
    }
7799
    /* Attribute ID */
7800
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7801
    /*
7802
    * And now for the children...
7803
    */
7804
0
    child = node->children;
7805
0
    if (IS_SCHEMA(child, "annotation")) {
7806
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7807
0
        child = child->next;
7808
0
    }
7809
    /*
7810
    * Parse contained attribute decls/refs.
7811
    */
7812
0
    if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7813
0
  (xmlSchemaItemListPtr *) &(ret->attrUses),
7814
0
  XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7815
0
  return(NULL);
7816
0
    if (hasRefs)
7817
0
  ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7818
    /*
7819
    * Parse the attribute wildcard.
7820
    */
7821
0
    if (IS_SCHEMA(child, "anyAttribute")) {
7822
0
  ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7823
0
      schema, child);
7824
0
  child = child->next;
7825
0
    }
7826
0
    if (child != NULL) {
7827
0
  xmlSchemaPContentErr(pctxt,
7828
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7829
0
      NULL, node, child, NULL,
7830
0
      "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7831
0
    }
7832
0
    return (ret);
7833
0
}
7834
7835
/**
7836
 * xmlSchemaPValAttrFormDefault:
7837
 * @value:  the value
7838
 * @flags: the flags to be modified
7839
 * @flagQualified: the specific flag for "qualified"
7840
 *
7841
 * Returns 0 if the value is valid, 1 otherwise.
7842
 */
7843
static int
7844
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7845
           int *flags,
7846
           int flagQualified)
7847
0
{
7848
0
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
7849
0
  if  ((*flags & flagQualified) == 0)
7850
0
      *flags |= flagQualified;
7851
0
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7852
0
  return (1);
7853
7854
0
    return (0);
7855
0
}
7856
7857
/**
7858
 * xmlSchemaPValAttrBlockFinal:
7859
 * @value:  the value
7860
 * @flags: the flags to be modified
7861
 * @flagAll: the specific flag for "#all"
7862
 * @flagExtension: the specific flag for "extension"
7863
 * @flagRestriction: the specific flag for "restriction"
7864
 * @flagSubstitution: the specific flag for "substitution"
7865
 * @flagList: the specific flag for "list"
7866
 * @flagUnion: the specific flag for "union"
7867
 *
7868
 * Validates the value of the attribute "final" and "block". The value
7869
 * is converted into the specified flag values and returned in @flags.
7870
 *
7871
 * Returns 0 if the value is valid, 1 otherwise.
7872
 */
7873
7874
static int
7875
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7876
          int *flags,
7877
          int flagAll,
7878
          int flagExtension,
7879
          int flagRestriction,
7880
          int flagSubstitution,
7881
          int flagList,
7882
          int flagUnion)
7883
0
{
7884
0
    int ret = 0;
7885
7886
    /*
7887
    * TODO: This does not check for duplicate entries.
7888
    */
7889
0
    if ((flags == NULL) || (value == NULL))
7890
0
  return (-1);
7891
0
    if (value[0] == 0)
7892
0
  return (0);
7893
0
    if (xmlStrEqual(value, BAD_CAST "#all")) {
7894
0
  if (flagAll != -1)
7895
0
      *flags |= flagAll;
7896
0
  else {
7897
0
      if (flagExtension != -1)
7898
0
    *flags |= flagExtension;
7899
0
      if (flagRestriction != -1)
7900
0
    *flags |= flagRestriction;
7901
0
      if (flagSubstitution != -1)
7902
0
    *flags |= flagSubstitution;
7903
0
      if (flagList != -1)
7904
0
    *flags |= flagList;
7905
0
      if (flagUnion != -1)
7906
0
    *flags |= flagUnion;
7907
0
  }
7908
0
    } else {
7909
0
  const xmlChar *end, *cur = value;
7910
0
  xmlChar *item;
7911
7912
0
  do {
7913
0
      while (IS_BLANK_CH(*cur))
7914
0
    cur++;
7915
0
      end = cur;
7916
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
7917
0
    end++;
7918
0
      if (end == cur)
7919
0
    break;
7920
0
      item = xmlStrndup(cur, end - cur);
7921
0
      if (xmlStrEqual(item, BAD_CAST "extension")) {
7922
0
    if (flagExtension != -1) {
7923
0
        if ((*flags & flagExtension) == 0)
7924
0
      *flags |= flagExtension;
7925
0
    } else
7926
0
        ret = 1;
7927
0
      } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
7928
0
    if (flagRestriction != -1) {
7929
0
        if ((*flags & flagRestriction) == 0)
7930
0
      *flags |= flagRestriction;
7931
0
    } else
7932
0
        ret = 1;
7933
0
      } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
7934
0
    if (flagSubstitution != -1) {
7935
0
        if ((*flags & flagSubstitution) == 0)
7936
0
      *flags |= flagSubstitution;
7937
0
    } else
7938
0
        ret = 1;
7939
0
      } else if (xmlStrEqual(item, BAD_CAST "list")) {
7940
0
    if (flagList != -1) {
7941
0
        if ((*flags & flagList) == 0)
7942
0
      *flags |= flagList;
7943
0
    } else
7944
0
        ret = 1;
7945
0
      } else if (xmlStrEqual(item, BAD_CAST "union")) {
7946
0
    if (flagUnion != -1) {
7947
0
        if ((*flags & flagUnion) == 0)
7948
0
      *flags |= flagUnion;
7949
0
    } else
7950
0
        ret = 1;
7951
0
      } else
7952
0
    ret = 1;
7953
0
      if (item != NULL)
7954
0
    xmlFree(item);
7955
0
      cur = end;
7956
0
  } while ((ret == 0) && (*cur != 0));
7957
0
    }
7958
7959
0
    return (ret);
7960
0
}
7961
7962
static int
7963
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7964
           xmlSchemaIDCPtr idc,
7965
           xmlSchemaIDCSelectPtr selector,
7966
           xmlAttrPtr attr,
7967
           int isField)
7968
0
{
7969
0
    xmlNodePtr node;
7970
7971
    /*
7972
    * c-selector-xpath:
7973
    * Schema Component Constraint: Selector Value OK
7974
    *
7975
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
7976
    * in [XPath].
7977
    */
7978
0
    if (selector == NULL) {
7979
0
  xmlSchemaPErr(ctxt, idc->node,
7980
0
      XML_SCHEMAP_INTERNAL,
7981
0
      "Internal error: xmlSchemaCheckCSelectorXPath, "
7982
0
      "the selector is not specified.\n", NULL, NULL);
7983
0
  return (-1);
7984
0
    }
7985
0
    if (attr == NULL)
7986
0
  node = idc->node;
7987
0
    else
7988
0
  node = (xmlNodePtr) attr;
7989
0
    if (selector->xpath == NULL) {
7990
0
  xmlSchemaPCustomErr(ctxt,
7991
      /* TODO: Adjust error code. */
7992
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7993
0
      NULL, node,
7994
0
      "The XPath expression of the selector is not valid", NULL);
7995
0
  return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
7996
0
    } else {
7997
0
  const xmlChar **nsArray = NULL;
7998
0
  xmlNsPtr *nsList = NULL;
7999
  /*
8000
  * Compile the XPath expression.
8001
  */
8002
  /*
8003
  * TODO: We need the array of in-scope namespaces for compilation.
8004
  * TODO: Call xmlPatterncompile with different options for selector/
8005
  * field.
8006
  */
8007
0
  if (attr == NULL)
8008
0
      nsList = NULL;
8009
0
  else
8010
0
      nsList = xmlGetNsList(attr->doc, attr->parent);
8011
  /*
8012
  * Build an array of prefixes and namespaces.
8013
  */
8014
0
  if (nsList != NULL) {
8015
0
      int i, count = 0;
8016
8017
0
      for (i = 0; nsList[i] != NULL; i++)
8018
0
    count++;
8019
8020
0
      nsArray = (const xmlChar **) xmlMalloc(
8021
0
    (count * 2 + 1) * sizeof(const xmlChar *));
8022
0
      if (nsArray == NULL) {
8023
0
    xmlSchemaPErrMemory(ctxt);
8024
0
    xmlFree(nsList);
8025
0
    return (-1);
8026
0
      }
8027
0
      for (i = 0; i < count; i++) {
8028
0
    nsArray[2 * i] = nsList[i]->href;
8029
0
    nsArray[2 * i + 1] = nsList[i]->prefix;
8030
0
      }
8031
0
      nsArray[count * 2] = NULL;
8032
0
      xmlFree(nsList);
8033
0
  }
8034
  /*
8035
  * TODO: Differentiate between "selector" and "field".
8036
  */
8037
0
  if (isField)
8038
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8039
0
    NULL, XML_PATTERN_XSFIELD, nsArray);
8040
0
  else
8041
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8042
0
    NULL, XML_PATTERN_XSSEL, nsArray);
8043
0
  if (nsArray != NULL)
8044
0
      xmlFree((xmlChar **) nsArray);
8045
8046
0
  if (selector->xpathComp == NULL) {
8047
0
      xmlSchemaPCustomErr(ctxt,
8048
    /* TODO: Adjust error code? */
8049
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8050
0
    NULL, node,
8051
0
    "The XPath expression '%s' could not be "
8052
0
    "compiled", selector->xpath);
8053
0
      return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8054
0
  }
8055
0
    }
8056
0
    return (0);
8057
0
}
8058
8059
#define ADD_ANNOTATION(annot)   \
8060
0
    xmlSchemaAnnotPtr cur = item->annot; \
8061
0
    if (item->annot == NULL) {  \
8062
0
  item->annot = annot;    \
8063
0
  return (annot);         \
8064
0
    }                           \
8065
0
    cur = item->annot;          \
8066
0
    while (cur->next != NULL) { \
8067
0
  cur = cur->next;  \
8068
0
    }                           \
8069
0
    cur->next = annot;
8070
8071
/**
8072
 * xmlSchemaAssignAnnotation:
8073
 * @item: the schema component
8074
 * @annot: the annotation
8075
 *
8076
 * Adds the annotation to the given schema component.
8077
 *
8078
 * Returns the given annotation.
8079
 */
8080
static xmlSchemaAnnotPtr
8081
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8082
           xmlSchemaAnnotPtr annot)
8083
0
{
8084
0
    if ((annItem == NULL) || (annot == NULL))
8085
0
  return (NULL);
8086
0
    switch (annItem->type) {
8087
0
  case XML_SCHEMA_TYPE_ELEMENT: {
8088
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8089
0
    ADD_ANNOTATION(annot)
8090
0
      }
8091
0
      break;
8092
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
8093
0
    xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8094
0
    ADD_ANNOTATION(annot)
8095
0
      }
8096
0
      break;
8097
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8098
0
  case XML_SCHEMA_TYPE_ANY: {
8099
0
    xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8100
0
    ADD_ANNOTATION(annot)
8101
0
      }
8102
0
      break;
8103
0
  case XML_SCHEMA_TYPE_PARTICLE:
8104
0
  case XML_SCHEMA_TYPE_IDC_KEY:
8105
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
8106
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8107
0
    xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8108
0
    ADD_ANNOTATION(annot)
8109
0
      }
8110
0
      break;
8111
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8112
0
    xmlSchemaAttributeGroupPtr item =
8113
0
        (xmlSchemaAttributeGroupPtr) annItem;
8114
0
    ADD_ANNOTATION(annot)
8115
0
      }
8116
0
      break;
8117
0
  case XML_SCHEMA_TYPE_NOTATION: {
8118
0
    xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8119
0
    ADD_ANNOTATION(annot)
8120
0
      }
8121
0
      break;
8122
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
8123
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
8124
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
8125
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8126
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
8127
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
8128
0
  case XML_SCHEMA_FACET_PATTERN:
8129
0
  case XML_SCHEMA_FACET_ENUMERATION:
8130
0
  case XML_SCHEMA_FACET_WHITESPACE:
8131
0
  case XML_SCHEMA_FACET_LENGTH:
8132
0
  case XML_SCHEMA_FACET_MAXLENGTH:
8133
0
  case XML_SCHEMA_FACET_MINLENGTH: {
8134
0
    xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8135
0
    ADD_ANNOTATION(annot)
8136
0
      }
8137
0
      break;
8138
0
  case XML_SCHEMA_TYPE_SIMPLE:
8139
0
  case XML_SCHEMA_TYPE_COMPLEX: {
8140
0
    xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8141
0
    ADD_ANNOTATION(annot)
8142
0
      }
8143
0
      break;
8144
0
  case XML_SCHEMA_TYPE_GROUP: {
8145
0
    xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8146
0
    ADD_ANNOTATION(annot)
8147
0
      }
8148
0
      break;
8149
0
  case XML_SCHEMA_TYPE_SEQUENCE:
8150
0
  case XML_SCHEMA_TYPE_CHOICE:
8151
0
  case XML_SCHEMA_TYPE_ALL: {
8152
0
    xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8153
0
    ADD_ANNOTATION(annot)
8154
0
      }
8155
0
      break;
8156
0
  default:
8157
0
       xmlSchemaPCustomErr(NULL,
8158
0
    XML_SCHEMAP_INTERNAL,
8159
0
    NULL, NULL,
8160
0
    "Internal error: xmlSchemaAddAnnotation, "
8161
0
    "The item is not a annotated schema component", NULL);
8162
0
       break;
8163
0
    }
8164
0
    return (annot);
8165
0
}
8166
8167
/**
8168
 * xmlSchemaParseIDCSelectorAndField:
8169
 * @ctxt:  a schema validation context
8170
 * @schema:  the schema being built
8171
 * @node:  a subtree containing XML Schema information
8172
 *
8173
 * Parses a XML Schema identity-constraint definition's
8174
 * <selector> and <field> elements.
8175
 *
8176
 * Returns the parsed identity-constraint definition.
8177
 */
8178
static xmlSchemaIDCSelectPtr
8179
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8180
        xmlSchemaIDCPtr idc,
8181
        xmlNodePtr node,
8182
        int isField)
8183
0
{
8184
0
    xmlSchemaIDCSelectPtr item;
8185
0
    xmlNodePtr child = NULL;
8186
0
    xmlAttrPtr attr;
8187
8188
    /*
8189
    * Check for illegal attributes.
8190
    */
8191
0
    attr = node->properties;
8192
0
    while (attr != NULL) {
8193
0
  if (attr->ns == NULL) {
8194
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8195
0
    (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8196
0
    xmlSchemaPIllegalAttrErr(ctxt,
8197
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8198
0
      }
8199
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8200
0
      xmlSchemaPIllegalAttrErr(ctxt,
8201
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8202
0
  }
8203
0
  attr = attr->next;
8204
0
    }
8205
    /*
8206
    * Create the item.
8207
    */
8208
0
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8209
0
    if (item == NULL) {
8210
0
        xmlSchemaPErrMemory(ctxt);
8211
0
        return (NULL);
8212
0
    }
8213
0
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
8214
    /*
8215
    * Attribute "xpath" (mandatory).
8216
    */
8217
0
    attr = xmlSchemaGetPropNode(node, "xpath");
8218
0
    if (attr == NULL) {
8219
0
  xmlSchemaPMissingAttrErr(ctxt,
8220
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8221
0
      NULL, node,
8222
0
      "name", NULL);
8223
0
    } else {
8224
0
  item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8225
  /*
8226
  * URGENT TODO: "field"s have an other syntax than "selector"s.
8227
  */
8228
8229
0
  if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8230
0
      isField) == -1) {
8231
0
      xmlSchemaPErr(ctxt,
8232
0
    (xmlNodePtr) attr,
8233
0
    XML_SCHEMAP_INTERNAL,
8234
0
    "Internal error: xmlSchemaParseIDCSelectorAndField, "
8235
0
    "validating the XPath expression of a IDC selector.\n",
8236
0
    NULL, NULL);
8237
0
  }
8238
8239
0
    }
8240
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8241
    /*
8242
    * And now for the children...
8243
    */
8244
0
    child = node->children;
8245
0
    if (IS_SCHEMA(child, "annotation")) {
8246
  /*
8247
  * Add the annotation to the parent IDC.
8248
  */
8249
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8250
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8251
0
  child = child->next;
8252
0
    }
8253
0
    if (child != NULL) {
8254
0
  xmlSchemaPContentErr(ctxt,
8255
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8256
0
      NULL, node, child,
8257
0
      NULL, "(annotation?)");
8258
0
    }
8259
8260
0
    return (item);
8261
0
}
8262
8263
/**
8264
 * xmlSchemaParseIDC:
8265
 * @ctxt:  a schema validation context
8266
 * @schema:  the schema being built
8267
 * @node:  a subtree containing XML Schema information
8268
 *
8269
 * Parses a XML Schema identity-constraint definition.
8270
 *
8271
 * Returns the parsed identity-constraint definition.
8272
 */
8273
static xmlSchemaIDCPtr
8274
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8275
      xmlSchemaPtr schema,
8276
      xmlNodePtr node,
8277
      xmlSchemaTypeType idcCategory,
8278
      const xmlChar *targetNamespace)
8279
0
{
8280
0
    xmlSchemaIDCPtr item = NULL;
8281
0
    xmlNodePtr child = NULL;
8282
0
    xmlAttrPtr attr;
8283
0
    const xmlChar *name = NULL;
8284
0
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8285
8286
    /*
8287
    * Check for illegal attributes.
8288
    */
8289
0
    attr = node->properties;
8290
0
    while (attr != NULL) {
8291
0
  if (attr->ns == NULL) {
8292
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8293
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8294
0
    ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8295
0
     (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8296
0
    xmlSchemaPIllegalAttrErr(ctxt,
8297
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8298
0
      }
8299
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8300
0
      xmlSchemaPIllegalAttrErr(ctxt,
8301
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8302
0
  }
8303
0
  attr = attr->next;
8304
0
    }
8305
    /*
8306
    * Attribute "name" (mandatory).
8307
    */
8308
0
    attr = xmlSchemaGetPropNode(node, "name");
8309
0
    if (attr == NULL) {
8310
0
  xmlSchemaPMissingAttrErr(ctxt,
8311
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8312
0
      NULL, node,
8313
0
      "name", NULL);
8314
0
  return (NULL);
8315
0
    } else if (xmlSchemaPValAttrNode(ctxt,
8316
0
  NULL, attr,
8317
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8318
0
  return (NULL);
8319
0
    }
8320
    /* Create the component. */
8321
0
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8322
0
  idcCategory, node);
8323
0
    if (item == NULL)
8324
0
  return(NULL);
8325
8326
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8327
0
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8328
  /*
8329
  * Attribute "refer" (mandatory).
8330
  */
8331
0
  attr = xmlSchemaGetPropNode(node, "refer");
8332
0
  if (attr == NULL) {
8333
0
      xmlSchemaPMissingAttrErr(ctxt,
8334
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8335
0
    NULL, node,
8336
0
    "refer", NULL);
8337
0
  } else {
8338
      /*
8339
      * Create a reference item.
8340
      */
8341
0
      item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8342
0
    NULL, NULL);
8343
0
      if (item->ref == NULL)
8344
0
    return (NULL);
8345
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8346
0
    NULL, attr,
8347
0
    &(item->ref->targetNamespace),
8348
0
    &(item->ref->name));
8349
0
      xmlSchemaCheckReference(ctxt, schema, node, attr,
8350
0
    item->ref->targetNamespace);
8351
0
  }
8352
0
    }
8353
    /*
8354
    * And now for the children...
8355
    */
8356
0
    child = node->children;
8357
0
    if (IS_SCHEMA(child, "annotation")) {
8358
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8359
0
  child = child->next;
8360
0
    }
8361
0
    if (child == NULL) {
8362
0
  xmlSchemaPContentErr(ctxt,
8363
0
    XML_SCHEMAP_S4S_ELEM_MISSING,
8364
0
    NULL, node, child,
8365
0
    "A child element is missing",
8366
0
    "(annotation?, (selector, field+))");
8367
0
    }
8368
    /*
8369
    * Child element <selector>.
8370
    */
8371
0
    if (IS_SCHEMA(child, "selector")) {
8372
0
  item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8373
0
      item, child, 0);
8374
0
  child = child->next;
8375
  /*
8376
  * Child elements <field>.
8377
  */
8378
0
  if (IS_SCHEMA(child, "field")) {
8379
0
      do {
8380
0
    field = xmlSchemaParseIDCSelectorAndField(ctxt,
8381
0
        item, child, 1);
8382
0
    if (field != NULL) {
8383
0
        field->index = item->nbFields;
8384
0
        item->nbFields++;
8385
0
        if (lastField != NULL)
8386
0
      lastField->next = field;
8387
0
        else
8388
0
      item->fields = field;
8389
0
        lastField = field;
8390
0
    }
8391
0
    child = child->next;
8392
0
      } while (IS_SCHEMA(child, "field"));
8393
0
  } else {
8394
0
      xmlSchemaPContentErr(ctxt,
8395
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8396
0
    NULL, node, child,
8397
0
    NULL, "(annotation?, (selector, field+))");
8398
0
  }
8399
0
    }
8400
0
    if (child != NULL) {
8401
0
  xmlSchemaPContentErr(ctxt,
8402
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8403
0
      NULL, node, child,
8404
0
      NULL, "(annotation?, (selector, field+))");
8405
0
    }
8406
8407
0
    return (item);
8408
0
}
8409
8410
/**
8411
 * xmlSchemaParseElement:
8412
 * @ctxt:  a schema validation context
8413
 * @schema:  the schema being built
8414
 * @node:  a subtree containing XML Schema information
8415
 * @topLevel: indicates if this is global declaration
8416
 *
8417
 * Parses a XML schema element declaration.
8418
 * *WARNING* this interface is highly subject to change
8419
 *
8420
 * Returns the element declaration or a particle; NULL in case
8421
 * of an error or if the particle has minOccurs==maxOccurs==0.
8422
 */
8423
static xmlSchemaBasicItemPtr
8424
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8425
                      xmlNodePtr node, int *isElemRef, int topLevel)
8426
0
{
8427
0
    xmlSchemaElementPtr decl = NULL;
8428
0
    xmlSchemaParticlePtr particle = NULL;
8429
0
    xmlSchemaAnnotPtr annot = NULL;
8430
0
    xmlNodePtr child = NULL;
8431
0
    xmlAttrPtr attr, nameAttr;
8432
0
    int min, max, isRef = 0;
8433
0
    xmlChar *des = NULL;
8434
8435
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
8436
    /* TODO: Complete implementation of 3.3.6 */
8437
8438
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8439
0
        return (NULL);
8440
8441
0
    if (isElemRef != NULL)
8442
0
  *isElemRef = 0;
8443
    /*
8444
    * If we get a "ref" attribute on a local <element> we will assume it's
8445
    * a reference - even if there's a "name" attribute; this seems to be more
8446
    * robust.
8447
    */
8448
0
    nameAttr = xmlSchemaGetPropNode(node, "name");
8449
0
    attr = xmlSchemaGetPropNode(node, "ref");
8450
0
    if ((topLevel) || (attr == NULL)) {
8451
0
  if (nameAttr == NULL) {
8452
0
      xmlSchemaPMissingAttrErr(ctxt,
8453
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8454
0
    NULL, node, "name", NULL);
8455
0
      return (NULL);
8456
0
  }
8457
0
    } else
8458
0
  isRef = 1;
8459
8460
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8461
0
    child = node->children;
8462
0
    if (IS_SCHEMA(child, "annotation")) {
8463
0
  annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8464
0
  child = child->next;
8465
0
    }
8466
    /*
8467
    * Skip particle part if a global declaration.
8468
    */
8469
0
    if (topLevel)
8470
0
  goto declaration_part;
8471
    /*
8472
    * The particle part ==================================================
8473
    */
8474
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8475
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8476
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8477
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
8478
0
    if (particle == NULL)
8479
0
  goto return_null;
8480
8481
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8482
8483
0
    if (isRef) {
8484
0
  const xmlChar *refNs = NULL, *ref = NULL;
8485
0
  xmlSchemaQNameRefPtr refer = NULL;
8486
  /*
8487
  * The reference part =============================================
8488
  */
8489
0
  if (isElemRef != NULL)
8490
0
      *isElemRef = 1;
8491
8492
0
  xmlSchemaPValAttrNodeQName(ctxt, schema,
8493
0
      NULL, attr, &refNs, &ref);
8494
0
  xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8495
  /*
8496
  * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8497
  */
8498
0
  if (nameAttr != NULL) {
8499
0
      xmlSchemaPMutualExclAttrErr(ctxt,
8500
0
    XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8501
0
  }
8502
  /*
8503
  * Check for illegal attributes.
8504
  */
8505
0
  attr = node->properties;
8506
0
  while (attr != NULL) {
8507
0
      if (attr->ns == NULL) {
8508
0
    if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8509
0
        xmlStrEqual(attr->name, BAD_CAST "name") ||
8510
0
        xmlStrEqual(attr->name, BAD_CAST "id") ||
8511
0
        xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8512
0
        xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8513
0
    {
8514
0
        attr = attr->next;
8515
0
        continue;
8516
0
    } else {
8517
        /* SPEC (3.3.3 : 2.2) */
8518
0
        xmlSchemaPCustomAttrErr(ctxt,
8519
0
      XML_SCHEMAP_SRC_ELEMENT_2_2,
8520
0
      NULL, NULL, attr,
8521
0
      "Only the attributes 'minOccurs', 'maxOccurs' and "
8522
0
      "'id' are allowed in addition to 'ref'");
8523
0
        break;
8524
0
    }
8525
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8526
0
    xmlSchemaPIllegalAttrErr(ctxt,
8527
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8528
0
      }
8529
0
      attr = attr->next;
8530
0
  }
8531
  /*
8532
  * No children except <annotation> expected.
8533
  */
8534
0
  if (child != NULL) {
8535
0
      xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8536
0
    NULL, node, child, NULL, "(annotation?)");
8537
0
  }
8538
0
  if ((min == 0) && (max == 0))
8539
0
      goto return_null;
8540
  /*
8541
  * Create the reference item and attach it to the particle.
8542
  */
8543
0
  refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8544
0
      ref, refNs);
8545
0
  if (refer == NULL)
8546
0
      goto return_null;
8547
0
  particle->children = (xmlSchemaTreeItemPtr) refer;
8548
0
  particle->annot = annot;
8549
  /*
8550
  * Add the particle to pending components, since the reference
8551
  * need to be resolved.
8552
  */
8553
0
  WXS_ADD_PENDING(ctxt, particle);
8554
0
  return ((xmlSchemaBasicItemPtr) particle);
8555
0
    }
8556
    /*
8557
    * The declaration part ===============================================
8558
    */
8559
0
declaration_part:
8560
0
    {
8561
0
  const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8562
0
  xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8563
8564
0
  if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8565
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8566
0
      goto return_null;
8567
  /*
8568
  * Evaluate the target namespace.
8569
  */
8570
0
  if (topLevel) {
8571
0
      ns = ctxt->targetNamespace;
8572
0
  } else {
8573
0
      attr = xmlSchemaGetPropNode(node, "form");
8574
0
      if (attr != NULL) {
8575
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8576
0
    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8577
0
        ns = ctxt->targetNamespace;
8578
0
    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8579
0
        xmlSchemaPSimpleTypeErr(ctxt,
8580
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8581
0
      NULL, (xmlNodePtr) attr,
8582
0
      NULL, "(qualified | unqualified)",
8583
0
      attrValue, NULL, NULL, NULL);
8584
0
    }
8585
0
      } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8586
0
    ns = ctxt->targetNamespace;
8587
0
  }
8588
0
  decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8589
0
  if (decl == NULL) {
8590
0
      goto return_null;
8591
0
  }
8592
  /*
8593
  * Check for illegal attributes.
8594
  */
8595
0
  attr = node->properties;
8596
0
  while (attr != NULL) {
8597
0
      if (attr->ns == NULL) {
8598
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8599
0
        (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8600
0
        (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8601
0
        (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8602
0
        (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8603
0
        (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8604
0
        (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8605
0
    {
8606
0
        if (topLevel == 0) {
8607
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8608
0
          (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8609
0
          (!xmlStrEqual(attr->name, BAD_CAST "form")))
8610
0
      {
8611
0
          xmlSchemaPIllegalAttrErr(ctxt,
8612
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8613
0
      }
8614
0
        } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8615
0
      (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8616
0
      (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8617
8618
0
      xmlSchemaPIllegalAttrErr(ctxt,
8619
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8620
0
        }
8621
0
    }
8622
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8623
8624
0
    xmlSchemaPIllegalAttrErr(ctxt,
8625
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8626
0
      }
8627
0
      attr = attr->next;
8628
0
  }
8629
  /*
8630
  * Extract/validate attributes.
8631
  */
8632
0
  if (topLevel) {
8633
      /*
8634
      * Process top attributes of global element declarations here.
8635
      */
8636
0
      decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8637
0
      decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8638
0
      xmlSchemaPValAttrQName(ctxt, schema,
8639
0
    NULL, node, "substitutionGroup",
8640
0
    &(decl->substGroupNs), &(decl->substGroup));
8641
0
      if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8642
0
    decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8643
      /*
8644
      * Attribute "final".
8645
      */
8646
0
      attr = xmlSchemaGetPropNode(node, "final");
8647
0
      if (attr == NULL) {
8648
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8649
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8650
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8651
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8652
0
      } else {
8653
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8654
0
    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8655
0
        -1,
8656
0
        XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8657
0
        XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8658
0
        xmlSchemaPSimpleTypeErr(ctxt,
8659
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8660
0
      NULL, (xmlNodePtr) attr,
8661
0
      NULL, "(#all | List of (extension | restriction))",
8662
0
      attrValue, NULL, NULL, NULL);
8663
0
    }
8664
0
      }
8665
0
  }
8666
  /*
8667
  * Attribute "block".
8668
  */
8669
0
  attr = xmlSchemaGetPropNode(node, "block");
8670
0
  if (attr == NULL) {
8671
      /*
8672
      * Apply default "block" values.
8673
      */
8674
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8675
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8676
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8677
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8678
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8679
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8680
0
  } else {
8681
0
      attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8682
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8683
0
    -1,
8684
0
    XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8685
0
    XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8686
0
    XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8687
0
    xmlSchemaPSimpleTypeErr(ctxt,
8688
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8689
0
        NULL, (xmlNodePtr) attr,
8690
0
        NULL, "(#all | List of (extension | "
8691
0
        "restriction | substitution))", attrValue,
8692
0
        NULL, NULL, NULL);
8693
0
      }
8694
0
  }
8695
0
  if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8696
0
      decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8697
8698
0
  attr = xmlSchemaGetPropNode(node, "type");
8699
0
  if (attr != NULL) {
8700
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8701
0
    NULL, attr,
8702
0
    &(decl->namedTypeNs), &(decl->namedType));
8703
0
      xmlSchemaCheckReference(ctxt, schema, node,
8704
0
    attr, decl->namedTypeNs);
8705
0
  }
8706
0
  decl->value = xmlSchemaGetProp(ctxt, node, "default");
8707
0
  attr = xmlSchemaGetPropNode(node, "fixed");
8708
0
  if (attr != NULL) {
8709
0
      fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8710
0
      if (decl->value != NULL) {
8711
    /*
8712
    * 3.3.3 : 1
8713
    * default and fixed must not both be present.
8714
    */
8715
0
    xmlSchemaPMutualExclAttrErr(ctxt,
8716
0
        XML_SCHEMAP_SRC_ELEMENT_1,
8717
0
        NULL, attr, "default", "fixed");
8718
0
      } else {
8719
0
    decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8720
0
    decl->value = fixed;
8721
0
      }
8722
0
  }
8723
  /*
8724
  * And now for the children...
8725
  */
8726
0
  if (IS_SCHEMA(child, "complexType")) {
8727
      /*
8728
      * 3.3.3 : 3
8729
      * "type" and either <simpleType> or <complexType> are mutually
8730
      * exclusive
8731
      */
8732
0
      if (decl->namedType != NULL) {
8733
0
    xmlSchemaPContentErr(ctxt,
8734
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8735
0
        NULL, node, child,
8736
0
        "The attribute 'type' and the <complexType> child are "
8737
0
        "mutually exclusive", NULL);
8738
0
      } else
8739
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8740
0
      child = child->next;
8741
0
  } else if (IS_SCHEMA(child, "simpleType")) {
8742
      /*
8743
      * 3.3.3 : 3
8744
      * "type" and either <simpleType> or <complexType> are
8745
      * mutually exclusive
8746
      */
8747
0
      if (decl->namedType != NULL) {
8748
0
    xmlSchemaPContentErr(ctxt,
8749
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8750
0
        NULL, node, child,
8751
0
        "The attribute 'type' and the <simpleType> child are "
8752
0
        "mutually exclusive", NULL);
8753
0
      } else
8754
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8755
0
      child = child->next;
8756
0
  }
8757
0
  while ((IS_SCHEMA(child, "unique")) ||
8758
0
      (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8759
0
      if (IS_SCHEMA(child, "unique")) {
8760
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8761
0
        XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8762
0
      } else if (IS_SCHEMA(child, "key")) {
8763
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8764
0
        XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8765
0
      } else if (IS_SCHEMA(child, "keyref")) {
8766
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8767
0
        XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8768
0
      }
8769
0
      if (lastIDC != NULL)
8770
0
    lastIDC->next = curIDC;
8771
0
      else
8772
0
    decl->idcs = (void *) curIDC;
8773
0
      lastIDC = curIDC;
8774
0
      child = child->next;
8775
0
  }
8776
0
  if (child != NULL) {
8777
0
      xmlSchemaPContentErr(ctxt,
8778
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8779
0
    NULL, node, child,
8780
0
    NULL, "(annotation?, ((simpleType | complexType)?, "
8781
0
    "(unique | key | keyref)*))");
8782
0
  }
8783
0
  decl->annot = annot;
8784
0
    }
8785
    /*
8786
    * NOTE: Element Declaration Representation OK 4. will be checked at a
8787
    * different layer.
8788
    */
8789
0
    FREE_AND_NULL(des)
8790
0
    if (topLevel)
8791
0
  return ((xmlSchemaBasicItemPtr) decl);
8792
0
    else {
8793
0
  particle->children = (xmlSchemaTreeItemPtr) decl;
8794
0
  return ((xmlSchemaBasicItemPtr) particle);
8795
0
    }
8796
8797
0
return_null:
8798
0
    FREE_AND_NULL(des);
8799
0
    if (annot != NULL) {
8800
0
  if (particle != NULL)
8801
0
      particle->annot = NULL;
8802
0
  if (decl != NULL)
8803
0
      decl->annot = NULL;
8804
0
  xmlSchemaFreeAnnot(annot);
8805
0
    }
8806
0
    return (NULL);
8807
0
}
8808
8809
/**
8810
 * xmlSchemaParseUnion:
8811
 * @ctxt:  a schema validation context
8812
 * @schema:  the schema being built
8813
 * @node:  a subtree containing XML Schema information
8814
 *
8815
 * parse a XML schema Union definition
8816
 * *WARNING* this interface is highly subject to change
8817
 *
8818
 * Returns -1 in case of internal error, 0 in case of success and a positive
8819
 * error code otherwise.
8820
 */
8821
static int
8822
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8823
                    xmlNodePtr node)
8824
0
{
8825
0
    xmlSchemaTypePtr type;
8826
0
    xmlNodePtr child = NULL;
8827
0
    xmlAttrPtr attr;
8828
0
    const xmlChar *cur = NULL;
8829
8830
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8831
0
        return (-1);
8832
    /* Not a component, don't create it. */
8833
0
    type = ctxt->ctxtType;
8834
    /*
8835
    * Mark the simple type as being of variety "union".
8836
    */
8837
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8838
    /*
8839
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8840
    * then the `simple ur-type definition`."
8841
    */
8842
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8843
    /*
8844
    * Check for illegal attributes.
8845
    */
8846
0
    attr = node->properties;
8847
0
    while (attr != NULL) {
8848
0
  if (attr->ns == NULL) {
8849
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8850
0
    (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8851
0
    xmlSchemaPIllegalAttrErr(ctxt,
8852
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8853
0
      }
8854
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8855
0
      xmlSchemaPIllegalAttrErr(ctxt,
8856
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8857
0
  }
8858
0
  attr = attr->next;
8859
0
    }
8860
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8861
    /*
8862
    * Attribute "memberTypes". This is a list of QNames.
8863
    * TODO: Check the value to contain anything.
8864
    */
8865
0
    attr = xmlSchemaGetPropNode(node, "memberTypes");
8866
0
    if (attr != NULL) {
8867
0
  const xmlChar *end;
8868
0
  xmlChar *tmp;
8869
0
  const xmlChar *localName, *nsName;
8870
0
  xmlSchemaTypeLinkPtr link, lastLink = NULL;
8871
0
  xmlSchemaQNameRefPtr ref;
8872
8873
0
  cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8874
0
        if (cur == NULL)
8875
0
            return (-1);
8876
0
  type->base = cur;
8877
0
  do {
8878
0
      while (IS_BLANK_CH(*cur))
8879
0
    cur++;
8880
0
      end = cur;
8881
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8882
0
    end++;
8883
0
      if (end == cur)
8884
0
    break;
8885
0
      tmp = xmlStrndup(cur, end - cur);
8886
0
            if (tmp == NULL) {
8887
0
                xmlSchemaPErrMemory(ctxt);
8888
0
                return (-1);
8889
0
            }
8890
0
      if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8891
0
    NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
8892
    /*
8893
    * Create the member type link.
8894
    */
8895
0
    link = (xmlSchemaTypeLinkPtr)
8896
0
        xmlMalloc(sizeof(xmlSchemaTypeLink));
8897
0
    if (link == NULL) {
8898
0
        xmlSchemaPErrMemory(ctxt);
8899
0
              FREE_AND_NULL(tmp)
8900
0
        return (-1);
8901
0
    }
8902
0
    link->type = NULL;
8903
0
    link->next = NULL;
8904
0
    if (lastLink == NULL)
8905
0
        type->memberTypes = link;
8906
0
    else
8907
0
        lastLink->next = link;
8908
0
    lastLink = link;
8909
    /*
8910
    * Create a reference item.
8911
    */
8912
0
    ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8913
0
        localName, nsName);
8914
0
    if (ref == NULL) {
8915
0
        FREE_AND_NULL(tmp)
8916
0
        return (-1);
8917
0
    }
8918
    /*
8919
    * Assign the reference to the link, it will be resolved
8920
    * later during fixup of the union simple type.
8921
    */
8922
0
    link->type = (xmlSchemaTypePtr) ref;
8923
0
      }
8924
0
      FREE_AND_NULL(tmp)
8925
0
      cur = end;
8926
0
  } while (*cur != 0);
8927
8928
0
    }
8929
    /*
8930
    * And now for the children...
8931
    */
8932
0
    child = node->children;
8933
0
    if (IS_SCHEMA(child, "annotation")) {
8934
  /*
8935
  * Add the annotation to the simple type ancestor.
8936
  */
8937
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8938
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8939
0
        child = child->next;
8940
0
    }
8941
0
    if (IS_SCHEMA(child, "simpleType")) {
8942
0
  xmlSchemaTypePtr subtype, last = NULL;
8943
8944
  /*
8945
  * Anchor the member types in the "subtypes" field of the
8946
  * simple type.
8947
  */
8948
0
  while (IS_SCHEMA(child, "simpleType")) {
8949
0
      subtype = (xmlSchemaTypePtr)
8950
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8951
0
      if (subtype != NULL) {
8952
0
    if (last == NULL) {
8953
0
        type->subtypes = subtype;
8954
0
        last = subtype;
8955
0
    } else {
8956
0
        last->next = subtype;
8957
0
        last = subtype;
8958
0
    }
8959
0
    last->next = NULL;
8960
0
      }
8961
0
      child = child->next;
8962
0
  }
8963
0
    }
8964
0
    if (child != NULL) {
8965
0
  xmlSchemaPContentErr(ctxt,
8966
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8967
0
      NULL, node, child, NULL, "(annotation?, simpleType*)");
8968
0
    }
8969
0
    if ((attr == NULL) && (type->subtypes == NULL)) {
8970
   /*
8971
  * src-union-memberTypes-or-simpleTypes
8972
  * Either the memberTypes [attribute] of the <union> element must
8973
  * be non-empty or there must be at least one simpleType [child].
8974
  */
8975
0
  xmlSchemaPCustomErr(ctxt,
8976
0
      XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8977
0
      NULL, node,
8978
0
      "Either the attribute 'memberTypes' or "
8979
0
      "at least one <simpleType> child must be present", NULL);
8980
0
    }
8981
0
    return (0);
8982
0
}
8983
8984
/**
8985
 * xmlSchemaParseList:
8986
 * @ctxt:  a schema validation context
8987
 * @schema:  the schema being built
8988
 * @node:  a subtree containing XML Schema information
8989
 *
8990
 * parse a XML schema List definition
8991
 * *WARNING* this interface is highly subject to change
8992
 *
8993
 * Returns -1 in case of error, 0 if the declaration is improper and
8994
 *         1 in case of success.
8995
 */
8996
static xmlSchemaTypePtr
8997
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8998
                   xmlNodePtr node)
8999
0
{
9000
0
    xmlSchemaTypePtr type;
9001
0
    xmlNodePtr child = NULL;
9002
0
    xmlAttrPtr attr;
9003
9004
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9005
0
        return (NULL);
9006
    /* Not a component, don't create it. */
9007
0
    type = ctxt->ctxtType;
9008
    /*
9009
    * Mark the type as being of variety "list".
9010
    */
9011
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9012
    /*
9013
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9014
    * then the `simple ur-type definition`."
9015
    */
9016
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9017
    /*
9018
    * Check for illegal attributes.
9019
    */
9020
0
    attr = node->properties;
9021
0
    while (attr != NULL) {
9022
0
  if (attr->ns == NULL) {
9023
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9024
0
    (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
9025
0
    xmlSchemaPIllegalAttrErr(ctxt,
9026
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9027
0
      }
9028
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9029
0
      xmlSchemaPIllegalAttrErr(ctxt,
9030
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9031
0
  }
9032
0
  attr = attr->next;
9033
0
    }
9034
9035
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9036
9037
    /*
9038
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9039
    * fields for holding the reference to the itemType.
9040
    *
9041
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9042
    * the "ref" fields.
9043
    */
9044
0
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
9045
0
  node, "itemType", &(type->baseNs), &(type->base));
9046
    /*
9047
    * And now for the children...
9048
    */
9049
0
    child = node->children;
9050
0
    if (IS_SCHEMA(child, "annotation")) {
9051
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9052
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
9053
0
        child = child->next;
9054
0
    }
9055
0
    if (IS_SCHEMA(child, "simpleType")) {
9056
  /*
9057
  * src-list-itemType-or-simpleType
9058
  * Either the itemType [attribute] or the <simpleType> [child] of
9059
  * the <list> element must be present, but not both.
9060
  */
9061
0
  if (type->base != NULL) {
9062
0
      xmlSchemaPCustomErr(ctxt,
9063
0
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9064
0
    NULL, node,
9065
0
    "The attribute 'itemType' and the <simpleType> child "
9066
0
    "are mutually exclusive", NULL);
9067
0
  } else {
9068
0
      type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9069
0
  }
9070
0
        child = child->next;
9071
0
    } else if (type->base == NULL) {
9072
0
  xmlSchemaPCustomErr(ctxt,
9073
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9074
0
      NULL, node,
9075
0
      "Either the attribute 'itemType' or the <simpleType> child "
9076
0
      "must be present", NULL);
9077
0
    }
9078
0
    if (child != NULL) {
9079
0
  xmlSchemaPContentErr(ctxt,
9080
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9081
0
      NULL, node, child, NULL, "(annotation?, simpleType?)");
9082
0
    }
9083
0
    if ((type->base == NULL) &&
9084
0
  (type->subtypes == NULL) &&
9085
0
  (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9086
0
  xmlSchemaPCustomErr(ctxt,
9087
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9088
0
      NULL, node,
9089
0
      "Either the attribute 'itemType' or the <simpleType> child "
9090
0
      "must be present", NULL);
9091
0
    }
9092
0
    return (NULL);
9093
0
}
9094
9095
/**
9096
 * xmlSchemaParseSimpleType:
9097
 * @ctxt:  a schema validation context
9098
 * @schema:  the schema being built
9099
 * @node:  a subtree containing XML Schema information
9100
 *
9101
 * parse a XML schema Simple Type definition
9102
 * *WARNING* this interface is highly subject to change
9103
 *
9104
 * Returns -1 in case of error, 0 if the declaration is improper and
9105
 * 1 in case of success.
9106
 */
9107
static xmlSchemaTypePtr
9108
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9109
                         xmlNodePtr node, int topLevel)
9110
0
{
9111
0
    xmlSchemaTypePtr type, oldCtxtType;
9112
0
    xmlNodePtr child = NULL;
9113
0
    const xmlChar *attrValue = NULL;
9114
0
    xmlAttrPtr attr;
9115
0
    int hasRestriction = 0;
9116
9117
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9118
0
        return (NULL);
9119
9120
0
    if (topLevel) {
9121
0
  attr = xmlSchemaGetPropNode(node, "name");
9122
0
  if (attr == NULL) {
9123
0
      xmlSchemaPMissingAttrErr(ctxt,
9124
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
9125
0
    NULL, node,
9126
0
    "name", NULL);
9127
0
      return (NULL);
9128
0
  } else {
9129
0
      if (xmlSchemaPValAttrNode(ctxt,
9130
0
    NULL, attr,
9131
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9132
0
    return (NULL);
9133
      /*
9134
      * Skip built-in types.
9135
      */
9136
0
      if (ctxt->isS4S) {
9137
0
    xmlSchemaTypePtr biType;
9138
9139
0
    if (ctxt->isRedefine) {
9140
        /*
9141
        * REDEFINE: Disallow redefinition of built-in-types.
9142
        * TODO: It seems that the spec does not say anything
9143
        * about this case.
9144
        */
9145
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9146
0
      NULL, node,
9147
0
      "Redefinition of built-in simple types is not "
9148
0
      "supported", NULL);
9149
0
        return(NULL);
9150
0
    }
9151
0
    biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9152
0
    if (biType != NULL)
9153
0
        return (biType);
9154
0
      }
9155
0
  }
9156
0
    }
9157
    /*
9158
    * TargetNamespace:
9159
    * SPEC "The `actual value` of the targetNamespace [attribute]
9160
    * of the <schema> ancestor element information item if present,
9161
    * otherwise `absent`.
9162
    */
9163
0
    if (topLevel == 0) {
9164
#ifdef ENABLE_NAMED_LOCALS
9165
        char buf[40];
9166
#endif
9167
  /*
9168
  * Parse as local simple type definition.
9169
  */
9170
#ifdef ENABLE_NAMED_LOCALS
9171
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9172
  type = xmlSchemaAddType(ctxt, schema,
9173
      XML_SCHEMA_TYPE_SIMPLE,
9174
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9175
      ctxt->targetNamespace, node, 0);
9176
#else
9177
0
  type = xmlSchemaAddType(ctxt, schema,
9178
0
      XML_SCHEMA_TYPE_SIMPLE,
9179
0
      NULL, ctxt->targetNamespace, node, 0);
9180
0
#endif
9181
0
  if (type == NULL)
9182
0
      return (NULL);
9183
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9184
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9185
  /*
9186
  * Check for illegal attributes.
9187
  */
9188
0
  attr = node->properties;
9189
0
  while (attr != NULL) {
9190
0
      if (attr->ns == NULL) {
9191
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9192
0
        xmlSchemaPIllegalAttrErr(ctxt,
9193
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9194
0
    }
9195
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9196
0
        xmlSchemaPIllegalAttrErr(ctxt,
9197
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9198
0
      }
9199
0
      attr = attr->next;
9200
0
  }
9201
0
    } else {
9202
  /*
9203
  * Parse as global simple type definition.
9204
  *
9205
  * Note that attrValue is the value of the attribute "name" here.
9206
  */
9207
0
  type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9208
0
      attrValue, ctxt->targetNamespace, node, 1);
9209
0
  if (type == NULL)
9210
0
      return (NULL);
9211
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9212
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9213
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9214
  /*
9215
  * Check for illegal attributes.
9216
  */
9217
0
  attr = node->properties;
9218
0
  while (attr != NULL) {
9219
0
      if (attr->ns == NULL) {
9220
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9221
0
        (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9222
0
        (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9223
0
        xmlSchemaPIllegalAttrErr(ctxt,
9224
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9225
0
    }
9226
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9227
0
    xmlSchemaPIllegalAttrErr(ctxt,
9228
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9229
0
      }
9230
0
      attr = attr->next;
9231
0
  }
9232
  /*
9233
  * Attribute "final".
9234
  */
9235
0
  attr = xmlSchemaGetPropNode(node, "final");
9236
0
  if (attr == NULL) {
9237
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9238
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9239
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9240
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9241
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9242
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9243
0
  } else {
9244
0
      attrValue = xmlSchemaGetProp(ctxt, node, "final");
9245
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9246
0
    -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9247
0
    XML_SCHEMAS_TYPE_FINAL_LIST,
9248
0
    XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9249
9250
0
    xmlSchemaPSimpleTypeErr(ctxt,
9251
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9252
0
        WXS_BASIC_CAST type, (xmlNodePtr) attr,
9253
0
        NULL, "(#all | List of (list | union | restriction)",
9254
0
        attrValue, NULL, NULL, NULL);
9255
0
      }
9256
0
  }
9257
0
    }
9258
0
    type->targetNamespace = ctxt->targetNamespace;
9259
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9260
    /*
9261
    * And now for the children...
9262
    */
9263
0
    oldCtxtType = ctxt->ctxtType;
9264
9265
0
    ctxt->ctxtType = type;
9266
9267
0
    child = node->children;
9268
0
    if (IS_SCHEMA(child, "annotation")) {
9269
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9270
0
        child = child->next;
9271
0
    }
9272
0
    if (child == NULL) {
9273
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9274
0
      NULL, node, child, NULL,
9275
0
      "(annotation?, (restriction | list | union))");
9276
0
    } else if (IS_SCHEMA(child, "restriction")) {
9277
0
        xmlSchemaParseRestriction(ctxt, schema, child,
9278
0
      XML_SCHEMA_TYPE_SIMPLE);
9279
0
  hasRestriction = 1;
9280
0
        child = child->next;
9281
0
    } else if (IS_SCHEMA(child, "list")) {
9282
0
        xmlSchemaParseList(ctxt, schema, child);
9283
0
        child = child->next;
9284
0
    } else if (IS_SCHEMA(child, "union")) {
9285
0
        xmlSchemaParseUnion(ctxt, schema, child);
9286
0
        child = child->next;
9287
0
    }
9288
0
    if (child != NULL) {
9289
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9290
0
      NULL, node, child, NULL,
9291
0
      "(annotation?, (restriction | list | union))");
9292
0
    }
9293
    /*
9294
    * REDEFINE: SPEC src-redefine (5)
9295
    * "Within the [children], each <simpleType> must have a
9296
    * <restriction> among its [children] ... the `actual value` of whose
9297
    * base [attribute] must be the same as the `actual value` of its own
9298
    * name attribute plus target namespace;"
9299
    */
9300
0
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9301
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9302
0
      NULL, node, "This is a redefinition, thus the "
9303
0
      "<simpleType> must have a <restriction> child", NULL);
9304
0
    }
9305
9306
0
    ctxt->ctxtType = oldCtxtType;
9307
0
    return (type);
9308
0
}
9309
9310
/**
9311
 * xmlSchemaParseModelGroupDefRef:
9312
 * @ctxt:  the parser context
9313
 * @schema: the schema being built
9314
 * @node:  the node
9315
 *
9316
 * Parses a reference to a model group definition.
9317
 *
9318
 * We will return a particle component with a qname-component or
9319
 * NULL in case of an error.
9320
 */
9321
static xmlSchemaTreeItemPtr
9322
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9323
             xmlSchemaPtr schema,
9324
             xmlNodePtr node)
9325
0
{
9326
0
    xmlSchemaParticlePtr item;
9327
0
    xmlNodePtr child = NULL;
9328
0
    xmlAttrPtr attr;
9329
0
    const xmlChar *ref = NULL, *refNs = NULL;
9330
0
    int min, max;
9331
9332
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9333
0
        return (NULL);
9334
9335
0
    attr = xmlSchemaGetPropNode(node, "ref");
9336
0
    if (attr == NULL) {
9337
0
  xmlSchemaPMissingAttrErr(ctxt,
9338
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9339
0
      NULL, node, "ref", NULL);
9340
0
  return (NULL);
9341
0
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9342
0
  attr, &refNs, &ref) != 0) {
9343
0
  return (NULL);
9344
0
    }
9345
0
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9346
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9347
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9348
0
  "(xs:nonNegativeInteger | unbounded)");
9349
    /*
9350
    * Check for illegal attributes.
9351
    */
9352
0
    attr = node->properties;
9353
0
    while (attr != NULL) {
9354
0
  if (attr->ns == NULL) {
9355
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9356
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9357
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9358
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9359
0
    xmlSchemaPIllegalAttrErr(ctxt,
9360
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9361
0
      }
9362
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9363
0
      xmlSchemaPIllegalAttrErr(ctxt,
9364
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9365
0
  }
9366
0
  attr = attr->next;
9367
0
    }
9368
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9369
0
    item = xmlSchemaAddParticle(ctxt, node, min, max);
9370
0
    if (item == NULL)
9371
0
  return (NULL);
9372
    /*
9373
    * Create a qname-reference and set as the term; it will be substituted
9374
    * for the model group after the reference has been resolved.
9375
    */
9376
0
    item->children = (xmlSchemaTreeItemPtr)
9377
0
  xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9378
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9379
    /*
9380
    * And now for the children...
9381
    */
9382
0
    child = node->children;
9383
    /* TODO: Is annotation even allowed for a model group reference? */
9384
0
    if (IS_SCHEMA(child, "annotation")) {
9385
  /*
9386
  * TODO: What to do exactly with the annotation?
9387
  */
9388
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9389
0
  child = child->next;
9390
0
    }
9391
0
    if (child != NULL) {
9392
0
  xmlSchemaPContentErr(ctxt,
9393
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9394
0
      NULL, node, child, NULL,
9395
0
      "(annotation?)");
9396
0
    }
9397
    /*
9398
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
9399
    */
9400
0
    if ((min == 0) && (max == 0))
9401
0
  return (NULL);
9402
9403
0
    return ((xmlSchemaTreeItemPtr) item);
9404
0
}
9405
9406
/**
9407
 * xmlSchemaParseModelGroupDefinition:
9408
 * @ctxt:  a schema validation context
9409
 * @schema:  the schema being built
9410
 * @node:  a subtree containing XML Schema information
9411
 *
9412
 * Parses a XML schema model group definition.
9413
 *
9414
 * Note that the constraint src-redefine (6.2) can't be applied until
9415
 * references have been resolved. So we will do this at the
9416
 * component fixup level.
9417
 *
9418
 * *WARNING* this interface is highly subject to change
9419
 *
9420
 * Returns -1 in case of error, 0 if the declaration is improper and
9421
 *         1 in case of success.
9422
 */
9423
static xmlSchemaModelGroupDefPtr
9424
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9425
           xmlSchemaPtr schema,
9426
           xmlNodePtr node)
9427
0
{
9428
0
    xmlSchemaModelGroupDefPtr item;
9429
0
    xmlNodePtr child = NULL;
9430
0
    xmlAttrPtr attr;
9431
0
    const xmlChar *name;
9432
9433
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9434
0
        return (NULL);
9435
9436
0
    attr = xmlSchemaGetPropNode(node, "name");
9437
0
    if (attr == NULL) {
9438
0
  xmlSchemaPMissingAttrErr(ctxt,
9439
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9440
0
      NULL, node,
9441
0
      "name", NULL);
9442
0
  return (NULL);
9443
0
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9444
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9445
0
  return (NULL);
9446
0
    }
9447
0
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9448
0
  ctxt->targetNamespace, node);
9449
0
    if (item == NULL)
9450
0
  return (NULL);
9451
    /*
9452
    * Check for illegal attributes.
9453
    */
9454
0
    attr = node->properties;
9455
0
    while (attr != NULL) {
9456
0
  if (attr->ns == NULL) {
9457
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9458
0
    (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9459
0
    xmlSchemaPIllegalAttrErr(ctxt,
9460
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9461
0
      }
9462
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9463
0
      xmlSchemaPIllegalAttrErr(ctxt,
9464
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9465
0
  }
9466
0
  attr = attr->next;
9467
0
    }
9468
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9469
    /*
9470
    * And now for the children...
9471
    */
9472
0
    child = node->children;
9473
0
    if (IS_SCHEMA(child, "annotation")) {
9474
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9475
0
  child = child->next;
9476
0
    }
9477
0
    if (IS_SCHEMA(child, "all")) {
9478
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9479
0
      XML_SCHEMA_TYPE_ALL, 0);
9480
0
  child = child->next;
9481
0
    } else if (IS_SCHEMA(child, "choice")) {
9482
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9483
0
      XML_SCHEMA_TYPE_CHOICE, 0);
9484
0
  child = child->next;
9485
0
    } else if (IS_SCHEMA(child, "sequence")) {
9486
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9487
0
      XML_SCHEMA_TYPE_SEQUENCE, 0);
9488
0
  child = child->next;
9489
0
    }
9490
9491
9492
9493
0
    if (child != NULL) {
9494
0
  xmlSchemaPContentErr(ctxt,
9495
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9496
0
      NULL, node, child, NULL,
9497
0
      "(annotation?, (all | choice | sequence)?)");
9498
0
    }
9499
0
    return (item);
9500
0
}
9501
9502
/**
9503
 * xmlSchemaCleanupDoc:
9504
 * @ctxt:  a schema validation context
9505
 * @node:  the root of the document.
9506
 *
9507
 * removes unwanted nodes in a schemas document tree
9508
 */
9509
static void
9510
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9511
0
{
9512
0
    xmlNodePtr delete, cur;
9513
9514
0
    if ((ctxt == NULL) || (root == NULL)) return;
9515
9516
    /*
9517
     * Remove all the blank text nodes
9518
     */
9519
0
    delete = NULL;
9520
0
    cur = root;
9521
0
    while (cur != NULL) {
9522
0
        if (delete != NULL) {
9523
0
            xmlUnlinkNode(delete);
9524
0
            xmlFreeNode(delete);
9525
0
            delete = NULL;
9526
0
        }
9527
0
        if (cur->type == XML_TEXT_NODE) {
9528
0
            if (IS_BLANK_NODE(cur)) {
9529
0
                if (xmlNodeGetSpacePreserve(cur) != 1) {
9530
0
                    delete = cur;
9531
0
                }
9532
0
            }
9533
0
        } else if ((cur->type != XML_ELEMENT_NODE) &&
9534
0
                   (cur->type != XML_CDATA_SECTION_NODE)) {
9535
0
            delete = cur;
9536
0
            goto skip_children;
9537
0
        }
9538
9539
        /*
9540
         * Skip to next node
9541
         */
9542
0
        if (cur->children != NULL) {
9543
0
            if ((cur->children->type != XML_ENTITY_DECL) &&
9544
0
                (cur->children->type != XML_ENTITY_REF_NODE) &&
9545
0
                (cur->children->type != XML_ENTITY_NODE)) {
9546
0
                cur = cur->children;
9547
0
                continue;
9548
0
            }
9549
0
        }
9550
0
      skip_children:
9551
0
        if (cur->next != NULL) {
9552
0
            cur = cur->next;
9553
0
            continue;
9554
0
        }
9555
9556
0
        do {
9557
0
            cur = cur->parent;
9558
0
            if (cur == NULL)
9559
0
                break;
9560
0
            if (cur == root) {
9561
0
                cur = NULL;
9562
0
                break;
9563
0
            }
9564
0
            if (cur->next != NULL) {
9565
0
                cur = cur->next;
9566
0
                break;
9567
0
            }
9568
0
        } while (cur != NULL);
9569
0
    }
9570
0
    if (delete != NULL) {
9571
0
        xmlUnlinkNode(delete);
9572
0
        xmlFreeNode(delete);
9573
0
        delete = NULL;
9574
0
    }
9575
0
}
9576
9577
9578
static void
9579
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9580
0
{
9581
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9582
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9583
9584
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9585
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9586
9587
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9588
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9589
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9590
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9591
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9592
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9593
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9594
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9595
9596
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9597
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9598
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9599
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9600
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9601
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9602
0
}
9603
9604
static int
9605
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9606
           xmlSchemaPtr schema,
9607
           xmlNodePtr node)
9608
0
{
9609
0
    xmlAttrPtr attr;
9610
0
    const xmlChar *val;
9611
0
    int res = 0, oldErrs = ctxt->nberrors;
9612
9613
    /*
9614
    * Those flags should be moved to the parser context flags,
9615
    * since they are not visible at the component level. I.e.
9616
    * they are used if processing schema *documents* only.
9617
    */
9618
0
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9619
0
    HFAILURE;
9620
9621
    /*
9622
    * Since the version is of type xs:token, we won't bother to
9623
    * check it.
9624
    */
9625
    /* REMOVED:
9626
    attr = xmlSchemaGetPropNode(node, "version");
9627
    if (attr != NULL) {
9628
  res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9629
      xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9630
  HFAILURE;
9631
    }
9632
    */
9633
0
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
9634
0
    if (attr != NULL) {
9635
0
  res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9636
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9637
0
  HFAILURE;
9638
0
  if (res != 0) {
9639
0
      ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9640
0
      goto exit;
9641
0
  }
9642
0
    }
9643
0
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9644
0
    if (attr != NULL) {
9645
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9646
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9647
0
      XML_SCHEMAS_QUALIF_ELEM);
9648
0
  HFAILURE;
9649
0
  if (res != 0) {
9650
0
      xmlSchemaPSimpleTypeErr(ctxt,
9651
0
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9652
0
    NULL, (xmlNodePtr) attr, NULL,
9653
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9654
0
  }
9655
0
    }
9656
0
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9657
0
    if (attr != NULL) {
9658
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9659
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9660
0
      XML_SCHEMAS_QUALIF_ATTR);
9661
0
  HFAILURE;
9662
0
  if (res != 0) {
9663
0
      xmlSchemaPSimpleTypeErr(ctxt,
9664
0
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9665
0
    NULL, (xmlNodePtr) attr, NULL,
9666
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9667
0
  }
9668
0
    }
9669
0
    attr = xmlSchemaGetPropNode(node, "finalDefault");
9670
0
    if (attr != NULL) {
9671
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9672
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9673
0
      XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9674
0
      XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9675
0
      -1,
9676
0
      XML_SCHEMAS_FINAL_DEFAULT_LIST,
9677
0
      XML_SCHEMAS_FINAL_DEFAULT_UNION);
9678
0
  HFAILURE;
9679
0
  if (res != 0) {
9680
0
      xmlSchemaPSimpleTypeErr(ctxt,
9681
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9682
0
    NULL, (xmlNodePtr) attr, NULL,
9683
0
    "(#all | List of (extension | restriction | list | union))",
9684
0
    val, NULL, NULL, NULL);
9685
0
  }
9686
0
    }
9687
0
    attr = xmlSchemaGetPropNode(node, "blockDefault");
9688
0
    if (attr != NULL) {
9689
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9690
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9691
0
      XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9692
0
      XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9693
0
      XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9694
0
  HFAILURE;
9695
0
  if (res != 0) {
9696
0
      xmlSchemaPSimpleTypeErr(ctxt,
9697
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9698
0
    NULL, (xmlNodePtr) attr, NULL,
9699
0
    "(#all | List of (extension | restriction | substitution))",
9700
0
    val, NULL, NULL, NULL);
9701
0
  }
9702
0
    }
9703
9704
0
exit:
9705
0
    if (oldErrs != ctxt->nberrors)
9706
0
  res = ctxt->err;
9707
0
    return(res);
9708
0
exit_failure:
9709
0
    return(-1);
9710
0
}
9711
9712
/**
9713
 * xmlSchemaParseSchemaTopLevel:
9714
 * @ctxt:  a schema validation context
9715
 * @schema:  the schemas
9716
 * @nodes:  the list of top level nodes
9717
 *
9718
 * Returns the internal XML Schema structure built from the resource or
9719
 *         NULL in case of error
9720
 */
9721
static int
9722
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9723
                             xmlSchemaPtr schema, xmlNodePtr nodes)
9724
0
{
9725
0
    xmlNodePtr child;
9726
0
    xmlSchemaAnnotPtr annot;
9727
0
    int res = 0, oldErrs, tmpOldErrs;
9728
9729
0
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9730
0
        return(-1);
9731
9732
0
    oldErrs = ctxt->nberrors;
9733
0
    child = nodes;
9734
0
    while ((IS_SCHEMA(child, "include")) ||
9735
0
     (IS_SCHEMA(child, "import")) ||
9736
0
     (IS_SCHEMA(child, "redefine")) ||
9737
0
     (IS_SCHEMA(child, "annotation"))) {
9738
0
  if (IS_SCHEMA(child, "annotation")) {
9739
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9740
0
      if (schema->annot == NULL)
9741
0
    schema->annot = annot;
9742
0
      else
9743
0
    xmlSchemaFreeAnnot(annot);
9744
0
  } else if (IS_SCHEMA(child, "import")) {
9745
0
      tmpOldErrs = ctxt->nberrors;
9746
0
      res = xmlSchemaParseImport(ctxt, schema, child);
9747
0
      HFAILURE;
9748
0
      HSTOP(ctxt);
9749
0
      if (tmpOldErrs != ctxt->nberrors)
9750
0
    goto exit;
9751
0
  } else if (IS_SCHEMA(child, "include")) {
9752
0
      tmpOldErrs = ctxt->nberrors;
9753
0
      res = xmlSchemaParseInclude(ctxt, schema, child);
9754
0
      HFAILURE;
9755
0
      HSTOP(ctxt);
9756
0
      if (tmpOldErrs != ctxt->nberrors)
9757
0
    goto exit;
9758
0
  } else if (IS_SCHEMA(child, "redefine")) {
9759
0
      tmpOldErrs = ctxt->nberrors;
9760
0
      res = xmlSchemaParseRedefine(ctxt, schema, child);
9761
0
      HFAILURE;
9762
0
      HSTOP(ctxt);
9763
0
      if (tmpOldErrs != ctxt->nberrors)
9764
0
    goto exit;
9765
0
  }
9766
0
  child = child->next;
9767
0
    }
9768
    /*
9769
    * URGENT TODO: Change the functions to return int results.
9770
    * We need especially to catch internal errors.
9771
    */
9772
0
    while (child != NULL) {
9773
0
  if (IS_SCHEMA(child, "complexType")) {
9774
0
      xmlSchemaParseComplexType(ctxt, schema, child, 1);
9775
0
      child = child->next;
9776
0
  } else if (IS_SCHEMA(child, "simpleType")) {
9777
0
      xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9778
0
      child = child->next;
9779
0
  } else if (IS_SCHEMA(child, "element")) {
9780
0
      xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9781
0
      child = child->next;
9782
0
  } else if (IS_SCHEMA(child, "attribute")) {
9783
0
      xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9784
0
      child = child->next;
9785
0
  } else if (IS_SCHEMA(child, "attributeGroup")) {
9786
0
      xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9787
0
      child = child->next;
9788
0
  } else if (IS_SCHEMA(child, "group")) {
9789
0
      xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9790
0
      child = child->next;
9791
0
  } else if (IS_SCHEMA(child, "notation")) {
9792
0
      xmlSchemaParseNotation(ctxt, schema, child);
9793
0
      child = child->next;
9794
0
  } else {
9795
0
      xmlSchemaPContentErr(ctxt,
9796
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9797
0
    NULL, child->parent, child,
9798
0
    NULL, "((include | import | redefine | annotation)*, "
9799
0
    "(((simpleType | complexType | group | attributeGroup) "
9800
0
    "| element | attribute | notation), annotation*)*)");
9801
0
      child = child->next;
9802
0
  }
9803
0
  while (IS_SCHEMA(child, "annotation")) {
9804
      /*
9805
      * TODO: We should add all annotations.
9806
      */
9807
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9808
0
      if (schema->annot == NULL)
9809
0
    schema->annot = annot;
9810
0
      else
9811
0
    xmlSchemaFreeAnnot(annot);
9812
0
      child = child->next;
9813
0
  }
9814
0
    }
9815
0
exit:
9816
0
    ctxt->ctxtType = NULL;
9817
0
    if (oldErrs != ctxt->nberrors)
9818
0
  res = ctxt->err;
9819
0
    return(res);
9820
0
exit_failure:
9821
0
    return(-1);
9822
0
}
9823
9824
static xmlSchemaSchemaRelationPtr
9825
xmlSchemaSchemaRelationCreate(void)
9826
0
{
9827
0
    xmlSchemaSchemaRelationPtr ret;
9828
9829
0
    ret = (xmlSchemaSchemaRelationPtr)
9830
0
  xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9831
0
    if (ret == NULL) {
9832
0
  xmlSchemaPErrMemory(NULL);
9833
0
  return(NULL);
9834
0
    }
9835
0
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9836
0
    return(ret);
9837
0
}
9838
9839
#if 0
9840
static void
9841
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9842
{
9843
    xmlFree(rel);
9844
}
9845
#endif
9846
9847
static void
9848
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9849
0
{
9850
0
    xmlSchemaRedefPtr prev;
9851
9852
0
    while (redef != NULL) {
9853
0
  prev = redef;
9854
0
  redef = redef->next;
9855
0
  xmlFree(prev);
9856
0
    }
9857
0
}
9858
9859
static void
9860
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9861
0
{
9862
    /*
9863
    * After the construction context has been freed, there will be
9864
    * no schema graph available any more. Only the schema buckets
9865
    * will stay alive, which are put into the "schemasImports" and
9866
    * "includes" slots of the xmlSchema.
9867
    */
9868
0
    if (con->buckets != NULL)
9869
0
  xmlSchemaItemListFree(con->buckets);
9870
0
    if (con->pending != NULL)
9871
0
  xmlSchemaItemListFree(con->pending);
9872
0
    if (con->substGroups != NULL)
9873
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9874
0
    if (con->redefs != NULL)
9875
0
  xmlSchemaRedefListFree(con->redefs);
9876
0
    if (con->dict != NULL)
9877
0
  xmlDictFree(con->dict);
9878
0
    xmlFree(con);
9879
0
}
9880
9881
static xmlSchemaConstructionCtxtPtr
9882
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9883
0
{
9884
0
    xmlSchemaConstructionCtxtPtr ret;
9885
9886
0
    ret = (xmlSchemaConstructionCtxtPtr)
9887
0
  xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9888
0
    if (ret == NULL) {
9889
0
        xmlSchemaPErrMemory(NULL);
9890
0
        return (NULL);
9891
0
    }
9892
0
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9893
9894
0
    ret->buckets = xmlSchemaItemListCreate();
9895
0
    if (ret->buckets == NULL) {
9896
0
  xmlSchemaPErrMemory(NULL);
9897
0
  xmlFree(ret);
9898
0
        return (NULL);
9899
0
    }
9900
0
    ret->pending = xmlSchemaItemListCreate();
9901
0
    if (ret->pending == NULL) {
9902
0
  xmlSchemaPErrMemory(NULL);
9903
0
  xmlSchemaConstructionCtxtFree(ret);
9904
0
        return (NULL);
9905
0
    }
9906
0
    ret->dict = dict;
9907
0
    xmlDictReference(dict);
9908
0
    return(ret);
9909
0
}
9910
9911
static xmlSchemaParserCtxtPtr
9912
xmlSchemaParserCtxtCreate(void)
9913
0
{
9914
0
    xmlSchemaParserCtxtPtr ret;
9915
9916
0
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9917
0
    if (ret == NULL) {
9918
0
        xmlSchemaPErrMemory(NULL);
9919
0
        return (NULL);
9920
0
    }
9921
0
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9922
0
    ret->type = XML_SCHEMA_CTXT_PARSER;
9923
0
    ret->attrProhibs = xmlSchemaItemListCreate();
9924
0
    if (ret->attrProhibs == NULL) {
9925
0
  xmlFree(ret);
9926
0
  return(NULL);
9927
0
    }
9928
0
    return(ret);
9929
0
}
9930
9931
/**
9932
 * xmlSchemaNewParserCtxtUseDict:
9933
 * @URL:  the location of the schema
9934
 * @dict: the dictionary to be used
9935
 *
9936
 * Create an XML Schemas parse context for that file/resource expected
9937
 * to contain an XML Schemas file.
9938
 *
9939
 * Returns the parser context or NULL in case of error
9940
 */
9941
static xmlSchemaParserCtxtPtr
9942
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9943
0
{
9944
0
    xmlSchemaParserCtxtPtr ret;
9945
9946
0
    ret = xmlSchemaParserCtxtCreate();
9947
0
    if (ret == NULL)
9948
0
        return (NULL);
9949
0
    ret->dict = dict;
9950
0
    xmlDictReference(dict);
9951
0
    if (URL != NULL)
9952
0
  ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9953
0
    return (ret);
9954
0
}
9955
9956
static int
9957
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9958
0
{
9959
0
    if (vctxt->pctxt == NULL) {
9960
0
        if (vctxt->schema != NULL)
9961
0
      vctxt->pctxt =
9962
0
    xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9963
0
  else
9964
0
      vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9965
0
  if (vctxt->pctxt == NULL) {
9966
0
      VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
9967
0
    "failed to create a temp. parser context");
9968
0
      return (-1);
9969
0
  }
9970
  /* TODO: Pass user data. */
9971
0
  xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9972
0
      vctxt->warning, vctxt->errCtxt);
9973
0
  xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9974
0
      vctxt->errCtxt);
9975
0
    }
9976
0
    return (0);
9977
0
}
9978
9979
/**
9980
 * xmlSchemaGetSchemaBucket:
9981
 * @pctxt: the schema parser context
9982
 * @schemaLocation: the URI of the schema document
9983
 *
9984
 * Returns a schema bucket if it was already parsed.
9985
 *
9986
 * Returns a schema bucket if it was already parsed from
9987
 *         @schemaLocation, NULL otherwise.
9988
 */
9989
static xmlSchemaBucketPtr
9990
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9991
          const xmlChar *schemaLocation)
9992
0
{
9993
0
    xmlSchemaBucketPtr cur;
9994
0
    xmlSchemaItemListPtr list;
9995
9996
0
    list = pctxt->constructor->buckets;
9997
0
    if (list->nbItems == 0)
9998
0
  return(NULL);
9999
0
    else {
10000
0
  int i;
10001
0
  for (i = 0; i < list->nbItems; i++) {
10002
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10003
      /* Pointer comparison! */
10004
0
      if (cur->schemaLocation == schemaLocation)
10005
0
    return(cur);
10006
0
  }
10007
0
    }
10008
0
    return(NULL);
10009
0
}
10010
10011
static xmlSchemaBucketPtr
10012
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10013
             const xmlChar *schemaLocation,
10014
             const xmlChar *targetNamespace)
10015
0
{
10016
0
    xmlSchemaBucketPtr cur;
10017
0
    xmlSchemaItemListPtr list;
10018
10019
0
    list = pctxt->constructor->buckets;
10020
0
    if (list->nbItems == 0)
10021
0
  return(NULL);
10022
0
    else {
10023
0
  int i;
10024
0
  for (i = 0; i < list->nbItems; i++) {
10025
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10026
      /* Pointer comparison! */
10027
0
      if ((cur->origTargetNamespace == NULL) &&
10028
0
    (cur->schemaLocation == schemaLocation) &&
10029
0
    (cur->targetNamespace == targetNamespace))
10030
0
    return(cur);
10031
0
  }
10032
0
    }
10033
0
    return(NULL);
10034
0
}
10035
10036
10037
#define IS_BAD_SCHEMA_DOC(b) \
10038
0
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10039
10040
static xmlSchemaBucketPtr
10041
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10042
         const xmlChar *targetNamespace,
10043
         int imported)
10044
0
{
10045
0
    xmlSchemaBucketPtr cur;
10046
0
    xmlSchemaItemListPtr list;
10047
10048
0
    list = pctxt->constructor->buckets;
10049
0
    if (list->nbItems == 0)
10050
0
  return(NULL);
10051
0
    else {
10052
0
  int i;
10053
0
  for (i = 0; i < list->nbItems; i++) {
10054
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10055
0
      if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10056
0
    (cur->origTargetNamespace == targetNamespace) &&
10057
0
    ((imported && cur->imported) ||
10058
0
     ((!imported) && (!cur->imported))))
10059
0
    return(cur);
10060
0
  }
10061
0
    }
10062
0
    return(NULL);
10063
0
}
10064
10065
static int
10066
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10067
         xmlSchemaPtr schema,
10068
         xmlSchemaBucketPtr bucket)
10069
0
{
10070
0
    int oldFlags;
10071
0
    xmlDocPtr oldDoc;
10072
0
    xmlNodePtr node;
10073
0
    int ret, oldErrs;
10074
0
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10075
10076
    /*
10077
    * Save old values; reset the *main* schema.
10078
    * URGENT TODO: This is not good; move the per-document information
10079
    * to the parser. Get rid of passing the main schema to the
10080
    * parsing functions.
10081
    */
10082
0
    oldFlags = schema->flags;
10083
0
    oldDoc = schema->doc;
10084
0
    if (schema->flags != 0)
10085
0
  xmlSchemaClearSchemaDefaults(schema);
10086
0
    schema->doc = bucket->doc;
10087
0
    pctxt->schema = schema;
10088
    /*
10089
    * Keep the current target namespace on the parser *not* on the
10090
    * main schema.
10091
    */
10092
0
    pctxt->targetNamespace = bucket->targetNamespace;
10093
0
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10094
10095
0
    if ((bucket->targetNamespace != NULL) &&
10096
0
  xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10097
  /*
10098
  * We are parsing the schema for schemas!
10099
  */
10100
0
  pctxt->isS4S = 1;
10101
0
    }
10102
    /* Mark it as parsed, even if parsing fails. */
10103
0
    bucket->parsed++;
10104
    /* Compile the schema doc. */
10105
0
    node = xmlDocGetRootElement(bucket->doc);
10106
0
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10107
0
    if (ret != 0)
10108
0
  goto exit;
10109
    /* An empty schema; just get out. */
10110
0
    if (node->children == NULL)
10111
0
  goto exit;
10112
0
    oldErrs = pctxt->nberrors;
10113
0
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10114
0
    if (ret != 0)
10115
0
  goto exit;
10116
    /*
10117
    * TODO: Not nice, but I'm not 100% sure we will get always an error
10118
    * as a result of the above functions; so better rely on pctxt->err
10119
    * as well.
10120
    */
10121
0
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10122
0
  ret = pctxt->err;
10123
0
  goto exit;
10124
0
    }
10125
10126
0
exit:
10127
0
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10128
    /* Restore schema values. */
10129
0
    schema->doc = oldDoc;
10130
0
    schema->flags = oldFlags;
10131
0
    return(ret);
10132
0
}
10133
10134
static int
10135
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10136
         xmlSchemaPtr schema,
10137
         xmlSchemaBucketPtr bucket)
10138
0
{
10139
0
    xmlSchemaParserCtxtPtr newpctxt;
10140
0
    int res = 0;
10141
10142
0
    if (bucket == NULL)
10143
0
  return(0);
10144
0
    if (bucket->parsed) {
10145
0
  PERROR_INT("xmlSchemaParseNewDoc",
10146
0
      "reparsing a schema doc");
10147
0
  return(-1);
10148
0
    }
10149
0
    if (bucket->doc == NULL) {
10150
0
  PERROR_INT("xmlSchemaParseNewDoc",
10151
0
      "parsing a schema doc, but there's no doc");
10152
0
  return(-1);
10153
0
    }
10154
0
    if (pctxt->constructor == NULL) {
10155
0
  PERROR_INT("xmlSchemaParseNewDoc",
10156
0
      "no constructor");
10157
0
  return(-1);
10158
0
    }
10159
    /* Create and init the temporary parser context. */
10160
0
    newpctxt = xmlSchemaNewParserCtxtUseDict(
10161
0
  (const char *) bucket->schemaLocation, pctxt->dict);
10162
0
    if (newpctxt == NULL)
10163
0
  return(-1);
10164
0
    newpctxt->constructor = pctxt->constructor;
10165
    /*
10166
    * TODO: Can we avoid that the parser knows about the main schema?
10167
    * It would be better if he knows about the current schema bucket
10168
    * only.
10169
    */
10170
0
    newpctxt->schema = schema;
10171
0
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10172
0
  pctxt->errCtxt);
10173
0
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10174
0
  pctxt->errCtxt);
10175
0
    newpctxt->counter = pctxt->counter;
10176
10177
10178
0
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10179
10180
    /* Channel back errors and cleanup the temporary parser context. */
10181
0
    if (res != 0)
10182
0
  pctxt->err = res;
10183
0
    pctxt->nberrors += newpctxt->nberrors;
10184
0
    pctxt->counter = newpctxt->counter;
10185
0
    newpctxt->constructor = NULL;
10186
    /* Free the parser context. */
10187
0
    xmlSchemaFreeParserCtxt(newpctxt);
10188
0
    return(res);
10189
0
}
10190
10191
static void
10192
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10193
        xmlSchemaSchemaRelationPtr rel)
10194
0
{
10195
0
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
10196
10197
0
    if (cur == NULL) {
10198
0
  bucket->relations = rel;
10199
0
  return;
10200
0
    }
10201
0
    while (cur->next != NULL)
10202
0
  cur = cur->next;
10203
0
    cur->next = rel;
10204
0
}
10205
10206
10207
static const xmlChar *
10208
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10209
        xmlNodePtr ctxtNode)
10210
0
{
10211
    /*
10212
    * Build an absolute location URI.
10213
    */
10214
0
    if (location != NULL) {
10215
0
  if (ctxtNode == NULL)
10216
0
      return(location);
10217
0
  else {
10218
0
      xmlChar *base, *URI;
10219
0
      const xmlChar *ret = NULL;
10220
10221
0
      base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10222
0
      if (base == NULL) {
10223
0
    URI = xmlBuildURI(location, ctxtNode->doc->URL);
10224
0
      } else {
10225
0
    URI = xmlBuildURI(location, base);
10226
0
    xmlFree(base);
10227
0
      }
10228
0
      if (URI != NULL) {
10229
0
    ret = xmlDictLookup(dict, URI, -1);
10230
0
    xmlFree(URI);
10231
0
    return(ret);
10232
0
      }
10233
0
  }
10234
0
    }
10235
0
    return(NULL);
10236
0
}
10237
10238
10239
10240
/**
10241
 * xmlSchemaAddSchemaDoc:
10242
 * @pctxt:  a schema validation context
10243
 * @schema:  the schema being built
10244
 * @node:  a subtree containing XML Schema information
10245
 *
10246
 * Parse an included (and to-be-redefined) XML schema document.
10247
 *
10248
 * Returns 0 on success, a positive error code on errors and
10249
 *         -1 in case of an internal or API error.
10250
 */
10251
10252
static int
10253
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10254
    int type, /* import or include or redefine */
10255
    const xmlChar *schemaLocation,
10256
    xmlDocPtr schemaDoc,
10257
    const char *schemaBuffer,
10258
    int schemaBufferLen,
10259
    xmlNodePtr invokingNode,
10260
    const xmlChar *sourceTargetNamespace,
10261
    const xmlChar *importNamespace,
10262
    xmlSchemaBucketPtr *bucket)
10263
0
{
10264
0
    const xmlChar *targetNamespace = NULL;
10265
0
    xmlSchemaSchemaRelationPtr relation = NULL;
10266
0
    xmlDocPtr doc = NULL;
10267
0
    int res = 0, err = 0, located = 0, preserveDoc = 0;
10268
0
    xmlSchemaBucketPtr bkt = NULL;
10269
10270
0
    if (bucket != NULL)
10271
0
  *bucket = NULL;
10272
10273
0
    switch (type) {
10274
0
  case XML_SCHEMA_SCHEMA_IMPORT:
10275
0
  case XML_SCHEMA_SCHEMA_MAIN:
10276
0
      err = XML_SCHEMAP_SRC_IMPORT;
10277
0
      break;
10278
0
  case XML_SCHEMA_SCHEMA_INCLUDE:
10279
0
      err = XML_SCHEMAP_SRC_INCLUDE;
10280
0
      break;
10281
0
  case XML_SCHEMA_SCHEMA_REDEFINE:
10282
0
      err = XML_SCHEMAP_SRC_REDEFINE;
10283
0
      break;
10284
0
    }
10285
10286
10287
    /* Special handling for the main schema:
10288
    * skip the location and relation logic and just parse the doc.
10289
    * We need just a bucket to be returned in this case.
10290
    */
10291
0
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10292
0
  goto doc_load;
10293
10294
    /* Note that we expect the location to be an absolute URI. */
10295
0
    if (schemaLocation != NULL) {
10296
0
  bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10297
0
  if ((bkt != NULL) &&
10298
0
      (pctxt->constructor->bucket == bkt)) {
10299
      /* Report self-imports/inclusions/redefinitions. */
10300
10301
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10302
0
    invokingNode, NULL,
10303
0
    "The schema must not import/include/redefine itself",
10304
0
    NULL, NULL);
10305
0
      goto exit;
10306
0
  }
10307
0
    }
10308
    /*
10309
    * Create a relation for the graph of schemas.
10310
    */
10311
0
    relation = xmlSchemaSchemaRelationCreate();
10312
0
    if (relation == NULL)
10313
0
  return(-1);
10314
0
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10315
0
  relation);
10316
0
    relation->type = type;
10317
10318
    /*
10319
    * Save the namespace import information.
10320
    */
10321
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10322
0
  relation->importNamespace = importNamespace;
10323
0
  if (schemaLocation == NULL) {
10324
      /*
10325
      * No location; this is just an import of the namespace.
10326
      * Note that we don't assign a bucket to the relation
10327
      * in this case.
10328
      */
10329
0
      goto exit;
10330
0
  }
10331
0
  targetNamespace = importNamespace;
10332
0
    }
10333
10334
    /* Did we already fetch the doc? */
10335
0
    if (bkt != NULL) {
10336
0
  if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10337
      /*
10338
      * We included/redefined and then try to import a schema,
10339
      * but the new location provided for import was different.
10340
      */
10341
0
      if (schemaLocation == NULL)
10342
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10343
0
      if (!xmlStrEqual(schemaLocation,
10344
0
    bkt->schemaLocation)) {
10345
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10346
0
        invokingNode, NULL,
10347
0
        "The schema document '%s' cannot be imported, since "
10348
0
        "it was already included or redefined",
10349
0
        schemaLocation, NULL);
10350
0
    goto exit;
10351
0
      }
10352
0
  } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10353
      /*
10354
      * We imported and then try to include/redefine a schema,
10355
      * but the new location provided for the include/redefine
10356
      * was different.
10357
      */
10358
0
      if (schemaLocation == NULL)
10359
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10360
0
      if (!xmlStrEqual(schemaLocation,
10361
0
    bkt->schemaLocation)) {
10362
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10363
0
        invokingNode, NULL,
10364
0
        "The schema document '%s' cannot be included or "
10365
0
        "redefined, since it was already imported",
10366
0
        schemaLocation, NULL);
10367
0
    goto exit;
10368
0
      }
10369
0
  }
10370
0
    }
10371
10372
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10373
  /*
10374
  * Given that the schemaLocation [attribute] is only a hint, it is open
10375
  * to applications to ignore all but the first <import> for a given
10376
  * namespace, regardless of the `actual value` of schemaLocation, but
10377
  * such a strategy risks missing useful information when new
10378
  * schemaLocations are offered.
10379
  *
10380
  * We will use the first <import> that comes with a location.
10381
  * Further <import>s *with* a location, will result in an error.
10382
  * TODO: Better would be to just report a warning here, but
10383
  * we'll try it this way until someone complains.
10384
  *
10385
  * Schema Document Location Strategy:
10386
  * 3 Based on the namespace name, identify an existing schema document,
10387
  * either as a resource which is an XML document or a <schema> element
10388
  * information item, in some local schema repository;
10389
  * 5 Attempt to resolve the namespace name to locate such a resource.
10390
  *
10391
  * NOTE: (3) and (5) are not supported.
10392
  */
10393
0
  if (bkt != NULL) {
10394
0
      relation->bucket = bkt;
10395
0
      goto exit;
10396
0
  }
10397
0
  bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10398
0
      importNamespace, 1);
10399
10400
0
  if (bkt != NULL) {
10401
0
      relation->bucket = bkt;
10402
0
      if (bkt->schemaLocation == NULL) {
10403
    /* First given location of the schema; load the doc. */
10404
0
    bkt->schemaLocation = schemaLocation;
10405
0
      } else {
10406
0
    if (!xmlStrEqual(schemaLocation,
10407
0
        bkt->schemaLocation)) {
10408
        /*
10409
        * Additional location given; just skip it.
10410
        * URGENT TODO: We should report a warning here.
10411
        * res = XML_SCHEMAP_SRC_IMPORT;
10412
        */
10413
0
        if (schemaLocation == NULL)
10414
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10415
10416
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10417
0
      XML_SCHEMAP_WARN_SKIP_SCHEMA,
10418
0
      invokingNode, NULL,
10419
0
      "Skipping import of schema located at '%s' for the "
10420
0
      "namespace '%s', since this namespace was already "
10421
0
      "imported with the schema located at '%s'",
10422
0
      schemaLocation, importNamespace, bkt->schemaLocation);
10423
0
    }
10424
0
    goto exit;
10425
0
      }
10426
0
  }
10427
  /*
10428
  * No bucket + first location: load the doc and create a
10429
  * bucket.
10430
  */
10431
0
    } else {
10432
  /* <include> and <redefine> */
10433
0
  if (bkt != NULL) {
10434
10435
0
      if ((bkt->origTargetNamespace == NULL) &&
10436
0
    (bkt->targetNamespace != sourceTargetNamespace)) {
10437
0
    xmlSchemaBucketPtr chamel;
10438
10439
    /*
10440
    * Chameleon include/redefine: skip loading only if it was
10441
    * already build for the targetNamespace of the including
10442
    * schema.
10443
    */
10444
    /*
10445
    * URGENT TODO: If the schema is a chameleon-include then copy
10446
    * the components into the including schema and modify the
10447
    * targetNamespace of those components, do nothing otherwise.
10448
    * NOTE: This is currently worked-around by compiling the
10449
    * chameleon for every distinct including targetNamespace; thus
10450
    * not performant at the moment.
10451
    * TODO: Check when the namespace in wildcards for chameleons
10452
    * needs to be converted: before we built wildcard intersections
10453
    * or after.
10454
    *   Answer: after!
10455
    */
10456
0
    chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10457
0
        schemaLocation, sourceTargetNamespace);
10458
0
    if (chamel != NULL) {
10459
        /* A fitting chameleon was already parsed; NOP. */
10460
0
        relation->bucket = chamel;
10461
0
        goto exit;
10462
0
    }
10463
    /*
10464
    * We need to parse the chameleon again for a different
10465
    * targetNamespace.
10466
    * CHAMELEON TODO: Optimize this by only parsing the
10467
    * chameleon once, and then copying the components to
10468
    * the new targetNamespace.
10469
    */
10470
0
    bkt = NULL;
10471
0
      } else {
10472
0
    relation->bucket = bkt;
10473
0
    goto exit;
10474
0
      }
10475
0
  }
10476
0
    }
10477
0
    if ((bkt != NULL) && (bkt->doc != NULL)) {
10478
0
  PERROR_INT("xmlSchemaAddSchemaDoc",
10479
0
      "trying to load a schema doc, but a doc is already "
10480
0
      "assigned to the schema bucket");
10481
0
  goto exit_failure;
10482
0
    }
10483
10484
0
doc_load:
10485
    /*
10486
    * Load the document.
10487
    */
10488
0
    if (schemaDoc != NULL) {
10489
0
  doc = schemaDoc;
10490
  /* Don' free this one, since it was provided by the caller. */
10491
0
  preserveDoc = 1;
10492
  /* TODO: Does the context or the doc hold the location? */
10493
0
  if (schemaDoc->URL != NULL)
10494
0
      schemaLocation = xmlDictLookup(pctxt->dict,
10495
0
    schemaDoc->URL, -1);
10496
0
        else
10497
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10498
0
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10499
0
  xmlParserCtxtPtr parserCtxt;
10500
10501
0
  parserCtxt = xmlNewParserCtxt();
10502
0
  if (parserCtxt == NULL) {
10503
0
      xmlSchemaPErrMemory(NULL);
10504
0
      goto exit_failure;
10505
0
  }
10506
10507
0
        if (pctxt->serror != NULL)
10508
0
            xmlCtxtSetErrorHandler(parserCtxt, pctxt->serror, pctxt->errCtxt);
10509
10510
0
  if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10511
      /*
10512
      * TODO: Do we have to burden the schema parser dict with all
10513
      * the content of the schema doc?
10514
      */
10515
0
      xmlDictFree(parserCtxt->dict);
10516
0
      parserCtxt->dict = pctxt->dict;
10517
0
      xmlDictReference(parserCtxt->dict);
10518
0
  }
10519
0
  if (schemaLocation != NULL) {
10520
      /* Parse from file. */
10521
0
      doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10522
0
    NULL, SCHEMAS_PARSE_OPTIONS);
10523
0
  } else if (schemaBuffer != NULL) {
10524
      /* Parse from memory buffer. */
10525
0
      doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10526
0
    NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10527
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10528
0
      if (doc != NULL)
10529
0
    doc->URL = xmlStrdup(schemaLocation);
10530
0
  }
10531
  /*
10532
  * For <import>:
10533
  * 2.1 The referent is (a fragment of) a resource which is an
10534
  * XML document (see clause 1.1), which in turn corresponds to
10535
  * a <schema> element information item in a well-formed information
10536
  * set, which in turn corresponds to a valid schema.
10537
  * TODO: (2.1) fragments of XML documents are not supported.
10538
  *
10539
  * 2.2 The referent is a <schema> element information item in
10540
  * a well-formed information set, which in turn corresponds
10541
  * to a valid schema.
10542
  * TODO: (2.2) is not supported.
10543
  */
10544
0
  if (doc == NULL) {
10545
0
      const xmlError *lerr;
10546
0
      lerr = xmlGetLastError();
10547
      /*
10548
      * Check if this a parser error, or if the document could
10549
      * just not be located.
10550
      * TODO: Try to find specific error codes to react only on
10551
      * localisation failures.
10552
      */
10553
0
      if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10554
    /*
10555
    * We assume a parser error here.
10556
    */
10557
0
    located = 1;
10558
    /* TODO: Error code ?? */
10559
0
    res = XML_SCHEMAP_SRC_IMPORT_2_1;
10560
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10561
0
        invokingNode, NULL,
10562
0
        "Failed to parse the XML resource '%s'",
10563
0
        schemaLocation, NULL);
10564
0
      }
10565
0
  }
10566
0
  xmlFreeParserCtxt(parserCtxt);
10567
0
  if ((doc == NULL) && located)
10568
0
      goto exit_error;
10569
0
    } else {
10570
0
  xmlSchemaPErr(pctxt, NULL,
10571
0
      XML_SCHEMAP_NOTHING_TO_PARSE,
10572
0
      "No information for parsing was provided with the "
10573
0
      "given schema parser context.\n",
10574
0
      NULL, NULL);
10575
0
  goto exit_failure;
10576
0
    }
10577
    /*
10578
    * Preprocess the document.
10579
    */
10580
0
    if (doc != NULL) {
10581
0
  xmlNodePtr docElem = NULL;
10582
10583
0
  located = 1;
10584
0
  docElem = xmlDocGetRootElement(doc);
10585
0
  if (docElem == NULL) {
10586
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10587
0
    invokingNode, NULL,
10588
0
    "The document '%s' has no document element",
10589
0
    schemaLocation, NULL);
10590
0
      goto exit_error;
10591
0
  }
10592
  /*
10593
  * Remove all the blank text nodes.
10594
  */
10595
0
  xmlSchemaCleanupDoc(pctxt, docElem);
10596
  /*
10597
  * Check the schema's top level element.
10598
  */
10599
0
  if (!IS_SCHEMA(docElem, "schema")) {
10600
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10601
0
    invokingNode, NULL,
10602
0
    "The XML document '%s' is not a schema document",
10603
0
    schemaLocation, NULL);
10604
0
      goto exit_error;
10605
0
  }
10606
  /*
10607
  * Note that we don't apply a type check for the
10608
  * targetNamespace value here.
10609
  */
10610
0
  targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10611
0
      "targetNamespace");
10612
0
    }
10613
10614
/* after_doc_loading: */
10615
0
    if ((bkt == NULL) && located) {
10616
  /* Only create a bucket if the schema was located. */
10617
0
        bkt = xmlSchemaBucketCreate(pctxt, type,
10618
0
      targetNamespace);
10619
0
  if (bkt == NULL)
10620
0
      goto exit_failure;
10621
0
    }
10622
0
    if (bkt != NULL) {
10623
0
  bkt->schemaLocation = schemaLocation;
10624
0
  bkt->located = located;
10625
0
  if (doc != NULL) {
10626
0
      bkt->doc = doc;
10627
0
      bkt->targetNamespace = targetNamespace;
10628
0
      bkt->origTargetNamespace = targetNamespace;
10629
0
      if (preserveDoc)
10630
0
    bkt->preserveDoc = 1;
10631
0
  }
10632
0
  if (WXS_IS_BUCKET_IMPMAIN(type))
10633
0
      bkt->imported++;
10634
      /*
10635
      * Add it to the graph of schemas.
10636
      */
10637
0
  if (relation != NULL)
10638
0
      relation->bucket = bkt;
10639
0
    }
10640
10641
0
exit:
10642
    /*
10643
    * Return the bucket explicitly; this is needed for the
10644
    * main schema.
10645
    */
10646
0
    if (bucket != NULL)
10647
0
  *bucket = bkt;
10648
0
    return (0);
10649
10650
0
exit_error:
10651
0
    if ((doc != NULL) && (! preserveDoc)) {
10652
0
  xmlFreeDoc(doc);
10653
0
  if (bkt != NULL)
10654
0
      bkt->doc = NULL;
10655
0
    }
10656
0
    return(pctxt->err);
10657
10658
0
exit_failure:
10659
0
    if ((doc != NULL) && (! preserveDoc)) {
10660
0
  xmlFreeDoc(doc);
10661
0
  if (bkt != NULL)
10662
0
      bkt->doc = NULL;
10663
0
    }
10664
0
    return (-1);
10665
0
}
10666
10667
/**
10668
 * xmlSchemaParseImport:
10669
 * @ctxt:  a schema validation context
10670
 * @schema:  the schema being built
10671
 * @node:  a subtree containing XML Schema information
10672
 *
10673
 * parse a XML schema Import definition
10674
 * *WARNING* this interface is highly subject to change
10675
 *
10676
 * Returns 0 in case of success, a positive error code if
10677
 * not valid and -1 in case of an internal error.
10678
 */
10679
static int
10680
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10681
                     xmlNodePtr node)
10682
0
{
10683
0
    xmlNodePtr child;
10684
0
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10685
0
    const xmlChar *thisTargetNamespace;
10686
0
    xmlAttrPtr attr;
10687
0
    int ret = 0;
10688
0
    xmlSchemaBucketPtr bucket = NULL;
10689
10690
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10691
0
        return (-1);
10692
10693
    /*
10694
    * Check for illegal attributes.
10695
    */
10696
0
    attr = node->properties;
10697
0
    while (attr != NULL) {
10698
0
  if (attr->ns == NULL) {
10699
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10700
0
    (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10701
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10702
0
    xmlSchemaPIllegalAttrErr(pctxt,
10703
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10704
0
      }
10705
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10706
0
      xmlSchemaPIllegalAttrErr(pctxt,
10707
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10708
0
  }
10709
0
  attr = attr->next;
10710
0
    }
10711
    /*
10712
    * Extract and validate attributes.
10713
    */
10714
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10715
0
  "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10716
0
  &namespaceName) != 0) {
10717
0
  xmlSchemaPSimpleTypeErr(pctxt,
10718
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10719
0
      NULL, node,
10720
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10721
0
      NULL, namespaceName, NULL, NULL, NULL);
10722
0
  return (pctxt->err);
10723
0
    }
10724
10725
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10726
0
  "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10727
0
  &schemaLocation) != 0) {
10728
0
  xmlSchemaPSimpleTypeErr(pctxt,
10729
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10730
0
      NULL, node,
10731
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10732
0
      NULL, schemaLocation, NULL, NULL, NULL);
10733
0
  return (pctxt->err);
10734
0
    }
10735
    /*
10736
    * And now for the children...
10737
    */
10738
0
    child = node->children;
10739
0
    if (IS_SCHEMA(child, "annotation")) {
10740
        /*
10741
         * the annotation here is simply discarded ...
10742
   * TODO: really?
10743
         */
10744
0
        child = child->next;
10745
0
    }
10746
0
    if (child != NULL) {
10747
0
  xmlSchemaPContentErr(pctxt,
10748
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10749
0
      NULL, node, child, NULL,
10750
0
      "(annotation?)");
10751
0
    }
10752
    /*
10753
    * Apply additional constraints.
10754
    *
10755
    * Note that it is important to use the original @targetNamespace
10756
    * (or none at all), to rule out imports of schemas _with_ a
10757
    * @targetNamespace if the importing schema is a chameleon schema
10758
    * (with no @targetNamespace).
10759
    */
10760
0
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10761
0
    if (namespaceName != NULL) {
10762
  /*
10763
  * 1.1 If the namespace [attribute] is present, then its `actual value`
10764
  * must not match the `actual value` of the enclosing <schema>'s
10765
  * targetNamespace [attribute].
10766
  */
10767
0
  if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10768
0
      xmlSchemaPCustomErr(pctxt,
10769
0
    XML_SCHEMAP_SRC_IMPORT_1_1,
10770
0
    NULL, node,
10771
0
    "The value of the attribute 'namespace' must not match "
10772
0
    "the target namespace '%s' of the importing schema",
10773
0
    thisTargetNamespace);
10774
0
      return (pctxt->err);
10775
0
  }
10776
0
    } else {
10777
  /*
10778
  * 1.2 If the namespace [attribute] is not present, then the enclosing
10779
  * <schema> must have a targetNamespace [attribute].
10780
  */
10781
0
  if (thisTargetNamespace == NULL) {
10782
0
      xmlSchemaPCustomErr(pctxt,
10783
0
    XML_SCHEMAP_SRC_IMPORT_1_2,
10784
0
    NULL, node,
10785
0
    "The attribute 'namespace' must be existent if "
10786
0
    "the importing schema has no target namespace",
10787
0
    NULL);
10788
0
      return (pctxt->err);
10789
0
  }
10790
0
    }
10791
    /*
10792
    * Locate and acquire the schema document.
10793
    */
10794
0
    if (schemaLocation != NULL)
10795
0
  schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10796
0
      schemaLocation, node);
10797
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10798
0
  schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10799
0
  namespaceName, &bucket);
10800
10801
0
    if (ret != 0)
10802
0
  return(ret);
10803
10804
    /*
10805
    * For <import>: "It is *not* an error for the application
10806
    * schema reference strategy to fail."
10807
    * So just don't parse if no schema document was found.
10808
    * Note that we will get no bucket if the schema could not be
10809
    * located or if there was no schemaLocation.
10810
    */
10811
0
    if ((bucket == NULL) && (schemaLocation != NULL)) {
10812
0
  xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10813
0
      XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10814
0
      node, NULL,
10815
0
      "Failed to locate a schema at location '%s'. "
10816
0
      "Skipping the import", schemaLocation, NULL, NULL);
10817
0
    }
10818
10819
0
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10820
0
  ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10821
0
    }
10822
10823
0
    return (ret);
10824
0
}
10825
10826
static int
10827
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10828
             xmlSchemaPtr schema,
10829
             xmlNodePtr node,
10830
             xmlChar **schemaLocation,
10831
             int type)
10832
0
{
10833
0
    xmlAttrPtr attr;
10834
10835
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10836
0
  (schemaLocation == NULL))
10837
0
        return (-1);
10838
10839
0
    *schemaLocation = NULL;
10840
    /*
10841
    * Check for illegal attributes.
10842
    * Applies for both <include> and <redefine>.
10843
    */
10844
0
    attr = node->properties;
10845
0
    while (attr != NULL) {
10846
0
  if (attr->ns == NULL) {
10847
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10848
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10849
0
    xmlSchemaPIllegalAttrErr(pctxt,
10850
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10851
0
      }
10852
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10853
0
      xmlSchemaPIllegalAttrErr(pctxt,
10854
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10855
0
  }
10856
0
  attr = attr->next;
10857
0
    }
10858
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10859
    /*
10860
    * Preliminary step, extract the URI-Reference and make an URI
10861
    * from the base.
10862
    */
10863
    /*
10864
    * Attribute "schemaLocation" is mandatory.
10865
    */
10866
0
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
10867
0
    if (attr != NULL) {
10868
0
        xmlChar *base = NULL;
10869
0
        xmlChar *uri = NULL;
10870
10871
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10872
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10873
0
      (const xmlChar **) schemaLocation) != 0)
10874
0
      goto exit_error;
10875
0
  base = xmlNodeGetBase(node->doc, node);
10876
0
  if (base == NULL) {
10877
0
      uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10878
0
  } else {
10879
0
      uri = xmlBuildURI(*schemaLocation, base);
10880
0
      xmlFree(base);
10881
0
  }
10882
0
  if (uri == NULL) {
10883
0
      PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10884
0
    "could not build an URI from the schemaLocation")
10885
0
      goto exit_failure;
10886
0
  }
10887
0
  (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10888
0
  xmlFree(uri);
10889
0
    } else {
10890
0
  xmlSchemaPMissingAttrErr(pctxt,
10891
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
10892
0
      NULL, node, "schemaLocation", NULL);
10893
0
  goto exit_error;
10894
0
    }
10895
    /*
10896
    * Report self-inclusion and self-redefinition.
10897
    */
10898
0
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10899
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10900
0
      xmlSchemaPCustomErr(pctxt,
10901
0
    XML_SCHEMAP_SRC_REDEFINE,
10902
0
    NULL, node,
10903
0
    "The schema document '%s' cannot redefine itself.",
10904
0
    *schemaLocation);
10905
0
  } else {
10906
0
      xmlSchemaPCustomErr(pctxt,
10907
0
    XML_SCHEMAP_SRC_INCLUDE,
10908
0
    NULL, node,
10909
0
    "The schema document '%s' cannot include itself.",
10910
0
    *schemaLocation);
10911
0
  }
10912
0
  goto exit_error;
10913
0
    }
10914
10915
0
    return(0);
10916
0
exit_error:
10917
0
    return(pctxt->err);
10918
0
exit_failure:
10919
0
    return(-1);
10920
0
}
10921
10922
static int
10923
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10924
        xmlSchemaPtr schema,
10925
        xmlNodePtr node,
10926
        int type)
10927
0
{
10928
0
    xmlNodePtr child = NULL;
10929
0
    const xmlChar *schemaLocation = NULL;
10930
0
    int res = 0; /* hasRedefinitions = 0 */
10931
0
    int isChameleon = 0, wasChameleon = 0;
10932
0
    xmlSchemaBucketPtr bucket = NULL;
10933
10934
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10935
0
        return (-1);
10936
10937
    /*
10938
    * Parse attributes. Note that the returned schemaLocation will
10939
    * be already converted to an absolute URI.
10940
    */
10941
0
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10942
0
  node, (xmlChar **) (&schemaLocation), type);
10943
0
    if (res != 0)
10944
0
  return(res);
10945
    /*
10946
    * Load and add the schema document.
10947
    */
10948
0
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10949
0
  NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10950
0
    if (res != 0)
10951
0
  return(res);
10952
    /*
10953
    * If we get no schema bucket back, then this means that the schema
10954
    * document could not be located or was broken XML or was not
10955
    * a schema document.
10956
    */
10957
0
    if ((bucket == NULL) || (bucket->doc == NULL)) {
10958
0
  if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10959
      /*
10960
      * WARNING for <include>:
10961
      * We will raise an error if the schema cannot be located
10962
      * for inclusions, since the that was the feedback from the
10963
      * schema people. I.e. the following spec piece will *not* be
10964
      * satisfied:
10965
      * SPEC src-include: "It is not an error for the `actual value` of the
10966
      * schemaLocation [attribute] to fail to resolve it all, in which
10967
      * case no corresponding inclusion is performed.
10968
      * So do we need a warning report here?"
10969
      */
10970
0
      res = XML_SCHEMAP_SRC_INCLUDE;
10971
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10972
0
    node, NULL,
10973
0
    "Failed to load the document '%s' for inclusion",
10974
0
    schemaLocation, NULL);
10975
0
  } else {
10976
      /*
10977
      * NOTE: This was changed to raise an error even if no redefinitions
10978
      * are specified.
10979
      *
10980
      * SPEC src-redefine (1)
10981
      * "If there are any element information items among the [children]
10982
      * other than <annotation> then the `actual value` of the
10983
      * schemaLocation [attribute] must successfully resolve."
10984
      * TODO: Ask the WG if a the location has always to resolve
10985
      * here as well!
10986
      */
10987
0
      res = XML_SCHEMAP_SRC_REDEFINE;
10988
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10989
0
    node, NULL,
10990
0
    "Failed to load the document '%s' for redefinition",
10991
0
    schemaLocation, NULL);
10992
0
  }
10993
0
    } else {
10994
  /*
10995
  * Check targetNamespace sanity before parsing the new schema.
10996
  * TODO: Note that we won't check further content if the
10997
  * targetNamespace was bad.
10998
  */
10999
0
  if (bucket->origTargetNamespace != NULL) {
11000
      /*
11001
      * SPEC src-include (2.1)
11002
      * "SII has a targetNamespace [attribute], and its `actual
11003
      * value` is identical to the `actual value` of the targetNamespace
11004
      * [attribute] of SII' (which must have such an [attribute])."
11005
      */
11006
0
      if (pctxt->targetNamespace == NULL) {
11007
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
11008
0
        XML_SCHEMAP_SRC_INCLUDE,
11009
0
        node, NULL,
11010
0
        "The target namespace of the included/redefined schema "
11011
0
        "'%s' has to be absent, since the including/redefining "
11012
0
        "schema has no target namespace",
11013
0
        schemaLocation, NULL);
11014
0
    goto exit_error;
11015
0
      } else if (!xmlStrEqual(bucket->origTargetNamespace,
11016
0
    pctxt->targetNamespace)) {
11017
    /* TODO: Change error function. */
11018
0
    xmlSchemaPCustomErrExt(pctxt,
11019
0
        XML_SCHEMAP_SRC_INCLUDE,
11020
0
        NULL, node,
11021
0
        "The target namespace '%s' of the included/redefined "
11022
0
        "schema '%s' differs from '%s' of the "
11023
0
        "including/redefining schema",
11024
0
        bucket->origTargetNamespace, schemaLocation,
11025
0
        pctxt->targetNamespace);
11026
0
    goto exit_error;
11027
0
      }
11028
0
  } else if (pctxt->targetNamespace != NULL) {
11029
      /*
11030
      * Chameleons: the original target namespace will
11031
      * differ from the resulting namespace.
11032
      */
11033
0
      isChameleon = 1;
11034
0
      bucket->targetNamespace = pctxt->targetNamespace;
11035
0
  }
11036
0
    }
11037
    /*
11038
    * Parse the schema.
11039
    */
11040
0
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11041
0
  if (isChameleon) {
11042
      /* TODO: Get rid of this flag on the schema itself. */
11043
0
      if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11044
0
    schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11045
0
      } else
11046
0
    wasChameleon = 1;
11047
0
  }
11048
0
  xmlSchemaParseNewDoc(pctxt, schema, bucket);
11049
  /* Restore chameleon flag. */
11050
0
  if (isChameleon && (!wasChameleon))
11051
0
      schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11052
0
    }
11053
    /*
11054
    * And now for the children...
11055
    */
11056
0
    child = node->children;
11057
0
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11058
  /*
11059
  * Parse (simpleType | complexType | group | attributeGroup))*
11060
  */
11061
0
  pctxt->redefined = bucket;
11062
  /*
11063
  * How to proceed if the redefined schema was not located?
11064
  */
11065
0
  pctxt->isRedefine = 1;
11066
0
  while (IS_SCHEMA(child, "annotation") ||
11067
0
      IS_SCHEMA(child, "simpleType") ||
11068
0
      IS_SCHEMA(child, "complexType") ||
11069
0
      IS_SCHEMA(child, "group") ||
11070
0
      IS_SCHEMA(child, "attributeGroup")) {
11071
0
      if (IS_SCHEMA(child, "annotation")) {
11072
    /*
11073
    * TODO: discard or not?
11074
    */
11075
0
      } else if (IS_SCHEMA(child, "simpleType")) {
11076
0
    xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11077
0
      } else if (IS_SCHEMA(child, "complexType")) {
11078
0
    xmlSchemaParseComplexType(pctxt, schema, child, 1);
11079
    /* hasRedefinitions = 1; */
11080
0
      } else if (IS_SCHEMA(child, "group")) {
11081
    /* hasRedefinitions = 1; */
11082
0
    xmlSchemaParseModelGroupDefinition(pctxt,
11083
0
        schema, child);
11084
0
      } else if (IS_SCHEMA(child, "attributeGroup")) {
11085
    /* hasRedefinitions = 1; */
11086
0
    xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11087
0
        child);
11088
0
      }
11089
0
      child = child->next;
11090
0
  }
11091
0
  pctxt->redefined = NULL;
11092
0
  pctxt->isRedefine = 0;
11093
0
    } else {
11094
0
  if (IS_SCHEMA(child, "annotation")) {
11095
      /*
11096
      * TODO: discard or not?
11097
      */
11098
0
      child = child->next;
11099
0
  }
11100
0
    }
11101
0
    if (child != NULL) {
11102
0
  res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11103
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11104
0
      xmlSchemaPContentErr(pctxt, res,
11105
0
    NULL, node, child, NULL,
11106
0
    "(annotation | (simpleType | complexType | group | attributeGroup))*");
11107
0
  } else {
11108
0
       xmlSchemaPContentErr(pctxt, res,
11109
0
    NULL, node, child, NULL,
11110
0
    "(annotation?)");
11111
0
  }
11112
0
    }
11113
0
    return(res);
11114
11115
0
exit_error:
11116
0
    return(pctxt->err);
11117
0
}
11118
11119
static int
11120
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11121
                       xmlNodePtr node)
11122
0
{
11123
0
    int res;
11124
#ifndef ENABLE_REDEFINE
11125
    TODO
11126
    return(0);
11127
#endif
11128
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11129
0
  XML_SCHEMA_SCHEMA_REDEFINE);
11130
0
    if (res != 0)
11131
0
  return(res);
11132
0
    return(0);
11133
0
}
11134
11135
static int
11136
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11137
                       xmlNodePtr node)
11138
0
{
11139
0
    int res;
11140
11141
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11142
0
  XML_SCHEMA_SCHEMA_INCLUDE);
11143
0
    if (res != 0)
11144
0
  return(res);
11145
0
    return(0);
11146
0
}
11147
11148
/**
11149
 * xmlSchemaParseModelGroup:
11150
 * @ctxt:  a schema validation context
11151
 * @schema:  the schema being built
11152
 * @node:  a subtree containing XML Schema information
11153
 * @type: the "compositor" type
11154
 * @particleNeeded: if a a model group with a particle
11155
 *
11156
 * parse a XML schema Sequence definition.
11157
 * Applies parts of:
11158
 *   Schema Representation Constraint:
11159
 *     Redefinition Constraints and Semantics (src-redefine)
11160
 *     (6.1), (6.1.1), (6.1.2)
11161
 *
11162
 *   Schema Component Constraint:
11163
 *     All Group Limited (cos-all-limited) (2)
11164
 *     TODO: Actually this should go to component-level checks,
11165
 *     but is done here due to performance. Move it to an other layer
11166
 *     is schema construction via an API is implemented.
11167
 *
11168
 * *WARNING* this interface is highly subject to change
11169
 *
11170
 * Returns -1 in case of error, 0 if the declaration is improper and
11171
 *         1 in case of success.
11172
 */
11173
static xmlSchemaTreeItemPtr
11174
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11175
       xmlNodePtr node, xmlSchemaTypeType type,
11176
       int withParticle)
11177
0
{
11178
0
    xmlSchemaModelGroupPtr item;
11179
0
    xmlSchemaParticlePtr particle = NULL;
11180
0
    xmlNodePtr child = NULL;
11181
0
    xmlAttrPtr attr;
11182
0
    int min = 1, max = 1, isElemRef, hasRefs = 0;
11183
11184
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11185
0
        return (NULL);
11186
    /*
11187
    * Create a model group with the given compositor.
11188
    */
11189
0
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11190
0
    if (item == NULL)
11191
0
  return (NULL);
11192
11193
0
    if (withParticle) {
11194
0
  if (type == XML_SCHEMA_TYPE_ALL) {
11195
0
      min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11196
0
      max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11197
0
  } else {
11198
      /* choice + sequence */
11199
0
      min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11200
0
      max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11201
0
    "(xs:nonNegativeInteger | unbounded)");
11202
0
  }
11203
0
  xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11204
  /*
11205
  * Create a particle
11206
  */
11207
0
  particle = xmlSchemaAddParticle(ctxt, node, min, max);
11208
0
  if (particle == NULL)
11209
0
      return (NULL);
11210
0
  particle->children = (xmlSchemaTreeItemPtr) item;
11211
  /*
11212
  * Check for illegal attributes.
11213
  */
11214
0
  attr = node->properties;
11215
0
  while (attr != NULL) {
11216
0
      if (attr->ns == NULL) {
11217
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11218
0
        (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11219
0
        (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11220
0
        xmlSchemaPIllegalAttrErr(ctxt,
11221
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11222
0
    }
11223
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11224
0
    xmlSchemaPIllegalAttrErr(ctxt,
11225
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11226
0
      }
11227
0
      attr = attr->next;
11228
0
  }
11229
0
    } else {
11230
  /*
11231
  * Check for illegal attributes.
11232
  */
11233
0
  attr = node->properties;
11234
0
  while (attr != NULL) {
11235
0
      if (attr->ns == NULL) {
11236
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11237
0
        xmlSchemaPIllegalAttrErr(ctxt,
11238
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11239
0
    }
11240
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11241
0
    xmlSchemaPIllegalAttrErr(ctxt,
11242
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11243
0
      }
11244
0
      attr = attr->next;
11245
0
  }
11246
0
    }
11247
11248
    /*
11249
    * Extract and validate attributes.
11250
    */
11251
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11252
    /*
11253
    * And now for the children...
11254
    */
11255
0
    child = node->children;
11256
0
    if (IS_SCHEMA(child, "annotation")) {
11257
0
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11258
0
        child = child->next;
11259
0
    }
11260
0
    if (type == XML_SCHEMA_TYPE_ALL) {
11261
0
  xmlSchemaParticlePtr part, last = NULL;
11262
11263
0
  while (IS_SCHEMA(child, "element")) {
11264
0
      part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11265
0
    schema, child, &isElemRef, 0);
11266
      /*
11267
      * SPEC cos-all-limited (2)
11268
      * "The {max occurs} of all the particles in the {particles}
11269
      * of the ('all') group must be 0 or 1.
11270
      */
11271
0
      if (part != NULL) {
11272
0
    if (isElemRef)
11273
0
        hasRefs++;
11274
0
    if (part->minOccurs > 1) {
11275
0
        xmlSchemaPCustomErr(ctxt,
11276
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11277
0
      NULL, child,
11278
0
      "Invalid value for minOccurs (must be 0 or 1)",
11279
0
      NULL);
11280
        /* Reset to 1. */
11281
0
        part->minOccurs = 1;
11282
0
    }
11283
0
    if (part->maxOccurs > 1) {
11284
0
        xmlSchemaPCustomErr(ctxt,
11285
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11286
0
      NULL, child,
11287
0
      "Invalid value for maxOccurs (must be 0 or 1)",
11288
0
      NULL);
11289
        /* Reset to 1. */
11290
0
        part->maxOccurs = 1;
11291
0
    }
11292
0
    if (last == NULL)
11293
0
        item->children = (xmlSchemaTreeItemPtr) part;
11294
0
    else
11295
0
        last->next = (xmlSchemaTreeItemPtr) part;
11296
0
    last = part;
11297
0
      }
11298
0
      child = child->next;
11299
0
  }
11300
0
  if (child != NULL) {
11301
0
      xmlSchemaPContentErr(ctxt,
11302
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11303
0
    NULL, node, child, NULL,
11304
0
    "(annotation?, (annotation?, element*)");
11305
0
  }
11306
0
    } else {
11307
  /* choice + sequence */
11308
0
  xmlSchemaTreeItemPtr part = NULL, last = NULL;
11309
11310
0
  while ((IS_SCHEMA(child, "element")) ||
11311
0
      (IS_SCHEMA(child, "group")) ||
11312
0
      (IS_SCHEMA(child, "any")) ||
11313
0
      (IS_SCHEMA(child, "choice")) ||
11314
0
      (IS_SCHEMA(child, "sequence"))) {
11315
11316
0
      if (IS_SCHEMA(child, "element")) {
11317
0
    part = (xmlSchemaTreeItemPtr)
11318
0
        xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11319
0
    if (part && isElemRef)
11320
0
        hasRefs++;
11321
0
      } else if (IS_SCHEMA(child, "group")) {
11322
0
    part =
11323
0
        xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11324
0
    if (part != NULL)
11325
0
        hasRefs++;
11326
    /*
11327
    * Handle redefinitions.
11328
    */
11329
0
    if (ctxt->isRedefine && ctxt->redef &&
11330
0
        (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11331
0
        part && part->children)
11332
0
    {
11333
0
        if ((xmlSchemaGetQNameRefName(part->children) ==
11334
0
          ctxt->redef->refName) &&
11335
0
      (xmlSchemaGetQNameRefTargetNs(part->children) ==
11336
0
          ctxt->redef->refTargetNs))
11337
0
        {
11338
      /*
11339
      * SPEC src-redefine:
11340
      * (6.1) "If it has a <group> among its contents at
11341
      * some level the `actual value` of whose ref
11342
      * [attribute] is the same as the `actual value` of
11343
      * its own name attribute plus target namespace, then
11344
      * all of the following must be true:"
11345
      * (6.1.1) "It must have exactly one such group."
11346
      */
11347
0
      if (ctxt->redefCounter != 0) {
11348
0
          xmlChar *str = NULL;
11349
11350
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11351
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11352
0
        "The redefining model group definition "
11353
0
        "'%s' must not contain more than one "
11354
0
        "reference to the redefined definition",
11355
0
        xmlSchemaFormatQName(&str,
11356
0
            ctxt->redef->refTargetNs,
11357
0
            ctxt->redef->refName),
11358
0
        NULL);
11359
0
          FREE_AND_NULL(str)
11360
0
          part = NULL;
11361
0
      } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11362
0
          ((WXS_PARTICLE(part))->maxOccurs != 1))
11363
0
      {
11364
0
          xmlChar *str = NULL;
11365
          /*
11366
          * SPEC src-redefine:
11367
          * (6.1.2) "The `actual value` of both that
11368
          * group's minOccurs and maxOccurs [attribute]
11369
          * must be 1 (or `absent`).
11370
          */
11371
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11372
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11373
0
        "The redefining model group definition "
11374
0
        "'%s' must not contain a reference to the "
11375
0
        "redefined definition with a "
11376
0
        "maxOccurs/minOccurs other than 1",
11377
0
        xmlSchemaFormatQName(&str,
11378
0
            ctxt->redef->refTargetNs,
11379
0
            ctxt->redef->refName),
11380
0
        NULL);
11381
0
          FREE_AND_NULL(str)
11382
0
          part = NULL;
11383
0
      }
11384
0
      ctxt->redef->reference = WXS_BASIC_CAST part;
11385
0
      ctxt->redefCounter++;
11386
0
        }
11387
0
    }
11388
0
      } else if (IS_SCHEMA(child, "any")) {
11389
0
    part = (xmlSchemaTreeItemPtr)
11390
0
        xmlSchemaParseAny(ctxt, schema, child);
11391
0
      } else if (IS_SCHEMA(child, "choice")) {
11392
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11393
0
        XML_SCHEMA_TYPE_CHOICE, 1);
11394
0
      } else if (IS_SCHEMA(child, "sequence")) {
11395
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11396
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11397
0
      }
11398
0
      if (part != NULL) {
11399
0
    if (last == NULL)
11400
0
        item->children = part;
11401
0
    else
11402
0
        last->next = part;
11403
0
    last = part;
11404
0
      }
11405
0
      child = child->next;
11406
0
  }
11407
0
  if (child != NULL) {
11408
0
      xmlSchemaPContentErr(ctxt,
11409
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11410
0
    NULL, node, child, NULL,
11411
0
    "(annotation?, (element | group | choice | sequence | any)*)");
11412
0
  }
11413
0
    }
11414
0
    if ((max == 0) && (min == 0))
11415
0
  return (NULL);
11416
0
    if (hasRefs) {
11417
  /*
11418
  * We need to resolve references.
11419
  */
11420
0
  WXS_ADD_PENDING(ctxt, item);
11421
0
    }
11422
0
    if (withParticle)
11423
0
  return ((xmlSchemaTreeItemPtr) particle);
11424
0
    else
11425
0
  return ((xmlSchemaTreeItemPtr) item);
11426
0
}
11427
11428
/**
11429
 * xmlSchemaParseRestriction:
11430
 * @ctxt:  a schema validation context
11431
 * @schema:  the schema being built
11432
 * @node:  a subtree containing XML Schema information
11433
 *
11434
 * parse a XML schema Restriction definition
11435
 * *WARNING* this interface is highly subject to change
11436
 *
11437
 * Returns the type definition or NULL in case of error
11438
 */
11439
static xmlSchemaTypePtr
11440
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11441
                          xmlNodePtr node, xmlSchemaTypeType parentType)
11442
0
{
11443
0
    xmlSchemaTypePtr type;
11444
0
    xmlNodePtr child = NULL;
11445
0
    xmlAttrPtr attr;
11446
11447
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11448
0
        return (NULL);
11449
    /* Not a component, don't create it. */
11450
0
    type = ctxt->ctxtType;
11451
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11452
11453
    /*
11454
    * Check for illegal attributes.
11455
    */
11456
0
    attr = node->properties;
11457
0
    while (attr != NULL) {
11458
0
  if (attr->ns == NULL) {
11459
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11460
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11461
0
    xmlSchemaPIllegalAttrErr(ctxt,
11462
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11463
0
      }
11464
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11465
0
      xmlSchemaPIllegalAttrErr(ctxt,
11466
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11467
0
  }
11468
0
  attr = attr->next;
11469
0
    }
11470
    /*
11471
    * Extract and validate attributes.
11472
    */
11473
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11474
    /*
11475
    * Attribute
11476
    */
11477
    /*
11478
    * Extract the base type. The "base" attribute is mandatory if inside
11479
    * a complex type or if redefining.
11480
    *
11481
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11482
    * among its [children]), the simple type definition which is
11483
    * the {content type} of the type definition `resolved` to by
11484
    * the `actual value` of the base [attribute]"
11485
    */
11486
0
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11487
0
  &(type->baseNs), &(type->base)) == 0)
11488
0
    {
11489
0
  if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11490
0
      xmlSchemaPMissingAttrErr(ctxt,
11491
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
11492
0
    NULL, node, "base", NULL);
11493
0
  } else if ((ctxt->isRedefine) &&
11494
0
      (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11495
0
  {
11496
0
      if (type->base == NULL) {
11497
0
    xmlSchemaPMissingAttrErr(ctxt,
11498
0
        XML_SCHEMAP_S4S_ATTR_MISSING,
11499
0
        NULL, node, "base", NULL);
11500
0
      } else if ((! xmlStrEqual(type->base, type->name)) ||
11501
0
    (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11502
0
      {
11503
0
    xmlChar *str1 = NULL, *str2 = NULL;
11504
    /*
11505
    * REDEFINE: SPEC src-redefine (5)
11506
    * "Within the [children], each <simpleType> must have a
11507
    * <restriction> among its [children] ... the `actual value` of
11508
    * whose base [attribute] must be the same as the `actual value`
11509
    * of its own name attribute plus target namespace;"
11510
    */
11511
0
    xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11512
0
        NULL, node, "This is a redefinition, but the QName "
11513
0
        "value '%s' of the 'base' attribute does not match the "
11514
0
        "type's designation '%s'",
11515
0
        xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11516
0
        xmlSchemaFormatQName(&str2, type->targetNamespace,
11517
0
      type->name), NULL);
11518
0
    FREE_AND_NULL(str1);
11519
0
    FREE_AND_NULL(str2);
11520
    /* Avoid confusion and erase the values. */
11521
0
    type->base = NULL;
11522
0
    type->baseNs = NULL;
11523
0
      }
11524
0
  }
11525
0
    }
11526
    /*
11527
    * And now for the children...
11528
    */
11529
0
    child = node->children;
11530
0
    if (IS_SCHEMA(child, "annotation")) {
11531
  /*
11532
  * Add the annotation to the simple type ancestor.
11533
  */
11534
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11535
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11536
0
        child = child->next;
11537
0
    }
11538
0
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11539
  /*
11540
  * Corresponds to <simpleType><restriction><simpleType>.
11541
  */
11542
0
  if (IS_SCHEMA(child, "simpleType")) {
11543
0
      if (type->base != NULL) {
11544
    /*
11545
    * src-restriction-base-or-simpleType
11546
    * Either the base [attribute] or the simpleType [child] of the
11547
    * <restriction> element must be present, but not both.
11548
    */
11549
0
    xmlSchemaPContentErr(ctxt,
11550
0
        XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11551
0
        NULL, node, child,
11552
0
        "The attribute 'base' and the <simpleType> child are "
11553
0
        "mutually exclusive", NULL);
11554
0
      } else {
11555
0
    type->baseType = (xmlSchemaTypePtr)
11556
0
        xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11557
0
      }
11558
0
      child = child->next;
11559
0
  } else if (type->base == NULL) {
11560
0
      xmlSchemaPContentErr(ctxt,
11561
0
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11562
0
    NULL, node, child,
11563
0
    "Either the attribute 'base' or a <simpleType> child "
11564
0
    "must be present", NULL);
11565
0
  }
11566
0
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11567
  /*
11568
  * Corresponds to <complexType><complexContent><restriction>...
11569
  * followed by:
11570
  *
11571
  * Model groups <all>, <choice> and <sequence>.
11572
  */
11573
0
  if (IS_SCHEMA(child, "all")) {
11574
0
      type->subtypes = (xmlSchemaTypePtr)
11575
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11576
0
        XML_SCHEMA_TYPE_ALL, 1);
11577
0
      child = child->next;
11578
0
  } else if (IS_SCHEMA(child, "choice")) {
11579
0
      type->subtypes = (xmlSchemaTypePtr)
11580
0
    xmlSchemaParseModelGroup(ctxt,
11581
0
        schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11582
0
      child = child->next;
11583
0
  } else if (IS_SCHEMA(child, "sequence")) {
11584
0
      type->subtypes = (xmlSchemaTypePtr)
11585
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11586
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11587
0
      child = child->next;
11588
  /*
11589
  * Model group reference <group>.
11590
  */
11591
0
  } else if (IS_SCHEMA(child, "group")) {
11592
0
      type->subtypes = (xmlSchemaTypePtr)
11593
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11594
      /*
11595
      * Note that the reference will be resolved in
11596
      * xmlSchemaResolveTypeReferences();
11597
      */
11598
0
      child = child->next;
11599
0
  }
11600
0
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11601
  /*
11602
  * Corresponds to <complexType><simpleContent><restriction>...
11603
  *
11604
  * "1.1 the simple type definition corresponding to the <simpleType>
11605
  * among the [children] of <restriction> if there is one;"
11606
  */
11607
0
  if (IS_SCHEMA(child, "simpleType")) {
11608
      /*
11609
      * We will store the to-be-restricted simple type in
11610
      * type->contentTypeDef *temporarily*.
11611
      */
11612
0
      type->contentTypeDef = (xmlSchemaTypePtr)
11613
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11614
0
      if ( type->contentTypeDef == NULL)
11615
0
    return (NULL);
11616
0
      child = child->next;
11617
0
  }
11618
0
    }
11619
11620
0
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11621
0
  (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11622
0
  xmlSchemaFacetPtr facet, lastfacet = NULL;
11623
  /*
11624
  * Corresponds to <complexType><simpleContent><restriction>...
11625
  * <simpleType><restriction>...
11626
  */
11627
11628
  /*
11629
  * Add the facets to the simple type ancestor.
11630
  */
11631
  /*
11632
  * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11633
  * Simple Type Definition Schema Representation Constraint:
11634
  * *Single Facet Value*
11635
  */
11636
0
  while ((IS_SCHEMA(child, "minInclusive")) ||
11637
0
      (IS_SCHEMA(child, "minExclusive")) ||
11638
0
      (IS_SCHEMA(child, "maxInclusive")) ||
11639
0
      (IS_SCHEMA(child, "maxExclusive")) ||
11640
0
      (IS_SCHEMA(child, "totalDigits")) ||
11641
0
      (IS_SCHEMA(child, "fractionDigits")) ||
11642
0
      (IS_SCHEMA(child, "pattern")) ||
11643
0
      (IS_SCHEMA(child, "enumeration")) ||
11644
0
      (IS_SCHEMA(child, "whiteSpace")) ||
11645
0
      (IS_SCHEMA(child, "length")) ||
11646
0
      (IS_SCHEMA(child, "maxLength")) ||
11647
0
      (IS_SCHEMA(child, "minLength"))) {
11648
0
      facet = xmlSchemaParseFacet(ctxt, schema, child);
11649
0
      if (facet != NULL) {
11650
0
    if (lastfacet == NULL)
11651
0
        type->facets = facet;
11652
0
    else
11653
0
        lastfacet->next = facet;
11654
0
    lastfacet = facet;
11655
0
    lastfacet->next = NULL;
11656
0
      }
11657
0
      child = child->next;
11658
0
  }
11659
  /*
11660
  * Create links for derivation and validation.
11661
  */
11662
0
  if (type->facets != NULL) {
11663
0
      xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11664
11665
0
      facet = type->facets;
11666
0
      do {
11667
0
    facetLink = (xmlSchemaFacetLinkPtr)
11668
0
        xmlMalloc(sizeof(xmlSchemaFacetLink));
11669
0
    if (facetLink == NULL) {
11670
0
        xmlSchemaPErrMemory(ctxt);
11671
0
        xmlFree(facetLink);
11672
0
        return (NULL);
11673
0
    }
11674
0
    facetLink->facet = facet;
11675
0
    facetLink->next = NULL;
11676
0
    if (lastFacetLink == NULL)
11677
0
        type->facetSet = facetLink;
11678
0
    else
11679
0
        lastFacetLink->next = facetLink;
11680
0
    lastFacetLink = facetLink;
11681
0
    facet = facet->next;
11682
0
      } while (facet != NULL);
11683
0
  }
11684
0
    }
11685
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11686
  /*
11687
  * Attribute uses/declarations.
11688
  */
11689
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11690
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11691
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11692
0
      return(NULL);
11693
  /*
11694
  * Attribute wildcard.
11695
  */
11696
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11697
0
      type->attributeWildcard =
11698
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11699
0
      child = child->next;
11700
0
  }
11701
0
    }
11702
0
    if (child != NULL) {
11703
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11704
0
      xmlSchemaPContentErr(ctxt,
11705
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11706
0
    NULL, node, child, NULL,
11707
0
    "annotation?, (group | all | choice | sequence)?, "
11708
0
    "((attribute | attributeGroup)*, anyAttribute?))");
11709
0
  } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11710
0
       xmlSchemaPContentErr(ctxt,
11711
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11712
0
    NULL, node, child, NULL,
11713
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11714
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11715
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11716
0
    "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11717
0
  } else {
11718
      /* Simple type */
11719
0
      xmlSchemaPContentErr(ctxt,
11720
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11721
0
    NULL, node, child, NULL,
11722
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11723
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11724
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11725
0
    "pattern)*))");
11726
0
  }
11727
0
    }
11728
0
    return (NULL);
11729
0
}
11730
11731
/**
11732
 * xmlSchemaParseExtension:
11733
 * @ctxt:  a schema validation context
11734
 * @schema:  the schema being built
11735
 * @node:  a subtree containing XML Schema information
11736
 *
11737
 * Parses an <extension>, which is found inside a
11738
 * <simpleContent> or <complexContent>.
11739
 * *WARNING* this interface is highly subject to change.
11740
 *
11741
 * TODO: Returns the type definition or NULL in case of error
11742
 */
11743
static xmlSchemaTypePtr
11744
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11745
                        xmlNodePtr node, xmlSchemaTypeType parentType)
11746
0
{
11747
0
    xmlSchemaTypePtr type;
11748
0
    xmlNodePtr child = NULL;
11749
0
    xmlAttrPtr attr;
11750
11751
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11752
0
        return (NULL);
11753
    /* Not a component, don't create it. */
11754
0
    type = ctxt->ctxtType;
11755
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11756
11757
    /*
11758
    * Check for illegal attributes.
11759
    */
11760
0
    attr = node->properties;
11761
0
    while (attr != NULL) {
11762
0
  if (attr->ns == NULL) {
11763
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11764
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11765
0
    xmlSchemaPIllegalAttrErr(ctxt,
11766
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11767
0
      }
11768
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11769
0
      xmlSchemaPIllegalAttrErr(ctxt,
11770
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11771
0
  }
11772
0
  attr = attr->next;
11773
0
    }
11774
11775
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11776
11777
    /*
11778
    * Attribute "base" - mandatory.
11779
    */
11780
0
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11781
0
  "base", &(type->baseNs), &(type->base)) == 0) &&
11782
0
  (type->base == NULL)) {
11783
0
  xmlSchemaPMissingAttrErr(ctxt,
11784
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11785
0
      NULL, node, "base", NULL);
11786
0
    }
11787
    /*
11788
    * And now for the children...
11789
    */
11790
0
    child = node->children;
11791
0
    if (IS_SCHEMA(child, "annotation")) {
11792
  /*
11793
  * Add the annotation to the type ancestor.
11794
  */
11795
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11796
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11797
0
        child = child->next;
11798
0
    }
11799
0
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11800
  /*
11801
  * Corresponds to <complexType><complexContent><extension>... and:
11802
  *
11803
  * Model groups <all>, <choice>, <sequence> and <group>.
11804
  */
11805
0
  if (IS_SCHEMA(child, "all")) {
11806
0
      type->subtypes = (xmlSchemaTypePtr)
11807
0
    xmlSchemaParseModelGroup(ctxt, schema,
11808
0
        child, XML_SCHEMA_TYPE_ALL, 1);
11809
0
      child = child->next;
11810
0
  } else if (IS_SCHEMA(child, "choice")) {
11811
0
      type->subtypes = (xmlSchemaTypePtr)
11812
0
    xmlSchemaParseModelGroup(ctxt, schema,
11813
0
        child, XML_SCHEMA_TYPE_CHOICE, 1);
11814
0
      child = child->next;
11815
0
  } else if (IS_SCHEMA(child, "sequence")) {
11816
0
      type->subtypes = (xmlSchemaTypePtr)
11817
0
    xmlSchemaParseModelGroup(ctxt, schema,
11818
0
    child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11819
0
      child = child->next;
11820
0
  } else if (IS_SCHEMA(child, "group")) {
11821
0
      type->subtypes = (xmlSchemaTypePtr)
11822
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11823
      /*
11824
      * Note that the reference will be resolved in
11825
      * xmlSchemaResolveTypeReferences();
11826
      */
11827
0
      child = child->next;
11828
0
  }
11829
0
    }
11830
0
    if (child != NULL) {
11831
  /*
11832
  * Attribute uses/declarations.
11833
  */
11834
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11835
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11836
0
      XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11837
0
      return(NULL);
11838
  /*
11839
  * Attribute wildcard.
11840
  */
11841
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11842
0
      ctxt->ctxtType->attributeWildcard =
11843
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11844
0
      child = child->next;
11845
0
  }
11846
0
    }
11847
0
    if (child != NULL) {
11848
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11849
      /* Complex content extension. */
11850
0
      xmlSchemaPContentErr(ctxt,
11851
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11852
0
    NULL, node, child, NULL,
11853
0
    "(annotation?, ((group | all | choice | sequence)?, "
11854
0
    "((attribute | attributeGroup)*, anyAttribute?)))");
11855
0
  } else {
11856
      /* Simple content extension. */
11857
0
      xmlSchemaPContentErr(ctxt,
11858
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11859
0
    NULL, node, child, NULL,
11860
0
    "(annotation?, ((attribute | attributeGroup)*, "
11861
0
    "anyAttribute?))");
11862
0
  }
11863
0
    }
11864
0
    return (NULL);
11865
0
}
11866
11867
/**
11868
 * xmlSchemaParseSimpleContent:
11869
 * @ctxt:  a schema validation context
11870
 * @schema:  the schema being built
11871
 * @node:  a subtree containing XML Schema information
11872
 *
11873
 * parse a XML schema SimpleContent definition
11874
 * *WARNING* this interface is highly subject to change
11875
 *
11876
 * Returns the type definition or NULL in case of error
11877
 */
11878
static int
11879
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11880
                            xmlSchemaPtr schema, xmlNodePtr node,
11881
          int *hasRestrictionOrExtension)
11882
0
{
11883
0
    xmlSchemaTypePtr type;
11884
0
    xmlNodePtr child = NULL;
11885
0
    xmlAttrPtr attr;
11886
11887
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11888
0
  (hasRestrictionOrExtension == NULL))
11889
0
        return (-1);
11890
0
    *hasRestrictionOrExtension = 0;
11891
    /* Not a component, don't create it. */
11892
0
    type = ctxt->ctxtType;
11893
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11894
    /*
11895
    * Check for illegal attributes.
11896
    */
11897
0
    attr = node->properties;
11898
0
    while (attr != NULL) {
11899
0
  if (attr->ns == NULL) {
11900
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11901
0
    xmlSchemaPIllegalAttrErr(ctxt,
11902
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11903
0
      }
11904
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11905
0
      xmlSchemaPIllegalAttrErr(ctxt,
11906
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11907
0
  }
11908
0
  attr = attr->next;
11909
0
    }
11910
11911
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11912
11913
    /*
11914
    * And now for the children...
11915
    */
11916
0
    child = node->children;
11917
0
    if (IS_SCHEMA(child, "annotation")) {
11918
  /*
11919
  * Add the annotation to the complex type ancestor.
11920
  */
11921
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11922
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11923
0
        child = child->next;
11924
0
    }
11925
0
    if (child == NULL) {
11926
0
  xmlSchemaPContentErr(ctxt,
11927
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11928
0
      NULL, node, NULL, NULL,
11929
0
      "(annotation?, (restriction | extension))");
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 (IS_SCHEMA(child, "restriction")) {
11938
0
        xmlSchemaParseRestriction(ctxt, schema, child,
11939
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11940
0
  (*hasRestrictionOrExtension) = 1;
11941
0
        child = child->next;
11942
0
    } else if (IS_SCHEMA(child, "extension")) {
11943
0
        xmlSchemaParseExtension(ctxt, schema, child,
11944
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11945
0
  (*hasRestrictionOrExtension) = 1;
11946
0
        child = child->next;
11947
0
    }
11948
0
    if (child != NULL) {
11949
0
  xmlSchemaPContentErr(ctxt,
11950
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11951
0
      NULL, node, child, NULL,
11952
0
      "(annotation?, (restriction | extension))");
11953
0
    }
11954
0
    return (0);
11955
0
}
11956
11957
/**
11958
 * xmlSchemaParseComplexContent:
11959
 * @ctxt:  a schema validation context
11960
 * @schema:  the schema being built
11961
 * @node:  a subtree containing XML Schema information
11962
 *
11963
 * parse a XML schema ComplexContent definition
11964
 * *WARNING* this interface is highly subject to change
11965
 *
11966
 * Returns the type definition or NULL in case of error
11967
 */
11968
static int
11969
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11970
                             xmlSchemaPtr schema, xmlNodePtr node,
11971
           int *hasRestrictionOrExtension)
11972
0
{
11973
0
    xmlSchemaTypePtr type;
11974
0
    xmlNodePtr child = NULL;
11975
0
    xmlAttrPtr attr;
11976
11977
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11978
0
  (hasRestrictionOrExtension == NULL))
11979
0
        return (-1);
11980
0
    *hasRestrictionOrExtension = 0;
11981
    /* Not a component, don't create it. */
11982
0
    type = ctxt->ctxtType;
11983
    /*
11984
    * Check for illegal attributes.
11985
    */
11986
0
    attr = node->properties;
11987
0
    while (attr != NULL) {
11988
0
  if (attr->ns == NULL) {
11989
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11990
0
    (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
11991
0
      {
11992
0
    xmlSchemaPIllegalAttrErr(ctxt,
11993
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11994
0
      }
11995
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11996
0
      xmlSchemaPIllegalAttrErr(ctxt,
11997
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11998
0
  }
11999
0
  attr = attr->next;
12000
0
    }
12001
12002
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12003
12004
    /*
12005
    * Set the 'mixed' on the complex type ancestor.
12006
    */
12007
0
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12008
0
  if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12009
0
      type->flags |= XML_SCHEMAS_TYPE_MIXED;
12010
0
    }
12011
0
    child = node->children;
12012
0
    if (IS_SCHEMA(child, "annotation")) {
12013
  /*
12014
  * Add the annotation to the complex type ancestor.
12015
  */
12016
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12017
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
12018
0
        child = child->next;
12019
0
    }
12020
0
    if (child == NULL) {
12021
0
  xmlSchemaPContentErr(ctxt,
12022
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12023
0
      NULL, node, NULL,
12024
0
      NULL, "(annotation?, (restriction | extension))");
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 (IS_SCHEMA(child, "restriction")) {
12033
0
        xmlSchemaParseRestriction(ctxt, schema, child,
12034
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12035
0
  (*hasRestrictionOrExtension) = 1;
12036
0
        child = child->next;
12037
0
    } else if (IS_SCHEMA(child, "extension")) {
12038
0
        xmlSchemaParseExtension(ctxt, schema, child,
12039
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12040
0
  (*hasRestrictionOrExtension) = 1;
12041
0
        child = child->next;
12042
0
    }
12043
0
    if (child != NULL) {
12044
0
  xmlSchemaPContentErr(ctxt,
12045
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12046
0
      NULL, node, child,
12047
0
      NULL, "(annotation?, (restriction | extension))");
12048
0
    }
12049
0
    return (0);
12050
0
}
12051
12052
/**
12053
 * xmlSchemaParseComplexType:
12054
 * @ctxt:  a schema validation context
12055
 * @schema:  the schema being built
12056
 * @node:  a subtree containing XML Schema information
12057
 *
12058
 * parse a XML schema Complex Type definition
12059
 * *WARNING* this interface is highly subject to change
12060
 *
12061
 * Returns the type definition or NULL in case of error
12062
 */
12063
static xmlSchemaTypePtr
12064
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12065
                          xmlNodePtr node, int topLevel)
12066
0
{
12067
0
    xmlSchemaTypePtr type, ctxtType;
12068
0
    xmlNodePtr child = NULL;
12069
0
    const xmlChar *name = NULL;
12070
0
    xmlAttrPtr attr;
12071
0
    const xmlChar *attrValue;
12072
#ifdef ENABLE_NAMED_LOCALS
12073
    char buf[40];
12074
#endif
12075
0
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
12076
12077
12078
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12079
0
        return (NULL);
12080
12081
0
    ctxtType = ctxt->ctxtType;
12082
12083
0
    if (topLevel) {
12084
0
  attr = xmlSchemaGetPropNode(node, "name");
12085
0
  if (attr == NULL) {
12086
0
      xmlSchemaPMissingAttrErr(ctxt,
12087
0
    XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12088
0
      return (NULL);
12089
0
  } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12090
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12091
0
      return (NULL);
12092
0
  }
12093
0
    }
12094
12095
0
    if (topLevel == 0) {
12096
  /*
12097
  * Parse as local complex type definition.
12098
  */
12099
#ifdef ENABLE_NAMED_LOCALS
12100
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12101
  type = xmlSchemaAddType(ctxt, schema,
12102
      XML_SCHEMA_TYPE_COMPLEX,
12103
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12104
      ctxt->targetNamespace, node, 0);
12105
#else
12106
0
  type = xmlSchemaAddType(ctxt, schema,
12107
0
      XML_SCHEMA_TYPE_COMPLEX,
12108
0
      NULL, ctxt->targetNamespace, node, 0);
12109
0
#endif
12110
0
  if (type == NULL)
12111
0
      return (NULL);
12112
0
  name = type->name;
12113
0
  type->node = node;
12114
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12115
  /*
12116
  * TODO: We need the target namespace.
12117
  */
12118
0
    } else {
12119
  /*
12120
  * Parse as global complex type definition.
12121
  */
12122
0
  type = xmlSchemaAddType(ctxt, schema,
12123
0
      XML_SCHEMA_TYPE_COMPLEX,
12124
0
      name, ctxt->targetNamespace, node, 1);
12125
0
  if (type == NULL)
12126
0
      return (NULL);
12127
0
  type->node = node;
12128
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12129
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12130
0
    }
12131
0
    type->targetNamespace = ctxt->targetNamespace;
12132
    /*
12133
    * Handle attributes.
12134
    */
12135
0
    attr = node->properties;
12136
0
    while (attr != NULL) {
12137
0
  if (attr->ns == NULL) {
12138
0
      if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12139
    /*
12140
    * Attribute "id".
12141
    */
12142
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12143
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12144
    /*
12145
    * Attribute "mixed".
12146
    */
12147
0
    if (xmlSchemaPGetBoolNodeValue(ctxt,
12148
0
      NULL, (xmlNodePtr) attr))
12149
0
        type->flags |= XML_SCHEMAS_TYPE_MIXED;
12150
0
      } else if (topLevel) {
12151
    /*
12152
    * Attributes of global complex type definitions.
12153
    */
12154
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12155
        /* Pass. */
12156
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12157
        /*
12158
        * Attribute "abstract".
12159
        */
12160
0
        if (xmlSchemaPGetBoolNodeValue(ctxt,
12161
0
          NULL, (xmlNodePtr) attr))
12162
0
      type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12163
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12164
        /*
12165
        * Attribute "final".
12166
        */
12167
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12168
0
      (xmlNodePtr) attr);
12169
0
        if (xmlSchemaPValAttrBlockFinal(attrValue,
12170
0
      &(type->flags),
12171
0
      -1,
12172
0
      XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12173
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12174
0
      -1, -1, -1) != 0)
12175
0
        {
12176
0
      xmlSchemaPSimpleTypeErr(ctxt,
12177
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12178
0
          NULL, (xmlNodePtr) attr, NULL,
12179
0
          "(#all | List of (extension | restriction))",
12180
0
          attrValue, NULL, NULL, NULL);
12181
0
        } else
12182
0
      final = 1;
12183
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12184
        /*
12185
        * Attribute "block".
12186
        */
12187
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12188
0
      (xmlNodePtr) attr);
12189
0
        if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12190
0
      -1,
12191
0
      XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12192
0
      XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12193
0
      -1, -1, -1) != 0) {
12194
0
      xmlSchemaPSimpleTypeErr(ctxt,
12195
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12196
0
          NULL, (xmlNodePtr) attr, NULL,
12197
0
          "(#all | List of (extension | restriction)) ",
12198
0
          attrValue, NULL, NULL, NULL);
12199
0
        } else
12200
0
      block = 1;
12201
0
    } else {
12202
0
      xmlSchemaPIllegalAttrErr(ctxt,
12203
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12204
0
    }
12205
0
      } else {
12206
0
    xmlSchemaPIllegalAttrErr(ctxt,
12207
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12208
0
      }
12209
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12210
0
      xmlSchemaPIllegalAttrErr(ctxt,
12211
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12212
0
  }
12213
0
  attr = attr->next;
12214
0
    }
12215
0
    if (! block) {
12216
  /*
12217
  * Apply default "block" values.
12218
  */
12219
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12220
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12221
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12222
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12223
0
    }
12224
0
    if (! final) {
12225
  /*
12226
  * Apply default "block" values.
12227
  */
12228
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12229
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12230
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12231
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12232
0
    }
12233
    /*
12234
    * And now for the children...
12235
    */
12236
0
    child = node->children;
12237
0
    if (IS_SCHEMA(child, "annotation")) {
12238
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12239
0
        child = child->next;
12240
0
    }
12241
0
    ctxt->ctxtType = type;
12242
0
    if (IS_SCHEMA(child, "simpleContent")) {
12243
  /*
12244
  * <complexType><simpleContent>...
12245
  * 3.4.3 : 2.2
12246
  * Specifying mixed='true' when the <simpleContent>
12247
  * alternative is chosen has no effect
12248
  */
12249
0
  if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12250
0
      type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12251
0
        xmlSchemaParseSimpleContent(ctxt, schema, child,
12252
0
      &hasRestrictionOrExtension);
12253
0
        child = child->next;
12254
0
    } else if (IS_SCHEMA(child, "complexContent")) {
12255
  /*
12256
  * <complexType><complexContent>...
12257
  */
12258
0
  type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12259
0
        xmlSchemaParseComplexContent(ctxt, schema, child,
12260
0
      &hasRestrictionOrExtension);
12261
0
        child = child->next;
12262
0
    } else {
12263
  /*
12264
  * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12265
  *
12266
  * SPEC
12267
  * "...the third alternative (neither <simpleContent> nor
12268
  * <complexContent>) is chosen. This case is understood as shorthand
12269
  * for complex content restricting the `ur-type definition`, and the
12270
  * details of the mappings should be modified as necessary.
12271
  */
12272
0
  type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12273
0
  type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12274
  /*
12275
  * Parse model groups.
12276
  */
12277
0
        if (IS_SCHEMA(child, "all")) {
12278
0
            type->subtypes = (xmlSchemaTypePtr)
12279
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12280
0
        XML_SCHEMA_TYPE_ALL, 1);
12281
0
            child = child->next;
12282
0
        } else if (IS_SCHEMA(child, "choice")) {
12283
0
            type->subtypes = (xmlSchemaTypePtr)
12284
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12285
0
        XML_SCHEMA_TYPE_CHOICE, 1);
12286
0
            child = child->next;
12287
0
        } else if (IS_SCHEMA(child, "sequence")) {
12288
0
            type->subtypes = (xmlSchemaTypePtr)
12289
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12290
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
12291
0
            child = child->next;
12292
0
        } else if (IS_SCHEMA(child, "group")) {
12293
0
            type->subtypes = (xmlSchemaTypePtr)
12294
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12295
      /*
12296
      * Note that the reference will be resolved in
12297
      * xmlSchemaResolveTypeReferences();
12298
      */
12299
0
            child = child->next;
12300
0
        }
12301
  /*
12302
  * Parse attribute decls/refs.
12303
  */
12304
0
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12305
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
12306
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12307
0
      return(NULL);
12308
  /*
12309
  * Parse attribute wildcard.
12310
  */
12311
0
  if (IS_SCHEMA(child, "anyAttribute")) {
12312
0
      type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12313
0
      child = child->next;
12314
0
  }
12315
0
    }
12316
0
    if (child != NULL) {
12317
0
  xmlSchemaPContentErr(ctxt,
12318
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12319
0
      NULL, node, child,
12320
0
      NULL, "(annotation?, (simpleContent | complexContent | "
12321
0
      "((group | all | choice | sequence)?, ((attribute | "
12322
0
      "attributeGroup)*, anyAttribute?))))");
12323
0
    }
12324
    /*
12325
    * REDEFINE: SPEC src-redefine (5)
12326
    */
12327
0
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12328
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12329
0
      NULL, node, "This is a redefinition, thus the "
12330
0
      "<complexType> must have a <restriction> or <extension> "
12331
0
      "grand-child", NULL);
12332
0
    }
12333
0
    ctxt->ctxtType = ctxtType;
12334
0
    return (type);
12335
0
}
12336
12337
/************************************************************************
12338
 *                  *
12339
 *      Validating using Schemas      *
12340
 *                  *
12341
 ************************************************************************/
12342
12343
/************************************************************************
12344
 *                  *
12345
 *      Reading/Writing Schemas       *
12346
 *                  *
12347
 ************************************************************************/
12348
12349
#if 0 /* Will be enabled if it is clear what options are needed. */
12350
/**
12351
 * xmlSchemaParserCtxtSetOptions:
12352
 * @ctxt: a schema parser context
12353
 * @options: a combination of xmlSchemaParserOption
12354
 *
12355
 * Sets the options to be used during the parse.
12356
 *
12357
 * Returns 0 in case of success, -1 in case of an
12358
 * API error.
12359
 */
12360
static int
12361
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12362
            int options)
12363
12364
{
12365
    int i;
12366
12367
    if (ctxt == NULL)
12368
  return (-1);
12369
    /*
12370
    * WARNING: Change the start value if adding to the
12371
    * xmlSchemaParseOption.
12372
    */
12373
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
12374
        if (options & 1<<i) {
12375
      return (-1);
12376
        }
12377
    }
12378
    ctxt->options = options;
12379
    return (0);
12380
}
12381
12382
/**
12383
 * xmlSchemaValidCtxtGetOptions:
12384
 * @ctxt: a schema parser context
12385
 *
12386
 * Returns the option combination of the parser context.
12387
 */
12388
static int
12389
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12390
12391
{
12392
    if (ctxt == NULL)
12393
  return (-1);
12394
    else
12395
  return (ctxt->options);
12396
}
12397
#endif
12398
12399
/**
12400
 * xmlSchemaNewParserCtxt:
12401
 * @URL:  the location of the schema
12402
 *
12403
 * Create an XML Schemas parse context for that file/resource expected
12404
 * to contain an XML Schemas file.
12405
 *
12406
 * Returns the parser context or NULL in case of error
12407
 */
12408
xmlSchemaParserCtxtPtr
12409
xmlSchemaNewParserCtxt(const char *URL)
12410
0
{
12411
0
    xmlSchemaParserCtxtPtr ret;
12412
12413
0
    if (URL == NULL)
12414
0
        return (NULL);
12415
12416
0
    ret = xmlSchemaParserCtxtCreate();
12417
0
    if (ret == NULL)
12418
0
  return(NULL);
12419
0
    ret->dict = xmlDictCreate();
12420
0
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12421
0
    return (ret);
12422
0
}
12423
12424
/**
12425
 * xmlSchemaNewMemParserCtxt:
12426
 * @buffer:  a pointer to a char array containing the schemas
12427
 * @size:  the size of the array
12428
 *
12429
 * Create an XML Schemas parse context for that memory buffer expected
12430
 * to contain an XML Schemas file.
12431
 *
12432
 * Returns the parser context or NULL in case of error
12433
 */
12434
xmlSchemaParserCtxtPtr
12435
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12436
0
{
12437
0
    xmlSchemaParserCtxtPtr ret;
12438
12439
0
    if ((buffer == NULL) || (size <= 0))
12440
0
        return (NULL);
12441
0
    ret = xmlSchemaParserCtxtCreate();
12442
0
    if (ret == NULL)
12443
0
  return(NULL);
12444
0
    ret->buffer = buffer;
12445
0
    ret->size = size;
12446
0
    ret->dict = xmlDictCreate();
12447
0
    return (ret);
12448
0
}
12449
12450
/**
12451
 * xmlSchemaNewDocParserCtxt:
12452
 * @doc:  a preparsed document tree
12453
 *
12454
 * Create an XML Schemas parse context for that document.
12455
 * NB. The document may be modified during the parsing process.
12456
 *
12457
 * Returns the parser context or NULL in case of error
12458
 */
12459
xmlSchemaParserCtxtPtr
12460
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12461
0
{
12462
0
    xmlSchemaParserCtxtPtr ret;
12463
12464
0
    if (doc == NULL)
12465
0
      return (NULL);
12466
0
    ret = xmlSchemaParserCtxtCreate();
12467
0
    if (ret == NULL)
12468
0
  return(NULL);
12469
0
    ret->doc = doc;
12470
0
    ret->dict = xmlDictCreate();
12471
    /* The application has responsibility for the document */
12472
0
    ret->preserve = 1;
12473
12474
0
    return (ret);
12475
0
}
12476
12477
/**
12478
 * xmlSchemaFreeParserCtxt:
12479
 * @ctxt:  the schema parser context
12480
 *
12481
 * Free the resources associated to the schema parser context
12482
 */
12483
void
12484
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12485
0
{
12486
0
    if (ctxt == NULL)
12487
0
        return;
12488
0
    if (ctxt->doc != NULL && !ctxt->preserve)
12489
0
        xmlFreeDoc(ctxt->doc);
12490
0
    if (ctxt->vctxt != NULL) {
12491
0
  xmlSchemaFreeValidCtxt(ctxt->vctxt);
12492
0
    }
12493
0
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12494
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
12495
0
  ctxt->constructor = NULL;
12496
0
  ctxt->ownsConstructor = 0;
12497
0
    }
12498
0
    if (ctxt->attrProhibs != NULL)
12499
0
  xmlSchemaItemListFree(ctxt->attrProhibs);
12500
0
    xmlDictFree(ctxt->dict);
12501
0
    xmlFree(ctxt);
12502
0
}
12503
12504
/************************************************************************
12505
 *                  *
12506
 *      Building the content models     *
12507
 *                  *
12508
 ************************************************************************/
12509
12510
/**
12511
 * xmlSchemaBuildContentModelForSubstGroup:
12512
 *
12513
 * Returns 1 if nillable, 0 otherwise
12514
 */
12515
static int
12516
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12517
  xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12518
0
{
12519
0
    xmlAutomataStatePtr start, tmp;
12520
0
    xmlSchemaElementPtr elemDecl, member;
12521
0
    xmlSchemaSubstGroupPtr substGroup;
12522
0
    int i;
12523
0
    int ret = 0;
12524
12525
0
    elemDecl = (xmlSchemaElementPtr) particle->children;
12526
    /*
12527
    * Wrap the substitution group with a CHOICE.
12528
    */
12529
0
    start = pctxt->state;
12530
0
    if (end == NULL)
12531
0
  end = xmlAutomataNewState(pctxt->am);
12532
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12533
0
    if (substGroup == NULL) {
12534
0
  xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12535
0
      XML_SCHEMAP_INTERNAL,
12536
0
      "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12537
0
      "declaration is marked having a subst. group but none "
12538
0
      "available.\n", elemDecl->name, NULL);
12539
0
  return(0);
12540
0
    }
12541
0
    if (counter >= 0) {
12542
  /*
12543
  * NOTE that we put the declaration in, even if it's abstract.
12544
  * However, an error will be raised during *validation* if an element
12545
  * information item shall be validated against an abstract element
12546
  * declaration.
12547
  */
12548
0
  tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12549
0
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
12550
0
              elemDecl->name, elemDecl->targetNamespace, elemDecl);
12551
  /*
12552
  * Add subst. group members.
12553
  */
12554
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12555
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12556
0
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
12557
0
                   member->name, member->targetNamespace, member);
12558
0
  }
12559
0
    } else if (particle->maxOccurs == 1) {
12560
  /*
12561
  * NOTE that we put the declaration in, even if it's abstract,
12562
  */
12563
0
  xmlAutomataNewEpsilon(pctxt->am,
12564
0
      xmlAutomataNewTransition2(pctxt->am,
12565
0
      start, NULL,
12566
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12567
  /*
12568
  * Add subst. group members.
12569
  */
12570
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12571
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12572
      /*
12573
      * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12574
      *  was incorrectly used instead of xmlAutomataNewTransition2()
12575
      *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12576
      *  section in xmlSchemaBuildAContentModel() ).
12577
      * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12578
      *  intended for the above "counter" section originally. I.e.,
12579
      *  check xs:all with subst-groups.
12580
      *
12581
      * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12582
      *                member->name, member->targetNamespace,
12583
      *          1, 1, member);
12584
      */
12585
0
      tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12586
0
    member->name, member->targetNamespace, member);
12587
0
      xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12588
0
  }
12589
0
    } else {
12590
0
  xmlAutomataStatePtr hop;
12591
0
  int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12592
0
      UNBOUNDED : particle->maxOccurs - 1;
12593
0
  int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12594
12595
0
  counter =
12596
0
      xmlAutomataNewCounter(pctxt->am, minOccurs,
12597
0
      maxOccurs);
12598
0
  hop = xmlAutomataNewState(pctxt->am);
12599
12600
0
  xmlAutomataNewEpsilon(pctxt->am,
12601
0
      xmlAutomataNewTransition2(pctxt->am,
12602
0
      start, NULL,
12603
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl),
12604
0
      hop);
12605
  /*
12606
   * Add subst. group members.
12607
   */
12608
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12609
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12610
0
      xmlAutomataNewEpsilon(pctxt->am,
12611
0
    xmlAutomataNewTransition2(pctxt->am,
12612
0
    start, NULL,
12613
0
    member->name, member->targetNamespace, member),
12614
0
    hop);
12615
0
  }
12616
0
  xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12617
0
  xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12618
0
    }
12619
0
    if (particle->minOccurs == 0) {
12620
0
  xmlAutomataNewEpsilon(pctxt->am, start, end);
12621
0
        ret = 1;
12622
0
    }
12623
0
    pctxt->state = end;
12624
0
    return(ret);
12625
0
}
12626
12627
/**
12628
 * xmlSchemaBuildContentModelForElement:
12629
 *
12630
 * Returns 1 if nillable, 0 otherwise
12631
 */
12632
static int
12633
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12634
             xmlSchemaParticlePtr particle)
12635
0
{
12636
0
    int ret = 0;
12637
12638
0
    if (((xmlSchemaElementPtr) particle->children)->flags &
12639
0
  XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12640
  /*
12641
  * Substitution groups.
12642
  */
12643
0
  ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12644
0
    } else {
12645
0
  xmlSchemaElementPtr elemDecl;
12646
0
  xmlAutomataStatePtr start;
12647
12648
0
  elemDecl = (xmlSchemaElementPtr) particle->children;
12649
12650
0
  if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12651
0
      return(0);
12652
0
  if (particle->maxOccurs == 1) {
12653
0
      start = ctxt->state;
12654
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12655
0
        elemDecl->name, elemDecl->targetNamespace, elemDecl);
12656
0
  } else if ((particle->maxOccurs >= UNBOUNDED) &&
12657
0
             (particle->minOccurs < 2)) {
12658
      /* Special case. */
12659
0
      start = ctxt->state;
12660
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12661
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12662
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12663
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12664
0
  } else {
12665
0
      int counter;
12666
0
      int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12667
0
          UNBOUNDED : particle->maxOccurs - 1;
12668
0
      int minOccurs = particle->minOccurs < 1 ?
12669
0
          0 : particle->minOccurs - 1;
12670
12671
0
      start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12672
0
      counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12673
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12674
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12675
0
      xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12676
0
      ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12677
0
    NULL, counter);
12678
0
  }
12679
0
  if (particle->minOccurs == 0) {
12680
0
      xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12681
0
            ret = 1;
12682
0
        }
12683
0
    }
12684
0
    return(ret);
12685
0
}
12686
12687
/**
12688
 * xmlSchemaBuildAContentModel:
12689
 * @ctxt:  the schema parser context
12690
 * @particle:  the particle component
12691
 * @name:  the complex type's name whose content is being built
12692
 *
12693
 * Create the automaton for the {content type} of a complex type.
12694
 *
12695
 * Returns 1 if the content is nillable, 0 otherwise
12696
 */
12697
static int
12698
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12699
          xmlSchemaParticlePtr particle)
12700
0
{
12701
0
    int ret = 0, tmp2;
12702
12703
0
    if (particle == NULL) {
12704
0
  PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12705
0
  return(1);
12706
0
    }
12707
0
    if (particle->children == NULL) {
12708
  /*
12709
  * Just return in this case. A missing "term" of the particle
12710
  * might arise due to an invalid "term" component.
12711
  */
12712
0
  return(1);
12713
0
    }
12714
12715
0
    switch (particle->children->type) {
12716
0
  case XML_SCHEMA_TYPE_ANY: {
12717
0
      xmlAutomataStatePtr start, end;
12718
0
      xmlSchemaWildcardPtr wild;
12719
0
      xmlSchemaWildcardNsPtr ns;
12720
12721
0
      wild = (xmlSchemaWildcardPtr) particle->children;
12722
12723
0
      start = pctxt->state;
12724
0
      end = xmlAutomataNewState(pctxt->am);
12725
12726
0
      if (particle->maxOccurs == 1) {
12727
0
    if (wild->any == 1) {
12728
        /*
12729
        * We need to add both transitions:
12730
        *
12731
        * 1. the {"*", "*"} for elements in a namespace.
12732
        */
12733
0
        pctxt->state =
12734
0
      xmlAutomataNewTransition2(pctxt->am,
12735
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12736
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12737
        /*
12738
        * 2. the {"*"} for elements in no namespace.
12739
        */
12740
0
        pctxt->state =
12741
0
      xmlAutomataNewTransition2(pctxt->am,
12742
0
      start, NULL, BAD_CAST "*", NULL, wild);
12743
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12744
12745
0
    } else if (wild->nsSet != NULL) {
12746
0
        ns = wild->nsSet;
12747
0
        do {
12748
0
      pctxt->state = start;
12749
0
      pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12750
0
          pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12751
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12752
0
      ns = ns->next;
12753
0
        } while (ns != NULL);
12754
12755
0
    } else if (wild->negNsSet != NULL) {
12756
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12757
0
      start, end, BAD_CAST "*", wild->negNsSet->value,
12758
0
      wild);
12759
0
    }
12760
0
      } else {
12761
0
    int counter;
12762
0
    xmlAutomataStatePtr hop;
12763
0
    int maxOccurs =
12764
0
        particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12765
0
                                           particle->maxOccurs - 1;
12766
0
    int minOccurs =
12767
0
        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12768
12769
0
    counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12770
0
    hop = xmlAutomataNewState(pctxt->am);
12771
0
    if (wild->any == 1) {
12772
0
        pctxt->state =
12773
0
      xmlAutomataNewTransition2(pctxt->am,
12774
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12775
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12776
0
        pctxt->state =
12777
0
      xmlAutomataNewTransition2(pctxt->am,
12778
0
      start, NULL, BAD_CAST "*", NULL, wild);
12779
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12780
0
    } else if (wild->nsSet != NULL) {
12781
0
        ns = wild->nsSet;
12782
0
        do {
12783
0
      pctxt->state =
12784
0
          xmlAutomataNewTransition2(pctxt->am,
12785
0
        start, NULL, BAD_CAST "*", ns->value, wild);
12786
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12787
0
      ns = ns->next;
12788
0
        } while (ns != NULL);
12789
12790
0
    } else if (wild->negNsSet != NULL) {
12791
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12792
0
      start, hop, BAD_CAST "*", wild->negNsSet->value,
12793
0
      wild);
12794
0
    }
12795
0
    xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12796
0
    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12797
0
      }
12798
0
      if (particle->minOccurs == 0) {
12799
0
    xmlAutomataNewEpsilon(pctxt->am, start, end);
12800
0
                ret = 1;
12801
0
      }
12802
0
      pctxt->state = end;
12803
0
            break;
12804
0
  }
12805
0
        case XML_SCHEMA_TYPE_ELEMENT:
12806
0
      ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12807
0
      break;
12808
0
        case XML_SCHEMA_TYPE_SEQUENCE:{
12809
0
            xmlSchemaTreeItemPtr sub;
12810
12811
0
            ret = 1;
12812
            /*
12813
             * If max and min occurrences are default (1) then
12814
             * simply iterate over the particles of the <sequence>.
12815
             */
12816
0
            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12817
0
                sub = particle->children->children;
12818
12819
0
                while (sub != NULL) {
12820
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12821
0
                                        (xmlSchemaParticlePtr) sub);
12822
0
                    if (tmp2 != 1) ret = 0;
12823
0
                    sub = sub->next;
12824
0
                }
12825
0
            } else {
12826
0
                xmlAutomataStatePtr oldstate = pctxt->state;
12827
12828
0
                if (particle->maxOccurs >= UNBOUNDED) {
12829
0
                    if (particle->minOccurs > 1) {
12830
0
                        xmlAutomataStatePtr tmp;
12831
0
                        int counter;
12832
12833
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12834
0
                            oldstate, NULL);
12835
0
                        oldstate = pctxt->state;
12836
12837
0
                        counter = xmlAutomataNewCounter(pctxt->am,
12838
0
                            particle->minOccurs - 1, UNBOUNDED);
12839
12840
0
                        sub = particle->children->children;
12841
0
                        while (sub != NULL) {
12842
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12843
0
                                            (xmlSchemaParticlePtr) sub);
12844
0
                            if (tmp2 != 1) ret = 0;
12845
0
                            sub = sub->next;
12846
0
                        }
12847
0
                        tmp = pctxt->state;
12848
0
                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
12849
0
                                                   oldstate, counter);
12850
0
                        pctxt->state =
12851
0
                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
12852
0
                                                       NULL, counter);
12853
0
                        if (ret == 1)
12854
0
                            xmlAutomataNewEpsilon(pctxt->am,
12855
0
                                                oldstate, pctxt->state);
12856
12857
0
                    } else {
12858
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12859
0
                            oldstate, NULL);
12860
0
                        oldstate = pctxt->state;
12861
12862
0
                        sub = particle->children->children;
12863
0
                        while (sub != NULL) {
12864
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12865
0
                                        (xmlSchemaParticlePtr) sub);
12866
0
                            if (tmp2 != 1) ret = 0;
12867
0
                            sub = sub->next;
12868
0
                        }
12869
0
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12870
0
                                              oldstate);
12871
                        /*
12872
                         * epsilon needed to block previous trans from
12873
                         * being allowed to enter back from another
12874
                         * construct
12875
                         */
12876
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12877
0
                                            pctxt->state, NULL);
12878
0
                        if (particle->minOccurs == 0) {
12879
0
                            xmlAutomataNewEpsilon(pctxt->am,
12880
0
                                oldstate, pctxt->state);
12881
0
                            ret = 1;
12882
0
                        }
12883
0
                    }
12884
0
                } else if ((particle->maxOccurs > 1)
12885
0
                           || (particle->minOccurs > 1)) {
12886
0
                    xmlAutomataStatePtr tmp;
12887
0
                    int counter;
12888
12889
0
                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12890
0
                        oldstate, NULL);
12891
0
                    oldstate = pctxt->state;
12892
12893
0
                    counter = xmlAutomataNewCounter(pctxt->am,
12894
0
                        particle->minOccurs - 1,
12895
0
                        particle->maxOccurs - 1);
12896
12897
0
                    sub = particle->children->children;
12898
0
                    while (sub != NULL) {
12899
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12900
0
                                        (xmlSchemaParticlePtr) sub);
12901
0
                        if (tmp2 != 1) ret = 0;
12902
0
                        sub = sub->next;
12903
0
                    }
12904
0
                    tmp = pctxt->state;
12905
0
                    xmlAutomataNewCountedTrans(pctxt->am,
12906
0
                        tmp, oldstate, counter);
12907
0
                    pctxt->state =
12908
0
                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12909
0
                                                   counter);
12910
0
                    if ((particle->minOccurs == 0) || (ret == 1)) {
12911
0
                        xmlAutomataNewEpsilon(pctxt->am,
12912
0
                                            oldstate, pctxt->state);
12913
0
                        ret = 1;
12914
0
                    }
12915
0
                } else {
12916
0
                    sub = particle->children->children;
12917
0
                    while (sub != NULL) {
12918
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12919
0
                                        (xmlSchemaParticlePtr) sub);
12920
0
                        if (tmp2 != 1) ret = 0;
12921
0
                        sub = sub->next;
12922
0
                    }
12923
12924
        /*
12925
         * epsilon needed to block previous trans from
12926
         * being allowed to enter back from another
12927
         * construct
12928
         */
12929
0
        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12930
0
          pctxt->state, NULL);
12931
12932
0
                    if (particle->minOccurs == 0) {
12933
0
                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
12934
0
                                              pctxt->state);
12935
0
                        ret = 1;
12936
0
                    }
12937
0
                }
12938
0
            }
12939
0
            break;
12940
0
        }
12941
0
        case XML_SCHEMA_TYPE_CHOICE:{
12942
0
            xmlSchemaTreeItemPtr sub;
12943
0
            xmlAutomataStatePtr start, end;
12944
12945
0
            ret = 0;
12946
0
            start = pctxt->state;
12947
0
            end = xmlAutomataNewState(pctxt->am);
12948
12949
            /*
12950
             * iterate over the subtypes and remerge the end with an
12951
             * epsilon transition
12952
             */
12953
0
            if (particle->maxOccurs == 1) {
12954
0
                sub = particle->children->children;
12955
0
                while (sub != NULL) {
12956
0
                    pctxt->state = start;
12957
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12958
0
                                        (xmlSchemaParticlePtr) sub);
12959
0
                    if (tmp2 == 1) ret = 1;
12960
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12961
0
                    sub = sub->next;
12962
0
                }
12963
0
            } else {
12964
0
                int counter;
12965
0
                xmlAutomataStatePtr hop, base;
12966
0
                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12967
0
                    UNBOUNDED : particle->maxOccurs - 1;
12968
0
                int minOccurs =
12969
0
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12970
12971
                /*
12972
                 * use a counter to keep track of the number of transitions
12973
                 * which went through the choice.
12974
                 */
12975
0
                counter =
12976
0
                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12977
0
                hop = xmlAutomataNewState(pctxt->am);
12978
0
                base = xmlAutomataNewState(pctxt->am);
12979
12980
0
                sub = particle->children->children;
12981
0
                while (sub != NULL) {
12982
0
                    pctxt->state = base;
12983
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12984
0
                                        (xmlSchemaParticlePtr) sub);
12985
0
                    if (tmp2 == 1) ret = 1;
12986
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12987
0
                    sub = sub->next;
12988
0
                }
12989
0
                xmlAutomataNewEpsilon(pctxt->am, start, base);
12990
0
                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
12991
0
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12992
0
                if (ret == 1)
12993
0
                    xmlAutomataNewEpsilon(pctxt->am, base, end);
12994
0
            }
12995
0
            if (particle->minOccurs == 0) {
12996
0
                xmlAutomataNewEpsilon(pctxt->am, start, end);
12997
0
                ret = 1;
12998
0
            }
12999
0
            pctxt->state = end;
13000
0
            break;
13001
0
        }
13002
0
        case XML_SCHEMA_TYPE_ALL:{
13003
0
            xmlAutomataStatePtr start, tmp;
13004
0
            xmlSchemaParticlePtr sub;
13005
0
            xmlSchemaElementPtr elemDecl;
13006
13007
0
            ret = 1;
13008
13009
0
            sub = (xmlSchemaParticlePtr) particle->children->children;
13010
0
            if (sub == NULL)
13011
0
                break;
13012
13013
0
            ret = 0;
13014
13015
0
            start = pctxt->state;
13016
0
            tmp = xmlAutomataNewState(pctxt->am);
13017
0
            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13018
0
            pctxt->state = tmp;
13019
0
            while (sub != NULL) {
13020
0
                pctxt->state = tmp;
13021
13022
0
                elemDecl = (xmlSchemaElementPtr) sub->children;
13023
0
                if (elemDecl == NULL) {
13024
0
                    PERROR_INT("xmlSchemaBuildAContentModel",
13025
0
                        "<element> particle has no term");
13026
0
                    return(ret);
13027
0
                };
13028
                /*
13029
                * NOTE: The {max occurs} of all the particles in the
13030
                * {particles} of the group must be 0 or 1; this is
13031
                * already ensured during the parse of the content of
13032
                * <all>.
13033
                */
13034
0
                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13035
0
                    int counter;
13036
13037
                    /*
13038
                     * This is an abstract group, we need to share
13039
                     * the same counter for all the element transitions
13040
                     * derived from the group
13041
                     */
13042
0
                    counter = xmlAutomataNewCounter(pctxt->am,
13043
0
                                       sub->minOccurs, sub->maxOccurs);
13044
0
                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
13045
0
                                       sub, counter, pctxt->state);
13046
0
                } else {
13047
0
                    if ((sub->minOccurs == 1) &&
13048
0
                        (sub->maxOccurs == 1)) {
13049
0
                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13050
0
                                                pctxt->state,
13051
0
                                                elemDecl->name,
13052
0
                                                elemDecl->targetNamespace,
13053
0
                                                1, 1, elemDecl);
13054
0
                    } else if ((sub->minOccurs == 0) &&
13055
0
                        (sub->maxOccurs == 1)) {
13056
13057
0
                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13058
0
                                                 pctxt->state,
13059
0
                                                 elemDecl->name,
13060
0
                                                 elemDecl->targetNamespace,
13061
0
                                                 0,
13062
0
                                                 1,
13063
0
                                                 elemDecl);
13064
0
                    }
13065
0
                }
13066
0
                sub = (xmlSchemaParticlePtr) sub->next;
13067
0
            }
13068
0
            pctxt->state =
13069
0
                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13070
0
            if (particle->minOccurs == 0) {
13071
0
                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13072
0
                ret = 1;
13073
0
            }
13074
0
            break;
13075
0
        }
13076
0
  case XML_SCHEMA_TYPE_GROUP:
13077
      /*
13078
      * If we hit a model group definition, then this means that
13079
      * it was empty, thus was not substituted for the containing
13080
      * model group. Just do nothing in this case.
13081
      * TODO: But the group should be substituted and not occur at
13082
      * all in the content model at this point. Fix this.
13083
      */
13084
0
            ret = 1;
13085
0
      break;
13086
0
        default:
13087
0
      xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13088
0
    "xmlSchemaBuildAContentModel",
13089
0
    "found unexpected term of type '%s' in content model",
13090
0
    WXS_ITEM_TYPE_NAME(particle->children), NULL);
13091
0
            return(ret);
13092
0
    }
13093
0
    return(ret);
13094
0
}
13095
13096
/**
13097
 * xmlSchemaBuildContentModel:
13098
 * @ctxt:  the schema parser context
13099
 * @type:  the complex type definition
13100
 * @name:  the element name
13101
 *
13102
 * Builds the content model of the complex type.
13103
 */
13104
static void
13105
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13106
         xmlSchemaParserCtxtPtr ctxt)
13107
0
{
13108
0
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13109
0
  (type->contModel != NULL) ||
13110
0
  ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13111
0
  (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13112
0
  return;
13113
13114
0
    ctxt->am = NULL;
13115
0
    ctxt->am = xmlNewAutomata();
13116
0
    if (ctxt->am == NULL) {
13117
0
  xmlSchemaPErrMemory(ctxt);
13118
0
        return;
13119
0
    }
13120
0
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
13121
    /*
13122
    * Build the automaton.
13123
    */
13124
0
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13125
0
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13126
0
    type->contModel = xmlAutomataCompile(ctxt->am);
13127
0
    if (type->contModel == NULL) {
13128
0
        xmlSchemaPCustomErr(ctxt,
13129
0
      XML_SCHEMAP_INTERNAL,
13130
0
      WXS_BASIC_CAST type, type->node,
13131
0
      "Failed to compile the content model", NULL);
13132
0
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13133
0
        xmlSchemaPCustomErr(ctxt,
13134
0
      XML_SCHEMAP_NOT_DETERMINISTIC,
13135
      /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13136
0
      WXS_BASIC_CAST type, type->node,
13137
0
      "The content model is not determinist", NULL);
13138
0
    } else {
13139
0
    }
13140
0
    ctxt->state = NULL;
13141
0
    xmlFreeAutomata(ctxt->am);
13142
0
    ctxt->am = NULL;
13143
0
}
13144
13145
/**
13146
 * xmlSchemaResolveElementReferences:
13147
 * @elem:  the schema element context
13148
 * @ctxt:  the schema parser context
13149
 *
13150
 * Resolves the references of an element declaration
13151
 * or particle, which has an element declaration as it's
13152
 * term.
13153
 */
13154
static void
13155
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13156
          xmlSchemaParserCtxtPtr ctxt)
13157
0
{
13158
0
    if ((ctxt == NULL) || (elemDecl == NULL) ||
13159
0
  ((elemDecl != NULL) &&
13160
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13161
0
        return;
13162
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13163
13164
0
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13165
0
  xmlSchemaTypePtr type;
13166
13167
  /* (type definition) ... otherwise the type definition `resolved`
13168
  * to by the `actual value` of the type [attribute] ...
13169
  */
13170
0
  type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13171
0
      elemDecl->namedTypeNs);
13172
0
  if (type == NULL) {
13173
0
      xmlSchemaPResCompAttrErr(ctxt,
13174
0
    XML_SCHEMAP_SRC_RESOLVE,
13175
0
    WXS_BASIC_CAST elemDecl, elemDecl->node,
13176
0
    "type", elemDecl->namedType, elemDecl->namedTypeNs,
13177
0
    XML_SCHEMA_TYPE_BASIC, "type definition");
13178
0
  } else
13179
0
      elemDecl->subtypes = type;
13180
0
    }
13181
0
    if (elemDecl->substGroup != NULL) {
13182
0
  xmlSchemaElementPtr substHead;
13183
13184
  /*
13185
  * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13186
  * substitutionGroup?
13187
  */
13188
0
  substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13189
0
      elemDecl->substGroupNs);
13190
0
  if (substHead == NULL) {
13191
0
      xmlSchemaPResCompAttrErr(ctxt,
13192
0
    XML_SCHEMAP_SRC_RESOLVE,
13193
0
    WXS_BASIC_CAST elemDecl, NULL,
13194
0
    "substitutionGroup", elemDecl->substGroup,
13195
0
    elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13196
0
  } else {
13197
0
      xmlSchemaResolveElementReferences(substHead, ctxt);
13198
      /*
13199
      * Set the "substitution group affiliation".
13200
      * NOTE that now we use the "refDecl" field for this.
13201
      */
13202
0
      WXS_SUBST_HEAD(elemDecl) = substHead;
13203
      /*
13204
      * The type definitions is set to:
13205
      * SPEC "...the {type definition} of the element
13206
      * declaration `resolved` to by the `actual value`
13207
      * of the substitutionGroup [attribute], if present"
13208
      */
13209
0
      if (elemDecl->subtypes == NULL) {
13210
0
                if (substHead->subtypes == NULL) {
13211
                    /*
13212
                     * This can happen with self-referencing substitution
13213
                     * groups. The cycle will be detected later, but we have
13214
                     * to set subtypes to avoid null-pointer dereferences.
13215
                     */
13216
0
              elemDecl->subtypes = xmlSchemaGetBuiltInType(
13217
0
                            XML_SCHEMAS_ANYTYPE);
13218
0
                } else {
13219
0
        elemDecl->subtypes = substHead->subtypes;
13220
0
                }
13221
0
            }
13222
0
  }
13223
0
    }
13224
    /*
13225
    * SPEC "The definition of anyType serves as the default type definition
13226
    * for element declarations whose XML representation does not specify one."
13227
    */
13228
0
    if ((elemDecl->subtypes == NULL) &&
13229
0
  (elemDecl->namedType == NULL) &&
13230
0
  (elemDecl->substGroup == NULL))
13231
0
  elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13232
0
}
13233
13234
/**
13235
 * xmlSchemaResolveUnionMemberTypes:
13236
 * @ctxt:  the schema parser context
13237
 * @type:  the schema simple type definition
13238
 *
13239
 * Checks and builds the "member type definitions" property of the union
13240
 * simple type. This handles part (1), part (2) is done in
13241
 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13242
 *
13243
 * Returns -1 in case of an internal error, 0 otherwise.
13244
 */
13245
static int
13246
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13247
         xmlSchemaTypePtr type)
13248
0
{
13249
13250
0
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
13251
0
    xmlSchemaTypePtr memberType;
13252
13253
    /*
13254
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13255
    * define the explicit members as the type definitions `resolved`
13256
    * to by the items in the `actual value` of the memberTypes [attribute],
13257
    * if any, followed by the type definitions corresponding to the
13258
    * <simpleType>s among the [children] of <union>, if any."
13259
    */
13260
    /*
13261
    * Resolve references.
13262
    */
13263
0
    link = type->memberTypes;
13264
0
    lastLink = NULL;
13265
0
    while (link != NULL) {
13266
0
  const xmlChar *name, *nsName;
13267
13268
0
  name = ((xmlSchemaQNameRefPtr) link->type)->name;
13269
0
  nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13270
13271
0
  memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13272
0
  if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13273
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13274
0
    WXS_BASIC_CAST type, type->node, "memberTypes",
13275
0
    name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13276
      /*
13277
      * Remove the member type link.
13278
      */
13279
0
      if (lastLink == NULL)
13280
0
    type->memberTypes = link->next;
13281
0
      else
13282
0
    lastLink->next = link->next;
13283
0
      newLink = link;
13284
0
      link = link->next;
13285
0
      xmlFree(newLink);
13286
0
  } else {
13287
0
      link->type = memberType;
13288
0
      lastLink = link;
13289
0
      link = link->next;
13290
0
  }
13291
0
    }
13292
    /*
13293
    * Add local simple types,
13294
    */
13295
0
    memberType = type->subtypes;
13296
0
    while (memberType != NULL) {
13297
0
  link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13298
0
  if (link == NULL) {
13299
0
      xmlSchemaPErrMemory(ctxt);
13300
0
      return (-1);
13301
0
  }
13302
0
  link->type = memberType;
13303
0
  link->next = NULL;
13304
0
  if (lastLink == NULL)
13305
0
      type->memberTypes = link;
13306
0
  else
13307
0
      lastLink->next = link;
13308
0
  lastLink = link;
13309
0
  memberType = memberType->next;
13310
0
    }
13311
0
    return (0);
13312
0
}
13313
13314
/**
13315
 * xmlSchemaIsDerivedFromBuiltInType:
13316
 * @ctxt:  the schema parser context
13317
 * @type:  the type definition
13318
 * @valType: the value type
13319
 *
13320
 *
13321
 * Returns 1 if the type has the given value type, or
13322
 * is derived from such a type.
13323
 */
13324
static int
13325
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13326
0
{
13327
0
    if (type == NULL)
13328
0
  return (0);
13329
0
    if (WXS_IS_COMPLEX(type))
13330
0
  return (0);
13331
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13332
0
  if (type->builtInType == valType)
13333
0
      return(1);
13334
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13335
0
      (type->builtInType == XML_SCHEMAS_ANYTYPE))
13336
0
      return (0);
13337
0
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13338
0
    }
13339
0
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13340
0
}
13341
13342
#if 0
13343
/**
13344
 * xmlSchemaIsDerivedFromBuiltInType:
13345
 * @ctxt:  the schema parser context
13346
 * @type:  the type definition
13347
 * @valType: the value type
13348
 *
13349
 *
13350
 * Returns 1 if the type has the given value type, or
13351
 * is derived from such a type.
13352
 */
13353
static int
13354
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13355
{
13356
    if (type == NULL)
13357
  return (0);
13358
    if (WXS_IS_COMPLEX(type))
13359
  return (0);
13360
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13361
  if (type->builtInType == valType)
13362
      return(1);
13363
  return (0);
13364
    } else
13365
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13366
13367
    return (0);
13368
}
13369
13370
static xmlSchemaTypePtr
13371
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13372
{
13373
    if (type == NULL)
13374
  return (NULL);
13375
    if (WXS_IS_COMPLEX(type))
13376
  return (NULL);
13377
    if (type->type == XML_SCHEMA_TYPE_BASIC)
13378
  return(type);
13379
    return(xmlSchemaQueryBuiltInType(type->subtypes));
13380
}
13381
#endif
13382
13383
/**
13384
 * xmlSchemaGetPrimitiveType:
13385
 * @type:  the simpleType definition
13386
 *
13387
 * Returns the primitive type of the given type or
13388
 * NULL in case of error.
13389
 */
13390
static xmlSchemaTypePtr
13391
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13392
0
{
13393
13394
0
    while (type != NULL) {
13395
  /*
13396
  * Note that anySimpleType is actually not a primitive type
13397
  * but we need that here.
13398
  */
13399
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13400
0
     (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13401
0
      return (type);
13402
0
  type = type->baseType;
13403
0
    }
13404
13405
0
    return (NULL);
13406
0
}
13407
13408
#if 0
13409
/**
13410
 * xmlSchemaGetBuiltInTypeAncestor:
13411
 * @type:  the simpleType definition
13412
 *
13413
 * Returns the primitive type of the given type or
13414
 * NULL in case of error.
13415
 */
13416
static xmlSchemaTypePtr
13417
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13418
{
13419
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13420
  return (0);
13421
    while (type != NULL) {
13422
  if (type->type == XML_SCHEMA_TYPE_BASIC)
13423
      return (type);
13424
  type = type->baseType;
13425
    }
13426
13427
    return (NULL);
13428
}
13429
#endif
13430
13431
/**
13432
 * xmlSchemaCloneWildcardNsConstraints:
13433
 * @ctxt:  the schema parser context
13434
 * @dest:  the destination wildcard
13435
 * @source: the source wildcard
13436
 *
13437
 * Clones the namespace constraints of source
13438
 * and assigns them to dest.
13439
 * Returns -1 on internal error, 0 otherwise.
13440
 */
13441
static int
13442
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13443
            xmlSchemaWildcardPtr dest,
13444
            xmlSchemaWildcardPtr source)
13445
0
{
13446
0
    xmlSchemaWildcardNsPtr cur, tmp, last;
13447
13448
0
    if ((source == NULL) || (dest == NULL))
13449
0
  return(-1);
13450
0
    dest->any = source->any;
13451
0
    cur = source->nsSet;
13452
0
    last = NULL;
13453
0
    while (cur != NULL) {
13454
0
  tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13455
0
  if (tmp == NULL)
13456
0
      return(-1);
13457
0
  tmp->value = cur->value;
13458
0
  if (last == NULL)
13459
0
      dest->nsSet = tmp;
13460
0
  else
13461
0
      last->next = tmp;
13462
0
  last = tmp;
13463
0
  cur = cur->next;
13464
0
    }
13465
0
    if (dest->negNsSet != NULL)
13466
0
  xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13467
0
    if (source->negNsSet != NULL) {
13468
0
  dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13469
0
  if (dest->negNsSet == NULL)
13470
0
      return(-1);
13471
0
  dest->negNsSet->value = source->negNsSet->value;
13472
0
    } else
13473
0
  dest->negNsSet = NULL;
13474
0
    return(0);
13475
0
}
13476
13477
/**
13478
 * xmlSchemaUnionWildcards:
13479
 * @ctxt:  the schema parser context
13480
 * @completeWild:  the first wildcard
13481
 * @curWild: the second wildcard
13482
 *
13483
 * Unions the namespace constraints of the given wildcards.
13484
 * @completeWild will hold the resulting union.
13485
 * Returns a positive error code on failure, -1 in case of an
13486
 * internal error, 0 otherwise.
13487
 */
13488
static int
13489
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13490
          xmlSchemaWildcardPtr completeWild,
13491
          xmlSchemaWildcardPtr curWild)
13492
0
{
13493
0
    xmlSchemaWildcardNsPtr cur, curB, tmp;
13494
13495
    /*
13496
    * 1 If O1 and O2 are the same value, then that value must be the
13497
    * value.
13498
    */
13499
0
    if ((completeWild->any == curWild->any) &&
13500
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13501
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13502
13503
0
  if ((completeWild->negNsSet == NULL) ||
13504
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13505
13506
0
      if (completeWild->nsSet != NULL) {
13507
0
    int found = 0;
13508
13509
    /*
13510
    * Check equality of sets.
13511
    */
13512
0
    cur = completeWild->nsSet;
13513
0
    while (cur != NULL) {
13514
0
        found = 0;
13515
0
        curB = curWild->nsSet;
13516
0
        while (curB != NULL) {
13517
0
      if (cur->value == curB->value) {
13518
0
          found = 1;
13519
0
          break;
13520
0
      }
13521
0
      curB = curB->next;
13522
0
        }
13523
0
        if (!found)
13524
0
      break;
13525
0
        cur = cur->next;
13526
0
    }
13527
0
    if (found)
13528
0
        return(0);
13529
0
      } else
13530
0
    return(0);
13531
0
  }
13532
0
    }
13533
    /*
13534
    * 2 If either O1 or O2 is any, then any must be the value
13535
    */
13536
0
    if (completeWild->any != curWild->any) {
13537
0
  if (completeWild->any == 0) {
13538
0
      completeWild->any = 1;
13539
0
      if (completeWild->nsSet != NULL) {
13540
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13541
0
    completeWild->nsSet = NULL;
13542
0
      }
13543
0
      if (completeWild->negNsSet != NULL) {
13544
0
    xmlFree(completeWild->negNsSet);
13545
0
    completeWild->negNsSet = NULL;
13546
0
      }
13547
0
  }
13548
0
  return (0);
13549
0
    }
13550
    /*
13551
    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13552
    * then the union of those sets must be the value.
13553
    */
13554
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13555
0
  int found;
13556
0
  xmlSchemaWildcardNsPtr start;
13557
13558
0
  cur = curWild->nsSet;
13559
0
  start = completeWild->nsSet;
13560
0
  while (cur != NULL) {
13561
0
      found = 0;
13562
0
      curB = start;
13563
0
      while (curB != NULL) {
13564
0
    if (cur->value == curB->value) {
13565
0
        found = 1;
13566
0
        break;
13567
0
    }
13568
0
    curB = curB->next;
13569
0
      }
13570
0
      if (!found) {
13571
0
    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13572
0
    if (tmp == NULL)
13573
0
        return (-1);
13574
0
    tmp->value = cur->value;
13575
0
    tmp->next = completeWild->nsSet;
13576
0
    completeWild->nsSet = tmp;
13577
0
      }
13578
0
      cur = cur->next;
13579
0
  }
13580
13581
0
  return(0);
13582
0
    }
13583
    /*
13584
    * 4 If the two are negations of different values (namespace names
13585
    * or `absent`), then a pair of not and `absent` must be the value.
13586
    */
13587
0
    if ((completeWild->negNsSet != NULL) &&
13588
0
  (curWild->negNsSet != NULL) &&
13589
0
  (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13590
0
  completeWild->negNsSet->value = NULL;
13591
13592
0
  return(0);
13593
0
    }
13594
    /*
13595
     * 5.
13596
     */
13597
0
    if (((completeWild->negNsSet != NULL) &&
13598
0
  (completeWild->negNsSet->value != NULL) &&
13599
0
  (curWild->nsSet != NULL)) ||
13600
0
  ((curWild->negNsSet != NULL) &&
13601
0
  (curWild->negNsSet->value != NULL) &&
13602
0
  (completeWild->nsSet != NULL))) {
13603
13604
0
  int nsFound, absentFound = 0;
13605
13606
0
  if (completeWild->nsSet != NULL) {
13607
0
      cur = completeWild->nsSet;
13608
0
      curB = curWild->negNsSet;
13609
0
  } else {
13610
0
      cur = curWild->nsSet;
13611
0
      curB = completeWild->negNsSet;
13612
0
  }
13613
0
  nsFound = 0;
13614
0
  while (cur != NULL) {
13615
0
      if (cur->value == NULL)
13616
0
    absentFound = 1;
13617
0
      else if (cur->value == curB->value)
13618
0
    nsFound = 1;
13619
0
      if (nsFound && absentFound)
13620
0
    break;
13621
0
      cur = cur->next;
13622
0
  }
13623
13624
0
  if (nsFound && absentFound) {
13625
      /*
13626
      * 5.1 If the set S includes both the negated namespace
13627
      * name and `absent`, then any must be the value.
13628
      */
13629
0
      completeWild->any = 1;
13630
0
      if (completeWild->nsSet != NULL) {
13631
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13632
0
    completeWild->nsSet = NULL;
13633
0
      }
13634
0
      if (completeWild->negNsSet != NULL) {
13635
0
    xmlFree(completeWild->negNsSet);
13636
0
    completeWild->negNsSet = NULL;
13637
0
      }
13638
0
  } else if (nsFound && (!absentFound)) {
13639
      /*
13640
      * 5.2 If the set S includes the negated namespace name
13641
      * but not `absent`, then a pair of not and `absent` must
13642
      * be the value.
13643
      */
13644
0
      if (completeWild->nsSet != NULL) {
13645
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13646
0
    completeWild->nsSet = NULL;
13647
0
      }
13648
0
      if (completeWild->negNsSet == NULL) {
13649
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13650
0
    if (completeWild->negNsSet == NULL)
13651
0
        return (-1);
13652
0
      }
13653
0
      completeWild->negNsSet->value = NULL;
13654
0
  } else if ((!nsFound) && absentFound) {
13655
      /*
13656
      * 5.3 If the set S includes `absent` but not the negated
13657
      * namespace name, then the union is not expressible.
13658
      */
13659
0
      xmlSchemaPErr(ctxt, completeWild->node,
13660
0
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13661
0
    "The union of the wildcard is not expressible.\n",
13662
0
    NULL, NULL);
13663
0
      return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13664
0
  } else if ((!nsFound) && (!absentFound)) {
13665
      /*
13666
      * 5.4 If the set S does not include either the negated namespace
13667
      * name or `absent`, then whichever of O1 or O2 is a pair of not
13668
      * and a namespace name must be the value.
13669
      */
13670
0
      if (completeWild->negNsSet == NULL) {
13671
0
    if (completeWild->nsSet != NULL) {
13672
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13673
0
        completeWild->nsSet = NULL;
13674
0
    }
13675
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13676
0
    if (completeWild->negNsSet == NULL)
13677
0
        return (-1);
13678
0
    completeWild->negNsSet->value = curWild->negNsSet->value;
13679
0
      }
13680
0
  }
13681
0
  return (0);
13682
0
    }
13683
    /*
13684
     * 6.
13685
     */
13686
0
    if (((completeWild->negNsSet != NULL) &&
13687
0
  (completeWild->negNsSet->value == NULL) &&
13688
0
  (curWild->nsSet != NULL)) ||
13689
0
  ((curWild->negNsSet != NULL) &&
13690
0
  (curWild->negNsSet->value == NULL) &&
13691
0
  (completeWild->nsSet != NULL))) {
13692
13693
0
  if (completeWild->nsSet != NULL) {
13694
0
      cur = completeWild->nsSet;
13695
0
  } else {
13696
0
      cur = curWild->nsSet;
13697
0
  }
13698
0
  while (cur != NULL) {
13699
0
      if (cur->value == NULL) {
13700
    /*
13701
    * 6.1 If the set S includes `absent`, then any must be the
13702
    * value.
13703
    */
13704
0
    completeWild->any = 1;
13705
0
    if (completeWild->nsSet != NULL) {
13706
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13707
0
        completeWild->nsSet = NULL;
13708
0
    }
13709
0
    if (completeWild->negNsSet != NULL) {
13710
0
        xmlFree(completeWild->negNsSet);
13711
0
        completeWild->negNsSet = NULL;
13712
0
    }
13713
0
    return (0);
13714
0
      }
13715
0
      cur = cur->next;
13716
0
  }
13717
0
  if (completeWild->negNsSet == NULL) {
13718
      /*
13719
      * 6.2 If the set S does not include `absent`, then a pair of not
13720
      * and `absent` must be the value.
13721
      */
13722
0
      if (completeWild->nsSet != NULL) {
13723
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13724
0
    completeWild->nsSet = NULL;
13725
0
      }
13726
0
      completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13727
0
      if (completeWild->negNsSet == NULL)
13728
0
    return (-1);
13729
0
      completeWild->negNsSet->value = NULL;
13730
0
  }
13731
0
  return (0);
13732
0
    }
13733
0
    return (0);
13734
13735
0
}
13736
13737
/**
13738
 * xmlSchemaIntersectWildcards:
13739
 * @ctxt:  the schema parser context
13740
 * @completeWild:  the first wildcard
13741
 * @curWild: the second wildcard
13742
 *
13743
 * Intersects the namespace constraints of the given wildcards.
13744
 * @completeWild will hold the resulting intersection.
13745
 * Returns a positive error code on failure, -1 in case of an
13746
 * internal error, 0 otherwise.
13747
 */
13748
static int
13749
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13750
          xmlSchemaWildcardPtr completeWild,
13751
          xmlSchemaWildcardPtr curWild)
13752
0
{
13753
0
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13754
13755
    /*
13756
    * 1 If O1 and O2 are the same value, then that value must be the
13757
    * value.
13758
    */
13759
0
    if ((completeWild->any == curWild->any) &&
13760
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13761
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13762
13763
0
  if ((completeWild->negNsSet == NULL) ||
13764
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13765
13766
0
      if (completeWild->nsSet != NULL) {
13767
0
    int found = 0;
13768
13769
    /*
13770
    * Check equality of sets.
13771
    */
13772
0
    cur = completeWild->nsSet;
13773
0
    while (cur != NULL) {
13774
0
        found = 0;
13775
0
        curB = curWild->nsSet;
13776
0
        while (curB != NULL) {
13777
0
      if (cur->value == curB->value) {
13778
0
          found = 1;
13779
0
          break;
13780
0
      }
13781
0
      curB = curB->next;
13782
0
        }
13783
0
        if (!found)
13784
0
      break;
13785
0
        cur = cur->next;
13786
0
    }
13787
0
    if (found)
13788
0
        return(0);
13789
0
      } else
13790
0
    return(0);
13791
0
  }
13792
0
    }
13793
    /*
13794
    * 2 If either O1 or O2 is any, then the other must be the value.
13795
    */
13796
0
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
13797
0
  if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13798
0
      return(-1);
13799
0
  return(0);
13800
0
    }
13801
    /*
13802
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
13803
    * name or `absent`) and the other is a set of (namespace names or
13804
    * `absent`), then that set, minus the negated value if it was in
13805
    * the set, minus `absent` if it was in the set, must be the value.
13806
    */
13807
0
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13808
0
  ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13809
0
  const xmlChar *neg;
13810
13811
0
  if (completeWild->nsSet == NULL) {
13812
0
      neg = completeWild->negNsSet->value;
13813
0
      if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13814
0
    return(-1);
13815
0
  } else
13816
0
      neg = curWild->negNsSet->value;
13817
  /*
13818
  * Remove absent and negated.
13819
  */
13820
0
  prev = NULL;
13821
0
  cur = completeWild->nsSet;
13822
0
  while (cur != NULL) {
13823
0
      if (cur->value == NULL) {
13824
0
    if (prev == NULL)
13825
0
        completeWild->nsSet = cur->next;
13826
0
    else
13827
0
        prev->next = cur->next;
13828
0
    xmlFree(cur);
13829
0
    break;
13830
0
      }
13831
0
      prev = cur;
13832
0
      cur = cur->next;
13833
0
  }
13834
0
  if (neg != NULL) {
13835
0
      prev = NULL;
13836
0
      cur = completeWild->nsSet;
13837
0
      while (cur != NULL) {
13838
0
    if (cur->value == neg) {
13839
0
        if (prev == NULL)
13840
0
      completeWild->nsSet = cur->next;
13841
0
        else
13842
0
      prev->next = cur->next;
13843
0
        xmlFree(cur);
13844
0
        break;
13845
0
    }
13846
0
    prev = cur;
13847
0
    cur = cur->next;
13848
0
      }
13849
0
  }
13850
13851
0
  return(0);
13852
0
    }
13853
    /*
13854
    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13855
    * then the intersection of those sets must be the value.
13856
    */
13857
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13858
0
  int found;
13859
13860
0
  cur = completeWild->nsSet;
13861
0
  prev = NULL;
13862
0
  while (cur != NULL) {
13863
0
      found = 0;
13864
0
      curB = curWild->nsSet;
13865
0
      while (curB != NULL) {
13866
0
    if (cur->value == curB->value) {
13867
0
        found = 1;
13868
0
        break;
13869
0
    }
13870
0
    curB = curB->next;
13871
0
      }
13872
0
      if (!found) {
13873
0
    if (prev == NULL)
13874
0
        completeWild->nsSet = cur->next;
13875
0
    else
13876
0
        prev->next = cur->next;
13877
0
    tmp = cur->next;
13878
0
    xmlFree(cur);
13879
0
    cur = tmp;
13880
0
    continue;
13881
0
      }
13882
0
      prev = cur;
13883
0
      cur = cur->next;
13884
0
  }
13885
13886
0
  return(0);
13887
0
    }
13888
    /* 5 If the two are negations of different namespace names,
13889
    * then the intersection is not expressible
13890
    */
13891
0
    if ((completeWild->negNsSet != NULL) &&
13892
0
  (curWild->negNsSet != NULL) &&
13893
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13894
0
  (completeWild->negNsSet->value != NULL) &&
13895
0
  (curWild->negNsSet->value != NULL)) {
13896
13897
0
  xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13898
0
      "The intersection of the wildcard is not expressible.\n",
13899
0
      NULL, NULL);
13900
0
  return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13901
0
    }
13902
    /*
13903
    * 6 If the one is a negation of a namespace name and the other
13904
    * is a negation of `absent`, then the one which is the negation
13905
    * of a namespace name must be the value.
13906
    */
13907
0
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13908
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13909
0
  (completeWild->negNsSet->value == NULL)) {
13910
0
  completeWild->negNsSet->value =  curWild->negNsSet->value;
13911
0
    }
13912
0
    return(0);
13913
0
}
13914
13915
/**
13916
 * xmlSchemaIsWildcardNsConstraintSubset:
13917
 * @ctxt:  the schema parser context
13918
 * @sub:  the first wildcard
13919
 * @super: the second wildcard
13920
 *
13921
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13922
 *
13923
 * Returns 0 if the namespace constraint of @sub is an intensional
13924
 * subset of @super, 1 otherwise.
13925
 */
13926
static int
13927
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13928
        xmlSchemaWildcardPtr super)
13929
0
{
13930
    /*
13931
    * 1 super must be any.
13932
    */
13933
0
    if (super->any)
13934
0
  return (0);
13935
    /*
13936
    * 2.1 sub must be a pair of not and a namespace name or `absent`.
13937
    * 2.2 super must be a pair of not and the same value.
13938
    */
13939
0
    if ((sub->negNsSet != NULL) &&
13940
0
  (super->negNsSet != NULL) &&
13941
0
  (sub->negNsSet->value == super->negNsSet->value))
13942
0
  return (0);
13943
    /*
13944
    * 3.1 sub must be a set whose members are either namespace names or `absent`.
13945
    */
13946
0
    if (sub->nsSet != NULL) {
13947
  /*
13948
  * 3.2.1 super must be the same set or a superset thereof.
13949
  */
13950
0
  if (super->nsSet != NULL) {
13951
0
      xmlSchemaWildcardNsPtr cur, curB;
13952
0
      int found = 0;
13953
13954
0
      cur = sub->nsSet;
13955
0
      while (cur != NULL) {
13956
0
    found = 0;
13957
0
    curB = super->nsSet;
13958
0
    while (curB != NULL) {
13959
0
        if (cur->value == curB->value) {
13960
0
      found = 1;
13961
0
      break;
13962
0
        }
13963
0
        curB = curB->next;
13964
0
    }
13965
0
    if (!found)
13966
0
        return (1);
13967
0
    cur = cur->next;
13968
0
      }
13969
0
      if (found)
13970
0
    return (0);
13971
0
  } else if (super->negNsSet != NULL) {
13972
0
      xmlSchemaWildcardNsPtr cur;
13973
      /*
13974
      * 3.2.2 super must be a pair of not and a namespace name or
13975
      * `absent` and that value must not be in sub's set.
13976
      */
13977
0
      cur = sub->nsSet;
13978
0
      while (cur != NULL) {
13979
0
    if (cur->value == super->negNsSet->value)
13980
0
        return (1);
13981
0
    cur = cur->next;
13982
0
      }
13983
0
      return (0);
13984
0
  }
13985
0
    }
13986
0
    return (1);
13987
0
}
13988
13989
static int
13990
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13991
             int *fixed,
13992
             const xmlChar **value,
13993
             xmlSchemaValPtr *val)
13994
0
{
13995
0
    *fixed = 0;
13996
0
    *value = NULL;
13997
0
    if (val != 0)
13998
0
  *val = NULL;
13999
14000
0
    if (attruse->defValue != NULL) {
14001
0
  *value = attruse->defValue;
14002
0
  if (val != NULL)
14003
0
      *val = attruse->defVal;
14004
0
  if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14005
0
      *fixed = 1;
14006
0
  return(1);
14007
0
    } else if ((attruse->attrDecl != NULL) &&
14008
0
  (attruse->attrDecl->defValue != NULL)) {
14009
0
  *value = attruse->attrDecl->defValue;
14010
0
  if (val != NULL)
14011
0
      *val = attruse->attrDecl->defVal;
14012
0
  if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14013
0
      *fixed = 1;
14014
0
  return(1);
14015
0
    }
14016
0
    return(0);
14017
0
}
14018
/**
14019
 * xmlSchemaCheckCVCWildcardNamespace:
14020
 * @wild:  the wildcard
14021
 * @ns:  the namespace
14022
 *
14023
 * Validation Rule: Wildcard allows Namespace Name
14024
 * (cvc-wildcard-namespace)
14025
 *
14026
 * Returns 0 if the given namespace matches the wildcard,
14027
 * 1 otherwise and -1 on API errors.
14028
 */
14029
static int
14030
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14031
           const xmlChar* ns)
14032
0
{
14033
0
    if (wild == NULL)
14034
0
  return(-1);
14035
14036
0
    if (wild->any)
14037
0
  return(0);
14038
0
    else if (wild->nsSet != NULL) {
14039
0
  xmlSchemaWildcardNsPtr cur;
14040
14041
0
  cur = wild->nsSet;
14042
0
  while (cur != NULL) {
14043
0
      if (xmlStrEqual(cur->value, ns))
14044
0
    return(0);
14045
0
      cur = cur->next;
14046
0
  }
14047
0
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14048
0
  (!xmlStrEqual(wild->negNsSet->value, ns)))
14049
0
  return(0);
14050
14051
0
    return(1);
14052
0
}
14053
14054
0
#define XML_SCHEMA_ACTION_DERIVE 0
14055
0
#define XML_SCHEMA_ACTION_REDEFINE 1
14056
14057
0
#define WXS_ACTION_STR(a) \
14058
0
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14059
14060
/*
14061
* Schema Component Constraint:
14062
*   Derivation Valid (Restriction, Complex)
14063
*   derivation-ok-restriction (2) - (4)
14064
*
14065
* ATTENTION:
14066
* In XML Schema 1.1 this will be:
14067
* Validation Rule:
14068
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14069
*
14070
*/
14071
static int
14072
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14073
               int action,
14074
               xmlSchemaBasicItemPtr item,
14075
               xmlSchemaBasicItemPtr baseItem,
14076
               xmlSchemaItemListPtr uses,
14077
               xmlSchemaItemListPtr baseUses,
14078
               xmlSchemaWildcardPtr wild,
14079
               xmlSchemaWildcardPtr baseWild)
14080
0
{
14081
0
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
14082
0
    int i, j, found; /* err = 0; */
14083
0
    const xmlChar *bEffValue;
14084
0
    int effFixed;
14085
14086
0
    if (uses != NULL) {
14087
0
  for (i = 0; i < uses->nbItems; i++) {
14088
0
      cur = uses->items[i];
14089
0
      found = 0;
14090
0
      if (baseUses == NULL)
14091
0
    goto not_found;
14092
0
      for (j = 0; j < baseUses->nbItems; j++) {
14093
0
    bcur = baseUses->items[j];
14094
0
    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14095
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14096
0
        (WXS_ATTRUSE_DECL_TNS(cur) ==
14097
0
      WXS_ATTRUSE_DECL_TNS(bcur)))
14098
0
    {
14099
        /*
14100
        * (2.1) "If there is an attribute use in the {attribute
14101
        * uses} of the {base type definition} (call this B) whose
14102
        * {attribute declaration} has the same {name} and {target
14103
        * namespace}, then  all of the following must be true:"
14104
        */
14105
0
        found = 1;
14106
14107
0
        if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14108
0
      (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14109
0
        {
14110
0
      xmlChar *str = NULL;
14111
      /*
14112
      * (2.1.1) "one of the following must be true:"
14113
      * (2.1.1.1) "B's {required} is false."
14114
      * (2.1.1.2) "R's {required} is true."
14115
      */
14116
0
      xmlSchemaPAttrUseErr4(pctxt,
14117
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14118
0
          WXS_ITEM_NODE(item), item, cur,
14119
0
          "The 'optional' attribute use is inconsistent "
14120
0
          "with the corresponding 'required' attribute use of "
14121
0
          "the %s %s",
14122
0
          WXS_ACTION_STR(action),
14123
0
          xmlSchemaGetComponentDesignation(&str, baseItem),
14124
0
          NULL, NULL);
14125
0
      FREE_AND_NULL(str);
14126
      /* err = pctxt->err; */
14127
0
        } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14128
0
      WXS_ATTRUSE_TYPEDEF(cur),
14129
0
      WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14130
0
        {
14131
0
      xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14132
14133
      /*
14134
      * SPEC (2.1.2) "R's {attribute declaration}'s
14135
      * {type definition} must be validly derived from
14136
      * B's {type definition} given the empty set as
14137
      * defined in Type Derivation OK (Simple) ($3.14.6)."
14138
      */
14139
0
      xmlSchemaPAttrUseErr4(pctxt,
14140
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14141
0
          WXS_ITEM_NODE(item), item, cur,
14142
0
          "The attribute declaration's %s "
14143
0
          "is not validly derived from "
14144
0
          "the corresponding %s of the "
14145
0
          "attribute declaration in the %s %s",
14146
0
          xmlSchemaGetComponentDesignation(&strA,
14147
0
        WXS_ATTRUSE_TYPEDEF(cur)),
14148
0
          xmlSchemaGetComponentDesignation(&strB,
14149
0
        WXS_ATTRUSE_TYPEDEF(bcur)),
14150
0
          WXS_ACTION_STR(action),
14151
0
          xmlSchemaGetComponentDesignation(&strC, baseItem));
14152
          /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14153
0
      FREE_AND_NULL(strA);
14154
0
      FREE_AND_NULL(strB);
14155
0
      FREE_AND_NULL(strC);
14156
      /* err = pctxt->err; */
14157
0
        } else {
14158
      /*
14159
      * 2.1.3 [Definition:]  Let the effective value
14160
      * constraint of an attribute use be its {value
14161
      * constraint}, if present, otherwise its {attribute
14162
      * declaration}'s {value constraint} .
14163
      */
14164
0
      xmlSchemaGetEffectiveValueConstraint(bcur,
14165
0
          &effFixed, &bEffValue, NULL);
14166
      /*
14167
      * 2.1.3 ... one of the following must be true
14168
      *
14169
      * 2.1.3.1 B's `effective value constraint` is
14170
      * `absent` or default.
14171
      */
14172
0
      if ((bEffValue != NULL) &&
14173
0
          (effFixed == 1)) {
14174
0
          const xmlChar *rEffValue = NULL;
14175
14176
0
          xmlSchemaGetEffectiveValueConstraint(bcur,
14177
0
        &effFixed, &rEffValue, NULL);
14178
          /*
14179
          * 2.1.3.2 R's `effective value constraint` is
14180
          * fixed with the same string as B's.
14181
          * MAYBE TODO: Compare the computed values.
14182
          *       Hmm, it says "same string" so
14183
          *       string-equality might really be sufficient.
14184
          */
14185
0
          if ((effFixed == 0) ||
14186
0
        (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14187
0
          {
14188
0
        xmlChar *str = NULL;
14189
14190
0
        xmlSchemaPAttrUseErr4(pctxt,
14191
0
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14192
0
            WXS_ITEM_NODE(item), item, cur,
14193
0
            "The effective value constraint of the "
14194
0
            "attribute use is inconsistent with "
14195
0
            "its correspondent in the %s %s",
14196
0
            WXS_ACTION_STR(action),
14197
0
            xmlSchemaGetComponentDesignation(&str,
14198
0
          baseItem),
14199
0
            NULL, NULL);
14200
0
        FREE_AND_NULL(str);
14201
        /* err = pctxt->err; */
14202
0
          }
14203
0
      }
14204
0
        }
14205
0
        break;
14206
0
    }
14207
0
      }
14208
0
not_found:
14209
0
      if (!found) {
14210
    /*
14211
    * (2.2) "otherwise the {base type definition} must have an
14212
    * {attribute wildcard} and the {target namespace} of the
14213
    * R's {attribute declaration} must be `valid` with respect
14214
    * to that wildcard, as defined in Wildcard allows Namespace
14215
    * Name ($3.10.4)."
14216
    */
14217
0
    if ((baseWild == NULL) ||
14218
0
        (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14219
0
        (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14220
0
    {
14221
0
        xmlChar *str = NULL;
14222
14223
0
        xmlSchemaPAttrUseErr4(pctxt,
14224
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14225
0
      WXS_ITEM_NODE(item), item, cur,
14226
0
      "Neither a matching attribute use, "
14227
0
      "nor a matching wildcard exists in the %s %s",
14228
0
      WXS_ACTION_STR(action),
14229
0
      xmlSchemaGetComponentDesignation(&str, baseItem),
14230
0
      NULL, NULL);
14231
0
        FREE_AND_NULL(str);
14232
        /* err = pctxt->err; */
14233
0
    }
14234
0
      }
14235
0
  }
14236
0
    }
14237
    /*
14238
    * SPEC derivation-ok-restriction (3):
14239
    * (3) "For each attribute use in the {attribute uses} of the {base type
14240
    * definition} whose {required} is true, there must be an attribute
14241
    * use with an {attribute declaration} with the same {name} and
14242
    * {target namespace} as its {attribute declaration} in the {attribute
14243
    * uses} of the complex type definition itself whose {required} is true.
14244
    */
14245
0
    if (baseUses != NULL) {
14246
0
  for (j = 0; j < baseUses->nbItems; j++) {
14247
0
      bcur = baseUses->items[j];
14248
0
      if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14249
0
    continue;
14250
0
      found = 0;
14251
0
      if (uses != NULL) {
14252
0
    for (i = 0; i < uses->nbItems; i++) {
14253
0
        cur = uses->items[i];
14254
0
        if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14255
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14256
0
      (WXS_ATTRUSE_DECL_TNS(cur) ==
14257
0
      WXS_ATTRUSE_DECL_TNS(bcur))) {
14258
0
      found = 1;
14259
0
      break;
14260
0
        }
14261
0
    }
14262
0
      }
14263
0
      if (!found) {
14264
0
    xmlChar *strA = NULL, *strB = NULL;
14265
14266
0
    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14267
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14268
0
        NULL, item,
14269
0
        "A matching attribute use for the "
14270
0
        "'required' %s of the %s %s is missing",
14271
0
        xmlSchemaGetComponentDesignation(&strA, bcur),
14272
0
        WXS_ACTION_STR(action),
14273
0
        xmlSchemaGetComponentDesignation(&strB, baseItem),
14274
0
        NULL);
14275
0
    FREE_AND_NULL(strA);
14276
0
    FREE_AND_NULL(strB);
14277
0
      }
14278
0
  }
14279
0
    }
14280
    /*
14281
    * derivation-ok-restriction (4)
14282
    */
14283
0
    if (wild != NULL) {
14284
  /*
14285
  * (4) "If there is an {attribute wildcard}, all of the
14286
  * following must be true:"
14287
  */
14288
0
  if (baseWild == NULL) {
14289
0
      xmlChar *str = NULL;
14290
14291
      /*
14292
      * (4.1) "The {base type definition} must also have one."
14293
      */
14294
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14295
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14296
0
    NULL, item,
14297
0
    "The %s has an attribute wildcard, "
14298
0
    "but the %s %s '%s' does not have one",
14299
0
    WXS_ITEM_TYPE_NAME(item),
14300
0
    WXS_ACTION_STR(action),
14301
0
    WXS_ITEM_TYPE_NAME(baseItem),
14302
0
    xmlSchemaGetComponentQName(&str, baseItem));
14303
0
      FREE_AND_NULL(str);
14304
0
      return(pctxt->err);
14305
0
  } else if ((baseWild->any == 0) &&
14306
0
    xmlSchemaCheckCOSNSSubset(wild, baseWild))
14307
0
  {
14308
0
      xmlChar *str = NULL;
14309
      /*
14310
      * (4.2) "The complex type definition's {attribute wildcard}'s
14311
      * {namespace constraint} must be a subset of the {base type
14312
      * definition}'s {attribute wildcard}'s {namespace constraint},
14313
      * as defined by Wildcard Subset ($3.10.6)."
14314
      */
14315
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14316
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14317
0
    NULL, item,
14318
0
    "The attribute wildcard is not a valid "
14319
0
    "subset of the wildcard in the %s %s '%s'",
14320
0
    WXS_ACTION_STR(action),
14321
0
    WXS_ITEM_TYPE_NAME(baseItem),
14322
0
    xmlSchemaGetComponentQName(&str, baseItem),
14323
0
    NULL);
14324
0
      FREE_AND_NULL(str);
14325
0
      return(pctxt->err);
14326
0
  }
14327
  /* 4.3 Unless the {base type definition} is the `ur-type
14328
  * definition`, the complex type definition's {attribute
14329
  * wildcard}'s {process contents} must be identical to or
14330
  * stronger than the {base type definition}'s {attribute
14331
  * wildcard}'s {process contents}, where strict is stronger
14332
  * than lax is stronger than skip.
14333
  */
14334
0
  if ((! WXS_IS_ANYTYPE(baseItem)) &&
14335
0
      (wild->processContents < baseWild->processContents)) {
14336
0
      xmlChar *str = NULL;
14337
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14338
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14339
0
    NULL, baseItem,
14340
0
    "The {process contents} of the attribute wildcard is "
14341
0
    "weaker than the one in the %s %s '%s'",
14342
0
    WXS_ACTION_STR(action),
14343
0
    WXS_ITEM_TYPE_NAME(baseItem),
14344
0
    xmlSchemaGetComponentQName(&str, baseItem),
14345
0
    NULL);
14346
0
      FREE_AND_NULL(str)
14347
0
    return(pctxt->err);
14348
0
  }
14349
0
    }
14350
0
    return(0);
14351
0
}
14352
14353
14354
static int
14355
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14356
          xmlSchemaBasicItemPtr item,
14357
          xmlSchemaWildcardPtr *completeWild,
14358
          xmlSchemaItemListPtr list,
14359
          xmlSchemaItemListPtr prohibs);
14360
/**
14361
 * xmlSchemaFixupTypeAttributeUses:
14362
 * @ctxt:  the schema parser context
14363
 * @type:  the complex type definition
14364
 *
14365
 *
14366
 * Builds the wildcard and the attribute uses on the given complex type.
14367
 * Returns -1 if an internal error occurs, 0 otherwise.
14368
 *
14369
 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14370
 * strings, so recheck this if we start to hardcode some schemata, since
14371
 * they might not be in the same dict.
14372
 * NOTE: It is allowed to "extend" the xs:anyType type.
14373
 */
14374
static int
14375
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14376
          xmlSchemaTypePtr type)
14377
0
{
14378
0
    xmlSchemaTypePtr baseType = NULL;
14379
0
    xmlSchemaAttributeUsePtr use;
14380
0
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14381
14382
0
    if (type->baseType == NULL) {
14383
0
  PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14384
0
      "no base type");
14385
0
        return (-1);
14386
0
    }
14387
0
    baseType = type->baseType;
14388
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14389
0
  if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14390
0
      return(-1);
14391
14392
0
    uses = type->attrUses;
14393
0
    baseUses = baseType->attrUses;
14394
    /*
14395
    * Expand attribute group references. And build the 'complete'
14396
    * wildcard, i.e. intersect multiple wildcards.
14397
    * Move attribute prohibitions into a separate list.
14398
    */
14399
0
    if (uses != NULL) {
14400
0
  if (WXS_IS_RESTRICTION(type)) {
14401
      /*
14402
      * This one will transfer all attr. prohibitions
14403
      * into pctxt->attrProhibs.
14404
      */
14405
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14406
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14407
0
    pctxt->attrProhibs) == -1)
14408
0
      {
14409
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14410
0
    "failed to expand attributes");
14411
0
                return(-1);
14412
0
      }
14413
0
      if (pctxt->attrProhibs->nbItems != 0)
14414
0
    prohibs = pctxt->attrProhibs;
14415
0
  } else {
14416
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14417
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14418
0
    NULL) == -1)
14419
0
      {
14420
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14421
0
    "failed to expand attributes");
14422
0
                return(-1);
14423
0
      }
14424
0
  }
14425
0
    }
14426
    /*
14427
    * Inherit the attribute uses of the base type.
14428
    */
14429
0
    if (baseUses != NULL) {
14430
0
  int i, j;
14431
0
  xmlSchemaAttributeUseProhibPtr pro;
14432
14433
0
  if (WXS_IS_RESTRICTION(type)) {
14434
0
      int usesCount;
14435
0
      xmlSchemaAttributeUsePtr tmp;
14436
14437
0
      if (uses != NULL)
14438
0
    usesCount = uses->nbItems;
14439
0
      else
14440
0
    usesCount = 0;
14441
14442
      /* Restriction. */
14443
0
      for (i = 0; i < baseUses->nbItems; i++) {
14444
0
    use = baseUses->items[i];
14445
0
    if (prohibs) {
14446
        /*
14447
        * Filter out prohibited uses.
14448
        */
14449
0
        for (j = 0; j < prohibs->nbItems; j++) {
14450
0
      pro = prohibs->items[j];
14451
0
      if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14452
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14453
0
        pro->targetNamespace))
14454
0
      {
14455
0
          goto inherit_next;
14456
0
      }
14457
0
        }
14458
0
    }
14459
0
    if (usesCount) {
14460
        /*
14461
        * Filter out existing uses.
14462
        */
14463
0
        for (j = 0; j < usesCount; j++) {
14464
0
      tmp = uses->items[j];
14465
0
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
14466
0
        WXS_ATTRUSE_DECL_NAME(tmp)) &&
14467
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14468
0
        WXS_ATTRUSE_DECL_TNS(tmp)))
14469
0
      {
14470
0
          goto inherit_next;
14471
0
      }
14472
0
        }
14473
0
    }
14474
0
    if (uses == NULL) {
14475
0
        type->attrUses = xmlSchemaItemListCreate();
14476
0
        if (type->attrUses == NULL)
14477
0
      goto exit_failure;
14478
0
        uses = type->attrUses;
14479
0
    }
14480
0
    xmlSchemaItemListAddSize(uses, 2, use);
14481
0
inherit_next: {}
14482
0
      }
14483
0
  } else {
14484
      /* Extension. */
14485
0
      for (i = 0; i < baseUses->nbItems; i++) {
14486
0
    use = baseUses->items[i];
14487
0
    if (uses == NULL) {
14488
0
        type->attrUses = xmlSchemaItemListCreate();
14489
0
        if (type->attrUses == NULL)
14490
0
      goto exit_failure;
14491
0
        uses = type->attrUses;
14492
0
    }
14493
0
    xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14494
0
      }
14495
0
  }
14496
0
    }
14497
    /*
14498
    * Shrink attr. uses.
14499
    */
14500
0
    if (uses) {
14501
0
  if (uses->nbItems == 0) {
14502
0
      xmlSchemaItemListFree(uses);
14503
0
      type->attrUses = NULL;
14504
0
  }
14505
  /*
14506
  * TODO: We could shrink the size of the array
14507
  * to fit the actual number of items.
14508
  */
14509
0
    }
14510
    /*
14511
    * Compute the complete wildcard.
14512
    */
14513
0
    if (WXS_IS_EXTENSION(type)) {
14514
0
  if (baseType->attributeWildcard != NULL) {
14515
      /*
14516
      * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14517
      * the appropriate case among the following:"
14518
      */
14519
0
      if (type->attributeWildcard != NULL) {
14520
    /*
14521
    * Union the complete wildcard with the base wildcard.
14522
    * SPEC {attribute wildcard}
14523
    * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14524
    * and {annotation} are those of the `complete wildcard`,
14525
    * and whose {namespace constraint} is the intensional union
14526
    * of the {namespace constraint} of the `complete wildcard`
14527
    * and of the `base wildcard`, as defined in Attribute
14528
    * Wildcard Union ($3.10.6)."
14529
    */
14530
0
    if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14531
0
        baseType->attributeWildcard) == -1)
14532
0
        goto exit_failure;
14533
0
      } else {
14534
    /*
14535
    * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14536
    * then the `base wildcard`."
14537
    */
14538
0
    type->attributeWildcard = baseType->attributeWildcard;
14539
0
      }
14540
0
  } else {
14541
      /*
14542
      * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14543
      * `complete wildcard`"
14544
      * NOOP
14545
      */
14546
0
  }
14547
0
    } else {
14548
  /*
14549
  * SPEC {attribute wildcard}
14550
  * (3.1) "If the <restriction> alternative is chosen, then the
14551
  * `complete wildcard`;"
14552
  * NOOP
14553
  */
14554
0
    }
14555
14556
0
    return (0);
14557
14558
0
exit_failure:
14559
0
    return(-1);
14560
0
}
14561
14562
/**
14563
 * xmlSchemaTypeFinalContains:
14564
 * @schema:  the schema
14565
 * @type:  the type definition
14566
 * @final: the final
14567
 *
14568
 * Evaluates if a type definition contains the given "final".
14569
 * This does take "finalDefault" into account as well.
14570
 *
14571
 * Returns 1 if the type does contain the given "final",
14572
 * 0 otherwise.
14573
 */
14574
static int
14575
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14576
0
{
14577
0
    if (type == NULL)
14578
0
  return (0);
14579
0
    if (type->flags & final)
14580
0
  return (1);
14581
0
    else
14582
0
  return (0);
14583
0
}
14584
14585
/**
14586
 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14587
 * @type:  the Union Simple Type
14588
 *
14589
 * Returns a list of member types of @type if existing,
14590
 * returns NULL otherwise.
14591
 */
14592
static xmlSchemaTypeLinkPtr
14593
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14594
0
{
14595
0
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14596
0
  if (type->memberTypes != NULL)
14597
0
      return (type->memberTypes);
14598
0
  else
14599
0
      type = type->baseType;
14600
0
    }
14601
0
    return (NULL);
14602
0
}
14603
14604
#if 0
14605
/**
14606
 * xmlSchemaGetParticleTotalRangeMin:
14607
 * @particle: the particle
14608
 *
14609
 * Schema Component Constraint: Effective Total Range
14610
 * (all and sequence) + (choice)
14611
 *
14612
 * Returns the minimum Effective Total Range.
14613
 */
14614
static int
14615
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14616
{
14617
    if ((particle->children == NULL) ||
14618
  (particle->minOccurs == 0))
14619
  return (0);
14620
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14621
  int min = -1, cur;
14622
  xmlSchemaParticlePtr part =
14623
      (xmlSchemaParticlePtr) particle->children->children;
14624
14625
  if (part == NULL)
14626
      return (0);
14627
  while (part != NULL) {
14628
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14629
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14630
    cur = part->minOccurs;
14631
      else
14632
    cur = xmlSchemaGetParticleTotalRangeMin(part);
14633
      if (cur == 0)
14634
    return (0);
14635
      if ((min > cur) || (min == -1))
14636
    min = cur;
14637
      part = (xmlSchemaParticlePtr) part->next;
14638
  }
14639
  return (particle->minOccurs * min);
14640
    } else {
14641
  /* <all> and <sequence> */
14642
  int sum = 0;
14643
  xmlSchemaParticlePtr part =
14644
      (xmlSchemaParticlePtr) particle->children->children;
14645
14646
  if (part == NULL)
14647
      return (0);
14648
  do {
14649
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14650
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14651
    sum += part->minOccurs;
14652
      else
14653
    sum += xmlSchemaGetParticleTotalRangeMin(part);
14654
      part = (xmlSchemaParticlePtr) part->next;
14655
  } while (part != NULL);
14656
  return (particle->minOccurs * sum);
14657
    }
14658
}
14659
14660
/**
14661
 * xmlSchemaGetParticleTotalRangeMax:
14662
 * @particle: the particle
14663
 *
14664
 * Schema Component Constraint: Effective Total Range
14665
 * (all and sequence) + (choice)
14666
 *
14667
 * Returns the maximum Effective Total Range.
14668
 */
14669
static int
14670
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14671
{
14672
    if ((particle->children == NULL) ||
14673
  (particle->children->children == NULL))
14674
  return (0);
14675
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14676
  int max = -1, cur;
14677
  xmlSchemaParticlePtr part =
14678
      (xmlSchemaParticlePtr) particle->children->children;
14679
14680
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14681
      if (part->children == NULL)
14682
    continue;
14683
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14684
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14685
    cur = part->maxOccurs;
14686
      else
14687
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14688
      if (cur == UNBOUNDED)
14689
    return (UNBOUNDED);
14690
      if ((max < cur) || (max == -1))
14691
    max = cur;
14692
  }
14693
  /* TODO: Handle overflows? */
14694
  return (particle->maxOccurs * max);
14695
    } else {
14696
  /* <all> and <sequence> */
14697
  int sum = 0, cur;
14698
  xmlSchemaParticlePtr part =
14699
      (xmlSchemaParticlePtr) particle->children->children;
14700
14701
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14702
      if (part->children == NULL)
14703
    continue;
14704
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14705
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14706
    cur = part->maxOccurs;
14707
      else
14708
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14709
      if (cur == UNBOUNDED)
14710
    return (UNBOUNDED);
14711
      if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14712
    return (UNBOUNDED);
14713
      sum += cur;
14714
  }
14715
  /* TODO: Handle overflows? */
14716
  return (particle->maxOccurs * sum);
14717
    }
14718
}
14719
#endif
14720
14721
/**
14722
 * xmlSchemaGetParticleEmptiable:
14723
 * @particle: the particle
14724
 *
14725
 * Returns 1 if emptiable, 0 otherwise.
14726
 */
14727
static int
14728
xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14729
0
{
14730
0
    xmlSchemaParticlePtr part;
14731
0
    int emptiable;
14732
14733
0
    if ((particle->children == NULL) || (particle->minOccurs == 0))
14734
0
  return (1);
14735
14736
0
    part = (xmlSchemaParticlePtr) particle->children->children;
14737
0
    if (part == NULL)
14738
0
        return (1);
14739
14740
0
    while (part != NULL) {
14741
0
        if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14742
0
            (part->children->type == XML_SCHEMA_TYPE_ANY))
14743
0
            emptiable = (part->minOccurs == 0);
14744
0
        else
14745
0
            emptiable = xmlSchemaGetParticleEmptiable(part);
14746
0
        if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14747
0
            if (emptiable)
14748
0
                return (1);
14749
0
        } else {
14750
      /* <all> and <sequence> */
14751
0
            if (!emptiable)
14752
0
                return (0);
14753
0
        }
14754
0
        part = (xmlSchemaParticlePtr) part->next;
14755
0
    }
14756
14757
0
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14758
0
        return (0);
14759
0
    else
14760
0
        return (1);
14761
0
}
14762
14763
/**
14764
 * xmlSchemaIsParticleEmptiable:
14765
 * @particle: the particle
14766
 *
14767
 * Schema Component Constraint: Particle Emptiable
14768
 * Checks whether the given particle is emptiable.
14769
 *
14770
 * Returns 1 if emptiable, 0 otherwise.
14771
 */
14772
static int
14773
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14774
0
{
14775
    /*
14776
    * SPEC (1) "Its {min occurs} is 0."
14777
    */
14778
0
    if ((particle == NULL) || (particle->minOccurs == 0) ||
14779
0
  (particle->children == NULL))
14780
0
  return (1);
14781
    /*
14782
    * SPEC (2) "Its {term} is a group and the minimum part of the
14783
    * effective total range of that group, [...] is 0."
14784
    */
14785
0
    if (WXS_IS_MODEL_GROUP(particle->children))
14786
0
  return (xmlSchemaGetParticleEmptiable(particle));
14787
0
    return (0);
14788
0
}
14789
14790
/**
14791
 * xmlSchemaCheckCOSSTDerivedOK:
14792
 * @actxt: a context
14793
 * @type:  the derived simple type definition
14794
 * @baseType:  the base type definition
14795
 * @subset: the subset of ('restriction', etc.)
14796
 *
14797
 * Schema Component Constraint:
14798
 * Type Derivation OK (Simple) (cos-st-derived-OK)
14799
 *
14800
 * Checks whether @type can be validly
14801
 * derived from @baseType.
14802
 *
14803
 * Returns 0 on success, an positive error code otherwise.
14804
 */
14805
static int
14806
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14807
           xmlSchemaTypePtr type,
14808
           xmlSchemaTypePtr baseType,
14809
           int subset)
14810
0
{
14811
    /*
14812
    * 1 They are the same type definition.
14813
    * TODO: The identity check might have to be more complex than this.
14814
    */
14815
0
    if (type == baseType)
14816
0
  return (0);
14817
    /*
14818
    * 2.1 restriction is not in the subset, or in the {final}
14819
    * of its own {base type definition};
14820
    *
14821
    * NOTE that this will be used also via "xsi:type".
14822
    *
14823
    * TODO: Revise this, it looks strange. How can the "type"
14824
    * not be fixed or *in* fixing?
14825
    */
14826
0
    if (WXS_IS_TYPE_NOT_FIXED(type))
14827
0
  if (xmlSchemaTypeFixup(type, actxt) == -1)
14828
0
      return(-1);
14829
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14830
0
  if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14831
0
      return(-1);
14832
0
    if ((subset & SUBSET_RESTRICTION) ||
14833
0
  (xmlSchemaTypeFinalContains(type->baseType,
14834
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14835
0
  return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14836
0
    }
14837
    /* 2.2 */
14838
0
    if (type->baseType == baseType) {
14839
  /*
14840
  * 2.2.1 D's `base type definition` is B.
14841
  */
14842
0
  return (0);
14843
0
    }
14844
    /*
14845
    * 2.2.2 D's `base type definition` is not the `ur-type definition`
14846
    * and is validly derived from B given the subset, as defined by this
14847
    * constraint.
14848
    */
14849
0
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14850
0
  (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14851
0
      baseType, subset) == 0)) {
14852
0
  return (0);
14853
0
    }
14854
    /*
14855
    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14856
    * definition`.
14857
    */
14858
0
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14859
0
  (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14860
0
  return (0);
14861
0
    }
14862
    /*
14863
    * 2.2.4 B's {variety} is union and D is validly derived from a type
14864
    * definition in B's {member type definitions} given the subset, as
14865
    * defined by this constraint.
14866
    *
14867
    * NOTE: This seems not to involve built-in types, since there is no
14868
    * built-in Union Simple Type.
14869
    */
14870
0
    if (WXS_IS_UNION(baseType)) {
14871
0
  xmlSchemaTypeLinkPtr cur;
14872
14873
0
  cur = baseType->memberTypes;
14874
0
  while (cur != NULL) {
14875
0
      if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14876
0
    if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14877
0
        return(-1);
14878
0
      if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14879
0
        type, cur->type, subset) == 0)
14880
0
      {
14881
    /*
14882
    * It just has to be validly derived from at least one
14883
    * member-type.
14884
    */
14885
0
    return (0);
14886
0
      }
14887
0
      cur = cur->next;
14888
0
  }
14889
0
    }
14890
0
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14891
0
}
14892
14893
/**
14894
 * xmlSchemaCheckTypeDefCircularInternal:
14895
 * @pctxt:  the schema parser context
14896
 * @ctxtType:  the type definition
14897
 * @ancestor: an ancestor of @ctxtType
14898
 *
14899
 * Checks st-props-correct (2) + ct-props-correct (3).
14900
 * Circular type definitions are not allowed.
14901
 *
14902
 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14903
 * circular, 0 otherwise.
14904
 */
14905
static int
14906
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14907
         xmlSchemaTypePtr ctxtType,
14908
         xmlSchemaTypePtr ancestor)
14909
0
{
14910
0
    int ret;
14911
14912
0
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14913
0
  return (0);
14914
14915
0
    if (ctxtType == ancestor) {
14916
0
  xmlSchemaPCustomErr(pctxt,
14917
0
      XML_SCHEMAP_ST_PROPS_CORRECT_2,
14918
0
      WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14919
0
      "The definition is circular", NULL);
14920
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14921
0
    }
14922
0
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14923
  /*
14924
  * Avoid infinite recursion on circular types not yet checked.
14925
  */
14926
0
  return (0);
14927
0
    }
14928
0
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14929
0
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14930
0
  ancestor->baseType);
14931
0
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14932
0
    return (ret);
14933
0
}
14934
14935
/**
14936
 * xmlSchemaCheckTypeDefCircular:
14937
 * @item:  the complex/simple type definition
14938
 * @ctxt:  the parser context
14939
 * @name:  the name
14940
 *
14941
 * Checks for circular type definitions.
14942
 */
14943
static void
14944
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14945
            xmlSchemaParserCtxtPtr ctxt)
14946
0
{
14947
0
    if ((item == NULL) ||
14948
0
  (item->type == XML_SCHEMA_TYPE_BASIC) ||
14949
0
  (item->baseType == NULL))
14950
0
  return;
14951
0
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14952
0
  item->baseType);
14953
0
}
14954
14955
/*
14956
* Simple Type Definition Representation OK (src-simple-type) 4
14957
*
14958
* "4 Circular union type definition is disallowed. That is, if the
14959
* <union> alternative is chosen, there must not be any entries in the
14960
* memberTypes [attribute] at any depth which resolve to the component
14961
* corresponding to the <simpleType>."
14962
*
14963
* Note that this should work on the *representation* of a component,
14964
* thus assumes any union types in the member types not being yet
14965
* substituted. At this stage we need the variety of the types
14966
* to be already computed.
14967
*/
14968
static int
14969
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14970
          xmlSchemaTypePtr ctxType,
14971
          xmlSchemaTypeLinkPtr members)
14972
0
{
14973
0
    xmlSchemaTypeLinkPtr member;
14974
0
    xmlSchemaTypePtr memberType;
14975
14976
0
    member = members;
14977
0
    while (member != NULL) {
14978
0
  memberType = member->type;
14979
0
  while ((memberType != NULL) &&
14980
0
      (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14981
0
      if (memberType == ctxType) {
14982
0
    xmlSchemaPCustomErr(pctxt,
14983
0
        XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14984
0
        WXS_BASIC_CAST ctxType, NULL,
14985
0
        "The union type definition is circular", NULL);
14986
0
    return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14987
0
      }
14988
0
      if ((WXS_IS_UNION(memberType)) &&
14989
0
    ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14990
0
      {
14991
0
    int res;
14992
0
    memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14993
0
    res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14994
0
        ctxType,
14995
0
        xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14996
0
    memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14997
0
    if (res != 0)
14998
0
        return(res);
14999
0
      }
15000
0
      memberType = memberType->baseType;
15001
0
  }
15002
0
  member = member->next;
15003
0
    }
15004
0
    return(0);
15005
0
}
15006
15007
static int
15008
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15009
           xmlSchemaTypePtr type)
15010
0
{
15011
0
    if (! WXS_IS_UNION(type))
15012
0
  return(0);
15013
0
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15014
0
  type->memberTypes));
15015
0
}
15016
15017
/**
15018
 * xmlSchemaResolveTypeReferences:
15019
 * @item:  the complex/simple type definition
15020
 * @ctxt:  the parser context
15021
 * @name:  the name
15022
 *
15023
 * Resolves type definition references
15024
 */
15025
static void
15026
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15027
       xmlSchemaParserCtxtPtr ctxt)
15028
0
{
15029
0
    if (typeDef == NULL)
15030
0
  return;
15031
15032
    /*
15033
    * Resolve the base type.
15034
    */
15035
0
    if (typeDef->baseType == NULL) {
15036
0
  typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15037
0
      typeDef->base, typeDef->baseNs);
15038
0
  if (typeDef->baseType == NULL) {
15039
0
      xmlSchemaPResCompAttrErr(ctxt,
15040
0
    XML_SCHEMAP_SRC_RESOLVE,
15041
0
    WXS_BASIC_CAST typeDef, typeDef->node,
15042
0
    "base", typeDef->base, typeDef->baseNs,
15043
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
15044
0
      return;
15045
0
  }
15046
0
    }
15047
0
    if (WXS_IS_SIMPLE(typeDef)) {
15048
0
  if (WXS_IS_UNION(typeDef)) {
15049
      /*
15050
      * Resolve the memberTypes.
15051
      */
15052
0
      xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15053
0
      return;
15054
0
  } else if (WXS_IS_LIST(typeDef)) {
15055
      /*
15056
      * Resolve the itemType.
15057
      */
15058
0
      if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15059
15060
0
    typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15061
0
        typeDef->base, typeDef->baseNs);
15062
15063
0
    if ((typeDef->subtypes == NULL) ||
15064
0
        (! WXS_IS_SIMPLE(typeDef->subtypes)))
15065
0
    {
15066
0
        typeDef->subtypes = NULL;
15067
0
        xmlSchemaPResCompAttrErr(ctxt,
15068
0
      XML_SCHEMAP_SRC_RESOLVE,
15069
0
      WXS_BASIC_CAST typeDef, typeDef->node,
15070
0
      "itemType", typeDef->base, typeDef->baseNs,
15071
0
      XML_SCHEMA_TYPE_SIMPLE, NULL);
15072
0
    }
15073
0
      }
15074
0
      return;
15075
0
  }
15076
0
    }
15077
    /*
15078
    * The ball of letters below means, that if we have a particle
15079
    * which has a QName-helper component as its {term}, we want
15080
    * to resolve it...
15081
    */
15082
0
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15083
0
  ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15084
0
      XML_SCHEMA_TYPE_PARTICLE) &&
15085
0
  (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15086
0
  ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15087
0
      XML_SCHEMA_EXTRA_QNAMEREF))
15088
0
    {
15089
0
  xmlSchemaQNameRefPtr ref =
15090
0
      WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15091
0
  xmlSchemaModelGroupDefPtr groupDef;
15092
15093
  /*
15094
  * URGENT TODO: Test this.
15095
  */
15096
0
  WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15097
  /*
15098
  * Resolve the MG definition reference.
15099
  */
15100
0
  groupDef =
15101
0
      WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15102
0
    ref->itemType, ref->name, ref->targetNamespace);
15103
0
  if (groupDef == NULL) {
15104
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15105
0
    NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15106
0
    "ref", ref->name, ref->targetNamespace, ref->itemType,
15107
0
    NULL);
15108
      /* Remove the particle. */
15109
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15110
0
  } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15111
      /* Remove the particle. */
15112
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15113
0
  else {
15114
      /*
15115
      * Assign the MG definition's {model group} to the
15116
      * particle's {term}.
15117
      */
15118
0
      WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15119
15120
0
      if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15121
    /*
15122
    * SPEC cos-all-limited (1.2)
15123
    * "1.2 the {term} property of a particle with
15124
    * {max occurs}=1 which is part of a pair which constitutes
15125
    * the {content type} of a complex type definition."
15126
    */
15127
0
    if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15128
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
15129
      /* TODO: error code */
15130
0
      XML_SCHEMAP_COS_ALL_LIMITED,
15131
0
      WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15132
0
      "The particle's {max occurs} must be 1, since the "
15133
0
      "reference resolves to an 'all' model group",
15134
0
      NULL, NULL);
15135
0
    }
15136
0
      }
15137
0
  }
15138
0
    }
15139
0
}
15140
15141
15142
15143
/**
15144
 * xmlSchemaCheckSTPropsCorrect:
15145
 * @ctxt:  the schema parser context
15146
 * @type:  the simple type definition
15147
 *
15148
 * Checks st-props-correct.
15149
 *
15150
 * Returns 0 if the properties are correct,
15151
 * if not, a positive error code and -1 on internal
15152
 * errors.
15153
 */
15154
static int
15155
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15156
           xmlSchemaTypePtr type)
15157
0
{
15158
0
    xmlSchemaTypePtr baseType = type->baseType;
15159
0
    xmlChar *str = NULL;
15160
15161
    /* STATE: error funcs converted. */
15162
    /*
15163
    * Schema Component Constraint: Simple Type Definition Properties Correct
15164
    *
15165
    * NOTE: This is somehow redundant, since we actually built a simple type
15166
    * to have all the needed information; this acts as an self test.
15167
    */
15168
    /* Base type: If the datatype has been `derived` by `restriction`
15169
    * then the Simple Type Definition component from which it is `derived`,
15170
    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15171
    */
15172
0
    if (baseType == NULL) {
15173
  /*
15174
  * TODO: Think about: "modulo the impact of Missing
15175
  * Sub-components ($5.3)."
15176
  */
15177
0
  xmlSchemaPCustomErr(ctxt,
15178
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15179
0
      WXS_BASIC_CAST type, NULL,
15180
0
      "No base type existent", NULL);
15181
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15182
15183
0
    }
15184
0
    if (! WXS_IS_SIMPLE(baseType)) {
15185
0
  xmlSchemaPCustomErr(ctxt,
15186
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15187
0
      WXS_BASIC_CAST type, NULL,
15188
0
      "The base type '%s' is not a simple type",
15189
0
      xmlSchemaGetComponentQName(&str, baseType));
15190
0
  FREE_AND_NULL(str)
15191
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15192
0
    }
15193
0
    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15194
0
  (WXS_IS_RESTRICTION(type) == 0) &&
15195
0
  ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15196
0
         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15197
0
  xmlSchemaPCustomErr(ctxt,
15198
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15199
0
      WXS_BASIC_CAST type, NULL,
15200
0
      "A type, derived by list or union, must have "
15201
0
      "the simple ur-type definition as base type, not '%s'",
15202
0
      xmlSchemaGetComponentQName(&str, baseType));
15203
0
  FREE_AND_NULL(str)
15204
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15205
0
    }
15206
    /*
15207
    * Variety: One of {atomic, list, union}.
15208
    */
15209
0
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15210
0
  (! WXS_IS_LIST(type))) {
15211
0
  xmlSchemaPCustomErr(ctxt,
15212
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15213
0
      WXS_BASIC_CAST type, NULL,
15214
0
      "The variety is absent", NULL);
15215
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15216
0
    }
15217
    /* TODO: Finish this. Hmm, is this finished? */
15218
15219
    /*
15220
    * 3 The {final} of the {base type definition} must not contain restriction.
15221
    */
15222
0
    if (xmlSchemaTypeFinalContains(baseType,
15223
0
  XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15224
0
  xmlSchemaPCustomErr(ctxt,
15225
0
      XML_SCHEMAP_ST_PROPS_CORRECT_3,
15226
0
      WXS_BASIC_CAST type, NULL,
15227
0
      "The 'final' of its base type '%s' must not contain "
15228
0
      "'restriction'",
15229
0
      xmlSchemaGetComponentQName(&str, baseType));
15230
0
  FREE_AND_NULL(str)
15231
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15232
0
    }
15233
15234
    /*
15235
    * 2 All simple type definitions must be derived ultimately from the `simple
15236
    * ur-type definition` (so circular definitions are disallowed). That is, it
15237
    * must be possible to reach a built-in primitive datatype or the `simple
15238
    * ur-type definition` by repeatedly following the {base type definition}.
15239
    *
15240
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15241
    */
15242
0
    return (0);
15243
0
}
15244
15245
/**
15246
 * xmlSchemaCheckCOSSTRestricts:
15247
 * @ctxt:  the schema parser context
15248
 * @type:  the simple type definition
15249
 *
15250
 * Schema Component Constraint:
15251
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15252
15253
 * Checks if the given @type (simpleType) is derived validly by restriction.
15254
 * STATUS:
15255
 *
15256
 * Returns -1 on internal errors, 0 if the type is validly derived,
15257
 * a positive error code otherwise.
15258
 */
15259
static int
15260
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15261
           xmlSchemaTypePtr type)
15262
0
{
15263
0
    xmlChar *str = NULL;
15264
15265
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15266
0
  PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15267
0
      "given type is not a user-derived simpleType");
15268
0
  return (-1);
15269
0
    }
15270
15271
0
    if (WXS_IS_ATOMIC(type)) {
15272
0
  xmlSchemaTypePtr primitive;
15273
  /*
15274
  * 1.1 The {base type definition} must be an atomic simple
15275
  * type definition or a built-in primitive datatype.
15276
  */
15277
0
  if (! WXS_IS_ATOMIC(type->baseType)) {
15278
0
      xmlSchemaPCustomErr(pctxt,
15279
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15280
0
    WXS_BASIC_CAST type, NULL,
15281
0
    "The base type '%s' is not an atomic simple type",
15282
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15283
0
      FREE_AND_NULL(str)
15284
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15285
0
  }
15286
  /* 1.2 The {final} of the {base type definition} must not contain
15287
  * restriction.
15288
  */
15289
  /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15290
0
  if (xmlSchemaTypeFinalContains(type->baseType,
15291
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15292
0
      xmlSchemaPCustomErr(pctxt,
15293
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15294
0
    WXS_BASIC_CAST type, NULL,
15295
0
    "The final of its base type '%s' must not contain 'restriction'",
15296
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15297
0
      FREE_AND_NULL(str)
15298
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15299
0
  }
15300
15301
  /*
15302
  * 1.3.1 DF must be an allowed constraining facet for the {primitive
15303
  * type definition}, as specified in the appropriate subsection of 3.2
15304
  * Primitive datatypes.
15305
  */
15306
0
  if (type->facets != NULL) {
15307
0
      xmlSchemaFacetPtr facet;
15308
0
      int ok = 1;
15309
15310
0
      primitive = xmlSchemaGetPrimitiveType(type);
15311
0
      if (primitive == NULL) {
15312
0
    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15313
0
        "failed to get primitive type");
15314
0
    return (-1);
15315
0
      }
15316
0
      facet = type->facets;
15317
0
      do {
15318
0
    if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15319
0
        ok = 0;
15320
0
        xmlSchemaPIllegalFacetAtomicErr(pctxt,
15321
0
      XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15322
0
      type, primitive, facet);
15323
0
    }
15324
0
    facet = facet->next;
15325
0
      } while (facet != NULL);
15326
0
      if (ok == 0)
15327
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15328
0
  }
15329
  /*
15330
  * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15331
  * of the {base type definition} (call this BF),then the DF's {value}
15332
  * must be a valid restriction of BF's {value} as defined in
15333
  * [XML Schemas: Datatypes]."
15334
  *
15335
  * NOTE (1.3.2) Facet derivation constraints are currently handled in
15336
  * xmlSchemaDeriveAndValidateFacets()
15337
  */
15338
0
    } else if (WXS_IS_LIST(type)) {
15339
0
  xmlSchemaTypePtr itemType = NULL;
15340
15341
0
  itemType = type->subtypes;
15342
0
  if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15343
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15344
0
    "failed to evaluate the item type");
15345
0
      return (-1);
15346
0
  }
15347
0
  if (WXS_IS_TYPE_NOT_FIXED(itemType))
15348
0
      xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15349
  /*
15350
  * 2.1 The {item type definition} must have a {variety} of atomic or
15351
  * union (in which case all the {member type definitions}
15352
  * must be atomic).
15353
  */
15354
0
  if ((! WXS_IS_ATOMIC(itemType)) &&
15355
0
      (! WXS_IS_UNION(itemType))) {
15356
0
      xmlSchemaPCustomErr(pctxt,
15357
0
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15358
0
    WXS_BASIC_CAST type, NULL,
15359
0
    "The item type '%s' does not have a variety of atomic or union",
15360
0
    xmlSchemaGetComponentQName(&str, itemType));
15361
0
      FREE_AND_NULL(str)
15362
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15363
0
  } else if (WXS_IS_UNION(itemType)) {
15364
0
      xmlSchemaTypeLinkPtr member;
15365
15366
0
      member = itemType->memberTypes;
15367
0
      while (member != NULL) {
15368
0
    if (! WXS_IS_ATOMIC(member->type)) {
15369
0
        xmlSchemaPCustomErr(pctxt,
15370
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15371
0
      WXS_BASIC_CAST type, NULL,
15372
0
      "The item type is a union type, but the "
15373
0
      "member type '%s' of this item type is not atomic",
15374
0
      xmlSchemaGetComponentQName(&str, member->type));
15375
0
        FREE_AND_NULL(str)
15376
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15377
0
    }
15378
0
    member = member->next;
15379
0
      }
15380
0
  }
15381
15382
0
  if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15383
0
      xmlSchemaFacetPtr facet;
15384
      /*
15385
      * This is the case if we have: <simpleType><list ..
15386
      */
15387
      /*
15388
      * 2.3.1
15389
      * 2.3.1.1 The {final} of the {item type definition} must not
15390
      * contain list.
15391
      */
15392
0
      if (xmlSchemaTypeFinalContains(itemType,
15393
0
    XML_SCHEMAS_TYPE_FINAL_LIST)) {
15394
0
    xmlSchemaPCustomErr(pctxt,
15395
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15396
0
        WXS_BASIC_CAST type, NULL,
15397
0
        "The final of its item type '%s' must not contain 'list'",
15398
0
        xmlSchemaGetComponentQName(&str, itemType));
15399
0
    FREE_AND_NULL(str)
15400
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15401
0
      }
15402
      /*
15403
      * 2.3.1.2 The {facets} must only contain the whiteSpace
15404
      * facet component.
15405
      * OPTIMIZE TODO: the S4S already disallows any facet
15406
      * to be specified.
15407
      */
15408
0
      if (type->facets != NULL) {
15409
0
    facet = type->facets;
15410
0
    do {
15411
0
        if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15412
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15413
0
          XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15414
0
          type, facet);
15415
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15416
0
        }
15417
0
        facet = facet->next;
15418
0
    } while (facet != NULL);
15419
0
      }
15420
      /*
15421
      * MAYBE TODO: (Hmm, not really) Datatypes states:
15422
      * A `list` datatype can be `derived` from an `atomic` datatype
15423
      * whose `lexical space` allows space (such as string or anyURI)or
15424
      * a `union` datatype any of whose {member type definitions}'s
15425
      * `lexical space` allows space.
15426
      */
15427
0
  } else {
15428
      /*
15429
      * This is the case if we have: <simpleType><restriction ...
15430
      * I.e. the variety of "list" is inherited.
15431
      */
15432
      /*
15433
      * 2.3.2
15434
      * 2.3.2.1 The {base type definition} must have a {variety} of list.
15435
      */
15436
0
      if (! WXS_IS_LIST(type->baseType)) {
15437
0
    xmlSchemaPCustomErr(pctxt,
15438
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15439
0
        WXS_BASIC_CAST type, NULL,
15440
0
        "The base type '%s' must be a list type",
15441
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15442
0
    FREE_AND_NULL(str)
15443
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15444
0
      }
15445
      /*
15446
      * 2.3.2.2 The {final} of the {base type definition} must not
15447
      * contain restriction.
15448
      */
15449
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15450
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15451
0
    xmlSchemaPCustomErr(pctxt,
15452
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15453
0
        WXS_BASIC_CAST type, NULL,
15454
0
        "The 'final' of the base type '%s' must not contain 'restriction'",
15455
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15456
0
    FREE_AND_NULL(str)
15457
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15458
0
      }
15459
      /*
15460
      * 2.3.2.3 The {item type definition} must be validly derived
15461
      * from the {base type definition}'s {item type definition} given
15462
      * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15463
      */
15464
0
      {
15465
0
    xmlSchemaTypePtr baseItemType;
15466
15467
0
    baseItemType = type->baseType->subtypes;
15468
0
    if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15469
0
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15470
0
      "failed to eval the item type of a base type");
15471
0
        return (-1);
15472
0
    }
15473
0
    if ((itemType != baseItemType) &&
15474
0
        (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15475
0
      baseItemType, 0) != 0)) {
15476
0
        xmlChar *strBIT = NULL, *strBT = NULL;
15477
0
        xmlSchemaPCustomErrExt(pctxt,
15478
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15479
0
      WXS_BASIC_CAST type, NULL,
15480
0
      "The item type '%s' is not validly derived from "
15481
0
      "the item type '%s' of the base type '%s'",
15482
0
      xmlSchemaGetComponentQName(&str, itemType),
15483
0
      xmlSchemaGetComponentQName(&strBIT, baseItemType),
15484
0
      xmlSchemaGetComponentQName(&strBT, type->baseType));
15485
15486
0
        FREE_AND_NULL(str)
15487
0
        FREE_AND_NULL(strBIT)
15488
0
        FREE_AND_NULL(strBT)
15489
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15490
0
    }
15491
0
      }
15492
15493
0
      if (type->facets != NULL) {
15494
0
    xmlSchemaFacetPtr facet;
15495
0
    int ok = 1;
15496
    /*
15497
    * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15498
    * and enumeration facet components are allowed among the {facets}.
15499
    */
15500
0
    facet = type->facets;
15501
0
    do {
15502
0
        switch (facet->type) {
15503
0
      case XML_SCHEMA_FACET_LENGTH:
15504
0
      case XML_SCHEMA_FACET_MINLENGTH:
15505
0
      case XML_SCHEMA_FACET_MAXLENGTH:
15506
0
      case XML_SCHEMA_FACET_WHITESPACE:
15507
          /*
15508
          * TODO: 2.5.1.2 List datatypes
15509
          * The value of `whiteSpace` is fixed to the value collapse.
15510
          */
15511
0
      case XML_SCHEMA_FACET_PATTERN:
15512
0
      case XML_SCHEMA_FACET_ENUMERATION:
15513
0
          break;
15514
0
      default: {
15515
0
          xmlSchemaPIllegalFacetListUnionErr(pctxt,
15516
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15517
0
        type, facet);
15518
          /*
15519
          * We could return, but it's nicer to report all
15520
          * invalid facets.
15521
          */
15522
0
          ok = 0;
15523
0
      }
15524
0
        }
15525
0
        facet = facet->next;
15526
0
    } while (facet != NULL);
15527
0
    if (ok == 0)
15528
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15529
    /*
15530
    * SPEC (2.3.2.5) (same as 1.3.2)
15531
    *
15532
    * NOTE (2.3.2.5) This is currently done in
15533
    * xmlSchemaDeriveAndValidateFacets()
15534
    */
15535
0
      }
15536
0
  }
15537
0
    } else if (WXS_IS_UNION(type)) {
15538
  /*
15539
  * 3.1 The {member type definitions} must all have {variety} of
15540
  * atomic or list.
15541
  */
15542
0
  xmlSchemaTypeLinkPtr member;
15543
15544
0
  member = type->memberTypes;
15545
0
  while (member != NULL) {
15546
0
      if (WXS_IS_TYPE_NOT_FIXED(member->type))
15547
0
    xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15548
15549
0
      if ((! WXS_IS_ATOMIC(member->type)) &&
15550
0
    (! WXS_IS_LIST(member->type))) {
15551
0
    xmlSchemaPCustomErr(pctxt,
15552
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15553
0
        WXS_BASIC_CAST type, NULL,
15554
0
        "The member type '%s' is neither an atomic, nor a list type",
15555
0
        xmlSchemaGetComponentQName(&str, member->type));
15556
0
    FREE_AND_NULL(str)
15557
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15558
0
      }
15559
0
      member = member->next;
15560
0
  }
15561
  /*
15562
  * 3.3.1 If the {base type definition} is the `simple ur-type
15563
  * definition`
15564
  */
15565
0
  if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15566
      /*
15567
      * 3.3.1.1 All of the {member type definitions} must have a
15568
      * {final} which does not contain union.
15569
      */
15570
0
      member = type->memberTypes;
15571
0
      while (member != NULL) {
15572
0
    if (xmlSchemaTypeFinalContains(member->type,
15573
0
        XML_SCHEMAS_TYPE_FINAL_UNION)) {
15574
0
        xmlSchemaPCustomErr(pctxt,
15575
0
      XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15576
0
      WXS_BASIC_CAST type, NULL,
15577
0
      "The 'final' of member type '%s' contains 'union'",
15578
0
      xmlSchemaGetComponentQName(&str, member->type));
15579
0
        FREE_AND_NULL(str)
15580
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15581
0
    }
15582
0
    member = member->next;
15583
0
      }
15584
      /*
15585
      * 3.3.1.2 The {facets} must be empty.
15586
      */
15587
0
      if (type->facetSet != NULL) {
15588
0
    xmlSchemaPCustomErr(pctxt,
15589
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15590
0
        WXS_BASIC_CAST type, NULL,
15591
0
        "No facets allowed", NULL);
15592
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15593
0
      }
15594
0
  } else {
15595
      /*
15596
      * 3.3.2.1 The {base type definition} must have a {variety} of union.
15597
      * I.e. the variety of "list" is inherited.
15598
      */
15599
0
      if (! WXS_IS_UNION(type->baseType)) {
15600
0
    xmlSchemaPCustomErr(pctxt,
15601
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15602
0
        WXS_BASIC_CAST type, NULL,
15603
0
        "The base type '%s' is not a union type",
15604
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15605
0
    FREE_AND_NULL(str)
15606
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15607
0
      }
15608
      /*
15609
      * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15610
      */
15611
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15612
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15613
0
    xmlSchemaPCustomErr(pctxt,
15614
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15615
0
        WXS_BASIC_CAST type, NULL,
15616
0
        "The 'final' of its base type '%s' must not contain 'restriction'",
15617
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15618
0
    FREE_AND_NULL(str)
15619
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15620
0
      }
15621
      /*
15622
      * 3.3.2.3 The {member type definitions}, in order, must be validly
15623
      * derived from the corresponding type definitions in the {base
15624
      * type definition}'s {member type definitions} given the empty set,
15625
      * as defined in Type Derivation OK (Simple) ($3.14.6).
15626
      */
15627
0
      {
15628
0
    xmlSchemaTypeLinkPtr baseMember;
15629
15630
    /*
15631
    * OPTIMIZE: if the type is restricting, it has no local defined
15632
    * member types and inherits the member types of the base type;
15633
    * thus a check for equality can be skipped.
15634
    */
15635
    /*
15636
    * Even worse: I cannot see a scenario where a restricting
15637
    * union simple type can have other member types as the member
15638
    * types of it's base type. This check seems not necessary with
15639
    * respect to the derivation process in libxml2.
15640
    * But necessary if constructing types with an API.
15641
    */
15642
0
    if (type->memberTypes != NULL) {
15643
0
        member = type->memberTypes;
15644
0
        baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15645
0
        if ((member == NULL) && (baseMember != NULL)) {
15646
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15647
0
          "different number of member types in base");
15648
0
        }
15649
0
        while (member != NULL) {
15650
0
      if (baseMember == NULL) {
15651
0
          PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15652
0
          "different number of member types in base");
15653
0
      } else if ((member->type != baseMember->type) &&
15654
0
          (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15655
0
        member->type, baseMember->type, 0) != 0)) {
15656
0
          xmlChar *strBMT = NULL, *strBT = NULL;
15657
15658
0
          xmlSchemaPCustomErrExt(pctxt,
15659
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15660
0
        WXS_BASIC_CAST type, NULL,
15661
0
        "The member type %s is not validly "
15662
0
        "derived from its corresponding member "
15663
0
        "type %s of the base type %s",
15664
0
        xmlSchemaGetComponentQName(&str, member->type),
15665
0
        xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15666
0
        xmlSchemaGetComponentQName(&strBT, type->baseType));
15667
0
          FREE_AND_NULL(str)
15668
0
          FREE_AND_NULL(strBMT)
15669
0
          FREE_AND_NULL(strBT)
15670
0
          return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15671
0
      }
15672
0
      member = member->next;
15673
0
                        if (baseMember != NULL)
15674
0
                            baseMember = baseMember->next;
15675
0
        }
15676
0
    }
15677
0
      }
15678
      /*
15679
      * 3.3.2.4 Only pattern and enumeration facet components are
15680
      * allowed among the {facets}.
15681
      */
15682
0
      if (type->facets != NULL) {
15683
0
    xmlSchemaFacetPtr facet;
15684
0
    int ok = 1;
15685
15686
0
    facet = type->facets;
15687
0
    do {
15688
0
        if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15689
0
      (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15690
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15691
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15692
0
        type, facet);
15693
0
      ok = 0;
15694
0
        }
15695
0
        facet = facet->next;
15696
0
    } while (facet != NULL);
15697
0
    if (ok == 0)
15698
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15699
15700
0
      }
15701
      /*
15702
      * SPEC (3.3.2.5) (same as 1.3.2)
15703
      *
15704
      * NOTE (3.3.2.5) This is currently done in
15705
      * xmlSchemaDeriveAndValidateFacets()
15706
      */
15707
0
  }
15708
0
    }
15709
15710
0
    return (0);
15711
0
}
15712
15713
/**
15714
 * xmlSchemaCheckSRCSimpleType:
15715
 * @ctxt:  the schema parser context
15716
 * @type:  the simple type definition
15717
 *
15718
 * Checks crc-simple-type constraints.
15719
 *
15720
 * Returns 0 if the constraints are satisfied,
15721
 * if not a positive error code and -1 on internal
15722
 * errors.
15723
 */
15724
#if 0
15725
static int
15726
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15727
          xmlSchemaTypePtr type)
15728
{
15729
    /*
15730
    * src-simple-type.1 The corresponding simple type definition, if any,
15731
    * must satisfy the conditions set out in Constraints on Simple Type
15732
    * Definition Schema Components ($3.14.6).
15733
    */
15734
    if (WXS_IS_RESTRICTION(type)) {
15735
  /*
15736
  * src-simple-type.2 "If the <restriction> alternative is chosen,
15737
  * either it must have a base [attribute] or a <simpleType> among its
15738
  * [children], but not both."
15739
  * NOTE: This is checked in the parse function of <restriction>.
15740
  */
15741
  /*
15742
  *
15743
  */
15744
    } else if (WXS_IS_LIST(type)) {
15745
  /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15746
  * an itemType [attribute] or a <simpleType> among its [children],
15747
  * but not both."
15748
  *
15749
  * NOTE: This is checked in the parse function of <list>.
15750
  */
15751
    } else if (WXS_IS_UNION(type)) {
15752
  /*
15753
  * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15754
  */
15755
    }
15756
    return (0);
15757
}
15758
#endif
15759
15760
static int
15761
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15762
0
{
15763
0
   if (ctxt->vctxt == NULL) {
15764
0
  ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15765
0
  if (ctxt->vctxt == NULL) {
15766
0
      xmlSchemaPErr(ctxt, NULL,
15767
0
    XML_SCHEMAP_INTERNAL,
15768
0
    "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15769
0
    "failed to create a temp. validation context.\n",
15770
0
    NULL, NULL);
15771
0
      return (-1);
15772
0
  }
15773
  /* TODO: Pass user data. */
15774
0
  xmlSchemaSetValidErrors(ctxt->vctxt,
15775
0
      ctxt->error, ctxt->warning, ctxt->errCtxt);
15776
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15777
0
      ctxt->serror, ctxt->errCtxt);
15778
0
    }
15779
0
    return (0);
15780
0
}
15781
15782
static int
15783
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15784
           xmlNodePtr node,
15785
           xmlSchemaTypePtr type,
15786
           const xmlChar *value,
15787
           xmlSchemaValPtr *retVal,
15788
           int fireErrors,
15789
           int normalize,
15790
           int isNormalized);
15791
15792
/**
15793
 * xmlSchemaParseCheckCOSValidDefault:
15794
 * @pctxt:  the schema parser context
15795
 * @type:  the simple type definition
15796
 * @value: the default value
15797
 * @node: an optional node (the holder of the value)
15798
 *
15799
 * Schema Component Constraint: Element Default Valid (Immediate)
15800
 * (cos-valid-default)
15801
 * This will be used by the parser only. For the validator there's
15802
 * an other version.
15803
 *
15804
 * Returns 0 if the constraints are satisfied,
15805
 * if not, a positive error code and -1 on internal
15806
 * errors.
15807
 */
15808
static int
15809
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15810
           xmlNodePtr node,
15811
           xmlSchemaTypePtr type,
15812
           const xmlChar *value,
15813
           xmlSchemaValPtr *val)
15814
0
{
15815
0
    int ret = 0;
15816
15817
    /*
15818
    * cos-valid-default:
15819
    * Schema Component Constraint: Element Default Valid (Immediate)
15820
    * For a string to be a valid default with respect to a type
15821
    * definition the appropriate case among the following must be true:
15822
    */
15823
0
    if WXS_IS_COMPLEX(type) {
15824
  /*
15825
  * Complex type.
15826
  *
15827
  * SPEC (2.1) "its {content type} must be a simple type definition
15828
  * or mixed."
15829
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15830
  * type}'s particle must be `emptiable` as defined by
15831
  * Particle Emptiable ($3.9.6)."
15832
  */
15833
0
  if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15834
0
      ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15835
      /* NOTE that this covers (2.2.2) as well. */
15836
0
      xmlSchemaPCustomErr(pctxt,
15837
0
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15838
0
    WXS_BASIC_CAST type, type->node,
15839
0
    "For a string to be a valid default, the type definition "
15840
0
    "must be a simple type or a complex type with mixed content "
15841
0
    "and a particle emptiable", NULL);
15842
0
      return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15843
0
  }
15844
0
    }
15845
    /*
15846
    * 1 If the type definition is a simple type definition, then the string
15847
    * must be `valid` with respect to that definition as defined by String
15848
    * Valid ($3.14.4).
15849
    *
15850
    * AND
15851
    *
15852
    * 2.2.1 If the {content type} is a simple type definition, then the
15853
    * string must be `valid` with respect to that simple type definition
15854
    * as defined by String Valid ($3.14.4).
15855
    */
15856
0
    if (WXS_IS_SIMPLE(type))
15857
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15858
0
      type, value, val, 1, 1, 0);
15859
0
    else if (WXS_HAS_SIMPLE_CONTENT(type))
15860
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15861
0
      type->contentTypeDef, value, val, 1, 1, 0);
15862
0
    else
15863
0
  return (ret);
15864
15865
0
    if (ret < 0) {
15866
0
  PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15867
0
      "calling xmlSchemaVCheckCVCSimpleType()");
15868
0
    }
15869
15870
0
    return (ret);
15871
0
}
15872
15873
/**
15874
 * xmlSchemaCheckCTPropsCorrect:
15875
 * @ctxt:  the schema parser context
15876
 * @type:  the complex type definition
15877
 *
15878
 *.(4.6) Constraints on Complex Type Definition Schema Components
15879
 * Schema Component Constraint:
15880
 * Complex Type Definition Properties Correct (ct-props-correct)
15881
 * STATUS: (seems) complete
15882
 *
15883
 * Returns 0 if the constraints are satisfied, a positive
15884
 * error code if not and -1 if an internal error occurred.
15885
 */
15886
static int
15887
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15888
           xmlSchemaTypePtr type)
15889
0
{
15890
    /*
15891
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15892
    *
15893
    * SPEC (1) "The values of the properties of a complex type definition must
15894
    * be as described in the property tableau in The Complex Type Definition
15895
    * Schema Component ($3.4.1), modulo the impact of Missing
15896
    * Sub-components ($5.3)."
15897
    */
15898
0
    if ((type->baseType != NULL) &&
15899
0
  (WXS_IS_SIMPLE(type->baseType)) &&
15900
0
  (WXS_IS_EXTENSION(type) == 0)) {
15901
  /*
15902
  * SPEC (2) "If the {base type definition} is a simple type definition,
15903
  * the {derivation method} must be extension."
15904
  */
15905
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
15906
0
      XML_SCHEMAP_SRC_CT_1,
15907
0
      NULL, WXS_BASIC_CAST type,
15908
0
      "If the base type is a simple type, the derivation method must be "
15909
0
      "'extension'", NULL, NULL);
15910
0
  return (XML_SCHEMAP_SRC_CT_1);
15911
0
    }
15912
    /*
15913
    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
15914
    * definition`. That is, it must be possible to reach the `ur-type
15915
    * definition` by repeatedly following the {base type definition}."
15916
    *
15917
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15918
    */
15919
    /*
15920
    * NOTE that (4) and (5) need the following:
15921
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
15922
    *   - attribute group references need to be expanded already
15923
    *   - simple types need to be typefixed already
15924
    */
15925
0
    if (type->attrUses &&
15926
0
  (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15927
0
    {
15928
0
  xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15929
0
  xmlSchemaAttributeUsePtr use, tmp;
15930
0
  int i, j, hasId = 0;
15931
15932
0
  for (i = uses->nbItems -1; i >= 0; i--) {
15933
0
      use = uses->items[i];
15934
15935
      /*
15936
      * SPEC ct-props-correct
15937
      * (4) "Two distinct attribute declarations in the
15938
      * {attribute uses} must not have identical {name}s and
15939
      * {target namespace}s."
15940
      */
15941
0
      if (i > 0) {
15942
0
    for (j = i -1; j >= 0; j--) {
15943
0
        tmp = uses->items[j];
15944
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
15945
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
15946
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
15947
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
15948
0
        {
15949
0
      xmlChar *str = NULL;
15950
15951
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15952
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15953
0
          NULL, WXS_BASIC_CAST type,
15954
0
          "Duplicate %s",
15955
0
          xmlSchemaGetComponentDesignation(&str, use),
15956
0
          NULL);
15957
0
      FREE_AND_NULL(str);
15958
      /*
15959
      * Remove the duplicate.
15960
      */
15961
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15962
0
          goto exit_failure;
15963
0
      goto next_use;
15964
0
        }
15965
0
    }
15966
0
      }
15967
      /*
15968
      * SPEC ct-props-correct
15969
      * (5) "Two distinct attribute declarations in the
15970
      * {attribute uses} must not have {type definition}s which
15971
      * are or are derived from ID."
15972
      */
15973
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15974
0
    if (xmlSchemaIsDerivedFromBuiltInType(
15975
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15976
0
    {
15977
0
        if (hasId) {
15978
0
      xmlChar *str = NULL;
15979
15980
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15981
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15982
0
          NULL, WXS_BASIC_CAST type,
15983
0
          "There must not exist more than one attribute "
15984
0
          "declaration of type 'xs:ID' "
15985
0
          "(or derived from 'xs:ID'). The %s violates this "
15986
0
          "constraint",
15987
0
          xmlSchemaGetComponentDesignation(&str, use),
15988
0
          NULL);
15989
0
      FREE_AND_NULL(str);
15990
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15991
0
          goto exit_failure;
15992
0
        }
15993
15994
0
        hasId = 1;
15995
0
    }
15996
0
      }
15997
0
next_use: {}
15998
0
  }
15999
0
    }
16000
0
    return (0);
16001
0
exit_failure:
16002
0
    return(-1);
16003
0
}
16004
16005
static int
16006
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16007
           xmlSchemaTypePtr typeB)
16008
0
{
16009
    /*
16010
    * TODO: This should implement component-identity
16011
    * in the future.
16012
    */
16013
0
    if ((typeA == NULL) || (typeB == NULL))
16014
0
  return (0);
16015
0
    return (typeA == typeB);
16016
0
}
16017
16018
/**
16019
 * xmlSchemaCheckCOSCTDerivedOK:
16020
 * @ctxt:  the schema parser context
16021
 * @type:  the to-be derived complex type definition
16022
 * @baseType:  the base complex type definition
16023
 * @set: the given set
16024
 *
16025
 * Schema Component Constraint:
16026
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16027
 *
16028
 * STATUS: completed
16029
 *
16030
 * Returns 0 if the constraints are satisfied, or 1
16031
 * if not.
16032
 */
16033
static int
16034
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16035
           xmlSchemaTypePtr type,
16036
           xmlSchemaTypePtr baseType,
16037
           int set)
16038
0
{
16039
0
    int equal = xmlSchemaAreEqualTypes(type, baseType);
16040
    /* TODO: Error codes. */
16041
    /*
16042
    * SPEC "For a complex type definition (call it D, for derived)
16043
    * to be validly derived from a type definition (call this
16044
    * B, for base) given a subset of {extension, restriction}
16045
    * all of the following must be true:"
16046
    */
16047
0
    if (! equal) {
16048
  /*
16049
  * SPEC (1) "If B and D are not the same type definition, then the
16050
  * {derivation method} of D must not be in the subset."
16051
  */
16052
0
  if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16053
0
      ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16054
0
      return (1);
16055
0
    } else {
16056
  /*
16057
  * SPEC (2.1) "B and D must be the same type definition."
16058
  */
16059
0
  return (0);
16060
0
    }
16061
    /*
16062
    * SPEC (2.2) "B must be D's {base type definition}."
16063
    */
16064
0
    if (type->baseType == baseType)
16065
0
  return (0);
16066
    /*
16067
    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16068
    * definition`."
16069
    */
16070
0
    if (WXS_IS_ANYTYPE(type->baseType))
16071
0
  return (1);
16072
16073
0
    if (WXS_IS_COMPLEX(type->baseType)) {
16074
  /*
16075
  * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16076
  * must be validly derived from B given the subset as defined by this
16077
  * constraint."
16078
  */
16079
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16080
0
      baseType, set));
16081
0
    } else {
16082
  /*
16083
  * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16084
  * must be validly derived from B given the subset as defined in Type
16085
  * Derivation OK (Simple) ($3.14.6).
16086
  */
16087
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16088
0
      baseType, set));
16089
0
    }
16090
0
}
16091
16092
/**
16093
 * xmlSchemaCheckCOSDerivedOK:
16094
 * @type:  the derived simple type definition
16095
 * @baseType:  the base type definition
16096
 *
16097
 * Calls:
16098
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16099
 *
16100
 * Checks whether @type can be validly derived from @baseType.
16101
 *
16102
 * Returns 0 on success, an positive error code otherwise.
16103
 */
16104
static int
16105
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16106
         xmlSchemaTypePtr type,
16107
         xmlSchemaTypePtr baseType,
16108
         int set)
16109
0
{
16110
0
    if (WXS_IS_SIMPLE(type))
16111
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16112
0
    else
16113
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16114
0
}
16115
16116
/**
16117
 * xmlSchemaCheckCOSCTExtends:
16118
 * @ctxt:  the schema parser context
16119
 * @type:  the complex type definition
16120
 *
16121
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16122
 * Schema Component Constraint:
16123
 * Derivation Valid (Extension) (cos-ct-extends)
16124
 *
16125
 * STATUS:
16126
 *   missing:
16127
 *     (1.5)
16128
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16129
 *
16130
 * Returns 0 if the constraints are satisfied, a positive
16131
 * error code if not and -1 if an internal error occurred.
16132
 */
16133
static int
16134
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16135
         xmlSchemaTypePtr type)
16136
0
{
16137
0
    xmlSchemaTypePtr base = type->baseType;
16138
    /*
16139
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16140
    * temporarily only.
16141
    */
16142
    /*
16143
    * SPEC (1) "If the {base type definition} is a complex type definition,
16144
    * then all of the following must be true:"
16145
    */
16146
0
    if (WXS_IS_COMPLEX(base)) {
16147
  /*
16148
  * SPEC (1.1) "The {final} of the {base type definition} must not
16149
  * contain extension."
16150
  */
16151
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16152
0
      xmlSchemaPCustomErr(ctxt,
16153
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16154
0
    WXS_BASIC_CAST type, NULL,
16155
0
    "The 'final' of the base type definition "
16156
0
    "contains 'extension'", NULL);
16157
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16158
0
  }
16159
16160
  /*
16161
  * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16162
  * since they are automatically satisfied through the
16163
  * inheriting mechanism.
16164
  * Note that even if redefining components, the inheriting mechanism
16165
  * is used.
16166
  */
16167
#if 0
16168
  /*
16169
  * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16170
  * uses}
16171
  * of the complex type definition itself, that is, for every attribute
16172
  * use in the {attribute uses} of the {base type definition}, there
16173
  * must be an attribute use in the {attribute uses} of the complex
16174
  * type definition itself whose {attribute declaration} has the same
16175
  * {name}, {target namespace} and {type definition} as its attribute
16176
  * declaration"
16177
  */
16178
  if (base->attrUses != NULL) {
16179
      int i, j, found;
16180
      xmlSchemaAttributeUsePtr use, buse;
16181
16182
      for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16183
    buse = (WXS_LIST_CAST base->attrUses)->items[i];
16184
    found = 0;
16185
    if (type->attrUses != NULL) {
16186
        use = (WXS_LIST_CAST type->attrUses)->items[j];
16187
        for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16188
        {
16189
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
16190
        WXS_ATTRUSE_DECL_NAME(buse)) &&
16191
          (WXS_ATTRUSE_DECL_TNS(use) ==
16192
        WXS_ATTRUSE_DECL_TNS(buse)) &&
16193
          (WXS_ATTRUSE_TYPEDEF(use) ==
16194
        WXS_ATTRUSE_TYPEDEF(buse))
16195
      {
16196
          found = 1;
16197
          break;
16198
      }
16199
        }
16200
    }
16201
    if (! found) {
16202
        xmlChar *str = NULL;
16203
16204
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
16205
      XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16206
      NULL, WXS_BASIC_CAST type,
16207
      /*
16208
      * TODO: The report does not indicate that also the
16209
      * type needs to be the same.
16210
      */
16211
      "This type is missing a matching correspondent "
16212
      "for its {base type}'s %s in its {attribute uses}",
16213
      xmlSchemaGetComponentDesignation(&str,
16214
          buse->children),
16215
      NULL);
16216
        FREE_AND_NULL(str)
16217
    }
16218
      }
16219
  }
16220
  /*
16221
  * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16222
  * definition must also have one, and the base type definition's
16223
  * {attribute  wildcard}'s {namespace constraint} must be a subset
16224
  * of the complex  type definition's {attribute wildcard}'s {namespace
16225
  * constraint}, as defined by Wildcard Subset ($3.10.6)."
16226
  */
16227
16228
  /*
16229
  * MAYBE TODO: Enable if ever needed. But this will be needed only
16230
  * if created the type via a schema construction API.
16231
  */
16232
  if (base->attributeWildcard != NULL) {
16233
      if (type->attributeWildcard == NULL) {
16234
    xmlChar *str = NULL;
16235
16236
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16237
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16238
        NULL, type,
16239
        "The base %s has an attribute wildcard, "
16240
        "but this type is missing an attribute wildcard",
16241
        xmlSchemaGetComponentDesignation(&str, base));
16242
    FREE_AND_NULL(str)
16243
16244
      } else if (xmlSchemaCheckCOSNSSubset(
16245
    base->attributeWildcard, type->attributeWildcard))
16246
      {
16247
    xmlChar *str = NULL;
16248
16249
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16250
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16251
        NULL, type,
16252
        "The attribute wildcard is not a valid "
16253
        "superset of the one in the base %s",
16254
        xmlSchemaGetComponentDesignation(&str, base));
16255
    FREE_AND_NULL(str)
16256
      }
16257
  }
16258
#endif
16259
  /*
16260
  * SPEC (1.4) "One of the following must be true:"
16261
  */
16262
0
  if ((type->contentTypeDef != NULL) &&
16263
0
      (type->contentTypeDef == base->contentTypeDef)) {
16264
      /*
16265
      * SPEC (1.4.1) "The {content type} of the {base type definition}
16266
      * and the {content type} of the complex type definition itself
16267
      * must be the same simple type definition"
16268
      * PASS
16269
      */
16270
0
  } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16271
0
      (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16272
      /*
16273
      * SPEC (1.4.2) "The {content type} of both the {base type
16274
      * definition} and the complex type definition itself must
16275
      * be empty."
16276
      * PASS
16277
      */
16278
0
  } else {
16279
      /*
16280
      * SPEC (1.4.3) "All of the following must be true:"
16281
      */
16282
0
      if (type->subtypes == NULL) {
16283
    /*
16284
    * SPEC 1.4.3.1 The {content type} of the complex type
16285
    * definition itself must specify a particle.
16286
    */
16287
0
    xmlSchemaPCustomErr(ctxt,
16288
0
        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16289
0
        WXS_BASIC_CAST type, NULL,
16290
0
        "The content type must specify a particle", NULL);
16291
0
    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16292
0
      }
16293
      /*
16294
      * SPEC (1.4.3.2) "One of the following must be true:"
16295
      */
16296
0
      if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16297
    /*
16298
    * SPEC (1.4.3.2.1) "The {content type} of the {base type
16299
    * definition} must be empty.
16300
    * PASS
16301
    */
16302
0
      } else {
16303
    /*
16304
    * SPEC (1.4.3.2.2) "All of the following must be true:"
16305
    */
16306
0
    if ((type->contentType != base->contentType) ||
16307
0
        ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16308
0
        (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16309
        /*
16310
        * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16311
        * or both must be element-only."
16312
        */
16313
0
        xmlSchemaPCustomErr(ctxt,
16314
0
      XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16315
0
      WXS_BASIC_CAST type, NULL,
16316
0
      "The content type of both, the type and its base "
16317
0
      "type, must either 'mixed' or 'element-only'", NULL);
16318
0
        return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16319
0
    }
16320
    /*
16321
    * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16322
    * complex type definition must be a `valid extension`
16323
    * of the {base type definition}'s particle, as defined
16324
    * in Particle Valid (Extension) ($3.9.6)."
16325
    *
16326
    * NOTE that we won't check "Particle Valid (Extension)",
16327
    * since it is ensured by the derivation process in
16328
    * xmlSchemaTypeFixup(). We need to implement this when heading
16329
    * for a construction API
16330
    * TODO: !! This is needed to be checked if redefining a type !!
16331
    */
16332
0
      }
16333
      /*
16334
      * URGENT TODO (1.5)
16335
      */
16336
0
  }
16337
0
    } else {
16338
  /*
16339
  * SPEC (2) "If the {base type definition} is a simple type definition,
16340
  * then all of the following must be true:"
16341
  */
16342
0
  if (type->contentTypeDef != base) {
16343
      /*
16344
      * SPEC (2.1) "The {content type} must be the same simple type
16345
      * definition."
16346
      */
16347
0
      xmlSchemaPCustomErr(ctxt,
16348
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16349
0
    WXS_BASIC_CAST type, NULL,
16350
0
    "The content type must be the simple base type", NULL);
16351
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16352
0
  }
16353
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16354
      /*
16355
      * SPEC (2.2) "The {final} of the {base type definition} must not
16356
      * contain extension"
16357
      * NOTE that this is the same as (1.1).
16358
      */
16359
0
      xmlSchemaPCustomErr(ctxt,
16360
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16361
0
    WXS_BASIC_CAST type, NULL,
16362
0
    "The 'final' of the base type definition "
16363
0
    "contains 'extension'", NULL);
16364
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16365
0
  }
16366
0
    }
16367
0
    return (0);
16368
0
}
16369
16370
/**
16371
 * xmlSchemaCheckDerivationOKRestriction:
16372
 * @ctxt:  the schema parser context
16373
 * @type:  the complex type definition
16374
 *
16375
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16376
 * Schema Component Constraint:
16377
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16378
 *
16379
 * STATUS:
16380
 *   missing:
16381
 *     (5.4.2) ???
16382
 *
16383
 * ATTENTION:
16384
 * In XML Schema 1.1 this will be:
16385
 * Validation Rule: Checking complex type subsumption
16386
 *
16387
 * Returns 0 if the constraints are satisfied, a positive
16388
 * error code if not and -1 if an internal error occurred.
16389
 */
16390
static int
16391
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16392
              xmlSchemaTypePtr type)
16393
0
{
16394
0
    xmlSchemaTypePtr base;
16395
16396
    /*
16397
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16398
    * temporarily only.
16399
    */
16400
0
    base = type->baseType;
16401
0
    if (! WXS_IS_COMPLEX(base)) {
16402
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16403
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16404
0
      type->node, WXS_BASIC_CAST type,
16405
0
      "The base type must be a complex type", NULL, NULL);
16406
0
  return(ctxt->err);
16407
0
    }
16408
0
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16409
  /*
16410
  * SPEC (1) "The {base type definition} must be a complex type
16411
  * definition whose {final} does not contain restriction."
16412
  */
16413
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16414
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16415
0
      type->node, WXS_BASIC_CAST type,
16416
0
      "The 'final' of the base type definition "
16417
0
      "contains 'restriction'", NULL, NULL);
16418
0
  return (ctxt->err);
16419
0
    }
16420
    /*
16421
    * SPEC (2), (3) and (4)
16422
    * Those are handled in a separate function, since the
16423
    * same constraints are needed for redefinition of
16424
    * attribute groups as well.
16425
    */
16426
0
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16427
0
  XML_SCHEMA_ACTION_DERIVE,
16428
0
  WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16429
0
  type->attrUses, base->attrUses,
16430
0
  type->attributeWildcard,
16431
0
  base->attributeWildcard) == -1)
16432
0
    {
16433
0
  return(-1);
16434
0
    }
16435
    /*
16436
    * SPEC (5) "One of the following must be true:"
16437
    */
16438
0
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16439
  /*
16440
  * SPEC (5.1) "The {base type definition} must be the
16441
  * `ur-type definition`."
16442
  * PASS
16443
  */
16444
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16445
0
      (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16446
  /*
16447
  * SPEC (5.2.1) "The {content type} of the complex type definition
16448
  * must be a simple type definition"
16449
  *
16450
  * SPEC (5.2.2) "One of the following must be true:"
16451
  */
16452
0
  if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16453
0
      (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16454
0
  {
16455
0
      int err;
16456
      /*
16457
      * SPEC (5.2.2.1) "The {content type} of the {base type
16458
      * definition} must be a simple type definition from which
16459
      * the {content type} is validly derived given the empty
16460
      * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16461
      *
16462
      * ATTENTION TODO: This seems not needed if the type implicitly
16463
      * derived from the base type.
16464
      *
16465
      */
16466
0
      err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16467
0
    type->contentTypeDef, base->contentTypeDef, 0);
16468
0
      if (err != 0) {
16469
0
    xmlChar *strA = NULL, *strB = NULL;
16470
16471
0
    if (err == -1)
16472
0
        return(-1);
16473
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16474
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16475
0
        NULL, WXS_BASIC_CAST type,
16476
0
        "The {content type} %s is not validly derived from the "
16477
0
        "base type's {content type} %s",
16478
0
        xmlSchemaGetComponentDesignation(&strA,
16479
0
      type->contentTypeDef),
16480
0
        xmlSchemaGetComponentDesignation(&strB,
16481
0
      base->contentTypeDef));
16482
0
    FREE_AND_NULL(strA);
16483
0
    FREE_AND_NULL(strB);
16484
0
    return(ctxt->err);
16485
0
      }
16486
0
  } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16487
0
      (xmlSchemaIsParticleEmptiable(
16488
0
    (xmlSchemaParticlePtr) base->subtypes))) {
16489
      /*
16490
      * SPEC (5.2.2.2) "The {base type definition} must be mixed
16491
      * and have a particle which is `emptiable` as defined in
16492
      * Particle Emptiable ($3.9.6)."
16493
      * PASS
16494
      */
16495
0
  } else {
16496
0
      xmlSchemaPCustomErr(ctxt,
16497
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16498
0
    WXS_BASIC_CAST type, NULL,
16499
0
    "The content type of the base type must be either "
16500
0
    "a simple type or 'mixed' and an emptiable particle", NULL);
16501
0
      return (ctxt->err);
16502
0
  }
16503
0
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16504
  /*
16505
  * SPEC (5.3.1) "The {content type} of the complex type itself must
16506
  * be empty"
16507
  */
16508
0
  if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16509
      /*
16510
      * SPEC (5.3.2.1) "The {content type} of the {base type
16511
      * definition} must also be empty."
16512
      * PASS
16513
      */
16514
0
  } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16515
0
      (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16516
0
      xmlSchemaIsParticleEmptiable(
16517
0
    (xmlSchemaParticlePtr) base->subtypes)) {
16518
      /*
16519
      * SPEC (5.3.2.2) "The {content type} of the {base type
16520
      * definition} must be elementOnly or mixed and have a particle
16521
      * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16522
      * PASS
16523
      */
16524
0
  } else {
16525
0
      xmlSchemaPCustomErr(ctxt,
16526
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16527
0
    WXS_BASIC_CAST type, NULL,
16528
0
    "The content type of the base type must be either "
16529
0
    "empty or 'mixed' (or 'elements-only') and an emptiable "
16530
0
    "particle", NULL);
16531
0
      return (ctxt->err);
16532
0
  }
16533
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16534
0
  WXS_HAS_MIXED_CONTENT(type)) {
16535
  /*
16536
  * SPEC (5.4.1.1) "The {content type} of the complex type definition
16537
  * itself must be element-only"
16538
  */
16539
0
  if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16540
      /*
16541
      * SPEC (5.4.1.2) "The {content type} of the complex type
16542
      * definition itself and of the {base type definition} must be
16543
      * mixed"
16544
      */
16545
0
      xmlSchemaPCustomErr(ctxt,
16546
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16547
0
    WXS_BASIC_CAST type, NULL,
16548
0
    "If the content type is 'mixed', then the content type of the "
16549
0
    "base type must also be 'mixed'", NULL);
16550
0
      return (ctxt->err);
16551
0
  }
16552
  /*
16553
  * SPEC (5.4.2) "The particle of the complex type definition itself
16554
  * must be a `valid restriction` of the particle of the {content
16555
  * type} of the {base type definition} as defined in Particle Valid
16556
  * (Restriction) ($3.9.6).
16557
  *
16558
  * URGENT TODO: (5.4.2)
16559
  */
16560
0
    } else {
16561
0
  xmlSchemaPCustomErr(ctxt,
16562
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16563
0
      WXS_BASIC_CAST type, NULL,
16564
0
      "The type is not a valid restriction of its base type", NULL);
16565
0
  return (ctxt->err);
16566
0
    }
16567
0
    return (0);
16568
0
}
16569
16570
/**
16571
 * xmlSchemaCheckCTComponent:
16572
 * @ctxt:  the schema parser context
16573
 * @type:  the complex type definition
16574
 *
16575
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16576
 *
16577
 * Returns 0 if the constraints are satisfied, a positive
16578
 * error code if not and -1 if an internal error occurred.
16579
 */
16580
static int
16581
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16582
        xmlSchemaTypePtr type)
16583
0
{
16584
0
    int ret;
16585
    /*
16586
    * Complex Type Definition Properties Correct
16587
    */
16588
0
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16589
0
    if (ret != 0)
16590
0
  return (ret);
16591
0
    if (WXS_IS_EXTENSION(type))
16592
0
  ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16593
0
    else
16594
0
  ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16595
0
    return (ret);
16596
0
}
16597
16598
/**
16599
 * xmlSchemaCheckSRCCT:
16600
 * @ctxt:  the schema parser context
16601
 * @type:  the complex type definition
16602
 *
16603
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16604
 * Schema Representation Constraint:
16605
 * Complex Type Definition Representation OK (src-ct)
16606
 *
16607
 * Returns 0 if the constraints are satisfied, a positive
16608
 * error code if not and -1 if an internal error occurred.
16609
 */
16610
static int
16611
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16612
        xmlSchemaTypePtr type)
16613
0
{
16614
0
    xmlSchemaTypePtr base;
16615
0
    int ret = 0;
16616
16617
    /*
16618
    * TODO: Adjust the error codes here, as I used
16619
    * XML_SCHEMAP_SRC_CT_1 only yet.
16620
    */
16621
0
    base = type->baseType;
16622
0
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16623
  /*
16624
  * 1 If the <complexContent> alternative is chosen, the type definition
16625
  * `resolved` to by the `actual value` of the base [attribute]
16626
  * must be a complex type definition;
16627
  */
16628
0
  if (! WXS_IS_COMPLEX(base)) {
16629
0
      xmlChar *str = NULL;
16630
0
      xmlSchemaPCustomErr(ctxt,
16631
0
    XML_SCHEMAP_SRC_CT_1,
16632
0
    WXS_BASIC_CAST type, type->node,
16633
0
    "If using <complexContent>, the base type is expected to be "
16634
0
    "a complex type. The base type '%s' is a simple type",
16635
0
    xmlSchemaFormatQName(&str, base->targetNamespace,
16636
0
    base->name));
16637
0
      FREE_AND_NULL(str)
16638
0
      return (XML_SCHEMAP_SRC_CT_1);
16639
0
  }
16640
0
    } else {
16641
  /*
16642
  * SPEC
16643
  * 2 If the <simpleContent> alternative is chosen, all of the
16644
  * following must be true:
16645
  * 2.1 The type definition `resolved` to by the `actual value` of the
16646
  * base [attribute] must be one of the following:
16647
  */
16648
0
  if (WXS_IS_SIMPLE(base)) {
16649
0
      if (WXS_IS_EXTENSION(type) == 0) {
16650
0
    xmlChar *str = NULL;
16651
    /*
16652
    * 2.1.3 only if the <extension> alternative is also
16653
    * chosen, a simple type definition.
16654
    */
16655
    /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16656
0
    xmlSchemaPCustomErr(ctxt,
16657
0
        XML_SCHEMAP_SRC_CT_1,
16658
0
        WXS_BASIC_CAST type, NULL,
16659
0
        "If using <simpleContent> and <restriction>, the base "
16660
0
        "type must be a complex type. The base type '%s' is "
16661
0
        "a simple type",
16662
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16663
0
      base->name));
16664
0
    FREE_AND_NULL(str)
16665
0
    return (XML_SCHEMAP_SRC_CT_1);
16666
0
      }
16667
0
  } else {
16668
      /* Base type is a complex type. */
16669
0
      if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16670
0
    (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16671
    /*
16672
    * 2.1.1 a complex type definition whose {content type} is a
16673
    * simple type definition;
16674
    * PASS
16675
    */
16676
0
    if (base->contentTypeDef == NULL) {
16677
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16678
0
      WXS_BASIC_CAST type, NULL,
16679
0
      "Internal error: xmlSchemaCheckSRCCT, "
16680
0
      "'%s', base type has no content type",
16681
0
      type->name);
16682
0
        return (-1);
16683
0
    }
16684
0
      } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16685
0
    (WXS_IS_RESTRICTION(type))) {
16686
16687
    /*
16688
    * 2.1.2 only if the <restriction> alternative is also
16689
    * chosen, a complex type definition whose {content type}
16690
    * is mixed and a particle emptiable.
16691
    */
16692
0
    if (! xmlSchemaIsParticleEmptiable(
16693
0
        (xmlSchemaParticlePtr) base->subtypes)) {
16694
0
        ret = XML_SCHEMAP_SRC_CT_1;
16695
0
    } else
16696
        /*
16697
        * Attention: at this point the <simpleType> child is in
16698
        * ->contentTypeDef (put there during parsing).
16699
        */
16700
0
        if (type->contentTypeDef == NULL) {
16701
0
        xmlChar *str = NULL;
16702
        /*
16703
        * 2.2 If clause 2.1.2 above is satisfied, then there
16704
        * must be a <simpleType> among the [children] of
16705
        * <restriction>.
16706
        */
16707
        /* TODO: Change error code to ..._SRC_CT_2_2. */
16708
0
        xmlSchemaPCustomErr(ctxt,
16709
0
      XML_SCHEMAP_SRC_CT_1,
16710
0
      WXS_BASIC_CAST type, NULL,
16711
0
      "A <simpleType> is expected among the children "
16712
0
      "of <restriction>, if <simpleContent> is used and "
16713
0
      "the base type '%s' is a complex type",
16714
0
      xmlSchemaFormatQName(&str, base->targetNamespace,
16715
0
      base->name));
16716
0
        FREE_AND_NULL(str)
16717
0
        return (XML_SCHEMAP_SRC_CT_1);
16718
0
    }
16719
0
      } else {
16720
0
    ret = XML_SCHEMAP_SRC_CT_1;
16721
0
      }
16722
0
  }
16723
0
  if (ret > 0) {
16724
0
      xmlChar *str = NULL;
16725
0
      if (WXS_IS_RESTRICTION(type)) {
16726
0
    xmlSchemaPCustomErr(ctxt,
16727
0
        XML_SCHEMAP_SRC_CT_1,
16728
0
        WXS_BASIC_CAST type, NULL,
16729
0
        "If <simpleContent> and <restriction> is used, the "
16730
0
        "base type must be a simple type or a complex type with "
16731
0
        "mixed content and particle emptiable. The base type "
16732
0
        "'%s' is none of those",
16733
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16734
0
        base->name));
16735
0
      } else {
16736
0
    xmlSchemaPCustomErr(ctxt,
16737
0
        XML_SCHEMAP_SRC_CT_1,
16738
0
        WXS_BASIC_CAST type, NULL,
16739
0
        "If <simpleContent> and <extension> is used, the "
16740
0
        "base type must be a simple type. The base type '%s' "
16741
0
        "is a complex type",
16742
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16743
0
        base->name));
16744
0
      }
16745
0
      FREE_AND_NULL(str)
16746
0
  }
16747
0
    }
16748
    /*
16749
    * SPEC (3) "The corresponding complex type definition component must
16750
    * satisfy the conditions set out in Constraints on Complex Type
16751
    * Definition Schema Components ($3.4.6);"
16752
    * NOTE (3) will be done in xmlSchemaTypeFixup().
16753
    */
16754
    /*
16755
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16756
    * above for {attribute wildcard} is satisfied, the intensional
16757
    * intersection must be expressible, as defined in Attribute Wildcard
16758
    * Intersection ($3.10.6).
16759
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16760
    */
16761
0
    return (ret);
16762
0
}
16763
16764
#ifdef ENABLE_PARTICLE_RESTRICTION
16765
/**
16766
 * xmlSchemaCheckParticleRangeOK:
16767
 * @ctxt:  the schema parser context
16768
 * @type:  the complex type definition
16769
 *
16770
 * (3.9.6) Constraints on Particle Schema Components
16771
 * Schema Component Constraint:
16772
 * Occurrence Range OK (range-ok)
16773
 *
16774
 * STATUS: complete
16775
 *
16776
 * Returns 0 if the constraints are satisfied, a positive
16777
 * error code if not and -1 if an internal error occurred.
16778
 */
16779
static int
16780
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16781
            int bmin, int bmax)
16782
{
16783
    if (rmin < bmin)
16784
  return (1);
16785
    if ((bmax != UNBOUNDED) &&
16786
  (rmax > bmax))
16787
  return (1);
16788
    return (0);
16789
}
16790
16791
/**
16792
 * xmlSchemaCheckRCaseNameAndTypeOK:
16793
 * @ctxt:  the schema parser context
16794
 * @r: the restricting element declaration particle
16795
 * @b: the base element declaration particle
16796
 *
16797
 * (3.9.6) Constraints on Particle Schema Components
16798
 * Schema Component Constraint:
16799
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16800
 * (rcase-NameAndTypeOK)
16801
 *
16802
 * STATUS:
16803
 *   MISSING (3.2.3)
16804
 *   CLARIFY: (3.2.2)
16805
 *
16806
 * Returns 0 if the constraints are satisfied, a positive
16807
 * error code if not and -1 if an internal error occurred.
16808
 */
16809
static int
16810
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16811
         xmlSchemaParticlePtr r,
16812
         xmlSchemaParticlePtr b)
16813
{
16814
    xmlSchemaElementPtr elemR, elemB;
16815
16816
    /* TODO: Error codes (rcase-NameAndTypeOK). */
16817
    elemR = (xmlSchemaElementPtr) r->children;
16818
    elemB = (xmlSchemaElementPtr) b->children;
16819
    /*
16820
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
16821
    * the same."
16822
    */
16823
    if ((elemR != elemB) &&
16824
  ((! xmlStrEqual(elemR->name, elemB->name)) ||
16825
  (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16826
  return (1);
16827
    /*
16828
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16829
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16830
    */
16831
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16832
      b->minOccurs, b->maxOccurs) != 0)
16833
  return (1);
16834
    /*
16835
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16836
    * {scope} are global."
16837
    */
16838
    if (elemR == elemB)
16839
  return (0);
16840
    /*
16841
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16842
    */
16843
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16844
  (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16845
   return (1);
16846
    /*
16847
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16848
    * or is not fixed, or R's declaration's {value constraint} is fixed
16849
    * with the same value."
16850
    */
16851
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16852
  ((elemR->value == NULL) ||
16853
   ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16854
   /* TODO: Equality of the initial value or normalized or canonical? */
16855
   (! xmlStrEqual(elemR->value, elemB->value))))
16856
   return (1);
16857
    /*
16858
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16859
    * definitions} is a subset of B's declaration's {identity-constraint
16860
    * definitions}, if any."
16861
    */
16862
    if (elemB->idcs != NULL) {
16863
  /* TODO */
16864
    }
16865
    /*
16866
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16867
    * superset of B's declaration's {disallowed substitutions}."
16868
    */
16869
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16870
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16871
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16872
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16873
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16874
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16875
   return (1);
16876
    /*
16877
    * SPEC (3.2.5) "R's {type definition} is validly derived given
16878
    * {extension, list, union} from B's {type definition}"
16879
    *
16880
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
16881
    * set, if the corresponding constraints handle "restriction" and
16882
    * "extension" only?
16883
    *
16884
    */
16885
    {
16886
  int set = 0;
16887
16888
  set |= SUBSET_EXTENSION;
16889
  set |= SUBSET_LIST;
16890
  set |= SUBSET_UNION;
16891
  if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16892
      elemB->subtypes, set) != 0)
16893
      return (1);
16894
    }
16895
    return (0);
16896
}
16897
16898
/**
16899
 * xmlSchemaCheckRCaseNSCompat:
16900
 * @ctxt:  the schema parser context
16901
 * @r: the restricting element declaration particle
16902
 * @b: the base wildcard particle
16903
 *
16904
 * (3.9.6) Constraints on Particle Schema Components
16905
 * Schema Component Constraint:
16906
 * Particle Derivation OK (Elt:Any -- NSCompat)
16907
 * (rcase-NSCompat)
16908
 *
16909
 * STATUS: complete
16910
 *
16911
 * Returns 0 if the constraints are satisfied, a positive
16912
 * error code if not and -1 if an internal error occurred.
16913
 */
16914
static int
16915
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16916
          xmlSchemaParticlePtr r,
16917
          xmlSchemaParticlePtr b)
16918
{
16919
    /* TODO:Error codes (rcase-NSCompat). */
16920
    /*
16921
    * SPEC "For an element declaration particle to be a `valid restriction`
16922
    * of a wildcard particle all of the following must be true:"
16923
    *
16924
    * SPEC (1) "The element declaration's {target namespace} is `valid`
16925
    * with respect to the wildcard's {namespace constraint} as defined by
16926
    * Wildcard allows Namespace Name ($3.10.4)."
16927
    */
16928
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16929
  ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16930
  return (1);
16931
    /*
16932
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16933
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16934
    */
16935
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16936
      b->minOccurs, b->maxOccurs) != 0)
16937
  return (1);
16938
16939
    return (0);
16940
}
16941
16942
/**
16943
 * xmlSchemaCheckRCaseRecurseAsIfGroup:
16944
 * @ctxt:  the schema parser context
16945
 * @r: the restricting element declaration particle
16946
 * @b: the base model group particle
16947
 *
16948
 * (3.9.6) Constraints on Particle Schema Components
16949
 * Schema Component Constraint:
16950
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16951
 * (rcase-RecurseAsIfGroup)
16952
 *
16953
 * STATUS: TODO
16954
 *
16955
 * Returns 0 if the constraints are satisfied, a positive
16956
 * error code if not and -1 if an internal error occurred.
16957
 */
16958
static int
16959
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16960
            xmlSchemaParticlePtr r,
16961
            xmlSchemaParticlePtr b)
16962
{
16963
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16964
    TODO
16965
    return (0);
16966
}
16967
16968
/**
16969
 * xmlSchemaCheckRCaseNSSubset:
16970
 * @ctxt:  the schema parser context
16971
 * @r: the restricting wildcard particle
16972
 * @b: the base wildcard particle
16973
 *
16974
 * (3.9.6) Constraints on Particle Schema Components
16975
 * Schema Component Constraint:
16976
 * Particle Derivation OK (Any:Any -- NSSubset)
16977
 * (rcase-NSSubset)
16978
 *
16979
 * STATUS: complete
16980
 *
16981
 * Returns 0 if the constraints are satisfied, a positive
16982
 * error code if not and -1 if an internal error occurred.
16983
 */
16984
static int
16985
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16986
            xmlSchemaParticlePtr r,
16987
            xmlSchemaParticlePtr b,
16988
            int isAnyTypeBase)
16989
{
16990
    /* TODO: Error codes (rcase-NSSubset). */
16991
    /*
16992
    * SPEC (1) "R's occurrence range is a valid restriction of B's
16993
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16994
    */
16995
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16996
      b->minOccurs, b->maxOccurs))
16997
  return (1);
16998
    /*
16999
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
17000
    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17001
    */
17002
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
17003
  (xmlSchemaWildcardPtr) b->children))
17004
  return (1);
17005
    /*
17006
    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17007
    * definition`, R's {process contents} must be identical to or stronger
17008
    * than B's {process contents}, where strict is stronger than lax is
17009
    * stronger than skip."
17010
    */
17011
    if (! isAnyTypeBase) {
17012
  if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17013
      ((xmlSchemaWildcardPtr) b->children)->processContents)
17014
      return (1);
17015
    }
17016
17017
    return (0);
17018
}
17019
17020
/**
17021
 * xmlSchemaCheckCOSParticleRestrict:
17022
 * @ctxt:  the schema parser context
17023
 * @type:  the complex type definition
17024
 *
17025
 * (3.9.6) Constraints on Particle Schema Components
17026
 * Schema Component Constraint:
17027
 * Particle Valid (Restriction) (cos-particle-restrict)
17028
 *
17029
 * STATUS: TODO
17030
 *
17031
 * Returns 0 if the constraints are satisfied, a positive
17032
 * error code if not and -1 if an internal error occurred.
17033
 */
17034
static int
17035
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17036
          xmlSchemaParticlePtr r,
17037
          xmlSchemaParticlePtr b)
17038
{
17039
    int ret = 0;
17040
17041
    /*part = WXS_TYPE_PARTICLE(type);
17042
    basePart = WXS_TYPE_PARTICLE(base);
17043
    */
17044
17045
    TODO
17046
17047
    /*
17048
    * SPEC (1) "They are the same particle."
17049
    */
17050
    if (r == b)
17051
  return (0);
17052
17053
17054
    return (0);
17055
}
17056
17057
#if 0
17058
/**
17059
 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17060
 * @ctxt:  the schema parser context
17061
 * @r: the model group particle
17062
 * @b: the base wildcard particle
17063
 *
17064
 * (3.9.6) Constraints on Particle Schema Components
17065
 * Schema Component Constraint:
17066
 * Particle Derivation OK (All/Choice/Sequence:Any --
17067
 *                         NSRecurseCheckCardinality)
17068
 * (rcase-NSRecurseCheckCardinality)
17069
 *
17070
 * STATUS: TODO: subst-groups
17071
 *
17072
 * Returns 0 if the constraints are satisfied, a positive
17073
 * error code if not and -1 if an internal error occurred.
17074
 */
17075
static int
17076
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17077
               xmlSchemaParticlePtr r,
17078
               xmlSchemaParticlePtr b)
17079
{
17080
    xmlSchemaParticlePtr part;
17081
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17082
    if ((r->children == NULL) || (r->children->children == NULL))
17083
  return (-1);
17084
    /*
17085
    * SPEC "For a group particle to be a `valid restriction` of a
17086
    * wildcard particle..."
17087
    *
17088
    * SPEC (1) "Every member of the {particles} of the group is a `valid
17089
    * restriction` of the wildcard as defined by
17090
    * Particle Valid (Restriction) ($3.9.6)."
17091
    */
17092
    part = (xmlSchemaParticlePtr) r->children->children;
17093
    do {
17094
  if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17095
      return (1);
17096
  part = (xmlSchemaParticlePtr) part->next;
17097
    } while (part != NULL);
17098
    /*
17099
    * SPEC (2) "The effective total range of the group [...] is a
17100
    * valid restriction of B's occurrence range as defined by
17101
    * Occurrence Range OK ($3.9.6)."
17102
    */
17103
    if (xmlSchemaCheckParticleRangeOK(
17104
      xmlSchemaGetParticleTotalRangeMin(r),
17105
      xmlSchemaGetParticleTotalRangeMax(r),
17106
      b->minOccurs, b->maxOccurs) != 0)
17107
  return (1);
17108
    return (0);
17109
}
17110
#endif
17111
17112
/**
17113
 * xmlSchemaCheckRCaseRecurse:
17114
 * @ctxt:  the schema parser context
17115
 * @r: the <all> or <sequence> model group particle
17116
 * @b: the base <all> or <sequence> model group particle
17117
 *
17118
 * (3.9.6) Constraints on Particle Schema Components
17119
 * Schema Component Constraint:
17120
 * Particle Derivation OK (All:All,Sequence:Sequence --
17121
                           Recurse)
17122
 * (rcase-Recurse)
17123
 *
17124
 * STATUS:  ?
17125
 * TODO: subst-groups
17126
 *
17127
 * Returns 0 if the constraints are satisfied, a positive
17128
 * error code if not and -1 if an internal error occurred.
17129
 */
17130
static int
17131
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17132
         xmlSchemaParticlePtr r,
17133
         xmlSchemaParticlePtr b)
17134
{
17135
    /* xmlSchemaParticlePtr part; */
17136
    /* TODO: Error codes (rcase-Recurse). */
17137
    if ((r->children == NULL) || (b->children == NULL) ||
17138
  (r->children->type != b->children->type))
17139
  return (-1);
17140
    /*
17141
    * SPEC "For an all or sequence group particle to be a `valid
17142
    * restriction` of another group particle with the same {compositor}..."
17143
    *
17144
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17145
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17146
    */
17147
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17148
      b->minOccurs, b->maxOccurs))
17149
  return (1);
17150
17151
17152
    return (0);
17153
}
17154
17155
#endif
17156
17157
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17158
0
    xmlSchemaPCustomErrExt(pctxt,      \
17159
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17160
0
  WXS_BASIC_CAST fac1, fac1->node, \
17161
0
  "It is an error for both '%s' and '%s' to be specified on the "\
17162
0
  "same type definition", \
17163
0
  BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17164
0
  BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17165
17166
#define FACET_RESTR_ERR(fac1, msg) \
17167
0
    xmlSchemaPCustomErr(pctxt,      \
17168
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17169
0
  WXS_BASIC_CAST fac1, fac1->node, \
17170
0
  msg, NULL);
17171
17172
#define FACET_RESTR_FIXED_ERR(fac) \
17173
0
    xmlSchemaPCustomErr(pctxt, \
17174
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17175
0
  WXS_BASIC_CAST fac, fac->node, \
17176
0
  "The base type's facet is 'fixed', thus the value must not " \
17177
0
  "differ", NULL);
17178
17179
static void
17180
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17181
      xmlSchemaFacetPtr facet1,
17182
      xmlSchemaFacetPtr facet2,
17183
      int lessGreater,
17184
      int orEqual,
17185
      int ofBase)
17186
0
{
17187
0
    xmlChar *msg = NULL;
17188
17189
0
    msg = xmlStrdup(BAD_CAST "'");
17190
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17191
0
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
17192
0
    if (lessGreater == 0)
17193
0
  msg = xmlStrcat(msg, BAD_CAST " equal to");
17194
0
    if (lessGreater == 1)
17195
0
  msg = xmlStrcat(msg, BAD_CAST " greater than");
17196
0
    else
17197
0
  msg = xmlStrcat(msg, BAD_CAST " less than");
17198
17199
0
    if (orEqual)
17200
0
  msg = xmlStrcat(msg, BAD_CAST " or equal to");
17201
0
    msg = xmlStrcat(msg, BAD_CAST " '");
17202
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17203
0
    if (ofBase)
17204
0
  msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17205
0
    else
17206
0
  msg = xmlStrcat(msg, BAD_CAST "'");
17207
17208
0
    xmlSchemaPCustomErr(pctxt,
17209
0
  XML_SCHEMAP_INVALID_FACET_VALUE,
17210
0
  WXS_BASIC_CAST facet1, NULL,
17211
0
  (const char *) msg, NULL);
17212
17213
0
    if (msg != NULL)
17214
0
  xmlFree(msg);
17215
0
}
17216
17217
/*
17218
* xmlSchemaDeriveAndValidateFacets:
17219
*
17220
* Schema Component Constraint: Simple Type Restriction (Facets)
17221
* (st-restrict-facets)
17222
*/
17223
static int
17224
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17225
         xmlSchemaTypePtr type)
17226
0
{
17227
0
    xmlSchemaTypePtr base = type->baseType;
17228
0
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
17229
0
    xmlSchemaFacetPtr facet, bfacet,
17230
0
  flength = NULL, ftotdig = NULL, ffracdig = NULL,
17231
0
  fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17232
0
  fmininc = NULL, fmaxinc = NULL,
17233
0
  fminexc = NULL, fmaxexc = NULL,
17234
0
  bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17235
0
  bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17236
0
  bfmininc = NULL, bfmaxinc = NULL,
17237
0
  bfminexc = NULL, bfmaxexc = NULL;
17238
0
    int res; /* err = 0, fixedErr; */
17239
17240
    /*
17241
    * SPEC st-restrict-facets 1:
17242
    * "The {variety} of R is the same as that of B."
17243
    */
17244
    /*
17245
    * SPEC st-restrict-facets 2:
17246
    * "If {variety} is atomic, the {primitive type definition}
17247
    * of R is the same as that of B."
17248
    *
17249
    * NOTE: we leave 1 & 2 out for now, since this will be
17250
    * satisfied by the derivation process.
17251
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
17252
    */
17253
    /*
17254
    * SPEC st-restrict-facets 3:
17255
    * "The {facets} of R are the union of S and the {facets}
17256
    * of B, eliminating duplicates. To eliminate duplicates,
17257
    * when a facet of the same kind occurs in both S and the
17258
    * {facets} of B, the one in the {facets} of B is not
17259
    * included, with the exception of enumeration and pattern
17260
    * facets, for which multiple occurrences with distinct values
17261
    * are allowed."
17262
    */
17263
17264
0
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
17265
0
  return (0);
17266
17267
0
    last = type->facetSet;
17268
0
    if (last != NULL)
17269
0
  while (last->next != NULL)
17270
0
      last = last->next;
17271
17272
0
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17273
0
  facet = cur->facet;
17274
0
  switch (facet->type) {
17275
0
      case XML_SCHEMA_FACET_LENGTH:
17276
0
    flength = facet; break;
17277
0
      case XML_SCHEMA_FACET_MINLENGTH:
17278
0
    fminlen = facet; break;
17279
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17280
0
    fmininc = facet; break;
17281
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17282
0
    fminexc = facet; break;
17283
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17284
0
    fmaxlen = facet; break;
17285
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17286
0
    fmaxinc = facet; break;
17287
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17288
0
    fmaxexc = facet; break;
17289
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17290
0
    ftotdig = facet; break;
17291
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17292
0
    ffracdig = facet; break;
17293
0
      default:
17294
0
    break;
17295
0
  }
17296
0
    }
17297
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17298
0
  facet = cur->facet;
17299
0
  switch (facet->type) {
17300
0
      case XML_SCHEMA_FACET_LENGTH:
17301
0
    bflength = facet; break;
17302
0
      case XML_SCHEMA_FACET_MINLENGTH:
17303
0
    bfminlen = facet; break;
17304
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17305
0
    bfmininc = facet; break;
17306
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17307
0
    bfminexc = facet; break;
17308
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17309
0
    bfmaxlen = facet; break;
17310
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17311
0
    bfmaxinc = facet; break;
17312
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17313
0
    bfmaxexc = facet; break;
17314
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17315
0
    bftotdig = facet; break;
17316
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17317
0
    bffracdig = facet; break;
17318
0
      default:
17319
0
    break;
17320
0
  }
17321
0
    }
17322
    /*
17323
    * length and minLength or maxLength (2.2) + (3.2)
17324
    */
17325
0
    if (flength && (fminlen || fmaxlen)) {
17326
0
  FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17327
0
      "either of 'minLength' or 'maxLength' to be specified on "
17328
0
      "the same type definition")
17329
0
    }
17330
    /*
17331
    * Mutual exclusions in the same derivation step.
17332
    */
17333
0
    if ((fmaxinc) && (fmaxexc)) {
17334
  /*
17335
  * SCC "maxInclusive and maxExclusive"
17336
  */
17337
0
  FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17338
0
    }
17339
0
    if ((fmininc) && (fminexc)) {
17340
  /*
17341
  * SCC "minInclusive and minExclusive"
17342
  */
17343
0
  FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17344
0
    }
17345
17346
0
    if (flength && bflength) {
17347
  /*
17348
  * SCC "length valid restriction"
17349
  * The values have to be equal.
17350
  */
17351
0
  res = xmlSchemaCompareValues(flength->val, bflength->val);
17352
0
  if (res == -2)
17353
0
      goto internal_error;
17354
0
  if (res != 0)
17355
0
      xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17356
0
  if ((res != 0) && (bflength->fixed)) {
17357
0
      FACET_RESTR_FIXED_ERR(flength)
17358
0
  }
17359
17360
0
    }
17361
0
    if (fminlen && bfminlen) {
17362
  /*
17363
  * SCC "minLength valid restriction"
17364
  * minLength >= BASE minLength
17365
  */
17366
0
  res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17367
0
  if (res == -2)
17368
0
      goto internal_error;
17369
0
  if (res == -1)
17370
0
      xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17371
0
  if ((res != 0) && (bfminlen->fixed)) {
17372
0
      FACET_RESTR_FIXED_ERR(fminlen)
17373
0
  }
17374
0
    }
17375
0
    if (fmaxlen && bfmaxlen) {
17376
  /*
17377
  * SCC "maxLength valid restriction"
17378
  * maxLength <= BASE minLength
17379
  */
17380
0
  res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17381
0
  if (res == -2)
17382
0
      goto internal_error;
17383
0
  if (res == 1)
17384
0
      xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17385
0
  if ((res != 0) && (bfmaxlen->fixed)) {
17386
0
      FACET_RESTR_FIXED_ERR(fmaxlen)
17387
0
  }
17388
0
    }
17389
    /*
17390
    * SCC "length and minLength or maxLength"
17391
    */
17392
0
    if (! flength)
17393
0
  flength = bflength;
17394
0
    if (flength) {
17395
0
  if (! fminlen)
17396
0
      fminlen = bfminlen;
17397
0
  if (fminlen) {
17398
      /* (1.1) length >= minLength */
17399
0
      res = xmlSchemaCompareValues(flength->val, fminlen->val);
17400
0
      if (res == -2)
17401
0
    goto internal_error;
17402
0
      if (res == -1)
17403
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17404
0
  }
17405
0
  if (! fmaxlen)
17406
0
      fmaxlen = bfmaxlen;
17407
0
  if (fmaxlen) {
17408
      /* (2.1) length <= maxLength */
17409
0
      res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17410
0
      if (res == -2)
17411
0
    goto internal_error;
17412
0
      if (res == 1)
17413
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17414
0
  }
17415
0
    }
17416
0
    if (fmaxinc) {
17417
  /*
17418
  * "maxInclusive"
17419
  */
17420
0
  if (fmininc) {
17421
      /* SCC "maxInclusive >= minInclusive" */
17422
0
      res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17423
0
      if (res == -2)
17424
0
    goto internal_error;
17425
0
      if (res == -1) {
17426
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17427
0
      }
17428
0
  }
17429
  /*
17430
  * SCC "maxInclusive valid restriction"
17431
  */
17432
0
  if (bfmaxinc) {
17433
      /* maxInclusive <= BASE maxInclusive */
17434
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17435
0
      if (res == -2)
17436
0
    goto internal_error;
17437
0
      if (res == 1)
17438
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17439
0
      if ((res != 0) && (bfmaxinc->fixed)) {
17440
0
    FACET_RESTR_FIXED_ERR(fmaxinc)
17441
0
      }
17442
0
  }
17443
0
  if (bfmaxexc) {
17444
      /* maxInclusive < BASE maxExclusive */
17445
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17446
0
      if (res == -2)
17447
0
    goto internal_error;
17448
0
      if (res != -1) {
17449
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17450
0
      }
17451
0
  }
17452
0
  if (bfmininc) {
17453
      /* maxInclusive >= BASE minInclusive */
17454
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17455
0
      if (res == -2)
17456
0
    goto internal_error;
17457
0
      if (res == -1) {
17458
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17459
0
      }
17460
0
  }
17461
0
  if (bfminexc) {
17462
      /* maxInclusive > BASE minExclusive */
17463
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17464
0
      if (res == -2)
17465
0
    goto internal_error;
17466
0
      if (res != 1) {
17467
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17468
0
      }
17469
0
  }
17470
0
    }
17471
0
    if (fmaxexc) {
17472
  /*
17473
  * "maxExclusive >= minExclusive"
17474
  */
17475
0
  if (fminexc) {
17476
0
      res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17477
0
      if (res == -2)
17478
0
    goto internal_error;
17479
0
      if (res == -1) {
17480
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17481
0
      }
17482
0
  }
17483
  /*
17484
  * "maxExclusive valid restriction"
17485
  */
17486
0
  if (bfmaxexc) {
17487
      /* maxExclusive <= BASE maxExclusive */
17488
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17489
0
      if (res == -2)
17490
0
    goto internal_error;
17491
0
      if (res == 1) {
17492
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17493
0
      }
17494
0
      if ((res != 0) && (bfmaxexc->fixed)) {
17495
0
    FACET_RESTR_FIXED_ERR(fmaxexc)
17496
0
      }
17497
0
  }
17498
0
  if (bfmaxinc) {
17499
      /* maxExclusive <= BASE maxInclusive */
17500
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17501
0
      if (res == -2)
17502
0
    goto internal_error;
17503
0
      if (res == 1) {
17504
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17505
0
      }
17506
0
  }
17507
0
  if (bfmininc) {
17508
      /* maxExclusive > BASE minInclusive */
17509
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17510
0
      if (res == -2)
17511
0
    goto internal_error;
17512
0
      if (res != 1) {
17513
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17514
0
      }
17515
0
  }
17516
0
  if (bfminexc) {
17517
      /* maxExclusive > BASE minExclusive */
17518
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17519
0
      if (res == -2)
17520
0
    goto internal_error;
17521
0
      if (res != 1) {
17522
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17523
0
      }
17524
0
  }
17525
0
    }
17526
0
    if (fminexc) {
17527
  /*
17528
  * "minExclusive < maxInclusive"
17529
  */
17530
0
  if (fmaxinc) {
17531
0
      res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17532
0
      if (res == -2)
17533
0
    goto internal_error;
17534
0
      if (res != -1) {
17535
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17536
0
      }
17537
0
  }
17538
  /*
17539
  * "minExclusive valid restriction"
17540
  */
17541
0
  if (bfminexc) {
17542
      /* minExclusive >= BASE minExclusive */
17543
0
      res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17544
0
      if (res == -2)
17545
0
    goto internal_error;
17546
0
      if (res == -1) {
17547
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17548
0
      }
17549
0
      if ((res != 0) && (bfminexc->fixed)) {
17550
0
    FACET_RESTR_FIXED_ERR(fminexc)
17551
0
      }
17552
0
  }
17553
0
  if (bfmaxinc) {
17554
      /* minExclusive <= BASE maxInclusive */
17555
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17556
0
      if (res == -2)
17557
0
    goto internal_error;
17558
0
      if (res == 1) {
17559
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17560
0
      }
17561
0
  }
17562
0
  if (bfmininc) {
17563
      /* minExclusive >= BASE minInclusive */
17564
0
      res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17565
0
      if (res == -2)
17566
0
    goto internal_error;
17567
0
      if (res == -1) {
17568
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17569
0
      }
17570
0
  }
17571
0
  if (bfmaxexc) {
17572
      /* minExclusive < BASE maxExclusive */
17573
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17574
0
      if (res == -2)
17575
0
    goto internal_error;
17576
0
      if (res != -1) {
17577
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17578
0
      }
17579
0
  }
17580
0
    }
17581
0
    if (fmininc) {
17582
  /*
17583
  * "minInclusive < maxExclusive"
17584
  */
17585
0
  if (fmaxexc) {
17586
0
      res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17587
0
      if (res == -2)
17588
0
    goto internal_error;
17589
0
      if (res != -1) {
17590
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17591
0
      }
17592
0
  }
17593
  /*
17594
  * "minExclusive valid restriction"
17595
  */
17596
0
  if (bfmininc) {
17597
      /* minInclusive >= BASE minInclusive */
17598
0
      res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17599
0
      if (res == -2)
17600
0
    goto internal_error;
17601
0
      if (res == -1) {
17602
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17603
0
      }
17604
0
      if ((res != 0) && (bfmininc->fixed)) {
17605
0
    FACET_RESTR_FIXED_ERR(fmininc)
17606
0
      }
17607
0
  }
17608
0
  if (bfmaxinc) {
17609
      /* minInclusive <= BASE maxInclusive */
17610
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17611
0
      if (res == -2)
17612
0
    goto internal_error;
17613
0
      if (res == 1) {
17614
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17615
0
      }
17616
0
  }
17617
0
  if (bfminexc) {
17618
      /* minInclusive > BASE minExclusive */
17619
0
      res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17620
0
      if (res == -2)
17621
0
    goto internal_error;
17622
0
      if (res != 1)
17623
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17624
0
  }
17625
0
  if (bfmaxexc) {
17626
      /* minInclusive < BASE maxExclusive */
17627
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17628
0
      if (res == -2)
17629
0
    goto internal_error;
17630
0
      if (res != -1)
17631
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17632
0
  }
17633
0
    }
17634
0
    if (ftotdig && bftotdig) {
17635
  /*
17636
  * SCC " totalDigits valid restriction"
17637
  * totalDigits <= BASE totalDigits
17638
  */
17639
0
  res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17640
0
  if (res == -2)
17641
0
      goto internal_error;
17642
0
  if (res == 1)
17643
0
      xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17644
0
      -1, 1, 1);
17645
0
  if ((res != 0) && (bftotdig->fixed)) {
17646
0
      FACET_RESTR_FIXED_ERR(ftotdig)
17647
0
  }
17648
0
    }
17649
0
    if (ffracdig && bffracdig) {
17650
  /*
17651
  * SCC  "fractionDigits valid restriction"
17652
  * fractionDigits <= BASE fractionDigits
17653
  */
17654
0
  res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17655
0
  if (res == -2)
17656
0
      goto internal_error;
17657
0
  if (res == 1)
17658
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17659
0
      -1, 1, 1);
17660
0
  if ((res != 0) && (bffracdig->fixed)) {
17661
0
      FACET_RESTR_FIXED_ERR(ffracdig)
17662
0
  }
17663
0
    }
17664
    /*
17665
    * SCC "fractionDigits less than or equal to totalDigits"
17666
    */
17667
0
    if (! ftotdig)
17668
0
  ftotdig = bftotdig;
17669
0
    if (! ffracdig)
17670
0
  ffracdig = bffracdig;
17671
0
    if (ftotdig && ffracdig) {
17672
0
  res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17673
0
  if (res == -2)
17674
0
      goto internal_error;
17675
0
  if (res == 1)
17676
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17677
0
    -1, 1, 0);
17678
0
    }
17679
    /*
17680
    * *Enumerations* won' be added here, since only the first set
17681
    * of enumerations in the ancestor-or-self axis is used
17682
    * for validation, plus we need to use the base type of those
17683
    * enumerations for whitespace.
17684
    *
17685
    * *Patterns*: won't be add here, since they are ORed at
17686
    * type level and ANDed at ancestor level. This will
17687
    * happen during validation by walking the base axis
17688
    * of the type.
17689
    */
17690
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17691
0
  bfacet = cur->facet;
17692
  /*
17693
  * Special handling of enumerations and patterns.
17694
  * TODO: hmm, they should not appear in the set, so remove this.
17695
  */
17696
0
  if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17697
0
      (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17698
0
      continue;
17699
  /*
17700
  * Search for a duplicate facet in the current type.
17701
  */
17702
0
  link = type->facetSet;
17703
  /* err = 0; */
17704
  /* fixedErr = 0; */
17705
0
  while (link != NULL) {
17706
0
      facet = link->facet;
17707
0
      if (facet->type == bfacet->type) {
17708
0
    switch (facet->type) {
17709
0
        case XML_SCHEMA_FACET_WHITESPACE:
17710
      /*
17711
      * The whitespace must be stronger.
17712
      */
17713
0
      if (facet->whitespace < bfacet->whitespace) {
17714
0
          FACET_RESTR_ERR(facet,
17715
0
        "The 'whitespace' value has to be equal to "
17716
0
        "or stronger than the 'whitespace' value of "
17717
0
        "the base type")
17718
0
      }
17719
0
      if ((bfacet->fixed) &&
17720
0
          (facet->whitespace != bfacet->whitespace)) {
17721
0
          FACET_RESTR_FIXED_ERR(facet)
17722
0
      }
17723
0
      break;
17724
0
        default:
17725
0
      break;
17726
0
    }
17727
    /* Duplicate found. */
17728
0
    break;
17729
0
      }
17730
0
      link = link->next;
17731
0
  }
17732
  /*
17733
  * If no duplicate was found: add the base types's facet
17734
  * to the set.
17735
  */
17736
0
  if (link == NULL) {
17737
0
      link = (xmlSchemaFacetLinkPtr)
17738
0
    xmlMalloc(sizeof(xmlSchemaFacetLink));
17739
0
      if (link == NULL) {
17740
0
    xmlSchemaPErrMemory(pctxt);
17741
0
    return (-1);
17742
0
      }
17743
0
      link->facet = cur->facet;
17744
0
      link->next = NULL;
17745
0
      if (last == NULL)
17746
0
    type->facetSet = link;
17747
0
      else
17748
0
    last->next = link;
17749
0
      last = link;
17750
0
  }
17751
17752
0
    }
17753
17754
0
    return (0);
17755
0
internal_error:
17756
0
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17757
0
  "an error occurred");
17758
0
    return (-1);
17759
0
}
17760
17761
static int
17762
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17763
               xmlSchemaTypePtr type)
17764
0
{
17765
0
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17766
    /*
17767
    * The actual value is then formed by replacing any union type
17768
    * definition in the `explicit members` with the members of their
17769
    * {member type definitions}, in order.
17770
    *
17771
    * TODO: There's a bug entry at
17772
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17773
    * which indicates that we'll keep the union types the future.
17774
    */
17775
0
    link = type->memberTypes;
17776
0
    while (link != NULL) {
17777
17778
0
  if (WXS_IS_TYPE_NOT_FIXED(link->type))
17779
0
      xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17780
17781
0
  if (WXS_IS_UNION(link->type)) {
17782
0
      subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17783
0
      if (subLink != NULL) {
17784
0
    link->type = subLink->type;
17785
0
    if (subLink->next != NULL) {
17786
0
        lastLink = link->next;
17787
0
        subLink = subLink->next;
17788
0
        prevLink = link;
17789
0
        while (subLink != NULL) {
17790
0
      newLink = (xmlSchemaTypeLinkPtr)
17791
0
          xmlMalloc(sizeof(xmlSchemaTypeLink));
17792
0
      if (newLink == NULL) {
17793
0
          xmlSchemaPErrMemory(pctxt);
17794
0
          return (-1);
17795
0
      }
17796
0
      newLink->type = subLink->type;
17797
0
      prevLink->next = newLink;
17798
0
      prevLink = newLink;
17799
0
      newLink->next = lastLink;
17800
17801
0
      subLink = subLink->next;
17802
0
        }
17803
0
    }
17804
0
      }
17805
0
  }
17806
0
  link = link->next;
17807
0
    }
17808
0
    return (0);
17809
0
}
17810
17811
static void
17812
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17813
0
{
17814
0
    int has = 0, needVal = 0, normVal = 0;
17815
17816
0
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17817
0
    if (has) {
17818
0
  needVal = (type->baseType->flags &
17819
0
      XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17820
0
  normVal = (type->baseType->flags &
17821
0
      XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17822
0
    }
17823
0
    if (type->facets != NULL) {
17824
0
  xmlSchemaFacetPtr fac;
17825
17826
0
  for (fac = type->facets; fac != NULL; fac = fac->next) {
17827
0
      switch (fac->type) {
17828
0
    case XML_SCHEMA_FACET_WHITESPACE:
17829
0
        break;
17830
0
    case XML_SCHEMA_FACET_PATTERN:
17831
0
        normVal = 1;
17832
0
        has = 1;
17833
0
        break;
17834
0
    case XML_SCHEMA_FACET_ENUMERATION:
17835
0
        needVal = 1;
17836
0
        normVal = 1;
17837
0
        has = 1;
17838
0
        break;
17839
0
    default:
17840
0
        has = 1;
17841
0
        break;
17842
0
      }
17843
0
  }
17844
0
    }
17845
0
    if (normVal)
17846
0
  type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17847
0
    if (needVal)
17848
0
  type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17849
0
    if (has)
17850
0
  type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17851
17852
0
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17853
0
  xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17854
  /*
17855
  * OPTIMIZE VAL TODO: Some facets need a computed value.
17856
  */
17857
0
  if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17858
0
      (prim->builtInType != XML_SCHEMAS_STRING)) {
17859
0
      type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17860
0
  }
17861
0
    }
17862
0
}
17863
17864
static int
17865
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17866
0
{
17867
17868
17869
    /*
17870
    * Evaluate the whitespace-facet value.
17871
    */
17872
0
    if (WXS_IS_LIST(type)) {
17873
0
  type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17874
0
  return (0);
17875
0
    } else if (WXS_IS_UNION(type))
17876
0
  return (0);
17877
17878
0
    if (type->facetSet != NULL) {
17879
0
  xmlSchemaFacetLinkPtr lin;
17880
17881
0
  for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17882
0
      if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17883
0
    switch (lin->facet->whitespace) {
17884
0
    case XML_SCHEMAS_FACET_PRESERVE:
17885
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17886
0
        break;
17887
0
    case XML_SCHEMAS_FACET_REPLACE:
17888
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17889
0
        break;
17890
0
    case XML_SCHEMAS_FACET_COLLAPSE:
17891
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17892
0
        break;
17893
0
    default:
17894
0
        return (-1);
17895
0
    }
17896
0
    return (0);
17897
0
      }
17898
0
  }
17899
0
    }
17900
    /*
17901
    * For all `atomic` datatypes other than string (and types `derived`
17902
    * by `restriction` from it) the value of whiteSpace is fixed to
17903
    * collapse
17904
    */
17905
0
    {
17906
0
  xmlSchemaTypePtr anc;
17907
17908
0
  for (anc = type->baseType; anc != NULL &&
17909
0
    anc->builtInType != XML_SCHEMAS_ANYTYPE;
17910
0
    anc = anc->baseType) {
17911
17912
0
      if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17913
0
    if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17914
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17915
17916
0
    } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17917
0
        (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17918
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17919
17920
0
    } else
17921
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17922
0
    break;
17923
0
      }
17924
0
  }
17925
0
    }
17926
0
    return (0);
17927
0
}
17928
17929
static int
17930
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17931
        xmlSchemaTypePtr type)
17932
0
{
17933
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17934
0
  return(0);
17935
0
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17936
0
  return(0);
17937
0
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17938
17939
0
    if (WXS_IS_LIST(type)) {
17940
  /*
17941
  * Corresponds to <simpleType><list>...
17942
  */
17943
0
  if (type->subtypes == NULL) {
17944
      /*
17945
      * This one is really needed, so get out.
17946
      */
17947
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17948
0
    "list type has no item-type assigned");
17949
0
      return(-1);
17950
0
  }
17951
0
    } else if (WXS_IS_UNION(type)) {
17952
  /*
17953
  * Corresponds to <simpleType><union>...
17954
  */
17955
0
  if (type->memberTypes == NULL) {
17956
      /*
17957
      * This one is really needed, so get out.
17958
      */
17959
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17960
0
    "union type has no member-types assigned");
17961
0
      return(-1);
17962
0
  }
17963
0
    } else {
17964
  /*
17965
  * Corresponds to <simpleType><restriction>...
17966
  */
17967
0
  if (type->baseType == NULL) {
17968
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17969
0
    "type has no base-type assigned");
17970
0
      return(-1);
17971
0
  }
17972
0
  if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17973
0
      if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17974
0
    return(-1);
17975
  /*
17976
  * Variety
17977
  * If the <restriction> alternative is chosen, then the
17978
  * {variety} of the {base type definition}.
17979
  */
17980
0
  if (WXS_IS_ATOMIC(type->baseType))
17981
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17982
0
  else if (WXS_IS_LIST(type->baseType)) {
17983
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17984
      /*
17985
      * Inherit the itemType.
17986
      */
17987
0
      type->subtypes = type->baseType->subtypes;
17988
0
  } else if (WXS_IS_UNION(type->baseType)) {
17989
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17990
      /*
17991
      * NOTE that we won't assign the memberTypes of the base,
17992
      * since this will make trouble when freeing them; we will
17993
      * use a lookup function to access them instead.
17994
      */
17995
0
  }
17996
0
    }
17997
0
    return(0);
17998
0
}
17999
18000
/*
18001
* 3.14.6 Constraints on Simple Type Definition Schema Components
18002
*/
18003
static int
18004
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18005
         xmlSchemaTypePtr type)
18006
0
{
18007
0
    int res, olderrs = pctxt->nberrors;
18008
18009
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18010
0
  return(-1);
18011
18012
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18013
0
  return(0);
18014
18015
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18016
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18017
18018
0
    if (type->baseType == NULL) {
18019
0
  PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18020
0
      "missing baseType");
18021
0
  goto exit_failure;
18022
0
    }
18023
0
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18024
0
  xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18025
    /*
18026
    * If a member type of a union is a union itself, we need to substitute
18027
    * that member type for its member types.
18028
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18029
    * types in WXS 1.1.
18030
    */
18031
0
    if ((type->memberTypes != NULL) &&
18032
0
  (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18033
0
  return(-1);
18034
    /*
18035
    * SPEC src-simple-type 1
18036
    * "The corresponding simple type definition, if any, must satisfy
18037
    * the conditions set out in Constraints on Simple Type Definition
18038
    * Schema Components ($3.14.6)."
18039
    */
18040
    /*
18041
    * Schema Component Constraint: Simple Type Definition Properties Correct
18042
    * (st-props-correct)
18043
    */
18044
0
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18045
0
    HFAILURE HERROR
18046
    /*
18047
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18048
    * (cos-st-restricts)
18049
    */
18050
0
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18051
0
    HFAILURE HERROR
18052
    /*
18053
    * TODO: Removed the error report, since it got annoying to get an
18054
    * extra error report, if anything failed until now.
18055
    * Enable this if needed.
18056
    *
18057
    * xmlSchemaPErr(ctxt, type->node,
18058
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18059
    *    "Simple type '%s' does not satisfy the constraints "
18060
    *    "on simple type definitions.\n",
18061
    *    type->name, NULL);
18062
    */
18063
    /*
18064
    * Schema Component Constraint: Simple Type Restriction (Facets)
18065
    * (st-restrict-facets)
18066
    */
18067
0
    res = xmlSchemaCheckFacetValues(type, pctxt);
18068
0
    HFAILURE HERROR
18069
0
    if ((type->facetSet != NULL) ||
18070
0
  (type->baseType->facetSet != NULL)) {
18071
0
  res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18072
0
  HFAILURE HERROR
18073
0
    }
18074
    /*
18075
    * Whitespace value.
18076
    */
18077
0
    res = xmlSchemaTypeFixupWhitespace(type);
18078
0
    HFAILURE HERROR
18079
0
    xmlSchemaTypeFixupOptimFacets(type);
18080
18081
0
exit_error:
18082
0
    if (olderrs != pctxt->nberrors)
18083
0
  return(pctxt->err);
18084
0
    return(0);
18085
18086
0
exit_failure:
18087
0
    return(-1);
18088
0
}
18089
18090
static int
18091
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18092
        xmlSchemaTypePtr type)
18093
0
{
18094
0
    int res = 0, olderrs = pctxt->nberrors;
18095
0
    xmlSchemaTypePtr baseType = type->baseType;
18096
18097
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18098
0
  return(0);
18099
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18100
0
    if (baseType == NULL) {
18101
0
  PERROR_INT("xmlSchemaFixupComplexType",
18102
0
      "missing baseType");
18103
0
  goto exit_failure;
18104
0
    }
18105
    /*
18106
    * Fixup the base type.
18107
    */
18108
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
18109
0
  xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18110
0
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18111
  /*
18112
  * Skip fixup if the base type is invalid.
18113
  * TODO: Generate a warning!
18114
  */
18115
0
  return(0);
18116
0
    }
18117
    /*
18118
    * This basically checks if the base type can be derived.
18119
    */
18120
0
    res = xmlSchemaCheckSRCCT(pctxt, type);
18121
0
    HFAILURE HERROR
18122
    /*
18123
    * Fixup the content type.
18124
    */
18125
0
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18126
  /*
18127
  * Corresponds to <complexType><simpleContent>...
18128
  */
18129
0
  if ((WXS_IS_COMPLEX(baseType)) &&
18130
0
      (baseType->contentTypeDef != NULL) &&
18131
0
      (WXS_IS_RESTRICTION(type))) {
18132
0
      xmlSchemaTypePtr contentBase, content;
18133
#ifdef ENABLE_NAMED_LOCALS
18134
      char buf[30];
18135
      const xmlChar *tmpname;
18136
#endif
18137
      /*
18138
      * SPEC (1) If <restriction> + base type is <complexType>,
18139
      * "whose own {content type} is a simple type..."
18140
      */
18141
0
      if (type->contentTypeDef != NULL) {
18142
    /*
18143
    * SPEC (1.1) "the simple type definition corresponding to the
18144
    * <simpleType> among the [children] of <restriction> if there
18145
    * is one;"
18146
    * Note that this "<simpleType> among the [children]" was put
18147
    * into ->contentTypeDef during parsing.
18148
    */
18149
0
    contentBase = type->contentTypeDef;
18150
0
    type->contentTypeDef = NULL;
18151
0
      } else {
18152
    /*
18153
    * (1.2) "...otherwise (<restriction> has no <simpleType>
18154
    * among its [children]), the simple type definition which
18155
    * is the {content type} of the ... base type."
18156
    */
18157
0
    contentBase = baseType->contentTypeDef;
18158
0
      }
18159
      /*
18160
      * SPEC
18161
      * "... a simple type definition which restricts the simple
18162
      * type definition identified in clause 1.1 or clause 1.2
18163
      * with a set of facet components"
18164
      *
18165
      * Create the anonymous simple type, which will be the content
18166
      * type of the complex type.
18167
      */
18168
#ifdef ENABLE_NAMED_LOCALS
18169
      snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18170
      tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18171
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18172
    XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18173
    type->node, 0);
18174
#else
18175
0
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18176
0
    XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18177
0
    type->node, 0);
18178
0
#endif
18179
0
      if (content == NULL)
18180
0
    goto exit_failure;
18181
      /*
18182
      * We will use the same node as for the <complexType>
18183
      * to have it somehow anchored in the schema doc.
18184
      */
18185
0
      content->type = XML_SCHEMA_TYPE_SIMPLE;
18186
0
      content->baseType = contentBase;
18187
      /*
18188
      * Move the facets, previously anchored on the
18189
      * complexType during parsing.
18190
      */
18191
0
      content->facets = type->facets;
18192
0
      type->facets = NULL;
18193
0
      content->facetSet = type->facetSet;
18194
0
      type->facetSet = NULL;
18195
18196
0
      type->contentTypeDef = content;
18197
0
      if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18198
0
    xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18199
      /*
18200
      * Fixup the newly created type. We don't need to check
18201
      * for circularity here.
18202
      */
18203
0
      res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18204
0
      HFAILURE HERROR
18205
0
      res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18206
0
      HFAILURE HERROR
18207
18208
0
  } else if ((WXS_IS_COMPLEX(baseType)) &&
18209
0
      (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18210
0
      (WXS_IS_RESTRICTION(type))) {
18211
      /*
18212
      * SPEC (2) If <restriction> + base is a mixed <complexType> with
18213
      * an emptiable particle, then a simple type definition which
18214
      * restricts the <restriction>'s <simpleType> child.
18215
      */
18216
0
      if ((type->contentTypeDef == NULL) ||
18217
0
    (type->contentTypeDef->baseType == NULL)) {
18218
    /*
18219
    * TODO: Check if this ever happens.
18220
    */
18221
0
    xmlSchemaPCustomErr(pctxt,
18222
0
        XML_SCHEMAP_INTERNAL,
18223
0
        WXS_BASIC_CAST type, NULL,
18224
0
        "Internal error: xmlSchemaTypeFixup, "
18225
0
        "complex type '%s': the <simpleContent><restriction> "
18226
0
        "is missing a <simpleType> child, but was not caught "
18227
0
        "by xmlSchemaCheckSRCCT()", type->name);
18228
0
    goto exit_failure;
18229
0
      }
18230
0
  } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18231
      /*
18232
      * SPEC (3) If <extension> + base is <complexType> with
18233
      * <simpleType> content, "...then the {content type} of that
18234
      * complex type definition"
18235
      */
18236
0
      if (baseType->contentTypeDef == NULL) {
18237
    /*
18238
    * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18239
    * should have caught this already.
18240
    */
18241
0
    xmlSchemaPCustomErr(pctxt,
18242
0
        XML_SCHEMAP_INTERNAL,
18243
0
        WXS_BASIC_CAST type, NULL,
18244
0
        "Internal error: xmlSchemaTypeFixup, "
18245
0
        "complex type '%s': the <extension>ed base type is "
18246
0
        "a complex type with no simple content type",
18247
0
        type->name);
18248
0
    goto exit_failure;
18249
0
      }
18250
0
      type->contentTypeDef = baseType->contentTypeDef;
18251
0
  } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18252
      /*
18253
      * SPEC (4) <extension> + base is <simpleType>
18254
      * "... then that simple type definition"
18255
      */
18256
0
      type->contentTypeDef = baseType;
18257
0
  } else {
18258
      /*
18259
      * TODO: Check if this ever happens.
18260
      */
18261
0
      xmlSchemaPCustomErr(pctxt,
18262
0
    XML_SCHEMAP_INTERNAL,
18263
0
    WXS_BASIC_CAST type, NULL,
18264
0
    "Internal error: xmlSchemaTypeFixup, "
18265
0
    "complex type '%s' with <simpleContent>: unhandled "
18266
0
    "derivation case", type->name);
18267
0
      goto exit_failure;
18268
0
  }
18269
0
    } else {
18270
0
  int dummySequence = 0;
18271
0
  xmlSchemaParticlePtr particle =
18272
0
      (xmlSchemaParticlePtr) type->subtypes;
18273
  /*
18274
  * Corresponds to <complexType><complexContent>...
18275
  *
18276
  * NOTE that the effective mixed was already set during parsing of
18277
  * <complexType> and <complexContent>; its flag value is
18278
  * XML_SCHEMAS_TYPE_MIXED.
18279
  *
18280
  * Compute the "effective content":
18281
  * (2.1.1) + (2.1.2) + (2.1.3)
18282
  */
18283
0
  if ((particle == NULL) ||
18284
0
      ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18285
0
      ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18286
0
      (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18287
0
      ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18288
0
      (particle->minOccurs == 0))) &&
18289
0
      ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18290
0
      if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18291
    /*
18292
    * SPEC (2.1.4) "If the `effective mixed` is true, then
18293
    * a particle whose properties are as follows:..."
18294
    *
18295
    * Empty sequence model group with
18296
    * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18297
    * NOTE that we sill assign it the <complexType> node to
18298
    * somehow anchor it in the doc.
18299
    */
18300
0
    if ((particle == NULL) ||
18301
0
        (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18302
        /*
18303
        * Create the particle.
18304
        */
18305
0
        particle = xmlSchemaAddParticle(pctxt,
18306
0
      type->node, 1, 1);
18307
0
        if (particle == NULL)
18308
0
      goto exit_failure;
18309
        /*
18310
        * Create the model group.
18311
        */ /* URGENT TODO: avoid adding to pending items. */
18312
0
        particle->children = (xmlSchemaTreeItemPtr)
18313
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18314
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18315
0
        if (particle->children == NULL)
18316
0
      goto exit_failure;
18317
18318
0
        type->subtypes = (xmlSchemaTypePtr) particle;
18319
0
    }
18320
0
    dummySequence = 1;
18321
0
    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18322
0
      } else {
18323
    /*
18324
    * SPEC (2.1.5) "otherwise empty"
18325
    */
18326
0
    type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18327
0
      }
18328
0
  } else {
18329
      /*
18330
      * SPEC (2.2) "otherwise the particle corresponding to the
18331
      * <all>, <choice>, <group> or <sequence> among the
18332
      * [children]."
18333
      */
18334
0
      type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18335
0
  }
18336
  /*
18337
  * Compute the "content type".
18338
  */
18339
0
  if (WXS_IS_RESTRICTION(type)) {
18340
      /*
18341
      * SPEC (3.1) "If <restriction>..."
18342
      * (3.1.1) + (3.1.2) */
18343
0
      if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18344
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18345
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18346
0
      }
18347
0
  } else {
18348
      /*
18349
      * SPEC (3.2) "If <extension>..."
18350
      */
18351
0
      if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18352
    /*
18353
    * SPEC (3.2.1)
18354
    * "If the `effective content` is empty, then the
18355
    *  {content type} of the [...] base ..."
18356
    */
18357
0
    type->contentType = baseType->contentType;
18358
0
    type->subtypes = baseType->subtypes;
18359
    /*
18360
    * Fixes bug #347316:
18361
    * This is the case when the base type has a simple
18362
    * type definition as content.
18363
    */
18364
0
    type->contentTypeDef = baseType->contentTypeDef;
18365
    /*
18366
    * NOTE that the effective mixed is ignored here.
18367
    */
18368
0
      } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18369
    /*
18370
    * SPEC (3.2.2)
18371
    */
18372
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18373
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18374
0
      } else {
18375
    /*
18376
    * SPEC (3.2.3)
18377
    */
18378
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18379
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18380
        /*
18381
        * "A model group whose {compositor} is sequence and whose
18382
        * {particles} are..."
18383
        */
18384
0
    if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18385
0
        (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18386
0
        ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18387
0
      XML_SCHEMA_TYPE_ALL))
18388
0
    {
18389
        /*
18390
        * SPEC cos-all-limited (1)
18391
        */
18392
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18393
      /* TODO: error code */
18394
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18395
0
      WXS_ITEM_NODE(type), NULL,
18396
0
      "The type has an 'all' model group in its "
18397
0
      "{content type} and thus cannot be derived from "
18398
0
      "a non-empty type, since this would produce a "
18399
0
      "'sequence' model group containing the 'all' "
18400
0
      "model group; 'all' model groups are not "
18401
0
      "allowed to appear inside other model groups",
18402
0
      NULL, NULL);
18403
18404
0
    } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18405
0
        (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18406
0
        ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18407
0
      XML_SCHEMA_TYPE_ALL))
18408
0
    {
18409
        /*
18410
        * SPEC cos-all-limited (1)
18411
        */
18412
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18413
      /* TODO: error code */
18414
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18415
0
      WXS_ITEM_NODE(type), NULL,
18416
0
      "A type cannot be derived by extension from a type "
18417
0
      "which has an 'all' model group in its "
18418
0
      "{content type}, since this would produce a "
18419
0
      "'sequence' model group containing the 'all' "
18420
0
      "model group; 'all' model groups are not "
18421
0
      "allowed to appear inside other model groups",
18422
0
      NULL, NULL);
18423
18424
0
    } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
18425
0
        xmlSchemaTreeItemPtr effectiveContent =
18426
0
      (xmlSchemaTreeItemPtr) type->subtypes;
18427
        /*
18428
        * Create the particle.
18429
        */
18430
0
        particle = xmlSchemaAddParticle(pctxt,
18431
0
      type->node, 1, 1);
18432
0
        if (particle == NULL)
18433
0
      goto exit_failure;
18434
        /*
18435
        * Create the "sequence" model group.
18436
        */
18437
0
        particle->children = (xmlSchemaTreeItemPtr)
18438
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18439
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18440
0
        if (particle->children == NULL)
18441
0
      goto exit_failure;
18442
0
        WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18443
        /*
18444
        * SPEC "the particle of the {content type} of
18445
        * the ... base ..."
18446
        * Create a duplicate of the base type's particle
18447
        * and assign its "term" to it.
18448
        */
18449
0
        particle->children->children =
18450
0
      (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18451
0
      type->node,
18452
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18453
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18454
0
        if (particle->children->children == NULL)
18455
0
      goto exit_failure;
18456
0
        particle = (xmlSchemaParticlePtr)
18457
0
      particle->children->children;
18458
0
        particle->children =
18459
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18460
        /*
18461
        * SPEC "followed by the `effective content`."
18462
        */
18463
0
        particle->next = effectiveContent;
18464
        /*
18465
        * This all will result in:
18466
        * new-particle
18467
        *   --> new-sequence(
18468
        *         new-particle
18469
        *           --> base-model,
18470
        *         this-particle
18471
        *         --> this-model
18472
        *     )
18473
        */
18474
0
    } else {
18475
        /*
18476
        * This is the case when there is already an empty
18477
        * <sequence> with minOccurs==maxOccurs==1.
18478
        * Just add the base types's content type.
18479
        * NOTE that, although we miss to add an intermediate
18480
        * <sequence>, this should produce no difference to
18481
        * neither the regex compilation of the content model,
18482
        * nor to the complex type constraints.
18483
        */
18484
0
        particle->children->children =
18485
0
      (xmlSchemaTreeItemPtr) baseType->subtypes;
18486
0
    }
18487
0
      }
18488
0
  }
18489
0
    }
18490
    /*
18491
    * Now fixup attribute uses:
18492
    *   - expand attr. group references
18493
    *     - intersect attribute wildcards
18494
    *   - inherit attribute uses of the base type
18495
    *   - inherit or union attr. wildcards if extending
18496
    *   - apply attr. use prohibitions if restricting
18497
    */
18498
0
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18499
0
    HFAILURE HERROR
18500
    /*
18501
    * Apply the complex type component constraints; this will not
18502
    * check attributes, since this is done in
18503
    * xmlSchemaFixupTypeAttributeUses().
18504
    */
18505
0
    res = xmlSchemaCheckCTComponent(pctxt, type);
18506
0
    HFAILURE HERROR
18507
18508
0
    if (olderrs != pctxt->nberrors)
18509
0
  return(pctxt->err);
18510
0
    else
18511
0
  return(0);
18512
18513
0
exit_error:
18514
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18515
0
    return(pctxt->err);
18516
18517
0
exit_failure:
18518
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18519
0
    return(-1);
18520
0
}
18521
18522
18523
/**
18524
 * xmlSchemaTypeFixup:
18525
 * @typeDecl:  the schema type definition
18526
 * @ctxt:  the schema parser context
18527
 *
18528
 * Fixes the content model of the type.
18529
 * URGENT TODO: We need an int result!
18530
 */
18531
static int
18532
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18533
                   xmlSchemaAbstractCtxtPtr actxt)
18534
0
{
18535
0
    if (type == NULL)
18536
0
        return(0);
18537
0
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18538
0
  AERROR_INT("xmlSchemaTypeFixup",
18539
0
      "this function needs a parser context");
18540
0
  return(-1);
18541
0
    }
18542
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18543
0
  return(0);
18544
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18545
0
  return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18546
0
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18547
0
  return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18548
0
    return(0);
18549
0
}
18550
18551
/**
18552
 * xmlSchemaCheckFacet:
18553
 * @facet:  the facet
18554
 * @typeDecl:  the schema type definition
18555
 * @pctxt:  the schema parser context or NULL
18556
 * @name: the optional name of the type
18557
 *
18558
 * Checks and computes the values of facets.
18559
 *
18560
 * Returns 0 if valid, a positive error code if not valid and
18561
 *         -1 in case of an internal or API error.
18562
 */
18563
int
18564
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18565
                    xmlSchemaTypePtr typeDecl,
18566
                    xmlSchemaParserCtxtPtr pctxt,
18567
        const xmlChar * name ATTRIBUTE_UNUSED)
18568
0
{
18569
0
    int ret = 0, ctxtGiven;
18570
18571
0
    if ((facet == NULL) || (typeDecl == NULL))
18572
0
        return(-1);
18573
    /*
18574
    * TODO: will the parser context be given if used from
18575
    * the relaxNG module?
18576
    */
18577
0
    if (pctxt == NULL)
18578
0
  ctxtGiven = 0;
18579
0
    else
18580
0
  ctxtGiven = 1;
18581
18582
0
    switch (facet->type) {
18583
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
18584
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
18585
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
18586
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18587
0
  case XML_SCHEMA_FACET_ENUMERATION: {
18588
                /*
18589
                 * Okay we need to validate the value
18590
                 * at that point.
18591
                 */
18592
0
    xmlSchemaTypePtr base;
18593
18594
    /* 4.3.5.5 Constraints on enumeration Schema Components
18595
    * Schema Component Constraint: enumeration valid restriction
18596
    * It is an `error` if any member of {value} is not in the
18597
    * `value space` of {base type definition}.
18598
    *
18599
    * minInclusive, maxInclusive, minExclusive, maxExclusive:
18600
    * The value `must` be in the
18601
    * `value space` of the `base type`.
18602
    */
18603
    /*
18604
    * This function is intended to deliver a compiled value
18605
    * on the facet. In this implementation of XML Schemata the
18606
    * type holding a facet, won't be a built-in type.
18607
    * Thus to ensure that other API
18608
    * calls (relaxng) do work, if the given type is a built-in
18609
    * type, we will assume that the given built-in type *is
18610
    * already* the base type.
18611
    */
18612
0
    if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18613
0
        base = typeDecl->baseType;
18614
0
        if (base == NULL) {
18615
0
      PERROR_INT("xmlSchemaCheckFacet",
18616
0
          "a type user derived type has no base type");
18617
0
      return (-1);
18618
0
        }
18619
0
    } else
18620
0
        base = typeDecl;
18621
18622
0
    if (! ctxtGiven) {
18623
        /*
18624
        * A context is needed if called from RelaxNG.
18625
        */
18626
0
        pctxt = xmlSchemaNewParserCtxt("*");
18627
0
        if (pctxt == NULL)
18628
0
      return (-1);
18629
0
    }
18630
    /*
18631
    * NOTE: This call does not check the content nodes,
18632
    * since they are not available:
18633
    * facet->node is just the node holding the facet
18634
    * definition, *not* the attribute holding the *value*
18635
    * of the facet.
18636
    */
18637
0
    ret = xmlSchemaVCheckCVCSimpleType(
18638
0
        ACTXT_CAST pctxt, facet->node, base,
18639
0
        facet->value, &(facet->val), 1, 1, 0);
18640
0
                if (ret != 0) {
18641
0
        if (ret < 0) {
18642
      /* No error message for RelaxNG. */
18643
0
      if (ctxtGiven) {
18644
0
          xmlSchemaCustomErr(ACTXT_CAST pctxt,
18645
0
        XML_SCHEMAP_INTERNAL, facet->node, NULL,
18646
0
        "Internal error: xmlSchemaCheckFacet, "
18647
0
        "failed to validate the value '%s' of the "
18648
0
        "facet '%s' against the base type",
18649
0
        facet->value, xmlSchemaFacetTypeToString(facet->type));
18650
0
      }
18651
0
      goto internal_error;
18652
0
        }
18653
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18654
        /* No error message for RelaxNG. */
18655
0
        if (ctxtGiven) {
18656
0
      xmlChar *str = NULL;
18657
18658
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18659
0
          ret, facet->node, WXS_BASIC_CAST facet,
18660
0
          "The value '%s' of the facet does not validate "
18661
0
          "against the base type '%s'",
18662
0
          facet->value,
18663
0
          xmlSchemaFormatQName(&str,
18664
0
        base->targetNamespace, base->name));
18665
0
      FREE_AND_NULL(str);
18666
0
        }
18667
0
        goto exit;
18668
0
                } else if (facet->val == NULL) {
18669
0
        if (ctxtGiven) {
18670
0
      PERROR_INT("xmlSchemaCheckFacet",
18671
0
          "value was not computed");
18672
0
        }
18673
        /* TODO */
18674
0
    }
18675
0
                break;
18676
0
            }
18677
0
        case XML_SCHEMA_FACET_PATTERN:
18678
0
            facet->regexp = xmlRegexpCompile(facet->value);
18679
0
            if (facet->regexp == NULL) {
18680
0
    ret = XML_SCHEMAP_REGEXP_INVALID;
18681
    /* No error message for RelaxNG. */
18682
0
    if (ctxtGiven) {
18683
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18684
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18685
0
      "The value '%s' of the facet 'pattern' is not a "
18686
0
      "valid regular expression",
18687
0
      facet->value, NULL);
18688
0
    }
18689
0
            }
18690
0
            break;
18691
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
18692
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
18693
0
        case XML_SCHEMA_FACET_LENGTH:
18694
0
        case XML_SCHEMA_FACET_MAXLENGTH:
18695
0
        case XML_SCHEMA_FACET_MINLENGTH:
18696
18697
0
      if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18698
0
    ret = xmlSchemaValidatePredefinedType(
18699
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18700
0
        facet->value, &(facet->val));
18701
0
      } else {
18702
0
    ret = xmlSchemaValidatePredefinedType(
18703
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18704
0
        facet->value, &(facet->val));
18705
0
      }
18706
0
      if (ret != 0) {
18707
0
    if (ret < 0) {
18708
        /* No error message for RelaxNG. */
18709
0
        if (ctxtGiven) {
18710
0
      PERROR_INT("xmlSchemaCheckFacet",
18711
0
          "validating facet value");
18712
0
        }
18713
0
        goto internal_error;
18714
0
    }
18715
0
    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18716
    /* No error message for RelaxNG. */
18717
0
    if (ctxtGiven) {
18718
        /* error code */
18719
0
        xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18720
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18721
0
      "The value '%s' of the facet '%s' is not a valid '%s'",
18722
0
      facet->value,
18723
0
      xmlSchemaFacetTypeToString(facet->type),
18724
0
      (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18725
0
          BAD_CAST "nonNegativeInteger" :
18726
0
          BAD_CAST "positiveInteger",
18727
0
      NULL);
18728
0
    }
18729
0
      }
18730
0
      break;
18731
18732
0
        case XML_SCHEMA_FACET_WHITESPACE:{
18733
0
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18734
0
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18735
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18736
0
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18737
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18738
0
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18739
0
                } else {
18740
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18741
                    /* No error message for RelaxNG. */
18742
0
        if (ctxtGiven) {
18743
      /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18744
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18745
0
          ret, facet->node, WXS_BASIC_CAST typeDecl,
18746
0
          "The value '%s' of the facet 'whitespace' is not "
18747
0
          "valid", facet->value, NULL);
18748
0
                    }
18749
0
                }
18750
0
            }
18751
0
        default:
18752
0
            break;
18753
0
    }
18754
0
exit:
18755
0
    if ((! ctxtGiven) && (pctxt != NULL))
18756
0
  xmlSchemaFreeParserCtxt(pctxt);
18757
0
    return (ret);
18758
0
internal_error:
18759
0
    if ((! ctxtGiven) && (pctxt != NULL))
18760
0
  xmlSchemaFreeParserCtxt(pctxt);
18761
0
    return (-1);
18762
0
}
18763
18764
/**
18765
 * xmlSchemaCheckFacetValues:
18766
 * @typeDecl:  the schema type definition
18767
 * @ctxt:  the schema parser context
18768
 *
18769
 * Checks the default values types, especially for facets
18770
 */
18771
static int
18772
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18773
        xmlSchemaParserCtxtPtr pctxt)
18774
0
{
18775
0
    int res, olderrs = pctxt->nberrors;
18776
0
    const xmlChar *name = typeDecl->name;
18777
    /*
18778
    * NOTE: It is intended to use the facets list, instead
18779
    * of facetSet.
18780
    */
18781
0
    if (typeDecl->facets != NULL) {
18782
0
  xmlSchemaFacetPtr facet = typeDecl->facets;
18783
18784
  /*
18785
  * Temporarily assign the "schema" to the validation context
18786
  * of the parser context. This is needed for NOTATION validation.
18787
  */
18788
0
  if (pctxt->vctxt == NULL) {
18789
0
      if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18790
0
    return(-1);
18791
0
  }
18792
0
  pctxt->vctxt->schema = pctxt->schema;
18793
0
  while (facet != NULL) {
18794
0
      res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18795
0
      HFAILURE
18796
0
      facet = facet->next;
18797
0
  }
18798
0
  pctxt->vctxt->schema = NULL;
18799
0
    }
18800
0
    if (olderrs != pctxt->nberrors)
18801
0
  return(pctxt->err);
18802
0
    return(0);
18803
0
exit_failure:
18804
0
    return(-1);
18805
0
}
18806
18807
/**
18808
 * xmlSchemaGetCircModelGrDefRef:
18809
 * @ctxtMGroup: the searched model group
18810
 * @selfMGroup: the second searched model group
18811
 * @particle: the first particle
18812
 *
18813
 * This one is intended to be used by
18814
 * xmlSchemaCheckGroupDefCircular only.
18815
 *
18816
 * Returns the particle with the circular model group definition reference,
18817
 * otherwise NULL.
18818
 */
18819
static xmlSchemaTreeItemPtr
18820
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18821
            xmlSchemaTreeItemPtr particle)
18822
0
{
18823
0
    xmlSchemaTreeItemPtr circ = NULL;
18824
0
    xmlSchemaTreeItemPtr term;
18825
0
    xmlSchemaModelGroupDefPtr gdef;
18826
18827
0
    for (; particle != NULL; particle = particle->next) {
18828
0
  term = particle->children;
18829
0
  if (term == NULL)
18830
0
      continue;
18831
0
  switch (term->type) {
18832
0
      case XML_SCHEMA_TYPE_GROUP:
18833
0
    gdef = (xmlSchemaModelGroupDefPtr) term;
18834
0
    if (gdef == groupDef)
18835
0
        return (particle);
18836
    /*
18837
    * Mark this model group definition to avoid infinite
18838
    * recursion on circular references not yet examined.
18839
    */
18840
0
    if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18841
0
        continue;
18842
0
    if (gdef->children != NULL) {
18843
0
        gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18844
0
        circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18845
0
      gdef->children->children);
18846
0
        gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18847
0
        if (circ != NULL)
18848
0
      return (circ);
18849
0
    }
18850
0
    break;
18851
0
      case XML_SCHEMA_TYPE_SEQUENCE:
18852
0
      case XML_SCHEMA_TYPE_CHOICE:
18853
0
      case XML_SCHEMA_TYPE_ALL:
18854
0
    circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18855
0
    if (circ != NULL)
18856
0
        return (circ);
18857
0
    break;
18858
0
      default:
18859
0
    break;
18860
0
  }
18861
0
    }
18862
0
    return (NULL);
18863
0
}
18864
18865
/**
18866
 * xmlSchemaCheckGroupDefCircular:
18867
 * @item:  the model group definition
18868
 * @ctxt:  the parser context
18869
 * @name:  the name
18870
 *
18871
 * Checks for circular references to model group definitions.
18872
 */
18873
static void
18874
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18875
             xmlSchemaParserCtxtPtr ctxt)
18876
0
{
18877
    /*
18878
    * Schema Component Constraint: Model Group Correct
18879
    * 2 Circular groups are disallowed. That is, within the {particles}
18880
    * of a group there must not be at any depth a particle whose {term}
18881
    * is the group itself.
18882
    */
18883
0
    if ((item == NULL) ||
18884
0
  (item->type != XML_SCHEMA_TYPE_GROUP) ||
18885
0
  (item->children == NULL))
18886
0
  return;
18887
0
    {
18888
0
  xmlSchemaTreeItemPtr circ;
18889
18890
0
  circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18891
0
  if (circ != NULL) {
18892
0
      xmlChar *str = NULL;
18893
      /*
18894
      * TODO: The error report is not adequate: this constraint
18895
      * is defined for model groups but not definitions, but since
18896
      * there cannot be any circular model groups without a model group
18897
      * definition (if not using a construction API), we check those
18898
      * definitions only.
18899
      */
18900
0
      xmlSchemaPCustomErr(ctxt,
18901
0
    XML_SCHEMAP_MG_PROPS_CORRECT_2,
18902
0
    NULL, WXS_ITEM_NODE(circ),
18903
0
    "Circular reference to the model group definition '%s' "
18904
0
    "defined", xmlSchemaFormatQName(&str,
18905
0
        item->targetNamespace, item->name));
18906
0
      FREE_AND_NULL(str)
18907
      /*
18908
      * NOTE: We will cut the reference to avoid further
18909
      * confusion of the processor. This is a fatal error.
18910
      */
18911
0
      circ->children = NULL;
18912
0
  }
18913
0
    }
18914
0
}
18915
18916
/**
18917
 * xmlSchemaModelGroupToModelGroupDefFixup:
18918
 * @ctxt:  the parser context
18919
 * @mg:  the model group
18920
 *
18921
 * Assigns the model group of model group definitions to the "term"
18922
 * of the referencing particle.
18923
 * In xmlSchemaResolveModelGroupParticleReferences the model group
18924
 * definitions were assigned to the "term", since needed for the
18925
 * circularity check.
18926
 *
18927
 * Schema Component Constraint:
18928
 *     All Group Limited (cos-all-limited) (1.2)
18929
 */
18930
static void
18931
xmlSchemaModelGroupToModelGroupDefFixup(
18932
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18933
    xmlSchemaModelGroupPtr mg)
18934
0
{
18935
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18936
18937
0
    while (particle != NULL) {
18938
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18939
0
      ((WXS_PARTICLE_TERM(particle))->type !=
18940
0
    XML_SCHEMA_TYPE_GROUP))
18941
0
  {
18942
0
      particle = WXS_PTC_CAST particle->next;
18943
0
      continue;
18944
0
  }
18945
0
  if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18946
      /*
18947
      * TODO: Remove the particle.
18948
      */
18949
0
      WXS_PARTICLE_TERM(particle) = NULL;
18950
0
      particle = WXS_PTC_CAST particle->next;
18951
0
      continue;
18952
0
  }
18953
  /*
18954
  * Assign the model group to the {term} of the particle.
18955
  */
18956
0
  WXS_PARTICLE_TERM(particle) =
18957
0
      WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18958
18959
0
  particle = WXS_PTC_CAST particle->next;
18960
0
    }
18961
0
}
18962
18963
/**
18964
 * xmlSchemaCheckAttrGroupCircularRecur:
18965
 * @ctxtGr: the searched attribute group
18966
 * @attr: the current attribute list to be processed
18967
 *
18968
 * This one is intended to be used by
18969
 * xmlSchemaCheckAttrGroupCircular only.
18970
 *
18971
 * Returns the circular attribute group reference, otherwise NULL.
18972
 */
18973
static xmlSchemaQNameRefPtr
18974
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
18975
             xmlSchemaItemListPtr list)
18976
0
{
18977
0
    xmlSchemaAttributeGroupPtr gr;
18978
0
    xmlSchemaQNameRefPtr ref, circ;
18979
0
    int i;
18980
    /*
18981
    * We will search for an attribute group reference which
18982
    * references the context attribute group.
18983
    */
18984
0
    for (i = 0; i < list->nbItems; i++) {
18985
0
  ref = list->items[i];
18986
0
  if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18987
0
      (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
18988
0
      (ref->item != NULL))
18989
0
  {
18990
0
      gr = WXS_ATTR_GROUP_CAST ref->item;
18991
0
      if (gr == ctxtGr)
18992
0
    return(ref);
18993
0
      if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
18994
0
    continue;
18995
      /*
18996
      * Mark as visited to avoid infinite recursion on
18997
      * circular references not yet examined.
18998
      */
18999
0
      if ((gr->attrUses) &&
19000
0
    (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19001
0
      {
19002
0
    gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19003
0
    circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19004
0
        (xmlSchemaItemListPtr) gr->attrUses);
19005
0
    gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19006
0
    if (circ != NULL)
19007
0
        return (circ);
19008
0
      }
19009
19010
0
  }
19011
0
    }
19012
0
    return (NULL);
19013
0
}
19014
19015
/**
19016
 * xmlSchemaCheckAttrGroupCircular:
19017
 * attrGr:  the attribute group definition
19018
 * @ctxt:  the parser context
19019
 * @name:  the name
19020
 *
19021
 * Checks for circular references of attribute groups.
19022
 */
19023
static int
19024
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19025
        xmlSchemaParserCtxtPtr ctxt)
19026
0
{
19027
    /*
19028
    * Schema Representation Constraint:
19029
    * Attribute Group Definition Representation OK
19030
    * 3 Circular group reference is disallowed outside <redefine>.
19031
    * That is, unless this element information item's parent is
19032
    * <redefine>, then among the [children], if any, there must
19033
    * not be an <attributeGroup> with ref [attribute] which resolves
19034
    * to the component corresponding to this <attributeGroup>. Indirect
19035
    * circularity is also ruled out. That is, when QName resolution
19036
    * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19037
    * any <attributeGroup>s with a ref [attribute] among the [children],
19038
    * it must not be the case that a `QName` is encountered at any depth
19039
    * which resolves to the component corresponding to this <attributeGroup>.
19040
    */
19041
0
    if (attrGr->attrUses == NULL)
19042
0
  return(0);
19043
0
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19044
0
  return(0);
19045
0
    else {
19046
0
  xmlSchemaQNameRefPtr circ;
19047
19048
0
  circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19049
0
      (xmlSchemaItemListPtr) attrGr->attrUses);
19050
0
  if (circ != NULL) {
19051
0
      xmlChar *str = NULL;
19052
      /*
19053
      * TODO: Report the referenced attr group as QName.
19054
      */
19055
0
      xmlSchemaPCustomErr(ctxt,
19056
0
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19057
0
    NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19058
0
    "Circular reference to the attribute group '%s' "
19059
0
    "defined", xmlSchemaGetComponentQName(&str, attrGr));
19060
0
      FREE_AND_NULL(str);
19061
      /*
19062
      * NOTE: We will cut the reference to avoid further
19063
      * confusion of the processor.
19064
      * BADSPEC TODO: The spec should define how to process in this case.
19065
      */
19066
0
      circ->item = NULL;
19067
0
      return(ctxt->err);
19068
0
  }
19069
0
    }
19070
0
    return(0);
19071
0
}
19072
19073
static int
19074
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19075
          xmlSchemaAttributeGroupPtr attrGr);
19076
19077
/**
19078
 * xmlSchemaExpandAttributeGroupRefs:
19079
 * @pctxt: the parser context
19080
 * @node: the node of the component holding the attribute uses
19081
 * @completeWild: the intersected wildcard to be returned
19082
 * @list: the attribute uses
19083
 *
19084
 * Substitutes contained attribute group references
19085
 * for their attribute uses. Wildcards are intersected.
19086
 * Attribute use prohibitions are removed from the list
19087
 * and returned via the @prohibs list.
19088
 * Pointlessness of attr. prohibs, if a matching attr. decl
19089
 * is existent a well, are checked.
19090
 */
19091
static int
19092
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19093
          xmlSchemaBasicItemPtr item,
19094
          xmlSchemaWildcardPtr *completeWild,
19095
          xmlSchemaItemListPtr list,
19096
          xmlSchemaItemListPtr prohibs)
19097
0
{
19098
0
    xmlSchemaAttributeGroupPtr gr;
19099
0
    xmlSchemaAttributeUsePtr use;
19100
0
    xmlSchemaItemListPtr sublist;
19101
0
    int i, j;
19102
0
    int created = (*completeWild == NULL) ? 0 : 1;
19103
19104
0
    if (prohibs)
19105
0
  prohibs->nbItems = 0;
19106
19107
0
    for (i = 0; i < list->nbItems; i++) {
19108
0
  use = list->items[i];
19109
19110
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19111
0
      if (prohibs == NULL) {
19112
0
    PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19113
0
        "unexpected attr prohibition found");
19114
0
    return(-1);
19115
0
      }
19116
      /*
19117
      * Remove from attribute uses.
19118
      */
19119
0
      if (xmlSchemaItemListRemove(list, i) == -1)
19120
0
    return(-1);
19121
0
      i--;
19122
      /*
19123
      * Note that duplicate prohibitions were already
19124
      * handled at parsing time.
19125
      */
19126
      /*
19127
      * Add to list of prohibitions.
19128
      */
19129
0
      xmlSchemaItemListAddSize(prohibs, 2, use);
19130
0
      continue;
19131
0
  }
19132
0
  if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19133
0
      ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19134
0
  {
19135
0
      if ((WXS_QNAME_CAST use)->item == NULL)
19136
0
    return(-1);
19137
0
      gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19138
      /*
19139
      * Expand the referenced attr. group.
19140
      * TODO: remove this, this is done in a previous step, so
19141
      * already done here.
19142
      */
19143
0
      if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19144
0
    if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19145
0
        return(-1);
19146
0
      }
19147
      /*
19148
      * Build the 'complete' wildcard; i.e. intersect multiple
19149
      * wildcards.
19150
      */
19151
0
      if (gr->attributeWildcard != NULL) {
19152
0
    if (*completeWild == NULL) {
19153
0
        *completeWild = gr->attributeWildcard;
19154
0
    } else {
19155
0
        if (! created) {
19156
0
      xmlSchemaWildcardPtr tmpWild;
19157
19158
       /*
19159
      * Copy the first encountered wildcard as context,
19160
      * except for the annotation.
19161
      *
19162
      * Although the complete wildcard might not correspond
19163
      * to any node in the schema, we will anchor it on
19164
      * the node of the owner component.
19165
      */
19166
0
      tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19167
0
          XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19168
0
          WXS_ITEM_NODE(item));
19169
0
      if (tmpWild == NULL)
19170
0
          return(-1);
19171
0
      if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19172
0
          tmpWild, *completeWild) == -1)
19173
0
          return (-1);
19174
0
      tmpWild->processContents = (*completeWild)->processContents;
19175
0
      *completeWild = tmpWild;
19176
0
      created = 1;
19177
0
        }
19178
19179
0
        if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19180
0
      gr->attributeWildcard) == -1)
19181
0
      return(-1);
19182
0
    }
19183
0
      }
19184
      /*
19185
      * Just remove the reference if the referenced group does not
19186
      * contain any attribute uses.
19187
      */
19188
0
      sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19189
0
      if ((sublist == NULL) || sublist->nbItems == 0) {
19190
0
    if (xmlSchemaItemListRemove(list, i) == -1)
19191
0
        return(-1);
19192
0
    i--;
19193
0
    continue;
19194
0
      }
19195
      /*
19196
      * Add the attribute uses.
19197
      */
19198
0
      list->items[i] = sublist->items[0];
19199
0
      if (sublist->nbItems != 1) {
19200
0
    for (j = 1; j < sublist->nbItems; j++) {
19201
0
        i++;
19202
0
        if (xmlSchemaItemListInsert(list,
19203
0
          sublist->items[j], i) == -1)
19204
0
      return(-1);
19205
0
    }
19206
0
      }
19207
0
  }
19208
19209
0
    }
19210
    /*
19211
    * Handle pointless prohibitions of declared attributes.
19212
    */
19213
0
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19214
0
  xmlSchemaAttributeUseProhibPtr prohib;
19215
19216
0
  for (i = prohibs->nbItems -1; i >= 0; i--) {
19217
0
      prohib = prohibs->items[i];
19218
0
      for (j = 0; j < list->nbItems; j++) {
19219
0
    use = list->items[j];
19220
19221
0
    if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19222
0
        (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19223
0
    {
19224
0
        xmlChar *str = NULL;
19225
19226
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19227
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19228
0
      prohib->node, NULL,
19229
0
      "Skipping pointless attribute use prohibition "
19230
0
      "'%s', since a corresponding attribute use "
19231
0
      "exists already in the type definition",
19232
0
      xmlSchemaFormatQName(&str,
19233
0
          prohib->targetNamespace, prohib->name),
19234
0
      NULL, NULL);
19235
0
        FREE_AND_NULL(str);
19236
        /*
19237
        * Remove the prohibition.
19238
        */
19239
0
        if (xmlSchemaItemListRemove(prohibs, i) == -1)
19240
0
      return(-1);
19241
0
        break;
19242
0
    }
19243
0
      }
19244
0
  }
19245
0
    }
19246
0
    return(0);
19247
0
}
19248
19249
/**
19250
 * xmlSchemaAttributeGroupExpandRefs:
19251
 * @pctxt:  the parser context
19252
 * @attrGr:  the attribute group definition
19253
 *
19254
 * Computation of:
19255
 * {attribute uses} property
19256
 * {attribute wildcard} property
19257
 *
19258
 * Substitutes contained attribute group references
19259
 * for their attribute uses. Wildcards are intersected.
19260
 */
19261
static int
19262
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19263
          xmlSchemaAttributeGroupPtr attrGr)
19264
0
{
19265
0
    if ((attrGr->attrUses == NULL) ||
19266
0
  (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19267
0
  return(0);
19268
19269
0
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19270
0
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19271
0
  &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19272
0
  return(-1);
19273
0
    return(0);
19274
0
}
19275
19276
/**
19277
 * xmlSchemaAttributeGroupExpandRefs:
19278
 * @pctxt:  the parser context
19279
 * @attrGr:  the attribute group definition
19280
 *
19281
 * Substitutes contained attribute group references
19282
 * for their attribute uses. Wildcards are intersected.
19283
 *
19284
 * Schema Component Constraint:
19285
 *    Attribute Group Definition Properties Correct (ag-props-correct)
19286
 */
19287
static int
19288
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19289
          xmlSchemaAttributeGroupPtr attrGr)
19290
0
{
19291
    /*
19292
    * SPEC ag-props-correct
19293
    * (1) "The values of the properties of an attribute group definition
19294
    * must be as described in the property tableau in The Attribute
19295
    * Group Definition Schema Component ($3.6.1), modulo the impact of
19296
    * Missing Sub-components ($5.3);"
19297
    */
19298
19299
0
    if ((attrGr->attrUses != NULL) &&
19300
0
  (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19301
0
    {
19302
0
  xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19303
0
  xmlSchemaAttributeUsePtr use, tmp;
19304
0
  int i, j, hasId = 0;
19305
19306
0
  for (i = uses->nbItems -1; i >= 0; i--) {
19307
0
      use = uses->items[i];
19308
      /*
19309
      * SPEC ag-props-correct
19310
      * (2) "Two distinct members of the {attribute uses} must not have
19311
      * {attribute declaration}s both of whose {name}s match and whose
19312
      * {target namespace}s are identical."
19313
      */
19314
0
      if (i > 0) {
19315
0
    for (j = i -1; j >= 0; j--) {
19316
0
        tmp = uses->items[j];
19317
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
19318
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
19319
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
19320
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
19321
0
        {
19322
0
      xmlChar *str = NULL;
19323
19324
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19325
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19326
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19327
0
          "Duplicate %s",
19328
0
          xmlSchemaGetComponentDesignation(&str, use),
19329
0
          NULL);
19330
0
      FREE_AND_NULL(str);
19331
      /*
19332
      * Remove the duplicate.
19333
      */
19334
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19335
0
          return(-1);
19336
0
      goto next_use;
19337
0
        }
19338
0
    }
19339
0
      }
19340
      /*
19341
      * SPEC ag-props-correct
19342
      * (3) "Two distinct members of the {attribute uses} must not have
19343
      * {attribute declaration}s both of whose {type definition}s are or
19344
      * are derived from ID."
19345
      * TODO: Does 'derived' include member-types of unions?
19346
      */
19347
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19348
0
    if (xmlSchemaIsDerivedFromBuiltInType(
19349
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19350
0
    {
19351
0
        if (hasId) {
19352
0
      xmlChar *str = NULL;
19353
19354
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19355
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19356
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19357
0
          "There must not exist more than one attribute "
19358
0
          "declaration of type 'xs:ID' "
19359
0
          "(or derived from 'xs:ID'). The %s violates this "
19360
0
          "constraint",
19361
0
          xmlSchemaGetComponentDesignation(&str, use),
19362
0
          NULL);
19363
0
      FREE_AND_NULL(str);
19364
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19365
0
          return(-1);
19366
0
        }
19367
0
        hasId = 1;
19368
0
    }
19369
0
      }
19370
0
next_use: {}
19371
0
  }
19372
0
    }
19373
0
    return(0);
19374
0
}
19375
19376
/**
19377
 * xmlSchemaResolveAttrGroupReferences:
19378
 * @attrgrpDecl:  the schema attribute definition
19379
 * @ctxt:  the schema parser context
19380
 * @name:  the attribute name
19381
 *
19382
 * Resolves references to attribute group definitions.
19383
 */
19384
static int
19385
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19386
            xmlSchemaParserCtxtPtr ctxt)
19387
0
{
19388
0
    xmlSchemaAttributeGroupPtr group;
19389
19390
0
    if (ref->item != NULL)
19391
0
        return(0);
19392
0
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
19393
0
  ref->name,
19394
0
  ref->targetNamespace);
19395
0
    if (group == NULL) {
19396
0
  xmlSchemaPResCompAttrErr(ctxt,
19397
0
      XML_SCHEMAP_SRC_RESOLVE,
19398
0
      NULL, ref->node,
19399
0
      "ref", ref->name, ref->targetNamespace,
19400
0
      ref->itemType, NULL);
19401
0
  return(ctxt->err);
19402
0
    }
19403
0
    ref->item = WXS_BASIC_CAST group;
19404
0
    return(0);
19405
0
}
19406
19407
/**
19408
 * xmlSchemaCheckAttrPropsCorrect:
19409
 * @item:  an schema attribute declaration/use
19410
 * @ctxt:  a schema parser context
19411
 * @name:  the name of the attribute
19412
 *
19413
 *
19414
 * Schema Component Constraint:
19415
 *    Attribute Declaration Properties Correct (a-props-correct)
19416
 *
19417
 * Validates the value constraints of an attribute declaration/use.
19418
 * NOTE that this needs the simple type definitions to be already
19419
 *   built and checked.
19420
 */
19421
static int
19422
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19423
             xmlSchemaAttributePtr attr)
19424
0
{
19425
19426
    /*
19427
    * SPEC a-props-correct (1)
19428
    * "The values of the properties of an attribute declaration must
19429
    * be as described in the property tableau in The Attribute
19430
    * Declaration Schema Component ($3.2.1), modulo the impact of
19431
    * Missing Sub-components ($5.3)."
19432
    */
19433
19434
0
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
19435
0
  return(0);
19436
19437
0
    if (attr->defValue != NULL) {
19438
0
  int ret;
19439
19440
  /*
19441
  * SPEC a-props-correct (3)
19442
  * "If the {type definition} is or is derived from ID then there
19443
  * must not be a {value constraint}."
19444
  */
19445
0
  if (xmlSchemaIsDerivedFromBuiltInType(
19446
0
      WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19447
0
  {
19448
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19449
0
    XML_SCHEMAP_A_PROPS_CORRECT_3,
19450
0
    NULL, WXS_BASIC_CAST attr,
19451
0
    "Value constraints are not allowed if the type definition "
19452
0
    "is or is derived from xs:ID",
19453
0
    NULL, NULL);
19454
0
      return(pctxt->err);
19455
0
  }
19456
  /*
19457
  * SPEC a-props-correct (2)
19458
  * "if there is a {value constraint}, the canonical lexical
19459
  * representation of its value must be `valid` with respect
19460
  * to the {type definition} as defined in String Valid ($3.14.4)."
19461
  * TODO: Don't care about the *canonical* stuff here, this requirement
19462
  * will be removed in WXS 1.1 anyway.
19463
  */
19464
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19465
0
      attr->node, WXS_ATTR_TYPEDEF(attr),
19466
0
      attr->defValue, &(attr->defVal),
19467
0
      1, 1, 0);
19468
0
  if (ret != 0) {
19469
0
      if (ret < 0) {
19470
0
    PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19471
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19472
0
    return(-1);
19473
0
      }
19474
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19475
0
    XML_SCHEMAP_A_PROPS_CORRECT_2,
19476
0
    NULL, WXS_BASIC_CAST attr,
19477
0
    "The value of the value constraint is not valid",
19478
0
    NULL, NULL);
19479
0
      return(pctxt->err);
19480
0
  }
19481
0
    }
19482
19483
0
    return(0);
19484
0
}
19485
19486
static xmlSchemaElementPtr
19487
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19488
         xmlSchemaElementPtr ancestor)
19489
0
{
19490
0
    xmlSchemaElementPtr ret;
19491
19492
0
    if (WXS_SUBST_HEAD(ancestor) == NULL)
19493
0
  return (NULL);
19494
0
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19495
0
  return (ancestor);
19496
19497
0
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19498
0
  return (NULL);
19499
0
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19500
0
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19501
0
  WXS_SUBST_HEAD(ancestor));
19502
0
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19503
19504
0
    return (ret);
19505
0
}
19506
19507
/**
19508
 * xmlSchemaCheckElemPropsCorrect:
19509
 * @ctxt:  a schema parser context
19510
 * @decl: the element declaration
19511
 * @name:  the name of the attribute
19512
 *
19513
 * Schema Component Constraint:
19514
 * Element Declaration Properties Correct (e-props-correct)
19515
 *
19516
 * STATUS:
19517
 *   missing: (6)
19518
 */
19519
static int
19520
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19521
             xmlSchemaElementPtr elemDecl)
19522
0
{
19523
0
    int ret = 0;
19524
0
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19525
    /*
19526
    * SPEC (1) "The values of the properties of an element declaration
19527
    * must be as described in the property tableau in The Element
19528
    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19529
    * Sub-components ($5.3)."
19530
    */
19531
0
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19532
0
  xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19533
19534
0
  xmlSchemaCheckElementDeclComponent(head, pctxt);
19535
  /*
19536
  * SPEC (3) "If there is a non-`absent` {substitution group
19537
  * affiliation}, then {scope} must be global."
19538
  */
19539
0
  if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19540
0
      xmlSchemaPCustomErr(pctxt,
19541
0
    XML_SCHEMAP_E_PROPS_CORRECT_3,
19542
0
    WXS_BASIC_CAST elemDecl, NULL,
19543
0
    "Only global element declarations can have a "
19544
0
    "substitution group affiliation", NULL);
19545
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19546
0
  }
19547
  /*
19548
  * TODO: SPEC (6) "Circular substitution groups are disallowed.
19549
  * That is, it must not be possible to return to an element declaration
19550
  * by repeatedly following the {substitution group affiliation}
19551
  * property."
19552
  */
19553
0
  if (head == elemDecl)
19554
0
      circ = head;
19555
0
  else if (WXS_SUBST_HEAD(head) != NULL)
19556
0
      circ = xmlSchemaCheckSubstGroupCircular(head, head);
19557
0
  else
19558
0
      circ = NULL;
19559
0
  if (circ != NULL) {
19560
0
      xmlChar *strA = NULL, *strB = NULL;
19561
19562
0
      xmlSchemaPCustomErrExt(pctxt,
19563
0
    XML_SCHEMAP_E_PROPS_CORRECT_6,
19564
0
    WXS_BASIC_CAST circ, NULL,
19565
0
    "The element declaration '%s' defines a circular "
19566
0
    "substitution group to element declaration '%s'",
19567
0
    xmlSchemaGetComponentQName(&strA, circ),
19568
0
    xmlSchemaGetComponentQName(&strB, head),
19569
0
    NULL);
19570
0
      FREE_AND_NULL(strA)
19571
0
      FREE_AND_NULL(strB)
19572
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19573
0
  }
19574
  /*
19575
  * SPEC (4) "If there is a {substitution group affiliation},
19576
  * the {type definition}
19577
  * of the element declaration must be validly derived from the {type
19578
  * definition} of the {substitution group affiliation}, given the value
19579
  * of the {substitution group exclusions} of the {substitution group
19580
  * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19581
  * (if the {type definition} is complex) or as defined in
19582
  * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19583
  * simple)."
19584
  *
19585
  * NOTE: {substitution group exclusions} means the values of the
19586
  * attribute "final".
19587
  */
19588
19589
0
  if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19590
0
      int set = 0;
19591
19592
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19593
0
    set |= SUBSET_EXTENSION;
19594
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19595
0
    set |= SUBSET_RESTRICTION;
19596
19597
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19598
0
    WXS_ELEM_TYPEDEF(head), set) != 0) {
19599
0
    xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19600
19601
0
    ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19602
0
    xmlSchemaPCustomErrExt(pctxt,
19603
0
        XML_SCHEMAP_E_PROPS_CORRECT_4,
19604
0
        WXS_BASIC_CAST elemDecl, NULL,
19605
0
        "The type definition '%s' was "
19606
0
        "either rejected by the substitution group "
19607
0
        "affiliation '%s', or not validly derived from its type "
19608
0
        "definition '%s'",
19609
0
        xmlSchemaGetComponentQName(&strA, typeDef),
19610
0
        xmlSchemaGetComponentQName(&strB, head),
19611
0
        xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19612
0
    FREE_AND_NULL(strA)
19613
0
    FREE_AND_NULL(strB)
19614
0
    FREE_AND_NULL(strC)
19615
0
      }
19616
0
  }
19617
0
    }
19618
    /*
19619
    * SPEC (5) "If the {type definition} or {type definition}'s
19620
    * {content type}
19621
    * is or is derived from ID then there must not be a {value constraint}.
19622
    * Note: The use of ID as a type definition for elements goes beyond
19623
    * XML 1.0, and should be avoided if backwards compatibility is desired"
19624
    */
19625
0
    if ((elemDecl->value != NULL) &&
19626
0
  ((WXS_IS_SIMPLE(typeDef) &&
19627
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19628
0
   (WXS_IS_COMPLEX(typeDef) &&
19629
0
    WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19630
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19631
0
      XML_SCHEMAS_ID)))) {
19632
19633
0
  ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19634
0
  xmlSchemaPCustomErr(pctxt,
19635
0
      XML_SCHEMAP_E_PROPS_CORRECT_5,
19636
0
      WXS_BASIC_CAST elemDecl, NULL,
19637
0
      "The type definition (or type definition's content type) is or "
19638
0
      "is derived from ID; value constraints are not allowed in "
19639
0
      "conjunction with such a type definition", NULL);
19640
0
    } else if (elemDecl->value != NULL) {
19641
0
  int vcret;
19642
0
  xmlNodePtr node = NULL;
19643
19644
  /*
19645
  * SPEC (2) "If there is a {value constraint}, the canonical lexical
19646
  * representation of its value must be `valid` with respect to the
19647
  * {type definition} as defined in Element Default Valid (Immediate)
19648
  * ($3.3.6)."
19649
  */
19650
0
  if (typeDef == NULL) {
19651
0
      xmlSchemaPErr(pctxt, elemDecl->node,
19652
0
    XML_SCHEMAP_INTERNAL,
19653
0
    "Internal error: xmlSchemaCheckElemPropsCorrect, "
19654
0
    "type is missing... skipping validation of "
19655
0
    "the value constraint", NULL, NULL);
19656
0
      return (-1);
19657
0
  }
19658
0
  if (elemDecl->node != NULL) {
19659
0
      if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19660
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19661
0
        BAD_CAST "fixed");
19662
0
      else
19663
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19664
0
        BAD_CAST "default");
19665
0
  }
19666
0
  vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19667
0
      typeDef, elemDecl->value, &(elemDecl->defVal));
19668
0
  if (vcret != 0) {
19669
0
      if (vcret < 0) {
19670
0
    PERROR_INT("xmlSchemaElemCheckValConstr",
19671
0
        "failed to validate the value constraint of an "
19672
0
        "element declaration");
19673
0
    return (-1);
19674
0
      }
19675
0
      return (vcret);
19676
0
  }
19677
0
    }
19678
19679
0
    return (ret);
19680
0
}
19681
19682
/**
19683
 * xmlSchemaCheckElemSubstGroup:
19684
 * @ctxt:  a schema parser context
19685
 * @decl: the element declaration
19686
 * @name:  the name of the attribute
19687
 *
19688
 * Schema Component Constraint:
19689
 * Substitution Group (cos-equiv-class)
19690
 *
19691
 * In Libxml2 the subst. groups will be precomputed, in terms of that
19692
 * a list will be built for each subst. group head, holding all direct
19693
 * referents to this head.
19694
 * NOTE that this function needs:
19695
 *   1. circular subst. groups to be checked beforehand
19696
 *   2. the declaration's type to be derived from the head's type
19697
 *
19698
 * STATUS:
19699
 *
19700
 */
19701
static void
19702
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19703
           xmlSchemaElementPtr elemDecl)
19704
0
{
19705
0
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19706
  /* SPEC (1) "Its {abstract} is false." */
19707
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19708
0
  return;
19709
0
    {
19710
0
  xmlSchemaElementPtr head;
19711
0
  xmlSchemaTypePtr headType, type;
19712
0
  int set, methSet;
19713
  /*
19714
  * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19715
  * {disallowed substitutions} as the blocking constraint, as defined in
19716
  * Substitution Group OK (Transitive) ($3.3.6)."
19717
  */
19718
0
  for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19719
0
      head = WXS_SUBST_HEAD(head)) {
19720
0
      set = 0;
19721
0
      methSet = 0;
19722
      /*
19723
      * The blocking constraints.
19724
      */
19725
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19726
0
    continue;
19727
0
      headType = head->subtypes;
19728
0
      type = elemDecl->subtypes;
19729
0
      if (headType == type)
19730
0
    goto add_member;
19731
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19732
0
    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19733
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19734
0
    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19735
      /*
19736
      * SPEC: Substitution Group OK (Transitive) (2.3)
19737
      * "The set of all {derivation method}s involved in the
19738
      * derivation of D's {type definition} from C's {type definition}
19739
      * does not intersect with the union of the blocking constraint,
19740
      * C's {prohibited substitutions} (if C is complex, otherwise the
19741
      * empty set) and the {prohibited substitutions} (respectively the
19742
      * empty set) of any intermediate {type definition}s in the
19743
      * derivation of D's {type definition} from C's {type definition}."
19744
      */
19745
      /*
19746
      * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19747
      * subst.head axis, the methSet does not need to be computed for
19748
      * the full depth over and over.
19749
      */
19750
      /*
19751
      * The set of all {derivation method}s involved in the derivation
19752
      */
19753
0
      while ((type != NULL) && (type != headType) &&
19754
0
                   (type != type->baseType)) {
19755
0
    if ((WXS_IS_EXTENSION(type)) &&
19756
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19757
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19758
19759
0
    if (WXS_IS_RESTRICTION(type) &&
19760
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19761
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19762
19763
0
    type = type->baseType;
19764
0
      }
19765
      /*
19766
      * The {prohibited substitutions} of all intermediate types +
19767
      * the head's type.
19768
      */
19769
0
      type = elemDecl->subtypes->baseType;
19770
0
      while (type != NULL) {
19771
0
    if (WXS_IS_COMPLEX(type)) {
19772
0
        if ((type->flags &
19773
0
          XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19774
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19775
0
        set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19776
0
        if ((type->flags &
19777
0
          XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19778
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19779
0
        set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19780
0
    } else
19781
0
        break;
19782
0
    if (type == headType)
19783
0
        break;
19784
0
    type = type->baseType;
19785
0
      }
19786
0
      if ((set != 0) &&
19787
0
    (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19788
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19789
0
    ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19790
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19791
0
    continue;
19792
0
      }
19793
0
add_member:
19794
0
      xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19795
0
      if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19796
0
    head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19797
0
  }
19798
0
    }
19799
0
}
19800
19801
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19802
/**
19803
 * xmlSchemaCheckElementDeclComponent
19804
 * @pctxt: the schema parser context
19805
 * @ctxtComponent: the context component (an element declaration)
19806
 * @ctxtParticle: the first particle of the context component
19807
 * @searchParticle: the element declaration particle to be analysed
19808
 *
19809
 * Schema Component Constraint: Element Declarations Consistent
19810
 */
19811
static int
19812
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19813
            xmlSchemaBasicItemPtr ctxtComponent,
19814
            xmlSchemaParticlePtr ctxtParticle,
19815
            xmlSchemaParticlePtr searchParticle,
19816
            xmlSchemaParticlePtr curParticle,
19817
            int search)
19818
{
19819
    return(0);
19820
19821
    int ret = 0;
19822
    xmlSchemaParticlePtr cur = curParticle;
19823
    if (curParticle == NULL) {
19824
  return(0);
19825
    }
19826
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19827
  /*
19828
  * Just return in this case. A missing "term" of the particle
19829
  * might arise due to an invalid "term" component.
19830
  */
19831
  return(0);
19832
    }
19833
    while (cur != NULL) {
19834
  switch (WXS_PARTICLE_TERM(cur)->type) {
19835
      case XML_SCHEMA_TYPE_ANY:
19836
    break;
19837
      case XML_SCHEMA_TYPE_ELEMENT:
19838
    if (search == 0) {
19839
        ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19840
      ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19841
        if (ret != 0)
19842
      return(ret);
19843
    } else {
19844
        xmlSchemaElementPtr elem =
19845
      WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19846
        /*
19847
        * SPEC Element Declarations Consistent:
19848
        * "If the {particles} contains, either directly,
19849
        * indirectly (that is, within the {particles} of a
19850
        * contained model group, recursively) or `implicitly`
19851
        * two or more element declaration particles with
19852
        * the same {name} and {target namespace}, then
19853
        * all their type definitions must be the same
19854
        * top-level definition [...]"
19855
        */
19856
        if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19857
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19858
      xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19859
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19860
        {
19861
      xmlChar *strA = NULL, *strB = NULL;
19862
19863
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19864
          /* TODO: error code */
19865
          XML_SCHEMAP_COS_NONAMBIG,
19866
          WXS_ITEM_NODE(cur), NULL,
19867
          "In the content model of %s, there are multiple "
19868
          "element declarations for '%s' with different "
19869
          "type definitions",
19870
          xmlSchemaGetComponentDesignation(&strA,
19871
        ctxtComponent),
19872
          xmlSchemaFormatQName(&strB,
19873
        WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19874
        WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19875
      FREE_AND_NULL(strA);
19876
      FREE_AND_NULL(strB);
19877
      return(XML_SCHEMAP_COS_NONAMBIG);
19878
        }
19879
    }
19880
    break;
19881
      case XML_SCHEMA_TYPE_SEQUENCE: {
19882
    break;
19883
    }
19884
      case XML_SCHEMA_TYPE_CHOICE:{
19885
    /*
19886
    xmlSchemaTreeItemPtr sub;
19887
19888
    sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19889
    while (sub != NULL) {
19890
        ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19891
      ctxtParticle, ctxtElem);
19892
        if (ret != 0)
19893
      return(ret);
19894
        sub = sub->next;
19895
    }
19896
    */
19897
    break;
19898
    }
19899
      case XML_SCHEMA_TYPE_ALL:
19900
    break;
19901
      case XML_SCHEMA_TYPE_GROUP:
19902
    break;
19903
      default:
19904
    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19905
        "xmlSchemaCheckElementDeclConsistent",
19906
        "found unexpected term of type '%s' in content model",
19907
        WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19908
    return(-1);
19909
  }
19910
  cur = (xmlSchemaParticlePtr) cur->next;
19911
    }
19912
19913
exit:
19914
    return(ret);
19915
}
19916
#endif
19917
19918
/**
19919
 * xmlSchemaCheckElementDeclComponent
19920
 * @item:  an schema element declaration/particle
19921
 * @ctxt:  a schema parser context
19922
 * @name:  the name of the attribute
19923
 *
19924
 * Validates the value constraints of an element declaration.
19925
 * Adds substitution group members.
19926
 */
19927
static void
19928
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19929
           xmlSchemaParserCtxtPtr ctxt)
19930
0
{
19931
0
    if (elemDecl == NULL)
19932
0
  return;
19933
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19934
0
  return;
19935
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19936
0
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19937
  /*
19938
  * Adds substitution group members.
19939
  */
19940
0
  xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19941
0
    }
19942
0
}
19943
19944
/**
19945
 * xmlSchemaResolveModelGroupParticleReferences:
19946
 * @particle:  a particle component
19947
 * @ctxt:  a parser context
19948
 *
19949
 * Resolves references of a model group's {particles} to
19950
 * model group definitions and to element declarations.
19951
 */
19952
static void
19953
xmlSchemaResolveModelGroupParticleReferences(
19954
    xmlSchemaParserCtxtPtr ctxt,
19955
    xmlSchemaModelGroupPtr mg)
19956
0
{
19957
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19958
0
    xmlSchemaQNameRefPtr ref;
19959
0
    xmlSchemaBasicItemPtr refItem;
19960
19961
    /*
19962
    * URGENT TODO: Test this.
19963
    */
19964
0
    while (particle != NULL) {
19965
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19966
0
      ((WXS_PARTICLE_TERM(particle))->type !=
19967
0
    XML_SCHEMA_EXTRA_QNAMEREF))
19968
0
  {
19969
0
      goto next_particle;
19970
0
  }
19971
0
  ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
19972
  /*
19973
  * Resolve the reference.
19974
  * NULL the {term} by default.
19975
  */
19976
0
  particle->children = NULL;
19977
19978
0
  refItem = xmlSchemaGetNamedComponent(ctxt->schema,
19979
0
      ref->itemType, ref->name, ref->targetNamespace);
19980
0
  if (refItem == NULL) {
19981
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
19982
0
    NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
19983
0
    ref->targetNamespace, ref->itemType, NULL);
19984
      /* TODO: remove the particle. */
19985
0
      goto next_particle;
19986
0
  }
19987
0
  if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
19988
0
      if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
19989
    /* TODO: remove the particle. */
19990
0
    goto next_particle;
19991
      /*
19992
      * NOTE that we will assign the model group definition
19993
      * itself to the "term" of the particle. This will ease
19994
      * the check for circular model group definitions. After
19995
      * that the "term" will be assigned the model group of the
19996
      * model group definition.
19997
      */
19998
0
      if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
19999
0
        XML_SCHEMA_TYPE_ALL) {
20000
    /*
20001
    * SPEC cos-all-limited (1)
20002
    * SPEC cos-all-limited (1.2)
20003
    * "It appears only as the value of one or both of the
20004
    * following properties:"
20005
    * (1.1) "the {model group} property of a model group
20006
    *        definition."
20007
    * (1.2) "the {term} property of a particle [... of] the "
20008
    * {content type} of a complex type definition."
20009
    */
20010
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20011
        /* TODO: error code */
20012
0
        XML_SCHEMAP_COS_ALL_LIMITED,
20013
0
        WXS_ITEM_NODE(particle), NULL,
20014
0
        "A model group definition is referenced, but "
20015
0
        "it contains an 'all' model group, which "
20016
0
        "cannot be contained by model groups",
20017
0
        NULL, NULL);
20018
    /* TODO: remove the particle. */
20019
0
    goto next_particle;
20020
0
      }
20021
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20022
0
  } else {
20023
      /*
20024
      * TODO: Are referenced element declarations the only
20025
      * other components we expect here?
20026
      */
20027
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20028
0
  }
20029
0
next_particle:
20030
0
  particle = WXS_PTC_CAST particle->next;
20031
0
    }
20032
0
}
20033
20034
static int
20035
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20036
           xmlSchemaValPtr y)
20037
0
{
20038
0
    xmlSchemaTypePtr tx, ty, ptx, pty;
20039
0
    int ret;
20040
20041
0
    while (x != NULL) {
20042
  /* Same types. */
20043
0
  tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20044
0
  ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20045
0
  ptx = xmlSchemaGetPrimitiveType(tx);
20046
0
  pty = xmlSchemaGetPrimitiveType(ty);
20047
  /*
20048
  * (1) if a datatype T' is `derived` by `restriction` from an
20049
  * atomic datatype T then the `value space` of T' is a subset of
20050
  * the `value space` of T. */
20051
  /*
20052
  * (2) if datatypes T' and T'' are `derived` by `restriction`
20053
  * from a common atomic ancestor T then the `value space`s of T'
20054
  * and T'' may overlap.
20055
  */
20056
0
  if (ptx != pty)
20057
0
      return(0);
20058
  /*
20059
  * We assume computed values to be normalized, so do a fast
20060
  * string comparison for string based types.
20061
  */
20062
0
  if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20063
0
      WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20064
0
      if (! xmlStrEqual(
20065
0
    xmlSchemaValueGetAsString(x),
20066
0
    xmlSchemaValueGetAsString(y)))
20067
0
    return (0);
20068
0
  } else {
20069
0
      ret = xmlSchemaCompareValuesWhtsp(
20070
0
    x, XML_SCHEMA_WHITESPACE_PRESERVE,
20071
0
    y, XML_SCHEMA_WHITESPACE_PRESERVE);
20072
0
      if (ret == -2)
20073
0
    return(-1);
20074
0
      if (ret != 0)
20075
0
    return(0);
20076
0
  }
20077
  /*
20078
  * Lists.
20079
  */
20080
0
  x = xmlSchemaValueGetNext(x);
20081
0
  if (x != NULL) {
20082
0
      y = xmlSchemaValueGetNext(y);
20083
0
      if (y == NULL)
20084
0
    return (0);
20085
0
  } else if (xmlSchemaValueGetNext(y) != NULL)
20086
0
      return (0);
20087
0
  else
20088
0
      return (1);
20089
0
    }
20090
0
    return (0);
20091
0
}
20092
20093
/**
20094
 * xmlSchemaResolveAttrUseReferences:
20095
 * @item:  an attribute use
20096
 * @ctxt:  a parser context
20097
 *
20098
 * Resolves the referenced attribute declaration.
20099
 */
20100
static int
20101
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20102
          xmlSchemaParserCtxtPtr ctxt)
20103
0
{
20104
0
    if ((ctxt == NULL) || (ause == NULL))
20105
0
  return(-1);
20106
0
    if ((ause->attrDecl == NULL) ||
20107
0
  (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20108
0
  return(0);
20109
20110
0
    {
20111
0
  xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20112
20113
  /*
20114
  * TODO: Evaluate, what errors could occur if the declaration is not
20115
  * found.
20116
  */
20117
0
  ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20118
0
      ref->name, ref->targetNamespace);
20119
0
        if (ause->attrDecl == NULL) {
20120
0
      xmlSchemaPResCompAttrErr(ctxt,
20121
0
    XML_SCHEMAP_SRC_RESOLVE,
20122
0
    WXS_BASIC_CAST ause, ause->node,
20123
0
    "ref", ref->name, ref->targetNamespace,
20124
0
    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20125
0
            return(ctxt->err);;
20126
0
        }
20127
0
    }
20128
0
    return(0);
20129
0
}
20130
20131
/**
20132
 * xmlSchemaCheckAttrUsePropsCorrect:
20133
 * @ctxt:  a parser context
20134
 * @use:  an attribute use
20135
 *
20136
 * Schema Component Constraint:
20137
 * Attribute Use Correct (au-props-correct)
20138
 *
20139
 */
20140
static int
20141
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20142
           xmlSchemaAttributeUsePtr use)
20143
0
{
20144
0
    if ((ctxt == NULL) || (use == NULL))
20145
0
  return(-1);
20146
0
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20147
0
  ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20148
0
  return(0);
20149
20150
    /*
20151
    * SPEC au-props-correct (1)
20152
    * "The values of the properties of an attribute use must be as
20153
    * described in the property tableau in The Attribute Use Schema
20154
    * Component ($3.5.1), modulo the impact of Missing
20155
    * Sub-components ($5.3)."
20156
    */
20157
20158
0
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20159
0
  ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20160
0
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20161
0
    {
20162
0
  xmlSchemaPCustomErr(ctxt,
20163
0
      XML_SCHEMAP_AU_PROPS_CORRECT_2,
20164
0
      WXS_BASIC_CAST use, NULL,
20165
0
      "The attribute declaration has a 'fixed' value constraint "
20166
0
      ", thus the attribute use must also have a 'fixed' value "
20167
0
      "constraint",
20168
0
      NULL);
20169
0
  return(ctxt->err);
20170
0
    }
20171
    /*
20172
    * Compute and check the value constraint's value.
20173
    */
20174
0
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20175
0
  int ret;
20176
  /*
20177
  * TODO: The spec seems to be missing a check of the
20178
  * value constraint of the attribute use. We will do it here.
20179
  */
20180
  /*
20181
  * SPEC a-props-correct (3)
20182
  */
20183
0
  if (xmlSchemaIsDerivedFromBuiltInType(
20184
0
      WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20185
0
  {
20186
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20187
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20188
0
    NULL, WXS_BASIC_CAST use,
20189
0
    "Value constraints are not allowed if the type definition "
20190
0
    "is or is derived from xs:ID",
20191
0
    NULL, NULL);
20192
0
      return(ctxt->err);
20193
0
  }
20194
20195
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20196
0
      use->node, WXS_ATTRUSE_TYPEDEF(use),
20197
0
      use->defValue, &(use->defVal),
20198
0
      1, 1, 0);
20199
0
  if (ret != 0) {
20200
0
      if (ret < 0) {
20201
0
    PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20202
0
        "calling xmlSchemaVCheckCVCSimpleType()");
20203
0
    return(-1);
20204
0
      }
20205
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20206
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20207
0
    NULL, WXS_BASIC_CAST use,
20208
0
    "The value of the value constraint is not valid",
20209
0
    NULL, NULL);
20210
0
      return(ctxt->err);
20211
0
  }
20212
0
    }
20213
    /*
20214
    * SPEC au-props-correct (2)
20215
    * "If the {attribute declaration} has a fixed
20216
    * {value constraint}, then if the attribute use itself has a
20217
    * {value constraint}, it must also be fixed and its value must match
20218
    * that of the {attribute declaration}'s {value constraint}."
20219
    */
20220
0
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20221
0
  (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20222
0
    {
20223
0
  if (! xmlSchemaAreValuesEqual(use->defVal,
20224
0
    (WXS_ATTRUSE_DECL(use))->defVal))
20225
0
  {
20226
0
      xmlSchemaPCustomErr(ctxt,
20227
0
    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20228
0
    WXS_BASIC_CAST use, NULL,
20229
0
    "The 'fixed' value constraint of the attribute use "
20230
0
    "must match the attribute declaration's value "
20231
0
    "constraint '%s'",
20232
0
    (WXS_ATTRUSE_DECL(use))->defValue);
20233
0
  }
20234
0
  return(ctxt->err);
20235
0
    }
20236
0
    return(0);
20237
0
}
20238
20239
20240
20241
20242
/**
20243
 * xmlSchemaResolveAttrTypeReferences:
20244
 * @item:  an attribute declaration
20245
 * @ctxt:  a parser context
20246
 *
20247
 * Resolves the referenced type definition component.
20248
 */
20249
static int
20250
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20251
           xmlSchemaParserCtxtPtr ctxt)
20252
0
{
20253
    /*
20254
    * The simple type definition corresponding to the <simpleType> element
20255
    * information item in the [children], if present, otherwise the simple
20256
    * type definition `resolved` to by the `actual value` of the type
20257
    * [attribute], if present, otherwise the `simple ur-type definition`.
20258
    */
20259
0
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20260
0
  return(0);
20261
0
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20262
0
    if (item->subtypes != NULL)
20263
0
        return(0);
20264
0
    if (item->typeName != NULL) {
20265
0
        xmlSchemaTypePtr type;
20266
20267
0
  type = xmlSchemaGetType(ctxt->schema, item->typeName,
20268
0
      item->typeNs);
20269
0
  if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20270
0
      xmlSchemaPResCompAttrErr(ctxt,
20271
0
    XML_SCHEMAP_SRC_RESOLVE,
20272
0
    WXS_BASIC_CAST item, item->node,
20273
0
    "type", item->typeName, item->typeNs,
20274
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
20275
0
      return(ctxt->err);
20276
0
  } else
20277
0
      item->subtypes = type;
20278
20279
0
    } else {
20280
  /*
20281
  * The type defaults to the xs:anySimpleType.
20282
  */
20283
0
  item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20284
0
    }
20285
0
    return(0);
20286
0
}
20287
20288
/**
20289
 * xmlSchemaResolveIDCKeyReferences:
20290
 * @idc:  the identity-constraint definition
20291
 * @ctxt:  the schema parser context
20292
 * @name:  the attribute name
20293
 *
20294
 * Resolve keyRef references to key/unique IDCs.
20295
 * Schema Component Constraint:
20296
 *   Identity-constraint Definition Properties Correct (c-props-correct)
20297
 */
20298
static int
20299
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20300
        xmlSchemaParserCtxtPtr pctxt)
20301
0
{
20302
0
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20303
0
        return(0);
20304
0
    if (idc->ref->name != NULL) {
20305
0
  idc->ref->item = (xmlSchemaBasicItemPtr)
20306
0
      xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20307
0
    idc->ref->targetNamespace);
20308
0
        if (idc->ref->item == NULL) {
20309
      /*
20310
      * TODO: It is actually not an error to fail to resolve
20311
      * at this stage. BUT we need to be that strict!
20312
      */
20313
0
      xmlSchemaPResCompAttrErr(pctxt,
20314
0
    XML_SCHEMAP_SRC_RESOLVE,
20315
0
    WXS_BASIC_CAST idc, idc->node,
20316
0
    "refer", idc->ref->name,
20317
0
    idc->ref->targetNamespace,
20318
0
    XML_SCHEMA_TYPE_IDC_KEY, NULL);
20319
0
            return(pctxt->err);
20320
0
  } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20321
      /*
20322
      * SPEC c-props-correct (1)
20323
      */
20324
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20325
0
    XML_SCHEMAP_C_PROPS_CORRECT,
20326
0
    NULL, WXS_BASIC_CAST idc,
20327
0
    "The keyref references a keyref",
20328
0
    NULL, NULL);
20329
0
      idc->ref->item = NULL;
20330
0
      return(pctxt->err);
20331
0
  } else {
20332
0
      if (idc->nbFields !=
20333
0
    ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20334
0
    xmlChar *str = NULL;
20335
0
    xmlSchemaIDCPtr refer;
20336
20337
0
    refer = (xmlSchemaIDCPtr) idc->ref->item;
20338
    /*
20339
    * SPEC c-props-correct(2)
20340
    * "If the {identity-constraint category} is keyref,
20341
    * the cardinality of the {fields} must equal that of
20342
    * the {fields} of the {referenced key}.
20343
    */
20344
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20345
0
        XML_SCHEMAP_C_PROPS_CORRECT,
20346
0
        NULL, WXS_BASIC_CAST idc,
20347
0
        "The cardinality of the keyref differs from the "
20348
0
        "cardinality of the referenced key/unique '%s'",
20349
0
        xmlSchemaFormatQName(&str, refer->targetNamespace,
20350
0
      refer->name),
20351
0
        NULL);
20352
0
    FREE_AND_NULL(str)
20353
0
    return(pctxt->err);
20354
0
      }
20355
0
  }
20356
0
    }
20357
0
    return(0);
20358
0
}
20359
20360
static int
20361
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20362
               xmlSchemaParserCtxtPtr pctxt)
20363
0
{
20364
0
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20365
0
  prohib->targetNamespace) == NULL) {
20366
20367
0
  xmlSchemaPResCompAttrErr(pctxt,
20368
0
      XML_SCHEMAP_SRC_RESOLVE,
20369
0
      NULL, prohib->node,
20370
0
      "ref", prohib->name, prohib->targetNamespace,
20371
0
      XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20372
0
  return(XML_SCHEMAP_SRC_RESOLVE);
20373
0
    }
20374
0
    return(0);
20375
0
}
20376
20377
0
#define WXS_REDEFINED_TYPE(c) \
20378
0
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20379
20380
0
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20381
0
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20382
20383
0
#define WXS_REDEFINED_ATTR_GROUP(c) \
20384
0
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20385
20386
static int
20387
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20388
0
{
20389
0
    int err = 0;
20390
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20391
0
    xmlSchemaBasicItemPtr prev, item;
20392
0
    int wasRedefined;
20393
20394
0
    if (redef == NULL)
20395
0
  return(0);
20396
20397
0
    do {
20398
0
  item = redef->item;
20399
  /*
20400
  * First try to locate the redefined component in the
20401
  * schema graph starting with the redefined schema.
20402
  * NOTE: According to this schema bug entry:
20403
  *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20404
  *   it's not clear if the referenced component needs to originate
20405
  *   from the <redefine>d schema _document_ or the schema; the latter
20406
  *   would include all imported and included sub-schemas of the
20407
  *   <redefine>d schema. Currently the latter approach is used.
20408
  *   SUPPLEMENT: It seems that the WG moves towards the latter
20409
  *   approach, so we are doing it right.
20410
  *
20411
  */
20412
0
  prev = xmlSchemaFindRedefCompInGraph(
20413
0
      redef->targetBucket, item->type,
20414
0
      redef->refName, redef->refTargetNs);
20415
0
  if (prev == NULL) {
20416
0
      xmlChar *str = NULL;
20417
0
      xmlNodePtr node;
20418
20419
      /*
20420
      * SPEC src-redefine:
20421
      * (6.2.1) "The `actual value` of its own name attribute plus
20422
      * target namespace must successfully `resolve` to a model
20423
      * group definition in I."
20424
      * (7.2.1) "The `actual value` of its own name attribute plus
20425
      * target namespace must successfully `resolve` to an attribute
20426
      * group definition in I."
20427
20428
      *
20429
      * Note that, if we are redefining with the use of references
20430
      * to components, the spec assumes the src-resolve to be used;
20431
      * but this won't assure that we search only *inside* the
20432
      * redefined schema.
20433
      */
20434
0
      if (redef->reference)
20435
0
    node = WXS_ITEM_NODE(redef->reference);
20436
0
      else
20437
0
    node = WXS_ITEM_NODE(item);
20438
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20439
    /*
20440
    * TODO: error code.
20441
    * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20442
    * reference kind.
20443
    */
20444
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20445
0
    "The %s '%s' to be redefined could not be found in "
20446
0
    "the redefined schema",
20447
0
    WXS_ITEM_TYPE_NAME(item),
20448
0
    xmlSchemaFormatQName(&str, redef->refTargetNs,
20449
0
        redef->refName));
20450
0
      FREE_AND_NULL(str);
20451
0
      err = pctxt->err;
20452
0
      redef = redef->next;
20453
0
      continue;
20454
0
  }
20455
  /*
20456
  * TODO: Obtaining and setting the redefinition state is really
20457
  * clumsy.
20458
  */
20459
0
  wasRedefined = 0;
20460
0
  switch (item->type) {
20461
0
      case XML_SCHEMA_TYPE_COMPLEX:
20462
0
      case XML_SCHEMA_TYPE_SIMPLE:
20463
0
    if ((WXS_TYPE_CAST prev)->flags &
20464
0
        XML_SCHEMAS_TYPE_REDEFINED)
20465
0
    {
20466
0
        wasRedefined = 1;
20467
0
        break;
20468
0
    }
20469
    /* Mark it as redefined. */
20470
0
    (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20471
    /*
20472
    * Assign the redefined type to the
20473
    * base type of the redefining type.
20474
    * TODO: How
20475
    */
20476
0
    ((xmlSchemaTypePtr) item)->baseType =
20477
0
        (xmlSchemaTypePtr) prev;
20478
0
    break;
20479
0
      case XML_SCHEMA_TYPE_GROUP:
20480
0
    if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20481
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20482
0
    {
20483
0
        wasRedefined = 1;
20484
0
        break;
20485
0
    }
20486
    /* Mark it as redefined. */
20487
0
    (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20488
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20489
0
    if (redef->reference != NULL) {
20490
        /*
20491
        * Overwrite the QName-reference with the
20492
        * referenced model group def.
20493
        */
20494
0
        (WXS_PTC_CAST redef->reference)->children =
20495
0
      WXS_TREE_CAST prev;
20496
0
    }
20497
0
    redef->target = prev;
20498
0
    break;
20499
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20500
0
    if ((WXS_ATTR_GROUP_CAST prev)->flags &
20501
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED)
20502
0
    {
20503
0
        wasRedefined = 1;
20504
0
        break;
20505
0
    }
20506
0
    (WXS_ATTR_GROUP_CAST prev)->flags |=
20507
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED;
20508
0
    if (redef->reference != NULL) {
20509
        /*
20510
        * Assign the redefined attribute group to the
20511
        * QName-reference component.
20512
        * This is the easy case, since we will just
20513
        * expand the redefined group.
20514
        */
20515
0
        (WXS_QNAME_CAST redef->reference)->item = prev;
20516
0
        redef->target = NULL;
20517
0
    } else {
20518
        /*
20519
        * This is the complicated case: we need
20520
        * to apply src-redefine (7.2.2) at a later
20521
        * stage, i.e. when attribute group references
20522
        * have been expanded and simple types have
20523
        * been fixed.
20524
        */
20525
0
        redef->target = prev;
20526
0
    }
20527
0
    break;
20528
0
      default:
20529
0
    PERROR_INT("xmlSchemaResolveRedefReferences",
20530
0
        "Unexpected redefined component type");
20531
0
    return(-1);
20532
0
  }
20533
0
  if (wasRedefined) {
20534
0
      xmlChar *str = NULL;
20535
0
      xmlNodePtr node;
20536
20537
0
      if (redef->reference)
20538
0
    node = WXS_ITEM_NODE(redef->reference);
20539
0
      else
20540
0
    node = WXS_ITEM_NODE(redef->item);
20541
20542
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20543
    /* TODO: error code. */
20544
0
    XML_SCHEMAP_SRC_REDEFINE,
20545
0
    node, NULL,
20546
0
    "The referenced %s was already redefined. Multiple "
20547
0
    "redefinition of the same component is not supported",
20548
0
    xmlSchemaGetComponentDesignation(&str, prev),
20549
0
    NULL);
20550
0
      FREE_AND_NULL(str)
20551
0
      err = pctxt->err;
20552
0
      redef = redef->next;
20553
0
      continue;
20554
0
  }
20555
0
  redef = redef->next;
20556
0
    } while (redef != NULL);
20557
20558
0
    return(err);
20559
0
}
20560
20561
static int
20562
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20563
0
{
20564
0
    int err = 0;
20565
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20566
0
    xmlSchemaBasicItemPtr item;
20567
20568
0
    if (redef == NULL)
20569
0
  return(0);
20570
20571
0
    do {
20572
0
  if (redef->target == NULL) {
20573
0
      redef = redef->next;
20574
0
      continue;
20575
0
  }
20576
0
  item = redef->item;
20577
20578
0
  switch (item->type) {
20579
0
      case XML_SCHEMA_TYPE_SIMPLE:
20580
0
      case XML_SCHEMA_TYPE_COMPLEX:
20581
    /*
20582
    * Since the spec wants the {name} of the redefined
20583
    * type to be 'absent', we'll NULL it.
20584
    */
20585
0
    (WXS_TYPE_CAST redef->target)->name = NULL;
20586
20587
    /*
20588
    * TODO: Seems like there's nothing more to do. The normal
20589
    * inheritance mechanism is used. But not 100% sure.
20590
    */
20591
0
    break;
20592
0
      case XML_SCHEMA_TYPE_GROUP:
20593
    /*
20594
    * URGENT TODO:
20595
    * SPEC src-redefine:
20596
    * (6.2.2) "The {model group} of the model group definition
20597
    * which corresponds to it per XML Representation of Model
20598
    * Group Definition Schema Components ($3.7.2) must be a
20599
    * `valid restriction` of the {model group} of that model
20600
    * group definition in I, as defined in Particle Valid
20601
    * (Restriction) ($3.9.6)."
20602
    */
20603
0
    break;
20604
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20605
    /*
20606
    * SPEC src-redefine:
20607
    * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20608
    * the attribute group definition which corresponds to it
20609
    * per XML Representation of Attribute Group Definition Schema
20610
    * Components ($3.6.2) must be `valid restrictions` of the
20611
    * {attribute uses} and {attribute wildcard} of that attribute
20612
    * group definition in I, as defined in clause 2, clause 3 and
20613
    * clause 4 of Derivation Valid (Restriction, Complex)
20614
    * ($3.4.6) (where references to the base type definition are
20615
    * understood as references to the attribute group definition
20616
    * in I)."
20617
    */
20618
0
    err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20619
0
        XML_SCHEMA_ACTION_REDEFINE,
20620
0
        item, redef->target,
20621
0
        (WXS_ATTR_GROUP_CAST item)->attrUses,
20622
0
        (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20623
0
        (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20624
0
        (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20625
0
    if (err == -1)
20626
0
        return(-1);
20627
0
    break;
20628
0
      default:
20629
0
    break;
20630
0
  }
20631
0
  redef = redef->next;
20632
0
    } while (redef != NULL);
20633
0
    return(0);
20634
0
}
20635
20636
20637
static int
20638
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20639
           xmlSchemaBucketPtr bucket)
20640
0
{
20641
0
    xmlSchemaBasicItemPtr item;
20642
0
    int err;
20643
0
    xmlHashTablePtr *table;
20644
0
    const xmlChar *name;
20645
0
    int i;
20646
20647
0
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20648
0
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20649
0
  table = &(WXS_IMPBUCKET((c))->schema->slot); \
20650
0
    else \
20651
0
  table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20652
20653
    /*
20654
    * Add global components to the schema's hash tables.
20655
    * This is the place where duplicate components will be
20656
    * detected.
20657
    * TODO: I think normally we should support imports of the
20658
    *   same namespace from multiple locations. We don't do currently,
20659
    *   but if we do then according to:
20660
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20661
    *   we would need, if imported directly, to import redefined
20662
    *   components as well to be able to catch clashing components.
20663
    *   (I hope I'll still know what this means after some months :-()
20664
    */
20665
0
    if (bucket == NULL)
20666
0
  return(-1);
20667
0
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20668
0
  return(0);
20669
0
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20670
20671
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
20672
0
  item = bucket->globals->items[i];
20673
0
  table = NULL;
20674
0
  switch (item->type) {
20675
0
      case XML_SCHEMA_TYPE_COMPLEX:
20676
0
      case XML_SCHEMA_TYPE_SIMPLE:
20677
0
    if (WXS_REDEFINED_TYPE(item))
20678
0
        continue;
20679
0
    name = (WXS_TYPE_CAST item)->name;
20680
0
    WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20681
0
    break;
20682
0
      case XML_SCHEMA_TYPE_ELEMENT:
20683
0
    name = (WXS_ELEM_CAST item)->name;
20684
0
    WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20685
0
    break;
20686
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20687
0
    name = (WXS_ATTR_CAST item)->name;
20688
0
    WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20689
0
    break;
20690
0
      case XML_SCHEMA_TYPE_GROUP:
20691
0
    if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20692
0
        continue;
20693
0
    name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20694
0
    WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20695
0
    break;
20696
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20697
0
    if (WXS_REDEFINED_ATTR_GROUP(item))
20698
0
        continue;
20699
0
    name = (WXS_ATTR_GROUP_CAST item)->name;
20700
0
    WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20701
0
    break;
20702
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20703
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20704
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20705
0
    name = (WXS_IDC_CAST item)->name;
20706
0
    WXS_GET_GLOBAL_HASH(bucket, idcDef)
20707
0
    break;
20708
0
      case XML_SCHEMA_TYPE_NOTATION:
20709
0
    name = ((xmlSchemaNotationPtr) item)->name;
20710
0
    WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20711
0
    break;
20712
0
      default:
20713
0
    PERROR_INT("xmlSchemaAddComponents",
20714
0
        "Unexpected global component type");
20715
0
    continue;
20716
0
  }
20717
0
  if (*table == NULL) {
20718
0
      *table = xmlHashCreateDict(10, pctxt->dict);
20719
0
      if (*table == NULL) {
20720
0
    PERROR_INT("xmlSchemaAddComponents",
20721
0
        "failed to create a component hash table");
20722
0
    return(-1);
20723
0
      }
20724
0
  }
20725
0
  err = xmlHashAddEntry(*table, name, item);
20726
0
  if (err != 0) {
20727
0
      xmlChar *str = NULL;
20728
20729
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20730
0
    XML_SCHEMAP_REDEFINED_TYPE,
20731
0
    WXS_ITEM_NODE(item),
20732
0
    WXS_BASIC_CAST item,
20733
0
    "A global %s '%s' does already exist",
20734
0
    WXS_ITEM_TYPE_NAME(item),
20735
0
    xmlSchemaGetComponentQName(&str, item));
20736
0
      FREE_AND_NULL(str);
20737
0
  }
20738
0
    }
20739
    /*
20740
    * Process imported/included schemas.
20741
    */
20742
0
    if (bucket->relations != NULL) {
20743
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
20744
0
  do {
20745
0
      if ((rel->bucket != NULL) &&
20746
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20747
0
    if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20748
0
        return(-1);
20749
0
      }
20750
0
      rel = rel->next;
20751
0
  } while (rel != NULL);
20752
0
    }
20753
0
    return(0);
20754
0
}
20755
20756
static int
20757
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20758
       xmlSchemaBucketPtr rootBucket)
20759
0
{
20760
0
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20761
0
    xmlSchemaTreeItemPtr item, *items;
20762
0
    int nbItems, i, ret = 0;
20763
0
    xmlSchemaBucketPtr oldbucket = con->bucket;
20764
0
    xmlSchemaElementPtr elemDecl;
20765
20766
0
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20767
20768
0
    if ((con->pending == NULL) ||
20769
0
  (con->pending->nbItems == 0))
20770
0
  return(0);
20771
20772
    /*
20773
    * Since xmlSchemaFixupComplexType() will create new particles
20774
    * (local components), and those particle components need a bucket
20775
    * on the constructor, we'll assure here that the constructor has
20776
    * a bucket.
20777
    * TODO: Think about storing locals _only_ on the main bucket.
20778
    */
20779
0
    if (con->bucket == NULL)
20780
0
  con->bucket = rootBucket;
20781
20782
    /* TODO:
20783
    * SPEC (src-redefine):
20784
    * (6.2) "If it has no such self-reference, then all of the
20785
    * following must be true:"
20786
20787
    * (6.2.2) The {model group} of the model group definition which
20788
    * corresponds to it per XML Representation of Model Group
20789
    * Definition Schema Components ($3.7.2) must be a `valid
20790
    * restriction` of the {model group} of that model group definition
20791
    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20792
    */
20793
0
    xmlSchemaCheckSRCRedefineFirst(pctxt);
20794
20795
    /*
20796
    * Add global components to the schemata's hash tables.
20797
    */
20798
0
    xmlSchemaAddComponents(pctxt, rootBucket);
20799
20800
0
    pctxt->ctxtType = NULL;
20801
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
20802
0
    nbItems = con->pending->nbItems;
20803
    /*
20804
    * Now that we have parsed *all* the schema document(s) and converted
20805
    * them to schema components, we can resolve references, apply component
20806
    * constraints, create the FSA from the content model, etc.
20807
    */
20808
    /*
20809
    * Resolve references of..
20810
    *
20811
    * 1. element declarations:
20812
    *   - the type definition
20813
    *   - the substitution group affiliation
20814
    * 2. simple/complex types:
20815
    *   - the base type definition
20816
    *   - the memberTypes of union types
20817
    *   - the itemType of list types
20818
    * 3. attributes declarations and attribute uses:
20819
    *   - the type definition
20820
    *   - if an attribute use, then the attribute declaration
20821
    * 4. attribute group references:
20822
    *   - the attribute group definition
20823
    * 5. particles:
20824
    *   - the term of the particle (e.g. a model group)
20825
    * 6. IDC key-references:
20826
    *   - the referenced IDC 'key' or 'unique' definition
20827
    * 7. Attribute prohibitions which had a "ref" attribute.
20828
    */
20829
0
    for (i = 0; i < nbItems; i++) {
20830
0
  item = items[i];
20831
0
  switch (item->type) {
20832
0
      case XML_SCHEMA_TYPE_ELEMENT:
20833
0
    xmlSchemaResolveElementReferences(
20834
0
        (xmlSchemaElementPtr) item, pctxt);
20835
0
    FIXHFAILURE;
20836
0
    break;
20837
0
      case XML_SCHEMA_TYPE_COMPLEX:
20838
0
      case XML_SCHEMA_TYPE_SIMPLE:
20839
0
    xmlSchemaResolveTypeReferences(
20840
0
        (xmlSchemaTypePtr) item, pctxt);
20841
0
    FIXHFAILURE;
20842
0
    break;
20843
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20844
0
    xmlSchemaResolveAttrTypeReferences(
20845
0
        (xmlSchemaAttributePtr) item, pctxt);
20846
0
    FIXHFAILURE;
20847
0
    break;
20848
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20849
0
    xmlSchemaResolveAttrUseReferences(
20850
0
        (xmlSchemaAttributeUsePtr) item, pctxt);
20851
0
    FIXHFAILURE;
20852
0
    break;
20853
0
      case XML_SCHEMA_EXTRA_QNAMEREF:
20854
0
    if ((WXS_QNAME_CAST item)->itemType ==
20855
0
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20856
0
    {
20857
0
        xmlSchemaResolveAttrGroupReferences(
20858
0
      WXS_QNAME_CAST item, pctxt);
20859
0
    }
20860
0
    FIXHFAILURE;
20861
0
    break;
20862
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20863
0
      case XML_SCHEMA_TYPE_CHOICE:
20864
0
      case XML_SCHEMA_TYPE_ALL:
20865
0
    xmlSchemaResolveModelGroupParticleReferences(pctxt,
20866
0
        WXS_MODEL_GROUP_CAST item);
20867
0
    FIXHFAILURE;
20868
0
    break;
20869
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20870
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20871
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20872
0
    xmlSchemaResolveIDCKeyReferences(
20873
0
        (xmlSchemaIDCPtr) item, pctxt);
20874
0
    FIXHFAILURE;
20875
0
    break;
20876
0
      case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20877
    /*
20878
    * Handle attribute prohibition which had a
20879
    * "ref" attribute.
20880
    */
20881
0
    xmlSchemaResolveAttrUseProhibReferences(
20882
0
        WXS_ATTR_PROHIB_CAST item, pctxt);
20883
0
    FIXHFAILURE;
20884
0
    break;
20885
0
      default:
20886
0
    break;
20887
0
  }
20888
0
    }
20889
0
    if (pctxt->nberrors != 0)
20890
0
  goto exit_error;
20891
20892
    /*
20893
    * Now that all references are resolved we
20894
    * can check for circularity of...
20895
    * 1. the base axis of type definitions
20896
    * 2. nested model group definitions
20897
    * 3. nested attribute group definitions
20898
    * TODO: check for circular substitution groups.
20899
    */
20900
0
    for (i = 0; i < nbItems; i++) {
20901
0
  item = items[i];
20902
  /*
20903
  * Let's better stop on the first error here.
20904
  */
20905
0
  switch (item->type) {
20906
0
      case XML_SCHEMA_TYPE_COMPLEX:
20907
0
      case XML_SCHEMA_TYPE_SIMPLE:
20908
0
    xmlSchemaCheckTypeDefCircular(
20909
0
        (xmlSchemaTypePtr) item, pctxt);
20910
0
    FIXHFAILURE;
20911
0
    if (pctxt->nberrors != 0)
20912
0
        goto exit_error;
20913
0
    break;
20914
0
      case XML_SCHEMA_TYPE_GROUP:
20915
0
    xmlSchemaCheckGroupDefCircular(
20916
0
        (xmlSchemaModelGroupDefPtr) item, pctxt);
20917
0
    FIXHFAILURE;
20918
0
    if (pctxt->nberrors != 0)
20919
0
        goto exit_error;
20920
0
    break;
20921
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20922
0
    xmlSchemaCheckAttrGroupCircular(
20923
0
        (xmlSchemaAttributeGroupPtr) item, pctxt);
20924
0
    FIXHFAILURE;
20925
0
    if (pctxt->nberrors != 0)
20926
0
        goto exit_error;
20927
0
    break;
20928
0
      default:
20929
0
    break;
20930
0
  }
20931
0
    }
20932
0
    if (pctxt->nberrors != 0)
20933
0
  goto exit_error;
20934
    /*
20935
    * Model group definition references:
20936
    * Such a reference is reflected by a particle at the component
20937
    * level. Until now the 'term' of such particles pointed
20938
    * to the model group definition; this was done, in order to
20939
    * ease circularity checks. Now we need to set the 'term' of
20940
    * such particles to the model group of the model group definition.
20941
    */
20942
0
    for (i = 0; i < nbItems; i++) {
20943
0
  item = items[i];
20944
0
  switch (item->type) {
20945
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20946
0
      case XML_SCHEMA_TYPE_CHOICE:
20947
0
    xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20948
0
        WXS_MODEL_GROUP_CAST item);
20949
0
    break;
20950
0
      default:
20951
0
    break;
20952
0
  }
20953
0
    }
20954
0
    if (pctxt->nberrors != 0)
20955
0
  goto exit_error;
20956
    /*
20957
    * Expand attribute group references of attribute group definitions.
20958
    */
20959
0
    for (i = 0; i < nbItems; i++) {
20960
0
  item = items[i];
20961
0
  switch (item->type) {
20962
0
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20963
0
    if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20964
0
        WXS_ATTR_GROUP_HAS_REFS(item))
20965
0
    {
20966
0
        xmlSchemaAttributeGroupExpandRefs(pctxt,
20967
0
      WXS_ATTR_GROUP_CAST item);
20968
0
        FIXHFAILURE;
20969
0
    }
20970
0
    break;
20971
0
      default:
20972
0
    break;
20973
0
  }
20974
0
    }
20975
0
    if (pctxt->nberrors != 0)
20976
0
  goto exit_error;
20977
    /*
20978
    * First compute the variety of simple types. This is needed as
20979
    * a separate step, since otherwise we won't be able to detect
20980
    * circular union types in all cases.
20981
    */
20982
0
    for (i = 0; i < nbItems; i++) {
20983
0
  item = items[i];
20984
0
  switch (item->type) {
20985
0
            case XML_SCHEMA_TYPE_SIMPLE:
20986
0
    if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
20987
0
        xmlSchemaFixupSimpleTypeStageOne(pctxt,
20988
0
      (xmlSchemaTypePtr) item);
20989
0
        FIXHFAILURE;
20990
0
    }
20991
0
    break;
20992
0
      default:
20993
0
    break;
20994
0
  }
20995
0
    }
20996
0
    if (pctxt->nberrors != 0)
20997
0
  goto exit_error;
20998
    /*
20999
    * Detect circular union types. Note that this needs the variety to
21000
    * be already computed.
21001
    */
21002
0
    for (i = 0; i < nbItems; i++) {
21003
0
  item = items[i];
21004
0
  switch (item->type) {
21005
0
            case XML_SCHEMA_TYPE_SIMPLE:
21006
0
    if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21007
0
        xmlSchemaCheckUnionTypeDefCircular(pctxt,
21008
0
      (xmlSchemaTypePtr) item);
21009
0
        FIXHFAILURE;
21010
0
    }
21011
0
    break;
21012
0
      default:
21013
0
    break;
21014
0
  }
21015
0
    }
21016
0
    if (pctxt->nberrors != 0)
21017
0
  goto exit_error;
21018
21019
    /*
21020
    * Do the complete type fixup for simple types.
21021
    */
21022
0
    for (i = 0; i < nbItems; i++) {
21023
0
  item = items[i];
21024
0
  switch (item->type) {
21025
0
            case XML_SCHEMA_TYPE_SIMPLE:
21026
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21027
0
        xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21028
0
        FIXHFAILURE;
21029
0
    }
21030
0
    break;
21031
0
      default:
21032
0
    break;
21033
0
  }
21034
0
    }
21035
0
    if (pctxt->nberrors != 0)
21036
0
  goto exit_error;
21037
    /*
21038
    * At this point we need build and check all simple types.
21039
    */
21040
    /*
21041
    * Apply constraints for attribute declarations.
21042
    */
21043
0
    for (i = 0; i < nbItems; i++) {
21044
0
  item = items[i];
21045
0
  switch (item->type) {
21046
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21047
0
    xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21048
0
    FIXHFAILURE;
21049
0
    break;
21050
0
      default:
21051
0
    break;
21052
0
  }
21053
0
    }
21054
0
    if (pctxt->nberrors != 0)
21055
0
  goto exit_error;
21056
    /*
21057
    * Apply constraints for attribute uses.
21058
    */
21059
0
    for (i = 0; i < nbItems; i++) {
21060
0
  item = items[i];
21061
0
  switch (item->type) {
21062
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21063
0
    if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21064
0
        xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21065
0
      WXS_ATTR_USE_CAST item);
21066
0
        FIXHFAILURE;
21067
0
    }
21068
0
    break;
21069
0
      default:
21070
0
    break;
21071
0
  }
21072
0
    }
21073
0
    if (pctxt->nberrors != 0)
21074
0
  goto exit_error;
21075
21076
    /*
21077
    * Apply constraints for attribute group definitions.
21078
    */
21079
0
    for (i = 0; i < nbItems; i++) {
21080
0
  item = items[i];
21081
0
  switch (item->type) {
21082
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21083
0
      if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21084
0
    ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21085
0
      {
21086
0
    xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21087
0
    FIXHFAILURE;
21088
0
      }
21089
0
      break;
21090
0
  default:
21091
0
      break;
21092
0
  }
21093
0
    }
21094
0
    if (pctxt->nberrors != 0)
21095
0
  goto exit_error;
21096
21097
    /*
21098
    * Apply constraints for redefinitions.
21099
    */
21100
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21101
0
  xmlSchemaCheckSRCRedefineSecond(pctxt);
21102
0
    if (pctxt->nberrors != 0)
21103
0
  goto exit_error;
21104
21105
    /*
21106
    * Complex types are built and checked.
21107
    */
21108
0
    for (i = 0; i < nbItems; i++) {
21109
0
  item = con->pending->items[i];
21110
0
  switch (item->type) {
21111
0
      case XML_SCHEMA_TYPE_COMPLEX:
21112
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21113
0
        xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21114
0
        FIXHFAILURE;
21115
0
    }
21116
0
    break;
21117
0
      default:
21118
0
    break;
21119
0
  }
21120
0
    }
21121
0
    if (pctxt->nberrors != 0)
21122
0
  goto exit_error;
21123
21124
    /*
21125
    * The list could have changed, since xmlSchemaFixupComplexType()
21126
    * will create particles and model groups in some cases.
21127
    */
21128
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
21129
0
    nbItems = con->pending->nbItems;
21130
21131
    /*
21132
    * Apply some constraints for element declarations.
21133
    */
21134
0
    for (i = 0; i < nbItems; i++) {
21135
0
  item = items[i];
21136
0
  switch (item->type) {
21137
0
      case XML_SCHEMA_TYPE_ELEMENT:
21138
0
    elemDecl = (xmlSchemaElementPtr) item;
21139
21140
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21141
0
    {
21142
0
        xmlSchemaCheckElementDeclComponent(
21143
0
      (xmlSchemaElementPtr) elemDecl, pctxt);
21144
0
        FIXHFAILURE;
21145
0
    }
21146
21147
#ifdef WXS_ELEM_DECL_CONS_ENABLED
21148
    /*
21149
    * Schema Component Constraint: Element Declarations Consistent
21150
    * Apply this constraint to local types of element declarations.
21151
    */
21152
    if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21153
        (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21154
        (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21155
    {
21156
        xmlSchemaCheckElementDeclConsistent(pctxt,
21157
      WXS_BASIC_CAST elemDecl,
21158
      WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21159
      NULL, NULL, 0);
21160
    }
21161
#endif
21162
0
    break;
21163
0
      default:
21164
0
    break;
21165
0
  }
21166
0
    }
21167
0
    if (pctxt->nberrors != 0)
21168
0
  goto exit_error;
21169
21170
    /*
21171
    * Finally we can build the automaton from the content model of
21172
    * complex types.
21173
    */
21174
21175
0
    for (i = 0; i < nbItems; i++) {
21176
0
  item = items[i];
21177
0
  switch (item->type) {
21178
0
      case XML_SCHEMA_TYPE_COMPLEX:
21179
0
    xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21180
    /* FIXHFAILURE; */
21181
0
    break;
21182
0
      default:
21183
0
    break;
21184
0
  }
21185
0
    }
21186
0
    if (pctxt->nberrors != 0)
21187
0
  goto exit_error;
21188
    /*
21189
    * URGENT TODO: cos-element-consistent
21190
    */
21191
0
    goto exit;
21192
21193
0
exit_error:
21194
0
    ret = pctxt->err;
21195
0
    goto exit;
21196
21197
0
exit_failure:
21198
0
    ret = -1;
21199
21200
0
exit:
21201
    /*
21202
    * Reset the constructor. This is needed for XSI acquisition, since
21203
    * those items will be processed over and over again for every XSI
21204
    * if not cleared here.
21205
    */
21206
0
    con->bucket = oldbucket;
21207
0
    con->pending->nbItems = 0;
21208
0
    if (con->substGroups != NULL) {
21209
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21210
0
  con->substGroups = NULL;
21211
0
    }
21212
0
    if (con->redefs != NULL) {
21213
0
  xmlSchemaRedefListFree(con->redefs);
21214
0
  con->redefs = NULL;
21215
0
    }
21216
0
    return(ret);
21217
0
}
21218
/**
21219
 * xmlSchemaParse:
21220
 * @ctxt:  a schema validation context
21221
 *
21222
 * parse a schema definition resource and build an internal
21223
 * XML Schema structure which can be used to validate instances.
21224
 *
21225
 * Returns the internal XML Schema structure built from the resource or
21226
 *         NULL in case of error
21227
 */
21228
xmlSchemaPtr
21229
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21230
0
{
21231
0
    xmlSchemaPtr mainSchema = NULL;
21232
0
    xmlSchemaBucketPtr bucket = NULL;
21233
0
    int res;
21234
21235
    /*
21236
    * This one is used if the schema to be parsed was specified via
21237
    * the API; i.e. not automatically by the validated instance document.
21238
    */
21239
21240
0
    if (xmlSchemaInitTypes() < 0)
21241
0
        return (NULL);
21242
21243
0
    if (ctxt == NULL)
21244
0
        return (NULL);
21245
21246
    /* TODO: Init the context. Is this all we need?*/
21247
0
    ctxt->nberrors = 0;
21248
0
    ctxt->err = 0;
21249
0
    ctxt->counter = 0;
21250
21251
    /* Create the *main* schema. */
21252
0
    mainSchema = xmlSchemaNewSchema(ctxt);
21253
0
    if (mainSchema == NULL)
21254
0
  goto exit_failure;
21255
    /*
21256
    * Create the schema constructor.
21257
    */
21258
0
    if (ctxt->constructor == NULL) {
21259
0
  ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21260
0
  if (ctxt->constructor == NULL)
21261
0
      goto exit_failure;
21262
  /* Take ownership of the constructor to be able to free it. */
21263
0
  ctxt->ownsConstructor = 1;
21264
0
    }
21265
0
    ctxt->constructor->mainSchema = mainSchema;
21266
    /*
21267
    * Locate and add the schema document.
21268
    */
21269
0
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21270
0
  ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21271
0
  NULL, NULL, &bucket);
21272
0
    if (res == -1)
21273
0
  goto exit_failure;
21274
0
    if (res != 0)
21275
0
  goto exit;
21276
21277
0
    if (bucket == NULL) {
21278
  /* TODO: Error code, actually we failed to *locate* the schema. */
21279
0
  if (ctxt->URL)
21280
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21281
0
    NULL, NULL,
21282
0
    "Failed to locate the main schema resource at '%s'",
21283
0
    ctxt->URL, NULL);
21284
0
  else
21285
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21286
0
    NULL, NULL,
21287
0
    "Failed to locate the main schema resource",
21288
0
        NULL, NULL);
21289
0
  goto exit;
21290
0
    }
21291
    /* Then do the parsing for good. */
21292
0
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21293
0
  goto exit_failure;
21294
0
    if (ctxt->nberrors != 0)
21295
0
  goto exit;
21296
21297
0
    mainSchema->doc = bucket->doc;
21298
0
    mainSchema->preserve = ctxt->preserve;
21299
21300
0
    ctxt->schema = mainSchema;
21301
21302
0
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21303
0
  goto exit_failure;
21304
21305
    /*
21306
    * TODO: This is not nice, since we cannot distinguish from the
21307
    * result if there was an internal error or not.
21308
    */
21309
0
exit:
21310
0
    if (ctxt->nberrors != 0) {
21311
0
  if (mainSchema) {
21312
0
      xmlSchemaFree(mainSchema);
21313
0
      mainSchema = NULL;
21314
0
  }
21315
0
  if (ctxt->constructor) {
21316
0
      xmlSchemaConstructionCtxtFree(ctxt->constructor);
21317
0
      ctxt->constructor = NULL;
21318
0
      ctxt->ownsConstructor = 0;
21319
0
  }
21320
0
    }
21321
0
    ctxt->schema = NULL;
21322
0
    return(mainSchema);
21323
0
exit_failure:
21324
    /*
21325
    * Quite verbose, but should catch internal errors, which were
21326
    * not communicated.
21327
    */
21328
0
    if (mainSchema) {
21329
0
        xmlSchemaFree(mainSchema);
21330
0
  mainSchema = NULL;
21331
0
    }
21332
0
    if (ctxt->constructor) {
21333
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
21334
0
  ctxt->constructor = NULL;
21335
0
  ctxt->ownsConstructor = 0;
21336
0
    }
21337
0
    PERROR_INT2("xmlSchemaParse",
21338
0
  "An internal error occurred");
21339
0
    ctxt->schema = NULL;
21340
0
    return(NULL);
21341
0
}
21342
21343
/**
21344
 * xmlSchemaSetParserErrors:
21345
 * @ctxt:  a schema validation context
21346
 * @err:  the error callback
21347
 * @warn:  the warning callback
21348
 * @ctx:  contextual data for the callbacks
21349
 *
21350
 * DEPRECATED: Use xmlSchemaSetParserStructuredErrors.
21351
 *
21352
 * Set the callback functions used to handle errors for a validation context
21353
 */
21354
void
21355
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21356
                         xmlSchemaValidityErrorFunc err,
21357
                         xmlSchemaValidityWarningFunc warn, void *ctx)
21358
0
{
21359
0
    if (ctxt == NULL)
21360
0
        return;
21361
0
    ctxt->error = err;
21362
0
    ctxt->warning = warn;
21363
0
    ctxt->errCtxt = ctx;
21364
0
    if (ctxt->vctxt != NULL)
21365
0
  xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21366
0
}
21367
21368
/**
21369
 * xmlSchemaSetParserStructuredErrors:
21370
 * @ctxt:  a schema parser context
21371
 * @serror:  the structured error function
21372
 * @ctx: the functions context
21373
 *
21374
 * Set the structured error callback
21375
 */
21376
void
21377
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21378
           xmlStructuredErrorFunc serror,
21379
           void *ctx)
21380
0
{
21381
0
    if (ctxt == NULL)
21382
0
  return;
21383
0
    ctxt->serror = serror;
21384
0
    ctxt->errCtxt = ctx;
21385
0
    if (ctxt->vctxt != NULL)
21386
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21387
0
}
21388
21389
/**
21390
 * xmlSchemaGetParserErrors:
21391
 * @ctxt:  a XMl-Schema parser context
21392
 * @err: the error callback result
21393
 * @warn: the warning callback result
21394
 * @ctx: contextual data for the callbacks result
21395
 *
21396
 * Get the callback information used to handle errors for a parser context
21397
 *
21398
 * Returns -1 in case of failure, 0 otherwise
21399
 */
21400
int
21401
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21402
       xmlSchemaValidityErrorFunc * err,
21403
       xmlSchemaValidityWarningFunc * warn, void **ctx)
21404
0
{
21405
0
  if (ctxt == NULL)
21406
0
    return(-1);
21407
0
  if (err != NULL)
21408
0
    *err = ctxt->error;
21409
0
  if (warn != NULL)
21410
0
    *warn = ctxt->warning;
21411
0
  if (ctx != NULL)
21412
0
    *ctx = ctxt->errCtxt;
21413
0
  return(0);
21414
0
}
21415
21416
/**
21417
 * xmlSchemaFacetTypeToString:
21418
 * @type:  the facet type
21419
 *
21420
 * Convert the xmlSchemaTypeType to a char string.
21421
 *
21422
 * Returns the char string representation of the facet type if the
21423
 *     type is a facet and an "Internal Error" string otherwise.
21424
 */
21425
static const xmlChar *
21426
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21427
0
{
21428
0
    switch (type) {
21429
0
        case XML_SCHEMA_FACET_PATTERN:
21430
0
            return (BAD_CAST "pattern");
21431
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21432
0
            return (BAD_CAST "maxExclusive");
21433
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
21434
0
            return (BAD_CAST "maxInclusive");
21435
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
21436
0
            return (BAD_CAST "minExclusive");
21437
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
21438
0
            return (BAD_CAST "minInclusive");
21439
0
        case XML_SCHEMA_FACET_WHITESPACE:
21440
0
            return (BAD_CAST "whiteSpace");
21441
0
        case XML_SCHEMA_FACET_ENUMERATION:
21442
0
            return (BAD_CAST "enumeration");
21443
0
        case XML_SCHEMA_FACET_LENGTH:
21444
0
            return (BAD_CAST "length");
21445
0
        case XML_SCHEMA_FACET_MAXLENGTH:
21446
0
            return (BAD_CAST "maxLength");
21447
0
        case XML_SCHEMA_FACET_MINLENGTH:
21448
0
            return (BAD_CAST "minLength");
21449
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
21450
0
            return (BAD_CAST "totalDigits");
21451
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
21452
0
            return (BAD_CAST "fractionDigits");
21453
0
        default:
21454
0
            break;
21455
0
    }
21456
0
    return (BAD_CAST "Internal Error");
21457
0
}
21458
21459
static xmlSchemaWhitespaceValueType
21460
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21461
0
{
21462
    /*
21463
    * The normalization type can be changed only for types which are derived
21464
    * from xsd:string.
21465
    */
21466
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
21467
  /*
21468
  * Note that we assume a whitespace of preserve for anySimpleType.
21469
  */
21470
0
  if ((type->builtInType == XML_SCHEMAS_STRING) ||
21471
0
      (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21472
0
      return(XML_SCHEMA_WHITESPACE_PRESERVE);
21473
0
  else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21474
0
      return(XML_SCHEMA_WHITESPACE_REPLACE);
21475
0
  else {
21476
      /*
21477
      * For all `atomic` datatypes other than string (and types `derived`
21478
      * by `restriction` from it) the value of whiteSpace is fixed to
21479
      * collapse
21480
      * Note that this includes built-in list datatypes.
21481
      */
21482
0
      return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21483
0
  }
21484
0
    } else if (WXS_IS_LIST(type)) {
21485
  /*
21486
  * For list types the facet "whiteSpace" is fixed to "collapse".
21487
  */
21488
0
  return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21489
0
    } else if (WXS_IS_UNION(type)) {
21490
0
  return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21491
0
    } else if (WXS_IS_ATOMIC(type)) {
21492
0
  if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21493
0
      return (XML_SCHEMA_WHITESPACE_PRESERVE);
21494
0
  else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21495
0
      return (XML_SCHEMA_WHITESPACE_REPLACE);
21496
0
  else
21497
0
      return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21498
0
    }
21499
0
    return (-1);
21500
0
}
21501
21502
/************************************************************************
21503
 *                  *
21504
 *      Simple type validation        *
21505
 *                  *
21506
 ************************************************************************/
21507
21508
21509
/************************************************************************
21510
 *                  *
21511
 *      DOM Validation code       *
21512
 *                  *
21513
 ************************************************************************/
21514
21515
/**
21516
 * xmlSchemaAssembleByLocation:
21517
 * @pctxt:  a schema parser context
21518
 * @vctxt:  a schema validation context
21519
 * @schema: the existing schema
21520
 * @node: the node that fired the assembling
21521
 * @nsName: the namespace name of the new schema
21522
 * @location: the location of the schema
21523
 *
21524
 * Expands an existing schema by an additional schema.
21525
 *
21526
 * Returns 0 if the new schema is correct, a positive error code
21527
 * number otherwise and -1 in case of an internal or API error.
21528
 */
21529
static int
21530
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21531
          xmlSchemaPtr schema,
21532
          xmlNodePtr node,
21533
          const xmlChar *nsName,
21534
          const xmlChar *location)
21535
0
{
21536
0
    int ret = 0;
21537
0
    xmlSchemaParserCtxtPtr pctxt;
21538
0
    xmlSchemaBucketPtr bucket = NULL;
21539
21540
0
    if ((vctxt == NULL) || (schema == NULL))
21541
0
  return (-1);
21542
21543
0
    if (vctxt->pctxt == NULL) {
21544
0
  VERROR_INT("xmlSchemaAssembleByLocation",
21545
0
      "no parser context available");
21546
0
  return(-1);
21547
0
    }
21548
0
    pctxt = vctxt->pctxt;
21549
0
    if (pctxt->constructor == NULL) {
21550
0
  PERROR_INT("xmlSchemaAssembleByLocation",
21551
0
      "no constructor");
21552
0
  return(-1);
21553
0
    }
21554
    /*
21555
    * Acquire the schema document.
21556
    */
21557
0
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21558
0
  location, node);
21559
    /*
21560
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21561
    * the process will automatically change this to
21562
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21563
    */
21564
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21565
0
  location, NULL, NULL, 0, node, NULL, nsName,
21566
0
  &bucket);
21567
0
    if (ret != 0)
21568
0
  return(ret);
21569
0
    if (bucket == NULL) {
21570
  /*
21571
  * Generate a warning that the document could not be located.
21572
  */
21573
0
  xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21574
0
      node, NULL,
21575
0
      "The document at location '%s' could not be acquired",
21576
0
      location, NULL, NULL);
21577
0
  return(ret);
21578
0
    }
21579
    /*
21580
    * The first located schema will be handled as if all other
21581
    * schemas imported by XSI were imported by this first schema.
21582
    */
21583
0
    if ((bucket != NULL) &&
21584
0
  (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21585
0
  WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21586
    /*
21587
    * TODO: Is this handled like an import? I.e. is it not an error
21588
    * if the schema cannot be located?
21589
    */
21590
0
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21591
0
  return(0);
21592
    /*
21593
    * We will reuse the parser context for every schema imported
21594
    * directly via XSI. So reset the context.
21595
    */
21596
0
    pctxt->nberrors = 0;
21597
0
    pctxt->err = 0;
21598
0
    pctxt->doc = bucket->doc;
21599
21600
0
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21601
0
    if (ret == -1) {
21602
0
  pctxt->doc = NULL;
21603
0
  goto exit_failure;
21604
0
    }
21605
    /* Paranoid error channelling. */
21606
0
    if ((ret == 0) && (pctxt->nberrors != 0))
21607
0
  ret = pctxt->err;
21608
0
    if (pctxt->nberrors == 0) {
21609
  /*
21610
  * Only bother to fixup pending components, if there was
21611
  * no error yet.
21612
  * For every XSI acquired schema (and its sub-schemata) we will
21613
  * fixup the components.
21614
  */
21615
0
  xmlSchemaFixupComponents(pctxt, bucket);
21616
0
  ret = pctxt->err;
21617
  /*
21618
  * Not nice, but we need somehow to channel the schema parser
21619
  * error to the validation context.
21620
  */
21621
0
  if ((ret != 0) && (vctxt->err == 0))
21622
0
      vctxt->err = ret;
21623
0
  vctxt->nberrors += pctxt->nberrors;
21624
0
    } else {
21625
  /* Add to validation error sum. */
21626
0
  vctxt->nberrors += pctxt->nberrors;
21627
0
    }
21628
0
    pctxt->doc = NULL;
21629
0
    return(ret);
21630
0
exit_failure:
21631
0
    pctxt->doc = NULL;
21632
0
    return (-1);
21633
0
}
21634
21635
static xmlSchemaAttrInfoPtr
21636
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21637
       int metaType)
21638
0
{
21639
0
    if (vctxt->nbAttrInfos == 0)
21640
0
  return (NULL);
21641
0
    {
21642
0
  int i;
21643
0
  xmlSchemaAttrInfoPtr iattr;
21644
21645
0
  for (i = 0; i < vctxt->nbAttrInfos; i++) {
21646
0
      iattr = vctxt->attrInfos[i];
21647
0
      if (iattr->metaType == metaType)
21648
0
    return (iattr);
21649
0
  }
21650
21651
0
    }
21652
0
    return (NULL);
21653
0
}
21654
21655
/**
21656
 * xmlSchemaAssembleByXSI:
21657
 * @vctxt:  a schema validation context
21658
 *
21659
 * Expands an existing schema by an additional schema using
21660
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21661
 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21662
 * must be set to 1.
21663
 *
21664
 * Returns 0 if the new schema is correct, a positive error code
21665
 * number otherwise and -1 in case of an internal or API error.
21666
 */
21667
static int
21668
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21669
0
{
21670
0
    const xmlChar *cur, *end;
21671
0
    const xmlChar *nsname = NULL, *location;
21672
0
    int ret = 0;
21673
0
    xmlSchemaAttrInfoPtr iattr;
21674
21675
    /*
21676
    * Parse the value; we will assume an even number of values
21677
    * to be given (this is how Xerces and XSV work).
21678
    *
21679
    * URGENT TODO: !! This needs to work for both
21680
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
21681
    * element !!
21682
    */
21683
0
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21684
0
  XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21685
0
    if (iattr == NULL)
21686
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21687
0
  XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21688
0
    if (iattr == NULL)
21689
0
  return (0);
21690
0
    cur = iattr->value;
21691
0
    do {
21692
  /*
21693
  * TODO: Move the string parsing mechanism away from here.
21694
  */
21695
0
  if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21696
      /*
21697
      * Get the namespace name.
21698
      */
21699
0
      while (IS_BLANK_CH(*cur))
21700
0
    cur++;
21701
0
      end = cur;
21702
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21703
0
    end++;
21704
0
      if (end == cur)
21705
0
    break;
21706
      /* TODO: Don't use the schema's dict. */
21707
0
      nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21708
0
      cur = end;
21709
0
  }
21710
  /*
21711
  * Get the URI.
21712
  */
21713
0
  while (IS_BLANK_CH(*cur))
21714
0
      cur++;
21715
0
  end = cur;
21716
0
  while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21717
0
      end++;
21718
0
  if (end == cur) {
21719
0
      if (iattr->metaType ==
21720
0
    XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21721
0
      {
21722
    /*
21723
    * If using @schemaLocation then tuples are expected.
21724
    * I.e. the namespace name *and* the document's URI.
21725
    */
21726
0
    xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21727
0
        iattr->node, NULL,
21728
0
        "The value must consist of tuples: the target namespace "
21729
0
        "name and the document's URI", NULL, NULL, NULL);
21730
0
      }
21731
0
      break;
21732
0
  }
21733
  /* TODO: Don't use the schema's dict. */
21734
0
  location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21735
0
  cur = end;
21736
0
  ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21737
0
      iattr->node, nsname, location);
21738
0
  if (ret == -1) {
21739
0
      VERROR_INT("xmlSchemaAssembleByXSI",
21740
0
    "assembling schemata");
21741
0
      return (-1);
21742
0
  }
21743
0
    } while (*cur != 0);
21744
0
    return (ret);
21745
0
}
21746
21747
static const xmlChar *
21748
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21749
       const xmlChar *prefix)
21750
0
{
21751
0
    if (vctxt->sax != NULL) {
21752
0
  int i, j;
21753
0
  xmlSchemaNodeInfoPtr inode;
21754
21755
0
  for (i = vctxt->depth; i >= 0; i--) {
21756
0
      if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21757
0
    inode = vctxt->elemInfos[i];
21758
0
    for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21759
0
        if (((prefix == NULL) &&
21760
0
          (inode->nsBindings[j] == NULL)) ||
21761
0
      ((prefix != NULL) && xmlStrEqual(prefix,
21762
0
          inode->nsBindings[j]))) {
21763
21764
      /*
21765
      * Note that the namespace bindings are already
21766
      * in a string dict.
21767
      */
21768
0
      return (inode->nsBindings[j+1]);
21769
0
        }
21770
0
    }
21771
0
      }
21772
0
  }
21773
0
  return (NULL);
21774
0
#ifdef LIBXML_READER_ENABLED
21775
0
    } else if (vctxt->reader != NULL) {
21776
0
  xmlChar *nsName;
21777
21778
0
  nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21779
0
  if (nsName != NULL) {
21780
0
      const xmlChar *ret;
21781
21782
0
      ret = xmlDictLookup(vctxt->dict, nsName, -1);
21783
0
      xmlFree(nsName);
21784
0
      return (ret);
21785
0
  } else
21786
0
      return (NULL);
21787
0
#endif
21788
0
    } else {
21789
0
  xmlNsPtr ns;
21790
21791
0
  if ((vctxt->inode->node == NULL) ||
21792
0
      (vctxt->inode->node->doc == NULL)) {
21793
0
      VERROR_INT("xmlSchemaLookupNamespace",
21794
0
    "no node or node's doc available");
21795
0
      return (NULL);
21796
0
  }
21797
0
  ns = xmlSearchNs(vctxt->inode->node->doc,
21798
0
      vctxt->inode->node, prefix);
21799
0
  if (ns != NULL)
21800
0
      return (ns->href);
21801
0
  return (NULL);
21802
0
    }
21803
0
}
21804
21805
/*
21806
* This one works on the schema of the validation context.
21807
*/
21808
static int
21809
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21810
        xmlSchemaPtr schema,
21811
        xmlNodePtr node,
21812
        const xmlChar *value,
21813
        xmlSchemaValPtr *val,
21814
        int valNeeded)
21815
0
{
21816
0
    int ret;
21817
21818
0
    if (vctxt && (vctxt->schema == NULL)) {
21819
0
  VERROR_INT("xmlSchemaValidateNotation",
21820
0
      "a schema is needed on the validation context");
21821
0
  return (-1);
21822
0
    }
21823
0
    ret = xmlValidateQName(value, 1);
21824
0
    if (ret != 0)
21825
0
  return (ret);
21826
0
    {
21827
0
  xmlChar *localName = NULL;
21828
0
  xmlChar *prefix = NULL;
21829
21830
0
  localName = xmlSplitQName2(value, &prefix);
21831
0
  if (prefix != NULL) {
21832
0
      const xmlChar *nsName = NULL;
21833
21834
0
      if (vctxt != NULL)
21835
0
    nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21836
0
      else if (node != NULL) {
21837
0
    xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21838
0
    if (ns != NULL)
21839
0
        nsName = ns->href;
21840
0
      } else {
21841
0
    xmlFree(prefix);
21842
0
    xmlFree(localName);
21843
0
    return (1);
21844
0
      }
21845
0
      if (nsName == NULL) {
21846
0
    xmlFree(prefix);
21847
0
    xmlFree(localName);
21848
0
    return (1);
21849
0
      }
21850
0
      if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21851
0
    if ((valNeeded) && (val != NULL)) {
21852
0
        (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21853
0
                   xmlStrdup(nsName));
21854
0
        if (*val == NULL)
21855
0
      ret = -1;
21856
0
    }
21857
0
      } else
21858
0
    ret = 1;
21859
0
      xmlFree(prefix);
21860
0
      xmlFree(localName);
21861
0
  } else {
21862
0
      if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21863
0
    if (valNeeded && (val != NULL)) {
21864
0
        (*val) = xmlSchemaNewNOTATIONValue(
21865
0
      BAD_CAST xmlStrdup(value), NULL);
21866
0
        if (*val == NULL)
21867
0
      ret = -1;
21868
0
    }
21869
0
      } else
21870
0
    return (1);
21871
0
  }
21872
0
    }
21873
0
    return (ret);
21874
0
}
21875
21876
static int
21877
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21878
           const xmlChar* lname,
21879
           const xmlChar* nsname)
21880
0
{
21881
0
    int i;
21882
21883
0
    lname = xmlDictLookup(vctxt->dict, lname, -1);
21884
0
    if (lname == NULL)
21885
0
  return(-1);
21886
0
    if (nsname != NULL) {
21887
0
  nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21888
0
  if (nsname == NULL)
21889
0
      return(-1);
21890
0
    }
21891
0
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21892
0
  if ((vctxt->nodeQNames->items [i] == lname) &&
21893
0
      (vctxt->nodeQNames->items[i +1] == nsname))
21894
      /* Already there */
21895
0
      return(i);
21896
0
    }
21897
    /* Add new entry. */
21898
0
    i = vctxt->nodeQNames->nbItems;
21899
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21900
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21901
0
    return(i);
21902
0
}
21903
21904
/************************************************************************
21905
 *                  *
21906
 *  Validation of identity-constraints (IDC)                            *
21907
 *                  *
21908
 ************************************************************************/
21909
21910
/**
21911
 * xmlSchemaAugmentIDC:
21912
 * @idcDef: the IDC definition
21913
 *
21914
 * Creates an augmented IDC definition item.
21915
 *
21916
 * Returns the item, or NULL on internal errors.
21917
 */
21918
static void
21919
xmlSchemaAugmentIDC(void *payload, void *data,
21920
                    const xmlChar *name ATTRIBUTE_UNUSED)
21921
0
{
21922
0
    xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
21923
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21924
0
    xmlSchemaIDCAugPtr aidc;
21925
21926
0
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21927
0
    if (aidc == NULL) {
21928
0
  xmlSchemaVErrMemory(vctxt);
21929
0
  return;
21930
0
    }
21931
0
    aidc->keyrefDepth = -1;
21932
0
    aidc->def = idcDef;
21933
0
    aidc->next = NULL;
21934
0
    if (vctxt->aidcs == NULL)
21935
0
  vctxt->aidcs = aidc;
21936
0
    else {
21937
0
  aidc->next = vctxt->aidcs;
21938
0
  vctxt->aidcs = aidc;
21939
0
    }
21940
    /*
21941
    * Save if we have keyrefs at all.
21942
    */
21943
0
    if ((vctxt->hasKeyrefs == 0) &&
21944
0
  (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21945
0
  vctxt->hasKeyrefs = 1;
21946
0
}
21947
21948
/**
21949
 * xmlSchemaAugmentImportedIDC:
21950
 * @imported: the imported schema
21951
 *
21952
 * Creates an augmented IDC definition for the imported schema.
21953
 */
21954
static void
21955
xmlSchemaAugmentImportedIDC(void *payload, void *data,
21956
0
                            const xmlChar *name ATTRIBUTE_UNUSED) {
21957
0
    xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
21958
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21959
0
    if (imported->schema->idcDef != NULL) {
21960
0
      xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
21961
0
    }
21962
0
}
21963
21964
/**
21965
 * xmlSchemaIDCNewBinding:
21966
 * @idcDef: the IDC definition of this binding
21967
 *
21968
 * Creates a new IDC binding.
21969
 *
21970
 * Returns the new IDC binding, NULL on internal errors.
21971
 */
21972
static xmlSchemaPSVIIDCBindingPtr
21973
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
21974
0
{
21975
0
    xmlSchemaPSVIIDCBindingPtr ret;
21976
21977
0
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
21978
0
      sizeof(xmlSchemaPSVIIDCBinding));
21979
0
    if (ret == NULL) {
21980
0
  xmlSchemaVErrMemory(NULL);
21981
0
  return (NULL);
21982
0
    }
21983
0
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
21984
0
    ret->definition = idcDef;
21985
0
    return (ret);
21986
0
}
21987
21988
/**
21989
 * xmlSchemaIDCStoreNodeTableItem:
21990
 * @vctxt: the WXS validation context
21991
 * @item: the IDC node table item
21992
 *
21993
 * The validation context is used to store IDC node table items.
21994
 * They are stored to avoid copying them if IDC node-tables are merged
21995
 * with corresponding parent IDC node-tables (bubbling).
21996
 *
21997
 * Returns 0 if succeeded, -1 on internal errors.
21998
 */
21999
static int
22000
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22001
             xmlSchemaPSVIIDCNodePtr item)
22002
0
{
22003
    /*
22004
    * Add to global list.
22005
    */
22006
0
    if (vctxt->idcNodes == NULL) {
22007
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22008
0
      xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22009
0
  if (vctxt->idcNodes == NULL) {
22010
0
      xmlSchemaVErrMemory(vctxt);
22011
0
      return (-1);
22012
0
  }
22013
0
  vctxt->sizeIdcNodes = 20;
22014
0
    } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22015
0
  vctxt->sizeIdcNodes *= 2;
22016
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22017
0
      xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22018
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
22019
0
  if (vctxt->idcNodes == NULL) {
22020
0
      xmlSchemaVErrMemory(vctxt);
22021
0
      return (-1);
22022
0
  }
22023
0
    }
22024
0
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22025
22026
0
    return (0);
22027
0
}
22028
22029
/**
22030
 * xmlSchemaIDCStoreKey:
22031
 * @vctxt: the WXS validation context
22032
 * @item: the IDC key
22033
 *
22034
 * The validation context is used to store an IDC key.
22035
 *
22036
 * Returns 0 if succeeded, -1 on internal errors.
22037
 */
22038
static int
22039
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22040
         xmlSchemaPSVIIDCKeyPtr key)
22041
0
{
22042
    /*
22043
    * Add to global list.
22044
    */
22045
0
    if (vctxt->idcKeys == NULL) {
22046
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22047
0
      xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22048
0
  if (vctxt->idcKeys == NULL) {
22049
0
      xmlSchemaVErrMemory(vctxt);
22050
0
      return (-1);
22051
0
  }
22052
0
  vctxt->sizeIdcKeys = 40;
22053
0
    } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22054
0
  vctxt->sizeIdcKeys *= 2;
22055
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22056
0
      xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22057
0
      sizeof(xmlSchemaPSVIIDCKeyPtr));
22058
0
  if (vctxt->idcKeys == NULL) {
22059
0
      xmlSchemaVErrMemory(vctxt);
22060
0
      return (-1);
22061
0
  }
22062
0
    }
22063
0
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22064
22065
0
    return (0);
22066
0
}
22067
22068
/**
22069
 * xmlSchemaIDCAppendNodeTableItem:
22070
 * @bind: the IDC binding
22071
 * @ntItem: the node-table item
22072
 *
22073
 * Appends the IDC node-table item to the binding.
22074
 *
22075
 * Returns 0 on success and -1 on internal errors.
22076
 */
22077
static int
22078
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22079
        xmlSchemaPSVIIDCNodePtr ntItem)
22080
0
{
22081
0
    if (bind->nodeTable == NULL) {
22082
0
  bind->sizeNodes = 10;
22083
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22084
0
      xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22085
0
  if (bind->nodeTable == NULL) {
22086
0
      xmlSchemaVErrMemory(NULL);
22087
0
      return(-1);
22088
0
  }
22089
0
    } else if (bind->sizeNodes <= bind->nbNodes) {
22090
0
  bind->sizeNodes *= 2;
22091
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22092
0
      xmlRealloc(bind->nodeTable, bind->sizeNodes *
22093
0
    sizeof(xmlSchemaPSVIIDCNodePtr));
22094
0
  if (bind->nodeTable == NULL) {
22095
0
      xmlSchemaVErrMemory(NULL);
22096
0
      return(-1);
22097
0
  }
22098
0
    }
22099
0
    bind->nodeTable[bind->nbNodes++] = ntItem;
22100
0
    return(0);
22101
0
}
22102
22103
/**
22104
 * xmlSchemaIDCAcquireBinding:
22105
 * @vctxt: the WXS validation context
22106
 * @matcher: the IDC matcher
22107
 *
22108
 * Looks up an PSVI IDC binding, for the IDC definition and
22109
 * of the given matcher. If none found, a new one is created
22110
 * and added to the IDC table.
22111
 *
22112
 * Returns an IDC binding or NULL on internal errors.
22113
 */
22114
static xmlSchemaPSVIIDCBindingPtr
22115
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22116
        xmlSchemaIDCMatcherPtr matcher)
22117
0
{
22118
0
    xmlSchemaNodeInfoPtr ielem;
22119
22120
0
    ielem = vctxt->elemInfos[matcher->depth];
22121
22122
0
    if (ielem->idcTable == NULL) {
22123
0
  ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22124
0
  if (ielem->idcTable == NULL)
22125
0
      return (NULL);
22126
0
  return(ielem->idcTable);
22127
0
    } else {
22128
0
  xmlSchemaPSVIIDCBindingPtr bind = NULL;
22129
22130
0
  bind = ielem->idcTable;
22131
0
  do {
22132
0
      if (bind->definition == matcher->aidc->def)
22133
0
    return(bind);
22134
0
      if (bind->next == NULL) {
22135
0
    bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22136
0
    if (bind->next == NULL)
22137
0
        return (NULL);
22138
0
    return(bind->next);
22139
0
      }
22140
0
      bind = bind->next;
22141
0
  } while (bind != NULL);
22142
0
    }
22143
0
    return (NULL);
22144
0
}
22145
22146
static xmlSchemaItemListPtr
22147
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22148
           xmlSchemaIDCMatcherPtr matcher)
22149
0
{
22150
0
    if (matcher->targets == NULL)
22151
0
  matcher->targets = xmlSchemaItemListCreate();
22152
0
    return(matcher->targets);
22153
0
}
22154
22155
/**
22156
 * xmlSchemaIDCFreeKey:
22157
 * @key: the IDC key
22158
 *
22159
 * Frees an IDC key together with its compiled value.
22160
 */
22161
static void
22162
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22163
0
{
22164
0
    if (key->val != NULL)
22165
0
  xmlSchemaFreeValue(key->val);
22166
0
    xmlFree(key);
22167
0
}
22168
22169
/**
22170
 * xmlSchemaIDCFreeBinding:
22171
 *
22172
 * Frees an IDC binding. Note that the node table-items
22173
 * are not freed.
22174
 */
22175
static void
22176
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22177
0
{
22178
0
    if (bind->nodeTable != NULL)
22179
0
  xmlFree(bind->nodeTable);
22180
0
    if (bind->dupls != NULL)
22181
0
  xmlSchemaItemListFree(bind->dupls);
22182
0
    xmlFree(bind);
22183
0
}
22184
22185
/**
22186
 * xmlSchemaIDCFreeIDCTable:
22187
 * @bind: the first IDC binding in the list
22188
 *
22189
 * Frees an IDC table, i.e. all the IDC bindings in the list.
22190
 */
22191
static void
22192
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22193
0
{
22194
0
    xmlSchemaPSVIIDCBindingPtr prev;
22195
22196
0
    while (bind != NULL) {
22197
0
  prev = bind;
22198
0
  bind = bind->next;
22199
0
  xmlSchemaIDCFreeBinding(prev);
22200
0
    }
22201
0
}
22202
22203
static void
22204
xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
22205
0
{
22206
0
    xmlIDCHashEntryPtr e = payload, n;
22207
0
    while (e) {
22208
0
  n = e->next;
22209
0
  xmlFree(e);
22210
0
  e = n;
22211
0
    }
22212
0
}
22213
22214
/**
22215
 * xmlSchemaIDCFreeMatcherList:
22216
 * @matcher: the first IDC matcher in the list
22217
 *
22218
 * Frees a list of IDC matchers.
22219
 */
22220
static void
22221
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22222
0
{
22223
0
    xmlSchemaIDCMatcherPtr next;
22224
22225
0
    while (matcher != NULL) {
22226
0
  next = matcher->next;
22227
0
  if (matcher->keySeqs != NULL) {
22228
0
      int i;
22229
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22230
0
    if (matcher->keySeqs[i] != NULL)
22231
0
        xmlFree(matcher->keySeqs[i]);
22232
0
      xmlFree(matcher->keySeqs);
22233
0
  }
22234
0
  if (matcher->targets != NULL) {
22235
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22236
0
    int i;
22237
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22238
    /*
22239
    * Node-table items for keyrefs are not stored globally
22240
    * to the validation context, since they are not bubbled.
22241
    * We need to free them here.
22242
    */
22243
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22244
0
        idcNode =
22245
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22246
0
        xmlFree(idcNode->keys);
22247
0
        xmlFree(idcNode);
22248
0
    }
22249
0
      }
22250
0
      xmlSchemaItemListFree(matcher->targets);
22251
0
  }
22252
0
  if (matcher->htab != NULL)
22253
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22254
0
  xmlFree(matcher);
22255
0
  matcher = next;
22256
0
    }
22257
0
}
22258
22259
/**
22260
 * xmlSchemaIDCReleaseMatcherList:
22261
 * @vctxt: the WXS validation context
22262
 * @matcher: the first IDC matcher in the list
22263
 *
22264
 * Caches a list of IDC matchers for reuse.
22265
 */
22266
static void
22267
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22268
             xmlSchemaIDCMatcherPtr matcher)
22269
0
{
22270
0
    xmlSchemaIDCMatcherPtr next;
22271
22272
0
    while (matcher != NULL) {
22273
0
  next = matcher->next;
22274
0
  if (matcher->keySeqs != NULL) {
22275
0
      int i;
22276
      /*
22277
      * Don't free the array, but only the content.
22278
      */
22279
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22280
0
    if (matcher->keySeqs[i] != NULL) {
22281
0
        xmlFree(matcher->keySeqs[i]);
22282
0
        matcher->keySeqs[i] = NULL;
22283
0
    }
22284
0
  }
22285
0
  if (matcher->targets) {
22286
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22287
0
    int i;
22288
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22289
    /*
22290
    * Node-table items for keyrefs are not stored globally
22291
    * to the validation context, since they are not bubbled.
22292
    * We need to free them here.
22293
    */
22294
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22295
0
        idcNode =
22296
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22297
0
        xmlFree(idcNode->keys);
22298
0
        xmlFree(idcNode);
22299
0
    }
22300
0
      }
22301
0
      xmlSchemaItemListFree(matcher->targets);
22302
0
      matcher->targets = NULL;
22303
0
  }
22304
0
  if (matcher->htab != NULL) {
22305
0
      xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22306
0
      matcher->htab = NULL;
22307
0
  }
22308
0
  matcher->next = NULL;
22309
  /*
22310
  * Cache the matcher.
22311
  */
22312
0
  if (vctxt->idcMatcherCache != NULL)
22313
0
      matcher->nextCached = vctxt->idcMatcherCache;
22314
0
  vctxt->idcMatcherCache = matcher;
22315
22316
0
  matcher = next;
22317
0
    }
22318
0
}
22319
22320
/**
22321
 * xmlSchemaIDCAddStateObject:
22322
 * @vctxt: the WXS validation context
22323
 * @matcher: the IDC matcher
22324
 * @sel: the XPath information
22325
 * @parent: the parent "selector" state object if any
22326
 * @type: "selector" or "field"
22327
 *
22328
 * Creates/reuses and activates state objects for the given
22329
 * XPath information; if the XPath expression consists of unions,
22330
 * multiple state objects are created for every unioned expression.
22331
 *
22332
 * Returns 0 on success and -1 on internal errors.
22333
 */
22334
static int
22335
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22336
      xmlSchemaIDCMatcherPtr matcher,
22337
      xmlSchemaIDCSelectPtr sel,
22338
      int type)
22339
0
{
22340
0
    xmlSchemaIDCStateObjPtr sto;
22341
22342
    /*
22343
    * Reuse the state objects from the pool.
22344
    */
22345
0
    if (vctxt->xpathStatePool != NULL) {
22346
0
  sto = vctxt->xpathStatePool;
22347
0
  vctxt->xpathStatePool = sto->next;
22348
0
  sto->next = NULL;
22349
0
    } else {
22350
  /*
22351
  * Create a new state object.
22352
  */
22353
0
  sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22354
0
  if (sto == NULL) {
22355
0
      xmlSchemaVErrMemory(NULL);
22356
0
      return (-1);
22357
0
  }
22358
0
  memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22359
0
    }
22360
    /*
22361
    * Add to global list.
22362
    */
22363
0
    if (vctxt->xpathStates != NULL)
22364
0
  sto->next = vctxt->xpathStates;
22365
0
    vctxt->xpathStates = sto;
22366
22367
    /*
22368
    * Free the old xpath validation context.
22369
    */
22370
0
    if (sto->xpathCtxt != NULL)
22371
0
  xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22372
22373
    /*
22374
    * Create a new XPath (pattern) validation context.
22375
    */
22376
0
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22377
0
  (xmlPatternPtr) sel->xpathComp);
22378
0
    if (sto->xpathCtxt == NULL) {
22379
0
  VERROR_INT("xmlSchemaIDCAddStateObject",
22380
0
      "failed to create an XPath validation context");
22381
0
  return (-1);
22382
0
    }
22383
0
    sto->type = type;
22384
0
    sto->depth = vctxt->depth;
22385
0
    sto->matcher = matcher;
22386
0
    sto->sel = sel;
22387
0
    sto->nbHistory = 0;
22388
22389
0
    return (0);
22390
0
}
22391
22392
/**
22393
 * xmlSchemaXPathEvaluate:
22394
 * @vctxt: the WXS validation context
22395
 * @nodeType: the nodeType of the current node
22396
 *
22397
 * Evaluates all active XPath state objects.
22398
 *
22399
 * Returns the number of IC "field" state objects which resolved to
22400
 * this node, 0 if none resolved and -1 on internal errors.
22401
 */
22402
static int
22403
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22404
           xmlElementType nodeType)
22405
0
{
22406
0
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22407
0
    int res, resolved = 0, depth = vctxt->depth;
22408
22409
0
    if (vctxt->xpathStates == NULL)
22410
0
  return (0);
22411
22412
0
    if (nodeType == XML_ATTRIBUTE_NODE)
22413
0
  depth++;
22414
    /*
22415
    * Process all active XPath state objects.
22416
    */
22417
0
    first = vctxt->xpathStates;
22418
0
    sto = first;
22419
0
    while (sto != head) {
22420
0
  if (nodeType == XML_ELEMENT_NODE)
22421
0
      res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22422
0
    vctxt->inode->localName, vctxt->inode->nsName);
22423
0
  else
22424
0
      res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22425
0
    vctxt->inode->localName, vctxt->inode->nsName);
22426
22427
0
  if (res == -1) {
22428
0
      VERROR_INT("xmlSchemaXPathEvaluate",
22429
0
    "calling xmlStreamPush()");
22430
0
      return (-1);
22431
0
  }
22432
0
  if (res == 0)
22433
0
      goto next_sto;
22434
  /*
22435
  * Full match.
22436
  */
22437
  /*
22438
  * Register a match in the state object history.
22439
  */
22440
0
  if (sto->history == NULL) {
22441
0
      sto->history = (int *) xmlMalloc(5 * sizeof(int));
22442
0
      if (sto->history == NULL) {
22443
0
    xmlSchemaVErrMemory(NULL);
22444
0
    return(-1);
22445
0
      }
22446
0
      sto->sizeHistory = 5;
22447
0
  } else if (sto->sizeHistory <= sto->nbHistory) {
22448
0
      sto->sizeHistory *= 2;
22449
0
      sto->history = (int *) xmlRealloc(sto->history,
22450
0
    sto->sizeHistory * sizeof(int));
22451
0
      if (sto->history == NULL) {
22452
0
    xmlSchemaVErrMemory(NULL);
22453
0
    return(-1);
22454
0
      }
22455
0
  }
22456
0
  sto->history[sto->nbHistory++] = depth;
22457
22458
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22459
0
      xmlSchemaIDCSelectPtr sel;
22460
      /*
22461
      * Activate state objects for the IDC fields of
22462
      * the IDC selector.
22463
      */
22464
0
      sel = sto->matcher->aidc->def->fields;
22465
0
      while (sel != NULL) {
22466
0
    if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22467
0
        sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22468
0
        return (-1);
22469
0
    sel = sel->next;
22470
0
      }
22471
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22472
      /*
22473
      * An IDC key node was found by the IDC field.
22474
      */
22475
      /*
22476
      * Notify that the character value of this node is
22477
      * needed.
22478
      */
22479
0
      if (resolved == 0) {
22480
0
    if ((vctxt->inode->flags &
22481
0
        XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22482
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22483
0
      }
22484
0
      resolved++;
22485
0
  }
22486
0
next_sto:
22487
0
  if (sto->next == NULL) {
22488
      /*
22489
      * Evaluate field state objects created on this node as well.
22490
      */
22491
0
      head = first;
22492
0
      sto = vctxt->xpathStates;
22493
0
  } else
22494
0
      sto = sto->next;
22495
0
    }
22496
0
    return (resolved);
22497
0
}
22498
22499
static const xmlChar *
22500
xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22501
        xmlChar **buf,
22502
        xmlSchemaPSVIIDCKeyPtr *seq,
22503
        int count, int for_hash)
22504
0
{
22505
0
    int i, res;
22506
0
    xmlChar *value = NULL;
22507
22508
0
    *buf = xmlStrdup(BAD_CAST "[");
22509
0
    for (i = 0; i < count; i++) {
22510
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
22511
0
  if (!for_hash)
22512
0
      res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22513
0
        xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22514
0
        &value);
22515
0
  else {
22516
0
      res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22517
0
  }
22518
0
  if (res == 0)
22519
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
22520
0
  else {
22521
0
      VERROR_INT("xmlSchemaFormatIDCKeySequence",
22522
0
    "failed to compute a canonical value");
22523
0
      *buf = xmlStrcat(*buf, BAD_CAST "???");
22524
0
  }
22525
0
  if (i < count -1)
22526
0
      *buf = xmlStrcat(*buf, BAD_CAST "', ");
22527
0
  else
22528
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
22529
0
  if (value != NULL) {
22530
0
      xmlFree(value);
22531
0
      value = NULL;
22532
0
  }
22533
0
    }
22534
0
    *buf = xmlStrcat(*buf, BAD_CAST "]");
22535
22536
0
    return (BAD_CAST *buf);
22537
0
}
22538
22539
static const xmlChar *
22540
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22541
            xmlChar **buf,
22542
            xmlSchemaPSVIIDCKeyPtr *seq,
22543
            int count)
22544
0
{
22545
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22546
0
}
22547
22548
static const xmlChar *
22549
xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22550
       xmlChar **buf,
22551
       xmlSchemaPSVIIDCKeyPtr *seq,
22552
       int count)
22553
0
{
22554
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22555
0
}
22556
22557
/**
22558
 * xmlSchemaXPathPop:
22559
 * @vctxt: the WXS validation context
22560
 *
22561
 * Pops all XPath states.
22562
 *
22563
 * Returns 0 on success and -1 on internal errors.
22564
 */
22565
static int
22566
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22567
0
{
22568
0
    xmlSchemaIDCStateObjPtr sto;
22569
0
    int res;
22570
22571
0
    if (vctxt->xpathStates == NULL)
22572
0
  return(0);
22573
0
    sto = vctxt->xpathStates;
22574
0
    do {
22575
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22576
0
  if (res == -1)
22577
0
      return (-1);
22578
0
  sto = sto->next;
22579
0
    } while (sto != NULL);
22580
0
    return(0);
22581
0
}
22582
22583
/**
22584
 * xmlSchemaXPathProcessHistory:
22585
 * @vctxt: the WXS validation context
22586
 * @type: the simple/complex type of the current node if any at all
22587
 * @val: the precompiled value
22588
 *
22589
 * Processes and pops the history items of the IDC state objects.
22590
 * IDC key-sequences are validated/created on IDC bindings.
22591
 *
22592
 * Returns 0 on success and -1 on internal errors.
22593
 */
22594
static int
22595
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22596
           int depth)
22597
0
{
22598
0
    xmlSchemaIDCStateObjPtr sto, nextsto;
22599
0
    int res, matchDepth;
22600
0
    xmlSchemaPSVIIDCKeyPtr key = NULL;
22601
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22602
22603
0
    if (vctxt->xpathStates == NULL)
22604
0
  return (0);
22605
0
    sto = vctxt->xpathStates;
22606
22607
    /*
22608
    * Evaluate the state objects.
22609
    */
22610
0
    while (sto != NULL) {
22611
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22612
0
  if (res == -1) {
22613
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22614
0
    "calling xmlStreamPop()");
22615
0
      return (-1);
22616
0
  }
22617
0
  if (sto->nbHistory == 0)
22618
0
      goto deregister_check;
22619
22620
0
  matchDepth = sto->history[sto->nbHistory -1];
22621
22622
  /*
22623
  * Only matches at the current depth are of interest.
22624
  */
22625
0
  if (matchDepth != depth) {
22626
0
      sto = sto->next;
22627
0
      continue;
22628
0
  }
22629
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22630
      /*
22631
      * NOTE: According to
22632
      *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22633
      *   ... the simple-content of complex types is also allowed.
22634
      */
22635
22636
0
      if (WXS_IS_COMPLEX(type)) {
22637
0
    if (WXS_HAS_SIMPLE_CONTENT(type)) {
22638
        /*
22639
        * Sanity check for complex types with simple content.
22640
        */
22641
0
        simpleType = type->contentTypeDef;
22642
0
        if (simpleType == NULL) {
22643
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22644
0
          "field resolves to a CT with simple content "
22645
0
          "but the CT is missing the ST definition");
22646
0
      return (-1);
22647
0
        }
22648
0
    } else
22649
0
        simpleType = NULL;
22650
0
      } else
22651
0
    simpleType = type;
22652
0
      if (simpleType == NULL) {
22653
0
    xmlChar *str = NULL;
22654
22655
    /*
22656
    * Not qualified if the field resolves to a node of non
22657
    * simple type.
22658
    */
22659
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22660
0
        XML_SCHEMAV_CVC_IDC, NULL,
22661
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22662
0
        "The XPath '%s' of a field of %s does evaluate to a node of "
22663
0
        "non-simple type",
22664
0
        sto->sel->xpath,
22665
0
        xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22666
0
    FREE_AND_NULL(str);
22667
0
    sto->nbHistory--;
22668
0
    goto deregister_check;
22669
0
      }
22670
22671
0
      if ((key == NULL) && (vctxt->inode->val == NULL)) {
22672
    /*
22673
    * Failed to provide the normalized value; maybe
22674
    * the value was invalid.
22675
    */
22676
0
    VERROR(XML_SCHEMAV_CVC_IDC,
22677
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22678
0
        "Warning: No precomputed value available, the value "
22679
0
        "was either invalid or something strange happened");
22680
0
    sto->nbHistory--;
22681
0
    goto deregister_check;
22682
0
      } else {
22683
0
    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22684
0
    xmlSchemaPSVIIDCKeyPtr *keySeq;
22685
0
    int pos, idx;
22686
22687
    /*
22688
    * The key will be anchored on the matcher's list of
22689
    * key-sequences. The position in this list is determined
22690
    * by the target node's depth relative to the matcher's
22691
    * depth of creation (i.e. the depth of the scope element).
22692
    *
22693
    * Element        Depth    Pos   List-entries
22694
    * <scope>          0              NULL
22695
    *   <bar>          1              NULL
22696
    *     <target/>    2       2      target
22697
    *   <bar>
22698
                * </scope>
22699
    *
22700
    * The size of the list is only dependent on the depth of
22701
    * the tree.
22702
    * An entry will be NULLed in selector_leave, i.e. when
22703
    * we hit the target's
22704
    */
22705
0
    pos = sto->depth - matcher->depth;
22706
0
    idx = sto->sel->index;
22707
22708
    /*
22709
    * Create/grow the array of key-sequences.
22710
    */
22711
0
    if (matcher->keySeqs == NULL) {
22712
0
        if (pos > 9)
22713
0
      matcher->sizeKeySeqs = pos * 2;
22714
0
        else
22715
0
      matcher->sizeKeySeqs = 10;
22716
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22717
0
      xmlMalloc(matcher->sizeKeySeqs *
22718
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22719
0
        if (matcher->keySeqs == NULL) {
22720
0
      xmlSchemaVErrMemory(NULL);
22721
0
      return(-1);
22722
0
        }
22723
0
        memset(matcher->keySeqs, 0,
22724
0
      matcher->sizeKeySeqs *
22725
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22726
0
    } else if (pos >= matcher->sizeKeySeqs) {
22727
0
        int i = matcher->sizeKeySeqs;
22728
22729
0
        matcher->sizeKeySeqs = pos * 2;
22730
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22731
0
      xmlRealloc(matcher->keySeqs,
22732
0
      matcher->sizeKeySeqs *
22733
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22734
0
        if (matcher->keySeqs == NULL) {
22735
0
      xmlSchemaVErrMemory(NULL);
22736
0
      return (-1);
22737
0
        }
22738
        /*
22739
        * The array needs to be NULLed.
22740
        * TODO: Use memset?
22741
        */
22742
0
        for (; i < matcher->sizeKeySeqs; i++)
22743
0
      matcher->keySeqs[i] = NULL;
22744
0
    }
22745
22746
    /*
22747
    * Get/create the key-sequence.
22748
    */
22749
0
    keySeq = matcher->keySeqs[pos];
22750
0
    if (keySeq == NULL) {
22751
0
        goto create_sequence;
22752
0
    } else if (keySeq[idx] != NULL) {
22753
0
        xmlChar *str = NULL;
22754
        /*
22755
        * cvc-identity-constraint:
22756
        * 3 For each node in the `target node set` all
22757
        * of the {fields}, with that node as the context
22758
        * node, evaluate to either an empty node-set or
22759
        * a node-set with exactly one member, which must
22760
        * have a simple type.
22761
        *
22762
        * The key was already set; report an error.
22763
        */
22764
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22765
0
      XML_SCHEMAV_CVC_IDC, NULL,
22766
0
      WXS_BASIC_CAST matcher->aidc->def,
22767
0
      "The XPath '%s' of a field of %s evaluates to a "
22768
0
      "node-set with more than one member",
22769
0
      sto->sel->xpath,
22770
0
      xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22771
0
        FREE_AND_NULL(str);
22772
0
        sto->nbHistory--;
22773
0
        goto deregister_check;
22774
0
    } else
22775
0
        goto create_key;
22776
22777
0
create_sequence:
22778
    /*
22779
    * Create a key-sequence.
22780
    */
22781
0
    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22782
0
        matcher->aidc->def->nbFields *
22783
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22784
0
    if (keySeq == NULL) {
22785
0
        xmlSchemaVErrMemory(NULL);
22786
0
        return(-1);
22787
0
    }
22788
0
    memset(keySeq, 0, matcher->aidc->def->nbFields *
22789
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22790
0
    matcher->keySeqs[pos] = keySeq;
22791
0
create_key:
22792
    /*
22793
    * Create a key once per node only.
22794
    */
22795
0
    if (key == NULL) {
22796
0
        key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22797
0
      sizeof(xmlSchemaPSVIIDCKey));
22798
0
        if (key == NULL) {
22799
0
      xmlSchemaVErrMemory(NULL);
22800
0
      xmlFree(keySeq);
22801
0
      matcher->keySeqs[pos] = NULL;
22802
0
      return(-1);
22803
0
        }
22804
        /*
22805
        * Consume the compiled value.
22806
        */
22807
0
        key->type = simpleType;
22808
0
        key->val = vctxt->inode->val;
22809
0
        vctxt->inode->val = NULL;
22810
        /*
22811
        * Store the key in a global list.
22812
        */
22813
0
        if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22814
0
      xmlSchemaIDCFreeKey(key);
22815
0
      return (-1);
22816
0
        }
22817
0
    }
22818
0
    keySeq[idx] = key;
22819
0
      }
22820
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22821
22822
0
      xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22823
      /* xmlSchemaPSVIIDCBindingPtr bind; */
22824
0
      xmlSchemaPSVIIDCNodePtr ntItem;
22825
0
      xmlSchemaIDCMatcherPtr matcher;
22826
0
      xmlSchemaIDCPtr idc;
22827
0
      xmlSchemaItemListPtr targets;
22828
0
      int pos, i, j, nbKeys;
22829
      /*
22830
      * Here we have the following scenario:
22831
      * An IDC 'selector' state object resolved to a target node,
22832
      * during the time this target node was in the
22833
      * ancestor-or-self axis, the 'field' state object(s) looked
22834
      * out for matching nodes to create a key-sequence for this
22835
      * target node. Now we are back to this target node and need
22836
      * to put the key-sequence, together with the target node
22837
      * itself, into the node-table of the corresponding IDC
22838
      * binding.
22839
      */
22840
0
      matcher = sto->matcher;
22841
0
      idc = matcher->aidc->def;
22842
0
      nbKeys = idc->nbFields;
22843
0
      pos = depth - matcher->depth;
22844
      /*
22845
      * Check if the matcher has any key-sequences at all, plus
22846
      * if it has a key-sequence for the current target node.
22847
      */
22848
0
      if ((matcher->keySeqs == NULL) ||
22849
0
    (matcher->sizeKeySeqs <= pos)) {
22850
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22851
0
        goto selector_key_error;
22852
0
    else
22853
0
        goto selector_leave;
22854
0
      }
22855
22856
0
      keySeq = &(matcher->keySeqs[pos]);
22857
0
      if (*keySeq == NULL) {
22858
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22859
0
        goto selector_key_error;
22860
0
    else
22861
0
        goto selector_leave;
22862
0
      }
22863
22864
0
      for (i = 0; i < nbKeys; i++) {
22865
0
    if ((*keySeq)[i] == NULL) {
22866
        /*
22867
        * Not qualified, if not all fields did resolve.
22868
        */
22869
0
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22870
      /*
22871
      * All fields of a "key" IDC must resolve.
22872
      */
22873
0
      goto selector_key_error;
22874
0
        }
22875
0
        goto selector_leave;
22876
0
    }
22877
0
      }
22878
      /*
22879
      * All fields did resolve.
22880
      */
22881
22882
      /*
22883
      * 4.1 If the {identity-constraint category} is unique(/key),
22884
      * then no two members of the `qualified node set` have
22885
      * `key-sequences` whose members are pairwise equal, as
22886
      * defined by Equal in [XML Schemas: Datatypes].
22887
      *
22888
      * Get the IDC binding from the matcher and check for
22889
      * duplicate key-sequences.
22890
      */
22891
#if 0
22892
      bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22893
#endif
22894
0
      targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22895
0
      if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22896
0
    (targets->nbItems != 0)) {
22897
0
    xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22898
0
    xmlIDCHashEntryPtr e;
22899
22900
0
    res = 0;
22901
22902
0
    if (!matcher->htab)
22903
0
        e = NULL;
22904
0
    else {
22905
0
        xmlChar *value = NULL;
22906
0
        xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
22907
0
        e = xmlHashLookup(matcher->htab, value);
22908
0
        FREE_AND_NULL(value);
22909
0
    }
22910
22911
    /*
22912
    * Compare the key-sequences, key by key.
22913
    */
22914
0
    for (;e; e = e->next) {
22915
0
        bkeySeq =
22916
0
      ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
22917
0
        for (j = 0; j < nbKeys; j++) {
22918
0
      ckey = (*keySeq)[j];
22919
0
      bkey = bkeySeq[j];
22920
0
      res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22921
0
      if (res == -1) {
22922
0
          return (-1);
22923
0
      } else if (res == 0) {
22924
          /*
22925
          * One of the keys differs, so the key-sequence
22926
          * won't be equal; get out.
22927
          */
22928
0
          break;
22929
0
      }
22930
0
        }
22931
0
        if (res == 1) {
22932
      /*
22933
      * Duplicate key-sequence found.
22934
      */
22935
0
      break;
22936
0
        }
22937
0
    }
22938
0
    if (e) {
22939
0
        xmlChar *str = NULL, *strB = NULL;
22940
        /*
22941
        * TODO: Try to report the key-sequence.
22942
        */
22943
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22944
0
      XML_SCHEMAV_CVC_IDC, NULL,
22945
0
      WXS_BASIC_CAST idc,
22946
0
      "Duplicate key-sequence %s in %s",
22947
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
22948
0
          (*keySeq), nbKeys),
22949
0
      xmlSchemaGetIDCDesignation(&strB, idc));
22950
0
        FREE_AND_NULL(str);
22951
0
        FREE_AND_NULL(strB);
22952
0
        goto selector_leave;
22953
0
    }
22954
0
      }
22955
      /*
22956
      * Add a node-table item to the IDC binding.
22957
      */
22958
0
      ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
22959
0
    sizeof(xmlSchemaPSVIIDCNode));
22960
0
      if (ntItem == NULL) {
22961
0
    xmlSchemaVErrMemory(NULL);
22962
0
    xmlFree(*keySeq);
22963
0
    *keySeq = NULL;
22964
0
    return(-1);
22965
0
      }
22966
0
      memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
22967
22968
      /*
22969
      * Store the node-table item in a global list.
22970
      */
22971
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22972
0
    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
22973
0
        xmlFree(ntItem);
22974
0
        xmlFree(*keySeq);
22975
0
        *keySeq = NULL;
22976
0
        return (-1);
22977
0
    }
22978
0
    ntItem->nodeQNameID = -1;
22979
0
      } else {
22980
    /*
22981
    * Save a cached QName for this node on the IDC node, to be
22982
    * able to report it, even if the node is not saved.
22983
    */
22984
0
    ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
22985
0
        vctxt->inode->localName, vctxt->inode->nsName);
22986
0
    if (ntItem->nodeQNameID == -1) {
22987
0
        xmlFree(ntItem);
22988
0
        xmlFree(*keySeq);
22989
0
        *keySeq = NULL;
22990
0
        return (-1);
22991
0
    }
22992
0
      }
22993
      /*
22994
      * Init the node-table item: Save the node, position and
22995
      * consume the key-sequence.
22996
      */
22997
0
      ntItem->node = vctxt->node;
22998
0
      ntItem->nodeLine = vctxt->inode->nodeLine;
22999
0
      ntItem->keys = *keySeq;
23000
0
      *keySeq = NULL;
23001
#if 0
23002
      if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23003
#endif
23004
0
      if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23005
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23006
        /*
23007
        * Free the item, since keyref items won't be
23008
        * put on a global list.
23009
        */
23010
0
        xmlFree(ntItem->keys);
23011
0
        xmlFree(ntItem);
23012
0
    }
23013
0
    return (-1);
23014
0
      }
23015
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23016
0
    xmlChar *value = NULL;
23017
0
    xmlIDCHashEntryPtr r, e;
23018
0
    if (!matcher->htab)
23019
0
      matcher->htab = xmlHashCreate(4);
23020
0
    xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23021
0
    e = xmlMalloc(sizeof *e);
23022
0
    e->index = targets->nbItems - 1;
23023
0
    r = xmlHashLookup(matcher->htab, value);
23024
0
    if (r) {
23025
0
        e->next = r->next;
23026
0
        r->next = e;
23027
0
    } else {
23028
0
        e->next = NULL;
23029
0
        xmlHashAddEntry(matcher->htab, value, e);
23030
0
    }
23031
0
    FREE_AND_NULL(value);
23032
0
      }
23033
23034
0
      goto selector_leave;
23035
0
selector_key_error:
23036
0
      {
23037
0
    xmlChar *str = NULL;
23038
    /*
23039
    * 4.2.1 (KEY) The `target node set` and the
23040
    * `qualified node set` are equal, that is, every
23041
    * member of the `target node set` is also a member
23042
    * of the `qualified node set` and vice versa.
23043
    */
23044
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
23045
0
        XML_SCHEMAV_CVC_IDC, NULL,
23046
0
        WXS_BASIC_CAST idc,
23047
0
        "Not all fields of %s evaluate to a node",
23048
0
        xmlSchemaGetIDCDesignation(&str, idc), NULL);
23049
0
    FREE_AND_NULL(str);
23050
0
      }
23051
0
selector_leave:
23052
      /*
23053
      * Free the key-sequence if not added to the IDC table.
23054
      */
23055
0
      if ((keySeq != NULL) && (*keySeq != NULL)) {
23056
0
    xmlFree(*keySeq);
23057
0
    *keySeq = NULL;
23058
0
      }
23059
0
  } /* if selector */
23060
23061
0
  sto->nbHistory--;
23062
23063
0
deregister_check:
23064
  /*
23065
  * Deregister state objects if they reach the depth of creation.
23066
  */
23067
0
  if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23068
0
      if (vctxt->xpathStates != sto) {
23069
0
    VERROR_INT("xmlSchemaXPathProcessHistory",
23070
0
        "The state object to be removed is not the first "
23071
0
        "in the list");
23072
0
      }
23073
0
      nextsto = sto->next;
23074
      /*
23075
      * Unlink from the list of active XPath state objects.
23076
      */
23077
0
      vctxt->xpathStates = sto->next;
23078
0
      sto->next = vctxt->xpathStatePool;
23079
      /*
23080
      * Link it to the pool of reusable state objects.
23081
      */
23082
0
      vctxt->xpathStatePool = sto;
23083
0
      sto = nextsto;
23084
0
  } else
23085
0
      sto = sto->next;
23086
0
    } /* while (sto != NULL) */
23087
0
    return (0);
23088
0
}
23089
23090
/**
23091
 * xmlSchemaIDCRegisterMatchers:
23092
 * @vctxt: the WXS validation context
23093
 * @elemDecl: the element declaration
23094
 *
23095
 * Creates helper objects to evaluate IDC selectors/fields
23096
 * successively.
23097
 *
23098
 * Returns 0 if OK and -1 on internal errors.
23099
 */
23100
static int
23101
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23102
           xmlSchemaElementPtr elemDecl)
23103
0
{
23104
0
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
23105
0
    xmlSchemaIDCPtr idc, refIdc;
23106
0
    xmlSchemaIDCAugPtr aidc;
23107
23108
0
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23109
0
    if (idc == NULL)
23110
0
  return (0);
23111
23112
0
    if (vctxt->inode->idcMatchers != NULL) {
23113
0
  VERROR_INT("xmlSchemaIDCRegisterMatchers",
23114
0
      "The chain of IDC matchers is expected to be empty");
23115
0
  return (-1);
23116
0
    }
23117
0
    do {
23118
0
  if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23119
      /*
23120
      * Since IDCs bubbles are expensive we need to know the
23121
      * depth at which the bubbles should stop; this will be
23122
      * the depth of the top-most keyref IDC. If no keyref
23123
      * references a key/unique IDC, the keyrefDepth will
23124
      * be -1, indicating that no bubbles are needed.
23125
      */
23126
0
      refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23127
0
      if (refIdc != NULL) {
23128
    /*
23129
    * Remember that we have keyrefs on this node.
23130
    */
23131
0
    vctxt->inode->hasKeyrefs = 1;
23132
    /*
23133
    * Lookup the referenced augmented IDC info.
23134
    */
23135
0
    aidc = vctxt->aidcs;
23136
0
    while (aidc != NULL) {
23137
0
        if (aidc->def == refIdc)
23138
0
      break;
23139
0
        aidc = aidc->next;
23140
0
    }
23141
0
    if (aidc == NULL) {
23142
0
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
23143
0
      "Could not find an augmented IDC item for an IDC "
23144
0
      "definition");
23145
0
        return (-1);
23146
0
    }
23147
0
    if ((aidc->keyrefDepth == -1) ||
23148
0
        (vctxt->depth < aidc->keyrefDepth))
23149
0
        aidc->keyrefDepth = vctxt->depth;
23150
0
      }
23151
0
  }
23152
  /*
23153
  * Lookup the augmented IDC item for the IDC definition.
23154
  */
23155
0
  aidc = vctxt->aidcs;
23156
0
  while (aidc != NULL) {
23157
0
      if (aidc->def == idc)
23158
0
    break;
23159
0
      aidc = aidc->next;
23160
0
  }
23161
0
  if (aidc == NULL) {
23162
0
      VERROR_INT("xmlSchemaIDCRegisterMatchers",
23163
0
    "Could not find an augmented IDC item for an IDC definition");
23164
0
      return (-1);
23165
0
  }
23166
  /*
23167
  * Create an IDC matcher for every IDC definition.
23168
  */
23169
0
  if (vctxt->idcMatcherCache != NULL) {
23170
      /*
23171
      * Reuse a cached matcher.
23172
      */
23173
0
      matcher = vctxt->idcMatcherCache;
23174
0
      vctxt->idcMatcherCache = matcher->nextCached;
23175
0
      matcher->nextCached = NULL;
23176
0
  } else {
23177
0
      matcher = (xmlSchemaIDCMatcherPtr)
23178
0
    xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23179
0
      if (matcher == NULL) {
23180
0
    xmlSchemaVErrMemory(vctxt);
23181
0
    return (-1);
23182
0
      }
23183
0
      memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23184
0
  }
23185
0
  if (last == NULL)
23186
0
      vctxt->inode->idcMatchers = matcher;
23187
0
  else
23188
0
      last->next = matcher;
23189
0
  last = matcher;
23190
23191
0
  matcher->type = IDC_MATCHER;
23192
0
  matcher->depth = vctxt->depth;
23193
0
  matcher->aidc = aidc;
23194
0
  matcher->idcType = aidc->def->type;
23195
  /*
23196
  * Init the automaton state object.
23197
  */
23198
0
  if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23199
0
      idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23200
0
      return (-1);
23201
23202
0
  idc = idc->next;
23203
0
    } while (idc != NULL);
23204
0
    return (0);
23205
0
}
23206
23207
static int
23208
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23209
         xmlSchemaNodeInfoPtr ielem)
23210
0
{
23211
0
    xmlSchemaPSVIIDCBindingPtr bind;
23212
0
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23213
0
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23214
0
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23215
23216
0
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23217
    /* vctxt->createIDCNodeTables */
23218
0
    while (matcher != NULL) {
23219
  /*
23220
  * Skip keyref IDCs and empty IDC target-lists.
23221
  */
23222
0
  if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23223
0
      WXS_ILIST_IS_EMPTY(matcher->targets))
23224
0
  {
23225
0
      matcher = matcher->next;
23226
0
      continue;
23227
0
  }
23228
  /*
23229
  * If we _want_ the IDC node-table to be created in any case
23230
  * then do so. Otherwise create them only if keyrefs need them.
23231
  */
23232
0
  if ((! vctxt->createIDCNodeTables) &&
23233
0
      ((matcher->aidc->keyrefDepth == -1) ||
23234
0
       (matcher->aidc->keyrefDepth > vctxt->depth)))
23235
0
  {
23236
0
      matcher = matcher->next;
23237
0
      continue;
23238
0
  }
23239
  /*
23240
  * Get/create the IDC binding on this element for the IDC definition.
23241
  */
23242
0
  bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23243
0
  if (bind == NULL)
23244
0
     goto internal_error;
23245
23246
0
  if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23247
0
      dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23248
0
      nbDupls = bind->dupls->nbItems;
23249
0
  } else {
23250
0
      dupls = NULL;
23251
0
      nbDupls = 0;
23252
0
  }
23253
0
  if (bind->nodeTable != NULL) {
23254
0
      nbNodeTable = bind->nbNodes;
23255
0
  } else {
23256
0
      nbNodeTable = 0;
23257
0
  }
23258
23259
0
  if ((nbNodeTable == 0) && (nbDupls == 0)) {
23260
      /*
23261
      * Transfer all IDC target-nodes to the IDC node-table.
23262
      */
23263
0
      bind->nodeTable =
23264
0
    (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23265
0
      bind->sizeNodes = matcher->targets->sizeItems;
23266
0
      bind->nbNodes = matcher->targets->nbItems;
23267
23268
0
      matcher->targets->items = NULL;
23269
0
      matcher->targets->sizeItems = 0;
23270
0
      matcher->targets->nbItems = 0;
23271
0
      if (matcher->htab) {
23272
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23273
0
    matcher->htab = NULL;
23274
0
      }
23275
0
  } else {
23276
      /*
23277
      * Compare the key-sequences and add to the IDC node-table.
23278
      */
23279
0
      nbTargets = matcher->targets->nbItems;
23280
0
      targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23281
0
      nbFields = matcher->aidc->def->nbFields;
23282
0
      i = 0;
23283
0
      do {
23284
0
    keys = targets[i]->keys;
23285
0
    if (nbDupls) {
23286
        /*
23287
        * Search in already found duplicates first.
23288
        */
23289
0
        j = 0;
23290
0
        do {
23291
0
      if (nbFields == 1) {
23292
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23293
0
        dupls[j]->keys[0]->val);
23294
0
          if (res == -1)
23295
0
        goto internal_error;
23296
0
          if (res == 1) {
23297
        /*
23298
        * Equal key-sequence.
23299
        */
23300
0
        goto next_target;
23301
0
          }
23302
0
      } else {
23303
0
          res = 0;
23304
0
          ntkeys = dupls[j]->keys;
23305
0
          for (k = 0; k < nbFields; k++) {
23306
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23307
0
            ntkeys[k]->val);
23308
0
        if (res == -1)
23309
0
            goto internal_error;
23310
0
        if (res == 0) {
23311
            /*
23312
            * One of the keys differs.
23313
            */
23314
0
            break;
23315
0
        }
23316
0
          }
23317
0
          if (res == 1) {
23318
        /*
23319
        * Equal key-sequence found.
23320
        */
23321
0
        goto next_target;
23322
0
          }
23323
0
      }
23324
0
      j++;
23325
0
        } while (j < nbDupls);
23326
0
    }
23327
0
    if (nbNodeTable) {
23328
0
        j = 0;
23329
0
        do {
23330
0
      if (nbFields == 1) {
23331
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23332
0
        bind->nodeTable[j]->keys[0]->val);
23333
0
          if (res == -1)
23334
0
        goto internal_error;
23335
0
          if (res == 0) {
23336
        /*
23337
        * The key-sequence differs.
23338
        */
23339
0
        goto next_node_table_entry;
23340
0
          }
23341
0
      } else {
23342
0
          res = 0;
23343
0
          ntkeys = bind->nodeTable[j]->keys;
23344
0
          for (k = 0; k < nbFields; k++) {
23345
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23346
0
            ntkeys[k]->val);
23347
0
        if (res == -1)
23348
0
            goto internal_error;
23349
0
        if (res == 0) {
23350
            /*
23351
            * One of the keys differs.
23352
            */
23353
0
            goto next_node_table_entry;
23354
0
        }
23355
0
          }
23356
0
      }
23357
      /*
23358
      * Add the duplicate to the list of duplicates.
23359
      */
23360
0
      if (bind->dupls == NULL) {
23361
0
          bind->dupls = xmlSchemaItemListCreate();
23362
0
          if (bind->dupls == NULL)
23363
0
        goto internal_error;
23364
0
      }
23365
0
      if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23366
0
          goto internal_error;
23367
      /*
23368
      * Remove the duplicate entry from the IDC node-table.
23369
      */
23370
0
      bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23371
0
      bind->nbNodes--;
23372
23373
0
      goto next_target;
23374
23375
0
next_node_table_entry:
23376
0
      j++;
23377
0
        } while (j < nbNodeTable);
23378
0
    }
23379
    /*
23380
    * If everything is fine, then add the IDC target-node to
23381
    * the IDC node-table.
23382
    */
23383
0
    if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23384
0
        goto internal_error;
23385
23386
0
next_target:
23387
0
    i++;
23388
0
      } while (i < nbTargets);
23389
0
  }
23390
0
  matcher = matcher->next;
23391
0
    }
23392
0
    return(0);
23393
23394
0
internal_error:
23395
0
    return(-1);
23396
0
}
23397
23398
/**
23399
 * xmlSchemaBubbleIDCNodeTables:
23400
 * @depth: the current tree depth
23401
 *
23402
 * Merges IDC bindings of an element at @depth into the corresponding IDC
23403
 * bindings of its parent element. If a duplicate note-table entry is found,
23404
 * both, the parent node-table entry and child entry are discarded from the
23405
 * node-table of the parent.
23406
 *
23407
 * Returns 0 if OK and -1 on internal errors.
23408
 */
23409
static int
23410
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23411
0
{
23412
0
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23413
0
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23414
0
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23415
0
    xmlSchemaIDCAugPtr aidc;
23416
0
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23417
23418
0
    bind = vctxt->inode->idcTable;
23419
0
    if (bind == NULL) {
23420
  /* Fine, no table, no bubbles. */
23421
0
  return (0);
23422
0
    }
23423
23424
0
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23425
    /*
23426
    * Walk all bindings; create new or add to existing bindings.
23427
    * Remove duplicate key-sequences.
23428
    */
23429
0
    while (bind != NULL) {
23430
23431
0
  if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23432
0
      goto next_binding;
23433
  /*
23434
  * Check if the key/unique IDC table needs to be bubbled.
23435
  */
23436
0
  if (! vctxt->createIDCNodeTables) {
23437
0
      aidc = vctxt->aidcs;
23438
0
      do {
23439
0
    if (aidc->def == bind->definition) {
23440
0
        if ((aidc->keyrefDepth == -1) ||
23441
0
      (aidc->keyrefDepth >= vctxt->depth)) {
23442
0
      goto next_binding;
23443
0
        }
23444
0
        break;
23445
0
    }
23446
0
    aidc = aidc->next;
23447
0
      } while (aidc != NULL);
23448
0
  }
23449
23450
0
  if (parTable != NULL)
23451
0
      parBind = *parTable;
23452
  /*
23453
  * Search a matching parent binding for the
23454
  * IDC definition.
23455
  */
23456
0
  while (parBind != NULL) {
23457
0
      if (parBind->definition == bind->definition)
23458
0
    break;
23459
0
      parBind = parBind->next;
23460
0
  }
23461
23462
0
  if (parBind != NULL) {
23463
      /*
23464
      * Compare every node-table entry of the child node,
23465
      * i.e. the key-sequence within, ...
23466
      */
23467
0
      oldNum = parBind->nbNodes; /* Skip newly added items. */
23468
23469
0
      if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23470
0
    oldDupls = parBind->dupls->nbItems;
23471
0
    dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23472
0
      } else {
23473
0
    dupls = NULL;
23474
0
    oldDupls = 0;
23475
0
      }
23476
23477
0
      parNodes = parBind->nodeTable;
23478
0
      nbFields = bind->definition->nbFields;
23479
23480
0
      for (i = 0; i < bind->nbNodes; i++) {
23481
0
    node = bind->nodeTable[i];
23482
0
    if (node == NULL)
23483
0
        continue;
23484
    /*
23485
    * ...with every key-sequence of the parent node, already
23486
    * evaluated to be a duplicate key-sequence.
23487
    */
23488
0
    if (oldDupls) {
23489
0
        j = 0;
23490
0
        while (j < oldDupls) {
23491
0
      if (nbFields == 1) {
23492
0
          ret = xmlSchemaAreValuesEqual(
23493
0
        node->keys[0]->val,
23494
0
        dupls[j]->keys[0]->val);
23495
0
          if (ret == -1)
23496
0
        goto internal_error;
23497
0
          if (ret == 0) {
23498
0
        j++;
23499
0
        continue;
23500
0
          }
23501
0
      } else {
23502
0
          parNode = dupls[j];
23503
0
          for (k = 0; k < nbFields; k++) {
23504
0
        ret = xmlSchemaAreValuesEqual(
23505
0
            node->keys[k]->val,
23506
0
            parNode->keys[k]->val);
23507
0
        if (ret == -1)
23508
0
            goto internal_error;
23509
0
        if (ret == 0)
23510
0
            break;
23511
0
          }
23512
0
      }
23513
0
      if (ret == 1)
23514
          /* Duplicate found. */
23515
0
          break;
23516
0
      j++;
23517
0
        }
23518
0
        if (j != oldDupls) {
23519
      /* Duplicate found. Skip this entry. */
23520
0
      continue;
23521
0
        }
23522
0
    }
23523
    /*
23524
    * ... and with every key-sequence of the parent node.
23525
    */
23526
0
    if (oldNum) {
23527
0
        j = 0;
23528
0
        while (j < oldNum) {
23529
0
      parNode = parNodes[j];
23530
0
      if (nbFields == 1) {
23531
0
          ret = xmlSchemaAreValuesEqual(
23532
0
        node->keys[0]->val,
23533
0
        parNode->keys[0]->val);
23534
0
          if (ret == -1)
23535
0
        goto internal_error;
23536
0
          if (ret == 0) {
23537
0
        j++;
23538
0
        continue;
23539
0
          }
23540
0
      } else {
23541
0
          for (k = 0; k < nbFields; k++) {
23542
0
        ret = xmlSchemaAreValuesEqual(
23543
0
            node->keys[k]->val,
23544
0
            parNode->keys[k]->val);
23545
0
        if (ret == -1)
23546
0
            goto internal_error;
23547
0
        if (ret == 0)
23548
0
            break;
23549
0
          }
23550
0
      }
23551
0
      if (ret == 1)
23552
          /* Duplicate found. */
23553
0
          break;
23554
0
      j++;
23555
0
        }
23556
0
        if (j != oldNum) {
23557
      /*
23558
      * Handle duplicates. Move the duplicate in
23559
      * the parent's node-table to the list of
23560
      * duplicates.
23561
      */
23562
0
      oldNum--;
23563
0
      parBind->nbNodes--;
23564
      /*
23565
      * Move last old item to pos of duplicate.
23566
      */
23567
0
      parNodes[j] = parNodes[oldNum];
23568
23569
0
      if (parBind->nbNodes != oldNum) {
23570
          /*
23571
          * If new items exist, move last new item to
23572
          * last of old items.
23573
          */
23574
0
          parNodes[oldNum] =
23575
0
        parNodes[parBind->nbNodes];
23576
0
      }
23577
0
      if (parBind->dupls == NULL) {
23578
0
          parBind->dupls = xmlSchemaItemListCreate();
23579
0
          if (parBind->dupls == NULL)
23580
0
        goto internal_error;
23581
0
      }
23582
0
      xmlSchemaItemListAdd(parBind->dupls, parNode);
23583
0
        } else {
23584
      /*
23585
      * Add the node-table entry (node and key-sequence) of
23586
      * the child node to the node table of the parent node.
23587
      */
23588
0
      if (parBind->nodeTable == NULL) {
23589
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23590
0
        xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23591
0
          if (parBind->nodeTable == NULL) {
23592
0
        xmlSchemaVErrMemory(NULL);
23593
0
        goto internal_error;
23594
0
          }
23595
0
          parBind->sizeNodes = 1;
23596
0
      } else if (parBind->nbNodes >= parBind->sizeNodes) {
23597
0
          parBind->sizeNodes *= 2;
23598
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23599
0
        xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23600
0
        sizeof(xmlSchemaPSVIIDCNodePtr));
23601
0
          if (parBind->nodeTable == NULL) {
23602
0
        xmlSchemaVErrMemory(NULL);
23603
0
        goto internal_error;
23604
0
          }
23605
0
      }
23606
0
      parNodes = parBind->nodeTable;
23607
      /*
23608
      * Append the new node-table entry to the 'new node-table
23609
      * entries' section.
23610
      */
23611
0
      parNodes[parBind->nbNodes++] = node;
23612
0
        }
23613
23614
0
    }
23615
23616
0
      }
23617
0
  } else {
23618
      /*
23619
      * No binding for the IDC was found: create a new one and
23620
      * copy all node-tables.
23621
      */
23622
0
      parBind = xmlSchemaIDCNewBinding(bind->definition);
23623
0
      if (parBind == NULL)
23624
0
    goto internal_error;
23625
23626
      /*
23627
      * TODO: Hmm, how to optimize the initial number of
23628
      * allocated entries?
23629
      */
23630
0
      if (bind->nbNodes != 0) {
23631
    /*
23632
    * Add all IDC node-table entries.
23633
    */
23634
0
    if (! vctxt->psviExposeIDCNodeTables) {
23635
        /*
23636
        * Just move the entries.
23637
        * NOTE: this is quite save here, since
23638
        * all the keyref lookups have already been
23639
        * performed.
23640
        */
23641
0
        parBind->nodeTable = bind->nodeTable;
23642
0
        bind->nodeTable = NULL;
23643
0
        parBind->sizeNodes = bind->sizeNodes;
23644
0
        bind->sizeNodes = 0;
23645
0
        parBind->nbNodes = bind->nbNodes;
23646
0
        bind->nbNodes = 0;
23647
0
    } else {
23648
        /*
23649
        * Copy the entries.
23650
        */
23651
0
        parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23652
0
      xmlMalloc(bind->nbNodes *
23653
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
23654
0
        if (parBind->nodeTable == NULL) {
23655
0
      xmlSchemaVErrMemory(NULL);
23656
0
      xmlSchemaIDCFreeBinding(parBind);
23657
0
      goto internal_error;
23658
0
        }
23659
0
        parBind->sizeNodes = bind->nbNodes;
23660
0
        parBind->nbNodes = bind->nbNodes;
23661
0
        memcpy(parBind->nodeTable, bind->nodeTable,
23662
0
      bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23663
0
    }
23664
0
      }
23665
0
      if (bind->dupls) {
23666
    /*
23667
    * Move the duplicates.
23668
    */
23669
0
    if (parBind->dupls != NULL)
23670
0
        xmlSchemaItemListFree(parBind->dupls);
23671
0
    parBind->dupls = bind->dupls;
23672
0
    bind->dupls = NULL;
23673
0
      }
23674
0
            if (parTable != NULL) {
23675
0
                if (*parTable == NULL)
23676
0
                    *parTable = parBind;
23677
0
                else {
23678
0
                    parBind->next = *parTable;
23679
0
                    *parTable = parBind;
23680
0
                }
23681
0
            }
23682
0
  }
23683
23684
0
next_binding:
23685
0
  bind = bind->next;
23686
0
    }
23687
0
    return (0);
23688
23689
0
internal_error:
23690
0
    return(-1);
23691
0
}
23692
23693
/**
23694
 * xmlSchemaCheckCVCIDCKeyRef:
23695
 * @vctxt: the WXS validation context
23696
 * @elemDecl: the element declaration
23697
 *
23698
 * Check the cvc-idc-keyref constraints.
23699
 */
23700
static int
23701
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23702
0
{
23703
0
    xmlSchemaIDCMatcherPtr matcher;
23704
0
    xmlSchemaPSVIIDCBindingPtr bind;
23705
23706
0
    matcher = vctxt->inode->idcMatchers;
23707
    /*
23708
    * Find a keyref.
23709
    */
23710
0
    while (matcher != NULL) {
23711
0
  if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23712
0
      matcher->targets &&
23713
0
      matcher->targets->nbItems)
23714
0
  {
23715
0
      int i, j, k, res, nbFields, hasDupls;
23716
0
      xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23717
0
      xmlSchemaPSVIIDCNodePtr refNode = NULL;
23718
0
      xmlHashTablePtr table = NULL;
23719
23720
0
      nbFields = matcher->aidc->def->nbFields;
23721
23722
      /*
23723
      * Find the IDC node-table for the referenced IDC key/unique.
23724
      */
23725
0
      bind = vctxt->inode->idcTable;
23726
0
      while (bind != NULL) {
23727
0
    if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23728
0
        bind->definition)
23729
0
        break;
23730
0
    bind = bind->next;
23731
0
      }
23732
0
      hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23733
      /*
23734
      * Search for a matching key-sequences.
23735
      */
23736
0
      if (bind) {
23737
0
    table = xmlHashCreate(bind->nbNodes * 2);
23738
0
    for (j = 0; j < bind->nbNodes; j++) {
23739
0
        xmlChar *value;
23740
0
        xmlIDCHashEntryPtr r, e;
23741
0
        keys = bind->nodeTable[j]->keys;
23742
0
        xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
23743
0
        e = xmlMalloc(sizeof *e);
23744
0
        e->index = j;
23745
0
        r = xmlHashLookup(table, value);
23746
0
        if (r) {
23747
0
      e->next = r->next;
23748
0
      r->next = e;
23749
0
        } else {
23750
0
      e->next = NULL;
23751
0
      xmlHashAddEntry(table, value, e);
23752
0
        }
23753
0
        FREE_AND_NULL(value);
23754
0
    }
23755
0
      }
23756
0
      for (i = 0; i < matcher->targets->nbItems; i++) {
23757
0
    res = 0;
23758
0
    refNode = matcher->targets->items[i];
23759
0
    if (bind != NULL) {
23760
0
        xmlChar *value;
23761
0
        xmlIDCHashEntryPtr e;
23762
0
        refKeys = refNode->keys;
23763
0
        xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
23764
0
        e = xmlHashLookup(table, value);
23765
0
        FREE_AND_NULL(value);
23766
0
        res = 0;
23767
0
        for (;e; e = e->next) {
23768
0
      keys = bind->nodeTable[e->index]->keys;
23769
0
      for (k = 0; k < nbFields; k++) {
23770
0
          res = xmlSchemaAreValuesEqual(keys[k]->val,
23771
0
                refKeys[k]->val);
23772
0
          if (res == 0)
23773
0
              break;
23774
0
          else if (res == -1) {
23775
0
        return (-1);
23776
0
          }
23777
0
      }
23778
0
      if (res == 1) {
23779
          /*
23780
           * Match found.
23781
           */
23782
0
          break;
23783
0
      }
23784
0
        }
23785
0
        if ((res == 0) && hasDupls) {
23786
      /*
23787
      * Search in duplicates
23788
      */
23789
0
      for (j = 0; j < bind->dupls->nbItems; j++) {
23790
0
          keys = ((xmlSchemaPSVIIDCNodePtr)
23791
0
        bind->dupls->items[j])->keys;
23792
0
          for (k = 0; k < nbFields; k++) {
23793
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23794
0
            refKeys[k]->val);
23795
0
        if (res == 0)
23796
0
            break;
23797
0
        else if (res == -1) {
23798
0
            return (-1);
23799
0
        }
23800
0
          }
23801
0
          if (res == 1) {
23802
        /*
23803
        * Match in duplicates found.
23804
        */
23805
0
        xmlChar *str = NULL, *strB = NULL;
23806
0
        xmlSchemaKeyrefErr(vctxt,
23807
0
            XML_SCHEMAV_CVC_IDC, refNode,
23808
0
            (xmlSchemaTypePtr) matcher->aidc->def,
23809
0
            "More than one match found for "
23810
0
            "key-sequence %s of keyref '%s'",
23811
0
            xmlSchemaFormatIDCKeySequence(vctxt, &str,
23812
0
          refNode->keys, nbFields),
23813
0
            xmlSchemaGetComponentQName(&strB,
23814
0
          matcher->aidc->def));
23815
0
        FREE_AND_NULL(str);
23816
0
        FREE_AND_NULL(strB);
23817
0
        break;
23818
0
          }
23819
0
      }
23820
0
        }
23821
0
    }
23822
23823
0
    if (res == 0) {
23824
0
        xmlChar *str = NULL, *strB = NULL;
23825
0
        xmlSchemaKeyrefErr(vctxt,
23826
0
      XML_SCHEMAV_CVC_IDC, refNode,
23827
0
      (xmlSchemaTypePtr) matcher->aidc->def,
23828
0
      "No match found for key-sequence %s of keyref '%s'",
23829
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
23830
0
          refNode->keys, nbFields),
23831
0
      xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23832
0
        FREE_AND_NULL(str);
23833
0
        FREE_AND_NULL(strB);
23834
0
    }
23835
0
      }
23836
0
      if (table) {
23837
0
    xmlHashFree(table, xmlFreeIDCHashEntry);
23838
0
      }
23839
0
  }
23840
0
  matcher = matcher->next;
23841
0
    }
23842
    /* TODO: Return an error if any error encountered. */
23843
0
    return (0);
23844
0
}
23845
23846
/************************************************************************
23847
 *                  *
23848
 *      XML Reader validation code                      *
23849
 *                  *
23850
 ************************************************************************/
23851
23852
static xmlSchemaAttrInfoPtr
23853
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23854
0
{
23855
0
    xmlSchemaAttrInfoPtr iattr;
23856
    /*
23857
    * Grow/create list of attribute infos.
23858
    */
23859
0
    if (vctxt->attrInfos == NULL) {
23860
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23861
0
      xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23862
0
  vctxt->sizeAttrInfos = 1;
23863
0
  if (vctxt->attrInfos == NULL) {
23864
0
      xmlSchemaVErrMemory(vctxt);
23865
0
      return (NULL);
23866
0
  }
23867
0
    } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23868
0
  vctxt->sizeAttrInfos++;
23869
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23870
0
      xmlRealloc(vctxt->attrInfos,
23871
0
    vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23872
0
  if (vctxt->attrInfos == NULL) {
23873
0
      xmlSchemaVErrMemory(vctxt);
23874
0
      return (NULL);
23875
0
  }
23876
0
    } else {
23877
0
  iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23878
0
  if (iattr->localName != NULL) {
23879
0
      VERROR_INT("xmlSchemaGetFreshAttrInfo",
23880
0
    "attr info not cleared");
23881
0
      return (NULL);
23882
0
  }
23883
0
  iattr->nodeType = XML_ATTRIBUTE_NODE;
23884
0
  return (iattr);
23885
0
    }
23886
    /*
23887
    * Create an attribute info.
23888
    */
23889
0
    iattr = (xmlSchemaAttrInfoPtr)
23890
0
  xmlMalloc(sizeof(xmlSchemaAttrInfo));
23891
0
    if (iattr == NULL) {
23892
0
  xmlSchemaVErrMemory(vctxt);
23893
0
  return (NULL);
23894
0
    }
23895
0
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23896
0
    iattr->nodeType = XML_ATTRIBUTE_NODE;
23897
0
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23898
23899
0
    return (iattr);
23900
0
}
23901
23902
static int
23903
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23904
      xmlNodePtr attrNode,
23905
      int nodeLine,
23906
      const xmlChar *localName,
23907
      const xmlChar *nsName,
23908
      int ownedNames,
23909
      xmlChar *value,
23910
      int ownedValue)
23911
0
{
23912
0
    xmlSchemaAttrInfoPtr attr;
23913
23914
0
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
23915
0
    if (attr == NULL) {
23916
0
  VERROR_INT("xmlSchemaPushAttribute",
23917
0
      "calling xmlSchemaGetFreshAttrInfo()");
23918
0
  return (-1);
23919
0
    }
23920
0
    attr->node = attrNode;
23921
0
    attr->nodeLine = nodeLine;
23922
0
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23923
0
    attr->localName = localName;
23924
0
    attr->nsName = nsName;
23925
0
    if (ownedNames)
23926
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23927
    /*
23928
    * Evaluate if it's an XSI attribute.
23929
    */
23930
0
    if (nsName != NULL) {
23931
0
  if (xmlStrEqual(localName, BAD_CAST "nil")) {
23932
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23933
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23934
0
      }
23935
0
  } else if (xmlStrEqual(localName, BAD_CAST "type")) {
23936
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23937
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23938
0
      }
23939
0
  } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23940
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23941
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23942
0
      }
23943
0
  } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23944
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23945
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23946
0
      }
23947
0
  } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23948
0
      attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23949
0
  }
23950
0
    }
23951
0
    attr->value = value;
23952
0
    if (ownedValue)
23953
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23954
0
    if (attr->metaType != 0)
23955
0
  attr->state = XML_SCHEMAS_ATTR_META;
23956
0
    return (0);
23957
0
}
23958
23959
/**
23960
 * xmlSchemaClearElemInfo:
23961
 * @vctxt: the WXS validation context
23962
 * @ielem: the element information item
23963
 */
23964
static void
23965
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23966
           xmlSchemaNodeInfoPtr ielem)
23967
0
{
23968
0
    ielem->hasKeyrefs = 0;
23969
0
    ielem->appliedXPath = 0;
23970
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23971
0
  FREE_AND_NULL(ielem->localName);
23972
0
  FREE_AND_NULL(ielem->nsName);
23973
0
    } else {
23974
0
  ielem->localName = NULL;
23975
0
  ielem->nsName = NULL;
23976
0
    }
23977
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
23978
0
  FREE_AND_NULL(ielem->value);
23979
0
    } else {
23980
0
  ielem->value = NULL;
23981
0
    }
23982
0
    if (ielem->val != NULL) {
23983
  /*
23984
  * PSVI TODO: Be careful not to free it when the value is
23985
  * exposed via PSVI.
23986
  */
23987
0
  xmlSchemaFreeValue(ielem->val);
23988
0
  ielem->val = NULL;
23989
0
    }
23990
0
    if (ielem->idcMatchers != NULL) {
23991
  /*
23992
  * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
23993
  *   Does it work?
23994
  */
23995
0
  xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
23996
#if 0
23997
  xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
23998
#endif
23999
0
  ielem->idcMatchers = NULL;
24000
0
    }
24001
0
    if (ielem->idcTable != NULL) {
24002
  /*
24003
  * OPTIMIZE TODO: Use a pool of IDC tables??.
24004
  */
24005
0
  xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24006
0
  ielem->idcTable = NULL;
24007
0
    }
24008
0
    if (ielem->regexCtxt != NULL) {
24009
0
  xmlRegFreeExecCtxt(ielem->regexCtxt);
24010
0
  ielem->regexCtxt = NULL;
24011
0
    }
24012
0
    if (ielem->nsBindings != NULL) {
24013
0
  xmlFree((xmlChar **)ielem->nsBindings);
24014
0
  ielem->nsBindings = NULL;
24015
0
  ielem->nbNsBindings = 0;
24016
0
  ielem->sizeNsBindings = 0;
24017
0
    }
24018
0
}
24019
24020
/**
24021
 * xmlSchemaGetFreshElemInfo:
24022
 * @vctxt: the schema validation context
24023
 *
24024
 * Creates/reuses and initializes the element info item for
24025
 * the current tree depth.
24026
 *
24027
 * Returns the element info item or NULL on API or internal errors.
24028
 */
24029
static xmlSchemaNodeInfoPtr
24030
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24031
0
{
24032
0
    xmlSchemaNodeInfoPtr info = NULL;
24033
24034
0
    if (vctxt->depth > vctxt->sizeElemInfos) {
24035
0
  VERROR_INT("xmlSchemaGetFreshElemInfo",
24036
0
      "inconsistent depth encountered");
24037
0
  return (NULL);
24038
0
    }
24039
0
    if (vctxt->elemInfos == NULL) {
24040
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24041
0
      xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24042
0
  if (vctxt->elemInfos == NULL) {
24043
0
      xmlSchemaVErrMemory(vctxt);
24044
0
      return (NULL);
24045
0
  }
24046
0
  memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24047
0
  vctxt->sizeElemInfos = 10;
24048
0
    } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24049
0
  int i = vctxt->sizeElemInfos;
24050
24051
0
  vctxt->sizeElemInfos *= 2;
24052
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24053
0
      xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24054
0
      sizeof(xmlSchemaNodeInfoPtr));
24055
0
  if (vctxt->elemInfos == NULL) {
24056
0
      xmlSchemaVErrMemory(vctxt);
24057
0
      return (NULL);
24058
0
  }
24059
  /*
24060
  * We need the new memory to be NULLed.
24061
  * TODO: Use memset instead?
24062
  */
24063
0
  for (; i < vctxt->sizeElemInfos; i++)
24064
0
      vctxt->elemInfos[i] = NULL;
24065
0
    } else
24066
0
  info = vctxt->elemInfos[vctxt->depth];
24067
24068
0
    if (info == NULL) {
24069
0
  info = (xmlSchemaNodeInfoPtr)
24070
0
      xmlMalloc(sizeof(xmlSchemaNodeInfo));
24071
0
  if (info == NULL) {
24072
0
      xmlSchemaVErrMemory(vctxt);
24073
0
      return (NULL);
24074
0
  }
24075
0
  vctxt->elemInfos[vctxt->depth] = info;
24076
0
    } else {
24077
0
  if (info->localName != NULL) {
24078
0
      VERROR_INT("xmlSchemaGetFreshElemInfo",
24079
0
    "elem info has not been cleared");
24080
0
      return (NULL);
24081
0
  }
24082
0
    }
24083
0
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
24084
0
    info->nodeType = XML_ELEMENT_NODE;
24085
0
    info->depth = vctxt->depth;
24086
24087
0
    return (info);
24088
0
}
24089
24090
0
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24091
0
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24092
0
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24093
24094
static int
24095
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24096
      xmlNodePtr node,
24097
      xmlSchemaTypePtr type,
24098
      xmlSchemaValType valType,
24099
      const xmlChar * value,
24100
      xmlSchemaValPtr val,
24101
      unsigned long length,
24102
      int fireErrors)
24103
0
{
24104
0
    int ret, error = 0, found;
24105
24106
0
    xmlSchemaTypePtr tmpType;
24107
0
    xmlSchemaFacetLinkPtr facetLink;
24108
0
    xmlSchemaFacetPtr facet;
24109
0
    unsigned long len = 0;
24110
0
    xmlSchemaWhitespaceValueType ws;
24111
24112
    /*
24113
    * In Libxml2, derived built-in types have currently no explicit facets.
24114
    */
24115
0
    if (type->type == XML_SCHEMA_TYPE_BASIC)
24116
0
  return (0);
24117
24118
    /*
24119
    * NOTE: Do not jump away, if the facetSet of the given type is
24120
    * empty: until now, "pattern" and "enumeration" facets of the
24121
    * *base types* need to be checked as well.
24122
    */
24123
0
    if (type->facetSet == NULL)
24124
0
  goto pattern_and_enum;
24125
24126
0
    if (! WXS_IS_ATOMIC(type)) {
24127
0
  if (WXS_IS_LIST(type))
24128
0
      goto WXS_IS_LIST;
24129
0
  else
24130
0
      goto pattern_and_enum;
24131
0
    }
24132
24133
    /*
24134
    * Whitespace handling is only of importance for string-based
24135
    * types.
24136
    */
24137
0
    tmpType = xmlSchemaGetPrimitiveType(type);
24138
0
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24139
0
  WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24140
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24141
0
    } else
24142
0
  ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24143
24144
    /*
24145
    * If the value was not computed (for string or
24146
    * anySimpleType based types), then use the provided
24147
    * type.
24148
    */
24149
0
    if (val != NULL)
24150
0
  valType = xmlSchemaGetValType(val);
24151
24152
0
    ret = 0;
24153
0
    for (facetLink = type->facetSet; facetLink != NULL;
24154
0
  facetLink = facetLink->next) {
24155
  /*
24156
  * Skip the pattern "whiteSpace": it is used to
24157
  * format the character content beforehand.
24158
  */
24159
0
  switch (facetLink->facet->type) {
24160
0
      case XML_SCHEMA_FACET_WHITESPACE:
24161
0
      case XML_SCHEMA_FACET_PATTERN:
24162
0
      case XML_SCHEMA_FACET_ENUMERATION:
24163
0
    continue;
24164
0
      case XML_SCHEMA_FACET_LENGTH:
24165
0
      case XML_SCHEMA_FACET_MINLENGTH:
24166
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24167
0
    ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24168
0
        valType, value, val, &len, ws);
24169
0
    break;
24170
0
      default:
24171
0
    ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24172
0
        valType, value, val, ws);
24173
0
    break;
24174
0
  }
24175
0
  if (ret < 0) {
24176
0
      AERROR_INT("xmlSchemaValidateFacets",
24177
0
    "validating against a atomic type facet");
24178
0
      return (-1);
24179
0
  } else if (ret > 0) {
24180
0
      if (fireErrors)
24181
0
    xmlSchemaFacetErr(actxt, ret, node,
24182
0
    value, len, type, facetLink->facet, NULL, NULL, NULL);
24183
0
      else
24184
0
    return (ret);
24185
0
      if (error == 0)
24186
0
    error = ret;
24187
0
  }
24188
0
  ret = 0;
24189
0
    }
24190
24191
0
WXS_IS_LIST:
24192
0
    if (! WXS_IS_LIST(type))
24193
0
  goto pattern_and_enum;
24194
    /*
24195
    * "length", "minLength" and "maxLength" of list types.
24196
    */
24197
0
    ret = 0;
24198
0
    for (facetLink = type->facetSet; facetLink != NULL;
24199
0
  facetLink = facetLink->next) {
24200
24201
0
  switch (facetLink->facet->type) {
24202
0
      case XML_SCHEMA_FACET_LENGTH:
24203
0
      case XML_SCHEMA_FACET_MINLENGTH:
24204
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24205
0
    ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24206
0
        value, length, NULL);
24207
0
    break;
24208
0
      default:
24209
0
    continue;
24210
0
  }
24211
0
  if (ret < 0) {
24212
0
      AERROR_INT("xmlSchemaValidateFacets",
24213
0
    "validating against a list type facet");
24214
0
      return (-1);
24215
0
  } else if (ret > 0) {
24216
0
      if (fireErrors)
24217
0
    xmlSchemaFacetErr(actxt, ret, node,
24218
0
    value, length, type, facetLink->facet, NULL, NULL, NULL);
24219
0
      else
24220
0
    return (ret);
24221
0
      if (error == 0)
24222
0
    error = ret;
24223
0
  }
24224
0
  ret = 0;
24225
0
    }
24226
24227
0
pattern_and_enum:
24228
0
    found = 0;
24229
    /*
24230
    * Process enumerations. Facet values are in the value space
24231
    * of the defining type's base type. This seems to be a bug in the
24232
    * XML Schema 1.0 spec. Use the whitespace type of the base type.
24233
    * Only the first set of enumerations in the ancestor-or-self axis
24234
    * is used for validation.
24235
    */
24236
0
    ret = 0;
24237
0
    tmpType = type;
24238
0
    do {
24239
0
        for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24240
0
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24241
0
                continue;
24242
0
            found = 1;
24243
0
            ret = xmlSchemaAreValuesEqual(facet->val, val);
24244
0
            if (ret == 1)
24245
0
                break;
24246
0
            else if (ret < 0) {
24247
0
                AERROR_INT("xmlSchemaValidateFacets",
24248
0
                    "validating against an enumeration facet");
24249
0
                return (-1);
24250
0
            }
24251
0
        }
24252
0
        if (ret != 0)
24253
0
            break;
24254
        /*
24255
        * Break on the first set of enumerations. Any additional
24256
        *  enumerations which might be existent on the ancestors
24257
        *  of the current type are restricted by this set; thus
24258
        *  *must* *not* be taken into account.
24259
        */
24260
0
        if (found)
24261
0
            break;
24262
0
        tmpType = tmpType->baseType;
24263
0
    } while ((tmpType != NULL) &&
24264
0
        (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24265
0
    if (found && (ret == 0)) {
24266
0
        ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24267
0
        if (fireErrors) {
24268
0
            xmlSchemaFacetErr(actxt, ret, node,
24269
0
                value, 0, type, NULL, NULL, NULL, NULL);
24270
0
        } else
24271
0
            return (ret);
24272
0
        if (error == 0)
24273
0
            error = ret;
24274
0
    }
24275
24276
    /*
24277
    * Process patters. Pattern facets are ORed at type level
24278
    * and ANDed if derived. Walk the base type axis.
24279
    */
24280
0
    tmpType = type;
24281
0
    facet = NULL;
24282
0
    do {
24283
0
        found = 0;
24284
0
        for (facetLink = tmpType->facetSet; facetLink != NULL;
24285
0
            facetLink = facetLink->next) {
24286
0
            if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24287
0
                continue;
24288
0
            found = 1;
24289
            /*
24290
            * NOTE that for patterns, @value needs to be the
24291
            * normalized value.
24292
            */
24293
0
            ret = xmlRegexpExec(facetLink->facet->regexp, value);
24294
0
            if (ret == 1)
24295
0
                break;
24296
0
            else if (ret < 0) {
24297
0
                AERROR_INT("xmlSchemaValidateFacets",
24298
0
                    "validating against a pattern facet");
24299
0
                return (-1);
24300
0
            } else {
24301
                /*
24302
                * Save the last non-validating facet.
24303
                */
24304
0
                facet = facetLink->facet;
24305
0
            }
24306
0
        }
24307
0
        if (found && (ret != 1)) {
24308
0
            ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24309
0
            if (fireErrors) {
24310
0
                xmlSchemaFacetErr(actxt, ret, node,
24311
0
                    value, 0, type, facet, NULL, NULL, NULL);
24312
0
            } else
24313
0
                return (ret);
24314
0
            if (error == 0)
24315
0
                error = ret;
24316
0
            break;
24317
0
        }
24318
0
        tmpType = tmpType->baseType;
24319
0
    } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24320
24321
0
    return (error);
24322
0
}
24323
24324
static xmlChar *
24325
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24326
      const xmlChar *value)
24327
0
{
24328
0
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24329
0
  case XML_SCHEMA_WHITESPACE_COLLAPSE:
24330
0
      return (xmlSchemaCollapseString(value));
24331
0
  case XML_SCHEMA_WHITESPACE_REPLACE:
24332
0
      return (xmlSchemaWhiteSpaceReplace(value));
24333
0
  default:
24334
0
      return (NULL);
24335
0
    }
24336
0
}
24337
24338
static int
24339
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24340
           const xmlChar *value,
24341
           xmlSchemaValPtr *val,
24342
           int valNeeded)
24343
0
{
24344
0
    int ret;
24345
0
    xmlChar *stripped;
24346
0
    const xmlChar *nsName;
24347
0
    xmlChar *local, *prefix = NULL;
24348
24349
0
    ret = xmlValidateQName(value, 1);
24350
0
    if (ret != 0) {
24351
0
  if (ret == -1) {
24352
0
      VERROR_INT("xmlSchemaValidateQName",
24353
0
    "calling xmlValidateQName()");
24354
0
      return (-1);
24355
0
  }
24356
0
  return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24357
0
    }
24358
    /*
24359
    * NOTE: xmlSplitQName2 will always return a duplicated
24360
    * strings.
24361
    */
24362
    /* TODO: Export and use xmlSchemaStrip instead */
24363
0
    stripped = xmlSchemaCollapseString(value);
24364
0
    local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24365
0
    xmlFree(stripped);
24366
0
    if (local == NULL)
24367
0
  local = xmlStrdup(value);
24368
    /*
24369
    * OPTIMIZE TODO: Use flags for:
24370
    *  - is there any namespace binding?
24371
    *  - is there a default namespace?
24372
    */
24373
0
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24374
24375
0
    if (prefix != NULL) {
24376
0
  xmlFree(prefix);
24377
  /*
24378
  * A namespace must be found if the prefix is
24379
  * NOT NULL.
24380
  */
24381
0
  if (nsName == NULL) {
24382
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24383
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24384
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24385
0
    "The QName value '%s' has no "
24386
0
    "corresponding namespace declaration in "
24387
0
    "scope", value, NULL);
24388
0
      if (local != NULL)
24389
0
    xmlFree(local);
24390
0
      return (ret);
24391
0
  }
24392
0
    }
24393
0
    if (valNeeded && val) {
24394
0
  if (nsName != NULL)
24395
0
      *val = xmlSchemaNewQNameValue(
24396
0
    BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24397
0
  else
24398
0
      *val = xmlSchemaNewQNameValue(NULL,
24399
0
    BAD_CAST local);
24400
0
    } else
24401
0
  xmlFree(local);
24402
0
    return (0);
24403
0
}
24404
24405
/*
24406
* cvc-simple-type
24407
*/
24408
static int
24409
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24410
           xmlNodePtr node,
24411
           xmlSchemaTypePtr type,
24412
           const xmlChar *value,
24413
           xmlSchemaValPtr *retVal,
24414
           int fireErrors,
24415
           int normalize,
24416
           int isNormalized)
24417
0
{
24418
0
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
24419
0
    xmlSchemaValPtr val = NULL;
24420
    /* xmlSchemaWhitespaceValueType ws; */
24421
0
    xmlChar *normValue = NULL;
24422
24423
0
#define NORMALIZE(atype) \
24424
0
    if ((! isNormalized) && \
24425
0
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24426
0
  normValue = xmlSchemaNormalizeValue(atype, value); \
24427
0
  if (normValue != NULL) \
24428
0
      value = normValue; \
24429
0
  isNormalized = 1; \
24430
0
    }
24431
24432
0
    if ((retVal != NULL) && (*retVal != NULL)) {
24433
0
  xmlSchemaFreeValue(*retVal);
24434
0
  *retVal = NULL;
24435
0
    }
24436
    /*
24437
    * 3.14.4 Simple Type Definition Validation Rules
24438
    * Validation Rule: String Valid
24439
    */
24440
    /*
24441
    * 1 It is schema-valid with respect to that definition as defined
24442
    * by Datatype Valid in [XML Schemas: Datatypes].
24443
    */
24444
    /*
24445
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24446
    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24447
    * the string must be a `declared entity name`.
24448
    */
24449
    /*
24450
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24451
    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24452
    * then every whitespace-delimited substring of the string must be a `declared
24453
    * entity name`.
24454
    */
24455
    /*
24456
    * 2.3 otherwise no further condition applies.
24457
    */
24458
0
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24459
0
  valNeeded = 1;
24460
0
    if (value == NULL)
24461
0
  value = BAD_CAST "";
24462
0
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24463
0
  xmlSchemaTypePtr biType; /* The built-in type. */
24464
  /*
24465
  * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24466
  * a literal in the `lexical space` of {base type definition}"
24467
  */
24468
  /*
24469
  * Whitespace-normalize.
24470
  */
24471
0
  NORMALIZE(type);
24472
0
  if (type->type != XML_SCHEMA_TYPE_BASIC) {
24473
      /*
24474
      * Get the built-in type.
24475
      */
24476
0
      biType = type->baseType;
24477
0
      while ((biType != NULL) &&
24478
0
    (biType->type != XML_SCHEMA_TYPE_BASIC))
24479
0
    biType = biType->baseType;
24480
24481
0
      if (biType == NULL) {
24482
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24483
0
        "could not get the built-in type");
24484
0
    goto internal_error;
24485
0
      }
24486
0
  } else
24487
0
      biType = type;
24488
  /*
24489
  * NOTATIONs need to be processed here, since they need
24490
  * to lookup in the hashtable of NOTATION declarations of the schema.
24491
  */
24492
0
  if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24493
0
      switch (biType->builtInType) {
24494
0
    case XML_SCHEMAS_NOTATION:
24495
0
        ret = xmlSchemaValidateNotation(
24496
0
      (xmlSchemaValidCtxtPtr) actxt,
24497
0
      ((xmlSchemaValidCtxtPtr) actxt)->schema,
24498
0
      NULL, value, &val, valNeeded);
24499
0
        break;
24500
0
    case XML_SCHEMAS_QNAME:
24501
0
        ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24502
0
      value, &val, valNeeded);
24503
0
        break;
24504
0
    default:
24505
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24506
0
        if (valNeeded)
24507
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24508
0
          value, &val, node);
24509
0
        else
24510
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24511
0
          value, NULL, node);
24512
0
        break;
24513
0
      }
24514
0
  } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24515
0
      switch (biType->builtInType) {
24516
0
    case XML_SCHEMAS_NOTATION:
24517
0
        ret = xmlSchemaValidateNotation(NULL,
24518
0
      ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24519
0
      value, &val, valNeeded);
24520
0
        break;
24521
0
    default:
24522
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24523
0
        if (valNeeded)
24524
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24525
0
          value, &val, node);
24526
0
        else
24527
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24528
0
          value, NULL, node);
24529
0
        break;
24530
0
      }
24531
0
  } else {
24532
      /*
24533
      * Validation via a public API is not implemented yet.
24534
      */
24535
0
      goto internal_error;
24536
0
  }
24537
0
  if (ret != 0) {
24538
0
      if (ret < 0) {
24539
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24540
0
        "validating against a built-in type");
24541
0
    goto internal_error;
24542
0
      }
24543
0
      if (WXS_IS_LIST(type))
24544
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24545
0
      else
24546
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24547
0
  }
24548
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24549
      /*
24550
      * Check facets.
24551
      */
24552
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24553
0
    (xmlSchemaValType) biType->builtInType, value, val,
24554
0
    0, fireErrors);
24555
0
      if (ret != 0) {
24556
0
    if (ret < 0) {
24557
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24558
0
      "validating facets of atomic simple type");
24559
0
        goto internal_error;
24560
0
    }
24561
0
    if (WXS_IS_LIST(type))
24562
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24563
0
    else
24564
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24565
0
      }
24566
0
  }
24567
0
  else if (fireErrors && (ret > 0))
24568
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24569
0
    } else if (WXS_IS_LIST(type)) {
24570
24571
0
  xmlSchemaTypePtr itemType;
24572
0
  const xmlChar *cur, *end;
24573
0
  xmlChar *tmpValue = NULL;
24574
0
  unsigned long len = 0;
24575
0
  xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24576
  /* 1.2.2 if {variety} is `list` then the string must be a sequence
24577
  * of white space separated tokens, each of which `match`es a literal
24578
  * in the `lexical space` of {item type definition}
24579
  */
24580
  /*
24581
  * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24582
  * the list type has an enum or pattern facet.
24583
  */
24584
0
  NORMALIZE(type);
24585
  /*
24586
  * VAL TODO: Optimize validation of empty values.
24587
  * VAL TODO: We do not have computed values for lists.
24588
  */
24589
0
  itemType = WXS_LIST_ITEMTYPE(type);
24590
0
  cur = value;
24591
0
  do {
24592
0
      while (IS_BLANK_CH(*cur))
24593
0
    cur++;
24594
0
      end = cur;
24595
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24596
0
    end++;
24597
0
      if (end == cur)
24598
0
    break;
24599
0
      tmpValue = xmlStrndup(cur, end - cur);
24600
0
      len++;
24601
24602
0
      if (valNeeded)
24603
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24604
0
        tmpValue, &curVal, fireErrors, 0, 1);
24605
0
      else
24606
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24607
0
        tmpValue, NULL, fireErrors, 0, 1);
24608
0
      FREE_AND_NULL(tmpValue);
24609
0
      if (curVal != NULL) {
24610
    /*
24611
    * Add to list of computed values.
24612
    */
24613
0
    if (val == NULL)
24614
0
        val = curVal;
24615
0
    else
24616
0
        xmlSchemaValueAppend(prevVal, curVal);
24617
0
    prevVal = curVal;
24618
0
    curVal = NULL;
24619
0
      }
24620
0
      if (ret != 0) {
24621
0
    if (ret < 0) {
24622
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24623
0
      "validating an item of list simple type");
24624
0
        goto internal_error;
24625
0
    }
24626
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24627
0
    break;
24628
0
      }
24629
0
      cur = end;
24630
0
  } while (*cur != 0);
24631
0
  FREE_AND_NULL(tmpValue);
24632
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24633
      /*
24634
      * Apply facets (pattern, enumeration).
24635
      */
24636
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24637
0
    XML_SCHEMAS_UNKNOWN, value, val,
24638
0
    len, fireErrors);
24639
0
      if (ret != 0) {
24640
0
    if (ret < 0) {
24641
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24642
0
      "validating facets of list simple type");
24643
0
        goto internal_error;
24644
0
    }
24645
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24646
0
      }
24647
0
  }
24648
0
  if (fireErrors && (ret > 0)) {
24649
      /*
24650
      * Report the normalized value.
24651
      */
24652
0
      normalize = 1;
24653
0
      NORMALIZE(type);
24654
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24655
0
  }
24656
0
    } else if (WXS_IS_UNION(type)) {
24657
0
  xmlSchemaTypeLinkPtr memberLink;
24658
  /*
24659
  * TODO: For all datatypes `derived` by `union`  whiteSpace does
24660
  * not apply directly; however, the normalization behavior of `union`
24661
  * types is controlled by the value of whiteSpace on that one of the
24662
  * `memberTypes` against which the `union` is successfully validated.
24663
  *
24664
  * This means that the value is normalized by the first validating
24665
  * member type, then the facets of the union type are applied. This
24666
  * needs changing of the value!
24667
  */
24668
24669
  /*
24670
  * 1.2.3 if {variety} is `union` then the string must `match` a
24671
  * literal in the `lexical space` of at least one member of
24672
  * {member type definitions}
24673
  */
24674
0
  memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24675
0
  if (memberLink == NULL) {
24676
0
      AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24677
0
    "union simple type has no member types");
24678
0
      goto internal_error;
24679
0
  }
24680
  /*
24681
  * Always normalize union type values, since we currently
24682
  * cannot store the whitespace information with the value
24683
  * itself; otherwise a later value-comparison would be
24684
  * not possible.
24685
  */
24686
0
  while (memberLink != NULL) {
24687
0
      if (valNeeded)
24688
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24689
0
        memberLink->type, value, &val, 0, 1, 0);
24690
0
      else
24691
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24692
0
        memberLink->type, value, NULL, 0, 1, 0);
24693
0
      if (ret <= 0)
24694
0
    break;
24695
0
      memberLink = memberLink->next;
24696
0
  }
24697
0
  if (ret != 0) {
24698
0
      if (ret < 0) {
24699
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24700
0
        "validating members of union simple type");
24701
0
    goto internal_error;
24702
0
      }
24703
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24704
0
  }
24705
  /*
24706
  * Apply facets (pattern, enumeration).
24707
  */
24708
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24709
      /*
24710
      * The normalization behavior of `union` types is controlled by
24711
      * the value of whiteSpace on that one of the `memberTypes`
24712
      * against which the `union` is successfully validated.
24713
      */
24714
0
      NORMALIZE(memberLink->type);
24715
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24716
0
    XML_SCHEMAS_UNKNOWN, value, val,
24717
0
    0, fireErrors);
24718
0
      if (ret != 0) {
24719
0
    if (ret < 0) {
24720
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24721
0
      "validating facets of union simple type");
24722
0
        goto internal_error;
24723
0
    }
24724
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24725
0
      }
24726
0
  }
24727
0
  if (fireErrors && (ret > 0))
24728
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24729
0
    }
24730
24731
0
    if (normValue != NULL)
24732
0
  xmlFree(normValue);
24733
0
    if (ret == 0) {
24734
0
  if (retVal != NULL)
24735
0
      *retVal = val;
24736
0
  else if (val != NULL)
24737
0
      xmlSchemaFreeValue(val);
24738
0
    } else if (val != NULL)
24739
0
  xmlSchemaFreeValue(val);
24740
0
    return (ret);
24741
0
internal_error:
24742
0
    if (normValue != NULL)
24743
0
  xmlFree(normValue);
24744
0
    if (val != NULL)
24745
0
  xmlSchemaFreeValue(val);
24746
0
    return (-1);
24747
0
}
24748
24749
static int
24750
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24751
         const xmlChar *value,
24752
         const xmlChar **nsName,
24753
         const xmlChar **localName)
24754
0
{
24755
0
    int ret = 0;
24756
24757
0
    if ((nsName == NULL) || (localName == NULL))
24758
0
  return (-1);
24759
0
    *nsName = NULL;
24760
0
    *localName = NULL;
24761
24762
0
    ret = xmlValidateQName(value, 1);
24763
0
    if (ret == -1)
24764
0
  return (-1);
24765
0
    if (ret > 0) {
24766
0
  xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24767
0
      XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24768
0
      value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24769
0
  return (1);
24770
0
    }
24771
0
    {
24772
0
  xmlChar *local = NULL;
24773
0
  xmlChar *prefix;
24774
24775
  /*
24776
  * NOTE: xmlSplitQName2 will return a duplicated
24777
  * string.
24778
  */
24779
0
  local = xmlSplitQName2(value, &prefix);
24780
0
  if (local == NULL)
24781
0
      *localName = xmlDictLookup(vctxt->dict, value, -1);
24782
0
  else {
24783
0
      *localName = xmlDictLookup(vctxt->dict, local, -1);
24784
0
      xmlFree(local);
24785
0
  }
24786
24787
0
  *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24788
24789
0
  if (prefix != NULL) {
24790
0
      xmlFree(prefix);
24791
      /*
24792
      * A namespace must be found if the prefix is NOT NULL.
24793
      */
24794
0
      if (*nsName == NULL) {
24795
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24796
0
        XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24797
0
        WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24798
0
        "The QName value '%s' has no "
24799
0
        "corresponding namespace declaration in scope",
24800
0
        value, NULL);
24801
0
    return (2);
24802
0
      }
24803
0
  }
24804
0
    }
24805
0
    return (0);
24806
0
}
24807
24808
static int
24809
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24810
      xmlSchemaAttrInfoPtr iattr,
24811
      xmlSchemaTypePtr *localType,
24812
      xmlSchemaElementPtr elemDecl)
24813
0
{
24814
0
    int ret = 0;
24815
    /*
24816
    * cvc-elt (3.3.4) : (4)
24817
    * AND
24818
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
24819
    *   (1.2.1.2.1) - (1.2.1.2.4)
24820
    * Handle 'xsi:type'.
24821
    */
24822
0
    if (localType == NULL)
24823
0
  return (-1);
24824
0
    *localType = NULL;
24825
0
    if (iattr == NULL)
24826
0
  return (0);
24827
0
    else {
24828
0
  const xmlChar *nsName = NULL, *local = NULL;
24829
  /*
24830
  * TODO: We should report a *warning* that the type was overridden
24831
  * by the instance.
24832
  */
24833
0
  ACTIVATE_ATTRIBUTE(iattr);
24834
  /*
24835
  * (cvc-elt) (3.3.4) : (4.1)
24836
  * (cvc-assess-elt) (1.2.1.2.2)
24837
  */
24838
0
  ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24839
0
      &nsName, &local);
24840
0
  if (ret != 0) {
24841
0
      if (ret < 0) {
24842
0
    VERROR_INT("xmlSchemaValidateElementByDeclaration",
24843
0
        "calling xmlSchemaQNameExpand() to validate the "
24844
0
        "attribute 'xsi:type'");
24845
0
    goto internal_error;
24846
0
      }
24847
0
      goto exit;
24848
0
  }
24849
  /*
24850
  * (cvc-elt) (3.3.4) : (4.2)
24851
  * (cvc-assess-elt) (1.2.1.2.3)
24852
  */
24853
0
  *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24854
0
  if (*localType == NULL) {
24855
0
      xmlChar *str = NULL;
24856
24857
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
24858
0
    XML_SCHEMAV_CVC_ELT_4_2, NULL,
24859
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24860
0
    "The QName value '%s' of the xsi:type attribute does not "
24861
0
    "resolve to a type definition",
24862
0
    xmlSchemaFormatQName(&str, nsName, local), NULL);
24863
0
      FREE_AND_NULL(str);
24864
0
      ret = vctxt->err;
24865
0
      goto exit;
24866
0
  }
24867
0
  if (elemDecl != NULL) {
24868
0
      int set = 0;
24869
24870
      /*
24871
      * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24872
      * "The `local type definition` must be validly
24873
      * derived from the {type definition} given the union of
24874
      * the {disallowed substitutions} and the {type definition}'s
24875
      * {prohibited substitutions}, as defined in
24876
      * Type Derivation OK (Complex) ($3.4.6)
24877
      * (if it is a complex type definition),
24878
      * or given {disallowed substitutions} as defined in Type
24879
      * Derivation OK (Simple) ($3.14.6) (if it is a simple type
24880
      * definition)."
24881
      *
24882
      * {disallowed substitutions}: the "block" on the element decl.
24883
      * {prohibited substitutions}: the "block" on the type def.
24884
      */
24885
      /*
24886
      * OPTIMIZE TODO: We could map types already evaluated
24887
      * to be validly derived from other types to avoid checking
24888
      * this over and over for the same types.
24889
      */
24890
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24891
0
    (elemDecl->subtypes->flags &
24892
0
        XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24893
0
    set |= SUBSET_EXTENSION;
24894
24895
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24896
0
    (elemDecl->subtypes->flags &
24897
0
        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24898
0
    set |= SUBSET_RESTRICTION;
24899
24900
      /*
24901
      * REMOVED and CHANGED since this produced a parser context
24902
      * which adds to the string dict of the schema. So this would
24903
      * change the schema and we don't want this. We don't need
24904
      * the parser context anymore.
24905
      *
24906
      * if ((vctxt->pctxt == NULL) &&
24907
      * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24908
      *     return (-1);
24909
      */
24910
24911
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24912
0
    elemDecl->subtypes, set) != 0) {
24913
0
    xmlChar *str = NULL;
24914
24915
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24916
0
        XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24917
0
        "The type definition '%s', specified by xsi:type, is "
24918
0
        "blocked or not validly derived from the type definition "
24919
0
        "of the element declaration",
24920
0
        xmlSchemaFormatQName(&str,
24921
0
      (*localType)->targetNamespace,
24922
0
      (*localType)->name),
24923
0
        NULL);
24924
0
    FREE_AND_NULL(str);
24925
0
    ret = vctxt->err;
24926
0
    *localType = NULL;
24927
0
      }
24928
0
  }
24929
0
    }
24930
0
exit:
24931
0
    ACTIVATE_ELEM;
24932
0
    return (ret);
24933
0
internal_error:
24934
0
    ACTIVATE_ELEM;
24935
0
    return (-1);
24936
0
}
24937
24938
static int
24939
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24940
0
{
24941
0
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24942
0
    xmlSchemaTypePtr actualType;
24943
24944
    /*
24945
    * cvc-elt (3.3.4) : 1
24946
    */
24947
0
    if (elemDecl == NULL) {
24948
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24949
0
      "No matching declaration available");
24950
0
        return (vctxt->err);
24951
0
    }
24952
0
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
24953
    /*
24954
    * cvc-elt (3.3.4) : 2
24955
    */
24956
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24957
0
  VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24958
0
      "The element declaration is abstract");
24959
0
        return (vctxt->err);
24960
0
    }
24961
0
    if (actualType == NULL) {
24962
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24963
0
      "The type definition is absent");
24964
0
  return (XML_SCHEMAV_CVC_TYPE_1);
24965
0
    }
24966
0
    if (vctxt->nbAttrInfos != 0) {
24967
0
  int ret;
24968
0
  xmlSchemaAttrInfoPtr iattr;
24969
  /*
24970
  * cvc-elt (3.3.4) : 3
24971
  * Handle 'xsi:nil'.
24972
  */
24973
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
24974
0
      XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
24975
0
  if (iattr) {
24976
0
      ACTIVATE_ATTRIBUTE(iattr);
24977
      /*
24978
      * Validate the value.
24979
      */
24980
0
      ret = xmlSchemaVCheckCVCSimpleType(
24981
0
    ACTXT_CAST vctxt, NULL,
24982
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
24983
0
    iattr->value, &(iattr->val), 1, 0, 0);
24984
0
      ACTIVATE_ELEM;
24985
0
      if (ret < 0) {
24986
0
    VERROR_INT("xmlSchemaValidateElemDecl",
24987
0
        "calling xmlSchemaVCheckCVCSimpleType() to "
24988
0
        "validate the attribute 'xsi:nil'");
24989
0
    return (-1);
24990
0
      }
24991
0
      if (ret == 0) {
24992
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
24993
        /*
24994
        * cvc-elt (3.3.4) : 3.1
24995
        */
24996
0
        VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
24997
0
      "The element is not 'nillable'");
24998
        /* Does not return an error on purpose. */
24999
0
    } else {
25000
0
        if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25001
      /*
25002
      * cvc-elt (3.3.4) : 3.2.2
25003
      */
25004
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25005
0
          (elemDecl->value != NULL)) {
25006
0
          VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25007
0
        "The element cannot be 'nilled' because "
25008
0
        "there is a fixed value constraint defined "
25009
0
        "for it");
25010
           /* Does not return an error on purpose. */
25011
0
      } else
25012
0
          vctxt->inode->flags |=
25013
0
        XML_SCHEMA_ELEM_INFO_NILLED;
25014
0
        }
25015
0
    }
25016
0
      }
25017
0
  }
25018
  /*
25019
  * cvc-elt (3.3.4) : 4
25020
  * Handle 'xsi:type'.
25021
  */
25022
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25023
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25024
0
  if (iattr) {
25025
0
      xmlSchemaTypePtr localType = NULL;
25026
25027
0
      ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25028
0
    elemDecl);
25029
0
      if (ret != 0) {
25030
0
    if (ret == -1) {
25031
0
        VERROR_INT("xmlSchemaValidateElemDecl",
25032
0
      "calling xmlSchemaProcessXSIType() to "
25033
0
      "process the attribute 'xsi:type'");
25034
0
        return (-1);
25035
0
    }
25036
    /* Does not return an error on purpose. */
25037
0
      }
25038
0
      if (localType != NULL) {
25039
0
    vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25040
0
    actualType = localType;
25041
0
      }
25042
0
  }
25043
0
    }
25044
    /*
25045
    * IDC: Register identity-constraint XPath matchers.
25046
    */
25047
0
    if ((elemDecl->idcs != NULL) &&
25048
0
  (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25049
0
      return (-1);
25050
    /*
25051
    * No actual type definition.
25052
    */
25053
0
    if (actualType == NULL) {
25054
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25055
0
      "The type definition is absent");
25056
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25057
0
    }
25058
    /*
25059
    * Remember the actual type definition.
25060
    */
25061
0
    vctxt->inode->typeDef = actualType;
25062
25063
0
    return (0);
25064
0
}
25065
25066
static int
25067
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25068
0
{
25069
0
    xmlSchemaAttrInfoPtr iattr;
25070
0
    int ret = 0, i;
25071
25072
    /*
25073
    * SPEC cvc-type (3.1.1)
25074
    * "The attributes of must be empty, excepting those whose namespace
25075
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25076
    * whose local name is one of type, nil, schemaLocation or
25077
    * noNamespaceSchemaLocation."
25078
    */
25079
0
    if (vctxt->nbAttrInfos == 0)
25080
0
  return (0);
25081
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25082
0
  iattr = vctxt->attrInfos[i];
25083
0
  if (! iattr->metaType) {
25084
0
      ACTIVATE_ATTRIBUTE(iattr)
25085
0
      xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25086
0
    XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25087
0
      ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25088
0
        }
25089
0
    }
25090
0
    ACTIVATE_ELEM
25091
0
    return (ret);
25092
0
}
25093
25094
/*
25095
* Cleanup currently used attribute infos.
25096
*/
25097
static void
25098
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25099
0
{
25100
0
    int i;
25101
0
    xmlSchemaAttrInfoPtr attr;
25102
25103
0
    if (vctxt->nbAttrInfos == 0)
25104
0
  return;
25105
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25106
0
  attr = vctxt->attrInfos[i];
25107
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25108
0
      if (attr->localName != NULL)
25109
0
    xmlFree((xmlChar *) attr->localName);
25110
0
      if (attr->nsName != NULL)
25111
0
    xmlFree((xmlChar *) attr->nsName);
25112
0
  }
25113
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25114
0
      if (attr->value != NULL)
25115
0
    xmlFree((xmlChar *) attr->value);
25116
0
  }
25117
0
  if (attr->val != NULL) {
25118
0
      xmlSchemaFreeValue(attr->val);
25119
0
      attr->val = NULL;
25120
0
  }
25121
0
  memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25122
0
    }
25123
0
    vctxt->nbAttrInfos = 0;
25124
0
}
25125
25126
/*
25127
* 3.4.4 Complex Type Definition Validation Rules
25128
*   Element Locally Valid (Complex Type) (cvc-complex-type)
25129
* 3.2.4 Attribute Declaration Validation Rules
25130
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
25131
*   Attribute Locally Valid (Use) (cvc-au)
25132
*
25133
* Only "assessed" attribute information items will be visible to
25134
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25135
*/
25136
static int
25137
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25138
0
{
25139
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef;
25140
0
    xmlSchemaItemListPtr attrUseList;
25141
0
    xmlSchemaAttributeUsePtr attrUse = NULL;
25142
0
    xmlSchemaAttributePtr attrDecl = NULL;
25143
0
    xmlSchemaAttrInfoPtr iattr, tmpiattr;
25144
0
    int i, j, found, nbAttrs, nbUses;
25145
0
    int xpathRes = 0, res, wildIDs = 0, fixed;
25146
0
    xmlNodePtr defAttrOwnerElem = NULL;
25147
25148
    /*
25149
    * SPEC (cvc-attribute)
25150
    * (1) "The declaration must not be `absent` (see Missing
25151
    * Sub-components ($5.3) for how this can fail to be
25152
    * the case)."
25153
    * (2) "Its {type definition} must not be absent."
25154
    *
25155
    * NOTE (1) + (2): This is not handled here, since we currently do not
25156
    * allow validation against schemas which have missing sub-components.
25157
    *
25158
    * SPEC (cvc-complex-type)
25159
    * (3) "For each attribute information item in the element information
25160
    * item's [attributes] excepting those whose [namespace name] is
25161
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25162
    * [local name] is one of type, nil, schemaLocation or
25163
    * noNamespaceSchemaLocation, the appropriate case among the following
25164
    * must be true:
25165
    *
25166
    */
25167
0
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25168
    /*
25169
    * @nbAttrs is the number of attributes present in the instance.
25170
    */
25171
0
    nbAttrs = vctxt->nbAttrInfos;
25172
0
    if (attrUseList != NULL)
25173
0
  nbUses = attrUseList->nbItems;
25174
0
    else
25175
0
  nbUses = 0;
25176
0
    for (i = 0; i < nbUses; i++) {
25177
0
        found = 0;
25178
0
  attrUse = attrUseList->items[i];
25179
0
  attrDecl = WXS_ATTRUSE_DECL(attrUse);
25180
0
        for (j = 0; j < nbAttrs; j++) {
25181
0
      iattr = vctxt->attrInfos[j];
25182
      /*
25183
      * SPEC (cvc-complex-type) (3)
25184
      * Skip meta attributes.
25185
      */
25186
0
      if (iattr->metaType)
25187
0
    continue;
25188
0
      if (iattr->localName[0] != attrDecl->name[0])
25189
0
    continue;
25190
0
      if (!xmlStrEqual(iattr->localName, attrDecl->name))
25191
0
    continue;
25192
0
      if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25193
0
    continue;
25194
0
      found = 1;
25195
      /*
25196
      * SPEC (cvc-complex-type)
25197
      * (3.1) "If there is among the {attribute uses} an attribute
25198
      * use with an {attribute declaration} whose {name} matches
25199
      * the attribute information item's [local name] and whose
25200
      * {target namespace} is identical to the attribute information
25201
      * item's [namespace name] (where an `absent` {target namespace}
25202
      * is taken to be identical to a [namespace name] with no value),
25203
      * then the attribute information must be `valid` with respect
25204
      * to that attribute use as per Attribute Locally Valid (Use)
25205
      * ($3.5.4). In this case the {attribute declaration} of that
25206
      * attribute use is the `context-determined declaration` for the
25207
      * attribute information item with respect to Schema-Validity
25208
      * Assessment (Attribute) ($3.2.4) and
25209
      * Assessment Outcome (Attribute) ($3.2.5).
25210
      */
25211
0
      iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25212
0
      iattr->use = attrUse;
25213
      /*
25214
      * Context-determined declaration.
25215
      */
25216
0
      iattr->decl = attrDecl;
25217
0
      iattr->typeDef = attrDecl->subtypes;
25218
0
      break;
25219
0
  }
25220
25221
0
  if (found)
25222
0
      continue;
25223
25224
0
  if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25225
      /*
25226
      * Handle non-existent, required attributes.
25227
      *
25228
      * SPEC (cvc-complex-type)
25229
      * (4) "The {attribute declaration} of each attribute use in
25230
      * the {attribute uses} whose {required} is true matches one
25231
      * of the attribute information items in the element information
25232
      * item's [attributes] as per clause 3.1 above."
25233
      */
25234
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25235
0
      if (tmpiattr == NULL) {
25236
0
    VERROR_INT(
25237
0
        "xmlSchemaVAttributesComplex",
25238
0
        "calling xmlSchemaGetFreshAttrInfo()");
25239
0
    return (-1);
25240
0
      }
25241
0
      tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25242
0
      tmpiattr->use = attrUse;
25243
0
      tmpiattr->decl = attrDecl;
25244
0
  } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25245
0
      ((attrUse->defValue != NULL) ||
25246
0
       (attrDecl->defValue != NULL))) {
25247
      /*
25248
      * Handle non-existent, optional, default/fixed attributes.
25249
      */
25250
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25251
0
      if (tmpiattr == NULL) {
25252
0
    VERROR_INT(
25253
0
        "xmlSchemaVAttributesComplex",
25254
0
        "calling xmlSchemaGetFreshAttrInfo()");
25255
0
    return (-1);
25256
0
      }
25257
0
      tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25258
0
      tmpiattr->use = attrUse;
25259
0
      tmpiattr->decl = attrDecl;
25260
0
      tmpiattr->typeDef = attrDecl->subtypes;
25261
0
      tmpiattr->localName = attrDecl->name;
25262
0
      tmpiattr->nsName = attrDecl->targetNamespace;
25263
0
  }
25264
0
    }
25265
25266
0
    if (vctxt->nbAttrInfos == 0)
25267
0
  return (0);
25268
    /*
25269
    * Validate against the wildcard.
25270
    */
25271
0
    if (type->attributeWildcard != NULL) {
25272
  /*
25273
  * SPEC (cvc-complex-type)
25274
  * (3.2.1) "There must be an {attribute wildcard}."
25275
  */
25276
0
  for (i = 0; i < nbAttrs; i++) {
25277
0
      iattr = vctxt->attrInfos[i];
25278
      /*
25279
      * SPEC (cvc-complex-type) (3)
25280
      * Skip meta attributes.
25281
      */
25282
0
      if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25283
0
    continue;
25284
      /*
25285
      * SPEC (cvc-complex-type)
25286
      * (3.2.2) "The attribute information item must be `valid` with
25287
      * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25288
      *
25289
      * SPEC Item Valid (Wildcard) (cvc-wildcard)
25290
      * "... its [namespace name] must be `valid` with respect to
25291
      * the wildcard constraint, as defined in Wildcard allows
25292
      * Namespace Name ($3.10.4)."
25293
      */
25294
0
      if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25295
0
        iattr->nsName) == 0) {
25296
    /*
25297
    * Handle processContents.
25298
    *
25299
    * SPEC (cvc-wildcard):
25300
    * processContents | context-determined declaration:
25301
    * "strict"          "mustFind"
25302
    * "lax"             "none"
25303
    * "skip"            "skip"
25304
    */
25305
0
    if (type->attributeWildcard->processContents ==
25306
0
        XML_SCHEMAS_ANY_SKIP) {
25307
         /*
25308
        * context-determined declaration = "skip"
25309
        *
25310
        * SPEC PSVI Assessment Outcome (Attribute)
25311
        * [validity] = "notKnown"
25312
        * [validation attempted] = "none"
25313
        */
25314
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25315
0
        continue;
25316
0
    }
25317
    /*
25318
    * Find an attribute declaration.
25319
    */
25320
0
    iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25321
0
        iattr->localName, iattr->nsName);
25322
0
    if (iattr->decl != NULL) {
25323
0
        iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25324
        /*
25325
        * SPEC (cvc-complex-type)
25326
        * (5) "Let [Definition:]  the wild IDs be the set of
25327
        * all attribute information item to which clause 3.2
25328
        * applied and whose `validation` resulted in a
25329
        * `context-determined declaration` of mustFind or no
25330
        * `context-determined declaration` at all, and whose
25331
        * [local name] and [namespace name] resolve (as
25332
        * defined by QName resolution (Instance) ($3.15.4)) to
25333
        * an attribute declaration whose {type definition} is
25334
        * or is derived from ID. Then all of the following
25335
        * must be true:"
25336
        */
25337
0
        iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25338
0
        if (xmlSchemaIsDerivedFromBuiltInType(
25339
0
      iattr->typeDef, XML_SCHEMAS_ID)) {
25340
      /*
25341
      * SPEC (5.1) "There must be no more than one
25342
      * item in `wild IDs`."
25343
      */
25344
0
      if (wildIDs != 0) {
25345
          /* VAL TODO */
25346
0
          iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25347
0
          continue;
25348
0
      }
25349
0
      wildIDs++;
25350
      /*
25351
      * SPEC (cvc-complex-type)
25352
      * (5.2) "If `wild IDs` is non-empty, there must not
25353
      * be any attribute uses among the {attribute uses}
25354
      * whose {attribute declaration}'s {type definition}
25355
      * is or is derived from ID."
25356
      */
25357
0
                        if (attrUseList != NULL) {
25358
0
                            for (j = 0; j < attrUseList->nbItems; j++) {
25359
0
                                if (xmlSchemaIsDerivedFromBuiltInType(
25360
0
                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25361
0
                                    XML_SCHEMAS_ID)) {
25362
                                    /* URGENT VAL TODO: implement */
25363
0
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25364
0
                                    break;
25365
0
                                }
25366
0
                            }
25367
0
                        }
25368
0
        }
25369
0
    } else if (type->attributeWildcard->processContents ==
25370
0
        XML_SCHEMAS_ANY_LAX) {
25371
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25372
        /*
25373
        * SPEC PSVI Assessment Outcome (Attribute)
25374
        * [validity] = "notKnown"
25375
        * [validation attempted] = "none"
25376
        */
25377
0
    } else {
25378
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25379
0
    }
25380
0
      }
25381
0
  }
25382
0
    }
25383
25384
0
    if (vctxt->nbAttrInfos == 0)
25385
0
  return (0);
25386
25387
    /*
25388
    * Get the owner element; needed for creation of default attributes.
25389
    * This fixes bug #341337, reported by David Grohmann.
25390
    */
25391
0
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25392
0
  xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25393
0
  if (ielem && ielem->node && ielem->node->doc)
25394
0
      defAttrOwnerElem = ielem->node;
25395
0
    }
25396
    /*
25397
    * Validate values, create default attributes, evaluate IDCs.
25398
    */
25399
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25400
0
  iattr = vctxt->attrInfos[i];
25401
  /*
25402
  * VAL TODO: Note that we won't try to resolve IDCs to
25403
  * "lax" and "skip" validated attributes. Check what to
25404
  * do in this case.
25405
  */
25406
0
  if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25407
0
      (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25408
0
      continue;
25409
  /*
25410
  * VAL TODO: What to do if the type definition is missing?
25411
  */
25412
0
  if (iattr->typeDef == NULL) {
25413
0
      iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25414
0
      continue;
25415
0
  }
25416
25417
0
  ACTIVATE_ATTRIBUTE(iattr);
25418
0
  fixed = 0;
25419
0
  xpathRes = 0;
25420
25421
0
  if (vctxt->xpathStates != NULL) {
25422
      /*
25423
      * Evaluate IDCs.
25424
      */
25425
0
      xpathRes = xmlSchemaXPathEvaluate(vctxt,
25426
0
    XML_ATTRIBUTE_NODE);
25427
0
      if (xpathRes == -1) {
25428
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25429
0
        "calling xmlSchemaXPathEvaluate()");
25430
0
    goto internal_error;
25431
0
      }
25432
0
  }
25433
25434
0
  if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25435
      /*
25436
      * Default/fixed attributes.
25437
      * We need the value only if we need to resolve IDCs or
25438
      * will create default attributes.
25439
      */
25440
0
      if ((xpathRes) || (defAttrOwnerElem)) {
25441
0
    if (iattr->use->defValue != NULL) {
25442
0
        iattr->value = (xmlChar *) iattr->use->defValue;
25443
0
        iattr->val = iattr->use->defVal;
25444
0
    } else {
25445
0
        iattr->value = (xmlChar *) iattr->decl->defValue;
25446
0
        iattr->val = iattr->decl->defVal;
25447
0
    }
25448
    /*
25449
    * IDCs will consume the precomputed default value,
25450
    * so we need to clone it.
25451
    */
25452
0
    if (iattr->val == NULL) {
25453
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25454
0
      "default/fixed value on an attribute use was "
25455
0
      "not precomputed");
25456
0
        goto internal_error;
25457
0
    }
25458
0
    iattr->val = xmlSchemaCopyValue(iattr->val);
25459
0
    if (iattr->val == NULL) {
25460
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25461
0
      "calling xmlSchemaCopyValue()");
25462
0
        goto internal_error;
25463
0
    }
25464
0
      }
25465
      /*
25466
      * PSVI: Add the default attribute to the current element.
25467
      * VAL TODO: Should we use the *normalized* value? This currently
25468
      *   uses the *initial* value.
25469
      */
25470
25471
0
      if (defAttrOwnerElem) {
25472
0
    xmlChar *normValue;
25473
0
    const xmlChar *value;
25474
25475
0
    value = iattr->value;
25476
    /*
25477
    * Normalize the value.
25478
    */
25479
0
    normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25480
0
        iattr->value);
25481
0
    if (normValue != NULL)
25482
0
        value = BAD_CAST normValue;
25483
25484
0
    if (iattr->nsName == NULL) {
25485
0
        if (xmlNewProp(defAttrOwnerElem,
25486
0
      iattr->localName, value) == NULL) {
25487
0
      VERROR_INT("xmlSchemaVAttributesComplex",
25488
0
          "calling xmlNewProp()");
25489
0
      if (normValue != NULL)
25490
0
          xmlFree(normValue);
25491
0
      goto internal_error;
25492
0
        }
25493
0
    } else {
25494
0
        xmlNsPtr ns;
25495
25496
0
        ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25497
0
      defAttrOwnerElem, iattr->nsName);
25498
0
        if (ns == NULL) {
25499
0
      xmlChar prefix[13];
25500
0
      int counter = 0;
25501
25502
      /*
25503
      * Create a namespace declaration on the validation
25504
      * root node if no namespace declaration is in scope.
25505
      */
25506
0
      do {
25507
0
          snprintf((char *) prefix, 13, "p%d", counter++);
25508
0
          ns = xmlSearchNs(defAttrOwnerElem->doc,
25509
0
        defAttrOwnerElem, BAD_CAST prefix);
25510
0
          if (counter > 1000) {
25511
0
        VERROR_INT(
25512
0
            "xmlSchemaVAttributesComplex",
25513
0
            "could not compute a ns prefix for a "
25514
0
            "default/fixed attribute");
25515
0
        if (normValue != NULL)
25516
0
            xmlFree(normValue);
25517
0
        goto internal_error;
25518
0
          }
25519
0
      } while (ns != NULL);
25520
0
      ns = xmlNewNs(vctxt->validationRoot,
25521
0
          iattr->nsName, BAD_CAST prefix);
25522
0
        }
25523
        /*
25524
        * TODO:
25525
        * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25526
        * If we have QNames: do we need to ensure there's a
25527
        * prefix defined for the QName?
25528
        */
25529
0
        xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25530
0
    }
25531
0
    if (normValue != NULL)
25532
0
        xmlFree(normValue);
25533
0
      }
25534
      /*
25535
      * Go directly to IDC evaluation.
25536
      */
25537
0
      goto eval_idcs;
25538
0
  }
25539
  /*
25540
  * Validate the value.
25541
  */
25542
0
  if (vctxt->value != NULL) {
25543
      /*
25544
      * Free last computed value; just for safety reasons.
25545
      */
25546
0
      xmlSchemaFreeValue(vctxt->value);
25547
0
      vctxt->value = NULL;
25548
0
  }
25549
  /*
25550
  * Note that the attribute *use* can be unavailable, if
25551
  * the attribute was a wild attribute.
25552
  */
25553
0
  if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25554
0
      ((iattr->use != NULL) &&
25555
0
       (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25556
0
      fixed = 1;
25557
0
  else
25558
0
      fixed = 0;
25559
  /*
25560
  * SPEC (cvc-attribute)
25561
  * (3) "The item's `normalized value` must be locally `valid`
25562
  * with respect to that {type definition} as per
25563
  * String Valid ($3.14.4)."
25564
  *
25565
  * VAL TODO: Do we already have the
25566
  * "normalized attribute value" here?
25567
  */
25568
0
  if (xpathRes || fixed) {
25569
0
      iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25570
      /*
25571
      * Request a computed value.
25572
      */
25573
0
      res = xmlSchemaVCheckCVCSimpleType(
25574
0
    ACTXT_CAST vctxt,
25575
0
    iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25576
0
    1, 1, 0);
25577
0
  } else {
25578
0
      res = xmlSchemaVCheckCVCSimpleType(
25579
0
    ACTXT_CAST vctxt,
25580
0
    iattr->node, iattr->typeDef, iattr->value, NULL,
25581
0
    1, 0, 0);
25582
0
  }
25583
25584
0
  if (res != 0) {
25585
0
      if (res == -1) {
25586
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25587
0
        "calling xmlSchemaStreamValidateSimpleTypeValue()");
25588
0
    goto internal_error;
25589
0
      }
25590
0
      iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25591
      /*
25592
      * SPEC PSVI Assessment Outcome (Attribute)
25593
      * [validity] = "invalid"
25594
      */
25595
0
      goto eval_idcs;
25596
0
  }
25597
25598
0
  if (fixed) {
25599
      /*
25600
      * SPEC Attribute Locally Valid (Use) (cvc-au)
25601
      * "For an attribute information item to be `valid`
25602
      * with respect to an attribute use its *normalized*
25603
      * value must match the *canonical* lexical
25604
      * representation of the attribute use's {value
25605
      * constraint}value, if it is present and fixed."
25606
      *
25607
      * VAL TODO: The requirement for the *canonical* value
25608
      * will be removed in XML Schema 1.1.
25609
      */
25610
      /*
25611
      * SPEC Attribute Locally Valid (cvc-attribute)
25612
      * (4) "The item's *actual* value must match the *value* of
25613
      * the {value constraint}, if it is present and fixed."
25614
      */
25615
0
      if (iattr->val == NULL) {
25616
    /* VAL TODO: A value was not precomputed. */
25617
0
    goto eval_idcs;
25618
0
      }
25619
0
      if ((iattr->use != NULL) &&
25620
0
    (iattr->use->defValue != NULL)) {
25621
0
    if (iattr->use->defVal == NULL) {
25622
        /* VAL TODO: A default value was not precomputed. */
25623
0
        goto eval_idcs;
25624
0
    }
25625
0
    iattr->vcValue = iattr->use->defValue;
25626
    /*
25627
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25628
        (xmlSchemaWhitespaceValueType) ws,
25629
        attr->use->defVal,
25630
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25631
    */
25632
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25633
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25634
0
      } else {
25635
0
    if (iattr->decl->defVal == NULL) {
25636
        /* VAL TODO: A default value was not precomputed. */
25637
0
        goto eval_idcs;
25638
0
    }
25639
0
    iattr->vcValue = iattr->decl->defValue;
25640
    /*
25641
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25642
        (xmlSchemaWhitespaceValueType) ws,
25643
        attrDecl->defVal,
25644
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25645
    */
25646
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25647
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25648
0
      }
25649
      /*
25650
      * [validity] = "valid"
25651
      */
25652
0
  }
25653
0
eval_idcs:
25654
  /*
25655
  * Evaluate IDCs.
25656
  */
25657
0
  if (xpathRes) {
25658
0
      if (xmlSchemaXPathProcessHistory(vctxt,
25659
0
    vctxt->depth +1) == -1) {
25660
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25661
0
        "calling xmlSchemaXPathEvaluate()");
25662
0
    goto internal_error;
25663
0
      }
25664
0
  } else if (vctxt->xpathStates != NULL)
25665
0
      xmlSchemaXPathPop(vctxt);
25666
0
    }
25667
25668
    /*
25669
    * Report errors.
25670
    */
25671
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25672
0
  iattr = vctxt->attrInfos[i];
25673
0
  if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25674
0
      (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25675
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25676
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25677
0
      continue;
25678
0
  ACTIVATE_ATTRIBUTE(iattr);
25679
0
  switch (iattr->state) {
25680
0
      case XML_SCHEMAS_ATTR_ERR_MISSING: {
25681
0
        xmlChar *str = NULL;
25682
0
        ACTIVATE_ELEM;
25683
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
25684
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25685
0
      "The attribute '%s' is required but missing",
25686
0
      xmlSchemaFormatQName(&str,
25687
0
          iattr->decl->targetNamespace,
25688
0
          iattr->decl->name),
25689
0
      NULL);
25690
0
        FREE_AND_NULL(str)
25691
0
        break;
25692
0
    }
25693
0
      case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25694
0
    VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25695
0
        "The type definition is absent");
25696
0
    break;
25697
0
      case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25698
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25699
0
        XML_SCHEMAV_CVC_AU, NULL, NULL,
25700
0
        "The value '%s' does not match the fixed "
25701
0
        "value constraint '%s'",
25702
0
        iattr->value, iattr->vcValue);
25703
0
    break;
25704
0
      case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25705
0
    VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25706
0
        "No matching global attribute declaration available, but "
25707
0
        "demanded by the strict wildcard");
25708
0
    break;
25709
0
      case XML_SCHEMAS_ATTR_UNKNOWN:
25710
0
    if (iattr->metaType)
25711
0
        break;
25712
    /*
25713
    * MAYBE VAL TODO: One might report different error messages
25714
    * for the following errors.
25715
    */
25716
0
    if (type->attributeWildcard == NULL) {
25717
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25718
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25719
0
    } else {
25720
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25721
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25722
0
    }
25723
0
    break;
25724
0
      default:
25725
0
    break;
25726
0
  }
25727
0
    }
25728
25729
0
    ACTIVATE_ELEM;
25730
0
    return (0);
25731
0
internal_error:
25732
0
    ACTIVATE_ELEM;
25733
0
    return (-1);
25734
0
}
25735
25736
static int
25737
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25738
            int *skip)
25739
0
{
25740
0
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25741
    /*
25742
    * The namespace of the element was already identified to be
25743
    * matching the wildcard.
25744
    */
25745
0
    if ((skip == NULL) || (wild == NULL) ||
25746
0
  (wild->type != XML_SCHEMA_TYPE_ANY)) {
25747
0
  VERROR_INT("xmlSchemaValidateElemWildcard",
25748
0
      "bad arguments");
25749
0
  return (-1);
25750
0
    }
25751
0
    *skip = 0;
25752
0
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25753
  /*
25754
  * URGENT VAL TODO: Either we need to position the stream to the
25755
  * next sibling, or walk the whole subtree.
25756
  */
25757
0
  *skip = 1;
25758
0
  return (0);
25759
0
    }
25760
0
    {
25761
0
  xmlSchemaElementPtr decl = NULL;
25762
25763
0
  decl = xmlSchemaGetElem(vctxt->schema,
25764
0
      vctxt->inode->localName, vctxt->inode->nsName);
25765
0
  if (decl != NULL) {
25766
0
      vctxt->inode->decl = decl;
25767
0
      return (0);
25768
0
  }
25769
0
    }
25770
0
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25771
  /* VAL TODO: Change to proper error code. */
25772
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25773
0
      "No matching global element declaration available, but "
25774
0
      "demanded by the strict wildcard");
25775
0
  return (vctxt->err);
25776
0
    }
25777
0
    if (vctxt->nbAttrInfos != 0) {
25778
0
  xmlSchemaAttrInfoPtr iattr;
25779
  /*
25780
  * SPEC Validation Rule: Schema-Validity Assessment (Element)
25781
  * (1.2.1.2.1) - (1.2.1.2.3 )
25782
  *
25783
  * Use the xsi:type attribute for the type definition.
25784
  */
25785
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25786
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25787
0
  if (iattr != NULL) {
25788
0
      if (xmlSchemaProcessXSIType(vctxt, iattr,
25789
0
    &(vctxt->inode->typeDef), NULL) == -1) {
25790
0
    VERROR_INT("xmlSchemaValidateElemWildcard",
25791
0
        "calling xmlSchemaProcessXSIType() to "
25792
0
        "process the attribute 'xsi:nil'");
25793
0
    return (-1);
25794
0
      }
25795
      /*
25796
      * Don't return an error on purpose.
25797
      */
25798
0
      return (0);
25799
0
  }
25800
0
    }
25801
    /*
25802
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
25803
    *
25804
    * Fallback to "anyType".
25805
    */
25806
0
    vctxt->inode->typeDef =
25807
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25808
0
    return (0);
25809
0
}
25810
25811
/*
25812
* xmlSchemaCheckCOSValidDefault:
25813
*
25814
* This will be called if: not nilled, no content and a default/fixed
25815
* value is provided.
25816
*/
25817
25818
static int
25819
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25820
            const xmlChar *value,
25821
            xmlSchemaValPtr *val)
25822
0
{
25823
0
    int ret = 0;
25824
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25825
25826
    /*
25827
    * cos-valid-default:
25828
    * Schema Component Constraint: Element Default Valid (Immediate)
25829
    * For a string to be a valid default with respect to a type
25830
    * definition the appropriate case among the following must be true:
25831
    */
25832
0
    if WXS_IS_COMPLEX(inode->typeDef) {
25833
  /*
25834
  * Complex type.
25835
  *
25836
  * SPEC (2.1) "its {content type} must be a simple type definition
25837
  * or mixed."
25838
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
25839
  * type}'s particle must be `emptiable` as defined by
25840
  * Particle Emptiable ($3.9.6)."
25841
  */
25842
0
  if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25843
0
      ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25844
0
       (! WXS_EMPTIABLE(inode->typeDef)))) {
25845
0
      ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25846
      /* NOTE that this covers (2.2.2) as well. */
25847
0
      VERROR(ret, NULL,
25848
0
    "For a string to be a valid default, the type definition "
25849
0
    "must be a simple type or a complex type with simple content "
25850
0
    "or mixed content and a particle emptiable");
25851
0
      return(ret);
25852
0
  }
25853
0
    }
25854
    /*
25855
    * 1 If the type definition is a simple type definition, then the string
25856
    * must be `valid` with respect to that definition as defined by String
25857
    * Valid ($3.14.4).
25858
    *
25859
    * AND
25860
    *
25861
    * 2.2.1 If the {content type} is a simple type definition, then the
25862
    * string must be `valid` with respect to that simple type definition
25863
    * as defined by String Valid ($3.14.4).
25864
    */
25865
0
    if (WXS_IS_SIMPLE(inode->typeDef)) {
25866
25867
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25868
0
      NULL, inode->typeDef, value, val, 1, 1, 0);
25869
25870
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25871
25872
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25873
0
      NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25874
0
    }
25875
0
    if (ret < 0) {
25876
0
  VERROR_INT("xmlSchemaCheckCOSValidDefault",
25877
0
      "calling xmlSchemaVCheckCVCSimpleType()");
25878
0
    }
25879
0
    return (ret);
25880
0
}
25881
25882
static void
25883
xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
25884
             const xmlChar * name ATTRIBUTE_UNUSED,
25885
             void *transdata, void *inputdata)
25886
0
{
25887
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
25888
0
    xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
25889
0
    inode->decl = item;
25890
0
}
25891
25892
static int
25893
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25894
0
{
25895
0
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25896
0
    if (vctxt->inode == NULL) {
25897
0
  VERROR_INT("xmlSchemaValidatorPushElem",
25898
0
      "calling xmlSchemaGetFreshElemInfo()");
25899
0
  return (-1);
25900
0
    }
25901
0
    vctxt->nbAttrInfos = 0;
25902
0
    return (0);
25903
0
}
25904
25905
static int
25906
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25907
           xmlSchemaNodeInfoPtr inode,
25908
           xmlSchemaTypePtr type,
25909
           const xmlChar *value)
25910
0
{
25911
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25912
0
  return (xmlSchemaVCheckCVCSimpleType(
25913
0
      ACTXT_CAST vctxt, NULL,
25914
0
      type, value, &(inode->val), 1, 1, 0));
25915
0
    else
25916
0
  return (xmlSchemaVCheckCVCSimpleType(
25917
0
      ACTXT_CAST vctxt, NULL,
25918
0
      type, value, NULL, 1, 0, 0));
25919
0
}
25920
25921
25922
25923
/*
25924
* Process END of element.
25925
*/
25926
static int
25927
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25928
0
{
25929
0
    int ret = 0;
25930
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25931
25932
0
    if (vctxt->nbAttrInfos != 0)
25933
0
  xmlSchemaClearAttrInfos(vctxt);
25934
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25935
  /*
25936
  * This element was not expected;
25937
  * we will not validate child elements of broken parents.
25938
  * Skip validation of all content of the parent.
25939
  */
25940
0
  vctxt->skipDepth = vctxt->depth -1;
25941
0
  goto end_elem;
25942
0
    }
25943
0
    if ((inode->typeDef == NULL) ||
25944
0
  (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25945
  /*
25946
  * 1. the type definition might be missing if the element was
25947
  *    error prone
25948
  * 2. it might be abstract.
25949
  */
25950
0
  goto end_elem;
25951
0
    }
25952
    /*
25953
    * Check the content model.
25954
    */
25955
0
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
25956
0
  (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
25957
25958
  /*
25959
  * Workaround for "anyType".
25960
  */
25961
0
  if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
25962
0
      goto character_content;
25963
25964
0
  if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
25965
0
      xmlChar *values[10];
25966
0
      int terminal, nbval = 10, nbneg;
25967
25968
0
      if (inode->regexCtxt == NULL) {
25969
    /*
25970
    * Create the regex context.
25971
    */
25972
0
    inode->regexCtxt =
25973
0
        xmlRegNewExecCtxt(inode->typeDef->contModel,
25974
0
        xmlSchemaVContentModelCallback, vctxt);
25975
0
    if (inode->regexCtxt == NULL) {
25976
0
        VERROR_INT("xmlSchemaValidatorPopElem",
25977
0
      "failed to create a regex context");
25978
0
        goto internal_error;
25979
0
    }
25980
0
      }
25981
25982
      /*
25983
       * Do not check further content if the node has been nilled
25984
       */
25985
0
      if (INODE_NILLED(inode)) {
25986
0
    ret = 0;
25987
0
                goto skip_nilled;
25988
0
      }
25989
25990
      /*
25991
      * Get hold of the still expected content, since a further
25992
      * call to xmlRegExecPushString() will lose this information.
25993
      */
25994
0
      xmlRegExecNextValues(inode->regexCtxt,
25995
0
    &nbval, &nbneg, &values[0], &terminal);
25996
0
      ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
25997
0
      if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
25998
    /*
25999
    * Still missing something.
26000
    */
26001
0
    ret = 1;
26002
0
    inode->flags |=
26003
0
        XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26004
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26005
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26006
0
        "Missing child element(s)",
26007
0
        nbval, nbneg, values);
26008
0
      } else {
26009
    /*
26010
    * Content model is satisfied.
26011
    */
26012
0
    ret = 0;
26013
0
      }
26014
26015
0
  }
26016
0
    }
26017
26018
0
skip_nilled:
26019
26020
0
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26021
0
  goto end_elem;
26022
26023
0
character_content:
26024
26025
0
    if (vctxt->value != NULL) {
26026
0
  xmlSchemaFreeValue(vctxt->value);
26027
0
  vctxt->value = NULL;
26028
0
    }
26029
    /*
26030
    * Check character content.
26031
    */
26032
0
    if (inode->decl == NULL) {
26033
  /*
26034
  * Speedup if no declaration exists.
26035
  */
26036
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26037
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26038
0
    inode, inode->typeDef, inode->value);
26039
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26040
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26041
0
    inode, inode->typeDef->contentTypeDef,
26042
0
    inode->value);
26043
0
  }
26044
0
  if (ret < 0) {
26045
0
      VERROR_INT("xmlSchemaValidatorPopElem",
26046
0
    "calling xmlSchemaVCheckCVCSimpleType()");
26047
0
      goto internal_error;
26048
0
  }
26049
0
  goto end_elem;
26050
0
    }
26051
    /*
26052
    * cvc-elt (3.3.4) : 5
26053
    * The appropriate case among the following must be true:
26054
    */
26055
    /*
26056
    * cvc-elt (3.3.4) : 5.1
26057
    * If the declaration has a {value constraint},
26058
    * the item has neither element nor character [children] and
26059
    * clause 3.2 has not applied, then all of the following must be true:
26060
    */
26061
0
    if ((inode->decl->value != NULL) &&
26062
0
  (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26063
0
  (! INODE_NILLED(inode))) {
26064
  /*
26065
  * cvc-elt (3.3.4) : 5.1.1
26066
  * If the `actual type definition` is a `local type definition`
26067
  * then the canonical lexical representation of the {value constraint}
26068
  * value must be a valid default for the `actual type definition` as
26069
  * defined in Element Default Valid (Immediate) ($3.3.6).
26070
  */
26071
  /*
26072
  * NOTE: 'local' above means types acquired by xsi:type.
26073
  * NOTE: Although the *canonical* value is stated, it is not
26074
  * relevant if canonical or not. Additionally XML Schema 1.1
26075
  * will removed this requirement as well.
26076
  */
26077
0
  if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26078
26079
0
      ret = xmlSchemaCheckCOSValidDefault(vctxt,
26080
0
    inode->decl->value, &(inode->val));
26081
0
      if (ret != 0) {
26082
0
    if (ret < 0) {
26083
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26084
0
      "calling xmlSchemaCheckCOSValidDefault()");
26085
0
        goto internal_error;
26086
0
    }
26087
0
    goto end_elem;
26088
0
      }
26089
      /*
26090
      * Stop here, to avoid redundant validation of the value
26091
      * (see following).
26092
      */
26093
0
      goto default_psvi;
26094
0
  }
26095
  /*
26096
  * cvc-elt (3.3.4) : 5.1.2
26097
  * The element information item with the canonical lexical
26098
  * representation of the {value constraint} value used as its
26099
  * `normalized value` must be `valid` with respect to the
26100
  * `actual type definition` as defined by Element Locally Valid (Type)
26101
  * ($3.3.4).
26102
  */
26103
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26104
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26105
0
    inode, inode->typeDef, inode->decl->value);
26106
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26107
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26108
0
    inode, inode->typeDef->contentTypeDef,
26109
0
    inode->decl->value);
26110
0
  }
26111
0
  if (ret != 0) {
26112
0
      if (ret < 0) {
26113
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26114
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26115
0
    goto internal_error;
26116
0
      }
26117
0
      goto end_elem;
26118
0
  }
26119
26120
0
default_psvi:
26121
  /*
26122
  * PSVI: Create a text node on the instance element.
26123
  */
26124
0
  if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26125
0
      (inode->node != NULL)) {
26126
0
      xmlNodePtr textChild;
26127
0
      xmlChar *normValue;
26128
      /*
26129
      * VAL TODO: Normalize the value.
26130
      */
26131
0
      normValue = xmlSchemaNormalizeValue(inode->typeDef,
26132
0
    inode->decl->value);
26133
0
      if (normValue != NULL) {
26134
0
    textChild = xmlNewDocText(inode->node->doc,
26135
0
                        BAD_CAST normValue);
26136
0
    xmlFree(normValue);
26137
0
      } else
26138
0
    textChild = xmlNewDocText(inode->node->doc,
26139
0
                        inode->decl->value);
26140
0
      if (textChild == NULL) {
26141
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26142
0
        "calling xmlNewDocText()");
26143
0
    goto internal_error;
26144
0
      } else
26145
0
    xmlAddChild(inode->node, textChild);
26146
0
  }
26147
26148
0
    } else if (! INODE_NILLED(inode)) {
26149
  /*
26150
  * 5.2.1 The element information item must be `valid` with respect
26151
  * to the `actual type definition` as defined by Element Locally
26152
  * Valid (Type) ($3.3.4).
26153
  */
26154
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26155
       /*
26156
      * SPEC (cvc-type) (3.1)
26157
      * "If the type definition is a simple type definition, ..."
26158
      * (3.1.3) "If clause 3.2 of Element Locally Valid
26159
      * (Element) ($3.3.4) did not apply, then the `normalized value`
26160
      * must be `valid` with respect to the type definition as defined
26161
      * by String Valid ($3.14.4).
26162
      */
26163
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26164
0
        inode, inode->typeDef, inode->value);
26165
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26166
      /*
26167
      * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26168
      * definition, then the element information item must be
26169
      * `valid` with respect to the type definition as per
26170
      * Element Locally Valid (Complex Type) ($3.4.4);"
26171
      *
26172
      * SPEC (cvc-complex-type) (2.2)
26173
      * "If the {content type} is a simple type definition, ...
26174
      * the `normalized value` of the element information item is
26175
      * `valid` with respect to that simple type definition as
26176
      * defined by String Valid ($3.14.4)."
26177
      */
26178
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26179
0
    inode, inode->typeDef->contentTypeDef, inode->value);
26180
0
  }
26181
0
  if (ret != 0) {
26182
0
      if (ret < 0) {
26183
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26184
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26185
0
    goto internal_error;
26186
0
      }
26187
0
      goto end_elem;
26188
0
  }
26189
  /*
26190
  * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26191
  * not applied, all of the following must be true:
26192
  */
26193
0
  if ((inode->decl->value != NULL) &&
26194
0
      (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26195
26196
      /*
26197
      * TODO: We will need a computed value, when comparison is
26198
      * done on computed values.
26199
      */
26200
      /*
26201
      * 5.2.2.1 The element information item must have no element
26202
      * information item [children].
26203
      */
26204
0
      if (inode->flags &
26205
0
        XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26206
0
    ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26207
0
    VERROR(ret, NULL,
26208
0
        "The content must not contain element nodes since "
26209
0
        "there is a fixed value constraint");
26210
0
    goto end_elem;
26211
0
      } else {
26212
    /*
26213
    * 5.2.2.2 The appropriate case among the following must
26214
    * be true:
26215
    */
26216
0
    if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26217
        /*
26218
        * 5.2.2.2.1 If the {content type} of the `actual type
26219
        * definition` is mixed, then the *initial value* of the
26220
        * item must match the canonical lexical representation
26221
        * of the {value constraint} value.
26222
        *
26223
        * ... the *initial value* of an element information
26224
        * item is the string composed of, in order, the
26225
        * [character code] of each character information item in
26226
        * the [children] of that element information item.
26227
        */
26228
0
        if (! xmlStrEqual(inode->value, inode->decl->value)){
26229
      /*
26230
      * VAL TODO: Report invalid & expected values as well.
26231
      * VAL TODO: Implement the canonical stuff.
26232
      */
26233
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26234
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26235
0
          ret, NULL, NULL,
26236
0
          "The initial value '%s' does not match the fixed "
26237
0
          "value constraint '%s'",
26238
0
          inode->value, inode->decl->value);
26239
0
      goto end_elem;
26240
0
        }
26241
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26242
        /*
26243
        * 5.2.2.2.2 If the {content type} of the `actual type
26244
        * definition` is a simple type definition, then the
26245
        * *actual value* of the item must match the canonical
26246
        * lexical representation of the {value constraint} value.
26247
        */
26248
        /*
26249
        * VAL TODO: *actual value* is the normalized value, impl.
26250
        *           this.
26251
        * VAL TODO: Report invalid & expected values as well.
26252
        * VAL TODO: Implement a comparison with the computed values.
26253
        */
26254
0
        if (! xmlStrEqual(inode->value,
26255
0
          inode->decl->value)) {
26256
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26257
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26258
0
          ret, NULL, NULL,
26259
0
          "The actual value '%s' does not match the fixed "
26260
0
          "value constraint '%s'",
26261
0
          inode->value,
26262
0
          inode->decl->value);
26263
0
      goto end_elem;
26264
0
        }
26265
0
    }
26266
0
      }
26267
0
  }
26268
0
    }
26269
26270
0
end_elem:
26271
0
    if (vctxt->depth < 0) {
26272
  /* TODO: raise error? */
26273
0
  return (0);
26274
0
    }
26275
0
    if (vctxt->depth == vctxt->skipDepth)
26276
0
  vctxt->skipDepth = -1;
26277
    /*
26278
    * Evaluate the history of XPath state objects.
26279
    */
26280
0
    if (inode->appliedXPath &&
26281
0
  (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26282
0
  goto internal_error;
26283
    /*
26284
    * MAYBE TODO:
26285
    * SPEC (6) "The element information item must be `valid` with
26286
    * respect to each of the {identity-constraint definitions} as per
26287
    * Identity-constraint Satisfied ($3.11.4)."
26288
    */
26289
    /*
26290
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26291
    *   need to be built in any case.
26292
    *   We will currently build IDC node-tables and bubble them only if
26293
    *   keyrefs do exist.
26294
    */
26295
26296
    /*
26297
    * Add the current IDC target-nodes to the IDC node-tables.
26298
    */
26299
0
    if ((inode->idcMatchers != NULL) &&
26300
0
  (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26301
0
    {
26302
0
  if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26303
0
      goto internal_error;
26304
0
    }
26305
    /*
26306
    * Validate IDC keyrefs.
26307
    */
26308
0
    if (vctxt->inode->hasKeyrefs)
26309
0
  if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26310
0
      goto internal_error;
26311
    /*
26312
    * Merge/free the IDC table.
26313
    */
26314
0
    if (inode->idcTable != NULL) {
26315
0
  if ((vctxt->depth > 0) &&
26316
0
      (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26317
0
  {
26318
      /*
26319
      * Merge the IDC node table with the table of the parent node.
26320
      */
26321
0
      if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26322
0
    goto internal_error;
26323
0
  }
26324
0
    }
26325
    /*
26326
    * Clear the current ielem.
26327
    * VAL TODO: Don't free the PSVI IDC tables if they are
26328
    * requested for the PSVI.
26329
    */
26330
0
    xmlSchemaClearElemInfo(vctxt, inode);
26331
    /*
26332
    * Skip further processing if we are on the validation root.
26333
    */
26334
0
    if (vctxt->depth == 0) {
26335
0
  vctxt->depth--;
26336
0
  vctxt->inode = NULL;
26337
0
  return (0);
26338
0
    }
26339
    /*
26340
    * Reset the keyrefDepth if needed.
26341
    */
26342
0
    if (vctxt->aidcs != NULL) {
26343
0
  xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26344
0
  do {
26345
0
      if (aidc->keyrefDepth == vctxt->depth) {
26346
    /*
26347
    * A 'keyrefDepth' of a key/unique IDC matches the current
26348
    * depth, this means that we are leaving the scope of the
26349
    * top-most keyref IDC which refers to this IDC.
26350
    */
26351
0
    aidc->keyrefDepth = -1;
26352
0
      }
26353
0
      aidc = aidc->next;
26354
0
  } while (aidc != NULL);
26355
0
    }
26356
0
    vctxt->depth--;
26357
0
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
26358
    /*
26359
    * VAL TODO: 7 If the element information item is the `validation root`, it must be
26360
    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26361
    */
26362
0
    return (ret);
26363
26364
0
internal_error:
26365
0
    vctxt->err = -1;
26366
0
    return (-1);
26367
0
}
26368
26369
/*
26370
* 3.4.4 Complex Type Definition Validation Rules
26371
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26372
*/
26373
static int
26374
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26375
0
{
26376
0
    xmlSchemaNodeInfoPtr pielem;
26377
0
    xmlSchemaTypePtr ptype;
26378
0
    int ret = 0;
26379
26380
0
    if (vctxt->depth <= 0) {
26381
0
  VERROR_INT("xmlSchemaValidateChildElem",
26382
0
      "not intended for the validation root");
26383
0
  return (-1);
26384
0
    }
26385
0
    pielem = vctxt->elemInfos[vctxt->depth -1];
26386
0
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26387
0
  pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26388
    /*
26389
    * Handle 'nilled' elements.
26390
    */
26391
0
    if (INODE_NILLED(pielem)) {
26392
  /*
26393
  * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26394
  */
26395
0
  ACTIVATE_PARENT_ELEM;
26396
0
  ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26397
0
  VERROR(ret, NULL,
26398
0
      "Neither character nor element content is allowed, "
26399
0
      "because the element was 'nilled'");
26400
0
  ACTIVATE_ELEM;
26401
0
  goto unexpected_elem;
26402
0
    }
26403
26404
0
    ptype = pielem->typeDef;
26405
26406
0
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26407
  /*
26408
  * Workaround for "anyType": we have currently no content model
26409
  * assigned for "anyType", so handle it explicitly.
26410
  * "anyType" has an unbounded, lax "any" wildcard.
26411
  */
26412
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26413
0
      vctxt->inode->localName,
26414
0
      vctxt->inode->nsName);
26415
26416
0
  if (vctxt->inode->decl == NULL) {
26417
0
      xmlSchemaAttrInfoPtr iattr;
26418
      /*
26419
      * Process "xsi:type".
26420
      * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26421
      */
26422
0
      iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26423
0
    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26424
0
      if (iattr != NULL) {
26425
0
    ret = xmlSchemaProcessXSIType(vctxt, iattr,
26426
0
        &(vctxt->inode->typeDef), NULL);
26427
0
    if (ret != 0) {
26428
0
        if (ret == -1) {
26429
0
      VERROR_INT("xmlSchemaValidateChildElem",
26430
0
          "calling xmlSchemaProcessXSIType() to "
26431
0
          "process the attribute 'xsi:nil'");
26432
0
      return (-1);
26433
0
        }
26434
0
        return (ret);
26435
0
    }
26436
0
      } else {
26437
     /*
26438
     * Fallback to "anyType".
26439
     *
26440
     * SPEC (cvc-assess-elt)
26441
     * "If the item cannot be `strictly assessed`, [...]
26442
     * an element information item's schema validity may be laxly
26443
     * assessed if its `context-determined declaration` is not
26444
     * skip by `validating` with respect to the `ur-type
26445
     * definition` as per Element Locally Valid (Type) ($3.3.4)."
26446
    */
26447
0
    vctxt->inode->typeDef =
26448
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26449
0
      }
26450
0
  }
26451
0
  return (0);
26452
0
    }
26453
26454
0
    switch (ptype->contentType) {
26455
0
  case XML_SCHEMA_CONTENT_EMPTY:
26456
      /*
26457
      * SPEC (2.1) "If the {content type} is empty, then the
26458
      * element information item has no character or element
26459
      * information item [children]."
26460
      */
26461
0
      ACTIVATE_PARENT_ELEM
26462
0
      ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26463
0
      VERROR(ret, NULL,
26464
0
    "Element content is not allowed, "
26465
0
    "because the content type is empty");
26466
0
      ACTIVATE_ELEM
26467
0
      goto unexpected_elem;
26468
0
      break;
26469
26470
0
  case XML_SCHEMA_CONTENT_MIXED:
26471
0
        case XML_SCHEMA_CONTENT_ELEMENTS: {
26472
0
      xmlRegExecCtxtPtr regexCtxt;
26473
0
      xmlChar *values[10];
26474
0
      int terminal, nbval = 10, nbneg;
26475
26476
      /* VAL TODO: Optimized "anyType" validation.*/
26477
26478
0
      if (ptype->contModel == NULL) {
26479
0
    VERROR_INT("xmlSchemaValidateChildElem",
26480
0
        "type has elem content but no content model");
26481
0
    return (-1);
26482
0
      }
26483
      /*
26484
      * Safety belt for evaluation if the cont. model was already
26485
      * examined to be invalid.
26486
      */
26487
0
      if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26488
0
    VERROR_INT("xmlSchemaValidateChildElem",
26489
0
        "validating elem, but elem content is already invalid");
26490
0
    return (-1);
26491
0
      }
26492
26493
0
      regexCtxt = pielem->regexCtxt;
26494
0
      if (regexCtxt == NULL) {
26495
    /*
26496
    * Create the regex context.
26497
    */
26498
0
    regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26499
0
        xmlSchemaVContentModelCallback, vctxt);
26500
0
    if (regexCtxt == NULL) {
26501
0
        VERROR_INT("xmlSchemaValidateChildElem",
26502
0
      "failed to create a regex context");
26503
0
        return (-1);
26504
0
    }
26505
0
    pielem->regexCtxt = regexCtxt;
26506
0
      }
26507
26508
      /*
26509
      * SPEC (2.4) "If the {content type} is element-only or mixed,
26510
      * then the sequence of the element information item's
26511
      * element information item [children], if any, taken in
26512
      * order, is `valid` with respect to the {content type}'s
26513
      * particle, as defined in Element Sequence Locally Valid
26514
      * (Particle) ($3.9.4)."
26515
      */
26516
0
      ret = xmlRegExecPushString2(regexCtxt,
26517
0
    vctxt->inode->localName,
26518
0
    vctxt->inode->nsName,
26519
0
    vctxt->inode);
26520
0
      if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26521
0
    VERROR_INT("xmlSchemaValidateChildElem",
26522
0
        "calling xmlRegExecPushString2()");
26523
0
    return (-1);
26524
0
      }
26525
0
      if (ret < 0) {
26526
0
    xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26527
0
        &values[0], &terminal);
26528
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26529
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26530
0
        "This element is not expected",
26531
0
        nbval, nbneg, values);
26532
0
    ret = vctxt->err;
26533
0
    goto unexpected_elem;
26534
0
      } else
26535
0
    ret = 0;
26536
0
  }
26537
0
      break;
26538
0
  case XML_SCHEMA_CONTENT_SIMPLE:
26539
0
  case XML_SCHEMA_CONTENT_BASIC:
26540
0
      ACTIVATE_PARENT_ELEM
26541
0
      if (WXS_IS_COMPLEX(ptype)) {
26542
    /*
26543
    * SPEC (cvc-complex-type) (2.2)
26544
    * "If the {content type} is a simple type definition, then
26545
    * the element information item has no element information
26546
    * item [children], ..."
26547
    */
26548
0
    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26549
0
    VERROR(ret, NULL, "Element content is not allowed, "
26550
0
        "because the content type is a simple type definition");
26551
0
      } else {
26552
    /*
26553
    * SPEC (cvc-type) (3.1.2) "The element information item must
26554
    * have no element information item [children]."
26555
    */
26556
0
    ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26557
0
    VERROR(ret, NULL, "Element content is not allowed, "
26558
0
        "because the type definition is simple");
26559
0
      }
26560
0
      ACTIVATE_ELEM
26561
0
      ret = vctxt->err;
26562
0
      goto unexpected_elem;
26563
0
      break;
26564
26565
0
  default:
26566
0
      break;
26567
0
    }
26568
0
    return (ret);
26569
0
unexpected_elem:
26570
    /*
26571
    * Pop this element and set the skipDepth to skip
26572
    * all further content of the parent element.
26573
    */
26574
0
    vctxt->skipDepth = vctxt->depth;
26575
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26576
0
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26577
0
    return (ret);
26578
0
}
26579
26580
0
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26581
0
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26582
0
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26583
26584
static int
26585
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26586
      int nodeType, const xmlChar *value, int len,
26587
      int mode, int *consumed)
26588
0
{
26589
    /*
26590
    * Unfortunately we have to duplicate the text sometimes.
26591
    * OPTIMIZE: Maybe we could skip it, if:
26592
    *   1. content type is simple
26593
    *   2. whitespace is "collapse"
26594
    *   3. it consists of whitespace only
26595
    *
26596
    * Process character content.
26597
    */
26598
0
    if (consumed != NULL)
26599
0
  *consumed = 0;
26600
0
    if (INODE_NILLED(vctxt->inode)) {
26601
  /*
26602
  * SPEC cvc-elt (3.3.4 - 3.2.1)
26603
  * "The element information item must have no character or
26604
  * element information item [children]."
26605
  */
26606
0
  VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26607
0
      "Neither character nor element content is allowed "
26608
0
      "because the element is 'nilled'");
26609
0
  return (vctxt->err);
26610
0
    }
26611
    /*
26612
    * SPEC (2.1) "If the {content type} is empty, then the
26613
    * element information item has no character or element
26614
    * information item [children]."
26615
    */
26616
0
    if (vctxt->inode->typeDef->contentType ==
26617
0
      XML_SCHEMA_CONTENT_EMPTY) {
26618
0
  VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26619
0
      "Character content is not allowed, "
26620
0
      "because the content type is empty");
26621
0
  return (vctxt->err);
26622
0
    }
26623
26624
0
    if (vctxt->inode->typeDef->contentType ==
26625
0
      XML_SCHEMA_CONTENT_ELEMENTS) {
26626
0
  if ((nodeType != XML_TEXT_NODE) ||
26627
0
      (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26628
      /*
26629
      * SPEC cvc-complex-type (2.3)
26630
      * "If the {content type} is element-only, then the
26631
      * element information item has no character information
26632
      * item [children] other than those whose [character
26633
      * code] is defined as a white space in [XML 1.0 (Second
26634
      * Edition)]."
26635
      */
26636
0
      VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26637
0
    "Character content other than whitespace is not allowed "
26638
0
    "because the content type is 'element-only'");
26639
0
      return (vctxt->err);
26640
0
  }
26641
0
  return (0);
26642
0
    }
26643
26644
0
    if ((value == NULL) || (value[0] == 0))
26645
0
  return (0);
26646
    /*
26647
    * Save the value.
26648
    * NOTE that even if the content type is *mixed*, we need the
26649
    * *initial value* for default/fixed value constraints.
26650
    */
26651
0
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26652
0
  ((vctxt->inode->decl == NULL) ||
26653
0
  (vctxt->inode->decl->value == NULL)))
26654
0
  return (0);
26655
26656
0
    if (vctxt->inode->value == NULL) {
26657
  /*
26658
  * Set the value.
26659
  */
26660
0
  switch (mode) {
26661
0
      case XML_SCHEMA_PUSH_TEXT_PERSIST:
26662
    /*
26663
    * When working on a tree.
26664
    */
26665
0
    vctxt->inode->value = value;
26666
0
    break;
26667
0
      case XML_SCHEMA_PUSH_TEXT_CREATED:
26668
    /*
26669
    * When working with the reader.
26670
    * The value will be freed by the element info.
26671
    */
26672
0
    vctxt->inode->value = value;
26673
0
    if (consumed != NULL)
26674
0
        *consumed = 1;
26675
0
    vctxt->inode->flags |=
26676
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26677
0
    break;
26678
0
      case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26679
    /*
26680
    * When working with SAX.
26681
    * The value will be freed by the element info.
26682
    */
26683
0
    if (len != -1)
26684
0
        vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26685
0
    else
26686
0
        vctxt->inode->value = BAD_CAST xmlStrdup(value);
26687
0
    vctxt->inode->flags |=
26688
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26689
0
    break;
26690
0
      default:
26691
0
    break;
26692
0
  }
26693
0
    } else {
26694
0
  if (len < 0)
26695
0
      len = xmlStrlen(value);
26696
  /*
26697
  * Concat the value.
26698
  */
26699
0
  if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26700
0
      vctxt->inode->value = BAD_CAST xmlStrncat(
26701
0
    (xmlChar *) vctxt->inode->value, value, len);
26702
0
  } else {
26703
0
      vctxt->inode->value =
26704
0
    BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26705
0
      vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26706
0
  }
26707
0
    }
26708
26709
0
    return (0);
26710
0
}
26711
26712
static int
26713
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26714
0
{
26715
0
    int ret = 0;
26716
26717
0
    if ((vctxt->skipDepth != -1) &&
26718
0
  (vctxt->depth >= vctxt->skipDepth)) {
26719
0
  VERROR_INT("xmlSchemaValidateElem",
26720
0
      "in skip-state");
26721
0
  goto internal_error;
26722
0
    }
26723
0
    if (vctxt->xsiAssemble) {
26724
  /*
26725
  * We will stop validation if there was an error during
26726
  * dynamic schema construction.
26727
  * Note that we simply set @skipDepth to 0, this could
26728
  * mean that a streaming document via SAX would be
26729
  * still read to the end but it won't be validated any more.
26730
  * TODO: If we are sure how to stop the validation at once
26731
  *   for all input scenarios, then this should be changed to
26732
  *   instantly stop the validation.
26733
  */
26734
0
  ret = xmlSchemaAssembleByXSI(vctxt);
26735
0
  if (ret != 0) {
26736
0
      if (ret == -1)
26737
0
    goto internal_error;
26738
0
      vctxt->skipDepth = 0;
26739
0
      return(ret);
26740
0
  }
26741
        /*
26742
         * Augment the IDC definitions for the main schema and all imported ones
26743
         * NOTE: main schema is the first in the imported list
26744
         */
26745
0
        xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
26746
0
                    vctxt);
26747
0
    }
26748
0
    if (vctxt->depth > 0) {
26749
  /*
26750
  * Validate this element against the content model
26751
  * of the parent.
26752
  */
26753
0
  ret = xmlSchemaValidateChildElem(vctxt);
26754
0
  if (ret != 0) {
26755
0
      if (ret < 0) {
26756
0
    VERROR_INT("xmlSchemaValidateElem",
26757
0
        "calling xmlSchemaStreamValidateChildElement()");
26758
0
    goto internal_error;
26759
0
      }
26760
0
      goto exit;
26761
0
  }
26762
0
  if (vctxt->depth == vctxt->skipDepth)
26763
0
      goto exit;
26764
0
  if ((vctxt->inode->decl == NULL) &&
26765
0
      (vctxt->inode->typeDef == NULL)) {
26766
0
      VERROR_INT("xmlSchemaValidateElem",
26767
0
    "the child element was valid but neither the "
26768
0
    "declaration nor the type was set");
26769
0
      goto internal_error;
26770
0
  }
26771
0
    } else {
26772
  /*
26773
  * Get the declaration of the validation root.
26774
  */
26775
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26776
0
      vctxt->inode->localName,
26777
0
      vctxt->inode->nsName);
26778
0
  if (vctxt->inode->decl == NULL) {
26779
0
      ret = XML_SCHEMAV_CVC_ELT_1;
26780
0
      VERROR(ret, NULL,
26781
0
    "No matching global declaration available "
26782
0
    "for the validation root");
26783
0
      goto exit;
26784
0
  }
26785
0
    }
26786
26787
0
    if (vctxt->inode->decl == NULL)
26788
0
  goto type_validation;
26789
26790
0
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26791
0
  int skip;
26792
  /*
26793
  * Wildcards.
26794
  */
26795
0
  ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26796
0
  if (ret != 0) {
26797
0
      if (ret < 0) {
26798
0
    VERROR_INT("xmlSchemaValidateElem",
26799
0
        "calling xmlSchemaValidateElemWildcard()");
26800
0
    goto internal_error;
26801
0
      }
26802
0
      goto exit;
26803
0
  }
26804
0
  if (skip) {
26805
0
      vctxt->skipDepth = vctxt->depth;
26806
0
      goto exit;
26807
0
  }
26808
  /*
26809
  * The declaration might be set by the wildcard validation,
26810
  * when the processContents is "lax" or "strict".
26811
  */
26812
0
  if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26813
      /*
26814
      * Clear the "decl" field to not confuse further processing.
26815
      */
26816
0
      vctxt->inode->decl = NULL;
26817
0
      goto type_validation;
26818
0
  }
26819
0
    }
26820
    /*
26821
    * Validate against the declaration.
26822
    */
26823
0
    ret = xmlSchemaValidateElemDecl(vctxt);
26824
0
    if (ret != 0) {
26825
0
  if (ret < 0) {
26826
0
      VERROR_INT("xmlSchemaValidateElem",
26827
0
    "calling xmlSchemaValidateElemDecl()");
26828
0
      goto internal_error;
26829
0
  }
26830
0
  goto exit;
26831
0
    }
26832
    /*
26833
    * Validate against the type definition.
26834
    */
26835
0
type_validation:
26836
26837
0
    if (vctxt->inode->typeDef == NULL) {
26838
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26839
0
  ret = XML_SCHEMAV_CVC_TYPE_1;
26840
0
  VERROR(ret, NULL,
26841
0
      "The type definition is absent");
26842
0
  goto exit;
26843
0
    }
26844
0
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26845
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26846
0
  ret = XML_SCHEMAV_CVC_TYPE_2;
26847
0
      VERROR(ret, NULL,
26848
0
      "The type definition is abstract");
26849
0
  goto exit;
26850
0
    }
26851
    /*
26852
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
26853
    * during validation against the declaration. This must be done
26854
    * _before_ attribute validation.
26855
    */
26856
0
    if (vctxt->xpathStates != NULL) {
26857
0
  ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26858
0
  vctxt->inode->appliedXPath = 1;
26859
0
  if (ret == -1) {
26860
0
      VERROR_INT("xmlSchemaValidateElem",
26861
0
    "calling xmlSchemaXPathEvaluate()");
26862
0
      goto internal_error;
26863
0
  }
26864
0
    }
26865
    /*
26866
    * Validate attributes.
26867
    */
26868
0
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26869
0
  if ((vctxt->nbAttrInfos != 0) ||
26870
0
      (vctxt->inode->typeDef->attrUses != NULL)) {
26871
26872
0
      ret = xmlSchemaVAttributesComplex(vctxt);
26873
0
  }
26874
0
    } else if (vctxt->nbAttrInfos != 0) {
26875
26876
0
  ret = xmlSchemaVAttributesSimple(vctxt);
26877
0
    }
26878
    /*
26879
    * Clear registered attributes.
26880
    */
26881
0
    if (vctxt->nbAttrInfos != 0)
26882
0
  xmlSchemaClearAttrInfos(vctxt);
26883
0
    if (ret == -1) {
26884
0
  VERROR_INT("xmlSchemaValidateElem",
26885
0
      "calling attributes validation");
26886
0
  goto internal_error;
26887
0
    }
26888
    /*
26889
    * Don't return an error if attributes are invalid on purpose.
26890
    */
26891
0
    ret = 0;
26892
26893
0
exit:
26894
0
    if (ret != 0)
26895
0
  vctxt->skipDepth = vctxt->depth;
26896
0
    return (ret);
26897
0
internal_error:
26898
0
    return (-1);
26899
0
}
26900
26901
#ifdef XML_SCHEMA_READER_ENABLED
26902
static int
26903
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26904
{
26905
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26906
    int depth, nodeType, ret = 0, consumed;
26907
    xmlSchemaNodeInfoPtr ielem;
26908
26909
    vctxt->depth = -1;
26910
    ret = xmlTextReaderRead(vctxt->reader);
26911
    /*
26912
    * Move to the document element.
26913
    */
26914
    while (ret == 1) {
26915
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26916
  if (nodeType == XML_ELEMENT_NODE)
26917
      goto root_found;
26918
  ret = xmlTextReaderRead(vctxt->reader);
26919
    }
26920
    goto exit;
26921
26922
root_found:
26923
26924
    do {
26925
  depth = xmlTextReaderDepth(vctxt->reader);
26926
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26927
26928
  if (nodeType == XML_ELEMENT_NODE) {
26929
26930
      vctxt->depth++;
26931
      if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26932
    VERROR_INT("xmlSchemaVReaderWalk",
26933
        "calling xmlSchemaValidatorPushElem()");
26934
    goto internal_error;
26935
      }
26936
      ielem = vctxt->inode;
26937
      ielem->localName = xmlTextReaderLocalName(vctxt->reader);
26938
      ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
26939
      ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
26940
      /*
26941
      * Is the element empty?
26942
      */
26943
      ret = xmlTextReaderIsEmptyElement(vctxt->reader);
26944
      if (ret == -1) {
26945
    VERROR_INT("xmlSchemaVReaderWalk",
26946
        "calling xmlTextReaderIsEmptyElement()");
26947
    goto internal_error;
26948
      }
26949
      if (ret) {
26950
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
26951
      }
26952
      /*
26953
      * Register attributes.
26954
      */
26955
      vctxt->nbAttrInfos = 0;
26956
      ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
26957
      if (ret == -1) {
26958
    VERROR_INT("xmlSchemaVReaderWalk",
26959
        "calling xmlTextReaderMoveToFirstAttribute()");
26960
    goto internal_error;
26961
      }
26962
      if (ret == 1) {
26963
    do {
26964
        /*
26965
        * VAL TODO: How do we know that the reader works on a
26966
        * node tree, to be able to pass a node here?
26967
        */
26968
        if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
26969
      (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
26970
      xmlTextReaderNamespaceUri(vctxt->reader), 1,
26971
      xmlTextReaderValue(vctxt->reader), 1) == -1) {
26972
26973
      VERROR_INT("xmlSchemaVReaderWalk",
26974
          "calling xmlSchemaValidatorPushAttribute()");
26975
      goto internal_error;
26976
        }
26977
        ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
26978
        if (ret == -1) {
26979
      VERROR_INT("xmlSchemaVReaderWalk",
26980
          "calling xmlTextReaderMoveToFirstAttribute()");
26981
      goto internal_error;
26982
        }
26983
    } while (ret == 1);
26984
    /*
26985
    * Back to element position.
26986
    */
26987
    ret = xmlTextReaderMoveToElement(vctxt->reader);
26988
    if (ret == -1) {
26989
        VERROR_INT("xmlSchemaVReaderWalk",
26990
      "calling xmlTextReaderMoveToElement()");
26991
        goto internal_error;
26992
    }
26993
      }
26994
      /*
26995
      * Validate the element.
26996
      */
26997
      ret= xmlSchemaValidateElem(vctxt);
26998
      if (ret != 0) {
26999
    if (ret == -1) {
27000
        VERROR_INT("xmlSchemaVReaderWalk",
27001
      "calling xmlSchemaValidateElem()");
27002
        goto internal_error;
27003
    }
27004
    goto exit;
27005
      }
27006
      if (vctxt->depth == vctxt->skipDepth) {
27007
    int curDepth;
27008
    /*
27009
    * Skip all content.
27010
    */
27011
    if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27012
        ret = xmlTextReaderRead(vctxt->reader);
27013
        curDepth = xmlTextReaderDepth(vctxt->reader);
27014
        while ((ret == 1) && (curDepth != depth)) {
27015
      ret = xmlTextReaderRead(vctxt->reader);
27016
      curDepth = xmlTextReaderDepth(vctxt->reader);
27017
        }
27018
        if (ret < 0) {
27019
      /*
27020
      * VAL TODO: A reader error occurred; what to do here?
27021
      */
27022
      ret = 1;
27023
      goto exit;
27024
        }
27025
    }
27026
    goto leave_elem;
27027
      }
27028
      /*
27029
      * READER VAL TODO: Is an END_ELEM really never called
27030
      * if the elem is empty?
27031
      */
27032
      if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27033
    goto leave_elem;
27034
  } else if (nodeType == END_ELEM) {
27035
      /*
27036
      * Process END of element.
27037
      */
27038
leave_elem:
27039
      ret = xmlSchemaValidatorPopElem(vctxt);
27040
      if (ret != 0) {
27041
    if (ret < 0) {
27042
        VERROR_INT("xmlSchemaVReaderWalk",
27043
      "calling xmlSchemaValidatorPopElem()");
27044
        goto internal_error;
27045
    }
27046
    goto exit;
27047
      }
27048
      if (vctxt->depth >= 0)
27049
    ielem = vctxt->inode;
27050
      else
27051
    ielem = NULL;
27052
  } else if ((nodeType == XML_TEXT_NODE) ||
27053
      (nodeType == XML_CDATA_SECTION_NODE) ||
27054
      (nodeType == WHTSP) ||
27055
      (nodeType == SIGN_WHTSP)) {
27056
      /*
27057
      * Process character content.
27058
      */
27059
      xmlChar *value;
27060
27061
      if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27062
    nodeType = XML_TEXT_NODE;
27063
27064
      value = xmlTextReaderValue(vctxt->reader);
27065
      ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27066
    -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27067
      if (! consumed)
27068
    xmlFree(value);
27069
      if (ret == -1) {
27070
    VERROR_INT("xmlSchemaVReaderWalk",
27071
        "calling xmlSchemaVPushText()");
27072
    goto internal_error;
27073
      }
27074
  } else if ((nodeType == XML_ENTITY_NODE) ||
27075
      (nodeType == XML_ENTITY_REF_NODE)) {
27076
      /*
27077
      * VAL TODO: What to do with entities?
27078
      */
27079
      TODO
27080
  }
27081
  /*
27082
  * Read next node.
27083
  */
27084
  ret = xmlTextReaderRead(vctxt->reader);
27085
    } while (ret == 1);
27086
27087
exit:
27088
    return (ret);
27089
internal_error:
27090
    return (-1);
27091
}
27092
#endif
27093
27094
/************************************************************************
27095
 *                  *
27096
 *      SAX validation handlers       *
27097
 *                  *
27098
 ************************************************************************/
27099
27100
/*
27101
* Process text content.
27102
*/
27103
static void
27104
xmlSchemaSAXHandleText(void *ctx,
27105
           const xmlChar * ch,
27106
           int len)
27107
0
{
27108
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27109
27110
0
    if (vctxt->depth < 0)
27111
0
  return;
27112
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27113
0
  return;
27114
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27115
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27116
0
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27117
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27118
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27119
0
      "calling xmlSchemaVPushText()");
27120
0
  vctxt->err = -1;
27121
0
  xmlStopParser(vctxt->parserCtxt);
27122
0
    }
27123
0
}
27124
27125
/*
27126
* Process CDATA content.
27127
*/
27128
static void
27129
xmlSchemaSAXHandleCDataSection(void *ctx,
27130
           const xmlChar * ch,
27131
           int len)
27132
0
{
27133
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27134
27135
0
    if (vctxt->depth < 0)
27136
0
  return;
27137
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27138
0
  return;
27139
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27140
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27141
0
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27142
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27143
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27144
0
      "calling xmlSchemaVPushText()");
27145
0
  vctxt->err = -1;
27146
0
  xmlStopParser(vctxt->parserCtxt);
27147
0
    }
27148
0
}
27149
27150
static void
27151
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27152
          const xmlChar * name ATTRIBUTE_UNUSED)
27153
0
{
27154
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27155
27156
0
    if (vctxt->depth < 0)
27157
0
  return;
27158
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27159
0
  return;
27160
    /* SAX VAL TODO: What to do here? */
27161
0
}
27162
27163
static void
27164
xmlSchemaSAXHandleStartElementNs(void *ctx,
27165
         const xmlChar * localname,
27166
         const xmlChar * prefix ATTRIBUTE_UNUSED,
27167
         const xmlChar * URI,
27168
         int nb_namespaces,
27169
         const xmlChar ** namespaces,
27170
         int nb_attributes,
27171
         int nb_defaulted ATTRIBUTE_UNUSED,
27172
         const xmlChar ** attributes)
27173
0
{
27174
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27175
0
    int ret;
27176
0
    xmlSchemaNodeInfoPtr ielem;
27177
0
    int i, j;
27178
27179
    /*
27180
    * SAX VAL TODO: What to do with nb_defaulted?
27181
    */
27182
    /*
27183
    * Skip elements if inside a "skip" wildcard or invalid.
27184
    */
27185
0
    vctxt->depth++;
27186
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27187
0
  return;
27188
    /*
27189
    * Push the element.
27190
    */
27191
0
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27192
0
  VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27193
0
      "calling xmlSchemaValidatorPushElem()");
27194
0
  goto internal_error;
27195
0
    }
27196
0
    ielem = vctxt->inode;
27197
    /*
27198
    * TODO: Is this OK?
27199
    */
27200
0
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27201
0
    ielem->localName = localname;
27202
0
    ielem->nsName = URI;
27203
0
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27204
    /*
27205
    * Register namespaces on the elem info.
27206
    */
27207
0
    if (nb_namespaces != 0) {
27208
  /*
27209
  * Although the parser builds its own namespace list,
27210
  * we have no access to it, so we'll use an own one.
27211
  */
27212
0
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27213
      /*
27214
      * Store prefix and namespace name.
27215
      */
27216
0
      if (ielem->nsBindings == NULL) {
27217
0
    ielem->nsBindings =
27218
0
        (const xmlChar **) xmlMalloc(10 *
27219
0
      sizeof(const xmlChar *));
27220
0
    if (ielem->nsBindings == NULL) {
27221
0
        xmlSchemaVErrMemory(vctxt);
27222
0
        goto internal_error;
27223
0
    }
27224
0
    ielem->nbNsBindings = 0;
27225
0
    ielem->sizeNsBindings = 5;
27226
0
      } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27227
0
    ielem->sizeNsBindings *= 2;
27228
0
    ielem->nsBindings =
27229
0
        (const xmlChar **) xmlRealloc(
27230
0
      (void *) ielem->nsBindings,
27231
0
      ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27232
0
    if (ielem->nsBindings == NULL) {
27233
0
        xmlSchemaVErrMemory(vctxt);
27234
0
        goto internal_error;
27235
0
    }
27236
0
      }
27237
27238
0
      ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27239
0
      if (namespaces[j+1][0] == 0) {
27240
    /*
27241
    * Handle xmlns="".
27242
    */
27243
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27244
0
      } else
27245
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27246
0
        namespaces[j+1];
27247
0
      ielem->nbNsBindings++;
27248
0
  }
27249
0
    }
27250
    /*
27251
    * Register attributes.
27252
    * SAX VAL TODO: We are not adding namespace declaration
27253
    * attributes yet.
27254
    */
27255
0
    if (nb_attributes != 0) {
27256
0
  int valueLen, k, l;
27257
0
  xmlChar *value;
27258
27259
0
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27260
      /*
27261
      * Duplicate the value, changing any &#38; to a literal ampersand.
27262
      *
27263
      * libxml2 differs from normal SAX here in that it escapes all ampersands
27264
      * as &#38; instead of delivering the raw converted string. Changing the
27265
      * behavior at this point would break applications that use this API, so
27266
      * we are forced to work around it.
27267
      */
27268
0
      valueLen = attributes[j+4] - attributes[j+3];
27269
0
      value = xmlMallocAtomic(valueLen + 1);
27270
0
      if (value == NULL) {
27271
0
    xmlSchemaVErrMemory(vctxt);
27272
0
    goto internal_error;
27273
0
      }
27274
0
      for (k = 0, l = 0; k < valueLen; l++) {
27275
0
    if (k < valueLen - 4 &&
27276
0
        attributes[j+3][k+0] == '&' &&
27277
0
        attributes[j+3][k+1] == '#' &&
27278
0
        attributes[j+3][k+2] == '3' &&
27279
0
        attributes[j+3][k+3] == '8' &&
27280
0
        attributes[j+3][k+4] == ';') {
27281
0
        value[l] = '&';
27282
0
        k += 5;
27283
0
    } else {
27284
0
        value[l] = attributes[j+3][k];
27285
0
        k++;
27286
0
    }
27287
0
      }
27288
0
      value[l] = '\0';
27289
      /*
27290
      * TODO: Set the node line.
27291
      */
27292
0
      ret = xmlSchemaValidatorPushAttribute(vctxt,
27293
0
    NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27294
0
    value, 1);
27295
0
      if (ret == -1) {
27296
0
    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27297
0
        "calling xmlSchemaValidatorPushAttribute()");
27298
0
    goto internal_error;
27299
0
      }
27300
0
  }
27301
0
    }
27302
    /*
27303
    * Validate the element.
27304
    */
27305
0
    ret = xmlSchemaValidateElem(vctxt);
27306
0
    if (ret != 0) {
27307
0
  if (ret == -1) {
27308
0
      VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27309
0
    "calling xmlSchemaValidateElem()");
27310
0
      goto internal_error;
27311
0
  }
27312
0
  goto exit;
27313
0
    }
27314
27315
0
exit:
27316
0
    return;
27317
0
internal_error:
27318
0
    vctxt->err = -1;
27319
0
    xmlStopParser(vctxt->parserCtxt);
27320
0
    return;
27321
0
}
27322
27323
static void
27324
xmlSchemaSAXHandleEndElementNs(void *ctx,
27325
             const xmlChar * localname ATTRIBUTE_UNUSED,
27326
             const xmlChar * prefix ATTRIBUTE_UNUSED,
27327
             const xmlChar * URI ATTRIBUTE_UNUSED)
27328
0
{
27329
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27330
0
    int res;
27331
27332
    /*
27333
    * Skip elements if inside a "skip" wildcard or if invalid.
27334
    */
27335
0
    if (vctxt->skipDepth != -1) {
27336
0
  if (vctxt->depth > vctxt->skipDepth) {
27337
0
      vctxt->depth--;
27338
0
      return;
27339
0
  } else
27340
0
      vctxt->skipDepth = -1;
27341
0
    }
27342
    /*
27343
    * SAX VAL TODO: Just a temporary check.
27344
    */
27345
0
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27346
0
  (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27347
0
  VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27348
0
      "elem pop mismatch");
27349
0
    }
27350
0
    res = xmlSchemaValidatorPopElem(vctxt);
27351
0
    if (res != 0) {
27352
0
  if (res < 0) {
27353
0
      VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27354
0
    "calling xmlSchemaValidatorPopElem()");
27355
0
      goto internal_error;
27356
0
  }
27357
0
  goto exit;
27358
0
    }
27359
0
exit:
27360
0
    return;
27361
0
internal_error:
27362
0
    vctxt->err = -1;
27363
0
    xmlStopParser(vctxt->parserCtxt);
27364
0
    return;
27365
0
}
27366
27367
/************************************************************************
27368
 *                  *
27369
 *      Validation interfaces       *
27370
 *                  *
27371
 ************************************************************************/
27372
27373
/**
27374
 * xmlSchemaNewValidCtxt:
27375
 * @schema:  a precompiled XML Schemas
27376
 *
27377
 * Create an XML Schemas validation context based on the given schema.
27378
 *
27379
 * Returns the validation context or NULL in case of error
27380
 */
27381
xmlSchemaValidCtxtPtr
27382
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27383
0
{
27384
0
    xmlSchemaValidCtxtPtr ret;
27385
27386
0
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27387
0
    if (ret == NULL) {
27388
0
        xmlSchemaVErrMemory(NULL);
27389
0
        return (NULL);
27390
0
    }
27391
0
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27392
0
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27393
0
    ret->dict = xmlDictCreate();
27394
0
    ret->nodeQNames = xmlSchemaItemListCreate();
27395
0
    ret->schema = schema;
27396
0
    return (ret);
27397
0
}
27398
27399
/**
27400
 * xmlSchemaValidateSetFilename:
27401
 * @vctxt: the schema validation context
27402
 * @filename: the file name
27403
 *
27404
 * Workaround to provide file error reporting information when this is
27405
 * not provided by current APIs
27406
 */
27407
void
27408
0
xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27409
0
    if (vctxt == NULL)
27410
0
        return;
27411
0
    if (vctxt->filename != NULL)
27412
0
        xmlFree(vctxt->filename);
27413
0
    if (filename != NULL)
27414
0
        vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27415
0
    else
27416
0
        vctxt->filename = NULL;
27417
0
}
27418
27419
/**
27420
 * xmlSchemaClearValidCtxt:
27421
 * @vctxt: the schema validation context
27422
 *
27423
 * Free the resources associated to the schema validation context;
27424
 * leaves some fields alive intended for reuse of the context.
27425
 */
27426
static void
27427
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27428
0
{
27429
0
    if (vctxt == NULL)
27430
0
        return;
27431
27432
    /*
27433
    * TODO: Should we clear the flags?
27434
    *   Might be problematic if one reuses the context
27435
    *   and assumes that the options remain the same.
27436
    */
27437
0
    vctxt->flags = 0;
27438
0
    vctxt->validationRoot = NULL;
27439
0
    vctxt->doc = NULL;
27440
0
#ifdef LIBXML_READER_ENABLED
27441
0
    vctxt->reader = NULL;
27442
0
#endif
27443
0
    vctxt->hasKeyrefs = 0;
27444
27445
0
    if (vctxt->value != NULL) {
27446
0
        xmlSchemaFreeValue(vctxt->value);
27447
0
  vctxt->value = NULL;
27448
0
    }
27449
    /*
27450
    * Augmented IDC information.
27451
    */
27452
0
    if (vctxt->aidcs != NULL) {
27453
0
  xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27454
0
  do {
27455
0
      next = cur->next;
27456
0
      xmlFree(cur);
27457
0
      cur = next;
27458
0
  } while (cur != NULL);
27459
0
  vctxt->aidcs = NULL;
27460
0
    }
27461
27462
0
    if (vctxt->idcNodes != NULL) {
27463
0
  int i;
27464
0
  xmlSchemaPSVIIDCNodePtr item;
27465
27466
0
  for (i = 0; i < vctxt->nbIdcNodes; i++) {
27467
0
      item = vctxt->idcNodes[i];
27468
0
      xmlFree(item->keys);
27469
0
      xmlFree(item);
27470
0
  }
27471
0
  xmlFree(vctxt->idcNodes);
27472
0
  vctxt->idcNodes = NULL;
27473
0
  vctxt->nbIdcNodes = 0;
27474
0
  vctxt->sizeIdcNodes = 0;
27475
0
    }
27476
27477
0
    if (vctxt->idcKeys != NULL) {
27478
0
  int i;
27479
0
  for (i = 0; i < vctxt->nbIdcKeys; i++)
27480
0
      xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27481
0
  xmlFree(vctxt->idcKeys);
27482
0
  vctxt->idcKeys = NULL;
27483
0
  vctxt->nbIdcKeys = 0;
27484
0
  vctxt->sizeIdcKeys = 0;
27485
0
    }
27486
27487
    /*
27488
    * Note that we won't delete the XPath state pool here.
27489
    */
27490
0
    if (vctxt->xpathStates != NULL) {
27491
0
  xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27492
0
  vctxt->xpathStates = NULL;
27493
0
    }
27494
    /*
27495
    * Attribute info.
27496
    */
27497
0
    if (vctxt->nbAttrInfos != 0) {
27498
0
  xmlSchemaClearAttrInfos(vctxt);
27499
0
    }
27500
    /*
27501
    * Element info.
27502
    */
27503
0
    if (vctxt->elemInfos != NULL) {
27504
0
  int i;
27505
0
  xmlSchemaNodeInfoPtr ei;
27506
27507
0
  for (i = 0; i < vctxt->sizeElemInfos; i++) {
27508
0
      ei = vctxt->elemInfos[i];
27509
0
      if (ei == NULL)
27510
0
    break;
27511
0
      xmlSchemaClearElemInfo(vctxt, ei);
27512
0
  }
27513
0
    }
27514
0
    xmlSchemaItemListClear(vctxt->nodeQNames);
27515
    /* Recreate the dict. */
27516
0
    xmlDictFree(vctxt->dict);
27517
    /*
27518
    * TODO: Is is save to recreate it? Do we have a scenario
27519
    * where the user provides the dict?
27520
    */
27521
0
    vctxt->dict = xmlDictCreate();
27522
27523
0
    if (vctxt->filename != NULL) {
27524
0
        xmlFree(vctxt->filename);
27525
0
  vctxt->filename = NULL;
27526
0
    }
27527
27528
    /*
27529
     * Note that some cleanup functions can move items to the cache,
27530
     * so the cache shouldn't be freed too early.
27531
     */
27532
0
    if (vctxt->idcMatcherCache != NULL) {
27533
0
  xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27534
27535
0
  while (matcher) {
27536
0
      tmp = matcher;
27537
0
      matcher = matcher->nextCached;
27538
0
      xmlSchemaIDCFreeMatcherList(tmp);
27539
0
  }
27540
0
  vctxt->idcMatcherCache = NULL;
27541
0
    }
27542
0
}
27543
27544
/**
27545
 * xmlSchemaFreeValidCtxt:
27546
 * @ctxt:  the schema validation context
27547
 *
27548
 * Free the resources associated to the schema validation context
27549
 */
27550
void
27551
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27552
0
{
27553
0
    if (ctxt == NULL)
27554
0
        return;
27555
0
    if (ctxt->value != NULL)
27556
0
        xmlSchemaFreeValue(ctxt->value);
27557
0
    if (ctxt->pctxt != NULL)
27558
0
  xmlSchemaFreeParserCtxt(ctxt->pctxt);
27559
0
    if (ctxt->idcNodes != NULL) {
27560
0
  int i;
27561
0
  xmlSchemaPSVIIDCNodePtr item;
27562
27563
0
  for (i = 0; i < ctxt->nbIdcNodes; i++) {
27564
0
      item = ctxt->idcNodes[i];
27565
0
      xmlFree(item->keys);
27566
0
      xmlFree(item);
27567
0
  }
27568
0
  xmlFree(ctxt->idcNodes);
27569
0
    }
27570
0
    if (ctxt->idcKeys != NULL) {
27571
0
  int i;
27572
0
  for (i = 0; i < ctxt->nbIdcKeys; i++)
27573
0
      xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27574
0
  xmlFree(ctxt->idcKeys);
27575
0
    }
27576
27577
0
    if (ctxt->xpathStates != NULL) {
27578
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27579
0
  ctxt->xpathStates = NULL;
27580
0
    }
27581
0
    if (ctxt->xpathStatePool != NULL) {
27582
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27583
0
  ctxt->xpathStatePool = NULL;
27584
0
    }
27585
27586
    /*
27587
    * Augmented IDC information.
27588
    */
27589
0
    if (ctxt->aidcs != NULL) {
27590
0
  xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27591
0
  do {
27592
0
      next = cur->next;
27593
0
      xmlFree(cur);
27594
0
      cur = next;
27595
0
  } while (cur != NULL);
27596
0
    }
27597
0
    if (ctxt->attrInfos != NULL) {
27598
0
  int i;
27599
0
  xmlSchemaAttrInfoPtr attr;
27600
27601
  /* Just a paranoid call to the cleanup. */
27602
0
  if (ctxt->nbAttrInfos != 0)
27603
0
      xmlSchemaClearAttrInfos(ctxt);
27604
0
  for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27605
0
      attr = ctxt->attrInfos[i];
27606
0
      xmlFree(attr);
27607
0
  }
27608
0
  xmlFree(ctxt->attrInfos);
27609
0
    }
27610
0
    if (ctxt->elemInfos != NULL) {
27611
0
  int i;
27612
0
  xmlSchemaNodeInfoPtr ei;
27613
27614
0
  for (i = 0; i < ctxt->sizeElemInfos; i++) {
27615
0
      ei = ctxt->elemInfos[i];
27616
0
      if (ei == NULL)
27617
0
    break;
27618
0
      xmlSchemaClearElemInfo(ctxt, ei);
27619
0
      xmlFree(ei);
27620
0
  }
27621
0
  xmlFree(ctxt->elemInfos);
27622
0
    }
27623
0
    if (ctxt->nodeQNames != NULL)
27624
0
  xmlSchemaItemListFree(ctxt->nodeQNames);
27625
0
    if (ctxt->dict != NULL)
27626
0
  xmlDictFree(ctxt->dict);
27627
0
    if (ctxt->filename != NULL)
27628
0
  xmlFree(ctxt->filename);
27629
0
    xmlFree(ctxt);
27630
0
}
27631
27632
/**
27633
 * xmlSchemaIsValid:
27634
 * @ctxt: the schema validation context
27635
 *
27636
 * Check if any error was detected during validation.
27637
 *
27638
 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27639
 *         of internal error.
27640
 */
27641
int
27642
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27643
0
{
27644
0
    if (ctxt == NULL)
27645
0
        return(-1);
27646
0
    return(ctxt->err == 0);
27647
0
}
27648
27649
/**
27650
 * xmlSchemaSetValidErrors:
27651
 * @ctxt:  a schema validation context
27652
 * @err:  the error function
27653
 * @warn: the warning function
27654
 * @ctx: the functions context
27655
 *
27656
 * DEPRECATED: Use xmlSchemaSetValidStructuredErrors.
27657
 *
27658
 * Set the error and warning callback information
27659
 */
27660
void
27661
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27662
                        xmlSchemaValidityErrorFunc err,
27663
                        xmlSchemaValidityWarningFunc warn, void *ctx)
27664
0
{
27665
0
    if (ctxt == NULL)
27666
0
        return;
27667
0
    ctxt->error = err;
27668
0
    ctxt->warning = warn;
27669
0
    ctxt->errCtxt = ctx;
27670
0
    if (ctxt->pctxt != NULL)
27671
0
  xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27672
0
}
27673
27674
/**
27675
 * xmlSchemaSetValidStructuredErrors:
27676
 * @ctxt:  a schema validation context
27677
 * @serror:  the structured error function
27678
 * @ctx: the functions context
27679
 *
27680
 * Set the structured error callback
27681
 */
27682
void
27683
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27684
          xmlStructuredErrorFunc serror, void *ctx)
27685
0
{
27686
0
    if (ctxt == NULL)
27687
0
        return;
27688
0
    ctxt->serror = serror;
27689
0
    ctxt->error = NULL;
27690
0
    ctxt->warning = NULL;
27691
0
    ctxt->errCtxt = ctx;
27692
0
    if (ctxt->pctxt != NULL)
27693
0
  xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27694
0
}
27695
27696
/**
27697
 * xmlSchemaGetValidErrors:
27698
 * @ctxt: a XML-Schema validation context
27699
 * @err: the error function result
27700
 * @warn: the warning function result
27701
 * @ctx: the functions context result
27702
 *
27703
 * Get the error and warning callback information
27704
 *
27705
 * Returns -1 in case of error and 0 otherwise
27706
 */
27707
int
27708
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27709
      xmlSchemaValidityErrorFunc * err,
27710
      xmlSchemaValidityWarningFunc * warn, void **ctx)
27711
0
{
27712
0
  if (ctxt == NULL)
27713
0
    return (-1);
27714
0
  if (err != NULL)
27715
0
    *err = ctxt->error;
27716
0
  if (warn != NULL)
27717
0
    *warn = ctxt->warning;
27718
0
  if (ctx != NULL)
27719
0
    *ctx = ctxt->errCtxt;
27720
0
  return (0);
27721
0
}
27722
27723
27724
/**
27725
 * xmlSchemaSetValidOptions:
27726
 * @ctxt: a schema validation context
27727
 * @options: a combination of xmlSchemaValidOption
27728
 *
27729
 * Sets the options to be used during the validation.
27730
 *
27731
 * Returns 0 in case of success, -1 in case of an
27732
 * API error.
27733
 */
27734
int
27735
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27736
       int options)
27737
27738
0
{
27739
0
    int i;
27740
27741
0
    if (ctxt == NULL)
27742
0
  return (-1);
27743
    /*
27744
    * WARNING: Change the start value if adding to the
27745
    * xmlSchemaValidOption.
27746
    * TODO: Is there an other, more easy to maintain,
27747
    * way?
27748
    */
27749
0
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
27750
0
        if (options & 1<<i)
27751
0
      return (-1);
27752
0
    }
27753
0
    ctxt->options = options;
27754
0
    return (0);
27755
0
}
27756
27757
/**
27758
 * xmlSchemaValidCtxtGetOptions:
27759
 * @ctxt: a schema validation context
27760
 *
27761
 * Get the validation context options.
27762
 *
27763
 * Returns the option combination or -1 on error.
27764
 */
27765
int
27766
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27767
27768
0
{
27769
0
    if (ctxt == NULL)
27770
0
  return (-1);
27771
0
    else
27772
0
  return (ctxt->options);
27773
0
}
27774
27775
static int
27776
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27777
0
{
27778
0
    xmlAttrPtr attr;
27779
0
    int ret = 0;
27780
0
    xmlSchemaNodeInfoPtr ielem = NULL;
27781
0
    xmlNodePtr node, valRoot;
27782
0
    const xmlChar *nsName;
27783
27784
    /* DOC VAL TODO: Move this to the start function. */
27785
0
    if (vctxt->validationRoot != NULL)
27786
0
        valRoot = vctxt->validationRoot;
27787
0
    else
27788
0
  valRoot = xmlDocGetRootElement(vctxt->doc);
27789
0
    if (valRoot == NULL) {
27790
  /* VAL TODO: Error code? */
27791
0
  VERROR(1, NULL, "The document has no document element");
27792
0
  return (1);
27793
0
    }
27794
0
    vctxt->depth = -1;
27795
0
    vctxt->validationRoot = valRoot;
27796
0
    node = valRoot;
27797
0
    while (node != NULL) {
27798
0
  if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27799
0
      goto next_sibling;
27800
0
  if (node->type == XML_ELEMENT_NODE) {
27801
27802
      /*
27803
      * Init the node-info.
27804
      */
27805
0
      vctxt->depth++;
27806
0
      if (xmlSchemaValidatorPushElem(vctxt) == -1)
27807
0
    goto internal_error;
27808
0
      ielem = vctxt->inode;
27809
0
      ielem->node = node;
27810
0
      ielem->nodeLine = node->line;
27811
0
      ielem->localName = node->name;
27812
0
      if (node->ns != NULL)
27813
0
    ielem->nsName = node->ns->href;
27814
0
      ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27815
      /*
27816
      * Register attributes.
27817
      * DOC VAL TODO: We do not register namespace declaration
27818
      * attributes yet.
27819
      */
27820
0
      vctxt->nbAttrInfos = 0;
27821
0
      if (node->properties != NULL) {
27822
0
    attr = node->properties;
27823
0
    do {
27824
0
        if (attr->ns != NULL)
27825
0
      nsName = attr->ns->href;
27826
0
        else
27827
0
      nsName = NULL;
27828
0
        ret = xmlSchemaValidatorPushAttribute(vctxt,
27829
0
      (xmlNodePtr) attr,
27830
      /*
27831
      * Note that we give it the line number of the
27832
      * parent element.
27833
      */
27834
0
      ielem->nodeLine,
27835
0
      attr->name, nsName, 0,
27836
0
      xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27837
0
        if (ret == -1) {
27838
0
      VERROR_INT("xmlSchemaDocWalk",
27839
0
          "calling xmlSchemaValidatorPushAttribute()");
27840
0
      goto internal_error;
27841
0
        }
27842
0
        attr = attr->next;
27843
0
    } while (attr);
27844
0
      }
27845
      /*
27846
      * Validate the element.
27847
      */
27848
0
      ret = xmlSchemaValidateElem(vctxt);
27849
0
      if (ret != 0) {
27850
0
    if (ret == -1) {
27851
0
        VERROR_INT("xmlSchemaDocWalk",
27852
0
      "calling xmlSchemaValidateElem()");
27853
0
        goto internal_error;
27854
0
    }
27855
    /*
27856
    * Don't stop validation; just skip the content
27857
    * of this element.
27858
    */
27859
0
    goto leave_node;
27860
0
      }
27861
0
      if ((vctxt->skipDepth != -1) &&
27862
0
    (vctxt->depth >= vctxt->skipDepth))
27863
0
    goto leave_node;
27864
0
  } else if ((node->type == XML_TEXT_NODE) ||
27865
0
      (node->type == XML_CDATA_SECTION_NODE)) {
27866
      /*
27867
      * Process character content.
27868
      */
27869
0
      if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27870
0
    ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27871
0
      ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27872
0
    -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27873
0
      if (ret < 0) {
27874
0
    VERROR_INT("xmlSchemaVDocWalk",
27875
0
        "calling xmlSchemaVPushText()");
27876
0
    goto internal_error;
27877
0
      }
27878
      /*
27879
      * DOC VAL TODO: Should we skip further validation of the
27880
      * element content here?
27881
      */
27882
0
  } else if ((node->type == XML_ENTITY_NODE) ||
27883
0
      (node->type == XML_ENTITY_REF_NODE)) {
27884
      /*
27885
      * DOC VAL TODO: What to do with entities?
27886
      */
27887
0
      VERROR_INT("xmlSchemaVDocWalk",
27888
0
    "there is at least one entity reference in the node-tree "
27889
0
    "currently being validated. Processing of entities with "
27890
0
    "this XML Schema processor is not supported (yet). Please "
27891
0
    "substitute entities before validation.");
27892
0
      goto internal_error;
27893
0
  } else {
27894
0
      goto leave_node;
27895
      /*
27896
      * DOC VAL TODO: XInclude nodes, etc.
27897
      */
27898
0
  }
27899
  /*
27900
  * Walk the doc.
27901
  */
27902
0
  if (node->children != NULL) {
27903
0
      node = node->children;
27904
0
      continue;
27905
0
  }
27906
0
leave_node:
27907
0
  if (node->type == XML_ELEMENT_NODE) {
27908
      /*
27909
      * Leaving the scope of an element.
27910
      */
27911
0
      if (node != vctxt->inode->node) {
27912
0
    VERROR_INT("xmlSchemaVDocWalk",
27913
0
        "element position mismatch");
27914
0
    goto internal_error;
27915
0
      }
27916
0
      ret = xmlSchemaValidatorPopElem(vctxt);
27917
0
      if (ret != 0) {
27918
0
    if (ret < 0) {
27919
0
        VERROR_INT("xmlSchemaVDocWalk",
27920
0
      "calling xmlSchemaValidatorPopElem()");
27921
0
        goto internal_error;
27922
0
    }
27923
0
      }
27924
0
      if (node == valRoot)
27925
0
    goto exit;
27926
0
  }
27927
0
next_sibling:
27928
0
  if (node->next != NULL)
27929
0
      node = node->next;
27930
0
  else {
27931
0
      node = node->parent;
27932
0
      goto leave_node;
27933
0
  }
27934
0
    }
27935
27936
0
exit:
27937
0
    return (ret);
27938
0
internal_error:
27939
0
    return (-1);
27940
0
}
27941
27942
static int
27943
0
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27944
    /*
27945
    * Some initialization.
27946
    */
27947
0
    vctxt->err = 0;
27948
0
    vctxt->nberrors = 0;
27949
0
    vctxt->depth = -1;
27950
0
    vctxt->skipDepth = -1;
27951
0
    vctxt->hasKeyrefs = 0;
27952
#ifdef ENABLE_IDC_NODE_TABLES_TEST
27953
    vctxt->createIDCNodeTables = 1;
27954
#else
27955
0
    vctxt->createIDCNodeTables = 0;
27956
0
#endif
27957
    /*
27958
    * Create a schema + parser if necessary.
27959
    */
27960
0
    if (vctxt->schema == NULL) {
27961
0
  xmlSchemaParserCtxtPtr pctxt;
27962
27963
0
  vctxt->xsiAssemble = 1;
27964
  /*
27965
  * If not schema was given then we will create a schema
27966
  * dynamically using XSI schema locations.
27967
  *
27968
  * Create the schema parser context.
27969
  */
27970
0
  if ((vctxt->pctxt == NULL) &&
27971
0
     (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27972
0
     return (-1);
27973
0
  pctxt = vctxt->pctxt;
27974
0
  pctxt->xsiAssemble = 1;
27975
  /*
27976
  * Create the schema.
27977
  */
27978
0
  vctxt->schema = xmlSchemaNewSchema(pctxt);
27979
0
  if (vctxt->schema == NULL)
27980
0
      return (-1);
27981
  /*
27982
  * Create the schema construction context.
27983
  */
27984
0
  pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
27985
0
  if (pctxt->constructor == NULL)
27986
0
      return(-1);
27987
0
  pctxt->constructor->mainSchema = vctxt->schema;
27988
  /*
27989
  * Take ownership of the constructor to be able to free it.
27990
  */
27991
0
  pctxt->ownsConstructor = 1;
27992
0
    }
27993
    /*
27994
    * Augment the IDC definitions for the main schema and all imported ones
27995
    * NOTE: main schema if the first in the imported list
27996
    */
27997
0
    xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
27998
0
                vctxt);
27999
28000
0
    return(0);
28001
0
}
28002
28003
static void
28004
0
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28005
0
    if (vctxt->xsiAssemble) {
28006
0
  if (vctxt->schema != NULL) {
28007
0
      xmlSchemaFree(vctxt->schema);
28008
0
      vctxt->schema = NULL;
28009
0
  }
28010
0
    }
28011
0
    xmlSchemaClearValidCtxt(vctxt);
28012
0
}
28013
28014
static int
28015
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28016
0
{
28017
0
    int ret = 0;
28018
28019
0
    if (xmlSchemaPreRun(vctxt) < 0)
28020
0
        return(-1);
28021
28022
0
    if (vctxt->doc != NULL) {
28023
  /*
28024
   * Tree validation.
28025
   */
28026
0
  ret = xmlSchemaVDocWalk(vctxt);
28027
0
#ifdef LIBXML_READER_ENABLED
28028
0
    } else if (vctxt->reader != NULL) {
28029
  /*
28030
   * XML Reader validation.
28031
   */
28032
#ifdef XML_SCHEMA_READER_ENABLED
28033
  ret = xmlSchemaVReaderWalk(vctxt);
28034
#endif
28035
0
#endif
28036
0
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28037
  /*
28038
   * SAX validation.
28039
   */
28040
0
  ret = xmlParseDocument(vctxt->parserCtxt);
28041
0
    } else {
28042
0
  VERROR_INT("xmlSchemaVStart",
28043
0
      "no instance to validate");
28044
0
  ret = -1;
28045
0
    }
28046
28047
0
    xmlSchemaPostRun(vctxt);
28048
0
    if (ret == 0)
28049
0
  ret = vctxt->err;
28050
0
    return (ret);
28051
0
}
28052
28053
/**
28054
 * xmlSchemaValidateOneElement:
28055
 * @ctxt:  a schema validation context
28056
 * @elem:  an element node
28057
 *
28058
 * Validate a branch of a tree, starting with the given @elem.
28059
 *
28060
 * Returns 0 if the element and its subtree is valid, a positive error
28061
 * code number otherwise and -1 in case of an internal or API error.
28062
 */
28063
int
28064
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28065
0
{
28066
0
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28067
0
  return (-1);
28068
28069
0
    if (ctxt->schema == NULL)
28070
0
  return (-1);
28071
28072
0
    ctxt->doc = elem->doc;
28073
0
    ctxt->node = elem;
28074
0
    ctxt->validationRoot = elem;
28075
0
    return(xmlSchemaVStart(ctxt));
28076
0
}
28077
28078
/**
28079
 * xmlSchemaValidateDoc:
28080
 * @ctxt:  a schema validation context
28081
 * @doc:  a parsed document tree
28082
 *
28083
 * Validate a document tree in memory.
28084
 *
28085
 * Returns 0 if the document is schemas valid, a positive error code
28086
 *     number otherwise and -1 in case of internal or API error.
28087
 */
28088
int
28089
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28090
0
{
28091
0
    if ((ctxt == NULL) || (doc == NULL))
28092
0
        return (-1);
28093
28094
0
    ctxt->doc = doc;
28095
0
    ctxt->node = xmlDocGetRootElement(doc);
28096
0
    if (ctxt->node == NULL) {
28097
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
28098
0
      XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28099
0
      (xmlNodePtr) doc, NULL,
28100
0
      "The document has no document element", NULL, NULL);
28101
0
        return (ctxt->err);
28102
0
    }
28103
0
    ctxt->validationRoot = ctxt->node;
28104
0
    return (xmlSchemaVStart(ctxt));
28105
0
}
28106
28107
28108
/************************************************************************
28109
 *                  *
28110
 *    Function and data for SAX streaming API     *
28111
 *                  *
28112
 ************************************************************************/
28113
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28114
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28115
28116
struct _xmlSchemaSplitSAXData {
28117
    xmlSAXHandlerPtr      user_sax;
28118
    void                 *user_data;
28119
    xmlSchemaValidCtxtPtr ctxt;
28120
    xmlSAXHandlerPtr      schemas_sax;
28121
};
28122
28123
0
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28124
28125
struct _xmlSchemaSAXPlug {
28126
    unsigned int magic;
28127
28128
    /* the original callbacks information */
28129
    xmlSAXHandlerPtr     *user_sax_ptr;
28130
    xmlSAXHandlerPtr      user_sax;
28131
    void                **user_data_ptr;
28132
    void                 *user_data;
28133
28134
    /* the block plugged back and validation information */
28135
    xmlSAXHandler         schemas_sax;
28136
    xmlSchemaValidCtxtPtr ctxt;
28137
};
28138
28139
/* All those functions just bounces to the user provided SAX handlers */
28140
static void
28141
internalSubsetSplit(void *ctx, const xmlChar *name,
28142
         const xmlChar *ExternalID, const xmlChar *SystemID)
28143
0
{
28144
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28145
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28146
0
        (ctxt->user_sax->internalSubset != NULL))
28147
0
  ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28148
0
                                 SystemID);
28149
0
}
28150
28151
static int
28152
isStandaloneSplit(void *ctx)
28153
0
{
28154
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28155
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28156
0
        (ctxt->user_sax->isStandalone != NULL))
28157
0
  return(ctxt->user_sax->isStandalone(ctxt->user_data));
28158
0
    return(0);
28159
0
}
28160
28161
static int
28162
hasInternalSubsetSplit(void *ctx)
28163
0
{
28164
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28165
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28166
0
        (ctxt->user_sax->hasInternalSubset != NULL))
28167
0
  return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28168
0
    return(0);
28169
0
}
28170
28171
static int
28172
hasExternalSubsetSplit(void *ctx)
28173
0
{
28174
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28175
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28176
0
        (ctxt->user_sax->hasExternalSubset != NULL))
28177
0
  return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28178
0
    return(0);
28179
0
}
28180
28181
static void
28182
externalSubsetSplit(void *ctx, const xmlChar *name,
28183
         const xmlChar *ExternalID, const xmlChar *SystemID)
28184
0
{
28185
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28186
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28187
0
        (ctxt->user_sax->externalSubset != NULL))
28188
0
  ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28189
0
                                 SystemID);
28190
0
}
28191
28192
static xmlParserInputPtr
28193
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28194
0
{
28195
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28196
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28197
0
        (ctxt->user_sax->resolveEntity != NULL))
28198
0
  return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28199
0
                                       systemId));
28200
0
    return(NULL);
28201
0
}
28202
28203
static xmlEntityPtr
28204
getEntitySplit(void *ctx, const xmlChar *name)
28205
0
{
28206
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28207
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28208
0
        (ctxt->user_sax->getEntity != NULL))
28209
0
  return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28210
0
    return(NULL);
28211
0
}
28212
28213
static xmlEntityPtr
28214
getParameterEntitySplit(void *ctx, const xmlChar *name)
28215
0
{
28216
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28217
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28218
0
        (ctxt->user_sax->getParameterEntity != NULL))
28219
0
  return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28220
0
    return(NULL);
28221
0
}
28222
28223
28224
static void
28225
entityDeclSplit(void *ctx, const xmlChar *name, int type,
28226
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28227
0
{
28228
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28229
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28230
0
        (ctxt->user_sax->entityDecl != NULL))
28231
0
  ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28232
0
                             systemId, content);
28233
0
}
28234
28235
static void
28236
attributeDeclSplit(void *ctx, const xmlChar * elem,
28237
                   const xmlChar * name, int type, int def,
28238
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
28239
0
{
28240
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28241
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28242
0
        (ctxt->user_sax->attributeDecl != NULL)) {
28243
0
  ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28244
0
                                def, defaultValue, tree);
28245
0
    } else {
28246
0
  xmlFreeEnumeration(tree);
28247
0
    }
28248
0
}
28249
28250
static void
28251
elementDeclSplit(void *ctx, const xmlChar *name, int type,
28252
      xmlElementContentPtr content)
28253
0
{
28254
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28255
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28256
0
        (ctxt->user_sax->elementDecl != NULL))
28257
0
  ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28258
0
}
28259
28260
static void
28261
notationDeclSplit(void *ctx, const xmlChar *name,
28262
       const xmlChar *publicId, const xmlChar *systemId)
28263
0
{
28264
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28265
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28266
0
        (ctxt->user_sax->notationDecl != NULL))
28267
0
  ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28268
0
                               systemId);
28269
0
}
28270
28271
static void
28272
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28273
       const xmlChar *publicId, const xmlChar *systemId,
28274
       const xmlChar *notationName)
28275
0
{
28276
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28277
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28278
0
        (ctxt->user_sax->unparsedEntityDecl != NULL))
28279
0
  ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28280
0
                                     systemId, notationName);
28281
0
}
28282
28283
static void
28284
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28285
0
{
28286
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28287
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28288
0
        (ctxt->user_sax->setDocumentLocator != NULL))
28289
0
  ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28290
0
}
28291
28292
static void
28293
startDocumentSplit(void *ctx)
28294
0
{
28295
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28296
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28297
0
        (ctxt->user_sax->startDocument != NULL))
28298
0
  ctxt->user_sax->startDocument(ctxt->user_data);
28299
0
}
28300
28301
static void
28302
endDocumentSplit(void *ctx)
28303
0
{
28304
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28305
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28306
0
        (ctxt->user_sax->endDocument != NULL))
28307
0
  ctxt->user_sax->endDocument(ctxt->user_data);
28308
0
}
28309
28310
static void
28311
processingInstructionSplit(void *ctx, const xmlChar *target,
28312
                      const xmlChar *data)
28313
0
{
28314
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28315
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28316
0
        (ctxt->user_sax->processingInstruction != NULL))
28317
0
  ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28318
0
}
28319
28320
static void
28321
commentSplit(void *ctx, const xmlChar *value)
28322
0
{
28323
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28324
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28325
0
        (ctxt->user_sax->comment != NULL))
28326
0
  ctxt->user_sax->comment(ctxt->user_data, value);
28327
0
}
28328
28329
/*
28330
 * Varargs error callbacks to the user application, harder ...
28331
 */
28332
28333
static void
28334
0
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28335
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28336
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28337
0
        (ctxt->user_sax->warning != NULL)) {
28338
  /* TODO */
28339
0
    }
28340
0
}
28341
static void
28342
0
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28343
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28344
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28345
0
        (ctxt->user_sax->error != NULL)) {
28346
  /* TODO */
28347
0
    }
28348
0
}
28349
static void
28350
0
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28351
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28352
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28353
0
        (ctxt->user_sax->fatalError != NULL)) {
28354
  /* TODO */
28355
0
    }
28356
0
}
28357
28358
/*
28359
 * Those are function where both the user handler and the schemas handler
28360
 * need to be called.
28361
 */
28362
static void
28363
charactersSplit(void *ctx, const xmlChar *ch, int len)
28364
0
{
28365
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28366
0
    if (ctxt == NULL)
28367
0
        return;
28368
0
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28369
0
  ctxt->user_sax->characters(ctxt->user_data, ch, len);
28370
0
    if (ctxt->ctxt != NULL)
28371
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28372
0
}
28373
28374
static void
28375
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28376
0
{
28377
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28378
0
    if (ctxt == NULL)
28379
0
        return;
28380
0
    if ((ctxt->user_sax != NULL) &&
28381
0
        (ctxt->user_sax->ignorableWhitespace != NULL))
28382
0
  ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28383
0
    if (ctxt->ctxt != NULL)
28384
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28385
0
}
28386
28387
static void
28388
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28389
0
{
28390
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28391
0
    if (ctxt == NULL)
28392
0
        return;
28393
0
    if ((ctxt->user_sax != NULL) &&
28394
0
        (ctxt->user_sax->cdataBlock != NULL))
28395
0
  ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28396
0
    if (ctxt->ctxt != NULL)
28397
0
  xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28398
0
}
28399
28400
static void
28401
referenceSplit(void *ctx, const xmlChar *name)
28402
0
{
28403
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28404
0
    if (ctxt == NULL)
28405
0
        return;
28406
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28407
0
        (ctxt->user_sax->reference != NULL))
28408
0
  ctxt->user_sax->reference(ctxt->user_data, name);
28409
0
    if (ctxt->ctxt != NULL)
28410
0
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
28411
0
}
28412
28413
static void
28414
startElementNsSplit(void *ctx, const xmlChar * localname,
28415
        const xmlChar * prefix, const xmlChar * URI,
28416
        int nb_namespaces, const xmlChar ** namespaces,
28417
        int nb_attributes, int nb_defaulted,
28418
0
        const xmlChar ** attributes) {
28419
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28420
0
    if (ctxt == NULL)
28421
0
        return;
28422
0
    if ((ctxt->user_sax != NULL) &&
28423
0
        (ctxt->user_sax->startElementNs != NULL))
28424
0
  ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28425
0
                                 URI, nb_namespaces, namespaces,
28426
0
               nb_attributes, nb_defaulted,
28427
0
               attributes);
28428
0
    if (ctxt->ctxt != NULL)
28429
0
  xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28430
0
                                   URI, nb_namespaces, namespaces,
28431
0
           nb_attributes, nb_defaulted,
28432
0
           attributes);
28433
0
}
28434
28435
static void
28436
endElementNsSplit(void *ctx, const xmlChar * localname,
28437
0
        const xmlChar * prefix, const xmlChar * URI) {
28438
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28439
0
    if (ctxt == NULL)
28440
0
        return;
28441
0
    if ((ctxt->user_sax != NULL) &&
28442
0
        (ctxt->user_sax->endElementNs != NULL))
28443
0
  ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28444
0
    if (ctxt->ctxt != NULL)
28445
0
  xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28446
0
}
28447
28448
/**
28449
 * xmlSchemaSAXPlug:
28450
 * @ctxt:  a schema validation context
28451
 * @sax:  a pointer to the original xmlSAXHandlerPtr
28452
 * @user_data:  a pointer to the original SAX user data pointer
28453
 *
28454
 * Plug a SAX based validation layer in a SAX parsing event flow.
28455
 * The original @saxptr and @dataptr data are replaced by new pointers
28456
 * but the calls to the original will be maintained.
28457
 *
28458
 * Returns a pointer to a data structure needed to unplug the validation layer
28459
 *         or NULL in case of errors.
28460
 */
28461
xmlSchemaSAXPlugPtr
28462
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28463
     xmlSAXHandlerPtr *sax, void **user_data)
28464
0
{
28465
0
    xmlSchemaSAXPlugPtr ret;
28466
0
    xmlSAXHandlerPtr old_sax;
28467
28468
0
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28469
0
        return(NULL);
28470
28471
    /*
28472
     * We only allow to plug into SAX2 event streams
28473
     */
28474
0
    old_sax = *sax;
28475
0
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28476
0
        return(NULL);
28477
0
    if ((old_sax != NULL) &&
28478
0
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28479
0
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28480
0
        return(NULL);
28481
28482
    /*
28483
     * everything seems right allocate the local data needed for that layer
28484
     */
28485
0
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28486
0
    if (ret == NULL) {
28487
0
        return(NULL);
28488
0
    }
28489
0
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28490
0
    ret->magic = XML_SAX_PLUG_MAGIC;
28491
0
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28492
0
    ret->ctxt = ctxt;
28493
0
    ret->user_sax_ptr = sax;
28494
0
    ret->user_sax = old_sax;
28495
0
    if (old_sax == NULL) {
28496
        /*
28497
   * go direct, no need for the split block and functions.
28498
   */
28499
0
  ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28500
0
  ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28501
  /*
28502
   * Note that we use the same text-function for both, to prevent
28503
   * the parser from testing for ignorable whitespace.
28504
   */
28505
0
  ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28506
0
  ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28507
28508
0
  ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28509
0
  ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28510
28511
0
  ret->user_data = ctxt;
28512
0
  *user_data = ctxt;
28513
0
    } else {
28514
       /*
28515
        * for each callback unused by Schemas initialize it to the Split
28516
  * routine only if non NULL in the user block, this can speed up
28517
  * things at the SAX level.
28518
  */
28519
0
        if (old_sax->internalSubset != NULL)
28520
0
            ret->schemas_sax.internalSubset = internalSubsetSplit;
28521
0
        if (old_sax->isStandalone != NULL)
28522
0
            ret->schemas_sax.isStandalone = isStandaloneSplit;
28523
0
        if (old_sax->hasInternalSubset != NULL)
28524
0
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28525
0
        if (old_sax->hasExternalSubset != NULL)
28526
0
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28527
0
        if (old_sax->resolveEntity != NULL)
28528
0
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
28529
0
        if (old_sax->getEntity != NULL)
28530
0
            ret->schemas_sax.getEntity = getEntitySplit;
28531
0
        if (old_sax->entityDecl != NULL)
28532
0
            ret->schemas_sax.entityDecl = entityDeclSplit;
28533
0
        if (old_sax->notationDecl != NULL)
28534
0
            ret->schemas_sax.notationDecl = notationDeclSplit;
28535
0
        if (old_sax->attributeDecl != NULL)
28536
0
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
28537
0
        if (old_sax->elementDecl != NULL)
28538
0
            ret->schemas_sax.elementDecl = elementDeclSplit;
28539
0
        if (old_sax->unparsedEntityDecl != NULL)
28540
0
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28541
0
        if (old_sax->setDocumentLocator != NULL)
28542
0
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28543
0
        if (old_sax->startDocument != NULL)
28544
0
            ret->schemas_sax.startDocument = startDocumentSplit;
28545
0
        if (old_sax->endDocument != NULL)
28546
0
            ret->schemas_sax.endDocument = endDocumentSplit;
28547
0
        if (old_sax->processingInstruction != NULL)
28548
0
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
28549
0
        if (old_sax->comment != NULL)
28550
0
            ret->schemas_sax.comment = commentSplit;
28551
0
        if (old_sax->warning != NULL)
28552
0
            ret->schemas_sax.warning = warningSplit;
28553
0
        if (old_sax->error != NULL)
28554
0
            ret->schemas_sax.error = errorSplit;
28555
0
        if (old_sax->fatalError != NULL)
28556
0
            ret->schemas_sax.fatalError = fatalErrorSplit;
28557
0
        if (old_sax->getParameterEntity != NULL)
28558
0
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28559
0
        if (old_sax->externalSubset != NULL)
28560
0
            ret->schemas_sax.externalSubset = externalSubsetSplit;
28561
28562
  /*
28563
   * the 6 schemas callback have to go to the splitter functions
28564
   * Note that we use the same text-function for ignorableWhitespace
28565
   * if possible, to prevent the parser from testing for ignorable
28566
   * whitespace.
28567
   */
28568
0
        ret->schemas_sax.characters = charactersSplit;
28569
0
  if ((old_sax->ignorableWhitespace != NULL) &&
28570
0
      (old_sax->ignorableWhitespace != old_sax->characters))
28571
0
      ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28572
0
  else
28573
0
      ret->schemas_sax.ignorableWhitespace = charactersSplit;
28574
0
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
28575
0
        ret->schemas_sax.reference = referenceSplit;
28576
0
        ret->schemas_sax.startElementNs = startElementNsSplit;
28577
0
        ret->schemas_sax.endElementNs = endElementNsSplit;
28578
28579
0
  ret->user_data_ptr = user_data;
28580
0
  ret->user_data = *user_data;
28581
0
  *user_data = ret;
28582
0
    }
28583
28584
    /*
28585
     * plug the pointers back.
28586
     */
28587
0
    *sax = &(ret->schemas_sax);
28588
0
    ctxt->sax = *sax;
28589
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28590
0
    xmlSchemaPreRun(ctxt);
28591
0
    return(ret);
28592
0
}
28593
28594
/**
28595
 * xmlSchemaSAXUnplug:
28596
 * @plug:  a data structure returned by xmlSchemaSAXPlug
28597
 *
28598
 * Unplug a SAX based validation layer in a SAX parsing event flow.
28599
 * The original pointers used in the call are restored.
28600
 *
28601
 * Returns 0 in case of success and -1 in case of failure.
28602
 */
28603
int
28604
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28605
0
{
28606
0
    xmlSAXHandlerPtr *sax;
28607
0
    void **user_data;
28608
28609
0
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28610
0
        return(-1);
28611
0
    plug->magic = 0;
28612
28613
0
    xmlSchemaPostRun(plug->ctxt);
28614
    /* restore the data */
28615
0
    sax = plug->user_sax_ptr;
28616
0
    *sax = plug->user_sax;
28617
0
    if (plug->user_sax != NULL) {
28618
0
  user_data = plug->user_data_ptr;
28619
0
  *user_data = plug->user_data;
28620
0
    }
28621
28622
    /* free and return */
28623
0
    xmlFree(plug);
28624
0
    return(0);
28625
0
}
28626
28627
/**
28628
 * xmlSchemaValidateSetLocator:
28629
 * @vctxt: a schema validation context
28630
 * @f: the locator function pointer
28631
 * @ctxt: the locator context
28632
 *
28633
 * Allows to set a locator function to the validation context,
28634
 * which will be used to provide file and line information since
28635
 * those are not provided as part of the SAX validation flow
28636
 * Setting @f to NULL disable the locator.
28637
 */
28638
28639
void
28640
xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
28641
                            xmlSchemaValidityLocatorFunc f,
28642
          void *ctxt)
28643
0
{
28644
0
    if (vctxt == NULL) return;
28645
0
    vctxt->locFunc = f;
28646
0
    vctxt->locCtxt = ctxt;
28647
0
}
28648
28649
/**
28650
 * xmlSchemaValidateStreamLocator:
28651
 * @ctx: the xmlTextReaderPtr used
28652
 * @file: returned file information
28653
 * @line: returned line information
28654
 *
28655
 * Internal locator function for the readers
28656
 *
28657
 * Returns 0 in case the Schema validation could be (de)activated and
28658
 *         -1 in case of error.
28659
 */
28660
static int
28661
xmlSchemaValidateStreamLocator(void *ctx, const char **file,
28662
0
                               unsigned long *line) {
28663
0
    xmlParserCtxtPtr ctxt;
28664
28665
0
    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
28666
0
        return(-1);
28667
28668
0
    if (file != NULL)
28669
0
        *file = NULL;
28670
0
    if (line != NULL)
28671
0
        *line = 0;
28672
28673
0
    ctxt = (xmlParserCtxtPtr) ctx;
28674
0
    if (ctxt->input != NULL) {
28675
0
       if (file != NULL)
28676
0
           *file = ctxt->input->filename;
28677
0
       if (line != NULL)
28678
0
           *line = ctxt->input->line;
28679
0
       return(0);
28680
0
    }
28681
0
    return(-1);
28682
0
}
28683
28684
/**
28685
 * xmlSchemaValidateStreamInternal:
28686
 * @ctxt:  a schema validation context
28687
 * @pctxt:  a parser context
28688
 *
28689
 * Returns 0 if the document is schemas valid, a positive error code
28690
 *     number otherwise and -1 in case of internal or API error.
28691
 */
28692
static int
28693
xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
28694
0
                                 xmlParserCtxtPtr pctxt) {
28695
0
    xmlSchemaSAXPlugPtr plug = NULL;
28696
0
    int ret;
28697
28698
0
    pctxt->linenumbers = 1;
28699
0
    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
28700
28701
0
    ctxt->parserCtxt = pctxt;
28702
0
    ctxt->input = pctxt->input->buf;
28703
28704
    /*
28705
     * Plug the validation and launch the parsing
28706
     */
28707
0
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28708
0
    if (plug == NULL) {
28709
0
        ret = -1;
28710
0
  goto done;
28711
0
    }
28712
0
    ctxt->input = pctxt->input->buf;
28713
0
    ctxt->sax = pctxt->sax;
28714
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28715
0
    ret = xmlSchemaVStart(ctxt);
28716
28717
0
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28718
0
  ret = ctxt->parserCtxt->errNo;
28719
0
  if (ret == 0)
28720
0
      ret = 1;
28721
0
    }
28722
28723
0
done:
28724
0
    ctxt->parserCtxt = NULL;
28725
0
    ctxt->sax = NULL;
28726
0
    ctxt->input = NULL;
28727
0
    if (plug != NULL) {
28728
0
        xmlSchemaSAXUnplug(plug);
28729
0
    }
28730
0
    return (ret);
28731
0
}
28732
28733
/**
28734
 * xmlSchemaValidateStream:
28735
 * @ctxt:  a schema validation context
28736
 * @input:  the input to use for reading the data
28737
 * @enc:  an optional encoding information
28738
 * @sax:  a SAX handler for the resulting events
28739
 * @user_data:  the context to provide to the SAX handler.
28740
 *
28741
 * Validate an input based on a flow of SAX event from the parser
28742
 * and forward the events to the @sax handler with the provided @user_data
28743
 * the user provided @sax handler must be a SAX2 one.
28744
 *
28745
 * Returns 0 if the document is schemas valid, a positive error code
28746
 *     number otherwise and -1 in case of internal or API error.
28747
 */
28748
int
28749
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28750
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
28751
                        xmlSAXHandlerPtr sax, void *user_data)
28752
0
{
28753
0
    xmlParserCtxtPtr pctxt = NULL;
28754
0
    xmlParserInputPtr inputStream = NULL;
28755
0
    int ret;
28756
28757
0
    if ((ctxt == NULL) || (input == NULL))
28758
0
        return (-1);
28759
28760
    /*
28761
     * prepare the parser
28762
     */
28763
0
    if (sax != NULL) {
28764
0
        pctxt = xmlNewSAXParserCtxt(sax, user_data);
28765
0
        if (pctxt == NULL)
28766
0
            return (-1);
28767
0
    } else {
28768
0
        pctxt = xmlNewParserCtxt();
28769
0
        if (pctxt == NULL)
28770
0
            return (-1);
28771
        /* We really want pctxt->sax to be NULL here. */
28772
0
        xmlFree(pctxt->sax);
28773
0
        pctxt->sax = NULL;
28774
0
    }
28775
#if 0
28776
    if (options)
28777
        xmlCtxtUseOptions(pctxt, options);
28778
#endif
28779
28780
0
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28781
0
    if (inputStream == NULL) {
28782
0
        ret = -1;
28783
0
  goto done;
28784
0
    }
28785
0
    inputPush(pctxt, inputStream);
28786
28787
0
    ctxt->enc = enc;
28788
28789
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28790
28791
0
done:
28792
    /* cleanup */
28793
0
    if (pctxt != NULL) {
28794
0
  xmlFreeParserCtxt(pctxt);
28795
0
    }
28796
0
    return (ret);
28797
0
}
28798
28799
/**
28800
 * xmlSchemaValidateFile:
28801
 * @ctxt: a schema validation context
28802
 * @filename: the URI of the instance
28803
 * @options: a future set of options, currently unused
28804
 *
28805
 * Do a schemas validation of the given resource, it will use the
28806
 * SAX streamable validation internally.
28807
 *
28808
 * Returns 0 if the document is valid, a positive error code
28809
 *     number otherwise and -1 in case of an internal or API error.
28810
 */
28811
int
28812
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28813
                      const char * filename,
28814
          int options ATTRIBUTE_UNUSED)
28815
0
{
28816
0
    int ret;
28817
0
    xmlParserCtxtPtr pctxt = NULL;
28818
28819
0
    if ((ctxt == NULL) || (filename == NULL))
28820
0
        return (-1);
28821
28822
0
    pctxt = xmlCreateURLParserCtxt(filename, 0);
28823
0
    if (pctxt == NULL)
28824
0
  return (-1);
28825
    /* We really want pctxt->sax to be NULL here. */
28826
0
    xmlFree(pctxt->sax);
28827
0
    pctxt->sax = NULL;
28828
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28829
0
    xmlFreeParserCtxt(pctxt);
28830
0
    return (ret);
28831
0
}
28832
28833
/**
28834
 * xmlSchemaValidCtxtGetParserCtxt:
28835
 * @ctxt: a schema validation context
28836
 *
28837
 * allow access to the parser context of the schema validation context
28838
 *
28839
 * Returns the parser context of the schema validation context or NULL
28840
 *         in case of error.
28841
 */
28842
xmlParserCtxtPtr
28843
xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28844
0
{
28845
0
    if (ctxt == NULL)
28846
0
        return(NULL);
28847
0
    return (ctxt->parserCtxt);
28848
0
}
28849
28850
#endif /* LIBXML_SCHEMAS_ENABLED */