Coverage Report

Created: 2026-07-24 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxml2/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
 * Author: Daniel Veillard
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/memory.h"
81
#include "private/string.h"
82
83
/* #define WXS_ELEM_DECL_CONS_ENABLED */
84
85
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
86
87
#define ENABLE_REDEFINE
88
89
/* #define ENABLE_NAMED_LOCALS */
90
91
/* #define ENABLE_IDC_NODE_TABLES_TEST */
92
93
#define DUMP_CONTENT_MODEL
94
95
#ifdef LIBXML_READER_ENABLED
96
/* #define XML_SCHEMA_READER_ENABLED */
97
#endif
98
99
0
#define UNBOUNDED (1 << 30)
100
101
0
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
102
103
/*
104
 * The XML Schemas namespaces
105
 */
106
static const xmlChar *xmlSchemaNs = (const xmlChar *)
107
    "http://www.w3.org/2001/XMLSchema";
108
109
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
110
    "http://www.w3.org/2001/XMLSchema-instance";
111
112
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
113
    "http://www.w3.org/2000/xmlns/";
114
115
/*
116
* Come casting macros.
117
*/
118
0
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
119
0
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
120
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
121
0
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
122
0
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
123
0
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
124
0
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
125
0
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
126
0
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
127
0
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
128
0
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
129
0
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
130
0
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
131
0
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
132
0
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
133
0
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
134
0
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
135
136
/*
137
* Macros to query common properties of components.
138
*/
139
0
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
140
141
0
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
142
/*
143
* Macros for element declarations.
144
*/
145
0
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
146
147
0
#define WXS_SUBST_HEAD(item) (item)->refDecl
148
/*
149
* Macros for attribute declarations.
150
*/
151
0
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
152
/*
153
* Macros for attribute uses.
154
*/
155
0
#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
156
157
0
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
158
159
0
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
160
161
0
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
162
/*
163
* Macros for attribute groups.
164
*/
165
0
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
166
0
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
167
/*
168
* Macros for particles.
169
*/
170
0
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
171
172
0
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
173
174
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
175
176
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
177
/*
178
* Macros for model groups definitions.
179
*/
180
0
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
181
/*
182
* Macros for model groups.
183
*/
184
#define WXS_IS_MODEL_GROUP(i) \
185
0
    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
186
0
     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
187
0
     ((i)->type == XML_SCHEMA_TYPE_ALL))
188
189
0
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
190
/*
191
* Macros for schema buckets.
192
*/
193
0
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
194
0
    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
195
196
0
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
197
0
    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
198
199
0
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
200
201
0
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
202
/*
203
* Macros for complex/simple types.
204
*/
205
#define WXS_IS_ANYTYPE(i) \
206
0
     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
207
0
      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
208
209
#define WXS_IS_COMPLEX(i) \
210
0
    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
211
0
     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
212
213
#define WXS_IS_SIMPLE(item) \
214
0
    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
215
0
     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
216
0
      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
217
218
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
219
0
    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
220
0
      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
221
222
#define WXS_IS_RESTRICTION(t) \
223
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
224
225
#define WXS_IS_EXTENSION(t) \
226
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
227
228
#define WXS_IS_TYPE_NOT_FIXED(i) \
229
0
    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
230
0
     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
231
232
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
233
0
    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
234
0
     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
235
236
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
237
238
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
239
/*
240
* Macros for exclusively for complex types.
241
*/
242
#define WXS_HAS_COMPLEX_CONTENT(item) \
243
    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
244
     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
245
     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
246
247
#define WXS_HAS_SIMPLE_CONTENT(item) \
248
0
    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
249
0
     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
250
251
#define WXS_HAS_MIXED_CONTENT(item) \
252
0
    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
253
254
#define WXS_EMPTIABLE(t) \
255
0
    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
256
257
0
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
258
259
0
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
260
261
0
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
262
/*
263
* Macros for exclusively for simple types.
264
*/
265
0
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
266
267
0
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
268
269
0
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
270
271
0
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
272
/*
273
* Misc parser context macros.
274
*/
275
0
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
276
277
0
#define WXS_HAS_BUCKETS(ctx) \
278
0
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
279
0
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
280
281
0
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
282
283
0
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
284
285
#define WXS_SCHEMA(ctx) (ctx)->schema
286
287
#define WXS_ADD_LOCAL(ctx, item) \
288
0
    do { \
289
0
        if ((item != NULL) && \
290
0
            (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, \
291
0
                                  item) < 0)) { \
292
0
            xmlSchemaPErrMemory(ctx); \
293
0
            xmlFree(item); \
294
0
            item = NULL; \
295
0
        } \
296
0
    } while (0)
297
298
#define WXS_ADD_GLOBAL(ctx, item) \
299
0
    do { \
300
0
        if ((item != NULL) && \
301
0
            (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, \
302
0
                                  item) < 0)) { \
303
0
            xmlSchemaPErrMemory(ctx); \
304
0
            xmlFree(item); \
305
0
            item = NULL; \
306
0
        } \
307
0
    } while (0)
308
309
#define WXS_ADD_PENDING(ctx, item) \
310
0
    do { \
311
0
        if ((item != NULL) && \
312
0
            (xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, \
313
0
                                  item) < 0)) { \
314
0
            xmlSchemaPErrMemory(ctx); \
315
0
        } \
316
0
    } while (0)
317
/*
318
* xmlSchemaItemList macros.
319
*/
320
0
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
321
/*
322
* Misc macros.
323
*/
324
#define IS_SCHEMA(node, type) \
325
0
   ((node != NULL) && (node->ns != NULL) && \
326
0
    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
327
0
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
328
329
0
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
330
331
/*
332
* Since we put the default/fixed values into the dict, we can
333
* use pointer comparison for those values.
334
* REMOVED: (xmlStrEqual((v1), (v2)))
335
*/
336
0
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
337
338
0
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
339
340
0
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
341
342
0
#define HFAILURE if (res == -1) goto exit_failure;
343
344
0
#define HERROR if (res != 0) goto exit_error;
345
346
0
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
347
/*
348
* Some flags used for various schema constraints.
349
*/
350
0
#define SUBSET_RESTRICTION  1<<0
351
0
#define SUBSET_EXTENSION    1<<1
352
#define SUBSET_SUBSTITUTION 1<<2
353
#define SUBSET_LIST         1<<3
354
#define SUBSET_UNION        1<<4
355
356
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
357
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
358
359
typedef struct _xmlSchemaItemList xmlSchemaItemList;
360
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
361
struct _xmlSchemaItemList {
362
    void **items;  /* used for dynamic addition of schemata */
363
    int nbItems; /* used for dynamic addition of schemata */
364
    int sizeItems; /* used for dynamic addition of schemata */
365
};
366
367
0
#define XML_SCHEMA_CTXT_PARSER 1
368
0
#define XML_SCHEMA_CTXT_VALIDATOR 2
369
370
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
371
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
372
struct _xmlSchemaAbstractCtxt {
373
    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
374
    void *dummy; /* Fix alignment issues */
375
};
376
377
typedef struct _xmlSchemaBucket xmlSchemaBucket;
378
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
379
380
0
#define XML_SCHEMA_SCHEMA_MAIN 0
381
0
#define XML_SCHEMA_SCHEMA_IMPORT 1
382
0
#define XML_SCHEMA_SCHEMA_INCLUDE 2
383
0
#define XML_SCHEMA_SCHEMA_REDEFINE 3
384
385
/**
386
 * Used to create a graph of schema relationships.
387
 */
388
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
389
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
390
struct _xmlSchemaSchemaRelation {
391
    xmlSchemaSchemaRelationPtr next;
392
    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
393
    const xmlChar *importNamespace;
394
    xmlSchemaBucketPtr bucket;
395
};
396
397
0
#define XML_SCHEMA_BUCKET_MARKED 1<<0
398
0
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
399
400
struct _xmlSchemaBucket {
401
    int type;
402
    int flags;
403
    const xmlChar *schemaLocation;
404
    const xmlChar *origTargetNamespace;
405
    const xmlChar *targetNamespace;
406
    xmlDocPtr doc;
407
    xmlSchemaSchemaRelationPtr relations;
408
    int located;
409
    int parsed;
410
    int imported;
411
    int preserveDoc;
412
    xmlSchemaItemListPtr globals; /* Global components. */
413
    xmlSchemaItemListPtr locals; /* Local components. */
414
};
415
416
/**
417
 * (extends xmlSchemaBucket)
418
 *
419
 * Reflects a schema. Holds some information
420
 * about the schema and its toplevel components. Duplicate
421
 * toplevel components are not checked at this level.
422
 */
423
typedef struct _xmlSchemaImport xmlSchemaImport;
424
typedef xmlSchemaImport *xmlSchemaImportPtr;
425
struct _xmlSchemaImport {
426
    int type; /* Main OR import OR include. */
427
    int flags;
428
    const xmlChar *schemaLocation; /* The URI of the schema document. */
429
    /* For chameleon includes, @origTargetNamespace will be NULL */
430
    const xmlChar *origTargetNamespace;
431
    /*
432
    * For chameleon includes, @targetNamespace will be the
433
    * targetNamespace of the including schema.
434
    */
435
    const xmlChar *targetNamespace;
436
    xmlDocPtr doc; /* The schema node-tree. */
437
    /* @relations will hold any included/imported/redefined schemas. */
438
    xmlSchemaSchemaRelationPtr relations;
439
    int located;
440
    int parsed;
441
    int imported;
442
    int preserveDoc;
443
    xmlSchemaItemListPtr globals;
444
    xmlSchemaItemListPtr locals;
445
    /* The imported schema. */
446
    xmlSchemaPtr schema;
447
};
448
449
/*
450
* (extends xmlSchemaBucket)
451
*/
452
typedef struct _xmlSchemaInclude xmlSchemaInclude;
453
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
454
struct _xmlSchemaInclude {
455
    int type;
456
    int flags;
457
    const xmlChar *schemaLocation;
458
    const xmlChar *origTargetNamespace;
459
    const xmlChar *targetNamespace;
460
    xmlDocPtr doc;
461
    xmlSchemaSchemaRelationPtr relations;
462
    int located;
463
    int parsed;
464
    int imported;
465
    int preserveDoc;
466
    xmlSchemaItemListPtr globals; /* Global components. */
467
    xmlSchemaItemListPtr locals; /* Local components. */
468
469
    /* The owning main or import schema bucket. */
470
    xmlSchemaImportPtr ownerImport;
471
};
472
473
/**
474
 * The abstract base type for schema components.
475
 */
476
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
477
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
478
struct _xmlSchemaBasicItem {
479
    xmlSchemaTypeType type;
480
    void *dummy; /* Fix alignment issues */
481
};
482
483
/**
484
 * The abstract base type for annotated schema components.
485
 * (Extends xmlSchemaBasicItem)
486
 */
487
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
488
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
489
struct _xmlSchemaAnnotItem {
490
    xmlSchemaTypeType type;
491
    xmlSchemaAnnotPtr annot;
492
};
493
494
/**
495
 * The abstract base type for tree-like structured schema components.
496
 * (Extends xmlSchemaAnnotItem)
497
 */
498
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
499
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
500
struct _xmlSchemaTreeItem {
501
    xmlSchemaTypeType type;
502
    xmlSchemaAnnotPtr annot;
503
    xmlSchemaTreeItemPtr next;
504
    xmlSchemaTreeItemPtr children;
505
};
506
507
508
0
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
509
/**
510
 * The abstract base type for tree-like structured schema components.
511
 * (Extends xmlSchemaTreeItem)
512
 */
513
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
514
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
515
struct _xmlSchemaAttributeUse {
516
    xmlSchemaTypeType type;
517
    xmlSchemaAnnotPtr annot;
518
    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
519
    /*
520
    * The attr. decl. OR a QName-ref. to an attr. decl. OR
521
    * a QName-ref. to an attribute group definition.
522
    */
523
    xmlSchemaAttributePtr attrDecl;
524
525
    int flags;
526
    xmlNodePtr node;
527
    int occurs; /* required, optional */
528
    const xmlChar * defValue;
529
    xmlSchemaValPtr defVal;
530
};
531
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
 */
548
typedef struct _xmlSchemaRedef xmlSchemaRedef;
549
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
550
struct _xmlSchemaRedef {
551
    xmlSchemaRedefPtr next;
552
    xmlSchemaBasicItemPtr item; /* The redefining component. */
553
    xmlSchemaBasicItemPtr reference; /* The referencing component. */
554
    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
555
    const xmlChar *refName; /* The name of the to-be-redefined component. */
556
    const xmlChar *refTargetNs; /* The target namespace of the
557
                                   to-be-redefined comp. */
558
    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
559
};
560
561
/**
562
 */
563
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
564
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
565
struct _xmlSchemaConstructionCtxt {
566
    xmlSchemaPtr mainSchema; /* The main schema. */
567
    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
568
    xmlDictPtr dict;
569
    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
570
    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
571
    xmlSchemaBucketPtr bucket; /* The current schema bucket */
572
    xmlSchemaItemListPtr pending; /* All Components of all schemas that
573
                                     need to be fixed. */
574
    xmlHashTablePtr substGroups;
575
    xmlSchemaRedefPtr redefs;
576
    xmlSchemaRedefPtr lastRedef;
577
};
578
579
#define XML_SCHEMAS_PARSE_ERROR   1
580
0
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
581
582
struct _xmlSchemaParserCtxt {
583
    int type;
584
    void *errCtxt;             /* user specific error context */
585
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
586
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
587
    int err;
588
    int nberrors;
589
    xmlStructuredErrorFunc serror;
590
591
    xmlSchemaConstructionCtxtPtr constructor;
592
    int ownsConstructor; /* TODO: Move this to parser *flags*. */
593
594
    /* xmlSchemaPtr topschema;  */
595
    /* xmlHashTablePtr namespaces;  */
596
597
    xmlSchemaPtr schema;        /* The main schema in use */
598
    int counter;
599
600
    const xmlChar *URL;
601
    xmlDocPtr doc;
602
    int preserve;   /* Whether the doc should be freed  */
603
604
    const char *buffer;
605
    int size;
606
607
    /*
608
     * Used to build complex element content models
609
     */
610
    xmlAutomataPtr am;
611
    xmlAutomataStatePtr start;
612
    xmlAutomataStatePtr end;
613
    xmlAutomataStatePtr state;
614
615
    xmlDictPtr dict;    /* dictionary for interned string names */
616
    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
617
    int options;
618
    xmlSchemaValidCtxtPtr vctxt;
619
    int isS4S;
620
    int isRedefine;
621
    int xsiAssemble;
622
    int stop; /* If the parser should stop; i.e. a critical error. */
623
    const xmlChar *targetNamespace;
624
    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
625
626
    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
627
    int redefCounter; /* Used for redefinitions. */
628
    xmlSchemaItemListPtr attrProhibs;
629
630
    xmlResourceLoader resourceLoader;
631
    void *resourceCtxt;
632
};
633
634
/**
635
 * A component reference item (not a schema component)
636
 * (Extends xmlSchemaBasicItem)
637
 */
638
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
639
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
640
struct _xmlSchemaQNameRef {
641
    xmlSchemaTypeType type;
642
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
643
    xmlSchemaTypeType itemType;
644
    const xmlChar *name;
645
    const xmlChar *targetNamespace;
646
    xmlNodePtr node;
647
};
648
649
/**
650
 * A particle component.
651
 * (Extends xmlSchemaTreeItem)
652
 */
653
typedef struct _xmlSchemaParticle xmlSchemaParticle;
654
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
655
struct _xmlSchemaParticle {
656
    xmlSchemaTypeType type;
657
    xmlSchemaAnnotPtr annot;
658
    xmlSchemaTreeItemPtr next; /* next particle */
659
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
660
  a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
661
        etc.) */
662
    int minOccurs;
663
    int maxOccurs;
664
    xmlNodePtr node;
665
};
666
667
/**
668
 * A model group component.
669
 * (Extends xmlSchemaTreeItem)
670
 */
671
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
672
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
673
struct _xmlSchemaModelGroup {
674
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
675
    xmlSchemaAnnotPtr annot;
676
    xmlSchemaTreeItemPtr next; /* not used */
677
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
678
    xmlNodePtr node;
679
};
680
681
0
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
682
0
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
683
/**
684
 * A model group definition component.
685
 * (Extends xmlSchemaTreeItem)
686
 */
687
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
688
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
689
struct _xmlSchemaModelGroupDef {
690
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
691
    xmlSchemaAnnotPtr annot;
692
    xmlSchemaTreeItemPtr next; /* not used */
693
    xmlSchemaTreeItemPtr children; /* the "model group" */
694
    const xmlChar *name;
695
    const xmlChar *targetNamespace;
696
    xmlNodePtr node;
697
    int flags;
698
};
699
700
typedef struct _xmlSchemaIDC xmlSchemaIDC;
701
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
702
703
/**
704
 * The identity-constraint "field" and "selector" item, holding the
705
 * XPath expression.
706
 */
707
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
708
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
709
struct _xmlSchemaIDCSelect {
710
    xmlSchemaIDCSelectPtr next;
711
    xmlSchemaIDCPtr idc;
712
    int index; /* an index position if significant for IDC key-sequences */
713
    const xmlChar *xpath; /* the XPath expression */
714
    void *xpathComp; /* the compiled XPath expression */
715
};
716
717
/**
718
 * The identity-constraint definition component.
719
 * (Extends xmlSchemaAnnotItem)
720
 */
721
722
struct _xmlSchemaIDC {
723
    xmlSchemaTypeType type;
724
    xmlSchemaAnnotPtr annot;
725
    xmlSchemaIDCPtr next;
726
    xmlNodePtr node;
727
    const xmlChar *name;
728
    const xmlChar *targetNamespace;
729
    xmlSchemaIDCSelectPtr selector;
730
    xmlSchemaIDCSelectPtr fields;
731
    int nbFields;
732
    xmlSchemaQNameRefPtr ref;
733
};
734
735
/**
736
 * The augmented IDC information used for validation.
737
 */
738
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
739
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
740
struct _xmlSchemaIDCAug {
741
    xmlSchemaIDCAugPtr next; /* next in a list */
742
    xmlSchemaIDCPtr def; /* the IDC definition */
743
    int keyrefDepth; /* the lowest tree level to which IDC
744
                        tables need to be bubbled upwards */
745
};
746
747
/**
748
 * The key sequence of a node table item.
749
 */
750
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
751
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
752
struct _xmlSchemaPSVIIDCKey {
753
    xmlSchemaTypePtr type;
754
    xmlSchemaValPtr val;
755
};
756
757
/**
758
 * The node table item of a node table.
759
 */
760
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
761
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
762
struct _xmlSchemaPSVIIDCNode {
763
    xmlNodePtr node;
764
    xmlSchemaPSVIIDCKeyPtr *keys;
765
    int nodeLine;
766
    int nodeQNameID;
767
768
};
769
770
/**
771
 * The identity-constraint binding item of the [identity-constraint table].
772
 */
773
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
774
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
775
struct _xmlSchemaPSVIIDCBinding {
776
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
777
    xmlSchemaIDCPtr definition; /* the IDC definition */
778
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
779
    int nbNodes; /* number of entries in the node table */
780
    int sizeNodes; /* size of the node table */
781
    xmlSchemaItemListPtr dupls;
782
};
783
784
785
0
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
786
0
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
787
788
#define XPATH_STATE_OBJ_MATCHES -2
789
#define XPATH_STATE_OBJ_BLOCKED -3
790
791
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
792
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
793
794
/**
795
 * The state object used to evaluate XPath expressions.
796
 */
797
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
798
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
799
struct _xmlSchemaIDCStateObj {
800
    int type;
801
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
802
    int depth; /* depth of creation */
803
    int *history; /* list of (depth, state-id) tuples */
804
    int nbHistory;
805
    int sizeHistory;
806
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
807
                                       matcher */
808
    xmlSchemaIDCSelectPtr sel;
809
    void *xpathCtxt;
810
};
811
812
0
#define IDC_MATCHER 0
813
814
/**
815
 * Used to evaluate IDC selectors (and fields).
816
 */
817
struct _xmlSchemaIDCMatcher {
818
    int type;
819
    int depth; /* the tree depth at creation time */
820
    xmlSchemaIDCMatcherPtr next; /* next in the list */
821
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
822
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
823
    int idcType;
824
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
825
                                         elements */
826
    int sizeKeySeqs;
827
    xmlSchemaItemListPtr targets; /* list of target-node
828
                                     (xmlSchemaPSVIIDCNodePtr) entries */
829
    xmlHashTablePtr htab;
830
};
831
832
/*
833
* Element info flags.
834
*/
835
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  (1<<0)
836
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES (1<<1)
837
0
#define XML_SCHEMA_ELEM_INFO_NILLED            (1<<2)
838
0
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        (1<<3)
839
840
0
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      (1<<4)
841
0
#define XML_SCHEMA_ELEM_INFO_EMPTY             (1<<5)
842
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       (1<<6)
843
844
0
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  (1<<7)
845
0
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT   (1<<8)
846
0
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  (1<<9)
847
0
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE      (1<<10)
848
849
/**
850
 * Holds information of an element node.
851
 */
852
struct _xmlSchemaNodeInfo {
853
    int nodeType;
854
    xmlNodePtr node;
855
    int nodeLine;
856
    const xmlChar *localName;
857
    const xmlChar *nsName;
858
    const xmlChar *value;
859
    xmlSchemaValPtr val; /* the pre-computed value if any */
860
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
861
862
    int flags; /* combination of node info flags */
863
864
    int valNeeded;
865
    int normVal;
866
867
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
868
    int depth;
869
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
870
                                            for the scope element*/
871
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
872
                                           element */
873
    xmlRegExecCtxtPtr regexCtxt;
874
875
    const xmlChar **nsBindings; /* Namespace bindings on this element */
876
    int nbNsBindings;
877
    int sizeNsBindings;
878
879
    int hasKeyrefs;
880
    int appliedXPath; /* Indicates that an XPath has been applied. */
881
};
882
883
0
#define XML_SCHEMAS_ATTR_UNKNOWN 1
884
0
#define XML_SCHEMAS_ATTR_ASSESSED 2
885
#define XML_SCHEMAS_ATTR_PROHIBITED 3
886
0
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
887
0
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
888
0
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
889
0
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
890
0
#define XML_SCHEMAS_ATTR_DEFAULT 8
891
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
892
0
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
893
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
894
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
895
0
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
896
0
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
897
0
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
898
0
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
899
0
#define XML_SCHEMAS_ATTR_META 17
900
/*
901
* @metaType values of xmlSchemaAttrInfo.
902
*/
903
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
904
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
905
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
906
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
907
0
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
908
909
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
910
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
911
struct _xmlSchemaAttrInfo {
912
    int nodeType;
913
    xmlNodePtr node;
914
    int nodeLine;
915
    const xmlChar *localName;
916
    const xmlChar *nsName;
917
    const xmlChar *value;
918
    xmlSchemaValPtr val; /* the pre-computed value if any */
919
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
920
    int flags; /* combination of node info flags */
921
922
    xmlSchemaAttributePtr decl; /* the attribute declaration */
923
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
924
    int state;
925
    int metaType;
926
    const xmlChar *vcValue; /* the value constraint value */
927
    xmlSchemaNodeInfoPtr parent;
928
};
929
930
931
0
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
932
/**
933
 * A Schemas validation context
934
 */
935
struct _xmlSchemaValidCtxt {
936
    int type;
937
    void *errCtxt;             /* user specific data block */
938
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
939
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
940
    xmlStructuredErrorFunc serror;
941
942
    xmlSchemaPtr schema;        /* The schema in use */
943
    xmlDocPtr doc;
944
    xmlParserInputBufferPtr input;
945
    xmlCharEncoding enc;
946
    xmlSAXHandlerPtr sax;
947
    xmlParserCtxtPtr parserCtxt;
948
    void *user_data; /* TODO: What is this for? */
949
    char *filename;
950
951
    int err;
952
    int nberrors;
953
954
    xmlNodePtr node;
955
    xmlNodePtr cur;
956
    /* xmlSchemaTypePtr type; */
957
958
    xmlRegExecCtxtPtr regexp;
959
    xmlSchemaValPtr value;
960
961
    int valueWS;
962
    int options;
963
    xmlNodePtr validationRoot;
964
    xmlSchemaParserCtxtPtr pctxt;
965
    int xsiAssemble;
966
967
    int depth;
968
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
969
    int sizeElemInfos;
970
    xmlSchemaNodeInfoPtr inode; /* the current element information */
971
972
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
973
974
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
975
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
976
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
977
978
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
979
    int nbIdcNodes;
980
    int sizeIdcNodes;
981
982
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
983
    int nbIdcKeys;
984
    int sizeIdcKeys;
985
986
    int flags;
987
988
    xmlDictPtr dict;
989
990
#ifdef LIBXML_READER_ENABLED
991
    xmlTextReaderPtr reader;
992
#endif
993
994
    xmlSchemaAttrInfoPtr *attrInfos;
995
    int nbAttrInfos;
996
    int sizeAttrInfos;
997
998
    int skipDepth;
999
    xmlSchemaItemListPtr nodeQNames;
1000
    int hasKeyrefs;
1001
    int createIDCNodeTables;
1002
    int psviExposeIDCNodeTables;
1003
1004
    /* Locator for error reporting in streaming mode */
1005
    xmlSchemaValidityLocatorFunc locFunc;
1006
    void *locCtxt;
1007
};
1008
1009
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1010
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1011
struct _xmlSchemaSubstGroup {
1012
    xmlSchemaElementPtr head;
1013
    xmlSchemaItemListPtr members;
1014
};
1015
1016
/**
1017
 * an entry in hash tables to quickly look up keys/uniques
1018
 */
1019
typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1020
typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1021
struct _xmlIDCHashEntry {
1022
    xmlIDCHashEntryPtr next; /* next item with same hash */
1023
    int index;               /* index into associated item list */
1024
};
1025
1026
/************************************************************************
1027
 *                  *
1028
 *      Some predeclarations        *
1029
 *                  *
1030
 ************************************************************************/
1031
1032
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1033
                                 xmlSchemaPtr schema,
1034
                                 xmlNodePtr node);
1035
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1036
                                 xmlSchemaPtr schema,
1037
                                 xmlNodePtr node);
1038
static int
1039
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1040
                   xmlSchemaAbstractCtxtPtr ctxt);
1041
static const xmlChar *
1042
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1043
static int
1044
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1045
                     xmlNodePtr node);
1046
static int
1047
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1048
                       xmlSchemaParserCtxtPtr ctxt);
1049
static void
1050
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1051
static xmlSchemaWhitespaceValueType
1052
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1053
static xmlSchemaTreeItemPtr
1054
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1055
       xmlNodePtr node, xmlSchemaTypeType type,
1056
       int withParticle);
1057
static const xmlChar *
1058
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1059
static xmlSchemaTypeLinkPtr
1060
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1061
static void
1062
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1063
         const char *funcName,
1064
         const char *message) LIBXML_ATTR_FORMAT(3,0);
1065
static int
1066
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1067
           xmlSchemaTypePtr type,
1068
           xmlSchemaTypePtr baseType,
1069
           int subset);
1070
static void
1071
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1072
           xmlSchemaParserCtxtPtr ctxt);
1073
static void
1074
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1075
static xmlSchemaQNameRefPtr
1076
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1077
        xmlSchemaPtr schema,
1078
        xmlNodePtr node);
1079
1080
/************************************************************************
1081
 *                  *
1082
 *      Helper functions              *
1083
 *                  *
1084
 ************************************************************************/
1085
1086
/**
1087
 * @param type  the type of the schema item
1088
 * @returns the component name of a schema item.
1089
 */
1090
static const xmlChar *
1091
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1092
0
{
1093
0
    switch (type) {
1094
0
  case XML_SCHEMA_TYPE_BASIC:
1095
0
      return(BAD_CAST "simple type definition");
1096
0
  case XML_SCHEMA_TYPE_SIMPLE:
1097
0
      return(BAD_CAST "simple type definition");
1098
0
  case XML_SCHEMA_TYPE_COMPLEX:
1099
0
      return(BAD_CAST "complex type definition");
1100
0
  case XML_SCHEMA_TYPE_ELEMENT:
1101
0
      return(BAD_CAST "element declaration");
1102
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1103
0
      return(BAD_CAST "attribute use");
1104
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1105
0
      return(BAD_CAST "attribute declaration");
1106
0
  case XML_SCHEMA_TYPE_GROUP:
1107
0
      return(BAD_CAST "model group definition");
1108
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1109
0
      return(BAD_CAST "attribute group definition");
1110
0
  case XML_SCHEMA_TYPE_NOTATION:
1111
0
      return(BAD_CAST "notation declaration");
1112
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1113
0
      return(BAD_CAST "model group (sequence)");
1114
0
  case XML_SCHEMA_TYPE_CHOICE:
1115
0
      return(BAD_CAST "model group (choice)");
1116
0
  case XML_SCHEMA_TYPE_ALL:
1117
0
      return(BAD_CAST "model group (all)");
1118
0
  case XML_SCHEMA_TYPE_PARTICLE:
1119
0
      return(BAD_CAST "particle");
1120
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1121
0
      return(BAD_CAST "unique identity-constraint");
1122
      /* return(BAD_CAST "IDC (unique)"); */
1123
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1124
0
      return(BAD_CAST "key identity-constraint");
1125
      /* return(BAD_CAST "IDC (key)"); */
1126
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1127
0
      return(BAD_CAST "keyref identity-constraint");
1128
      /* return(BAD_CAST "IDC (keyref)"); */
1129
0
  case XML_SCHEMA_TYPE_ANY:
1130
0
      return(BAD_CAST "wildcard (any)");
1131
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1132
0
      return(BAD_CAST "[helper component] QName reference");
1133
0
  case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1134
0
      return(BAD_CAST "[helper component] attribute use prohibition");
1135
0
  default:
1136
0
      return(BAD_CAST "Not a schema component");
1137
0
    }
1138
0
}
1139
1140
/**
1141
 * @param item  the type of the schema item
1142
 * @returns the component name of a schema item.
1143
 */
1144
static const xmlChar *
1145
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1146
0
{
1147
0
    switch (item->type) {
1148
0
  case XML_SCHEMA_TYPE_BASIC:
1149
0
      if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1150
0
    return(BAD_CAST "complex type definition");
1151
0
      else
1152
0
    return(BAD_CAST "simple type definition");
1153
0
  default:
1154
0
      return(xmlSchemaItemTypeToStr(item->type));
1155
0
    }
1156
0
}
1157
1158
/**
1159
 * @param item  a schema component
1160
 * @returns node associated with the schema component.
1161
 * NOTE that such a node need not be available; plus, a component's
1162
 * node need not to reflect the component directly, since there is no
1163
 * one-to-one relationship between the XML Schema representation and
1164
 * the component representation.
1165
 */
1166
static xmlNodePtr
1167
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1168
0
{
1169
0
    switch (item->type) {
1170
0
  case XML_SCHEMA_TYPE_ELEMENT:
1171
0
      return (((xmlSchemaElementPtr) item)->node);
1172
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1173
0
      return (((xmlSchemaAttributePtr) item)->node);
1174
0
  case XML_SCHEMA_TYPE_COMPLEX:
1175
0
  case XML_SCHEMA_TYPE_SIMPLE:
1176
0
      return (((xmlSchemaTypePtr) item)->node);
1177
0
  case XML_SCHEMA_TYPE_ANY:
1178
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1179
0
      return (((xmlSchemaWildcardPtr) item)->node);
1180
0
  case XML_SCHEMA_TYPE_PARTICLE:
1181
0
      return (((xmlSchemaParticlePtr) item)->node);
1182
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1183
0
  case XML_SCHEMA_TYPE_CHOICE:
1184
0
  case XML_SCHEMA_TYPE_ALL:
1185
0
      return (((xmlSchemaModelGroupPtr) item)->node);
1186
0
  case XML_SCHEMA_TYPE_GROUP:
1187
0
      return (((xmlSchemaModelGroupDefPtr) item)->node);
1188
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1189
0
      return (((xmlSchemaAttributeGroupPtr) item)->node);
1190
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1191
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1192
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1193
0
      return (((xmlSchemaIDCPtr) item)->node);
1194
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1195
0
      return(((xmlSchemaQNameRefPtr) item)->node);
1196
  /* TODO: What to do with NOTATIONs?
1197
  case XML_SCHEMA_TYPE_NOTATION:
1198
      return (((xmlSchemaNotationPtr) item)->node);
1199
  */
1200
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1201
0
      return (((xmlSchemaAttributeUsePtr) item)->node);
1202
0
  default:
1203
0
      return (NULL);
1204
0
    }
1205
0
}
1206
1207
#if 0
1208
/**
1209
 * @param item  a schema component
1210
 * @returns the next sibling of the schema component.
1211
 */
1212
static xmlSchemaBasicItemPtr
1213
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1214
{
1215
    switch (item->type) {
1216
  case XML_SCHEMA_TYPE_ELEMENT:
1217
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1218
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1219
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1220
  case XML_SCHEMA_TYPE_COMPLEX:
1221
  case XML_SCHEMA_TYPE_SIMPLE:
1222
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1223
  case XML_SCHEMA_TYPE_ANY:
1224
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1225
      return (NULL);
1226
  case XML_SCHEMA_TYPE_PARTICLE:
1227
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1228
  case XML_SCHEMA_TYPE_SEQUENCE:
1229
  case XML_SCHEMA_TYPE_CHOICE:
1230
  case XML_SCHEMA_TYPE_ALL:
1231
      return (NULL);
1232
  case XML_SCHEMA_TYPE_GROUP:
1233
      return (NULL);
1234
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1235
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1236
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1237
  case XML_SCHEMA_TYPE_IDC_KEY:
1238
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1239
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1240
  default:
1241
      return (NULL);
1242
    }
1243
}
1244
#endif
1245
1246
1247
/**
1248
 * Returns the given QName in the format "{namespaceName}localName" or
1249
 * just "localName" if `namespaceName` is NULL.
1250
 *
1251
 * @param buf  the string buffer
1252
 * @param namespaceName  the namespace name
1253
 * @param localName  the local name
1254
 * @returns the localName if `namespaceName` is NULL, a formatted
1255
 * string otherwise.
1256
 */
1257
static const xmlChar*
1258
xmlSchemaFormatQName(xmlChar **buf,
1259
         const xmlChar *namespaceName,
1260
         const xmlChar *localName)
1261
0
{
1262
0
    FREE_AND_NULL(*buf)
1263
0
    if (namespaceName != NULL) {
1264
0
  *buf = xmlStrdup(BAD_CAST "{");
1265
0
  *buf = xmlStrcat(*buf, namespaceName);
1266
0
  *buf = xmlStrcat(*buf, BAD_CAST "}");
1267
0
    }
1268
0
    if (localName != NULL) {
1269
0
  if (namespaceName == NULL)
1270
0
      return(localName);
1271
0
  *buf = xmlStrcat(*buf, localName);
1272
0
    } else {
1273
0
  *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1274
0
    }
1275
0
    return ((const xmlChar *) *buf);
1276
0
}
1277
1278
static const xmlChar*
1279
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1280
0
{
1281
0
    if (ns != NULL)
1282
0
  return (xmlSchemaFormatQName(buf, ns->href, localName));
1283
0
    else
1284
0
  return (xmlSchemaFormatQName(buf, NULL, localName));
1285
0
}
1286
1287
static const xmlChar *
1288
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1289
0
{
1290
0
    if (item == NULL) {
1291
0
        return (NULL);
1292
0
    }
1293
0
    switch (item->type) {
1294
0
  case XML_SCHEMA_TYPE_ELEMENT:
1295
0
      return (((xmlSchemaElementPtr) item)->name);
1296
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1297
0
      return (((xmlSchemaAttributePtr) item)->name);
1298
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1299
0
      return (((xmlSchemaAttributeGroupPtr) item)->name);
1300
0
  case XML_SCHEMA_TYPE_BASIC:
1301
0
  case XML_SCHEMA_TYPE_SIMPLE:
1302
0
  case XML_SCHEMA_TYPE_COMPLEX:
1303
0
      return (((xmlSchemaTypePtr) item)->name);
1304
0
  case XML_SCHEMA_TYPE_GROUP:
1305
0
      return (((xmlSchemaModelGroupDefPtr) item)->name);
1306
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1307
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1308
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1309
0
      return (((xmlSchemaIDCPtr) item)->name);
1310
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1311
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1312
0
    return(xmlSchemaGetComponentName(
1313
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1314
0
      } else
1315
0
    return(NULL);
1316
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1317
0
      return (((xmlSchemaQNameRefPtr) item)->name);
1318
0
  case XML_SCHEMA_TYPE_NOTATION:
1319
0
      return (((xmlSchemaNotationPtr) item)->name);
1320
0
  default:
1321
      /*
1322
      * Other components cannot have names.
1323
      */
1324
0
      break;
1325
0
    }
1326
0
    return (NULL);
1327
0
}
1328
1329
0
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1330
0
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1331
/*
1332
static const xmlChar *
1333
xmlSchemaGetQNameRefName(void *ref)
1334
{
1335
    return(((xmlSchemaQNameRefPtr) ref)->name);
1336
}
1337
1338
static const xmlChar *
1339
xmlSchemaGetQNameRefTargetNs(void *ref)
1340
{
1341
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1342
}
1343
*/
1344
1345
static const xmlChar *
1346
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1347
0
{
1348
0
    if (item == NULL) {
1349
0
        return (NULL);
1350
0
    }
1351
0
    switch (item->type) {
1352
0
  case XML_SCHEMA_TYPE_ELEMENT:
1353
0
      return (((xmlSchemaElementPtr) item)->targetNamespace);
1354
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1355
0
      return (((xmlSchemaAttributePtr) item)->targetNamespace);
1356
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1357
0
      return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1358
0
  case XML_SCHEMA_TYPE_BASIC:
1359
0
      return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1360
0
  case XML_SCHEMA_TYPE_SIMPLE:
1361
0
  case XML_SCHEMA_TYPE_COMPLEX:
1362
0
      return (((xmlSchemaTypePtr) item)->targetNamespace);
1363
0
  case XML_SCHEMA_TYPE_GROUP:
1364
0
      return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1365
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1366
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1367
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1368
0
      return (((xmlSchemaIDCPtr) item)->targetNamespace);
1369
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1370
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1371
0
    return(xmlSchemaGetComponentTargetNs(
1372
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1373
0
      }
1374
      /* TODO: Will returning NULL break something? */
1375
0
      break;
1376
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1377
0
      return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1378
0
  case XML_SCHEMA_TYPE_NOTATION:
1379
0
      return (((xmlSchemaNotationPtr) item)->targetNamespace);
1380
0
  default:
1381
      /*
1382
      * Other components cannot have names.
1383
      */
1384
0
      break;
1385
0
    }
1386
0
    return (NULL);
1387
0
}
1388
1389
static const xmlChar*
1390
xmlSchemaGetComponentQName(xmlChar **buf,
1391
         void *item)
1392
0
{
1393
0
    return (xmlSchemaFormatQName(buf,
1394
0
  xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1395
0
  xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1396
0
}
1397
1398
static const xmlChar*
1399
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1400
0
{
1401
0
    xmlChar *str = NULL;
1402
1403
0
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1404
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1405
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1406
0
  (xmlSchemaBasicItemPtr) item));
1407
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1408
0
    FREE_AND_NULL(str);
1409
0
    return(*buf);
1410
0
}
1411
1412
static const xmlChar*
1413
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1414
0
{
1415
0
    return(xmlSchemaGetComponentDesignation(buf, idc));
1416
0
}
1417
1418
/**
1419
 * @param pc  the type of processContents
1420
 * @returns a string representation of the type of
1421
 * processContents.
1422
 */
1423
static const xmlChar *
1424
xmlSchemaWildcardPCToString(int pc)
1425
0
{
1426
0
    switch (pc) {
1427
0
  case XML_SCHEMAS_ANY_SKIP:
1428
0
      return (BAD_CAST "skip");
1429
0
  case XML_SCHEMAS_ANY_LAX:
1430
0
      return (BAD_CAST "lax");
1431
0
  case XML_SCHEMAS_ANY_STRICT:
1432
0
      return (BAD_CAST "strict");
1433
0
  default:
1434
0
      return (BAD_CAST "invalid process contents");
1435
0
    }
1436
0
}
1437
1438
/**
1439
 * Get a the canonical representation of the value.
1440
 * The caller has to free the returned retValue.
1441
 *
1442
 * @param val  the precomputed value
1443
 * @param retValue  the returned value
1444
 * @param ws  the whitespace type of the value
1445
 * @param for_hash  non-zero if this is supposed to generate a string for hashing
1446
 * @returns 0 if the value could be built and -1 in case of
1447
 *         API errors or if the value type is not supported yet.
1448
 */
1449
static int
1450
xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1451
               xmlSchemaWhitespaceValueType ws,
1452
               xmlChar **retValue,
1453
         int for_hash)
1454
0
{
1455
0
    int list;
1456
0
    xmlSchemaValType valType;
1457
0
    const xmlChar *value, *value2 = NULL;
1458
1459
1460
0
    if ((retValue == NULL) || (val == NULL))
1461
0
  return (-1);
1462
0
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1463
0
    *retValue = NULL;
1464
0
    do {
1465
0
  value = NULL;
1466
0
  valType = xmlSchemaGetValType(val);
1467
0
  switch (valType) {
1468
0
      case XML_SCHEMAS_STRING:
1469
0
      case XML_SCHEMAS_NORMSTRING:
1470
0
      case XML_SCHEMAS_ANYSIMPLETYPE:
1471
0
    value = xmlSchemaValueGetAsString(val);
1472
0
    if (value != NULL) {
1473
0
        if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1474
0
      value2 = xmlSchemaCollapseString(value);
1475
0
        else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1476
0
      value2 = xmlSchemaWhiteSpaceReplace(value);
1477
0
        if (value2 != NULL)
1478
0
      value = value2;
1479
0
    }
1480
0
    break;
1481
0
      default:
1482
0
    if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1483
0
        if (value2 != NULL)
1484
0
      xmlFree((xmlChar *) value2);
1485
0
        goto internal_error;
1486
0
    }
1487
0
    if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1488
        /* We can mostly use the canonical value for hashing,
1489
           except in the case of decimal.  There the canonical
1490
           representation requires a trailing '.0' even for
1491
           non-fractional numbers, but for the derived integer
1492
           types it forbids any decimal point.  Nevertheless they
1493
           compare equal if the value is equal.  We need to generate
1494
           the same hash value for this to work, and it's easiest
1495
           to just cut off the useless '.0' suffix for the
1496
           decimal type.  */
1497
0
        int len = xmlStrlen(value2);
1498
0
        if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1499
0
          ((xmlChar*)value2)[len-2] = 0;
1500
0
    }
1501
0
    value = value2;
1502
0
  }
1503
0
  if (*retValue == NULL)
1504
0
      if (value == NULL) {
1505
0
    if (! list)
1506
0
        *retValue = xmlStrdup(BAD_CAST "");
1507
0
      } else
1508
0
    *retValue = xmlStrdup(value);
1509
0
  else if (value != NULL) {
1510
      /* List. */
1511
0
      *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1512
0
      *retValue = xmlStrcat((xmlChar *) *retValue, value);
1513
0
  }
1514
0
  FREE_AND_NULL(value2)
1515
0
  val = xmlSchemaValueGetNext(val);
1516
0
    } while (val != NULL);
1517
1518
0
    return (0);
1519
0
internal_error:
1520
0
    if (*retValue != NULL)
1521
0
  xmlFree((xmlChar *) (*retValue));
1522
0
    if (value2 != NULL)
1523
0
  xmlFree((xmlChar *) value2);
1524
0
    return (-1);
1525
0
}
1526
1527
static int
1528
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1529
             xmlSchemaWhitespaceValueType ws,
1530
             xmlChar **retValue)
1531
0
{
1532
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1533
0
}
1534
1535
static int
1536
xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1537
         xmlChar **retValue)
1538
0
{
1539
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1540
0
              retValue, 1);
1541
0
}
1542
1543
/**
1544
 * The following order is used to build the resulting
1545
 * designation if the arguments are not NULL:
1546
 * 1a. If itemDes not NULL -> itemDes
1547
 * 1b. If (itemDes not NULL) and (itemName not NULL)
1548
 *     -> itemDes + itemName
1549
 * 2. If the preceding was NULL and (item not NULL) -> item
1550
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1551
 *
1552
 * If the itemNode is an attribute node, the name of the attribute
1553
 * will be appended to the result.
1554
 *
1555
 * Returns a representation of the given item used
1556
 * for error reports.
1557
 *
1558
 * @param buf  the string buffer
1559
 * @param itemDes  the designation of the item
1560
 * @param item  the item as an object
1561
 * @param itemNode  the node of the item
1562
 * @returns the formatted string and sets `buf` to the resulting value.
1563
 */
1564
static xmlChar*
1565
xmlSchemaFormatItemForReport(xmlChar **buf,
1566
         const xmlChar *itemDes,
1567
         xmlSchemaBasicItemPtr item,
1568
         xmlNodePtr itemNode)
1569
0
{
1570
0
    xmlChar *str = NULL;
1571
0
    int named = 1;
1572
1573
0
    if (*buf != NULL) {
1574
0
  xmlFree(*buf);
1575
0
  *buf = NULL;
1576
0
    }
1577
1578
0
    if (itemDes != NULL) {
1579
0
  *buf = xmlStrdup(itemDes);
1580
0
    } else if (item != NULL) {
1581
0
  switch (item->type) {
1582
0
  case XML_SCHEMA_TYPE_BASIC: {
1583
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1584
1585
0
      if (WXS_IS_ATOMIC(type))
1586
0
    *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1587
0
      else if (WXS_IS_LIST(type))
1588
0
    *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1589
0
      else if (WXS_IS_UNION(type))
1590
0
    *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1591
0
      else
1592
0
    *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1593
0
      *buf = xmlStrcat(*buf, type->name);
1594
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1595
0
      }
1596
0
      break;
1597
0
  case XML_SCHEMA_TYPE_SIMPLE: {
1598
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1599
1600
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1601
0
    *buf = xmlStrdup(BAD_CAST"");
1602
0
      } else {
1603
0
    *buf = xmlStrdup(BAD_CAST "local ");
1604
0
      }
1605
0
      if (WXS_IS_ATOMIC(type))
1606
0
    *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1607
0
      else if (WXS_IS_LIST(type))
1608
0
    *buf = xmlStrcat(*buf, BAD_CAST "list type");
1609
0
      else if (WXS_IS_UNION(type))
1610
0
    *buf = xmlStrcat(*buf, BAD_CAST "union type");
1611
0
      else
1612
0
    *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1613
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1614
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1615
0
    *buf = xmlStrcat(*buf, type->name);
1616
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1617
0
      }
1618
0
      }
1619
0
      break;
1620
0
  case XML_SCHEMA_TYPE_COMPLEX: {
1621
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1622
1623
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1624
0
    *buf = xmlStrdup(BAD_CAST "");
1625
0
      else
1626
0
    *buf = xmlStrdup(BAD_CAST "local ");
1627
0
      *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1628
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1629
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1630
0
    *buf = xmlStrcat(*buf, type->name);
1631
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1632
0
      }
1633
0
      }
1634
0
      break;
1635
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1636
0
    xmlSchemaAttributeUsePtr ause;
1637
1638
0
    ause = WXS_ATTR_USE_CAST item;
1639
0
    *buf = xmlStrdup(BAD_CAST "attribute use ");
1640
0
    if (WXS_ATTRUSE_DECL(ause) != NULL) {
1641
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1642
0
        *buf = xmlStrcat(*buf,
1643
0
      xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1644
0
        FREE_AND_NULL(str)
1645
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1646
0
    } else {
1647
0
        *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1648
0
    }
1649
0
      }
1650
0
      break;
1651
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
1652
0
    xmlSchemaAttributePtr attr;
1653
1654
0
    attr = (xmlSchemaAttributePtr) item;
1655
0
    *buf = xmlStrdup(BAD_CAST "attribute decl.");
1656
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1657
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1658
0
        attr->targetNamespace, attr->name));
1659
0
    FREE_AND_NULL(str)
1660
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1661
0
      }
1662
0
      break;
1663
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1664
0
      xmlSchemaGetComponentDesignation(buf, item);
1665
0
      break;
1666
0
  case XML_SCHEMA_TYPE_ELEMENT: {
1667
0
    xmlSchemaElementPtr elem;
1668
1669
0
    elem = (xmlSchemaElementPtr) item;
1670
0
    *buf = xmlStrdup(BAD_CAST "element decl.");
1671
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1672
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1673
0
        elem->targetNamespace, elem->name));
1674
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1675
0
      }
1676
0
      break;
1677
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1678
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1679
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1680
0
      if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1681
0
    *buf = xmlStrdup(BAD_CAST "unique '");
1682
0
      else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1683
0
    *buf = xmlStrdup(BAD_CAST "key '");
1684
0
      else
1685
0
    *buf = xmlStrdup(BAD_CAST "keyRef '");
1686
0
      *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1687
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1688
0
      break;
1689
0
  case XML_SCHEMA_TYPE_ANY:
1690
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1691
0
      *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1692
0
        ((xmlSchemaWildcardPtr) item)->processContents));
1693
0
      *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1694
0
      break;
1695
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
1696
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
1697
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
1698
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1699
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
1700
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
1701
0
  case XML_SCHEMA_FACET_PATTERN:
1702
0
  case XML_SCHEMA_FACET_ENUMERATION:
1703
0
  case XML_SCHEMA_FACET_WHITESPACE:
1704
0
  case XML_SCHEMA_FACET_LENGTH:
1705
0
  case XML_SCHEMA_FACET_MAXLENGTH:
1706
0
  case XML_SCHEMA_FACET_MINLENGTH:
1707
0
      *buf = xmlStrdup(BAD_CAST "facet '");
1708
0
      *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1709
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1710
0
      break;
1711
0
  case XML_SCHEMA_TYPE_GROUP: {
1712
0
    *buf = xmlStrdup(BAD_CAST "model group def.");
1713
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1714
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1715
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1716
0
    FREE_AND_NULL(str)
1717
0
      }
1718
0
      break;
1719
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1720
0
  case XML_SCHEMA_TYPE_CHOICE:
1721
0
  case XML_SCHEMA_TYPE_ALL:
1722
0
  case XML_SCHEMA_TYPE_PARTICLE:
1723
0
      *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1724
0
      break;
1725
0
  case XML_SCHEMA_TYPE_NOTATION: {
1726
0
    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1727
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1728
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1729
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1730
0
    FREE_AND_NULL(str);
1731
0
      }
1732
            /* Falls through. */
1733
0
  default:
1734
0
      named = 0;
1735
0
  }
1736
0
    } else
1737
0
  named = 0;
1738
1739
0
    if ((named == 0) && (itemNode != NULL)) {
1740
0
  xmlNodePtr elem;
1741
1742
0
  if (itemNode->type == XML_ATTRIBUTE_NODE)
1743
0
      elem = itemNode->parent;
1744
0
  else
1745
0
      elem = itemNode;
1746
0
  *buf = xmlStrdup(BAD_CAST "Element '");
1747
0
  if (elem->ns != NULL) {
1748
0
      *buf = xmlStrcat(*buf,
1749
0
    xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1750
0
      FREE_AND_NULL(str)
1751
0
  } else
1752
0
      *buf = xmlStrcat(*buf, elem->name);
1753
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1754
1755
0
    }
1756
0
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1757
0
  *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1758
0
  if (itemNode->ns != NULL) {
1759
0
      *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1760
0
    itemNode->ns->href, itemNode->name));
1761
0
      FREE_AND_NULL(str)
1762
0
  } else
1763
0
      *buf = xmlStrcat(*buf, itemNode->name);
1764
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1765
0
    }
1766
0
    FREE_AND_NULL(str)
1767
1768
0
    return (xmlEscapeFormatString(buf));
1769
0
}
1770
1771
/**
1772
 * Builds a string consisting of all enumeration elements.
1773
 *
1774
 * @param actxt  schema context
1775
 * @param buf  the string buffer
1776
 * @param type  the type holding the enumeration facets
1777
 * @returns a string of all enumeration elements.
1778
 */
1779
static const xmlChar *
1780
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1781
          xmlChar **buf, xmlSchemaTypePtr type)
1782
0
{
1783
0
    xmlSchemaFacetPtr facet;
1784
0
    xmlSchemaWhitespaceValueType ws;
1785
0
    xmlChar *value = NULL;
1786
0
    int res, found = 0;
1787
1788
0
    if (*buf != NULL)
1789
0
  xmlFree(*buf);
1790
0
    *buf = NULL;
1791
1792
0
    do {
1793
  /*
1794
  * Use the whitespace type of the base type.
1795
  */
1796
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1797
0
  for (facet = type->facets; facet != NULL; facet = facet->next) {
1798
0
      if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1799
0
    continue;
1800
0
      found = 1;
1801
0
      res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1802
0
    ws, &value);
1803
0
      if (res == -1) {
1804
0
    xmlSchemaInternalErr(actxt,
1805
0
        "xmlSchemaFormatFacetEnumSet",
1806
0
        "compute the canonical lexical representation");
1807
0
    if (*buf != NULL)
1808
0
        xmlFree(*buf);
1809
0
    *buf = NULL;
1810
0
    return (NULL);
1811
0
      }
1812
0
      if (*buf == NULL)
1813
0
    *buf = xmlStrdup(BAD_CAST "'");
1814
0
      else
1815
0
    *buf = xmlStrcat(*buf, BAD_CAST ", '");
1816
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
1817
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1818
0
      if (value != NULL) {
1819
0
    xmlFree((xmlChar *)value);
1820
0
    value = NULL;
1821
0
      }
1822
0
  }
1823
  /*
1824
  * The enumeration facet of a type restricts the enumeration
1825
  * facet of the ancestor type; i.e., such restricted enumerations
1826
  * do not belong to the set of the given type. Thus we break
1827
  * on the first found enumeration.
1828
  */
1829
0
  if (found)
1830
0
      break;
1831
0
  type = type->baseType;
1832
0
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1833
1834
0
    return ((const xmlChar *) *buf);
1835
0
}
1836
1837
/************************************************************************
1838
 *                  *
1839
 *      Error functions               *
1840
 *                  *
1841
 ************************************************************************/
1842
1843
/**
1844
 * Handle an out of memory condition
1845
 *
1846
 * @param ctxt  schema parser context
1847
 */
1848
static void
1849
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt)
1850
0
{
1851
0
    xmlGenericErrorFunc channel = NULL;
1852
0
    xmlStructuredErrorFunc schannel = NULL;
1853
0
    void *data = NULL;
1854
1855
0
    if (ctxt != NULL) {
1856
0
        ctxt->nberrors++;
1857
0
        ctxt->err = XML_ERR_NO_MEMORY;
1858
0
        channel = ctxt->error;
1859
0
        schannel = ctxt->serror;
1860
0
        data = ctxt->errCtxt;
1861
0
    }
1862
1863
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASP, NULL);
1864
0
}
1865
1866
static void LIBXML_ATTR_FORMAT(11,12)
1867
xmlSchemaPErrFull(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1868
                  xmlErrorLevel level, const char *file, int line,
1869
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
1870
0
                  int col, const char *msg, ...) {
1871
0
    xmlGenericErrorFunc channel = NULL;
1872
0
    xmlStructuredErrorFunc schannel = NULL;
1873
0
    void *data = NULL;
1874
0
    int res;
1875
0
    va_list ap;
1876
1877
0
    if (ctxt != NULL) {
1878
        /* Don't overwrite memory errors */
1879
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
1880
0
            return;
1881
1882
0
        if (level == XML_ERR_WARNING) {
1883
0
            channel = ctxt->warning;
1884
0
        } else {
1885
0
            ctxt->nberrors++;
1886
0
            ctxt->err = code;
1887
0
            channel = ctxt->error;
1888
0
        }
1889
0
        data = ctxt->errCtxt;
1890
0
        schannel = ctxt->serror;
1891
0
    }
1892
1893
0
    if ((channel == NULL) && (schannel == NULL)) {
1894
0
        channel = xmlGenericError;
1895
0
        data = xmlGenericErrorContext;
1896
0
    }
1897
1898
0
    va_start(ap, msg);
1899
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
1900
0
                         XML_FROM_SCHEMASP, code, level, file, line,
1901
0
                         (const char *) str1,
1902
0
                         (const char *) str2,
1903
0
                         (const char *) str3,
1904
0
                         0, col, msg, ap);
1905
0
    va_end(ap);
1906
1907
0
    if (res < 0)
1908
0
        xmlSchemaPErrMemory(ctxt);
1909
0
}
1910
1911
/**
1912
 * Handle a parser error
1913
 *
1914
 * @param ctxt  the parsing context
1915
 * @param node  the context node
1916
 * @param code  the error code
1917
 * @param msg  the error message
1918
 * @param str1  extra data
1919
 * @param str2  extra data
1920
 */
1921
static void LIBXML_ATTR_FORMAT(4,0)
1922
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1923
              const char *msg, const xmlChar * str1, const xmlChar * str2)
1924
0
{
1925
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
1926
0
                      str1, str2, NULL, 0, msg, str1, str2);
1927
0
}
1928
1929
/**
1930
 * Handle a parser error
1931
 *
1932
 * @param ctxt  the parsing context
1933
 * @param node  the context node
1934
 * @param child  the current child
1935
 * @param error  the error code
1936
 * @param msg  the error message
1937
 * @param str1  extra data
1938
 * @param str2  extra data
1939
 */
1940
static void LIBXML_ATTR_FORMAT(5,0)
1941
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1942
               xmlNodePtr child, int error,
1943
               const char *msg, const xmlChar * str1, const xmlChar * str2)
1944
0
{
1945
0
    if (child != NULL)
1946
0
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1947
0
    else
1948
0
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1949
0
}
1950
1951
1952
/**
1953
 * Handle a parser error
1954
 *
1955
 * @param ctxt  the parsing context
1956
 * @param node  the context node
1957
 * @param code  the error code
1958
 * @param strData1  extra data
1959
 * @param strData2  extra data
1960
 * @param strData3  extra data
1961
 * @param msg  the message
1962
 * @param str1  extra parameter for the message display
1963
 * @param str2  extra parameter for the message display
1964
 * @param str3  extra parameter for the message display
1965
 * @param str4  extra parameter for the message display
1966
 * @param str5  extra parameter for the message display
1967
 */
1968
static void LIBXML_ATTR_FORMAT(7,0)
1969
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1970
    const xmlChar * strData1, const xmlChar * strData2,
1971
    const xmlChar * strData3, const char *msg, const xmlChar * str1,
1972
    const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
1973
    const xmlChar * str5)
1974
0
{
1975
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
1976
0
                      strData1, strData2, strData3, 0,
1977
0
                      msg, str1, str2, str3, str4, str5);
1978
0
}
1979
1980
/************************************************************************
1981
 *                  *
1982
 *      Allround error functions      *
1983
 *                  *
1984
 ************************************************************************/
1985
1986
/**
1987
 * Handle an out of memory condition
1988
 *
1989
 * @param ctxt  schema validation context
1990
 */
1991
static void
1992
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt)
1993
0
{
1994
0
    xmlGenericErrorFunc channel = NULL;
1995
0
    xmlStructuredErrorFunc schannel = NULL;
1996
0
    void *data = NULL;
1997
1998
0
    if (ctxt != NULL) {
1999
0
        ctxt->nberrors++;
2000
0
        ctxt->err = XML_ERR_NO_MEMORY;
2001
0
        channel = ctxt->error;
2002
0
        schannel = ctxt->serror;
2003
0
        data = ctxt->errCtxt;
2004
0
    }
2005
2006
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASV, NULL);
2007
0
}
2008
2009
static void LIBXML_ATTR_FORMAT(11,12)
2010
xmlSchemaVErrFull(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int code,
2011
                  xmlErrorLevel level, const char *file, int line,
2012
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
2013
0
                  int col, const char *msg, ...) {
2014
0
    xmlGenericErrorFunc channel = NULL;
2015
0
    xmlStructuredErrorFunc schannel = NULL;
2016
0
    void *data = NULL;
2017
0
    int res;
2018
0
    va_list ap;
2019
2020
0
    if (ctxt != NULL) {
2021
        /* Don't overwrite memory errors */
2022
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
2023
0
            return;
2024
2025
0
        if (level == XML_ERR_WARNING) {
2026
0
            channel = ctxt->warning;
2027
0
        } else {
2028
0
            ctxt->nberrors++;
2029
0
            ctxt->err = code;
2030
0
            channel = ctxt->error;
2031
0
        }
2032
0
        data = ctxt->errCtxt;
2033
0
        schannel = ctxt->serror;
2034
0
    }
2035
2036
0
    if ((channel == NULL) && (schannel == NULL)) {
2037
0
        channel = xmlGenericError;
2038
0
        data = xmlGenericErrorContext;
2039
0
    }
2040
2041
0
    va_start(ap, msg);
2042
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
2043
0
                         XML_FROM_SCHEMASV, code, level, file, line,
2044
0
                         (const char *) str1,
2045
0
                         (const char *) str2,
2046
0
                         (const char *) str3,
2047
0
                         0, col, msg, ap);
2048
0
    va_end(ap);
2049
2050
0
    if (res < 0)
2051
0
        xmlSchemaVErrMemory(ctxt);
2052
0
}
2053
2054
#define WXS_ERROR_TYPE_ERROR 1
2055
#define WXS_ERROR_TYPE_WARNING 2
2056
/**
2057
 * Handle a validation error
2058
 *
2059
 * @param ctxt  the validation context
2060
 * @param errorLevel  the error level
2061
 * @param code  the error code
2062
 * @param node  the context node
2063
 * @param line  the line number
2064
 * @param msg  the error message
2065
 * @param str1  extra data
2066
 * @param str2  extra data
2067
 * @param str3  extra data
2068
 * @param str4  extra data
2069
 */
2070
static void LIBXML_ATTR_FORMAT(6,0)
2071
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2072
      xmlErrorLevel errorLevel,
2073
      int code, xmlNodePtr node, int line, const char *msg,
2074
      const xmlChar *str1, const xmlChar *str2,
2075
      const xmlChar *str3, const xmlChar *str4)
2076
0
{
2077
0
    if (ctxt != NULL) {
2078
0
  if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2079
0
      xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2080
0
      const char *file = NULL;
2081
0
      int col = 0;
2082
2083
      /*
2084
      * Error node. If we specify a line number, then
2085
      * do not channel any node to the error function.
2086
      */
2087
0
      if (line == 0) {
2088
0
    if ((node == NULL) &&
2089
0
        (vctxt->depth >= 0) &&
2090
0
        (vctxt->inode != NULL)) {
2091
0
        node = vctxt->inode->node;
2092
0
    }
2093
    /*
2094
    * Get filename and line if no node-tree.
2095
    */
2096
0
    if ((node == NULL) &&
2097
0
        (vctxt->parserCtxt != NULL) &&
2098
0
        (vctxt->parserCtxt->input != NULL)) {
2099
0
        file = vctxt->parserCtxt->input->filename;
2100
0
                    if (vctxt->inode != NULL) {
2101
0
            line = vctxt->inode->nodeLine;
2102
0
                        col = 0;
2103
0
                    } else {
2104
                        /* This is inaccurate. */
2105
0
            line = vctxt->parserCtxt->input->line;
2106
0
            col = vctxt->parserCtxt->input->col;
2107
0
                    }
2108
0
    }
2109
0
      } else {
2110
    /*
2111
    * Override the given node's (if any) position
2112
    * and channel only the given line number.
2113
    */
2114
0
    node = NULL;
2115
    /*
2116
    * Get filename.
2117
    */
2118
0
    if (vctxt->doc != NULL)
2119
0
        file = (const char *) vctxt->doc->URL;
2120
0
    else if ((vctxt->parserCtxt != NULL) &&
2121
0
        (vctxt->parserCtxt->input != NULL))
2122
0
        file = vctxt->parserCtxt->input->filename;
2123
0
      }
2124
0
      if (vctxt->locFunc != NULL) {
2125
0
          if ((file == NULL) || (line == 0)) {
2126
0
        unsigned long l = 0;
2127
0
        const char *f = NULL;
2128
0
        vctxt->locFunc(vctxt->locCtxt, &f, &l);
2129
0
        if (file == NULL)
2130
0
            file = f;
2131
0
        if (line == 0)
2132
0
            line = (int) l;
2133
0
    }
2134
0
      }
2135
0
      if ((file == NULL) && (vctxt->filename != NULL))
2136
0
          file = vctxt->filename;
2137
2138
0
            xmlSchemaVErrFull(vctxt, node, code, errorLevel,
2139
0
                              file, line, str1, str2, str3, col,
2140
0
                              msg, str1, str2, str3, str4);
2141
0
  } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2142
0
      xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2143
2144
0
            xmlSchemaPErrFull(pctxt, node, code, errorLevel,
2145
0
                              NULL, 0, str1, str2, str3, 0,
2146
0
                              msg, str1, str2, str3, str4);
2147
0
  }
2148
0
    }
2149
0
}
2150
2151
/**
2152
 * Handle a validation error
2153
 *
2154
 * @param actxt  the validation context
2155
 * @param error  the error code
2156
 * @param node  the context node
2157
 * @param msg  the error message
2158
 * @param str1  extra data
2159
 * @param str2  extra data
2160
 * @param str3  extra data
2161
 */
2162
static void LIBXML_ATTR_FORMAT(4,0)
2163
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2164
        int error, xmlNodePtr node, const char *msg,
2165
        const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2166
0
{
2167
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2168
0
  msg, str1, str2, str3, NULL);
2169
0
}
2170
2171
static void LIBXML_ATTR_FORMAT(4,0)
2172
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2173
        int error, xmlNodePtr node, const char *msg,
2174
        const xmlChar *str1, const xmlChar *str2,
2175
        const xmlChar *str3, const xmlChar *str4)
2176
0
{
2177
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2178
0
  msg, str1, str2, str3, str4);
2179
0
}
2180
2181
static void LIBXML_ATTR_FORMAT(4,0)
2182
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2183
       int error, xmlNodePtr node, const char *msg,
2184
       const xmlChar *str1, const xmlChar *str2)
2185
0
{
2186
0
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2187
0
}
2188
2189
static xmlChar *
2190
xmlSchemaFormatNodeForError(xmlChar ** msg,
2191
          xmlSchemaAbstractCtxtPtr actxt,
2192
          xmlNodePtr node)
2193
0
{
2194
0
    xmlChar *str = NULL;
2195
2196
0
    *msg = NULL;
2197
0
    if ((node != NULL) &&
2198
0
  (node->type != XML_ELEMENT_NODE) &&
2199
0
  (node->type != XML_ATTRIBUTE_NODE))
2200
0
    {
2201
  /*
2202
  * Don't try to format other nodes than element and
2203
  * attribute nodes.
2204
  * Play safe and return an empty string.
2205
  */
2206
0
  *msg = xmlStrdup(BAD_CAST "");
2207
0
  return(*msg);
2208
0
    }
2209
0
    if (node != NULL) {
2210
  /*
2211
  * Work on tree nodes.
2212
  */
2213
0
  if (node->type == XML_ATTRIBUTE_NODE) {
2214
0
      xmlNodePtr elem = node->parent;
2215
2216
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2217
0
      if (elem->ns != NULL)
2218
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2219
0
        elem->ns->href, elem->name));
2220
0
      else
2221
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2222
0
        NULL, elem->name));
2223
0
      FREE_AND_NULL(str);
2224
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2225
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2226
0
  } else {
2227
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2228
0
  }
2229
0
  if (node->ns != NULL)
2230
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2231
0
      node->ns->href, node->name));
2232
0
  else
2233
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2234
0
      NULL, node->name));
2235
0
  FREE_AND_NULL(str);
2236
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2237
0
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2238
0
  xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2239
  /*
2240
  * Work on node infos.
2241
  */
2242
0
  if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2243
0
      xmlSchemaNodeInfoPtr ielem =
2244
0
    vctxt->elemInfos[vctxt->depth];
2245
2246
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2247
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2248
0
    ielem->nsName, ielem->localName));
2249
0
      FREE_AND_NULL(str);
2250
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2251
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2252
0
  } else {
2253
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2254
0
  }
2255
0
  *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2256
0
      vctxt->inode->nsName, vctxt->inode->localName));
2257
0
  FREE_AND_NULL(str);
2258
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2259
0
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2260
  /*
2261
  * Hmm, no node while parsing?
2262
  * Return an empty string, in case NULL will break something.
2263
  */
2264
0
  *msg = xmlStrdup(BAD_CAST "");
2265
0
    } else {
2266
  /* TODO */
2267
0
  return (NULL);
2268
0
    }
2269
2270
    /*
2271
     * xmlSchemaFormatItemForReport() also returns an escaped format
2272
     * string, so do this before calling it below (in the future).
2273
     */
2274
0
    xmlEscapeFormatString(msg);
2275
2276
    /*
2277
    * VAL TODO: The output of the given schema component is currently
2278
    * disabled.
2279
    */
2280
#if 0
2281
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2282
  *msg = xmlStrcat(*msg, BAD_CAST " [");
2283
  *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2284
      NULL, type, NULL, 0));
2285
  FREE_AND_NULL(str)
2286
  *msg = xmlStrcat(*msg, BAD_CAST "]");
2287
    }
2288
#endif
2289
0
    return (*msg);
2290
0
}
2291
2292
static void LIBXML_ATTR_FORMAT(3,0)
2293
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2294
         const char *funcName,
2295
         const char *message,
2296
         const xmlChar *str1,
2297
         const xmlChar *str2)
2298
0
{
2299
0
    xmlChar *msg = NULL;
2300
2301
0
    if (actxt == NULL)
2302
0
        return;
2303
0
    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2304
0
    msg = xmlStrcat(msg, BAD_CAST message);
2305
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2306
2307
0
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2308
0
  xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2309
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2310
0
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2311
0
  xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2312
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2313
2314
0
    FREE_AND_NULL(msg)
2315
0
}
2316
2317
static void LIBXML_ATTR_FORMAT(3,0)
2318
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2319
         const char *funcName,
2320
         const char *message)
2321
0
{
2322
0
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2323
0
}
2324
2325
#if 0
2326
static void LIBXML_ATTR_FORMAT(3,0)
2327
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2328
         const char *funcName,
2329
         const char *message,
2330
         const xmlChar *str1,
2331
         const xmlChar *str2)
2332
{
2333
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2334
  str1, str2);
2335
}
2336
#endif
2337
2338
static void LIBXML_ATTR_FORMAT(5,0)
2339
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2340
       xmlParserErrors error,
2341
       xmlNodePtr node,
2342
       xmlSchemaBasicItemPtr item,
2343
       const char *message,
2344
       const xmlChar *str1, const xmlChar *str2,
2345
       const xmlChar *str3, const xmlChar *str4)
2346
0
{
2347
0
    xmlChar *msg = NULL;
2348
2349
0
    if ((node == NULL) && (item != NULL) &&
2350
0
  (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2351
0
  node = WXS_ITEM_NODE(item);
2352
0
  xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2353
0
  msg = xmlStrcat(msg, BAD_CAST ": ");
2354
0
    } else
2355
0
  xmlSchemaFormatNodeForError(&msg, actxt, node);
2356
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2357
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2358
0
    xmlSchemaErr4(actxt, error, node,
2359
0
  (const char *) msg, str1, str2, str3, str4);
2360
0
    FREE_AND_NULL(msg)
2361
0
}
2362
2363
static void LIBXML_ATTR_FORMAT(5,0)
2364
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2365
       xmlParserErrors error,
2366
       xmlNodePtr node,
2367
       xmlSchemaBasicItemPtr item,
2368
       const char *message,
2369
       const xmlChar *str1,
2370
       const xmlChar *str2)
2371
0
{
2372
0
    xmlSchemaCustomErr4(actxt, error, node, item,
2373
0
  message, str1, str2, NULL, NULL);
2374
0
}
2375
2376
2377
2378
static void LIBXML_ATTR_FORMAT(5,0)
2379
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2380
       xmlParserErrors error,
2381
       xmlNodePtr node,
2382
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2383
       const char *message,
2384
       const xmlChar *str1,
2385
       const xmlChar *str2,
2386
       const xmlChar *str3)
2387
0
{
2388
0
    xmlChar *msg = NULL;
2389
2390
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2391
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2392
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2393
2394
    /* URGENT TODO: Set the error code to something sane. */
2395
0
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2396
0
  (const char *) msg, str1, str2, str3, NULL);
2397
2398
0
    FREE_AND_NULL(msg)
2399
0
}
2400
2401
2402
2403
static void LIBXML_ATTR_FORMAT(5,0)
2404
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2405
       xmlParserErrors error,
2406
       xmlSchemaPSVIIDCNodePtr idcNode,
2407
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2408
       const char *message,
2409
       const xmlChar *str1,
2410
       const xmlChar *str2)
2411
0
{
2412
0
    xmlChar *msg = NULL, *qname = NULL;
2413
2414
0
    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2415
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2416
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2417
0
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2418
0
  error, NULL, idcNode->nodeLine, (const char *) msg,
2419
0
  xmlSchemaFormatQName(&qname,
2420
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2421
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2422
0
  str1, str2, NULL);
2423
0
    FREE_AND_NULL(qname);
2424
0
    FREE_AND_NULL(msg);
2425
0
}
2426
2427
static int
2428
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2429
         xmlNodePtr node)
2430
0
{
2431
0
    if (node != NULL)
2432
0
  return (node->type);
2433
0
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2434
0
  (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2435
0
  return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2436
0
    return (-1);
2437
0
}
2438
2439
static int
2440
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2441
0
{
2442
0
    switch (item->type) {
2443
0
  case XML_SCHEMA_TYPE_COMPLEX:
2444
0
  case XML_SCHEMA_TYPE_SIMPLE:
2445
0
      if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2446
0
    return(1);
2447
0
      break;
2448
0
  case XML_SCHEMA_TYPE_GROUP:
2449
0
      return (1);
2450
0
  case XML_SCHEMA_TYPE_ELEMENT:
2451
0
      if ( ((xmlSchemaElementPtr) item)->flags &
2452
0
    XML_SCHEMAS_ELEM_GLOBAL)
2453
0
    return(1);
2454
0
      break;
2455
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
2456
0
      if ( ((xmlSchemaAttributePtr) item)->flags &
2457
0
    XML_SCHEMAS_ATTR_GLOBAL)
2458
0
    return(1);
2459
0
      break;
2460
  /* Note that attribute groups are always global. */
2461
0
  default:
2462
0
      return(1);
2463
0
    }
2464
0
    return (0);
2465
0
}
2466
2467
static void
2468
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2469
           xmlParserErrors error,
2470
           xmlNodePtr node,
2471
           const xmlChar *value,
2472
           xmlSchemaTypePtr type,
2473
           int displayValue)
2474
0
{
2475
0
    xmlChar *msg = NULL;
2476
2477
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2478
2479
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2480
0
      XML_ATTRIBUTE_NODE))
2481
0
  msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2482
0
    else
2483
0
  msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2484
0
      "value of ");
2485
2486
0
    if (! xmlSchemaIsGlobalItem(type))
2487
0
  msg = xmlStrcat(msg, BAD_CAST "the local ");
2488
0
    else
2489
0
  msg = xmlStrcat(msg, BAD_CAST "the ");
2490
2491
0
    if (WXS_IS_ATOMIC(type))
2492
0
  msg = xmlStrcat(msg, BAD_CAST "atomic type");
2493
0
    else if (WXS_IS_LIST(type))
2494
0
  msg = xmlStrcat(msg, BAD_CAST "list type");
2495
0
    else if (WXS_IS_UNION(type))
2496
0
  msg = xmlStrcat(msg, BAD_CAST "union type");
2497
2498
0
    if (xmlSchemaIsGlobalItem(type)) {
2499
0
  xmlChar *str = NULL;
2500
0
  msg = xmlStrcat(msg, BAD_CAST " '");
2501
0
  if (type->builtInType != 0) {
2502
0
      msg = xmlStrcat(msg, BAD_CAST "xs:");
2503
0
      str = xmlStrdup(type->name);
2504
0
  } else {
2505
0
      const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2506
0
      if (!str)
2507
0
    str = xmlStrdup(qName);
2508
0
  }
2509
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2510
0
  msg = xmlStrcat(msg, BAD_CAST "'");
2511
0
  FREE_AND_NULL(str);
2512
0
    }
2513
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2514
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2515
0
      XML_ATTRIBUTE_NODE))
2516
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2517
0
    else
2518
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2519
0
    FREE_AND_NULL(msg)
2520
0
}
2521
2522
static const xmlChar *
2523
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2524
            xmlSchemaNodeInfoPtr ni,
2525
            xmlNodePtr node)
2526
0
{
2527
0
    if (node != NULL) {
2528
0
  if (node->ns != NULL)
2529
0
      return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2530
0
  else
2531
0
      return (xmlSchemaFormatQName(str, NULL, node->name));
2532
0
    } else if (ni != NULL)
2533
0
  return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2534
0
    return (NULL);
2535
0
}
2536
2537
static void
2538
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2539
      xmlParserErrors error,
2540
      xmlSchemaAttrInfoPtr ni,
2541
      xmlNodePtr node)
2542
0
{
2543
0
    xmlChar *msg = NULL, *str = NULL;
2544
2545
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2546
0
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2547
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2548
0
  xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2549
0
  NULL);
2550
0
    FREE_AND_NULL(str)
2551
0
    FREE_AND_NULL(msg)
2552
0
}
2553
2554
static void LIBXML_ATTR_FORMAT(5,0)
2555
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2556
            xmlParserErrors error,
2557
            xmlNodePtr node,
2558
      xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2559
      const char *message,
2560
      int nbval,
2561
      int nbneg,
2562
      xmlChar **values)
2563
0
{
2564
0
    xmlChar *str = NULL, *msg = NULL;
2565
0
    xmlChar *localName, *nsName;
2566
0
    const xmlChar *cur, *end;
2567
0
    int i;
2568
2569
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2570
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2571
0
    msg = xmlStrcat(msg, BAD_CAST ".");
2572
    /*
2573
    * Note that is does not make sense to report that we have a
2574
    * wildcard here, since the wildcard might be unfolded into
2575
    * multiple transitions.
2576
    */
2577
0
    if (nbval + nbneg > 0) {
2578
0
  if (nbval + nbneg > 1) {
2579
0
      str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2580
0
  } else
2581
0
      str = xmlStrdup(BAD_CAST " Expected is ( ");
2582
0
  nsName = NULL;
2583
2584
0
  for (i = 0; i < nbval + nbneg; i++) {
2585
0
      cur = values[i];
2586
0
      if (cur == NULL)
2587
0
          continue;
2588
0
      if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2589
0
          (cur[3] == ' ')) {
2590
0
    cur += 4;
2591
0
    str = xmlStrcat(str, BAD_CAST "##other");
2592
0
      }
2593
      /*
2594
      * Get the local name.
2595
      */
2596
0
      localName = NULL;
2597
2598
0
      end = cur;
2599
0
      if (*end == '*') {
2600
0
    localName = xmlStrdup(BAD_CAST "*");
2601
0
    end++;
2602
0
      } else {
2603
0
    while ((*end != 0) && (*end != '|'))
2604
0
        end++;
2605
0
    localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2606
0
      }
2607
0
      if (*end != 0) {
2608
0
    end++;
2609
    /*
2610
    * Skip "*|*" if they come with negated expressions, since
2611
    * they represent the same negated wildcard.
2612
    */
2613
0
    if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2614
        /*
2615
        * Get the namespace name.
2616
        */
2617
0
        cur = end;
2618
0
        if (*end == '*') {
2619
0
      nsName = xmlStrdup(BAD_CAST "{*}");
2620
0
        } else {
2621
0
      while (*end != 0)
2622
0
          end++;
2623
2624
0
      if (i >= nbval)
2625
0
          nsName = xmlStrdup(BAD_CAST "{##other:");
2626
0
      else
2627
0
          nsName = xmlStrdup(BAD_CAST "{");
2628
2629
0
      nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2630
0
      nsName = xmlStrcat(nsName, BAD_CAST "}");
2631
0
        }
2632
0
        str = xmlStrcat(str, BAD_CAST nsName);
2633
0
        FREE_AND_NULL(nsName)
2634
0
    } else {
2635
0
        FREE_AND_NULL(localName);
2636
0
        continue;
2637
0
    }
2638
0
      }
2639
0
      str = xmlStrcat(str, BAD_CAST localName);
2640
0
      FREE_AND_NULL(localName);
2641
2642
0
      if (i < nbval + nbneg -1)
2643
0
    str = xmlStrcat(str, BAD_CAST ", ");
2644
0
  }
2645
0
  str = xmlStrcat(str, BAD_CAST " ).\n");
2646
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2647
0
  FREE_AND_NULL(str)
2648
0
    } else
2649
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
2650
0
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2651
0
    xmlFree(msg);
2652
0
}
2653
2654
static void LIBXML_ATTR_FORMAT(8,0)
2655
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2656
      xmlParserErrors error,
2657
      xmlNodePtr node,
2658
      const xmlChar *value,
2659
      unsigned long length,
2660
      xmlSchemaTypePtr type,
2661
      xmlSchemaFacetPtr facet,
2662
      const char *message,
2663
      const xmlChar *str1,
2664
      const xmlChar *str2)
2665
0
{
2666
0
    xmlChar *str = NULL, *msg = NULL;
2667
0
    xmlSchemaTypeType facetType;
2668
0
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2669
2670
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2671
0
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2672
0
  facetType = XML_SCHEMA_FACET_ENUMERATION;
2673
  /*
2674
  * If enumerations are validated, one must not expect the
2675
  * facet to be given.
2676
  */
2677
0
    } else
2678
0
  facetType = facet->type;
2679
0
    msg = xmlStrcat(msg, BAD_CAST "[");
2680
0
    msg = xmlStrcat(msg, BAD_CAST "facet '");
2681
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2682
0
    msg = xmlStrcat(msg, BAD_CAST "'] ");
2683
0
    if (message == NULL) {
2684
  /*
2685
  * Use a default message.
2686
  */
2687
0
  if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2688
0
      (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2689
0
      (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2690
2691
0
      char len[25], actLen[25];
2692
2693
      /* FIXME, TODO: What is the max expected string length of the
2694
      * this value?
2695
      */
2696
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2697
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2698
0
      else
2699
0
    msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2700
2701
0
      snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2702
0
      snprintf(actLen, 24, "%lu", length);
2703
2704
0
      if (facetType == XML_SCHEMA_FACET_LENGTH)
2705
0
    msg = xmlStrcat(msg,
2706
0
    BAD_CAST "this differs from the allowed length of '%s'.\n");
2707
0
      else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2708
0
    msg = xmlStrcat(msg,
2709
0
    BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2710
0
      else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2711
0
    msg = xmlStrcat(msg,
2712
0
    BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2713
2714
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2715
0
    xmlSchemaErr3(actxt, error, node, (const char *) msg,
2716
0
        value, (const xmlChar *) actLen, (const xmlChar *) len);
2717
0
      else
2718
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2719
0
        (const xmlChar *) actLen, (const xmlChar *) len);
2720
2721
0
  } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2722
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2723
0
    "of the set {%s}.\n");
2724
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2725
0
    xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2726
0
  } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2727
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2728
0
    "by the pattern '%s'.\n");
2729
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2730
0
    facet->value);
2731
0
  } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2732
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2733
0
    "minimum value allowed ('%s').\n");
2734
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2735
0
    facet->value);
2736
0
  } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2737
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2738
0
    "maximum value allowed ('%s').\n");
2739
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2740
0
    facet->value);
2741
0
  } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2742
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2743
0
    "'%s'.\n");
2744
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2745
0
    facet->value);
2746
0
  } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2747
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2748
0
    "'%s'.\n");
2749
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2750
0
    facet->value);
2751
0
  } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2752
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2753
0
    "digits than are allowed ('%s').\n");
2754
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2755
0
    facet->value);
2756
0
  } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2757
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2758
0
    "digits than are allowed ('%s').\n");
2759
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2760
0
    facet->value);
2761
0
  } else if (nodeType == XML_ATTRIBUTE_NODE) {
2762
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2763
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2764
0
  } else {
2765
0
      msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2766
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2767
0
  }
2768
0
    } else {
2769
0
  msg = xmlStrcat(msg, (const xmlChar *) message);
2770
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
2771
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2772
0
    }
2773
0
    FREE_AND_NULL(str)
2774
0
    xmlFree(msg);
2775
0
}
2776
2777
#define VERROR(err, type, msg) \
2778
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2779
2780
0
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2781
2782
0
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2783
0
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2784
2785
0
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2786
2787
2788
/**
2789
 * Reports an illegal attribute.
2790
 *
2791
 * @param ctxt  the schema validation context
2792
 * @param error  the error code
2793
 * @param ownerItem  the owner as a schema object
2794
 * @param ownerElem  the owner as an element node
2795
 * @param name  name of the attribute
2796
 * @param message  the error message
2797
 */
2798
static void
2799
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2800
       xmlParserErrors error,
2801
       xmlSchemaBasicItemPtr ownerItem,
2802
       xmlNodePtr ownerElem,
2803
       const char *name,
2804
       const char *message)
2805
0
{
2806
0
    xmlChar *des = NULL;
2807
2808
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2809
2810
0
    if (message != NULL)
2811
0
  xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2812
0
    else
2813
0
  xmlSchemaPErr(ctxt, ownerElem, error,
2814
0
      "%s: The attribute '%s' is required but missing.\n",
2815
0
      BAD_CAST des, BAD_CAST name);
2816
0
    FREE_AND_NULL(des);
2817
0
}
2818
2819
2820
/**
2821
 * Used to report QName attribute values that failed to resolve
2822
 * to schema components.
2823
 *
2824
 * @param ctxt  the schema validation context
2825
 * @param error  the error code
2826
 * @param ownerItem  the owner as a schema object
2827
 * @param ownerElem  the owner as an element node
2828
 * @param name  the name of the attribute holding the QName
2829
 * @param refName  the referenced local name
2830
 * @param refURI  the referenced namespace URI
2831
 * @param refType  the referenced type
2832
 * @param refTypeStr  the referenced type string
2833
 */
2834
static void
2835
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2836
       xmlParserErrors error,
2837
       xmlSchemaBasicItemPtr ownerItem,
2838
       xmlNodePtr ownerElem,
2839
       const char *name,
2840
       const xmlChar *refName,
2841
       const xmlChar *refURI,
2842
       xmlSchemaTypeType refType,
2843
       const char *refTypeStr)
2844
0
{
2845
0
    xmlChar *des = NULL, *strA = NULL;
2846
2847
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2848
0
    if (refTypeStr == NULL)
2849
0
  refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2850
0
    xmlSchemaPErrExt(ctxt, ownerElem, error,
2851
0
      NULL, NULL, NULL,
2852
0
      "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2853
0
      "%s.\n", BAD_CAST des, BAD_CAST name,
2854
0
      xmlSchemaFormatQName(&strA, refURI, refName),
2855
0
      BAD_CAST refTypeStr, NULL);
2856
0
    FREE_AND_NULL(des)
2857
0
    FREE_AND_NULL(strA)
2858
0
}
2859
2860
/**
2861
 * Reports an illegal attribute during the parse.
2862
 *
2863
 * @param ctxt  the schema parser context
2864
 * @param error  the error code
2865
 * @param ownerDes  the designation of the owner
2866
 * @param ownerItem  the owner as a schema object
2867
 * @param attr  the illegal attribute node
2868
 * @param msg  the error message
2869
 */
2870
static void
2871
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2872
      xmlParserErrors error,
2873
      xmlChar **ownerDes,
2874
      xmlSchemaBasicItemPtr ownerItem,
2875
      xmlAttrPtr attr,
2876
      const char *msg)
2877
0
{
2878
0
    xmlChar *des = NULL;
2879
2880
0
    if (ownerDes == NULL)
2881
0
  xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2882
0
    else if (*ownerDes == NULL) {
2883
0
  xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2884
0
  des = *ownerDes;
2885
0
    } else
2886
0
  des = *ownerDes;
2887
0
    if (attr == NULL) {
2888
0
  xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2889
0
      "%s, attribute '%s': %s.\n",
2890
0
      BAD_CAST des, (const xmlChar *) "Unknown",
2891
0
      (const xmlChar *) msg, NULL, NULL);
2892
0
    } else {
2893
0
  xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2894
0
      "%s, attribute '%s': %s.\n",
2895
0
      BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2896
0
    }
2897
0
    if (ownerDes == NULL)
2898
0
  FREE_AND_NULL(des);
2899
0
}
2900
2901
/**
2902
 * Reports an illegal attribute during the parse.
2903
 *
2904
 * @param ctxt  the schema parser context
2905
 * @param error  the error code
2906
 * @param ownerComp  the attribute's owner item (unused)
2907
 * @param attr  the illegal attribute node
2908
 */
2909
static void
2910
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2911
       xmlParserErrors error,
2912
       xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2913
       xmlAttrPtr attr)
2914
0
{
2915
0
    xmlChar *strA = NULL, *strB = NULL;
2916
2917
0
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2918
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2919
0
  "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2920
0
  xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2921
0
  NULL, NULL);
2922
0
    FREE_AND_NULL(strA);
2923
0
    FREE_AND_NULL(strB);
2924
0
}
2925
2926
/**
2927
 * Reports an error during parsing.
2928
 *
2929
 * @param ctxt  the schema parser context
2930
 * @param error  the error code
2931
 * @param item  the schema item
2932
 * @param itemElem  the node of the schema item
2933
 * @param message  the error message
2934
 * @param str1  an optional param for the error message
2935
 * @param str2  an optional param for the error message
2936
 * @param str3  an optional param for the error message
2937
 */
2938
static void LIBXML_ATTR_FORMAT(5,0)
2939
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2940
        xmlParserErrors error,
2941
        xmlSchemaBasicItemPtr item,
2942
        xmlNodePtr itemElem,
2943
        const char *message,
2944
        const xmlChar *str1,
2945
        const xmlChar *str2,
2946
        const xmlChar *str3)
2947
0
{
2948
0
    xmlChar *des = NULL, *msg = NULL;
2949
2950
0
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
2951
0
    msg = xmlStrdup(BAD_CAST "%s: ");
2952
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2953
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2954
0
    if ((itemElem == NULL) && (item != NULL))
2955
0
  itemElem = WXS_ITEM_NODE(item);
2956
0
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
2957
0
  (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
2958
0
    FREE_AND_NULL(des);
2959
0
    FREE_AND_NULL(msg);
2960
0
}
2961
2962
/**
2963
 * Reports an error during parsing.
2964
 *
2965
 * @param ctxt  the schema parser context
2966
 * @param error  the error code
2967
 * @param item  the schema item
2968
 * @param itemElem  the node of the schema item
2969
 * @param message  the error message
2970
 * @param str1  the optional param for the error message
2971
 */
2972
static void LIBXML_ATTR_FORMAT(5,0)
2973
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
2974
        xmlParserErrors error,
2975
        xmlSchemaBasicItemPtr item,
2976
        xmlNodePtr itemElem,
2977
        const char *message,
2978
        const xmlChar *str1)
2979
0
{
2980
0
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
2981
0
  str1, NULL, NULL);
2982
0
}
2983
2984
/**
2985
 * Reports an attribute use error during parsing.
2986
 *
2987
 * @param ctxt  the schema parser context
2988
 * @param error  the error code
2989
 * @param node  the context node
2990
 * @param ownerItem  the owner as a schema object
2991
 * @param attruse  the invalid schema attribute
2992
 * @param message  the error message
2993
 * @param str1  the optional param for the error message
2994
 * @param str2  the optional param for the error message
2995
 * @param str3  the optional param for the error message
2996
 * @param str4  the optional param for the error message
2997
 */
2998
static void LIBXML_ATTR_FORMAT(6,0)
2999
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3000
        xmlParserErrors error,
3001
        xmlNodePtr node,
3002
        xmlSchemaBasicItemPtr ownerItem,
3003
        const xmlSchemaAttributeUsePtr attruse,
3004
        const char *message,
3005
        const xmlChar *str1, const xmlChar *str2,
3006
        const xmlChar *str3,const xmlChar *str4)
3007
0
{
3008
0
    xmlChar *str = NULL, *msg = NULL;
3009
3010
0
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3011
0
    msg = xmlStrcat(msg, BAD_CAST ", ");
3012
0
    msg = xmlStrcat(msg,
3013
0
  BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3014
0
  WXS_BASIC_CAST attruse, NULL));
3015
0
    FREE_AND_NULL(str);
3016
0
    msg = xmlStrcat(msg, BAD_CAST ": ");
3017
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3018
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3019
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3020
0
  (const char *) msg, str1, str2, str3, str4);
3021
0
    xmlFree(msg);
3022
0
}
3023
3024
/**
3025
 * Reports an illegal facet for atomic simple types.
3026
 *
3027
 * @param ctxt  the schema parser context
3028
 * @param error  the error code
3029
 * @param type  the schema type
3030
 * @param baseType  the base type of type
3031
 * @param facet  the illegal facet
3032
 */
3033
static void
3034
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3035
        xmlParserErrors error,
3036
        xmlSchemaTypePtr type,
3037
        xmlSchemaTypePtr baseType,
3038
        xmlSchemaFacetPtr facet)
3039
0
{
3040
0
    xmlChar *des = NULL, *strT = NULL;
3041
3042
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3043
0
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3044
0
  "%s: The facet '%s' is not allowed on types derived from the "
3045
0
  "type %s.\n",
3046
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3047
0
  xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3048
0
  NULL, NULL);
3049
0
    FREE_AND_NULL(des);
3050
0
    FREE_AND_NULL(strT);
3051
0
}
3052
3053
/**
3054
 * Reports an illegal facet for `<list>` and `<union>`.
3055
 *
3056
 * @param ctxt  the schema parser context
3057
 * @param error  the error code
3058
 * @param type  the schema type
3059
 * @param facet  the illegal facet
3060
 */
3061
static void
3062
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3063
        xmlParserErrors error,
3064
        xmlSchemaTypePtr type,
3065
        xmlSchemaFacetPtr facet)
3066
0
{
3067
0
    xmlChar *des = NULL;
3068
3069
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3070
0
  type->node);
3071
0
    xmlSchemaPErr(ctxt, type->node, error,
3072
0
  "%s: The facet '%s' is not allowed.\n",
3073
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3074
0
    FREE_AND_NULL(des);
3075
0
}
3076
3077
/**
3078
 * Reports an illegal attribute.
3079
 *
3080
 * @param ctxt  the schema validation context
3081
 * @param error  the error code
3082
 * @param ownerItem  the owner as a schema object
3083
 * @param attr  the bad attribute node
3084
 * @param name1  first mutually exclusive name
3085
 * @param name2  second mutually exclusive name
3086
 */
3087
static void
3088
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3089
       xmlParserErrors error,
3090
       xmlSchemaBasicItemPtr ownerItem,
3091
       xmlAttrPtr attr,
3092
       const char *name1,
3093
       const char *name2)
3094
0
{
3095
0
    xmlChar *des = NULL;
3096
3097
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3098
0
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3099
0
  "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3100
0
  BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3101
0
    FREE_AND_NULL(des);
3102
0
}
3103
3104
/**
3105
 * Reports a simple type validation error.
3106
 * TODO: Should this report the value of an element as well?
3107
 *
3108
 * @param ctxt  the schema validation context
3109
 * @param error  the error code
3110
 * @param ownerItem  the schema object if existent
3111
 * @param node  the validated node
3112
 * @param type  the type specifier
3113
 * @param expected  the expected value
3114
 * @param value  the validated value
3115
 * @param message  error message
3116
 * @param str1  extra data
3117
 * @param str2  extra data
3118
 */
3119
static void LIBXML_ATTR_FORMAT(8,0)
3120
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3121
      xmlParserErrors error,
3122
      xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3123
      xmlNodePtr node,
3124
      xmlSchemaTypePtr type,
3125
      const char *expected,
3126
      const xmlChar *value,
3127
      const char *message,
3128
      const xmlChar *str1,
3129
      const xmlChar *str2)
3130
0
{
3131
0
    xmlChar *msg = NULL;
3132
3133
0
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3134
0
    if (message == NULL) {
3135
  /*
3136
  * Use default messages.
3137
  */
3138
0
  if (type != NULL) {
3139
0
      if (node->type == XML_ATTRIBUTE_NODE)
3140
0
    msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3141
0
      else
3142
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3143
0
    "valid value of ");
3144
0
      if (! xmlSchemaIsGlobalItem(type))
3145
0
    msg = xmlStrcat(msg, BAD_CAST "the local ");
3146
0
      else
3147
0
    msg = xmlStrcat(msg, BAD_CAST "the ");
3148
3149
0
      if (WXS_IS_ATOMIC(type))
3150
0
    msg = xmlStrcat(msg, BAD_CAST "atomic type");
3151
0
      else if (WXS_IS_LIST(type))
3152
0
    msg = xmlStrcat(msg, BAD_CAST "list type");
3153
0
      else if (WXS_IS_UNION(type))
3154
0
    msg = xmlStrcat(msg, BAD_CAST "union type");
3155
3156
0
      if (xmlSchemaIsGlobalItem(type)) {
3157
0
    xmlChar *str = NULL;
3158
0
    msg = xmlStrcat(msg, BAD_CAST " '");
3159
0
    if (type->builtInType != 0) {
3160
0
        msg = xmlStrcat(msg, BAD_CAST "xs:");
3161
0
        str = xmlStrdup(type->name);
3162
0
    } else {
3163
0
        const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3164
0
        if (!str)
3165
0
      str = xmlStrdup(qName);
3166
0
    }
3167
0
    msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3168
0
    msg = xmlStrcat(msg, BAD_CAST "'.");
3169
0
    FREE_AND_NULL(str);
3170
0
      }
3171
0
  } else {
3172
0
      if (node->type == XML_ATTRIBUTE_NODE)
3173
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3174
0
      else
3175
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3176
0
    "valid.");
3177
0
  }
3178
0
  if (expected) {
3179
0
      xmlChar *expectedEscaped = xmlCharStrdup(expected);
3180
0
      msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3181
0
      msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3182
0
      FREE_AND_NULL(expectedEscaped);
3183
0
      msg = xmlStrcat(msg, BAD_CAST "'.\n");
3184
0
  } else
3185
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
3186
0
  if (node->type == XML_ATTRIBUTE_NODE)
3187
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3188
0
  else
3189
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3190
0
    } else {
3191
0
  msg = xmlStrcat(msg, BAD_CAST message);
3192
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
3193
0
  xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3194
0
       (const char*) msg, str1, str2, NULL, NULL, NULL);
3195
0
    }
3196
    /* Cleanup. */
3197
0
    FREE_AND_NULL(msg)
3198
0
}
3199
3200
/**
3201
 * Reports an error concerning the content of a schema element.
3202
 *
3203
 * @param ctxt  the schema parser context
3204
 * @param error  the error code
3205
 * @param ownerItem  the owner item of the holder of the content
3206
 * @param ownerElem  the node of the holder of the content
3207
 * @param child  the invalid child node
3208
 * @param message  the optional error message
3209
 * @param content  the optional string describing the correct content
3210
 */
3211
static void
3212
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3213
         xmlParserErrors error,
3214
         xmlSchemaBasicItemPtr ownerItem,
3215
         xmlNodePtr ownerElem,
3216
         xmlNodePtr child,
3217
         const char *message,
3218
         const char *content)
3219
0
{
3220
0
    xmlChar *des = NULL;
3221
3222
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3223
0
    if (message != NULL)
3224
0
  xmlSchemaPErr2(ctxt, ownerElem, child, error,
3225
0
      "%s: %s.\n",
3226
0
      BAD_CAST des, BAD_CAST message);
3227
0
    else {
3228
0
  if (content != NULL) {
3229
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3230
0
    "%s: The content is not valid. Expected is %s.\n",
3231
0
    BAD_CAST des, BAD_CAST content);
3232
0
  } else {
3233
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3234
0
    "%s: The content is not valid.\n",
3235
0
    BAD_CAST des, NULL);
3236
0
  }
3237
0
    }
3238
0
    FREE_AND_NULL(des)
3239
0
}
3240
3241
/************************************************************************
3242
 *                  *
3243
 *      Streamable error functions                      *
3244
 *                  *
3245
 ************************************************************************/
3246
3247
3248
3249
3250
/************************************************************************
3251
 *                  *
3252
 *      Validation helper functions     *
3253
 *                  *
3254
 ************************************************************************/
3255
3256
3257
/************************************************************************
3258
 *                  *
3259
 *      Allocation functions        *
3260
 *                  *
3261
 ************************************************************************/
3262
3263
/**
3264
 * Allocate a new Schema structure.
3265
 *
3266
 * @param ctxt  a schema validation context
3267
 * @returns the newly allocated structure or NULL in case or error
3268
 */
3269
static xmlSchemaPtr
3270
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3271
0
{
3272
0
    xmlSchemaPtr ret;
3273
3274
0
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3275
0
    if (ret == NULL) {
3276
0
        xmlSchemaPErrMemory(ctxt);
3277
0
        return (NULL);
3278
0
    }
3279
0
    memset(ret, 0, sizeof(xmlSchema));
3280
0
    ret->dict = ctxt->dict;
3281
0
    xmlDictReference(ret->dict);
3282
3283
0
    return (ret);
3284
0
}
3285
3286
/**
3287
 * Allocate a new Facet structure.
3288
 *
3289
 * @returns the newly allocated structure or NULL in case or error
3290
 */
3291
xmlSchemaFacet *
3292
xmlSchemaNewFacet(void)
3293
0
{
3294
0
    xmlSchemaFacetPtr ret;
3295
3296
0
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3297
0
    if (ret == NULL) {
3298
0
        return (NULL);
3299
0
    }
3300
0
    memset(ret, 0, sizeof(xmlSchemaFacet));
3301
3302
0
    return (ret);
3303
0
}
3304
3305
/**
3306
 * Allocate a new annotation structure.
3307
 *
3308
 * @param ctxt  a schema validation context
3309
 * @param node  a node
3310
 * @returns the newly allocated structure or NULL in case or error
3311
 */
3312
static xmlSchemaAnnotPtr
3313
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3314
0
{
3315
0
    xmlSchemaAnnotPtr ret;
3316
3317
0
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3318
0
    if (ret == NULL) {
3319
0
        xmlSchemaPErrMemory(ctxt);
3320
0
        return (NULL);
3321
0
    }
3322
0
    memset(ret, 0, sizeof(xmlSchemaAnnot));
3323
0
    ret->content = node;
3324
0
    return (ret);
3325
0
}
3326
3327
static xmlSchemaItemListPtr
3328
xmlSchemaItemListCreate(void)
3329
0
{
3330
0
    xmlSchemaItemListPtr ret;
3331
3332
0
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3333
0
    if (ret == NULL) {
3334
0
  xmlSchemaPErrMemory(NULL);
3335
0
  return (NULL);
3336
0
    }
3337
0
    memset(ret, 0, sizeof(xmlSchemaItemList));
3338
0
    return (ret);
3339
0
}
3340
3341
static void
3342
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3343
0
{
3344
0
    if (list->items != NULL) {
3345
0
  xmlFree(list->items);
3346
0
  list->items = NULL;
3347
0
    }
3348
0
    list->nbItems = 0;
3349
0
    list->sizeItems = 0;
3350
0
}
3351
3352
static int
3353
xmlSchemaItemListGrow(xmlSchemaItemListPtr list, int initialSize)
3354
0
{
3355
0
    void **tmp;
3356
0
    int newSize;
3357
3358
0
    if (initialSize <= 0)
3359
0
        initialSize = 1;
3360
0
    newSize = xmlGrowCapacity(list->sizeItems, sizeof(tmp[0]),
3361
0
                              initialSize, XML_MAX_ITEMS);
3362
0
    if (newSize < 0)
3363
0
        return(-1);
3364
0
    tmp = xmlRealloc(list->items, newSize * sizeof(tmp[0]));
3365
0
    if (tmp == NULL)
3366
0
        return(-1);
3367
3368
0
    list->items = tmp;
3369
0
    list->sizeItems = newSize;
3370
0
    return(0);
3371
0
}
3372
3373
static int
3374
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3375
       int initialSize,
3376
       void *item)
3377
0
{
3378
0
    if (list->sizeItems <= list->nbItems) {
3379
0
        if (xmlSchemaItemListGrow(list, initialSize) < 0) {
3380
0
      xmlSchemaPErrMemory(NULL);
3381
0
      return(-1);
3382
0
        }
3383
0
    }
3384
3385
0
    list->items[list->nbItems++] = item;
3386
0
    return(0);
3387
0
}
3388
3389
static int
3390
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3391
0
{
3392
0
    return(xmlSchemaItemListAddSize(list, 20, item));
3393
0
}
3394
3395
static int
3396
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3397
0
{
3398
0
    if (list->sizeItems <= list->nbItems) {
3399
0
        if (xmlSchemaItemListGrow(list, 20) < 0) {
3400
0
      xmlSchemaPErrMemory(NULL);
3401
0
      return(-1);
3402
0
        }
3403
0
    }
3404
3405
    /*
3406
    * Just append if the index is greater/equal than the item count.
3407
    */
3408
0
    if (idx >= list->nbItems) {
3409
0
  list->items[list->nbItems++] = item;
3410
0
    } else {
3411
0
  int i;
3412
0
  for (i = list->nbItems; i > idx; i--)
3413
0
      list->items[i] = list->items[i-1];
3414
0
  list->items[idx] = item;
3415
0
  list->nbItems++;
3416
0
    }
3417
0
    return(0);
3418
0
}
3419
3420
static int
3421
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3422
0
{
3423
0
    int i;
3424
0
    if ((list->items == NULL) || (idx >= list->nbItems))
3425
0
  return(-1);
3426
3427
0
    if (list->nbItems == 1) {
3428
  /* TODO: Really free the list? */
3429
0
  xmlFree(list->items);
3430
0
  list->items = NULL;
3431
0
  list->nbItems = 0;
3432
0
  list->sizeItems = 0;
3433
0
    } else if (list->nbItems -1 == idx) {
3434
0
  list->nbItems--;
3435
0
    } else {
3436
0
  for (i = idx; i < list->nbItems -1; i++)
3437
0
      list->items[i] = list->items[i+1];
3438
0
  list->nbItems--;
3439
0
    }
3440
0
    return(0);
3441
0
}
3442
3443
/**
3444
 * Deallocate a annotation structure
3445
 *
3446
 * @param list  a schema type structure
3447
 */
3448
static void
3449
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3450
0
{
3451
0
    if (list == NULL)
3452
0
  return;
3453
0
    if (list->items != NULL)
3454
0
  xmlFree(list->items);
3455
0
    xmlFree(list);
3456
0
}
3457
3458
static void
3459
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3460
0
{
3461
0
    if (bucket == NULL)
3462
0
  return;
3463
0
    if (bucket->globals != NULL) {
3464
0
  xmlSchemaComponentListFree(bucket->globals);
3465
0
  xmlSchemaItemListFree(bucket->globals);
3466
0
    }
3467
0
    if (bucket->locals != NULL) {
3468
0
  xmlSchemaComponentListFree(bucket->locals);
3469
0
  xmlSchemaItemListFree(bucket->locals);
3470
0
    }
3471
0
    if (bucket->relations != NULL) {
3472
0
  xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3473
0
  do {
3474
0
      prev = cur;
3475
0
      cur = cur->next;
3476
0
      xmlFree(prev);
3477
0
  } while (cur != NULL);
3478
0
    }
3479
0
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3480
0
  xmlFreeDoc(bucket->doc);
3481
0
    }
3482
0
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3483
0
  if (WXS_IMPBUCKET(bucket)->schema != NULL)
3484
0
      xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3485
0
    }
3486
0
    xmlFree(bucket);
3487
0
}
3488
3489
static void
3490
xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3491
0
{
3492
0
    xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3493
0
}
3494
3495
static xmlSchemaBucketPtr
3496
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3497
       int type, const xmlChar *targetNamespace)
3498
0
{
3499
0
    xmlSchemaBucketPtr ret;
3500
0
    int size;
3501
0
    xmlSchemaPtr mainSchema;
3502
3503
0
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3504
0
  PERROR_INT("xmlSchemaBucketCreate",
3505
0
      "no main schema on constructor");
3506
0
  return(NULL);
3507
0
    }
3508
0
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3509
    /* Create the schema bucket. */
3510
0
    if (WXS_IS_BUCKET_INCREDEF(type))
3511
0
  size = sizeof(xmlSchemaInclude);
3512
0
    else
3513
0
  size = sizeof(xmlSchemaImport);
3514
0
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3515
0
    if (ret == NULL) {
3516
0
  xmlSchemaPErrMemory(NULL);
3517
0
  return(NULL);
3518
0
    }
3519
0
    memset(ret, 0, size);
3520
0
    ret->targetNamespace = targetNamespace;
3521
0
    ret->type = type;
3522
0
    ret->globals = xmlSchemaItemListCreate();
3523
0
    if (ret->globals == NULL) {
3524
0
  xmlSchemaBucketFree(ret);
3525
0
  return(NULL);
3526
0
    }
3527
0
    ret->locals = xmlSchemaItemListCreate();
3528
0
    if (ret->locals == NULL) {
3529
0
  xmlSchemaBucketFree(ret);
3530
0
  return(NULL);
3531
0
    }
3532
    /*
3533
    * The following will assure that only the first bucket is marked as
3534
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3535
    * For each following import buckets an xmlSchema will be created.
3536
    * An xmlSchema will be created for every distinct targetNamespace.
3537
    * We assign the targetNamespace to the schemata here.
3538
    */
3539
0
    if (! WXS_HAS_BUCKETS(pctxt)) {
3540
0
  if (WXS_IS_BUCKET_INCREDEF(type)) {
3541
0
      PERROR_INT("xmlSchemaBucketCreate",
3542
0
    "first bucket but it's an include or redefine");
3543
0
      xmlSchemaBucketFree(ret);
3544
0
      return(NULL);
3545
0
  }
3546
  /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3547
0
  ret->type = XML_SCHEMA_SCHEMA_MAIN;
3548
  /* Point to the *main* schema. */
3549
0
  WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3550
0
  WXS_IMPBUCKET(ret)->schema = mainSchema;
3551
  /*
3552
  * Ensure that the main schema gets a targetNamespace.
3553
  */
3554
0
  mainSchema->targetNamespace = targetNamespace;
3555
0
    } else {
3556
0
  if (type == XML_SCHEMA_SCHEMA_MAIN) {
3557
0
      PERROR_INT("xmlSchemaBucketCreate",
3558
0
    "main bucket but it's not the first one");
3559
0
      xmlSchemaBucketFree(ret);
3560
0
      return(NULL);
3561
0
  } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3562
      /*
3563
      * Create a schema for imports and assign the
3564
      * targetNamespace.
3565
      */
3566
0
      WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3567
0
      if (WXS_IMPBUCKET(ret)->schema == NULL) {
3568
0
    xmlSchemaBucketFree(ret);
3569
0
    return(NULL);
3570
0
      }
3571
0
      WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3572
0
  }
3573
0
    }
3574
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3575
0
  int res;
3576
  /*
3577
  * Imports go into the "schemasImports" slot of the main *schema*.
3578
  * Note that we create an import entry for the main schema as well; i.e.,
3579
  * even if there's only one schema, we'll get an import.
3580
  */
3581
0
  if (mainSchema->schemasImports == NULL) {
3582
0
      mainSchema->schemasImports = xmlHashCreateDict(5,
3583
0
    WXS_CONSTRUCTOR(pctxt)->dict);
3584
0
      if (mainSchema->schemasImports == NULL) {
3585
0
    xmlSchemaBucketFree(ret);
3586
0
    return(NULL);
3587
0
      }
3588
0
  }
3589
0
  if (targetNamespace == NULL)
3590
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3591
0
    XML_SCHEMAS_NO_NAMESPACE, ret);
3592
0
  else
3593
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3594
0
    targetNamespace, ret);
3595
0
  if (res != 0) {
3596
0
      PERROR_INT("xmlSchemaBucketCreate",
3597
0
    "failed to add the schema bucket to the hash");
3598
0
      xmlSchemaBucketFree(ret);
3599
0
      return(NULL);
3600
0
  }
3601
0
    } else {
3602
  /* Set the @ownerImport of an include bucket. */
3603
0
  if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3604
0
      WXS_INCBUCKET(ret)->ownerImport =
3605
0
    WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3606
0
  else
3607
0
      WXS_INCBUCKET(ret)->ownerImport =
3608
0
    WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3609
3610
  /* Includes got into the "includes" slot of the *main* schema. */
3611
0
  if (mainSchema->includes == NULL) {
3612
0
      mainSchema->includes = xmlSchemaItemListCreate();
3613
0
      if (mainSchema->includes == NULL) {
3614
0
    xmlSchemaBucketFree(ret);
3615
0
    return(NULL);
3616
0
      }
3617
0
  }
3618
0
  if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
3619
0
      xmlSchemaBucketFree(ret);
3620
0
      return(NULL);
3621
0
        }
3622
0
    }
3623
    /*
3624
    * Add to list of all buckets; this is used for lookup
3625
    * during schema construction time only.
3626
    */
3627
0
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3628
0
  return(NULL);
3629
0
    return(ret);
3630
0
}
3631
3632
static int
3633
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3634
0
{
3635
0
    if (*list == NULL) {
3636
0
  *list = xmlSchemaItemListCreate();
3637
0
  if (*list == NULL)
3638
0
      return(-1);
3639
0
    }
3640
0
    return(xmlSchemaItemListAddSize(*list, initialSize, item));
3641
0
}
3642
3643
/**
3644
 * Deallocate a annotation structure
3645
 *
3646
 * @param annot  a schema type structure
3647
 */
3648
static void
3649
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3650
0
{
3651
0
    if (annot == NULL)
3652
0
        return;
3653
0
    if (annot->next == NULL) {
3654
0
  xmlFree(annot);
3655
0
    } else {
3656
0
  xmlSchemaAnnotPtr prev;
3657
3658
0
  do {
3659
0
      prev = annot;
3660
0
      annot = annot->next;
3661
0
      xmlFree(prev);
3662
0
  } while (annot != NULL);
3663
0
    }
3664
0
}
3665
3666
/**
3667
 * Deallocate a Schema Notation structure.
3668
 *
3669
 * @param nota  a schema notation structure
3670
 */
3671
static void
3672
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3673
0
{
3674
0
    if (nota == NULL)
3675
0
        return;
3676
0
    if (nota->annot != NULL)
3677
0
  xmlSchemaFreeAnnot(nota->annot);
3678
0
    xmlFree(nota);
3679
0
}
3680
3681
/**
3682
 * Deallocates an attribute declaration structure.
3683
 *
3684
 * @param attr  an attribute declaration
3685
 */
3686
static void
3687
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3688
0
{
3689
0
    if (attr == NULL)
3690
0
        return;
3691
0
    if (attr->annot != NULL)
3692
0
  xmlSchemaFreeAnnot(attr->annot);
3693
0
    if (attr->defVal != NULL)
3694
0
  xmlSchemaFreeValue(attr->defVal);
3695
0
    xmlFree(attr);
3696
0
}
3697
3698
/**
3699
 * Deallocates an attribute use structure.
3700
 *
3701
 * @param use  an attribute use
3702
 */
3703
static void
3704
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3705
0
{
3706
0
    if (use == NULL)
3707
0
        return;
3708
0
    if (use->annot != NULL)
3709
0
  xmlSchemaFreeAnnot(use->annot);
3710
0
    if (use->defVal != NULL)
3711
0
  xmlSchemaFreeValue(use->defVal);
3712
0
    xmlFree(use);
3713
0
}
3714
3715
/**
3716
 * Deallocates an attribute use structure.
3717
 *
3718
 * @param prohib  an attribute use prohibition
3719
 */
3720
static void
3721
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3722
0
{
3723
0
    if (prohib == NULL)
3724
0
        return;
3725
0
    xmlFree(prohib);
3726
0
}
3727
3728
/**
3729
 * set:  a schema wildcard namespace
3730
 *
3731
 * Deallocates a list of wildcard constraint structures.
3732
 */
3733
static void
3734
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3735
0
{
3736
0
    xmlSchemaWildcardNsPtr next;
3737
3738
0
    while (set != NULL) {
3739
0
  next = set->next;
3740
0
  xmlFree(set);
3741
0
  set = next;
3742
0
    }
3743
0
}
3744
3745
/**
3746
 * Deallocates a wildcard structure.
3747
 *
3748
 * @param wildcard  a wildcard structure
3749
 */
3750
void
3751
xmlSchemaFreeWildcard(xmlSchemaWildcard *wildcard)
3752
0
{
3753
0
    if (wildcard == NULL)
3754
0
        return;
3755
0
    if (wildcard->annot != NULL)
3756
0
        xmlSchemaFreeAnnot(wildcard->annot);
3757
0
    if (wildcard->nsSet != NULL)
3758
0
  xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3759
0
    if (wildcard->negNsSet != NULL)
3760
0
  xmlFree(wildcard->negNsSet);
3761
0
    xmlFree(wildcard);
3762
0
}
3763
3764
/**
3765
 * Deallocate a Schema Attribute Group structure.
3766
 *
3767
 * @param attrGr  a schema attribute group structure
3768
 */
3769
static void
3770
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3771
0
{
3772
0
    if (attrGr == NULL)
3773
0
        return;
3774
0
    if (attrGr->annot != NULL)
3775
0
        xmlSchemaFreeAnnot(attrGr->annot);
3776
0
    if (attrGr->attrUses != NULL)
3777
0
  xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3778
0
    xmlFree(attrGr);
3779
0
}
3780
3781
/**
3782
 * Deallocatea a QName reference structure.
3783
 *
3784
 * @param item  a QName reference structure
3785
 */
3786
static void
3787
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3788
0
{
3789
0
    xmlFree(item);
3790
0
}
3791
3792
/**
3793
 * Deallocate a list of types.
3794
 *
3795
 * @param link  a type link
3796
 */
3797
static void
3798
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3799
0
{
3800
0
    xmlSchemaTypeLinkPtr next;
3801
3802
0
    while (link != NULL) {
3803
0
  next = link->next;
3804
0
  xmlFree(link);
3805
0
  link = next;
3806
0
    }
3807
0
}
3808
3809
static void
3810
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3811
0
{
3812
0
    xmlSchemaIDCStateObjPtr next;
3813
0
    while (sto != NULL) {
3814
0
  next = sto->next;
3815
0
  if (sto->history != NULL)
3816
0
      xmlFree(sto->history);
3817
0
  if (sto->xpathCtxt != NULL)
3818
0
      xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3819
0
  xmlFree(sto);
3820
0
  sto = next;
3821
0
    }
3822
0
}
3823
3824
/**
3825
 * Deallocates an identity-constraint definition.
3826
 *
3827
 * @param idcDef  a identity-constraint definition
3828
 */
3829
static void
3830
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3831
0
{
3832
0
    xmlSchemaIDCSelectPtr cur, prev;
3833
3834
0
    if (idcDef == NULL)
3835
0
  return;
3836
0
    if (idcDef->annot != NULL)
3837
0
        xmlSchemaFreeAnnot(idcDef->annot);
3838
    /* Selector */
3839
0
    if (idcDef->selector != NULL) {
3840
0
  if (idcDef->selector->xpathComp != NULL)
3841
0
      xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3842
0
  xmlFree(idcDef->selector);
3843
0
    }
3844
    /* Fields */
3845
0
    if (idcDef->fields != NULL) {
3846
0
  cur = idcDef->fields;
3847
0
  do {
3848
0
      prev = cur;
3849
0
      cur = cur->next;
3850
0
      if (prev->xpathComp != NULL)
3851
0
    xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3852
0
      xmlFree(prev);
3853
0
  } while (cur != NULL);
3854
0
    }
3855
0
    xmlFree(idcDef);
3856
0
}
3857
3858
/**
3859
 * Deallocate a Schema Element structure.
3860
 *
3861
 * @param elem  a schema element structure
3862
 */
3863
static void
3864
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3865
0
{
3866
0
    if (elem == NULL)
3867
0
        return;
3868
0
    if (elem->annot != NULL)
3869
0
        xmlSchemaFreeAnnot(elem->annot);
3870
0
    if (elem->contModel != NULL)
3871
0
        xmlRegFreeRegexp(elem->contModel);
3872
0
    if (elem->defVal != NULL)
3873
0
  xmlSchemaFreeValue(elem->defVal);
3874
0
    xmlFree(elem);
3875
0
}
3876
3877
/**
3878
 * Deallocate a Schema Facet structure.
3879
 *
3880
 * @param facet  a schema facet structure
3881
 */
3882
void
3883
xmlSchemaFreeFacet(xmlSchemaFacet *facet)
3884
0
{
3885
0
    if (facet == NULL)
3886
0
        return;
3887
0
    if (facet->val != NULL)
3888
0
        xmlSchemaFreeValue(facet->val);
3889
0
    if (facet->regexp != NULL)
3890
0
        xmlRegFreeRegexp(facet->regexp);
3891
0
    if (facet->annot != NULL)
3892
0
        xmlSchemaFreeAnnot(facet->annot);
3893
0
    xmlFree(facet);
3894
0
}
3895
3896
/**
3897
 * Deallocate a Schema Type structure.
3898
 *
3899
 * @param type  a schema type structure
3900
 */
3901
void
3902
xmlSchemaFreeType(xmlSchemaType *type)
3903
0
{
3904
0
    if (type == NULL)
3905
0
        return;
3906
0
    if (type->annot != NULL)
3907
0
        xmlSchemaFreeAnnot(type->annot);
3908
0
    if (type->facets != NULL) {
3909
0
        xmlSchemaFacetPtr facet, next;
3910
3911
0
        facet = type->facets;
3912
0
        while (facet != NULL) {
3913
0
            next = facet->next;
3914
0
            xmlSchemaFreeFacet(facet);
3915
0
            facet = next;
3916
0
        }
3917
0
    }
3918
0
    if (type->attrUses != NULL)
3919
0
  xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
3920
0
    if (type->memberTypes != NULL)
3921
0
  xmlSchemaFreeTypeLinkList(type->memberTypes);
3922
0
    if (type->facetSet != NULL) {
3923
0
  xmlSchemaFacetLinkPtr next, link;
3924
3925
0
  link = type->facetSet;
3926
0
  do {
3927
0
      next = link->next;
3928
0
      xmlFree(link);
3929
0
      link = next;
3930
0
  } while (link != NULL);
3931
0
    }
3932
0
    if (type->contModel != NULL)
3933
0
        xmlRegFreeRegexp(type->contModel);
3934
0
    xmlFree(type);
3935
0
}
3936
3937
/**
3938
 * Deallocates a schema model group definition.
3939
 *
3940
 * @param item  a schema model group definition
3941
 */
3942
static void
3943
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
3944
0
{
3945
0
    if (item->annot != NULL)
3946
0
  xmlSchemaFreeAnnot(item->annot);
3947
0
    xmlFree(item);
3948
0
}
3949
3950
/**
3951
 * Deallocates a schema model group structure.
3952
 *
3953
 * @param item  a schema model group
3954
 */
3955
static void
3956
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
3957
0
{
3958
0
    if (item->annot != NULL)
3959
0
  xmlSchemaFreeAnnot(item->annot);
3960
0
    xmlFree(item);
3961
0
}
3962
3963
static void
3964
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
3965
0
{
3966
0
    if ((list == NULL) || (list->nbItems == 0))
3967
0
  return;
3968
0
    {
3969
0
  xmlSchemaTreeItemPtr item;
3970
0
  xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
3971
0
  int i;
3972
3973
0
  for (i = 0; i < list->nbItems; i++) {
3974
0
      item = items[i];
3975
0
      if (item == NULL)
3976
0
    continue;
3977
0
      switch (item->type) {
3978
0
    case XML_SCHEMA_TYPE_SIMPLE:
3979
0
    case XML_SCHEMA_TYPE_COMPLEX:
3980
0
        xmlSchemaFreeType((xmlSchemaTypePtr) item);
3981
0
        break;
3982
0
    case XML_SCHEMA_TYPE_ATTRIBUTE:
3983
0
        xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
3984
0
        break;
3985
0
    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
3986
0
        xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
3987
0
        break;
3988
0
    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
3989
0
        xmlSchemaFreeAttributeUseProhib(
3990
0
      (xmlSchemaAttributeUseProhibPtr) item);
3991
0
        break;
3992
0
    case XML_SCHEMA_TYPE_ELEMENT:
3993
0
        xmlSchemaFreeElement((xmlSchemaElementPtr) item);
3994
0
        break;
3995
0
    case XML_SCHEMA_TYPE_PARTICLE:
3996
0
        if (item->annot != NULL)
3997
0
      xmlSchemaFreeAnnot(item->annot);
3998
0
        xmlFree(item);
3999
0
        break;
4000
0
    case XML_SCHEMA_TYPE_SEQUENCE:
4001
0
    case XML_SCHEMA_TYPE_CHOICE:
4002
0
    case XML_SCHEMA_TYPE_ALL:
4003
0
        xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4004
0
        break;
4005
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4006
0
        xmlSchemaFreeAttributeGroup(
4007
0
      (xmlSchemaAttributeGroupPtr) item);
4008
0
        break;
4009
0
    case XML_SCHEMA_TYPE_GROUP:
4010
0
        xmlSchemaFreeModelGroupDef(
4011
0
      (xmlSchemaModelGroupDefPtr) item);
4012
0
        break;
4013
0
    case XML_SCHEMA_TYPE_ANY:
4014
0
    case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4015
0
        xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4016
0
        break;
4017
0
    case XML_SCHEMA_TYPE_IDC_KEY:
4018
0
    case XML_SCHEMA_TYPE_IDC_UNIQUE:
4019
0
    case XML_SCHEMA_TYPE_IDC_KEYREF:
4020
0
        xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4021
0
        break;
4022
0
    case XML_SCHEMA_TYPE_NOTATION:
4023
0
        xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4024
0
        break;
4025
0
    case XML_SCHEMA_EXTRA_QNAMEREF:
4026
0
        xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4027
0
        break;
4028
0
    default:
4029
        /* TODO: This should never be hit. */
4030
0
        break;
4031
0
      }
4032
0
  }
4033
0
  list->nbItems = 0;
4034
0
    }
4035
0
}
4036
4037
/**
4038
 * Deallocate a Schema structure.
4039
 *
4040
 * @param schema  a schema structure
4041
 */
4042
void
4043
xmlSchemaFree(xmlSchema *schema)
4044
0
{
4045
0
    if (schema == NULL)
4046
0
        return;
4047
    /*
4048
    * Note that those slots are not responsible for freeing
4049
    * schema components anymore; this will now be done by
4050
    * the schema buckets.
4051
    */
4052
0
    if (schema->notaDecl != NULL)
4053
0
        xmlHashFree(schema->notaDecl, NULL);
4054
0
    if (schema->attrDecl != NULL)
4055
0
        xmlHashFree(schema->attrDecl, NULL);
4056
0
    if (schema->attrgrpDecl != NULL)
4057
0
        xmlHashFree(schema->attrgrpDecl, NULL);
4058
0
    if (schema->elemDecl != NULL)
4059
0
        xmlHashFree(schema->elemDecl, NULL);
4060
0
    if (schema->typeDecl != NULL)
4061
0
        xmlHashFree(schema->typeDecl, NULL);
4062
0
    if (schema->groupDecl != NULL)
4063
0
        xmlHashFree(schema->groupDecl, NULL);
4064
0
    if (schema->idcDef != NULL)
4065
0
        xmlHashFree(schema->idcDef, NULL);
4066
4067
0
    if (schema->schemasImports != NULL)
4068
0
  xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4069
0
    if (schema->includes != NULL) {
4070
0
  xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4071
0
  int i;
4072
0
  for (i = 0; i < list->nbItems; i++) {
4073
0
      xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4074
0
  }
4075
0
  xmlSchemaItemListFree(list);
4076
0
    }
4077
0
    if (schema->annot != NULL)
4078
0
        xmlSchemaFreeAnnot(schema->annot);
4079
    /* Never free the doc here, since this will be done by the buckets. */
4080
4081
0
    xmlDictFree(schema->dict);
4082
0
    xmlFree(schema);
4083
0
}
4084
4085
/************************************************************************
4086
 *                  *
4087
 *      Debug functions         *
4088
 *                  *
4089
 ************************************************************************/
4090
4091
#ifdef LIBXML_DEBUG_ENABLED
4092
4093
static void
4094
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4095
4096
/**
4097
 * Dump the element
4098
 *
4099
 * @param payload  an element
4100
 * @param data  the file output
4101
 * @param name  unused
4102
 * @param namespace  unused
4103
 * @param context  unused
4104
 */
4105
static void
4106
xmlSchemaElementDump(void *payload, void *data,
4107
                     const xmlChar * name ATTRIBUTE_UNUSED,
4108
         const xmlChar * namespace ATTRIBUTE_UNUSED,
4109
                     const xmlChar * context ATTRIBUTE_UNUSED)
4110
0
{
4111
0
    xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4112
0
    FILE *output = (FILE *) data;
4113
0
    if (elem == NULL)
4114
0
        return;
4115
4116
4117
0
    fprintf(output, "Element");
4118
0
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4119
0
  fprintf(output, " (global)");
4120
0
    fprintf(output, ": '%s' ", elem->name);
4121
0
    if (namespace != NULL)
4122
0
  fprintf(output, "ns '%s'", namespace);
4123
0
    fprintf(output, "\n");
4124
#if 0
4125
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4126
  fprintf(output, "  min %d ", elem->minOccurs);
4127
        if (elem->maxOccurs >= UNBOUNDED)
4128
            fprintf(output, "max: unbounded\n");
4129
        else if (elem->maxOccurs != 1)
4130
            fprintf(output, "max: %d\n", elem->maxOccurs);
4131
        else
4132
            fprintf(output, "\n");
4133
    }
4134
#endif
4135
    /*
4136
    * Misc other properties.
4137
    */
4138
0
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4139
0
  (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4140
0
  (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4141
0
  (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4142
0
  fprintf(output, "  props: ");
4143
0
  if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4144
0
      fprintf(output, "[fixed] ");
4145
0
  if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4146
0
      fprintf(output, "[default] ");
4147
0
  if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4148
0
      fprintf(output, "[abstract] ");
4149
0
  if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4150
0
      fprintf(output, "[nillable] ");
4151
0
  fprintf(output, "\n");
4152
0
    }
4153
    /*
4154
    * Default/fixed value.
4155
    */
4156
0
    if (elem->value != NULL)
4157
0
  fprintf(output, "  value: '%s'\n", elem->value);
4158
    /*
4159
    * Type.
4160
    */
4161
0
    if (elem->namedType != NULL) {
4162
0
  fprintf(output, "  type: '%s' ", elem->namedType);
4163
0
  if (elem->namedTypeNs != NULL)
4164
0
      fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4165
0
  else
4166
0
      fprintf(output, "\n");
4167
0
    } else if (elem->subtypes != NULL) {
4168
  /*
4169
  * Dump local types.
4170
  */
4171
0
  xmlSchemaTypeDump(elem->subtypes, output);
4172
0
    }
4173
    /*
4174
    * Substitution group.
4175
    */
4176
0
    if (elem->substGroup != NULL) {
4177
0
  fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4178
0
  if (elem->substGroupNs != NULL)
4179
0
      fprintf(output, "ns '%s'\n", elem->substGroupNs);
4180
0
  else
4181
0
      fprintf(output, "\n");
4182
0
    }
4183
0
}
4184
4185
/**
4186
 * Dump the annotation
4187
 *
4188
 * @param output  the file output
4189
 * @param annot  a annotation
4190
 */
4191
static void
4192
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4193
0
{
4194
0
    xmlChar *content;
4195
4196
0
    if (annot == NULL)
4197
0
        return;
4198
4199
0
    content = xmlNodeGetContent(annot->content);
4200
0
    if (content != NULL) {
4201
0
        fprintf(output, "  Annot: %s\n", content);
4202
0
        xmlFree(content);
4203
0
    } else
4204
0
        fprintf(output, "  Annot: empty\n");
4205
0
}
4206
4207
/**
4208
 * Dump a SchemaType structure
4209
 *
4210
 * @param particle  the schema particle
4211
 * @param output  the file output
4212
 * @param depth  the depth used for indentation
4213
 */
4214
static void
4215
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4216
0
{
4217
0
    xmlChar *str = NULL;
4218
0
    xmlSchemaTreeItemPtr term;
4219
0
    char shift[100];
4220
0
    int i;
4221
4222
0
    if (particle == NULL)
4223
0
  return;
4224
0
    for (i = 0;((i < depth) && (i < 25));i++)
4225
0
        shift[2 * i] = shift[2 * i + 1] = ' ';
4226
0
    shift[2 * i] = shift[2 * i + 1] = 0;
4227
0
    fprintf(output, "%s", shift);
4228
0
    if (particle->children == NULL) {
4229
0
  fprintf(output, "MISSING particle term\n");
4230
0
  return;
4231
0
    }
4232
0
    term = particle->children;
4233
0
    if (term == NULL) {
4234
0
  fprintf(output, "(NULL)");
4235
0
    } else {
4236
0
  switch (term->type) {
4237
0
      case XML_SCHEMA_TYPE_ELEMENT:
4238
0
    fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4239
0
        ((xmlSchemaElementPtr)term)->targetNamespace,
4240
0
        ((xmlSchemaElementPtr)term)->name));
4241
0
    FREE_AND_NULL(str);
4242
0
    break;
4243
0
      case XML_SCHEMA_TYPE_SEQUENCE:
4244
0
    fprintf(output, "SEQUENCE");
4245
0
    break;
4246
0
      case XML_SCHEMA_TYPE_CHOICE:
4247
0
    fprintf(output, "CHOICE");
4248
0
    break;
4249
0
      case XML_SCHEMA_TYPE_ALL:
4250
0
    fprintf(output, "ALL");
4251
0
    break;
4252
0
      case XML_SCHEMA_TYPE_ANY:
4253
0
    fprintf(output, "ANY");
4254
0
    break;
4255
0
      default:
4256
0
    fprintf(output, "UNKNOWN\n");
4257
0
    return;
4258
0
  }
4259
0
    }
4260
0
    if (particle->minOccurs != 1)
4261
0
  fprintf(output, " min: %d", particle->minOccurs);
4262
0
    if (particle->maxOccurs >= UNBOUNDED)
4263
0
  fprintf(output, " max: unbounded");
4264
0
    else if (particle->maxOccurs != 1)
4265
0
  fprintf(output, " max: %d", particle->maxOccurs);
4266
0
    fprintf(output, "\n");
4267
0
    if (term &&
4268
0
  ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4269
0
   (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4270
0
   (term->type == XML_SCHEMA_TYPE_ALL)) &&
4271
0
   (term->children != NULL)) {
4272
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4273
0
      output, depth +1);
4274
0
    }
4275
0
    if (particle->next != NULL)
4276
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4277
0
    output, depth);
4278
0
}
4279
4280
/**
4281
 * Dumps a list of attribute use components.
4282
 *
4283
 * @param uses  attribute uses list
4284
 * @param output  the file output
4285
 */
4286
static void
4287
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4288
0
{
4289
0
    xmlSchemaAttributeUsePtr use;
4290
0
    xmlSchemaAttributeUseProhibPtr prohib;
4291
0
    xmlSchemaQNameRefPtr ref;
4292
0
    const xmlChar *name, *tns;
4293
0
    xmlChar *str = NULL;
4294
0
    int i;
4295
4296
0
    if ((uses == NULL) || (uses->nbItems == 0))
4297
0
        return;
4298
4299
0
    fprintf(output, "  attributes:\n");
4300
0
    for (i = 0; i < uses->nbItems; i++) {
4301
0
  use = uses->items[i];
4302
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4303
0
      fprintf(output, "  [prohibition] ");
4304
0
      prohib = (xmlSchemaAttributeUseProhibPtr) use;
4305
0
      name = prohib->name;
4306
0
      tns = prohib->targetNamespace;
4307
0
  } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4308
0
      fprintf(output, "  [reference] ");
4309
0
      ref = (xmlSchemaQNameRefPtr) use;
4310
0
      name = ref->name;
4311
0
      tns = ref->targetNamespace;
4312
0
  } else {
4313
0
      fprintf(output, "  [use] ");
4314
0
      name = WXS_ATTRUSE_DECL_NAME(use);
4315
0
      tns = WXS_ATTRUSE_DECL_TNS(use);
4316
0
  }
4317
0
  fprintf(output, "'%s'\n",
4318
0
      (const char *) xmlSchemaFormatQName(&str, tns, name));
4319
0
  FREE_AND_NULL(str);
4320
0
    }
4321
0
}
4322
4323
/**
4324
 * Dump a SchemaType structure
4325
 *
4326
 * @param output  the file output
4327
 * @param type  a type structure
4328
 */
4329
static void
4330
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4331
0
{
4332
0
    if (type == NULL) {
4333
0
        fprintf(output, "Type: NULL\n");
4334
0
        return;
4335
0
    }
4336
0
    fprintf(output, "Type: ");
4337
0
    if (type->name != NULL)
4338
0
        fprintf(output, "'%s' ", type->name);
4339
0
    else
4340
0
        fprintf(output, "(no name) ");
4341
0
    if (type->targetNamespace != NULL)
4342
0
  fprintf(output, "ns '%s' ", type->targetNamespace);
4343
0
    switch (type->type) {
4344
0
        case XML_SCHEMA_TYPE_BASIC:
4345
0
            fprintf(output, "[basic] ");
4346
0
            break;
4347
0
        case XML_SCHEMA_TYPE_SIMPLE:
4348
0
            fprintf(output, "[simple] ");
4349
0
            break;
4350
0
        case XML_SCHEMA_TYPE_COMPLEX:
4351
0
            fprintf(output, "[complex] ");
4352
0
            break;
4353
0
        case XML_SCHEMA_TYPE_SEQUENCE:
4354
0
            fprintf(output, "[sequence] ");
4355
0
            break;
4356
0
        case XML_SCHEMA_TYPE_CHOICE:
4357
0
            fprintf(output, "[choice] ");
4358
0
            break;
4359
0
        case XML_SCHEMA_TYPE_ALL:
4360
0
            fprintf(output, "[all] ");
4361
0
            break;
4362
0
        case XML_SCHEMA_TYPE_UR:
4363
0
            fprintf(output, "[ur] ");
4364
0
            break;
4365
0
        case XML_SCHEMA_TYPE_RESTRICTION:
4366
0
            fprintf(output, "[restriction] ");
4367
0
            break;
4368
0
        case XML_SCHEMA_TYPE_EXTENSION:
4369
0
            fprintf(output, "[extension] ");
4370
0
            break;
4371
0
        default:
4372
0
            fprintf(output, "[unknown type %d] ", type->type);
4373
0
            break;
4374
0
    }
4375
0
    fprintf(output, "content: ");
4376
0
    switch (type->contentType) {
4377
0
        case XML_SCHEMA_CONTENT_UNKNOWN:
4378
0
            fprintf(output, "[unknown] ");
4379
0
            break;
4380
0
        case XML_SCHEMA_CONTENT_EMPTY:
4381
0
            fprintf(output, "[empty] ");
4382
0
            break;
4383
0
        case XML_SCHEMA_CONTENT_ELEMENTS:
4384
0
            fprintf(output, "[element] ");
4385
0
            break;
4386
0
        case XML_SCHEMA_CONTENT_MIXED:
4387
0
            fprintf(output, "[mixed] ");
4388
0
            break;
4389
0
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4390
  /* not used. */
4391
0
            break;
4392
0
        case XML_SCHEMA_CONTENT_BASIC:
4393
0
            fprintf(output, "[basic] ");
4394
0
            break;
4395
0
        case XML_SCHEMA_CONTENT_SIMPLE:
4396
0
            fprintf(output, "[simple] ");
4397
0
            break;
4398
0
        case XML_SCHEMA_CONTENT_ANY:
4399
0
            fprintf(output, "[any] ");
4400
0
            break;
4401
0
    }
4402
0
    fprintf(output, "\n");
4403
0
    if (type->base != NULL) {
4404
0
        fprintf(output, "  base type: '%s'", type->base);
4405
0
  if (type->baseNs != NULL)
4406
0
      fprintf(output, " ns '%s'\n", type->baseNs);
4407
0
  else
4408
0
      fprintf(output, "\n");
4409
0
    }
4410
0
    if (type->attrUses != NULL)
4411
0
  xmlSchemaAttrUsesDump(type->attrUses, output);
4412
0
    if (type->annot != NULL)
4413
0
        xmlSchemaAnnotDump(output, type->annot);
4414
0
#ifdef DUMP_CONTENT_MODEL
4415
0
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4416
0
  (type->subtypes != NULL)) {
4417
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4418
0
      output, 1);
4419
0
    }
4420
0
#endif
4421
0
}
4422
4423
static void
4424
xmlSchemaTypeDumpEntry(void *type, void *output,
4425
                       const xmlChar *name ATTRIBUTE_UNUSED)
4426
0
{
4427
0
    xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4428
0
}
4429
4430
/**
4431
 * Dump a Schema structure.
4432
 *
4433
 * @param output  the file output
4434
 * @param schema  a schema structure
4435
 */
4436
void
4437
xmlSchemaDump(FILE * output, xmlSchema *schema)
4438
0
{
4439
0
    if (output == NULL)
4440
0
        return;
4441
0
    if (schema == NULL) {
4442
0
        fprintf(output, "Schemas: NULL\n");
4443
0
        return;
4444
0
    }
4445
0
    fprintf(output, "Schemas: ");
4446
0
    if (schema->name != NULL)
4447
0
        fprintf(output, "%s, ", schema->name);
4448
0
    else
4449
0
        fprintf(output, "no name, ");
4450
0
    if (schema->targetNamespace != NULL)
4451
0
        fprintf(output, "%s", (const char *) schema->targetNamespace);
4452
0
    else
4453
0
        fprintf(output, "no target namespace");
4454
0
    fprintf(output, "\n");
4455
0
    if (schema->annot != NULL)
4456
0
        xmlSchemaAnnotDump(output, schema->annot);
4457
0
    xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4458
0
    xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4459
0
}
4460
4461
#endif /* LIBXML_DEBUG_ENABLED */
4462
4463
/************************************************************************
4464
 *                  *
4465
 *      Utilities         *
4466
 *                  *
4467
 ************************************************************************/
4468
4469
/**
4470
 * Seeks an attribute with a name of `name` in
4471
 * no namespace.
4472
 *
4473
 * @param node  the element node
4474
 * @param name  the name of the attribute
4475
 * @returns the attribute or NULL if not present.
4476
 */
4477
static xmlAttrPtr
4478
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4479
0
{
4480
0
    xmlAttrPtr prop;
4481
4482
0
    if ((node == NULL) || (name == NULL))
4483
0
  return(NULL);
4484
0
    prop = node->properties;
4485
0
    while (prop != NULL) {
4486
0
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4487
0
      return(prop);
4488
0
  prop = prop->next;
4489
0
    }
4490
0
    return (NULL);
4491
0
}
4492
4493
/**
4494
 * Seeks an attribute with a local name of `name` and
4495
 * a namespace URI of `uri`.
4496
 *
4497
 * @param node  the element node
4498
 * @param uri  the uri
4499
 * @param name  the name of the attribute
4500
 * @returns the attribute or NULL if not present.
4501
 */
4502
static xmlAttrPtr
4503
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4504
0
{
4505
0
    xmlAttrPtr prop;
4506
4507
0
    if ((node == NULL) || (name == NULL))
4508
0
  return(NULL);
4509
0
    prop = node->properties;
4510
0
    while (prop != NULL) {
4511
0
  if ((prop->ns != NULL) &&
4512
0
      xmlStrEqual(prop->name, BAD_CAST name) &&
4513
0
      xmlStrEqual(prop->ns->href, BAD_CAST uri))
4514
0
      return(prop);
4515
0
  prop = prop->next;
4516
0
    }
4517
0
    return (NULL);
4518
0
}
4519
4520
static const xmlChar *
4521
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4522
0
{
4523
0
    xmlChar *val;
4524
0
    const xmlChar *ret;
4525
4526
0
    val = xmlNodeGetContent(node);
4527
0
    if (val == NULL)
4528
0
  val = xmlStrdup((xmlChar *)"");
4529
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4530
0
    xmlFree(val);
4531
0
    if (ret == NULL)
4532
0
        xmlSchemaPErrMemory(ctxt);
4533
0
    return(ret);
4534
0
}
4535
4536
static const xmlChar *
4537
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4538
0
{
4539
0
    return((const xmlChar*) xmlNodeGetContent(node));
4540
0
}
4541
4542
/**
4543
 * Read a attribute value and internalize the string
4544
 *
4545
 * @param ctxt  the parser context
4546
 * @param node  the node
4547
 * @param name  the property name
4548
 * @returns the string or NULL if not present.
4549
 */
4550
static const xmlChar *
4551
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4552
                 const char *name)
4553
0
{
4554
0
    xmlChar *val;
4555
0
    const xmlChar *ret;
4556
4557
0
    val = xmlGetNoNsProp(node, BAD_CAST name);
4558
0
    if (val == NULL)
4559
0
        return(NULL);
4560
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4561
0
    xmlFree(val);
4562
0
    return(ret);
4563
0
}
4564
4565
/************************************************************************
4566
 *                  *
4567
 *      Parsing functions       *
4568
 *                  *
4569
 ************************************************************************/
4570
4571
#define WXS_FIND_GLOBAL_ITEM(slot)      \
4572
0
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4573
0
  ret = xmlHashLookup(schema->slot, name); \
4574
0
  if (ret != NULL) goto exit; \
4575
0
    } \
4576
0
    if (xmlHashSize(schema->schemasImports) > 1) { \
4577
0
  xmlSchemaImportPtr import; \
4578
0
  if (nsName == NULL) \
4579
0
      import = xmlHashLookup(schema->schemasImports, \
4580
0
    XML_SCHEMAS_NO_NAMESPACE); \
4581
0
  else \
4582
0
      import = xmlHashLookup(schema->schemasImports, nsName); \
4583
0
  if (import == NULL) \
4584
0
      goto exit; \
4585
0
  ret = xmlHashLookup(import->schema->slot, name); \
4586
0
    }
4587
4588
/**
4589
 * Lookup a global element declaration in the schema.
4590
 *
4591
 * @param schema  the schema context
4592
 * @param name  the element name
4593
 * @param nsName  the element namespace
4594
 * @returns the element declaration or NULL if not found.
4595
 */
4596
static xmlSchemaElementPtr
4597
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4598
                 const xmlChar * nsName)
4599
0
{
4600
0
    xmlSchemaElementPtr ret = NULL;
4601
4602
0
    if ((name == NULL) || (schema == NULL))
4603
0
        return(NULL);
4604
0
    if (schema != NULL) {
4605
0
  WXS_FIND_GLOBAL_ITEM(elemDecl)
4606
0
    }
4607
0
exit:
4608
0
    return (ret);
4609
0
}
4610
4611
/**
4612
 * Lookup a type in the schemas or the predefined types
4613
 *
4614
 * @param schema  the main schema
4615
 * @param name  the type's name
4616
 * @param nsName  the type's namespace
4617
 * @returns the group definition or NULL if not found.
4618
 */
4619
static xmlSchemaTypePtr
4620
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4621
                 const xmlChar * nsName)
4622
0
{
4623
0
    xmlSchemaTypePtr ret = NULL;
4624
4625
0
    if (name == NULL)
4626
0
        return (NULL);
4627
    /* First try the built-in types. */
4628
0
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4629
0
  ret = xmlSchemaGetPredefinedType(name, nsName);
4630
0
  if (ret != NULL)
4631
0
      goto exit;
4632
  /*
4633
  * Note that we try the parsed schemas as well here
4634
  * since one might have parsed the S4S, which contain more
4635
  * than the built-in types.
4636
  * TODO: Can we optimize this?
4637
  */
4638
0
    }
4639
0
    if (schema != NULL) {
4640
0
  WXS_FIND_GLOBAL_ITEM(typeDecl)
4641
0
    }
4642
0
exit:
4643
4644
0
    return (ret);
4645
0
}
4646
4647
/**
4648
 * Lookup a an attribute in the schema or imported schemas
4649
 *
4650
 * @param schema  the context of the schema
4651
 * @param name  the name of the attribute
4652
 * @param nsName  the target namespace of the attribute
4653
 * @returns the attribute declaration or NULL if not found.
4654
 */
4655
static xmlSchemaAttributePtr
4656
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4657
                 const xmlChar * nsName)
4658
0
{
4659
0
    xmlSchemaAttributePtr ret = NULL;
4660
4661
0
    if ((name == NULL) || (schema == NULL))
4662
0
        return (NULL);
4663
0
    if (schema != NULL) {
4664
0
  WXS_FIND_GLOBAL_ITEM(attrDecl)
4665
0
    }
4666
0
exit:
4667
0
    return (ret);
4668
0
}
4669
4670
/**
4671
 * Lookup a an attribute group in the schema or imported schemas
4672
 *
4673
 * @param schema  the context of the schema
4674
 * @param name  the name of the attribute group
4675
 * @param nsName  the target namespace of the attribute group
4676
 * @returns the attribute group definition or NULL if not found.
4677
 */
4678
static xmlSchemaAttributeGroupPtr
4679
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4680
                 const xmlChar * nsName)
4681
0
{
4682
0
    xmlSchemaAttributeGroupPtr ret = NULL;
4683
4684
0
    if ((name == NULL) || (schema == NULL))
4685
0
        return (NULL);
4686
0
    if (schema != NULL) {
4687
0
  WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4688
0
    }
4689
0
exit:
4690
    /* TODO:
4691
    if ((ret != NULL) && (ret->redef != NULL)) {
4692
  * Return the last redefinition. *
4693
  ret = ret->redef;
4694
    }
4695
    */
4696
0
    return (ret);
4697
0
}
4698
4699
/**
4700
 * Lookup a group in the schema or imported schemas
4701
 *
4702
 * @param schema  the context of the schema
4703
 * @param name  the name of the group
4704
 * @param nsName  the target namespace of the group
4705
 * @returns the group definition or NULL if not found.
4706
 */
4707
static xmlSchemaModelGroupDefPtr
4708
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4709
                 const xmlChar * nsName)
4710
0
{
4711
0
    xmlSchemaModelGroupDefPtr ret = NULL;
4712
4713
0
    if ((name == NULL) || (schema == NULL))
4714
0
        return (NULL);
4715
0
    if (schema != NULL) {
4716
0
  WXS_FIND_GLOBAL_ITEM(groupDecl)
4717
0
    }
4718
0
exit:
4719
4720
0
    return (ret);
4721
0
}
4722
4723
static xmlSchemaNotationPtr
4724
xmlSchemaGetNotation(xmlSchemaPtr schema,
4725
         const xmlChar *name,
4726
         const xmlChar *nsName)
4727
0
{
4728
0
    xmlSchemaNotationPtr ret = NULL;
4729
4730
0
    if ((name == NULL) || (schema == NULL))
4731
0
        return (NULL);
4732
0
    if (schema != NULL) {
4733
0
  WXS_FIND_GLOBAL_ITEM(notaDecl)
4734
0
    }
4735
0
exit:
4736
0
    return (ret);
4737
0
}
4738
4739
static xmlSchemaIDCPtr
4740
xmlSchemaGetIDC(xmlSchemaPtr schema,
4741
    const xmlChar *name,
4742
    const xmlChar *nsName)
4743
0
{
4744
0
    xmlSchemaIDCPtr ret = NULL;
4745
4746
0
    if ((name == NULL) || (schema == NULL))
4747
0
        return (NULL);
4748
0
    if (schema != NULL) {
4749
0
  WXS_FIND_GLOBAL_ITEM(idcDef)
4750
0
    }
4751
0
exit:
4752
0
    return (ret);
4753
0
}
4754
4755
/**
4756
 * Lookup a group in the schema or imported schemas
4757
 *
4758
 * @param schema  the schema
4759
 * @param itemType  the item type
4760
 * @param name  the name of the group
4761
 * @param targetNs  the target namespace of the group
4762
 * @returns the group definition or NULL if not found.
4763
 */
4764
static xmlSchemaBasicItemPtr
4765
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4766
         xmlSchemaTypeType itemType,
4767
         const xmlChar *name,
4768
         const xmlChar *targetNs)
4769
0
{
4770
0
    switch (itemType) {
4771
0
  case XML_SCHEMA_TYPE_GROUP:
4772
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4773
0
    name, targetNs));
4774
0
  case XML_SCHEMA_TYPE_ELEMENT:
4775
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4776
0
    name, targetNs));
4777
0
  default:
4778
      /* TODO */
4779
0
      return (NULL);
4780
0
    }
4781
0
}
4782
4783
/************************************************************************
4784
 *                  *
4785
 *      Parsing functions       *
4786
 *                  *
4787
 ************************************************************************/
4788
4789
#define IS_BLANK_NODE(n)            \
4790
0
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4791
4792
/**
4793
 * Check if a string is ignorable
4794
 *
4795
 * @param str  a string
4796
 * @param len  the length of the string or -1
4797
 * @returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4798
 */
4799
static int
4800
xmlSchemaIsBlank(xmlChar * str, int len)
4801
0
{
4802
0
    if (str == NULL)
4803
0
        return (1);
4804
0
    if (len < 0) {
4805
0
  while (*str != 0) {
4806
0
      if (!(IS_BLANK_CH(*str)))
4807
0
    return (0);
4808
0
      str++;
4809
0
  }
4810
0
    } else while ((*str != 0) && (len != 0)) {
4811
0
  if (!(IS_BLANK_CH(*str)))
4812
0
      return (0);
4813
0
  str++;
4814
0
  len--;
4815
0
    }
4816
4817
0
    return (1);
4818
0
}
4819
4820
0
#define WXS_COMP_NAME(c, t) ((t) (c))->name
4821
0
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
4822
/*
4823
* xmlSchemaFindRedefCompInGraph:
4824
* ATTENTION TODO: This uses pointer comp. for strings.
4825
*/
4826
static xmlSchemaBasicItemPtr
4827
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
4828
            xmlSchemaTypeType type,
4829
            const xmlChar *name,
4830
            const xmlChar *nsName)
4831
0
{
4832
0
    xmlSchemaBasicItemPtr ret;
4833
0
    int i;
4834
4835
0
    if ((bucket == NULL) || (name == NULL))
4836
0
  return(NULL);
4837
0
    if ((bucket->globals == NULL) ||
4838
0
  (bucket->globals->nbItems == 0))
4839
0
  goto subschemas;
4840
    /*
4841
    * Search in global components.
4842
    */
4843
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
4844
0
  ret = bucket->globals->items[i];
4845
0
  if (ret->type == type) {
4846
0
      switch (type) {
4847
0
    case XML_SCHEMA_TYPE_COMPLEX:
4848
0
    case XML_SCHEMA_TYPE_SIMPLE:
4849
0
        if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
4850
0
      (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
4851
0
      nsName))
4852
0
        {
4853
0
      return(ret);
4854
0
        }
4855
0
        break;
4856
0
    case XML_SCHEMA_TYPE_GROUP:
4857
0
        if ((WXS_COMP_NAME(ret,
4858
0
          xmlSchemaModelGroupDefPtr) == name) &&
4859
0
      (WXS_COMP_TNS(ret,
4860
0
          xmlSchemaModelGroupDefPtr) == nsName))
4861
0
        {
4862
0
      return(ret);
4863
0
        }
4864
0
        break;
4865
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4866
0
        if ((WXS_COMP_NAME(ret,
4867
0
          xmlSchemaAttributeGroupPtr) == name) &&
4868
0
      (WXS_COMP_TNS(ret,
4869
0
          xmlSchemaAttributeGroupPtr) == nsName))
4870
0
        {
4871
0
      return(ret);
4872
0
        }
4873
0
        break;
4874
0
    default:
4875
        /* Should not be hit. */
4876
0
        return(NULL);
4877
0
      }
4878
0
  }
4879
0
    }
4880
0
subschemas:
4881
    /*
4882
    * Process imported/included schemas.
4883
    */
4884
0
    if (bucket->relations != NULL) {
4885
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
4886
4887
  /*
4888
  * TODO: Marking the bucket will not avoid multiple searches
4889
  * in the same schema, but avoids at least circularity.
4890
  */
4891
0
  bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
4892
0
  do {
4893
0
      if ((rel->bucket != NULL) &&
4894
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
4895
0
    ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
4896
0
        type, name, nsName);
4897
0
    if (ret != NULL)
4898
0
        return(ret);
4899
0
      }
4900
0
      rel = rel->next;
4901
0
  } while (rel != NULL);
4902
0
   bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
4903
0
    }
4904
0
    return(NULL);
4905
0
}
4906
4907
/**
4908
 * Add an XML schema annotation declaration
4909
 * *WARNING* this interface is highly subject to change
4910
 *
4911
 * @param ctxt  a schema parser context
4912
 * @param schema  the schema being built
4913
 * @param name  the item name
4914
 * @param nsName  the element namespace
4915
 * @param node  unused
4916
 * @returns the new structure or NULL in case of error
4917
 */
4918
static xmlSchemaNotationPtr
4919
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
4920
                     const xmlChar *name, const xmlChar *nsName,
4921
         xmlNodePtr node ATTRIBUTE_UNUSED)
4922
0
{
4923
0
    xmlSchemaNotationPtr ret = NULL;
4924
4925
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
4926
0
        return (NULL);
4927
4928
0
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
4929
0
    if (ret == NULL) {
4930
0
        xmlSchemaPErrMemory(ctxt);
4931
0
        return (NULL);
4932
0
    }
4933
0
    memset(ret, 0, sizeof(xmlSchemaNotation));
4934
0
    ret->type = XML_SCHEMA_TYPE_NOTATION;
4935
0
    ret->name = name;
4936
0
    ret->targetNamespace = nsName;
4937
    /* TODO: do we need the node to be set?
4938
    * ret->node = node;*/
4939
0
    WXS_ADD_GLOBAL(ctxt, ret);
4940
0
    return (ret);
4941
0
}
4942
4943
/**
4944
 * Add an XML schema Attribute declaration
4945
 * *WARNING* this interface is highly subject to change
4946
 *
4947
 * @param ctxt  a schema parser context
4948
 * @param schema  the schema being built
4949
 * @param name  the item name
4950
 * @param nsName  the item namespace
4951
 * @param node  the context node
4952
 * @param topLevel  whether this is a top-level element
4953
 * @returns the new structure or NULL in case of error
4954
 */
4955
static xmlSchemaAttributePtr
4956
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
4957
                      const xmlChar * name, const xmlChar * nsName,
4958
          xmlNodePtr node, int topLevel)
4959
0
{
4960
0
    xmlSchemaAttributePtr ret = NULL;
4961
4962
0
    if ((ctxt == NULL) || (schema == NULL))
4963
0
        return (NULL);
4964
4965
0
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
4966
0
    if (ret == NULL) {
4967
0
        xmlSchemaPErrMemory(ctxt);
4968
0
        return (NULL);
4969
0
    }
4970
0
    memset(ret, 0, sizeof(xmlSchemaAttribute));
4971
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
4972
0
    ret->node = node;
4973
0
    ret->name = name;
4974
0
    ret->targetNamespace = nsName;
4975
4976
0
    if (topLevel)
4977
0
  WXS_ADD_GLOBAL(ctxt, ret);
4978
0
    else
4979
0
  WXS_ADD_LOCAL(ctxt, ret);
4980
0
    WXS_ADD_PENDING(ctxt, ret);
4981
0
    return (ret);
4982
0
}
4983
4984
/**
4985
 * Add an XML schema Attribute declaration
4986
 * *WARNING* this interface is highly subject to change
4987
 *
4988
 * @param pctxt  a schema parser context
4989
 * @param node  the context node
4990
 * @returns the new structure or NULL in case of error
4991
 */
4992
static xmlSchemaAttributeUsePtr
4993
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
4994
       xmlNodePtr node)
4995
0
{
4996
0
    xmlSchemaAttributeUsePtr ret = NULL;
4997
4998
0
    if (pctxt == NULL)
4999
0
        return (NULL);
5000
5001
0
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5002
0
    if (ret == NULL) {
5003
0
        xmlSchemaPErrMemory(pctxt);
5004
0
        return (NULL);
5005
0
    }
5006
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5007
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5008
0
    ret->node = node;
5009
5010
0
    WXS_ADD_LOCAL(pctxt, ret);
5011
0
    return (ret);
5012
0
}
5013
5014
/*
5015
* xmlSchemaAddRedef:
5016
*
5017
* Adds a redefinition information. This is used at a later stage to:
5018
* resolve references to the redefined components and to check constraints.
5019
*/
5020
static xmlSchemaRedefPtr
5021
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5022
      xmlSchemaBucketPtr targetBucket,
5023
      void *item,
5024
      const xmlChar *refName,
5025
      const xmlChar *refTargetNs)
5026
0
{
5027
0
    xmlSchemaRedefPtr ret;
5028
5029
0
    ret = (xmlSchemaRedefPtr)
5030
0
  xmlMalloc(sizeof(xmlSchemaRedef));
5031
0
    if (ret == NULL) {
5032
0
  xmlSchemaPErrMemory(pctxt);
5033
0
  return (NULL);
5034
0
    }
5035
0
    memset(ret, 0, sizeof(xmlSchemaRedef));
5036
0
    ret->item = item;
5037
0
    ret->targetBucket = targetBucket;
5038
0
    ret->refName = refName;
5039
0
    ret->refTargetNs = refTargetNs;
5040
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5041
0
  WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5042
0
    else
5043
0
  WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5044
0
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5045
5046
0
    return (ret);
5047
0
}
5048
5049
/**
5050
 * Add an XML schema Attribute Group definition.
5051
 *
5052
 * @param pctxt  a schema parser context
5053
 * @param schema  the schema being built
5054
 * @param name  the item name
5055
 * @param nsName  the target namespace
5056
 * @param node  the corresponding node
5057
 * @returns the new structure or NULL in case of error
5058
 */
5059
static xmlSchemaAttributeGroupPtr
5060
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5061
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5062
         const xmlChar *name,
5063
         const xmlChar *nsName,
5064
         xmlNodePtr node)
5065
0
{
5066
0
    xmlSchemaAttributeGroupPtr ret = NULL;
5067
5068
0
    if ((pctxt == NULL) || (name == NULL))
5069
0
        return (NULL);
5070
5071
0
    ret = (xmlSchemaAttributeGroupPtr)
5072
0
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5073
0
    if (ret == NULL) {
5074
0
  xmlSchemaPErrMemory(pctxt);
5075
0
  return (NULL);
5076
0
    }
5077
0
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5078
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5079
0
    ret->name = name;
5080
0
    ret->targetNamespace = nsName;
5081
0
    ret->node = node;
5082
5083
    /* TODO: Remove the flag. */
5084
0
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5085
0
    if (pctxt->isRedefine) {
5086
0
  pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5087
0
      ret, name, nsName);
5088
0
  if (pctxt->redef == NULL) {
5089
0
      xmlFree(ret);
5090
0
      return(NULL);
5091
0
  }
5092
0
  pctxt->redefCounter = 0;
5093
0
    }
5094
0
    WXS_ADD_GLOBAL(pctxt, ret);
5095
0
    WXS_ADD_PENDING(pctxt, ret);
5096
0
    return (ret);
5097
0
}
5098
5099
/**
5100
 * Add an XML schema Element declaration
5101
 * *WARNING* this interface is highly subject to change
5102
 *
5103
 * @param ctxt  a schema parser context
5104
 * @param name  the type name
5105
 * @param nsName  the type namespace
5106
 * @param node  the context node
5107
 * @param topLevel  whether this is a top-level element
5108
 * @returns the new structure or NULL in case of error
5109
 */
5110
static xmlSchemaElementPtr
5111
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5112
                    const xmlChar * name, const xmlChar * nsName,
5113
        xmlNodePtr node, int topLevel)
5114
0
{
5115
0
    xmlSchemaElementPtr ret = NULL;
5116
5117
0
    if ((ctxt == NULL) || (name == NULL))
5118
0
        return (NULL);
5119
5120
0
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5121
0
    if (ret == NULL) {
5122
0
        xmlSchemaPErrMemory(ctxt);
5123
0
        return (NULL);
5124
0
    }
5125
0
    memset(ret, 0, sizeof(xmlSchemaElement));
5126
0
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5127
0
    ret->name = name;
5128
0
    ret->targetNamespace = nsName;
5129
0
    ret->node = node;
5130
5131
0
    if (topLevel)
5132
0
  WXS_ADD_GLOBAL(ctxt, ret);
5133
0
    else
5134
0
  WXS_ADD_LOCAL(ctxt, ret);
5135
0
    WXS_ADD_PENDING(ctxt, ret);
5136
0
    return (ret);
5137
0
}
5138
5139
/**
5140
 * Add an XML schema item
5141
 * *WARNING* this interface is highly subject to change
5142
 *
5143
 * @param ctxt  a schema parser context
5144
 * @param schema  the schema being built
5145
 * @param type  the type
5146
 * @param name  the item name
5147
 * @param nsName  the namespace
5148
 * @param node  the context node
5149
 * @param topLevel  whether this is a top-level element
5150
 * @returns the new structure or NULL in case of error
5151
 */
5152
static xmlSchemaTypePtr
5153
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5154
     xmlSchemaTypeType type,
5155
                 const xmlChar * name, const xmlChar * nsName,
5156
     xmlNodePtr node, int topLevel)
5157
0
{
5158
0
    xmlSchemaTypePtr ret = NULL;
5159
5160
0
    if ((ctxt == NULL) || (schema == NULL))
5161
0
        return (NULL);
5162
5163
0
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5164
0
    if (ret == NULL) {
5165
0
        xmlSchemaPErrMemory(ctxt);
5166
0
        return (NULL);
5167
0
    }
5168
0
    memset(ret, 0, sizeof(xmlSchemaType));
5169
0
    ret->type = type;
5170
0
    ret->name = name;
5171
0
    ret->targetNamespace = nsName;
5172
0
    ret->node = node;
5173
0
    if (topLevel) {
5174
0
  if (ctxt->isRedefine) {
5175
0
      ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5176
0
    ret, name, nsName);
5177
0
      if (ctxt->redef == NULL) {
5178
0
    xmlFree(ret);
5179
0
    return(NULL);
5180
0
      }
5181
0
      ctxt->redefCounter = 0;
5182
0
  }
5183
0
  WXS_ADD_GLOBAL(ctxt, ret);
5184
0
    } else
5185
0
  WXS_ADD_LOCAL(ctxt, ret);
5186
0
    WXS_ADD_PENDING(ctxt, ret);
5187
0
    return (ret);
5188
0
}
5189
5190
static xmlSchemaQNameRefPtr
5191
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5192
         xmlSchemaTypeType refType,
5193
         const xmlChar *refName,
5194
         const xmlChar *refNs)
5195
0
{
5196
0
    xmlSchemaQNameRefPtr ret;
5197
5198
0
    ret = (xmlSchemaQNameRefPtr)
5199
0
  xmlMalloc(sizeof(xmlSchemaQNameRef));
5200
0
    if (ret == NULL) {
5201
0
  xmlSchemaPErrMemory(pctxt);
5202
0
  return (NULL);
5203
0
    }
5204
0
    ret->node = NULL;
5205
0
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5206
0
    ret->name = refName;
5207
0
    ret->targetNamespace = refNs;
5208
0
    ret->item = NULL;
5209
0
    ret->itemType = refType;
5210
    /*
5211
    * Store the reference item in the schema.
5212
    */
5213
0
    WXS_ADD_LOCAL(pctxt, ret);
5214
0
    return (ret);
5215
0
}
5216
5217
static xmlSchemaAttributeUseProhibPtr
5218
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5219
0
{
5220
0
    xmlSchemaAttributeUseProhibPtr ret;
5221
5222
0
    ret = (xmlSchemaAttributeUseProhibPtr)
5223
0
  xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5224
0
    if (ret == NULL) {
5225
0
  xmlSchemaPErrMemory(pctxt);
5226
0
  return (NULL);
5227
0
    }
5228
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5229
0
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5230
0
    WXS_ADD_LOCAL(pctxt, ret);
5231
0
    return (ret);
5232
0
}
5233
5234
5235
/**
5236
 * Adds a schema model group
5237
 * *WARNING* this interface is highly subject to change
5238
 *
5239
 * @param ctxt  a schema parser context
5240
 * @param schema  the schema being built
5241
 * @param type  the "compositor" type of the model group
5242
 * @param node  the node in the schema doc
5243
 * @returns the new structure or NULL in case of error
5244
 */
5245
static xmlSchemaModelGroupPtr
5246
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5247
           xmlSchemaPtr schema,
5248
           xmlSchemaTypeType type,
5249
           xmlNodePtr node)
5250
0
{
5251
0
    xmlSchemaModelGroupPtr ret = NULL;
5252
5253
0
    if ((ctxt == NULL) || (schema == NULL))
5254
0
        return (NULL);
5255
5256
0
    ret = (xmlSchemaModelGroupPtr)
5257
0
  xmlMalloc(sizeof(xmlSchemaModelGroup));
5258
0
    if (ret == NULL) {
5259
0
  xmlSchemaPErrMemory(ctxt);
5260
0
  return (NULL);
5261
0
    }
5262
0
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5263
0
    ret->type = type;
5264
0
    ret->node = node;
5265
0
    WXS_ADD_LOCAL(ctxt, ret);
5266
0
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5267
0
  (type == XML_SCHEMA_TYPE_CHOICE))
5268
0
  WXS_ADD_PENDING(ctxt, ret);
5269
0
    return (ret);
5270
0
}
5271
5272
5273
/**
5274
 * Adds an XML schema particle component.
5275
 * *WARNING* this interface is highly subject to change
5276
 *
5277
 * @param ctxt  a schema parser context
5278
 * @param node  the corresponding node in the schema doc
5279
 * @param min  the minOccurs
5280
 * @param max  the maxOccurs
5281
 * @returns the new structure or NULL in case of error
5282
 */
5283
static xmlSchemaParticlePtr
5284
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5285
         xmlNodePtr node, int min, int max)
5286
0
{
5287
0
    xmlSchemaParticlePtr ret = NULL;
5288
0
    if (ctxt == NULL)
5289
0
        return (NULL);
5290
5291
0
    ret = (xmlSchemaParticlePtr)
5292
0
  xmlMalloc(sizeof(xmlSchemaParticle));
5293
0
    if (ret == NULL) {
5294
0
  xmlSchemaPErrMemory(ctxt);
5295
0
  return (NULL);
5296
0
    }
5297
0
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5298
0
    ret->annot = NULL;
5299
0
    ret->node = node;
5300
0
    ret->minOccurs = min;
5301
0
    ret->maxOccurs = max;
5302
0
    ret->next = NULL;
5303
0
    ret->children = NULL;
5304
5305
0
    WXS_ADD_LOCAL(ctxt, ret);
5306
    /*
5307
    * Note that addition to pending components will be done locally
5308
    * to the specific parsing function, since the most particles
5309
    * need not to be fixed up (i.e. the reference to be resolved).
5310
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5311
    */
5312
0
    return (ret);
5313
0
}
5314
5315
/**
5316
 * Add an XML schema Group definition
5317
 *
5318
 * @param ctxt  a schema validation context
5319
 * @param schema  the schema being built
5320
 * @param name  the group name
5321
 * @param nsName  the group namespace
5322
 * @param node  the context node
5323
 * @returns the new structure or NULL in case of error
5324
 */
5325
static xmlSchemaModelGroupDefPtr
5326
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5327
         xmlSchemaPtr schema,
5328
         const xmlChar *name,
5329
         const xmlChar *nsName,
5330
         xmlNodePtr node)
5331
0
{
5332
0
    xmlSchemaModelGroupDefPtr ret = NULL;
5333
5334
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5335
0
        return (NULL);
5336
5337
0
    ret = (xmlSchemaModelGroupDefPtr)
5338
0
  xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5339
0
    if (ret == NULL) {
5340
0
        xmlSchemaPErrMemory(ctxt);
5341
0
        return (NULL);
5342
0
    }
5343
0
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5344
0
    ret->name = name;
5345
0
    ret->type = XML_SCHEMA_TYPE_GROUP;
5346
0
    ret->node = node;
5347
0
    ret->targetNamespace = nsName;
5348
5349
0
    if (ctxt->isRedefine) {
5350
0
  ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5351
0
      ret, name, nsName);
5352
0
  if (ctxt->redef == NULL) {
5353
0
      xmlFree(ret);
5354
0
      return(NULL);
5355
0
  }
5356
0
  ctxt->redefCounter = 0;
5357
0
    }
5358
0
    WXS_ADD_GLOBAL(ctxt, ret);
5359
0
    WXS_ADD_PENDING(ctxt, ret);
5360
0
    return (ret);
5361
0
}
5362
5363
/**
5364
 * Creates a new wildcard namespace constraint.
5365
 *
5366
 * @param ctxt  a schema validation context
5367
 * @returns the new structure or NULL in case of error
5368
 */
5369
static xmlSchemaWildcardNsPtr
5370
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5371
0
{
5372
0
    xmlSchemaWildcardNsPtr ret;
5373
5374
0
    ret = (xmlSchemaWildcardNsPtr)
5375
0
  xmlMalloc(sizeof(xmlSchemaWildcardNs));
5376
0
    if (ret == NULL) {
5377
0
  xmlSchemaPErrMemory(ctxt);
5378
0
  return (NULL);
5379
0
    }
5380
0
    ret->value = NULL;
5381
0
    ret->next = NULL;
5382
0
    return (ret);
5383
0
}
5384
5385
static xmlSchemaIDCPtr
5386
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5387
                  const xmlChar *name, const xmlChar *nsName,
5388
      int category, xmlNodePtr node)
5389
0
{
5390
0
    xmlSchemaIDCPtr ret = NULL;
5391
5392
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5393
0
        return (NULL);
5394
5395
0
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5396
0
    if (ret == NULL) {
5397
0
        xmlSchemaPErrMemory(ctxt);
5398
0
        return (NULL);
5399
0
    }
5400
0
    memset(ret, 0, sizeof(xmlSchemaIDC));
5401
    /* The target namespace of the parent element declaration. */
5402
0
    ret->targetNamespace = nsName;
5403
0
    ret->name = name;
5404
0
    ret->type = category;
5405
0
    ret->node = node;
5406
5407
0
    WXS_ADD_GLOBAL(ctxt, ret);
5408
    /*
5409
    * Only keyrefs need to be fixup up.
5410
    */
5411
0
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5412
0
  WXS_ADD_PENDING(ctxt, ret);
5413
0
    return (ret);
5414
0
}
5415
5416
/**
5417
 * Adds a wildcard.
5418
 * It corresponds to a xsd:anyAttribute and xsd:any.
5419
 *
5420
 * @param ctxt  a schema validation context
5421
 * @param schema  a schema
5422
 * @param type  the type
5423
 * @param node  the context node
5424
 * @returns the new structure or NULL in case of error
5425
 */
5426
static xmlSchemaWildcardPtr
5427
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5428
         xmlSchemaTypeType type, xmlNodePtr node)
5429
0
{
5430
0
    xmlSchemaWildcardPtr ret = NULL;
5431
5432
0
    if ((ctxt == NULL) || (schema == NULL))
5433
0
        return (NULL);
5434
5435
0
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5436
0
    if (ret == NULL) {
5437
0
        xmlSchemaPErrMemory(ctxt);
5438
0
        return (NULL);
5439
0
    }
5440
0
    memset(ret, 0, sizeof(xmlSchemaWildcard));
5441
0
    ret->type = type;
5442
0
    ret->node = node;
5443
0
    WXS_ADD_LOCAL(ctxt, ret);
5444
0
    return (ret);
5445
0
}
5446
5447
static void
5448
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5449
0
{
5450
0
    if (group == NULL)
5451
0
  return;
5452
0
    if (group->members != NULL)
5453
0
  xmlSchemaItemListFree(group->members);
5454
0
    xmlFree(group);
5455
0
}
5456
5457
static void
5458
xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5459
0
{
5460
0
    xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5461
0
}
5462
5463
static xmlSchemaSubstGroupPtr
5464
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5465
           xmlSchemaElementPtr head)
5466
0
{
5467
0
    xmlSchemaSubstGroupPtr ret;
5468
5469
    /* Init subst group hash. */
5470
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5471
0
  WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5472
0
  if (WXS_SUBST_GROUPS(pctxt) == NULL)
5473
0
      return(NULL);
5474
0
    }
5475
    /* Create a new substitution group. */
5476
0
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5477
0
    if (ret == NULL) {
5478
0
  xmlSchemaPErrMemory(NULL);
5479
0
  return(NULL);
5480
0
    }
5481
0
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5482
0
    ret->head = head;
5483
    /* Create list of members. */
5484
0
    ret->members = xmlSchemaItemListCreate();
5485
0
    if (ret->members == NULL) {
5486
0
  xmlSchemaSubstGroupFree(ret);
5487
0
  return(NULL);
5488
0
    }
5489
    /* Add subst group to hash. */
5490
0
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5491
0
  head->name, head->targetNamespace, ret) != 0) {
5492
0
  PERROR_INT("xmlSchemaSubstGroupAdd",
5493
0
      "failed to add a new substitution container");
5494
0
  xmlSchemaSubstGroupFree(ret);
5495
0
  return(NULL);
5496
0
    }
5497
0
    return(ret);
5498
0
}
5499
5500
static xmlSchemaSubstGroupPtr
5501
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5502
           xmlSchemaElementPtr head)
5503
0
{
5504
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5505
0
  return(NULL);
5506
0
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5507
0
  head->name, head->targetNamespace));
5508
5509
0
}
5510
5511
/**
5512
 * Allocate a new annotation structure.
5513
 *
5514
 * @param pctxt  a schema parser context
5515
 * @param head  the head of the substitution group
5516
 * @param member  the new member of the substitution group
5517
 * @returns the newly allocated structure or NULL in case or error
5518
 */
5519
static int
5520
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5521
              xmlSchemaElementPtr head,
5522
              xmlSchemaElementPtr member)
5523
0
{
5524
0
    xmlSchemaSubstGroupPtr substGroup = NULL;
5525
5526
0
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5527
0
  return (-1);
5528
5529
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5530
0
    if (substGroup == NULL)
5531
0
  substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5532
0
    if (substGroup == NULL)
5533
0
  return(-1);
5534
0
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5535
0
  return(-1);
5536
0
    return(0);
5537
0
}
5538
5539
/************************************************************************
5540
 *                  *
5541
 *    Utilities for parsing         *
5542
 *                  *
5543
 ************************************************************************/
5544
5545
/**
5546
 * Extracts the local name and the URI of a QName value and validates it.
5547
 * This one is intended to be used on attribute values that
5548
 * should resolve to schema components.
5549
 *
5550
 * @param ctxt  a schema parser context
5551
 * @param schema  the schema context
5552
 * @param attr  the attribute node
5553
 * @param ownerItem  the parent as a schema object
5554
 * @param value  the QName value
5555
 * @param uri  the resulting namespace URI if found
5556
 * @param local  the resulting local part if found, the attribute value otherwise
5557
 * @returns 0, in case the QName is valid, a positive error code
5558
 * if not valid and -1 if an internal error occurs.
5559
 */
5560
static int
5561
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5562
               xmlSchemaPtr schema,
5563
               xmlSchemaBasicItemPtr ownerItem,
5564
               xmlAttrPtr attr,
5565
               const xmlChar *value,
5566
               const xmlChar **uri,
5567
               const xmlChar **local)
5568
0
{
5569
0
    const xmlChar *pref;
5570
0
    xmlNsPtr ns;
5571
0
    int len, ret;
5572
5573
0
    *uri = NULL;
5574
0
    *local = NULL;
5575
0
    ret = xmlValidateQName(value, 1);
5576
0
    if (ret > 0) {
5577
0
  xmlSchemaPSimpleTypeErr(ctxt,
5578
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5579
0
      ownerItem, (xmlNodePtr) attr,
5580
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5581
0
      NULL, value, NULL, NULL, NULL);
5582
0
  *local = value;
5583
0
  return (ctxt->err);
5584
0
    } else if (ret < 0)
5585
0
  return (-1);
5586
5587
0
    if (!strchr((char *) value, ':')) {
5588
0
  ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5589
0
  if (ns && ns->href && ns->href[0])
5590
0
      *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5591
0
  else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5592
      /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5593
      * parser context. */
5594
      /*
5595
      * This one takes care of included schemas with no
5596
      * target namespace.
5597
      */
5598
0
      *uri = ctxt->targetNamespace;
5599
0
  }
5600
0
  *local = xmlDictLookup(ctxt->dict, value, -1);
5601
0
  return (0);
5602
0
    }
5603
    /*
5604
    * At this point xmlSplitQName3 has to return a local name.
5605
    */
5606
0
    *local = xmlSplitQName3(value, &len);
5607
0
    *local = xmlDictLookup(ctxt->dict, *local, -1);
5608
0
    pref = xmlDictLookup(ctxt->dict, value, len);
5609
0
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5610
0
    if (ns == NULL) {
5611
0
  xmlSchemaPSimpleTypeErr(ctxt,
5612
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5613
0
      ownerItem, (xmlNodePtr) attr,
5614
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5615
0
      "The value '%s' of simple type 'xs:QName' has no "
5616
0
      "corresponding namespace declaration in scope", value, NULL);
5617
0
  return (ctxt->err);
5618
0
    } else {
5619
0
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5620
0
    }
5621
0
    return (0);
5622
0
}
5623
5624
/**
5625
 * Extracts and validates the QName of an attribute value.
5626
 * This one is intended to be used on attribute values that
5627
 * should resolve to schema components.
5628
 *
5629
 * @param ctxt  a schema parser context
5630
 * @param schema  the schema context
5631
 * @param ownerItem  the owner as a schema object
5632
 * @param attr  the attribute node
5633
 * @param uri  the resulting namespace URI if found
5634
 * @param local  the resulting local part if found, the attribute value otherwise
5635
 * @returns 0, in case the QName is valid, a positive error code
5636
 * if not valid and -1 if an internal error occurs.
5637
 */
5638
static int
5639
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5640
               xmlSchemaPtr schema,
5641
               xmlSchemaBasicItemPtr ownerItem,
5642
               xmlAttrPtr attr,
5643
               const xmlChar **uri,
5644
               const xmlChar **local)
5645
0
{
5646
0
    const xmlChar *value;
5647
5648
0
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5649
0
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5650
0
  ownerItem, attr, value, uri, local));
5651
0
}
5652
5653
/**
5654
 * Extracts and validates the QName of an attribute value.
5655
 *
5656
 * @param ctxt  a schema parser context
5657
 * @param schema  the schema context
5658
 * @param ownerItem  the owner as a schema object
5659
 * @param ownerElem  the parent node of the attribute
5660
 * @param name  the name of the attribute
5661
 * @param uri  the resulting namespace URI if found
5662
 * @param local  the resulting local part if found, the attribute value otherwise
5663
 * @returns 0, in case the QName is valid, a positive error code
5664
 * if not valid and -1 if an internal error occurs.
5665
 */
5666
static int
5667
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5668
           xmlSchemaPtr schema,
5669
           xmlSchemaBasicItemPtr ownerItem,
5670
           xmlNodePtr ownerElem,
5671
           const char *name,
5672
           const xmlChar **uri,
5673
           const xmlChar **local)
5674
0
{
5675
0
    xmlAttrPtr attr;
5676
5677
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
5678
0
    if (attr == NULL) {
5679
0
  *local = NULL;
5680
0
  *uri = NULL;
5681
0
  return (0);
5682
0
    }
5683
0
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5684
0
  ownerItem, attr, uri, local));
5685
0
}
5686
5687
/**
5688
 * Extracts and validates the ID of an attribute value.
5689
 *
5690
 * @param ctxt  a schema parser context
5691
 * @param attr  attribute node
5692
 * @returns 0, in case the ID is valid, a positive error code
5693
 * if not valid and -1 if an internal error occurs.
5694
 */
5695
static int
5696
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5697
0
{
5698
0
    int ret;
5699
0
    const xmlChar *value;
5700
5701
0
    if (attr == NULL)
5702
0
  return(0);
5703
0
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5704
0
    ret = xmlValidateNCName(value, 1);
5705
0
    if (ret == 0) {
5706
  /*
5707
  * NOTE: the IDness might have already be declared in the DTD
5708
  */
5709
0
  if (attr->atype != XML_ATTRIBUTE_ID) {
5710
0
      xmlChar *strip;
5711
0
            int res;
5712
5713
      /*
5714
      * TODO: Use xmlSchemaStrip here; it's not exported at this
5715
      * moment.
5716
      */
5717
0
      strip = xmlSchemaCollapseString(value);
5718
0
      if (strip != NULL) {
5719
0
    xmlFree((xmlChar *) value);
5720
0
    value = strip;
5721
0
      }
5722
0
      res = xmlAddIDSafe(attr, value);
5723
0
            if (res < 0) {
5724
0
                xmlSchemaPErrMemory(ctxt);
5725
0
      } else if (res == 0) {
5726
0
    ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5727
0
    xmlSchemaPSimpleTypeErr(ctxt,
5728
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5729
0
        NULL, (xmlNodePtr) attr,
5730
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5731
0
        NULL, NULL, "Duplicate value '%s' of simple "
5732
0
        "type 'xs:ID'", value, NULL);
5733
0
      }
5734
0
  }
5735
0
    } else if (ret > 0) {
5736
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5737
0
  xmlSchemaPSimpleTypeErr(ctxt,
5738
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5739
0
      NULL, (xmlNodePtr) attr,
5740
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5741
0
      NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
5742
0
      "not a valid 'xs:NCName'",
5743
0
      value, NULL);
5744
0
    }
5745
0
    if (value != NULL)
5746
0
  xmlFree((xmlChar *)value);
5747
5748
0
    return (ret);
5749
0
}
5750
5751
static int
5752
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5753
        xmlNodePtr ownerElem,
5754
        const xmlChar *name)
5755
0
{
5756
0
    xmlAttrPtr attr;
5757
5758
0
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5759
0
    if (attr == NULL)
5760
0
  return(0);
5761
0
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
5762
5763
0
}
5764
5765
/**
5766
 * Get the maxOccurs property
5767
 *
5768
 * @param ctxt  a schema validation context
5769
 * @param node  a subtree containing XML Schema information
5770
 * @param min  minimum
5771
 * @param max  maximum
5772
 * @param def  default
5773
 * @param expected  expected
5774
 * @returns the default if not found, or the value
5775
 */
5776
static int
5777
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5778
    int min, int max, int def, const char *expected)
5779
0
{
5780
0
    const xmlChar *val, *cur;
5781
0
    int ret = 0;
5782
0
    xmlAttrPtr attr;
5783
5784
0
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
5785
0
    if (attr == NULL)
5786
0
  return (def);
5787
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5788
0
    if (val == NULL)
5789
0
        return (def);
5790
5791
0
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
5792
0
  if (max != UNBOUNDED) {
5793
0
      xmlSchemaPSimpleTypeErr(ctxt,
5794
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5795
    /* XML_SCHEMAP_INVALID_MINOCCURS, */
5796
0
    NULL, (xmlNodePtr) attr, NULL, expected,
5797
0
    val, NULL, NULL, NULL);
5798
0
      return (def);
5799
0
  } else
5800
0
      return (UNBOUNDED);  /* encoding it with -1 might be another option */
5801
0
    }
5802
5803
0
    cur = val;
5804
0
    while (IS_BLANK_CH(*cur))
5805
0
        cur++;
5806
0
    if (*cur == 0) {
5807
0
        xmlSchemaPSimpleTypeErr(ctxt,
5808
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5809
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5810
0
      NULL, (xmlNodePtr) attr, NULL, expected,
5811
0
      val, NULL, NULL, NULL);
5812
0
  return (def);
5813
0
    }
5814
0
    while ((*cur >= '0') && (*cur <= '9')) {
5815
0
        if (ret > INT_MAX / 10) {
5816
0
            ret = INT_MAX;
5817
0
        } else {
5818
0
            int digit = *cur - '0';
5819
0
            ret *= 10;
5820
0
            if (ret > INT_MAX - digit)
5821
0
                ret = INT_MAX;
5822
0
            else
5823
0
                ret += digit;
5824
0
        }
5825
0
        cur++;
5826
0
    }
5827
0
    while (IS_BLANK_CH(*cur))
5828
0
        cur++;
5829
    /*
5830
    * TODO: Restrict the maximal value to Integer.
5831
    */
5832
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
5833
0
  xmlSchemaPSimpleTypeErr(ctxt,
5834
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5835
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5836
0
      NULL, (xmlNodePtr) attr, NULL, expected,
5837
0
      val, NULL, NULL, NULL);
5838
0
        return (def);
5839
0
    }
5840
0
    return (ret);
5841
0
}
5842
5843
/**
5844
 * Get the minOccurs property
5845
 *
5846
 * @param ctxt  a schema validation context
5847
 * @param node  a subtree containing XML Schema information
5848
 * @param min  minimum
5849
 * @param max  maximum
5850
 * @param def  default
5851
 * @param expected  expected
5852
 * @returns the default if not found, or the value
5853
 */
5854
static int
5855
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5856
    int min, int max, int def, const char *expected)
5857
0
{
5858
0
    const xmlChar *val, *cur;
5859
0
    int ret = 0;
5860
0
    xmlAttrPtr attr;
5861
5862
0
    attr = xmlSchemaGetPropNode(node, "minOccurs");
5863
0
    if (attr == NULL)
5864
0
  return (def);
5865
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5866
0
    if (val == NULL)
5867
0
  return (def);
5868
0
    cur = val;
5869
0
    while (IS_BLANK_CH(*cur))
5870
0
        cur++;
5871
0
    if (*cur == 0) {
5872
0
        xmlSchemaPSimpleTypeErr(ctxt,
5873
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5874
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5875
0
      NULL, (xmlNodePtr) attr, NULL, expected,
5876
0
      val, NULL, NULL, NULL);
5877
0
        return (def);
5878
0
    }
5879
0
    while ((*cur >= '0') && (*cur <= '9')) {
5880
0
        if (ret > INT_MAX / 10) {
5881
0
            ret = INT_MAX;
5882
0
        } else {
5883
0
            int digit = *cur - '0';
5884
0
            ret *= 10;
5885
0
            if (ret > INT_MAX - digit)
5886
0
                ret = INT_MAX;
5887
0
            else
5888
0
                ret += digit;
5889
0
        }
5890
0
        cur++;
5891
0
    }
5892
0
    while (IS_BLANK_CH(*cur))
5893
0
        cur++;
5894
    /*
5895
    * TODO: Restrict the maximal value to Integer.
5896
    */
5897
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
5898
0
  xmlSchemaPSimpleTypeErr(ctxt,
5899
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5900
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5901
0
      NULL, (xmlNodePtr) attr, NULL, expected,
5902
0
      val, NULL, NULL, NULL);
5903
0
        return (def);
5904
0
    }
5905
0
    return (ret);
5906
0
}
5907
5908
/**
5909
 * Converts a boolean string value into 1 or 0.
5910
 *
5911
 * @param ctxt  a schema validation context
5912
 * @param ownerItem  the owner as a schema item
5913
 * @param node  the node holding the value
5914
 * @returns 0 or 1.
5915
 */
5916
static int
5917
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
5918
         xmlSchemaBasicItemPtr ownerItem,
5919
         xmlNodePtr node)
5920
0
{
5921
0
    xmlChar *value = NULL;
5922
0
    int res = 0;
5923
5924
0
    value = xmlNodeGetContent(node);
5925
    /*
5926
    * 3.2.2.1 Lexical representation
5927
    * An instance of a datatype that is defined as `boolean`
5928
    * can have the following legal literals {true, false, 1, 0}.
5929
    */
5930
0
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
5931
0
        res = 1;
5932
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
5933
0
        res = 0;
5934
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
5935
0
  res = 1;
5936
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
5937
0
        res = 0;
5938
0
    else {
5939
0
        xmlSchemaPSimpleTypeErr(ctxt,
5940
0
      XML_SCHEMAP_INVALID_BOOLEAN,
5941
0
      ownerItem, node,
5942
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
5943
0
      NULL, BAD_CAST value,
5944
0
      NULL, NULL, NULL);
5945
0
    }
5946
0
    if (value != NULL)
5947
0
  xmlFree(value);
5948
0
    return (res);
5949
0
}
5950
5951
/**
5952
 * Evaluate if a boolean property is set
5953
 *
5954
 * @param ctxt  a schema validation context
5955
 * @param node  a subtree containing XML Schema information
5956
 * @param name  the attribute name
5957
 * @param def  the default value
5958
 * @returns the default if not found, 0 if found to be false,
5959
 * 1 if found to be true
5960
 */
5961
static int
5962
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
5963
      xmlNodePtr node,
5964
                  const char *name, int def)
5965
0
{
5966
0
    const xmlChar *val;
5967
5968
0
    val = xmlSchemaGetProp(ctxt, node, name);
5969
0
    if (val == NULL)
5970
0
        return (def);
5971
    /*
5972
    * 3.2.2.1 Lexical representation
5973
    * An instance of a datatype that is defined as `boolean`
5974
    * can have the following legal literals {true, false, 1, 0}.
5975
    */
5976
0
    if (xmlStrEqual(val, BAD_CAST "true"))
5977
0
        def = 1;
5978
0
    else if (xmlStrEqual(val, BAD_CAST "false"))
5979
0
        def = 0;
5980
0
    else if (xmlStrEqual(val, BAD_CAST "1"))
5981
0
  def = 1;
5982
0
    else if (xmlStrEqual(val, BAD_CAST "0"))
5983
0
        def = 0;
5984
0
    else {
5985
0
        xmlSchemaPSimpleTypeErr(ctxt,
5986
0
      XML_SCHEMAP_INVALID_BOOLEAN,
5987
0
      NULL,
5988
0
      (xmlNodePtr) xmlSchemaGetPropNode(node, name),
5989
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
5990
0
      NULL, val, NULL, NULL, NULL);
5991
0
    }
5992
0
    return (def);
5993
0
}
5994
5995
/************************************************************************
5996
 *                  *
5997
 *    Schema extraction from an Infoset     *
5998
 *                  *
5999
 ************************************************************************/
6000
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6001
                                                 ctxt, xmlSchemaPtr schema,
6002
                                                 xmlNodePtr node,
6003
             int topLevel);
6004
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6005
                                                  ctxt,
6006
                                                  xmlSchemaPtr schema,
6007
                                                  xmlNodePtr node,
6008
              int topLevel);
6009
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6010
                                                  ctxt,
6011
                                                  xmlSchemaPtr schema,
6012
                                                  xmlNodePtr node,
6013
              xmlSchemaTypeType parentType);
6014
static xmlSchemaBasicItemPtr
6015
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6016
           xmlSchemaPtr schema,
6017
           xmlNodePtr node,
6018
           xmlSchemaItemListPtr uses,
6019
           int parentType);
6020
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6021
                                           xmlSchemaPtr schema,
6022
                                           xmlNodePtr node);
6023
static xmlSchemaWildcardPtr
6024
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6025
                           xmlSchemaPtr schema, xmlNodePtr node);
6026
6027
/**
6028
 * Validates a value against the given built-in type.
6029
 * This one is intended to be used internally for validation
6030
 * of schema attribute values during parsing of the schema.
6031
 *
6032
 * @param pctxt  a schema parser context
6033
 * @param ownerItem  the schema object owner if existent
6034
 * @param attr  the schema attribute node being validated
6035
 * @param value  the value
6036
 * @param type  the built-in type to be validated against
6037
 * @returns 0 if the value is valid, a positive error code
6038
 * number otherwise and -1 in case of an internal or API error.
6039
 */
6040
static int
6041
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6042
         xmlSchemaBasicItemPtr ownerItem,
6043
         xmlAttrPtr attr,
6044
         const xmlChar *value,
6045
         xmlSchemaTypePtr type)
6046
0
{
6047
6048
0
    int ret = 0;
6049
6050
    /*
6051
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6052
    * one is really meant to be used internally, so better not.
6053
    */
6054
0
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6055
0
  return (-1);
6056
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6057
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6058
0
      "the given type is not a built-in type");
6059
0
  return (-1);
6060
0
    }
6061
0
    switch (type->builtInType) {
6062
0
  case XML_SCHEMAS_NCNAME:
6063
0
  case XML_SCHEMAS_QNAME:
6064
0
  case XML_SCHEMAS_ANYURI:
6065
0
  case XML_SCHEMAS_TOKEN:
6066
0
  case XML_SCHEMAS_LANGUAGE:
6067
0
      ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6068
0
    (xmlNodePtr) attr);
6069
0
      break;
6070
0
  default: {
6071
0
      PERROR_INT("xmlSchemaPValAttrNodeValue",
6072
0
    "validation using the given type is not supported while "
6073
0
    "parsing a schema");
6074
0
      return (-1);
6075
0
  }
6076
0
    }
6077
    /*
6078
    * TODO: Should we use the S4S error codes instead?
6079
    */
6080
0
    if (ret < 0) {
6081
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6082
0
      "failed to validate a schema attribute value");
6083
0
  return (-1);
6084
0
    } else if (ret > 0) {
6085
0
  if (WXS_IS_LIST(type))
6086
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6087
0
  else
6088
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6089
0
  xmlSchemaPSimpleTypeErr(pctxt,
6090
0
      ret, ownerItem, (xmlNodePtr) attr,
6091
0
      type, NULL, value, NULL, NULL, NULL);
6092
0
    }
6093
0
    return (ret);
6094
0
}
6095
6096
/**
6097
 * Extracts and validates a value against the given built-in type.
6098
 * This one is intended to be used internally for validation
6099
 * of schema attribute values during parsing of the schema.
6100
 *
6101
 * @param ctxt  a schema parser context
6102
 * @param ownerItem  the schema object owner if existent
6103
 * @param attr  the schema attribute node being validated
6104
 * @param type  the built-in type to be validated against
6105
 * @param value  the resulting value if any
6106
 * @returns 0 if the value is valid, a positive error code
6107
 * number otherwise and -1 in case of an internal or API error.
6108
 */
6109
static int
6110
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6111
         xmlSchemaBasicItemPtr ownerItem,
6112
         xmlAttrPtr attr,
6113
         xmlSchemaTypePtr type,
6114
         const xmlChar **value)
6115
0
{
6116
0
    const xmlChar *val;
6117
6118
0
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6119
0
  return (-1);
6120
6121
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6122
0
    if (value != NULL)
6123
0
  *value = val;
6124
6125
0
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6126
0
  val, type));
6127
0
}
6128
6129
/**
6130
 * Extracts and validates a value against the given built-in type.
6131
 * This one is intended to be used internally for validation
6132
 * of schema attribute values during parsing of the schema.
6133
 *
6134
 * @param ctxt  a schema parser context
6135
 * @param ownerItem  the schema object owner if existent
6136
 * @param ownerElem  the owner element node
6137
 * @param name  the name of the schema attribute node
6138
 * @param type  the built-in type to be validated against
6139
 * @param value  the resulting value if any
6140
 * @returns 0 if the value is valid, a positive error code
6141
 * number otherwise and -1 in case of an internal or API error.
6142
 */
6143
static int
6144
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6145
           xmlSchemaBasicItemPtr ownerItem,
6146
           xmlNodePtr ownerElem,
6147
           const char *name,
6148
           xmlSchemaTypePtr type,
6149
           const xmlChar **value)
6150
0
{
6151
0
    xmlAttrPtr attr;
6152
6153
0
    if ((ctxt == NULL) || (type == NULL)) {
6154
0
  if (value != NULL)
6155
0
      *value = NULL;
6156
0
  return (-1);
6157
0
    }
6158
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6159
0
  if (value != NULL)
6160
0
      *value = NULL;
6161
0
  xmlSchemaPErr(ctxt, ownerElem,
6162
0
      XML_SCHEMAP_INTERNAL,
6163
0
      "Internal error: xmlSchemaPValAttr, the given "
6164
0
      "type '%s' is not a built-in type.\n",
6165
0
      type->name, NULL);
6166
0
  return (-1);
6167
0
    }
6168
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
6169
0
    if (attr == NULL) {
6170
0
  if (value != NULL)
6171
0
      *value = NULL;
6172
0
  return (0);
6173
0
    }
6174
0
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6175
0
  type, value));
6176
0
}
6177
6178
static int
6179
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6180
      xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6181
      xmlNodePtr node,
6182
      xmlAttrPtr attr,
6183
      const xmlChar *namespaceName)
6184
0
{
6185
    /* TODO: Pointer comparison instead? */
6186
0
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6187
0
  return (0);
6188
0
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
6189
0
  return (0);
6190
    /*
6191
    * Check if the referenced namespace was <import>ed.
6192
    */
6193
0
    if (WXS_BUCKET(pctxt)->relations != NULL) {
6194
0
  xmlSchemaSchemaRelationPtr rel;
6195
6196
0
  rel = WXS_BUCKET(pctxt)->relations;
6197
0
  do {
6198
0
      if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6199
0
    xmlStrEqual(namespaceName, rel->importNamespace))
6200
0
    return (0);
6201
0
      rel = rel->next;
6202
0
  } while (rel != NULL);
6203
0
    }
6204
    /*
6205
    * No matching <import>ed namespace found.
6206
    */
6207
0
    {
6208
0
  xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6209
6210
0
  if (namespaceName == NULL)
6211
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6212
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6213
0
    "References from this schema to components in no "
6214
0
    "namespace are not allowed, since not indicated by an "
6215
0
    "import statement", NULL, NULL);
6216
0
  else
6217
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6218
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6219
0
    "References from this schema to components in the "
6220
0
    "namespace '%s' are not allowed, since not indicated by an "
6221
0
    "import statement", namespaceName, NULL);
6222
0
    }
6223
0
    return (XML_SCHEMAP_SRC_RESOLVE);
6224
0
}
6225
6226
/**
6227
 * Parses attribute uses and attribute declarations and
6228
 * attribute group references.
6229
 *
6230
 * @param ctxt  a schema validation context
6231
 * @param schema  the schema being built
6232
 * @param child  a subtree containing XML Schema information
6233
 * @param list  an item list
6234
 * @param parentType  the hosting type where the attributes will be anchored
6235
 * @param hasRefs  set if references were found
6236
 */
6237
static int
6238
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6239
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
6240
      int parentType, int *hasRefs)
6241
0
{
6242
0
    void *item;
6243
6244
0
    while ((IS_SCHEMA((*child), "attribute")) ||
6245
0
           (IS_SCHEMA((*child), "attributeGroup"))) {
6246
0
        if (IS_SCHEMA((*child), "attribute")) {
6247
0
      item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6248
0
    *list, parentType);
6249
0
        } else {
6250
0
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6251
0
      if ((item != NULL) && (hasRefs != NULL))
6252
0
    *hasRefs = 1;
6253
0
        }
6254
0
  if (item != NULL) {
6255
0
      if (*list == NULL) {
6256
    /* TODO: Customize grow factor. */
6257
0
    *list = xmlSchemaItemListCreate();
6258
0
    if (*list == NULL)
6259
0
        return(-1);
6260
0
      }
6261
0
      if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6262
0
    return(-1);
6263
0
  }
6264
0
        *child = (*child)->next;
6265
0
    }
6266
0
    return (0);
6267
0
}
6268
6269
/**
6270
 * parse a XML schema Attribute declaration
6271
 * *WARNING* this interface is highly subject to change
6272
 *
6273
 * @param ctxt  a schema validation context
6274
 * @param node  a subtree containing XML Schema information
6275
 * @param needed  needed
6276
 * @returns -1 in case of error, 0 if the declaration is improper and
6277
 *         1 in case of success.
6278
 */
6279
static xmlSchemaAnnotPtr
6280
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6281
0
{
6282
0
    xmlSchemaAnnotPtr ret;
6283
0
    xmlNodePtr child = NULL;
6284
0
    xmlAttrPtr attr;
6285
0
    int barked = 0;
6286
6287
    /*
6288
    * INFO: S4S completed.
6289
    */
6290
    /*
6291
    * id = ID
6292
    * {any attributes with non-schema namespace . . .}>
6293
    * Content: (appinfo | documentation)*
6294
    */
6295
0
    if ((ctxt == NULL) || (node == NULL))
6296
0
        return (NULL);
6297
0
    if (needed)
6298
0
  ret = xmlSchemaNewAnnot(ctxt, node);
6299
0
    else
6300
0
  ret = NULL;
6301
0
    attr = node->properties;
6302
0
    while (attr != NULL) {
6303
0
  if (((attr->ns == NULL) &&
6304
0
      (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6305
0
      ((attr->ns != NULL) &&
6306
0
      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6307
6308
0
      xmlSchemaPIllegalAttrErr(ctxt,
6309
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6310
0
  }
6311
0
  attr = attr->next;
6312
0
    }
6313
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6314
    /*
6315
    * And now for the children...
6316
    */
6317
0
    child = node->children;
6318
0
    while (child != NULL) {
6319
0
  if (IS_SCHEMA(child, "appinfo")) {
6320
      /* TODO: make available the content of "appinfo". */
6321
      /*
6322
      * source = anyURI
6323
      * {any attributes with non-schema namespace . . .}>
6324
      * Content: ({any})*
6325
      */
6326
0
      attr = child->properties;
6327
0
      while (attr != NULL) {
6328
0
    if (((attr->ns == NULL) &&
6329
0
         (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6330
0
         ((attr->ns != NULL) &&
6331
0
          xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6332
6333
0
        xmlSchemaPIllegalAttrErr(ctxt,
6334
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6335
0
    }
6336
0
    attr = attr->next;
6337
0
      }
6338
0
      xmlSchemaPValAttr(ctxt, NULL, child, "source",
6339
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6340
0
      child = child->next;
6341
0
  } else if (IS_SCHEMA(child, "documentation")) {
6342
      /* TODO: make available the content of "documentation". */
6343
      /*
6344
      * source = anyURI
6345
      * {any attributes with non-schema namespace . . .}>
6346
      * Content: ({any})*
6347
      */
6348
0
      attr = child->properties;
6349
0
      while (attr != NULL) {
6350
0
    if (attr->ns == NULL) {
6351
0
        if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6352
0
      xmlSchemaPIllegalAttrErr(ctxt,
6353
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6354
0
        }
6355
0
    } else {
6356
0
        if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6357
0
      (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6358
0
      (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6359
6360
0
      xmlSchemaPIllegalAttrErr(ctxt,
6361
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6362
0
        }
6363
0
    }
6364
0
    attr = attr->next;
6365
0
      }
6366
      /*
6367
      * Attribute "xml:lang".
6368
      */
6369
0
      attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6370
0
      if (attr != NULL)
6371
0
    xmlSchemaPValAttrNode(ctxt, NULL, attr,
6372
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6373
0
      child = child->next;
6374
0
  } else {
6375
0
      if (!barked)
6376
0
    xmlSchemaPContentErr(ctxt,
6377
0
        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6378
0
        NULL, node, child, NULL, "(appinfo | documentation)*");
6379
0
      barked = 1;
6380
0
      child = child->next;
6381
0
  }
6382
0
    }
6383
6384
0
    return (ret);
6385
0
}
6386
6387
/**
6388
 * parse a XML schema Facet declaration
6389
 * *WARNING* this interface is highly subject to change
6390
 *
6391
 * @param ctxt  a schema validation context
6392
 * @param schema  the schema being built
6393
 * @param node  a subtree containing XML Schema information
6394
 * @returns the new type structure or NULL in case of error
6395
 */
6396
static xmlSchemaFacetPtr
6397
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6398
                    xmlNodePtr node)
6399
0
{
6400
0
    xmlSchemaFacetPtr facet;
6401
0
    xmlNodePtr child = NULL;
6402
0
    const xmlChar *value;
6403
6404
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6405
0
        return (NULL);
6406
6407
0
    facet = xmlSchemaNewFacet();
6408
0
    if (facet == NULL) {
6409
0
        xmlSchemaPErrMemory(ctxt);
6410
0
        return (NULL);
6411
0
    }
6412
0
    facet->node = node;
6413
0
    value = xmlSchemaGetProp(ctxt, node, "value");
6414
0
    if (value == NULL) {
6415
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6416
0
                       "Facet %s has no value\n", node->name, NULL);
6417
0
        xmlSchemaFreeFacet(facet);
6418
0
        return (NULL);
6419
0
    }
6420
0
    if (IS_SCHEMA(node, "minInclusive")) {
6421
0
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6422
0
    } else if (IS_SCHEMA(node, "minExclusive")) {
6423
0
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6424
0
    } else if (IS_SCHEMA(node, "maxInclusive")) {
6425
0
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6426
0
    } else if (IS_SCHEMA(node, "maxExclusive")) {
6427
0
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6428
0
    } else if (IS_SCHEMA(node, "totalDigits")) {
6429
0
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6430
0
    } else if (IS_SCHEMA(node, "fractionDigits")) {
6431
0
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6432
0
    } else if (IS_SCHEMA(node, "pattern")) {
6433
0
        facet->type = XML_SCHEMA_FACET_PATTERN;
6434
0
    } else if (IS_SCHEMA(node, "enumeration")) {
6435
0
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
6436
0
    } else if (IS_SCHEMA(node, "whiteSpace")) {
6437
0
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
6438
0
    } else if (IS_SCHEMA(node, "length")) {
6439
0
        facet->type = XML_SCHEMA_FACET_LENGTH;
6440
0
    } else if (IS_SCHEMA(node, "maxLength")) {
6441
0
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6442
0
    } else if (IS_SCHEMA(node, "minLength")) {
6443
0
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
6444
0
    } else {
6445
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6446
0
                       "Unknown facet type %s\n", node->name, NULL);
6447
0
        xmlSchemaFreeFacet(facet);
6448
0
        return (NULL);
6449
0
    }
6450
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6451
0
    facet->value = value;
6452
0
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6453
0
  (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6454
0
  const xmlChar *fixed;
6455
6456
0
  fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6457
0
  if (fixed != NULL) {
6458
0
      if (xmlStrEqual(fixed, BAD_CAST "true"))
6459
0
    facet->fixed = 1;
6460
0
  }
6461
0
    }
6462
0
    child = node->children;
6463
6464
0
    if (IS_SCHEMA(child, "annotation")) {
6465
0
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6466
0
        child = child->next;
6467
0
    }
6468
0
    if (child != NULL) {
6469
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6470
0
                       "Facet %s has unexpected child content\n",
6471
0
                       node->name, NULL);
6472
0
    }
6473
0
    return (facet);
6474
0
}
6475
6476
/**
6477
 * Parses the attribute "processContents" and "namespace"
6478
 * of a xsd:anyAttribute and xsd:any.
6479
 * *WARNING* this interface is highly subject to change
6480
 *
6481
 * @param ctxt  a schema parser context
6482
 * @param schema  unused
6483
 * @param wildc  the wildcard, already created
6484
 * @param node  a subtree containing XML Schema information
6485
 * @returns 0 if everything goes fine, a positive error code
6486
 * if something is not valid and -1 if an internal error occurs.
6487
 */
6488
static int
6489
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6490
       xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6491
       xmlSchemaWildcardPtr wildc,
6492
       xmlNodePtr node)
6493
0
{
6494
0
    const xmlChar *pc, *ns, *dictnsItem;
6495
0
    int ret = 0;
6496
0
    xmlChar *nsItem;
6497
0
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6498
0
    xmlAttrPtr attr;
6499
6500
0
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
6501
0
    if ((pc == NULL)
6502
0
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6503
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6504
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6505
0
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6506
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6507
0
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
6508
0
    } else {
6509
0
        xmlSchemaPSimpleTypeErr(ctxt,
6510
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6511
0
      NULL, node,
6512
0
      NULL, "(strict | skip | lax)", pc,
6513
0
      NULL, NULL, NULL);
6514
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6515
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6516
0
    }
6517
    /*
6518
     * Build the namespace constraints.
6519
     */
6520
0
    attr = xmlSchemaGetPropNode(node, "namespace");
6521
0
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6522
0
    if (ns == NULL)
6523
0
        return (-1);
6524
0
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6525
0
  wildc->any = 1;
6526
0
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6527
0
  wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6528
0
  if (wildc->negNsSet == NULL) {
6529
0
      return (-1);
6530
0
  }
6531
0
  wildc->negNsSet->value = ctxt->targetNamespace;
6532
0
    } else {
6533
0
  const xmlChar *end, *cur;
6534
6535
0
  cur = ns;
6536
0
  do {
6537
0
      while (IS_BLANK_CH(*cur))
6538
0
    cur++;
6539
0
      end = cur;
6540
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6541
0
    end++;
6542
0
      if (end == cur)
6543
0
    break;
6544
0
      nsItem = xmlStrndup(cur, end - cur);
6545
0
      if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6546
0
        (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6547
0
    xmlSchemaPSimpleTypeErr(ctxt,
6548
0
        XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6549
0
        NULL, (xmlNodePtr) attr,
6550
0
        NULL,
6551
0
        "((##any | ##other) | List of (xs:anyURI | "
6552
0
        "(##targetNamespace | ##local)))",
6553
0
        nsItem, NULL, NULL, NULL);
6554
0
    ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6555
0
      } else {
6556
0
    if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6557
0
        dictnsItem = ctxt->targetNamespace;
6558
0
    } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6559
0
        dictnsItem = NULL;
6560
0
    } else {
6561
        /*
6562
        * Validate the item (anyURI).
6563
        */
6564
0
        xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6565
0
      nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6566
0
        dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6567
0
    }
6568
    /*
6569
    * Avoid duplicate namespaces.
6570
    */
6571
0
    tmp = wildc->nsSet;
6572
0
    while (tmp != NULL) {
6573
0
        if (dictnsItem == tmp->value)
6574
0
      break;
6575
0
        tmp = tmp->next;
6576
0
    }
6577
0
    if (tmp == NULL) {
6578
0
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6579
0
        if (tmp == NULL) {
6580
0
      xmlFree(nsItem);
6581
0
      return (-1);
6582
0
        }
6583
0
        tmp->value = dictnsItem;
6584
0
        tmp->next = NULL;
6585
0
        if (wildc->nsSet == NULL)
6586
0
      wildc->nsSet = tmp;
6587
0
        else if (lastNs != NULL)
6588
0
      lastNs->next = tmp;
6589
0
        lastNs = tmp;
6590
0
    }
6591
6592
0
      }
6593
0
      xmlFree(nsItem);
6594
0
      cur = end;
6595
0
  } while (*cur != 0);
6596
0
    }
6597
0
    return (ret);
6598
0
}
6599
6600
static int
6601
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6602
         xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6603
         xmlNodePtr node,
6604
         int minOccurs,
6605
0
         int maxOccurs) {
6606
6607
0
    if ((maxOccurs == 0) && ( minOccurs == 0))
6608
0
  return (0);
6609
0
    if (maxOccurs != UNBOUNDED) {
6610
  /*
6611
  * TODO: Maybe we should better not create the particle,
6612
  * if min/max is invalid, since it could confuse the build of the
6613
  * content model.
6614
  */
6615
  /*
6616
  * 3.9.6 Schema Component Constraint: Particle Correct
6617
  *
6618
  */
6619
0
  if (maxOccurs < 1) {
6620
      /*
6621
      * 2.2 {max occurs} must be greater than or equal to 1.
6622
      */
6623
0
      xmlSchemaPCustomAttrErr(ctxt,
6624
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6625
0
    NULL, NULL,
6626
0
    xmlSchemaGetPropNode(node, "maxOccurs"),
6627
0
    "The value must be greater than or equal to 1");
6628
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6629
0
  } else if (minOccurs > maxOccurs) {
6630
      /*
6631
      * 2.1 {min occurs} must not be greater than {max occurs}.
6632
      */
6633
0
      xmlSchemaPCustomAttrErr(ctxt,
6634
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6635
0
    NULL, NULL,
6636
0
    xmlSchemaGetPropNode(node, "minOccurs"),
6637
0
    "The value must not be greater than the value of 'maxOccurs'");
6638
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6639
0
  }
6640
0
    }
6641
0
    return (0);
6642
0
}
6643
6644
/**
6645
 * Parsea a XML schema `<any>` element. A particle and wildcard
6646
 * will be created (except if minOccurs==maxOccurs==0, in this case
6647
 * nothing will be created).
6648
 * *WARNING* this interface is highly subject to change
6649
 *
6650
 * @param ctxt  a schema validation context
6651
 * @param schema  the schema being built
6652
 * @param node  a subtree containing XML Schema information
6653
 * @returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6654
 */
6655
static xmlSchemaParticlePtr
6656
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6657
                  xmlNodePtr node)
6658
0
{
6659
0
    xmlSchemaParticlePtr particle;
6660
0
    xmlNodePtr child = NULL;
6661
0
    xmlSchemaWildcardPtr wild;
6662
0
    int min, max;
6663
0
    xmlAttrPtr attr;
6664
0
    xmlSchemaAnnotPtr annot = NULL;
6665
6666
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6667
0
        return (NULL);
6668
    /*
6669
    * Check for illegal attributes.
6670
    */
6671
0
    attr = node->properties;
6672
0
    while (attr != NULL) {
6673
0
  if (attr->ns == NULL) {
6674
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6675
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
6676
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
6677
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6678
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6679
0
    xmlSchemaPIllegalAttrErr(ctxt,
6680
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6681
0
      }
6682
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6683
0
      xmlSchemaPIllegalAttrErr(ctxt,
6684
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6685
0
  }
6686
0
  attr = attr->next;
6687
0
    }
6688
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6689
    /*
6690
    * minOccurs/maxOccurs.
6691
    */
6692
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
6693
0
  "(xs:nonNegativeInteger | unbounded)");
6694
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
6695
0
  "xs:nonNegativeInteger");
6696
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
6697
    /*
6698
    * Create & parse the wildcard.
6699
    */
6700
0
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6701
0
    if (wild == NULL)
6702
0
  return (NULL);
6703
0
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6704
    /*
6705
    * And now for the children...
6706
    */
6707
0
    child = node->children;
6708
0
    if (IS_SCHEMA(child, "annotation")) {
6709
0
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6710
0
        child = child->next;
6711
0
    }
6712
0
    if (child != NULL) {
6713
0
  xmlSchemaPContentErr(ctxt,
6714
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6715
0
      NULL, node, child,
6716
0
      NULL, "(annotation?)");
6717
0
    }
6718
    /*
6719
    * No component if minOccurs==maxOccurs==0.
6720
    */
6721
0
    if ((min == 0) && (max == 0)) {
6722
  /* Don't free the wildcard, since it's already on the list. */
6723
0
  return (NULL);
6724
0
    }
6725
    /*
6726
    * Create the particle.
6727
    */
6728
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
6729
0
    if (particle == NULL)
6730
0
        return (NULL);
6731
0
    particle->annot = annot;
6732
0
    particle->children = (xmlSchemaTreeItemPtr) wild;
6733
6734
0
    return (particle);
6735
0
}
6736
6737
/**
6738
 * parse a XML schema Notation declaration
6739
 *
6740
 * @param ctxt  a schema validation context
6741
 * @param schema  the schema being built
6742
 * @param node  a subtree containing XML Schema information
6743
 * @returns the new structure or NULL in case of error
6744
 */
6745
static xmlSchemaNotationPtr
6746
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6747
                       xmlNodePtr node)
6748
0
{
6749
0
    const xmlChar *name;
6750
0
    xmlSchemaNotationPtr ret;
6751
0
    xmlNodePtr child = NULL;
6752
6753
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6754
0
        return (NULL);
6755
0
    name = xmlSchemaGetProp(ctxt, node, "name");
6756
0
    if (name == NULL) {
6757
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6758
0
                       "Notation has no name\n", NULL, NULL);
6759
0
        return (NULL);
6760
0
    }
6761
0
    ret = xmlSchemaAddNotation(ctxt, schema, name,
6762
0
  ctxt->targetNamespace, node);
6763
0
    if (ret == NULL)
6764
0
        return (NULL);
6765
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6766
6767
0
    child = node->children;
6768
0
    if (IS_SCHEMA(child, "annotation")) {
6769
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6770
0
        child = child->next;
6771
0
    }
6772
0
    if (child != NULL) {
6773
0
  xmlSchemaPContentErr(ctxt,
6774
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6775
0
      NULL, node, child,
6776
0
      NULL, "(annotation?)");
6777
0
    }
6778
6779
0
    return (ret);
6780
0
}
6781
6782
/**
6783
 * parse a XML schema AnyAttribute declaration
6784
 * *WARNING* this interface is highly subject to change
6785
 *
6786
 * @param ctxt  a schema validation context
6787
 * @param schema  the schema being built
6788
 * @param node  a subtree containing XML Schema information
6789
 * @returns a wildcard or NULL.
6790
 */
6791
static xmlSchemaWildcardPtr
6792
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6793
                           xmlSchemaPtr schema, xmlNodePtr node)
6794
0
{
6795
0
    xmlSchemaWildcardPtr ret;
6796
0
    xmlNodePtr child = NULL;
6797
0
    xmlAttrPtr attr;
6798
6799
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6800
0
        return (NULL);
6801
6802
0
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
6803
0
  node);
6804
0
    if (ret == NULL) {
6805
0
        return (NULL);
6806
0
    }
6807
    /*
6808
    * Check for illegal attributes.
6809
    */
6810
0
    attr = node->properties;
6811
0
    while (attr != NULL) {
6812
0
  if (attr->ns == NULL) {
6813
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6814
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6815
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6816
0
    xmlSchemaPIllegalAttrErr(ctxt,
6817
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6818
0
      }
6819
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6820
0
      xmlSchemaPIllegalAttrErr(ctxt,
6821
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6822
0
  }
6823
0
  attr = attr->next;
6824
0
    }
6825
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6826
    /*
6827
    * Parse the namespace list.
6828
    */
6829
0
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
6830
0
  return (NULL);
6831
    /*
6832
    * And now for the children...
6833
    */
6834
0
    child = node->children;
6835
0
    if (IS_SCHEMA(child, "annotation")) {
6836
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6837
0
        child = child->next;
6838
0
    }
6839
0
    if (child != NULL) {
6840
0
  xmlSchemaPContentErr(ctxt,
6841
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6842
0
      NULL, node, child,
6843
0
      NULL, "(annotation?)");
6844
0
    }
6845
6846
0
    return (ret);
6847
0
}
6848
6849
6850
/**
6851
 * parse a XML schema Attribute declaration
6852
 * *WARNING* this interface is highly subject to change
6853
 *
6854
 * @param pctxt  a schema validation context
6855
 * @param schema  the schema being built
6856
 * @param node  a subtree containing XML Schema information
6857
 * @param uses  attribute uses list
6858
 * @param parentType  parent type
6859
 * @returns the attribute declaration.
6860
 */
6861
static xmlSchemaBasicItemPtr
6862
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6863
           xmlSchemaPtr schema,
6864
           xmlNodePtr node,
6865
           xmlSchemaItemListPtr uses,
6866
           int parentType)
6867
0
{
6868
0
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
6869
0
    xmlSchemaAttributeUsePtr use = NULL;
6870
0
    xmlNodePtr child = NULL;
6871
0
    xmlAttrPtr attr;
6872
0
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
6873
0
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
6874
0
    int nberrors, hasForm = 0, defValueType = 0;
6875
6876
0
#define WXS_ATTR_DEF_VAL_DEFAULT 1
6877
0
#define WXS_ATTR_DEF_VAL_FIXED 2
6878
6879
    /*
6880
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
6881
     */
6882
6883
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
6884
0
        return (NULL);
6885
0
    attr = xmlSchemaGetPropNode(node, "ref");
6886
0
    if (attr != NULL) {
6887
0
  if (xmlSchemaPValAttrNodeQName(pctxt, schema,
6888
0
      NULL, attr, &tmpNs, &tmpName) != 0) {
6889
0
      return (NULL);
6890
0
  }
6891
0
  if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
6892
0
      return(NULL);
6893
0
  isRef = 1;
6894
0
    }
6895
0
    nberrors = pctxt->nberrors;
6896
    /*
6897
    * Check for illegal attributes.
6898
    */
6899
0
    attr = node->properties;
6900
0
    while (attr != NULL) {
6901
0
  if (attr->ns == NULL) {
6902
0
      if (isRef) {
6903
0
    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
6904
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
6905
0
        goto attr_next;
6906
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
6907
0
        goto attr_next;
6908
0
    }
6909
0
      } else {
6910
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
6911
0
        goto attr_next;
6912
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
6913
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
6914
0
        goto attr_next;
6915
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
6916
0
        xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
6917
0
      attr, &tmpNs, &tmpName);
6918
0
        goto attr_next;
6919
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
6920
        /*
6921
        * Evaluate the target namespace
6922
        */
6923
0
        hasForm = 1;
6924
0
        attrValue = xmlSchemaGetNodeContent(pctxt,
6925
0
      (xmlNodePtr) attr);
6926
0
        if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
6927
0
      ns = pctxt->targetNamespace;
6928
0
        } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
6929
0
        {
6930
0
      xmlSchemaPSimpleTypeErr(pctxt,
6931
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6932
0
          NULL, (xmlNodePtr) attr,
6933
0
          NULL, "(qualified | unqualified)",
6934
0
          attrValue, NULL, NULL, NULL);
6935
0
        }
6936
0
        goto attr_next;
6937
0
    }
6938
0
      }
6939
0
      if (xmlStrEqual(attr->name, BAD_CAST "use")) {
6940
6941
0
    attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
6942
    /* TODO: Maybe we need to normalize the value beforehand. */
6943
0
    if (xmlStrEqual(attrValue, BAD_CAST "optional"))
6944
0
        occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
6945
0
    else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
6946
0
        occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
6947
0
    else if (xmlStrEqual(attrValue, BAD_CAST "required"))
6948
0
        occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
6949
0
    else {
6950
0
        xmlSchemaPSimpleTypeErr(pctxt,
6951
0
      XML_SCHEMAP_INVALID_ATTR_USE,
6952
0
      NULL, (xmlNodePtr) attr,
6953
0
      NULL, "(optional | prohibited | required)",
6954
0
      attrValue, NULL, NULL, NULL);
6955
0
    }
6956
0
    goto attr_next;
6957
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
6958
    /*
6959
    * 3.2.3 : 1
6960
    * default and fixed must not both be present.
6961
    */
6962
0
    if (defValue) {
6963
0
        xmlSchemaPMutualExclAttrErr(pctxt,
6964
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
6965
0
      NULL, attr, "default", "fixed");
6966
0
    } else {
6967
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
6968
0
        defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
6969
0
    }
6970
0
    goto attr_next;
6971
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
6972
    /*
6973
    * 3.2.3 : 1
6974
    * default and fixed must not both be present.
6975
    */
6976
0
    if (defValue) {
6977
0
        xmlSchemaPMutualExclAttrErr(pctxt,
6978
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
6979
0
      NULL, attr, "default", "fixed");
6980
0
    } else {
6981
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
6982
0
        defValueType = WXS_ATTR_DEF_VAL_FIXED;
6983
0
    }
6984
0
    goto attr_next;
6985
0
      }
6986
0
  } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
6987
0
      goto attr_next;
6988
6989
0
  xmlSchemaPIllegalAttrErr(pctxt,
6990
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6991
6992
0
attr_next:
6993
0
  attr = attr->next;
6994
0
    }
6995
    /*
6996
    * 3.2.3 : 2
6997
    * If default and use are both present, use must have
6998
    * the actual value optional.
6999
    */
7000
0
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7001
0
  (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7002
0
  xmlSchemaPSimpleTypeErr(pctxt,
7003
0
      XML_SCHEMAP_SRC_ATTRIBUTE_2,
7004
0
      NULL, node, NULL,
7005
0
      "(optional | prohibited | required)", NULL,
7006
0
      "The value of the attribute 'use' must be 'optional' "
7007
0
      "if the attribute 'default' is present",
7008
0
      NULL, NULL);
7009
0
    }
7010
    /*
7011
    * We want correct attributes.
7012
    */
7013
0
    if (nberrors != pctxt->nberrors)
7014
0
  return(NULL);
7015
0
    if (! isRef) {
7016
0
  xmlSchemaAttributePtr attrDecl;
7017
7018
  /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7019
0
  if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7020
0
      ns = pctxt->targetNamespace;
7021
  /*
7022
  * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7023
  * TODO: Move this to the component layer.
7024
  */
7025
0
  if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7026
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7027
0
    XML_SCHEMAP_NO_XSI,
7028
0
    node, NULL,
7029
0
    "The target namespace must not match '%s'",
7030
0
    xmlSchemaInstanceNs, NULL);
7031
0
  }
7032
0
  attr = xmlSchemaGetPropNode(node, "name");
7033
0
  if (attr == NULL) {
7034
0
      xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7035
0
    NULL, node, "name", NULL);
7036
0
      return (NULL);
7037
0
  }
7038
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7039
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7040
0
      return (NULL);
7041
0
  }
7042
  /*
7043
  * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7044
  * TODO: Move this to the component layer.
7045
  */
7046
0
  if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7047
0
      xmlSchemaPSimpleTypeErr(pctxt,
7048
0
    XML_SCHEMAP_NO_XMLNS,
7049
0
    NULL, (xmlNodePtr) attr,
7050
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7051
0
    "The value of the attribute must not match 'xmlns'",
7052
0
    NULL, NULL);
7053
0
      return (NULL);
7054
0
  }
7055
0
  if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7056
0
      goto check_children;
7057
  /*
7058
  * Create the attribute use component.
7059
  */
7060
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7061
0
  if (use == NULL)
7062
0
      return(NULL);
7063
0
  use->occurs = occurs;
7064
  /*
7065
  * Create the attribute declaration.
7066
  */
7067
0
  attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7068
0
  if (attrDecl == NULL)
7069
0
      return (NULL);
7070
0
  if (tmpName != NULL) {
7071
0
      attrDecl->typeName = tmpName;
7072
0
      attrDecl->typeNs = tmpNs;
7073
0
  }
7074
0
  use->attrDecl = attrDecl;
7075
  /*
7076
  * Value constraint.
7077
  */
7078
0
  if (defValue != NULL) {
7079
0
      attrDecl->defValue = defValue;
7080
0
      if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7081
0
    attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7082
0
  }
7083
0
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7084
0
  xmlSchemaQNameRefPtr ref;
7085
7086
  /*
7087
  * Create the attribute use component.
7088
  */
7089
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7090
0
  if (use == NULL)
7091
0
      return(NULL);
7092
  /*
7093
  * We need to resolve the reference at later stage.
7094
  */
7095
0
  WXS_ADD_PENDING(pctxt, use);
7096
0
  use->occurs = occurs;
7097
  /*
7098
  * Create a QName reference to the attribute declaration.
7099
  */
7100
0
  ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7101
0
      tmpName, tmpNs);
7102
0
  if (ref == NULL)
7103
0
      return(NULL);
7104
  /*
7105
  * Assign the reference. This will be substituted for the
7106
  * referenced attribute declaration when the QName is resolved.
7107
  */
7108
0
  use->attrDecl = WXS_ATTR_CAST ref;
7109
  /*
7110
  * Value constraint.
7111
  */
7112
0
  if (defValue != NULL)
7113
0
      use->defValue = defValue;
7114
0
  if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7115
0
      use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7116
0
    }
7117
7118
0
check_children:
7119
    /*
7120
    * And now for the children...
7121
    */
7122
0
    child = node->children;
7123
0
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7124
0
  xmlSchemaAttributeUseProhibPtr prohib;
7125
7126
0
  if (IS_SCHEMA(child, "annotation")) {
7127
0
      xmlSchemaParseAnnotation(pctxt, child, 0);
7128
0
      child = child->next;
7129
0
  }
7130
0
  if (child != NULL) {
7131
0
      xmlSchemaPContentErr(pctxt,
7132
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7133
0
    NULL, node, child, NULL,
7134
0
    "(annotation?)");
7135
0
  }
7136
  /*
7137
  * Check for pointlessness of attribute prohibitions.
7138
  */
7139
0
  if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7140
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7141
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7142
0
    node, NULL,
7143
0
    "Skipping attribute use prohibition, since it is "
7144
0
    "pointless inside an <attributeGroup>",
7145
0
    NULL, NULL, NULL);
7146
0
      return(NULL);
7147
0
  } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7148
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7149
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7150
0
    node, NULL,
7151
0
    "Skipping attribute use prohibition, since it is "
7152
0
    "pointless when extending a type",
7153
0
    NULL, NULL, NULL);
7154
0
      return(NULL);
7155
0
  }
7156
0
  if (! isRef) {
7157
0
      tmpName = name;
7158
0
      tmpNs = ns;
7159
0
  }
7160
  /*
7161
  * Check for duplicate attribute prohibitions.
7162
  */
7163
0
  if (uses) {
7164
0
      int i;
7165
7166
0
      for (i = 0; i < uses->nbItems; i++) {
7167
0
    use = uses->items[i];
7168
0
    if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7169
0
        (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7170
0
        (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7171
0
    {
7172
0
        xmlChar *str = NULL;
7173
7174
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7175
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7176
0
      node, NULL,
7177
0
      "Skipping duplicate attribute use prohibition '%s'",
7178
0
      xmlSchemaFormatQName(&str, tmpNs, tmpName),
7179
0
      NULL, NULL);
7180
0
        FREE_AND_NULL(str)
7181
0
        return(NULL);
7182
0
    }
7183
0
      }
7184
0
  }
7185
  /*
7186
  * Create the attribute prohibition helper component.
7187
  */
7188
0
  prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7189
0
  if (prohib == NULL)
7190
0
      return(NULL);
7191
0
  prohib->node = node;
7192
0
  prohib->name = tmpName;
7193
0
  prohib->targetNamespace = tmpNs;
7194
0
  if (isRef) {
7195
      /*
7196
      * We need at least to resolve to the attribute declaration.
7197
      */
7198
0
      WXS_ADD_PENDING(pctxt, prohib);
7199
0
  }
7200
0
  return(WXS_BASIC_CAST prohib);
7201
0
    } else {
7202
0
  if (IS_SCHEMA(child, "annotation")) {
7203
      /*
7204
      * TODO: Should this go into the attr decl?
7205
      */
7206
0
      use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7207
0
      child = child->next;
7208
0
  }
7209
0
  if (isRef) {
7210
0
      if (child != NULL) {
7211
0
    if (IS_SCHEMA(child, "simpleType"))
7212
        /*
7213
        * 3.2.3 : 3.2
7214
        * If ref is present, then all of <simpleType>,
7215
        * form and type must be absent.
7216
        */
7217
0
        xmlSchemaPContentErr(pctxt,
7218
0
      XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7219
0
      NULL, node, child, NULL,
7220
0
      "(annotation?)");
7221
0
    else
7222
0
        xmlSchemaPContentErr(pctxt,
7223
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7224
0
      NULL, node, child, NULL,
7225
0
      "(annotation?)");
7226
0
      }
7227
0
  } else {
7228
0
      if (IS_SCHEMA(child, "simpleType")) {
7229
0
    if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7230
        /*
7231
        * 3.2.3 : 4
7232
        * type and <simpleType> must not both be present.
7233
        */
7234
0
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7235
0
      NULL, node, child,
7236
0
      "The attribute 'type' and the <simpleType> child "
7237
0
      "are mutually exclusive", NULL);
7238
0
    } else
7239
0
        WXS_ATTRUSE_TYPEDEF(use) =
7240
0
      xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7241
0
    child = child->next;
7242
0
      }
7243
0
      if (child != NULL)
7244
0
    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7245
0
    NULL, node, child, NULL,
7246
0
    "(annotation?, simpleType?)");
7247
0
  }
7248
0
    }
7249
0
    return (WXS_BASIC_CAST use);
7250
0
}
7251
7252
7253
static xmlSchemaAttributePtr
7254
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7255
            xmlSchemaPtr schema,
7256
            xmlNodePtr node)
7257
0
{
7258
0
    const xmlChar *attrValue;
7259
0
    xmlSchemaAttributePtr ret;
7260
0
    xmlNodePtr child = NULL;
7261
0
    xmlAttrPtr attr;
7262
7263
    /*
7264
     * Note that the w3c spec assumes the schema to be validated with schema
7265
     * for schemas beforehand.
7266
     *
7267
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7268
     */
7269
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7270
0
        return (NULL);
7271
    /*
7272
    * 3.2.3 : 3.1
7273
    * One of ref or name must be present, but not both
7274
    */
7275
0
    attr = xmlSchemaGetPropNode(node, "name");
7276
0
    if (attr == NULL) {
7277
0
  xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7278
0
      NULL, node, "name", NULL);
7279
0
  return (NULL);
7280
0
    }
7281
0
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7282
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7283
0
  return (NULL);
7284
0
    }
7285
    /*
7286
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7287
    * TODO: Move this to the component layer.
7288
    */
7289
0
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7290
0
  xmlSchemaPSimpleTypeErr(pctxt,
7291
0
      XML_SCHEMAP_NO_XMLNS,
7292
0
      NULL, (xmlNodePtr) attr,
7293
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7294
0
      "The value of the attribute must not match 'xmlns'",
7295
0
      NULL, NULL);
7296
0
  return (NULL);
7297
0
    }
7298
    /*
7299
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7300
    * TODO: Move this to the component layer.
7301
    *       Or better leave it here and add it to the component layer
7302
    *       if we have a schema construction API.
7303
    */
7304
0
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7305
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
7306
0
      XML_SCHEMAP_NO_XSI, node, NULL,
7307
0
      "The target namespace must not match '%s'",
7308
0
      xmlSchemaInstanceNs, NULL);
7309
0
    }
7310
7311
0
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7312
0
  pctxt->targetNamespace, node, 1);
7313
0
    if (ret == NULL)
7314
0
  return (NULL);
7315
0
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7316
7317
    /*
7318
    * Check for illegal attributes.
7319
    */
7320
0
    attr = node->properties;
7321
0
    while (attr != NULL) {
7322
0
  if (attr->ns == NULL) {
7323
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7324
0
    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7325
0
    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7326
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7327
0
    (!xmlStrEqual(attr->name, BAD_CAST "type")))
7328
0
      {
7329
0
    xmlSchemaPIllegalAttrErr(pctxt,
7330
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7331
0
      }
7332
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7333
0
      xmlSchemaPIllegalAttrErr(pctxt,
7334
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7335
0
  }
7336
0
  attr = attr->next;
7337
0
    }
7338
0
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
7339
0
  node, "type", &ret->typeNs, &ret->typeName);
7340
7341
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7342
    /*
7343
    * Attribute "fixed".
7344
    */
7345
0
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7346
0
    if (ret->defValue != NULL)
7347
0
  ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7348
    /*
7349
    * Attribute "default".
7350
    */
7351
0
    attr = xmlSchemaGetPropNode(node, "default");
7352
0
    if (attr != NULL) {
7353
  /*
7354
  * 3.2.3 : 1
7355
  * default and fixed must not both be present.
7356
  */
7357
0
  if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7358
0
      xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7359
0
    WXS_BASIC_CAST ret, attr, "default", "fixed");
7360
0
  } else
7361
0
      ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7362
0
    }
7363
    /*
7364
    * And now for the children...
7365
    */
7366
0
    child = node->children;
7367
0
    if (IS_SCHEMA(child, "annotation")) {
7368
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7369
0
        child = child->next;
7370
0
    }
7371
0
    if (IS_SCHEMA(child, "simpleType")) {
7372
0
  if (ret->typeName != NULL) {
7373
      /*
7374
      * 3.2.3 : 4
7375
      * type and <simpleType> must not both be present.
7376
      */
7377
0
      xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7378
0
    NULL, node, child,
7379
0
    "The attribute 'type' and the <simpleType> child "
7380
0
    "are mutually exclusive", NULL);
7381
0
  } else
7382
0
      ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7383
0
  child = child->next;
7384
0
    }
7385
0
    if (child != NULL)
7386
0
  xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7387
0
      NULL, node, child, NULL,
7388
0
      "(annotation?, simpleType?)");
7389
7390
0
    return (ret);
7391
0
}
7392
7393
/**
7394
 * Parse an attribute group definition reference.
7395
 * Note that a reference to an attribute group does not
7396
 * correspond to any component at all.
7397
 * *WARNING* this interface is highly subject to change
7398
 *
7399
 * @param pctxt  a schema validation context
7400
 * @param schema  the schema being built
7401
 * @param node  a subtree containing XML Schema information
7402
 * @returns the attribute group or NULL in case of error.
7403
 */
7404
static xmlSchemaQNameRefPtr
7405
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7406
        xmlSchemaPtr schema,
7407
        xmlNodePtr node)
7408
0
{
7409
0
    xmlSchemaQNameRefPtr ret;
7410
0
    xmlNodePtr child = NULL;
7411
0
    xmlAttrPtr attr;
7412
0
    const xmlChar *refNs = NULL, *ref = NULL;
7413
7414
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7415
0
        return (NULL);
7416
7417
0
    attr = xmlSchemaGetPropNode(node, "ref");
7418
0
    if (attr == NULL) {
7419
0
  xmlSchemaPMissingAttrErr(pctxt,
7420
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7421
0
      NULL, node, "ref", NULL);
7422
0
  return (NULL);
7423
0
    }
7424
0
    xmlSchemaPValAttrNodeQName(pctxt, schema,
7425
0
  NULL, attr, &refNs, &ref);
7426
0
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7427
0
  return(NULL);
7428
7429
    /*
7430
    * Check for illegal attributes.
7431
    */
7432
0
    attr = node->properties;
7433
0
    while (attr != NULL) {
7434
0
  if (attr->ns == NULL) {
7435
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7436
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7437
0
      {
7438
0
    xmlSchemaPIllegalAttrErr(pctxt,
7439
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7440
0
      }
7441
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7442
0
      xmlSchemaPIllegalAttrErr(pctxt,
7443
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7444
0
  }
7445
0
  attr = attr->next;
7446
0
    }
7447
    /* Attribute ID */
7448
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7449
7450
    /*
7451
    * And now for the children...
7452
    */
7453
0
    child = node->children;
7454
0
    if (IS_SCHEMA(child, "annotation")) {
7455
  /*
7456
  * TODO: We do not have a place to store the annotation, do we?
7457
  */
7458
0
        xmlSchemaParseAnnotation(pctxt, child, 0);
7459
0
        child = child->next;
7460
0
    }
7461
0
    if (child != NULL) {
7462
0
  xmlSchemaPContentErr(pctxt,
7463
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7464
0
      NULL, node, child, NULL,
7465
0
      "(annotation?)");
7466
0
    }
7467
7468
    /*
7469
    * Handle attribute group redefinitions.
7470
    */
7471
0
    if (pctxt->isRedefine && pctxt->redef &&
7472
0
  (pctxt->redef->item->type ==
7473
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7474
0
  (ref == pctxt->redef->refName) &&
7475
0
  (refNs == pctxt->redef->refTargetNs))
7476
0
    {
7477
  /*
7478
  * SPEC src-redefine:
7479
  * (7.1) "If it has an <attributeGroup> among its contents
7480
  * the `actual value` of whose ref [attribute] is the same
7481
  * as the `actual value` of its own name attribute plus
7482
  * target namespace, then it must have exactly one such group."
7483
  */
7484
0
  if (pctxt->redefCounter != 0) {
7485
0
      xmlChar *str = NULL;
7486
7487
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7488
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7489
0
    "The redefining attribute group definition "
7490
0
    "'%s' must not contain more than one "
7491
0
    "reference to the redefined definition",
7492
0
    xmlSchemaFormatQName(&str, refNs, ref), NULL);
7493
0
      FREE_AND_NULL(str);
7494
0
      return(NULL);
7495
0
  }
7496
0
  pctxt->redefCounter++;
7497
  /*
7498
  * URGENT TODO: How to ensure that the reference will not be
7499
  * handled by the normal component resolution mechanism?
7500
  */
7501
0
  ret = xmlSchemaNewQNameRef(pctxt,
7502
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7503
0
  if (ret == NULL)
7504
0
      return(NULL);
7505
0
  ret->node = node;
7506
0
  pctxt->redef->reference = WXS_BASIC_CAST ret;
7507
0
    } else {
7508
  /*
7509
  * Create a QName-reference helper component. We will substitute this
7510
  * component for the attribute uses of the referenced attribute group
7511
  * definition.
7512
  */
7513
0
  ret = xmlSchemaNewQNameRef(pctxt,
7514
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7515
0
  if (ret == NULL)
7516
0
      return(NULL);
7517
0
  ret->node = node;
7518
  /* Add to pending items, to be able to resolve the reference. */
7519
0
  WXS_ADD_PENDING(pctxt, ret);
7520
0
    }
7521
0
    return (ret);
7522
0
}
7523
7524
/**
7525
 * parse a XML schema Attribute Group declaration
7526
 * *WARNING* this interface is highly subject to change
7527
 *
7528
 * @param pctxt  a schema validation context
7529
 * @param schema  the schema being built
7530
 * @param node  a subtree containing XML Schema information
7531
 * @returns the attribute group definition or NULL in case of error.
7532
 */
7533
static xmlSchemaAttributeGroupPtr
7534
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7535
               xmlSchemaPtr schema,
7536
               xmlNodePtr node)
7537
0
{
7538
0
    const xmlChar *name;
7539
0
    xmlSchemaAttributeGroupPtr ret;
7540
0
    xmlNodePtr child = NULL;
7541
0
    xmlAttrPtr attr;
7542
0
    int hasRefs = 0;
7543
0
    int res;
7544
7545
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7546
0
        return (NULL);
7547
7548
0
    attr = xmlSchemaGetPropNode(node, "name");
7549
0
    if (attr == NULL) {
7550
0
  xmlSchemaPMissingAttrErr(pctxt,
7551
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7552
0
      NULL, node, "name", NULL);
7553
0
  return (NULL);
7554
0
    }
7555
    /*
7556
    * The name is crucial, exit if invalid.
7557
    */
7558
0
    if (xmlSchemaPValAttrNode(pctxt,
7559
0
  NULL, attr,
7560
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7561
0
  return (NULL);
7562
0
    }
7563
0
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7564
0
  name, pctxt->targetNamespace, node);
7565
0
    if (ret == NULL)
7566
0
  return (NULL);
7567
    /*
7568
    * Check for illegal attributes.
7569
    */
7570
0
    attr = node->properties;
7571
0
    while (attr != NULL) {
7572
0
  if (attr->ns == NULL) {
7573
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7574
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7575
0
      {
7576
0
    xmlSchemaPIllegalAttrErr(pctxt,
7577
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7578
0
      }
7579
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7580
0
      xmlSchemaPIllegalAttrErr(pctxt,
7581
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7582
0
  }
7583
0
  attr = attr->next;
7584
0
    }
7585
    /* Attribute ID */
7586
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7587
    /*
7588
    * And now for the children...
7589
    */
7590
0
    child = node->children;
7591
0
    if (IS_SCHEMA(child, "annotation")) {
7592
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7593
0
        child = child->next;
7594
0
    }
7595
    /*
7596
    * Parse contained attribute decls/refs.
7597
    */
7598
0
    res = xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7599
0
  (xmlSchemaItemListPtr *) &(ret->attrUses),
7600
0
  XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs);
7601
0
    if (hasRefs)
7602
0
  ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7603
0
    if (res == -1)
7604
0
  return(NULL);
7605
    /*
7606
    * Parse the attribute wildcard.
7607
    */
7608
0
    if (IS_SCHEMA(child, "anyAttribute")) {
7609
0
  ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7610
0
      schema, child);
7611
0
  child = child->next;
7612
0
    }
7613
0
    if (child != NULL) {
7614
0
  xmlSchemaPContentErr(pctxt,
7615
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7616
0
      NULL, node, child, NULL,
7617
0
      "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7618
0
    }
7619
0
    return (ret);
7620
0
}
7621
7622
/**
7623
 * @param value  the value
7624
 * @param flags  the flags to be modified
7625
 * @param flagQualified  the specific flag for "qualified"
7626
 * @returns 0 if the value is valid, 1 otherwise.
7627
 */
7628
static int
7629
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7630
           int *flags,
7631
           int flagQualified)
7632
0
{
7633
0
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
7634
0
  if  ((*flags & flagQualified) == 0)
7635
0
      *flags |= flagQualified;
7636
0
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7637
0
  return (1);
7638
7639
0
    return (0);
7640
0
}
7641
7642
/**
7643
 * Validates the value of the attribute "final" and "block". The value
7644
 * is converted into the specified flag values and returned in `flags`.
7645
 *
7646
 * @param value  the value
7647
 * @param flags  the flags to be modified
7648
 * @param flagAll  the specific flag for "\#all"
7649
 * @param flagExtension  the specific flag for "extension"
7650
 * @param flagRestriction  the specific flag for "restriction"
7651
 * @param flagSubstitution  the specific flag for "substitution"
7652
 * @param flagList  the specific flag for "list"
7653
 * @param flagUnion  the specific flag for "union"
7654
 * @returns 0 if the value is valid, 1 otherwise.
7655
 */
7656
7657
static int
7658
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7659
          int *flags,
7660
          int flagAll,
7661
          int flagExtension,
7662
          int flagRestriction,
7663
          int flagSubstitution,
7664
          int flagList,
7665
          int flagUnion)
7666
0
{
7667
0
    int ret = 0;
7668
7669
    /*
7670
    * TODO: This does not check for duplicate entries.
7671
    */
7672
0
    if ((flags == NULL) || (value == NULL))
7673
0
  return (-1);
7674
0
    if (value[0] == 0)
7675
0
  return (0);
7676
0
    if (xmlStrEqual(value, BAD_CAST "#all")) {
7677
0
  if (flagAll != -1)
7678
0
      *flags |= flagAll;
7679
0
  else {
7680
0
      if (flagExtension != -1)
7681
0
    *flags |= flagExtension;
7682
0
      if (flagRestriction != -1)
7683
0
    *flags |= flagRestriction;
7684
0
      if (flagSubstitution != -1)
7685
0
    *flags |= flagSubstitution;
7686
0
      if (flagList != -1)
7687
0
    *flags |= flagList;
7688
0
      if (flagUnion != -1)
7689
0
    *flags |= flagUnion;
7690
0
  }
7691
0
    } else {
7692
0
  const xmlChar *end, *cur = value;
7693
0
  xmlChar *item;
7694
7695
0
  do {
7696
0
      while (IS_BLANK_CH(*cur))
7697
0
    cur++;
7698
0
      end = cur;
7699
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
7700
0
    end++;
7701
0
      if (end == cur)
7702
0
    break;
7703
0
      item = xmlStrndup(cur, end - cur);
7704
0
      if (xmlStrEqual(item, BAD_CAST "extension")) {
7705
0
    if (flagExtension != -1) {
7706
0
        if ((*flags & flagExtension) == 0)
7707
0
      *flags |= flagExtension;
7708
0
    } else
7709
0
        ret = 1;
7710
0
      } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
7711
0
    if (flagRestriction != -1) {
7712
0
        if ((*flags & flagRestriction) == 0)
7713
0
      *flags |= flagRestriction;
7714
0
    } else
7715
0
        ret = 1;
7716
0
      } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
7717
0
    if (flagSubstitution != -1) {
7718
0
        if ((*flags & flagSubstitution) == 0)
7719
0
      *flags |= flagSubstitution;
7720
0
    } else
7721
0
        ret = 1;
7722
0
      } else if (xmlStrEqual(item, BAD_CAST "list")) {
7723
0
    if (flagList != -1) {
7724
0
        if ((*flags & flagList) == 0)
7725
0
      *flags |= flagList;
7726
0
    } else
7727
0
        ret = 1;
7728
0
      } else if (xmlStrEqual(item, BAD_CAST "union")) {
7729
0
    if (flagUnion != -1) {
7730
0
        if ((*flags & flagUnion) == 0)
7731
0
      *flags |= flagUnion;
7732
0
    } else
7733
0
        ret = 1;
7734
0
      } else
7735
0
    ret = 1;
7736
0
      if (item != NULL)
7737
0
    xmlFree(item);
7738
0
      cur = end;
7739
0
  } while ((ret == 0) && (*cur != 0));
7740
0
    }
7741
7742
0
    return (ret);
7743
0
}
7744
7745
static int
7746
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7747
           xmlSchemaIDCPtr idc,
7748
           xmlSchemaIDCSelectPtr selector,
7749
           xmlAttrPtr attr,
7750
           int isField)
7751
0
{
7752
0
    xmlNodePtr node;
7753
7754
    /*
7755
    * c-selector-xpath:
7756
    * Schema Component Constraint: Selector Value OK
7757
    *
7758
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
7759
    * in [XPath].
7760
    */
7761
0
    if (selector == NULL) {
7762
0
  xmlSchemaPErr(ctxt, idc->node,
7763
0
      XML_SCHEMAP_INTERNAL,
7764
0
      "Internal error: xmlSchemaCheckCSelectorXPath, "
7765
0
      "the selector is not specified.\n", NULL, NULL);
7766
0
  return (-1);
7767
0
    }
7768
0
    if (attr == NULL)
7769
0
  node = idc->node;
7770
0
    else
7771
0
  node = (xmlNodePtr) attr;
7772
0
    if (selector->xpath == NULL) {
7773
0
  xmlSchemaPCustomErr(ctxt,
7774
      /* TODO: Adjust error code. */
7775
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7776
0
      NULL, node,
7777
0
      "The XPath expression of the selector is not valid", NULL);
7778
0
  return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
7779
0
    } else {
7780
0
  const xmlChar **nsArray = NULL;
7781
0
  xmlNsPtr *nsList = NULL;
7782
  /*
7783
  * Compile the XPath expression.
7784
  */
7785
  /*
7786
  * TODO: We need the array of in-scope namespaces for compilation.
7787
  * TODO: Call xmlPatterncompile with different options for selector/
7788
  * field.
7789
  */
7790
0
  if (attr == NULL)
7791
0
      nsList = NULL;
7792
0
  else
7793
0
      nsList = xmlGetNsList(attr->doc, attr->parent);
7794
  /*
7795
  * Build an array of prefixes and namespaces.
7796
  */
7797
0
  if (nsList != NULL) {
7798
0
      int i, count = 0;
7799
7800
0
      for (i = 0; nsList[i] != NULL; i++)
7801
0
    count++;
7802
7803
0
      nsArray = (const xmlChar **) xmlMalloc(
7804
0
    (count * 2 + 1) * sizeof(const xmlChar *));
7805
0
      if (nsArray == NULL) {
7806
0
    xmlSchemaPErrMemory(ctxt);
7807
0
    xmlFree(nsList);
7808
0
    return (-1);
7809
0
      }
7810
0
      for (i = 0; i < count; i++) {
7811
0
    nsArray[2 * i] = nsList[i]->href;
7812
0
    nsArray[2 * i + 1] = nsList[i]->prefix;
7813
0
      }
7814
0
      nsArray[count * 2] = NULL;
7815
0
      xmlFree(nsList);
7816
0
  }
7817
  /*
7818
  * TODO: Differentiate between "selector" and "field".
7819
  */
7820
0
  if (isField)
7821
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
7822
0
    NULL, XML_PATTERN_XSFIELD, nsArray);
7823
0
  else
7824
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
7825
0
    NULL, XML_PATTERN_XSSEL, nsArray);
7826
0
  if (nsArray != NULL)
7827
0
      xmlFree((xmlChar **) nsArray);
7828
7829
0
  if (selector->xpathComp == NULL) {
7830
0
      xmlSchemaPCustomErr(ctxt,
7831
    /* TODO: Adjust error code? */
7832
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7833
0
    NULL, node,
7834
0
    "The XPath expression '%s' could not be "
7835
0
    "compiled", selector->xpath);
7836
0
      return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
7837
0
  }
7838
0
    }
7839
0
    return (0);
7840
0
}
7841
7842
#define ADD_ANNOTATION(annot)   \
7843
0
    xmlSchemaAnnotPtr cur = item->annot; \
7844
0
    if (item->annot == NULL) {  \
7845
0
  item->annot = annot;    \
7846
0
  return (annot);         \
7847
0
    }                           \
7848
0
    cur = item->annot;          \
7849
0
    while (cur->next != NULL) { \
7850
0
  cur = cur->next;  \
7851
0
    }                           \
7852
0
    cur->next = annot;
7853
7854
/**
7855
 * Adds the annotation to the given schema component.
7856
 *
7857
 * @param annItem  the schema component
7858
 * @param annot  the annotation
7859
 * @returns the given annotation.
7860
 */
7861
static xmlSchemaAnnotPtr
7862
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
7863
           xmlSchemaAnnotPtr annot)
7864
0
{
7865
0
    if ((annItem == NULL) || (annot == NULL))
7866
0
  return (NULL);
7867
0
    switch (annItem->type) {
7868
0
  case XML_SCHEMA_TYPE_ELEMENT: {
7869
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
7870
0
    ADD_ANNOTATION(annot)
7871
0
      }
7872
0
      break;
7873
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
7874
0
    xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
7875
0
    ADD_ANNOTATION(annot)
7876
0
      }
7877
0
      break;
7878
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
7879
0
  case XML_SCHEMA_TYPE_ANY: {
7880
0
    xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
7881
0
    ADD_ANNOTATION(annot)
7882
0
      }
7883
0
      break;
7884
0
  case XML_SCHEMA_TYPE_PARTICLE:
7885
0
  case XML_SCHEMA_TYPE_IDC_KEY:
7886
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
7887
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE: {
7888
0
    xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
7889
0
    ADD_ANNOTATION(annot)
7890
0
      }
7891
0
      break;
7892
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
7893
0
    xmlSchemaAttributeGroupPtr item =
7894
0
        (xmlSchemaAttributeGroupPtr) annItem;
7895
0
    ADD_ANNOTATION(annot)
7896
0
      }
7897
0
      break;
7898
0
  case XML_SCHEMA_TYPE_NOTATION: {
7899
0
    xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
7900
0
    ADD_ANNOTATION(annot)
7901
0
      }
7902
0
      break;
7903
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
7904
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
7905
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
7906
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
7907
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
7908
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
7909
0
  case XML_SCHEMA_FACET_PATTERN:
7910
0
  case XML_SCHEMA_FACET_ENUMERATION:
7911
0
  case XML_SCHEMA_FACET_WHITESPACE:
7912
0
  case XML_SCHEMA_FACET_LENGTH:
7913
0
  case XML_SCHEMA_FACET_MAXLENGTH:
7914
0
  case XML_SCHEMA_FACET_MINLENGTH: {
7915
0
    xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
7916
0
    ADD_ANNOTATION(annot)
7917
0
      }
7918
0
      break;
7919
0
  case XML_SCHEMA_TYPE_SIMPLE:
7920
0
  case XML_SCHEMA_TYPE_COMPLEX: {
7921
0
    xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
7922
0
    ADD_ANNOTATION(annot)
7923
0
      }
7924
0
      break;
7925
0
  case XML_SCHEMA_TYPE_GROUP: {
7926
0
    xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
7927
0
    ADD_ANNOTATION(annot)
7928
0
      }
7929
0
      break;
7930
0
  case XML_SCHEMA_TYPE_SEQUENCE:
7931
0
  case XML_SCHEMA_TYPE_CHOICE:
7932
0
  case XML_SCHEMA_TYPE_ALL: {
7933
0
    xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
7934
0
    ADD_ANNOTATION(annot)
7935
0
      }
7936
0
      break;
7937
0
  default:
7938
0
       xmlSchemaPCustomErr(NULL,
7939
0
    XML_SCHEMAP_INTERNAL,
7940
0
    NULL, NULL,
7941
0
    "Internal error: xmlSchemaAddAnnotation, "
7942
0
    "The item is not a annotated schema component", NULL);
7943
0
       break;
7944
0
    }
7945
0
    return (annot);
7946
0
}
7947
7948
/**
7949
 * Parses a XML Schema identity-constraint definition's
7950
 * `<selector>` and `<field>` elements.
7951
 *
7952
 * @param ctxt  a schema validation context
7953
 * @param idc  the identity-constraint definition
7954
 * @param node  a subtree containing XML Schema information
7955
 * @param isField  field indicator
7956
 * @returns the parsed identity-constraint definition.
7957
 */
7958
static xmlSchemaIDCSelectPtr
7959
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
7960
        xmlSchemaIDCPtr idc,
7961
        xmlNodePtr node,
7962
        int isField)
7963
0
{
7964
0
    xmlSchemaIDCSelectPtr item;
7965
0
    xmlNodePtr child = NULL;
7966
0
    xmlAttrPtr attr;
7967
7968
    /*
7969
    * Check for illegal attributes.
7970
    */
7971
0
    attr = node->properties;
7972
0
    while (attr != NULL) {
7973
0
  if (attr->ns == NULL) {
7974
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7975
0
    (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
7976
0
    xmlSchemaPIllegalAttrErr(ctxt,
7977
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7978
0
      }
7979
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7980
0
      xmlSchemaPIllegalAttrErr(ctxt,
7981
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7982
0
  }
7983
0
  attr = attr->next;
7984
0
    }
7985
    /*
7986
    * Create the item.
7987
    */
7988
0
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
7989
0
    if (item == NULL) {
7990
0
        xmlSchemaPErrMemory(ctxt);
7991
0
        return (NULL);
7992
0
    }
7993
0
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
7994
    /*
7995
    * Attribute "xpath" (mandatory).
7996
    */
7997
0
    attr = xmlSchemaGetPropNode(node, "xpath");
7998
0
    if (attr == NULL) {
7999
0
  xmlSchemaPMissingAttrErr(ctxt,
8000
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8001
0
      NULL, node,
8002
0
      "name", NULL);
8003
0
    } else {
8004
0
  item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8005
  /*
8006
  * URGENT TODO: "field"s have an other syntax than "selector"s.
8007
  */
8008
8009
0
  if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8010
0
      isField) == -1) {
8011
0
      xmlSchemaPErr(ctxt,
8012
0
    (xmlNodePtr) attr,
8013
0
    XML_SCHEMAP_INTERNAL,
8014
0
    "Internal error: xmlSchemaParseIDCSelectorAndField, "
8015
0
    "validating the XPath expression of a IDC selector.\n",
8016
0
    NULL, NULL);
8017
0
  }
8018
8019
0
    }
8020
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8021
    /*
8022
    * And now for the children...
8023
    */
8024
0
    child = node->children;
8025
0
    if (IS_SCHEMA(child, "annotation")) {
8026
  /*
8027
  * Add the annotation to the parent IDC.
8028
  */
8029
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8030
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8031
0
  child = child->next;
8032
0
    }
8033
0
    if (child != NULL) {
8034
0
  xmlSchemaPContentErr(ctxt,
8035
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8036
0
      NULL, node, child,
8037
0
      NULL, "(annotation?)");
8038
0
    }
8039
8040
0
    return (item);
8041
0
}
8042
8043
/**
8044
 * Parses a XML Schema identity-constraint definition.
8045
 *
8046
 * @param ctxt  a schema validation context
8047
 * @param schema  the schema being built
8048
 * @param node  a subtree containing XML Schema information
8049
 * @param idcCategory  the IDC category
8050
 * @param targetNamespace  the target namespace
8051
 * @returns the parsed identity-constraint definition.
8052
 */
8053
static xmlSchemaIDCPtr
8054
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8055
      xmlSchemaPtr schema,
8056
      xmlNodePtr node,
8057
      xmlSchemaTypeType idcCategory,
8058
      const xmlChar *targetNamespace)
8059
0
{
8060
0
    xmlSchemaIDCPtr item = NULL;
8061
0
    xmlNodePtr child = NULL;
8062
0
    xmlAttrPtr attr;
8063
0
    const xmlChar *name = NULL;
8064
0
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8065
8066
    /*
8067
    * Check for illegal attributes.
8068
    */
8069
0
    attr = node->properties;
8070
0
    while (attr != NULL) {
8071
0
  if (attr->ns == NULL) {
8072
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8073
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8074
0
    ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8075
0
     (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8076
0
    xmlSchemaPIllegalAttrErr(ctxt,
8077
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8078
0
      }
8079
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8080
0
      xmlSchemaPIllegalAttrErr(ctxt,
8081
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8082
0
  }
8083
0
  attr = attr->next;
8084
0
    }
8085
    /*
8086
    * Attribute "name" (mandatory).
8087
    */
8088
0
    attr = xmlSchemaGetPropNode(node, "name");
8089
0
    if (attr == NULL) {
8090
0
  xmlSchemaPMissingAttrErr(ctxt,
8091
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8092
0
      NULL, node,
8093
0
      "name", NULL);
8094
0
  return (NULL);
8095
0
    } else if (xmlSchemaPValAttrNode(ctxt,
8096
0
  NULL, attr,
8097
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8098
0
  return (NULL);
8099
0
    }
8100
    /* Create the component. */
8101
0
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8102
0
  idcCategory, node);
8103
0
    if (item == NULL)
8104
0
  return(NULL);
8105
8106
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8107
0
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8108
  /*
8109
  * Attribute "refer" (mandatory).
8110
  */
8111
0
  attr = xmlSchemaGetPropNode(node, "refer");
8112
0
  if (attr == NULL) {
8113
0
      xmlSchemaPMissingAttrErr(ctxt,
8114
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8115
0
    NULL, node,
8116
0
    "refer", NULL);
8117
0
  } else {
8118
      /*
8119
      * Create a reference item.
8120
      */
8121
0
      item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8122
0
    NULL, NULL);
8123
0
      if (item->ref == NULL)
8124
0
    return (NULL);
8125
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8126
0
    NULL, attr,
8127
0
    &(item->ref->targetNamespace),
8128
0
    &(item->ref->name));
8129
0
      xmlSchemaCheckReference(ctxt, schema, node, attr,
8130
0
    item->ref->targetNamespace);
8131
0
  }
8132
0
    }
8133
    /*
8134
    * And now for the children...
8135
    */
8136
0
    child = node->children;
8137
0
    if (IS_SCHEMA(child, "annotation")) {
8138
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8139
0
  child = child->next;
8140
0
    }
8141
0
    if (child == NULL) {
8142
0
  xmlSchemaPContentErr(ctxt,
8143
0
    XML_SCHEMAP_S4S_ELEM_MISSING,
8144
0
    NULL, node, child,
8145
0
    "A child element is missing",
8146
0
    "(annotation?, (selector, field+))");
8147
0
    }
8148
    /*
8149
    * Child element <selector>.
8150
    */
8151
0
    if (IS_SCHEMA(child, "selector")) {
8152
0
  item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8153
0
      item, child, 0);
8154
0
  child = child->next;
8155
  /*
8156
  * Child elements <field>.
8157
  */
8158
0
  if (IS_SCHEMA(child, "field")) {
8159
0
      do {
8160
0
    field = xmlSchemaParseIDCSelectorAndField(ctxt,
8161
0
        item, child, 1);
8162
0
    if (field != NULL) {
8163
0
        field->index = item->nbFields;
8164
0
        item->nbFields++;
8165
0
        if (lastField != NULL)
8166
0
      lastField->next = field;
8167
0
        else
8168
0
      item->fields = field;
8169
0
        lastField = field;
8170
0
    }
8171
0
    child = child->next;
8172
0
      } while (IS_SCHEMA(child, "field"));
8173
0
  } else {
8174
0
      xmlSchemaPContentErr(ctxt,
8175
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8176
0
    NULL, node, child,
8177
0
    NULL, "(annotation?, (selector, field+))");
8178
0
  }
8179
0
    }
8180
0
    if (child != NULL) {
8181
0
  xmlSchemaPContentErr(ctxt,
8182
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8183
0
      NULL, node, child,
8184
0
      NULL, "(annotation?, (selector, field+))");
8185
0
    }
8186
8187
0
    return (item);
8188
0
}
8189
8190
/**
8191
 * Parses a XML schema element declaration.
8192
 * *WARNING* this interface is highly subject to change
8193
 *
8194
 * @param ctxt  a schema validation context
8195
 * @param schema  the schema being built
8196
 * @param node  a subtree containing XML Schema information
8197
 * @param isElemRef  set if the element is a reference
8198
 * @param topLevel  indicates if this is global declaration
8199
 * @returns the element declaration or a particle; NULL in case
8200
 * of an error or if the particle has minOccurs==maxOccurs==0.
8201
 */
8202
static xmlSchemaBasicItemPtr
8203
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8204
                      xmlNodePtr node, int *isElemRef, int topLevel)
8205
0
{
8206
0
    xmlSchemaElementPtr decl = NULL;
8207
0
    xmlSchemaParticlePtr particle = NULL;
8208
0
    xmlSchemaAnnotPtr annot = NULL;
8209
0
    xmlNodePtr child = NULL;
8210
0
    xmlAttrPtr attr, nameAttr;
8211
0
    int min, max, isRef = 0;
8212
0
    xmlChar *des = NULL;
8213
8214
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
8215
    /* TODO: Complete implementation of 3.3.6 */
8216
8217
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8218
0
        return (NULL);
8219
8220
0
    if (isElemRef != NULL)
8221
0
  *isElemRef = 0;
8222
    /*
8223
    * If we get a "ref" attribute on a local <element> we will assume it's
8224
    * a reference - even if there's a "name" attribute; this seems to be more
8225
    * robust.
8226
    */
8227
0
    nameAttr = xmlSchemaGetPropNode(node, "name");
8228
0
    attr = xmlSchemaGetPropNode(node, "ref");
8229
0
    if ((topLevel) || (attr == NULL)) {
8230
0
  if (nameAttr == NULL) {
8231
0
      xmlSchemaPMissingAttrErr(ctxt,
8232
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8233
0
    NULL, node, "name", NULL);
8234
0
      return (NULL);
8235
0
  }
8236
0
    } else
8237
0
  isRef = 1;
8238
8239
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8240
0
    child = node->children;
8241
0
    if (IS_SCHEMA(child, "annotation")) {
8242
0
  annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8243
0
  child = child->next;
8244
0
    }
8245
    /*
8246
    * Skip particle part if a global declaration.
8247
    */
8248
0
    if (topLevel)
8249
0
  goto declaration_part;
8250
    /*
8251
    * The particle part ==================================================
8252
    */
8253
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8254
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8255
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8256
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
8257
0
    if (particle == NULL)
8258
0
  goto return_null;
8259
8260
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8261
8262
0
    if (isRef) {
8263
0
  const xmlChar *refNs = NULL, *ref = NULL;
8264
0
  xmlSchemaQNameRefPtr refer = NULL;
8265
  /*
8266
  * The reference part =============================================
8267
  */
8268
0
  if (isElemRef != NULL)
8269
0
      *isElemRef = 1;
8270
8271
0
  xmlSchemaPValAttrNodeQName(ctxt, schema,
8272
0
      NULL, attr, &refNs, &ref);
8273
0
  xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8274
  /*
8275
  * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8276
  */
8277
0
  if (nameAttr != NULL) {
8278
0
      xmlSchemaPMutualExclAttrErr(ctxt,
8279
0
    XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8280
0
  }
8281
  /*
8282
  * Check for illegal attributes.
8283
  */
8284
0
  attr = node->properties;
8285
0
  while (attr != NULL) {
8286
0
      if (attr->ns == NULL) {
8287
0
    if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8288
0
        xmlStrEqual(attr->name, BAD_CAST "name") ||
8289
0
        xmlStrEqual(attr->name, BAD_CAST "id") ||
8290
0
        xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8291
0
        xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8292
0
    {
8293
0
        attr = attr->next;
8294
0
        continue;
8295
0
    } else {
8296
        /* SPEC (3.3.3 : 2.2) */
8297
0
        xmlSchemaPCustomAttrErr(ctxt,
8298
0
      XML_SCHEMAP_SRC_ELEMENT_2_2,
8299
0
      NULL, NULL, attr,
8300
0
      "Only the attributes 'minOccurs', 'maxOccurs' and "
8301
0
      "'id' are allowed in addition to 'ref'");
8302
0
        break;
8303
0
    }
8304
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8305
0
    xmlSchemaPIllegalAttrErr(ctxt,
8306
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8307
0
      }
8308
0
      attr = attr->next;
8309
0
  }
8310
  /*
8311
  * No children except <annotation> expected.
8312
  */
8313
0
  if (child != NULL) {
8314
0
      xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8315
0
    NULL, node, child, NULL, "(annotation?)");
8316
0
  }
8317
0
  if ((min == 0) && (max == 0))
8318
0
      goto return_null;
8319
  /*
8320
  * Create the reference item and attach it to the particle.
8321
  */
8322
0
  refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8323
0
      ref, refNs);
8324
0
  if (refer == NULL)
8325
0
      goto return_null;
8326
0
  particle->children = (xmlSchemaTreeItemPtr) refer;
8327
0
  particle->annot = annot;
8328
  /*
8329
  * Add the particle to pending components, since the reference
8330
  * need to be resolved.
8331
  */
8332
0
  WXS_ADD_PENDING(ctxt, particle);
8333
0
  return ((xmlSchemaBasicItemPtr) particle);
8334
0
    }
8335
    /*
8336
    * The declaration part ===============================================
8337
    */
8338
0
declaration_part:
8339
0
    {
8340
0
  const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8341
0
  xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8342
8343
0
  if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8344
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8345
0
      goto return_null;
8346
  /*
8347
  * Evaluate the target namespace.
8348
  */
8349
0
  if (topLevel) {
8350
0
      ns = ctxt->targetNamespace;
8351
0
  } else {
8352
0
      attr = xmlSchemaGetPropNode(node, "form");
8353
0
      if (attr != NULL) {
8354
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8355
0
    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8356
0
        ns = ctxt->targetNamespace;
8357
0
    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8358
0
        xmlSchemaPSimpleTypeErr(ctxt,
8359
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8360
0
      NULL, (xmlNodePtr) attr,
8361
0
      NULL, "(qualified | unqualified)",
8362
0
      attrValue, NULL, NULL, NULL);
8363
0
    }
8364
0
      } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8365
0
    ns = ctxt->targetNamespace;
8366
0
  }
8367
0
  decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8368
0
  if (decl == NULL) {
8369
0
      goto return_null;
8370
0
  }
8371
  /*
8372
  * Check for illegal attributes.
8373
  */
8374
0
  attr = node->properties;
8375
0
  while (attr != NULL) {
8376
0
      if (attr->ns == NULL) {
8377
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8378
0
        (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8379
0
        (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8380
0
        (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8381
0
        (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8382
0
        (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8383
0
        (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8384
0
    {
8385
0
        if (topLevel == 0) {
8386
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8387
0
          (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8388
0
          (!xmlStrEqual(attr->name, BAD_CAST "form")))
8389
0
      {
8390
0
          xmlSchemaPIllegalAttrErr(ctxt,
8391
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8392
0
      }
8393
0
        } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8394
0
      (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8395
0
      (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8396
8397
0
      xmlSchemaPIllegalAttrErr(ctxt,
8398
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8399
0
        }
8400
0
    }
8401
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8402
8403
0
    xmlSchemaPIllegalAttrErr(ctxt,
8404
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8405
0
      }
8406
0
      attr = attr->next;
8407
0
  }
8408
  /*
8409
  * Extract/validate attributes.
8410
  */
8411
0
  if (topLevel) {
8412
      /*
8413
      * Process top attributes of global element declarations here.
8414
      */
8415
0
      decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8416
0
      decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8417
0
      xmlSchemaPValAttrQName(ctxt, schema,
8418
0
    NULL, node, "substitutionGroup",
8419
0
    &(decl->substGroupNs), &(decl->substGroup));
8420
0
      if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8421
0
    decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8422
      /*
8423
      * Attribute "final".
8424
      */
8425
0
      attr = xmlSchemaGetPropNode(node, "final");
8426
0
      if (attr == NULL) {
8427
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8428
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8429
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8430
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8431
0
      } else {
8432
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8433
0
    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8434
0
        -1,
8435
0
        XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8436
0
        XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8437
0
        xmlSchemaPSimpleTypeErr(ctxt,
8438
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8439
0
      NULL, (xmlNodePtr) attr,
8440
0
      NULL, "(#all | List of (extension | restriction))",
8441
0
      attrValue, NULL, NULL, NULL);
8442
0
    }
8443
0
      }
8444
0
  }
8445
  /*
8446
  * Attribute "block".
8447
  */
8448
0
  attr = xmlSchemaGetPropNode(node, "block");
8449
0
  if (attr == NULL) {
8450
      /*
8451
      * Apply default "block" values.
8452
      */
8453
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8454
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8455
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8456
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8457
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8458
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8459
0
  } else {
8460
0
      attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8461
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8462
0
    -1,
8463
0
    XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8464
0
    XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8465
0
    XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8466
0
    xmlSchemaPSimpleTypeErr(ctxt,
8467
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8468
0
        NULL, (xmlNodePtr) attr,
8469
0
        NULL, "(#all | List of (extension | "
8470
0
        "restriction | substitution))", attrValue,
8471
0
        NULL, NULL, NULL);
8472
0
      }
8473
0
  }
8474
0
  if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8475
0
      decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8476
8477
0
  attr = xmlSchemaGetPropNode(node, "type");
8478
0
  if (attr != NULL) {
8479
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8480
0
    NULL, attr,
8481
0
    &(decl->namedTypeNs), &(decl->namedType));
8482
0
      xmlSchemaCheckReference(ctxt, schema, node,
8483
0
    attr, decl->namedTypeNs);
8484
0
  }
8485
0
  decl->value = xmlSchemaGetProp(ctxt, node, "default");
8486
0
  attr = xmlSchemaGetPropNode(node, "fixed");
8487
0
  if (attr != NULL) {
8488
0
      fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8489
0
      if (decl->value != NULL) {
8490
    /*
8491
    * 3.3.3 : 1
8492
    * default and fixed must not both be present.
8493
    */
8494
0
    xmlSchemaPMutualExclAttrErr(ctxt,
8495
0
        XML_SCHEMAP_SRC_ELEMENT_1,
8496
0
        NULL, attr, "default", "fixed");
8497
0
      } else {
8498
0
    decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8499
0
    decl->value = fixed;
8500
0
      }
8501
0
  }
8502
  /*
8503
  * And now for the children...
8504
  */
8505
0
  if (IS_SCHEMA(child, "complexType")) {
8506
      /*
8507
      * 3.3.3 : 3
8508
      * "type" and either <simpleType> or <complexType> are mutually
8509
      * exclusive
8510
      */
8511
0
      if (decl->namedType != NULL) {
8512
0
    xmlSchemaPContentErr(ctxt,
8513
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8514
0
        NULL, node, child,
8515
0
        "The attribute 'type' and the <complexType> child are "
8516
0
        "mutually exclusive", NULL);
8517
0
      } else
8518
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8519
0
      child = child->next;
8520
0
  } else if (IS_SCHEMA(child, "simpleType")) {
8521
      /*
8522
      * 3.3.3 : 3
8523
      * "type" and either <simpleType> or <complexType> are
8524
      * mutually exclusive
8525
      */
8526
0
      if (decl->namedType != NULL) {
8527
0
    xmlSchemaPContentErr(ctxt,
8528
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8529
0
        NULL, node, child,
8530
0
        "The attribute 'type' and the <simpleType> child are "
8531
0
        "mutually exclusive", NULL);
8532
0
      } else
8533
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8534
0
      child = child->next;
8535
0
  }
8536
0
  while ((IS_SCHEMA(child, "unique")) ||
8537
0
      (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8538
0
      if (IS_SCHEMA(child, "unique")) {
8539
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8540
0
        XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8541
0
      } else if (IS_SCHEMA(child, "key")) {
8542
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8543
0
        XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8544
0
      } else if (IS_SCHEMA(child, "keyref")) {
8545
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8546
0
        XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8547
0
      }
8548
0
      if (lastIDC != NULL)
8549
0
    lastIDC->next = curIDC;
8550
0
      else
8551
0
    decl->idcs = (void *) curIDC;
8552
0
      lastIDC = curIDC;
8553
0
      child = child->next;
8554
0
  }
8555
0
  if (child != NULL) {
8556
0
      xmlSchemaPContentErr(ctxt,
8557
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8558
0
    NULL, node, child,
8559
0
    NULL, "(annotation?, ((simpleType | complexType)?, "
8560
0
    "(unique | key | keyref)*))");
8561
0
  }
8562
0
  decl->annot = annot;
8563
0
    }
8564
    /*
8565
    * NOTE: Element Declaration Representation OK 4. will be checked at a
8566
    * different layer.
8567
    */
8568
0
    FREE_AND_NULL(des)
8569
0
    if (topLevel)
8570
0
  return ((xmlSchemaBasicItemPtr) decl);
8571
0
    else {
8572
0
  particle->children = (xmlSchemaTreeItemPtr) decl;
8573
0
  return ((xmlSchemaBasicItemPtr) particle);
8574
0
    }
8575
8576
0
return_null:
8577
0
    FREE_AND_NULL(des);
8578
0
    if (annot != NULL) {
8579
0
  if (particle != NULL)
8580
0
      particle->annot = NULL;
8581
0
  if (decl != NULL)
8582
0
      decl->annot = NULL;
8583
0
  xmlSchemaFreeAnnot(annot);
8584
0
    }
8585
0
    return (NULL);
8586
0
}
8587
8588
/**
8589
 * parse a XML schema Union definition
8590
 * *WARNING* this interface is highly subject to change
8591
 *
8592
 * @param ctxt  a schema validation context
8593
 * @param schema  the schema being built
8594
 * @param node  a subtree containing XML Schema information
8595
 * @returns -1 in case of internal error, 0 in case of success and a positive
8596
 * error code otherwise.
8597
 */
8598
static int
8599
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8600
                    xmlNodePtr node)
8601
0
{
8602
0
    xmlSchemaTypePtr type;
8603
0
    xmlNodePtr child = NULL;
8604
0
    xmlAttrPtr attr;
8605
0
    const xmlChar *cur = NULL;
8606
8607
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8608
0
        return (-1);
8609
    /* Not a component, don't create it. */
8610
0
    type = ctxt->ctxtType;
8611
    /*
8612
    * Mark the simple type as being of variety "union".
8613
    */
8614
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8615
    /*
8616
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8617
    * then the `simple ur-type definition`."
8618
    */
8619
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8620
    /*
8621
    * Check for illegal attributes.
8622
    */
8623
0
    attr = node->properties;
8624
0
    while (attr != NULL) {
8625
0
  if (attr->ns == NULL) {
8626
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8627
0
    (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8628
0
    xmlSchemaPIllegalAttrErr(ctxt,
8629
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8630
0
      }
8631
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8632
0
      xmlSchemaPIllegalAttrErr(ctxt,
8633
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8634
0
  }
8635
0
  attr = attr->next;
8636
0
    }
8637
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8638
    /*
8639
    * Attribute "memberTypes". This is a list of QNames.
8640
    * TODO: Check the value to contain anything.
8641
    */
8642
0
    attr = xmlSchemaGetPropNode(node, "memberTypes");
8643
0
    if (attr != NULL) {
8644
0
  const xmlChar *end;
8645
0
  xmlChar *tmp;
8646
0
  const xmlChar *localName, *nsName;
8647
0
  xmlSchemaTypeLinkPtr link, lastLink = NULL;
8648
0
  xmlSchemaQNameRefPtr ref;
8649
8650
0
  cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8651
0
        if (cur == NULL)
8652
0
            return (-1);
8653
0
  type->base = cur;
8654
0
  do {
8655
0
      while (IS_BLANK_CH(*cur))
8656
0
    cur++;
8657
0
      end = cur;
8658
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8659
0
    end++;
8660
0
      if (end == cur)
8661
0
    break;
8662
0
      tmp = xmlStrndup(cur, end - cur);
8663
0
            if (tmp == NULL) {
8664
0
                xmlSchemaPErrMemory(ctxt);
8665
0
                return (-1);
8666
0
            }
8667
0
      if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8668
0
    NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
8669
    /*
8670
    * Create the member type link.
8671
    */
8672
0
    link = (xmlSchemaTypeLinkPtr)
8673
0
        xmlMalloc(sizeof(xmlSchemaTypeLink));
8674
0
    if (link == NULL) {
8675
0
        xmlSchemaPErrMemory(ctxt);
8676
0
              FREE_AND_NULL(tmp)
8677
0
        return (-1);
8678
0
    }
8679
0
    link->type = NULL;
8680
0
    link->next = NULL;
8681
    /*
8682
    * Create a reference item.
8683
    */
8684
0
    ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8685
0
        localName, nsName);
8686
0
    if (ref == NULL) {
8687
0
                    xmlSchemaPErrMemory(ctxt);
8688
0
                    xmlFree(link);
8689
0
        FREE_AND_NULL(tmp)
8690
0
        return (-1);
8691
0
    }
8692
    /*
8693
    * Assign the reference to the link, it will be resolved
8694
    * later during fixup of the union simple type.
8695
    */
8696
0
    link->type = (xmlSchemaTypePtr) ref;
8697
8698
0
    if (lastLink == NULL)
8699
0
        type->memberTypes = link;
8700
0
    else
8701
0
        lastLink->next = link;
8702
0
    lastLink = link;
8703
0
      }
8704
0
      FREE_AND_NULL(tmp)
8705
0
      cur = end;
8706
0
  } while (*cur != 0);
8707
8708
0
    }
8709
    /*
8710
    * And now for the children...
8711
    */
8712
0
    child = node->children;
8713
0
    if (IS_SCHEMA(child, "annotation")) {
8714
  /*
8715
  * Add the annotation to the simple type ancestor.
8716
  */
8717
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8718
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8719
0
        child = child->next;
8720
0
    }
8721
0
    if (IS_SCHEMA(child, "simpleType")) {
8722
0
  xmlSchemaTypePtr subtype, last = NULL;
8723
8724
  /*
8725
  * Anchor the member types in the "subtypes" field of the
8726
  * simple type.
8727
  */
8728
0
  while (IS_SCHEMA(child, "simpleType")) {
8729
0
      subtype = (xmlSchemaTypePtr)
8730
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8731
0
      if (subtype != NULL) {
8732
0
    if (last == NULL) {
8733
0
        type->subtypes = subtype;
8734
0
        last = subtype;
8735
0
    } else {
8736
0
        last->next = subtype;
8737
0
        last = subtype;
8738
0
    }
8739
0
    last->next = NULL;
8740
0
      }
8741
0
      child = child->next;
8742
0
  }
8743
0
    }
8744
0
    if (child != NULL) {
8745
0
  xmlSchemaPContentErr(ctxt,
8746
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8747
0
      NULL, node, child, NULL, "(annotation?, simpleType*)");
8748
0
    }
8749
0
    if ((attr == NULL) && (type->subtypes == NULL)) {
8750
   /*
8751
  * src-union-memberTypes-or-simpleTypes
8752
  * Either the memberTypes [attribute] of the <union> element must
8753
  * be non-empty or there must be at least one simpleType [child].
8754
  */
8755
0
  xmlSchemaPCustomErr(ctxt,
8756
0
      XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8757
0
      NULL, node,
8758
0
      "Either the attribute 'memberTypes' or "
8759
0
      "at least one <simpleType> child must be present", NULL);
8760
0
    }
8761
0
    return (0);
8762
0
}
8763
8764
/**
8765
 * parse a XML schema List definition
8766
 * *WARNING* this interface is highly subject to change
8767
 *
8768
 * @param ctxt  a schema validation context
8769
 * @param schema  the schema being built
8770
 * @param node  a subtree containing XML Schema information
8771
 * @returns -1 in case of error, 0 if the declaration is improper and
8772
 *         1 in case of success.
8773
 */
8774
static xmlSchemaTypePtr
8775
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8776
                   xmlNodePtr node)
8777
0
{
8778
0
    xmlSchemaTypePtr type;
8779
0
    xmlNodePtr child = NULL;
8780
0
    xmlAttrPtr attr;
8781
8782
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8783
0
        return (NULL);
8784
    /* Not a component, don't create it. */
8785
0
    type = ctxt->ctxtType;
8786
    /*
8787
    * Mark the type as being of variety "list".
8788
    */
8789
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
8790
    /*
8791
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8792
    * then the `simple ur-type definition`."
8793
    */
8794
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8795
    /*
8796
    * Check for illegal attributes.
8797
    */
8798
0
    attr = node->properties;
8799
0
    while (attr != NULL) {
8800
0
  if (attr->ns == NULL) {
8801
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8802
0
    (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
8803
0
    xmlSchemaPIllegalAttrErr(ctxt,
8804
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8805
0
      }
8806
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8807
0
      xmlSchemaPIllegalAttrErr(ctxt,
8808
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8809
0
  }
8810
0
  attr = attr->next;
8811
0
    }
8812
8813
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8814
8815
    /*
8816
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
8817
    * fields for holding the reference to the itemType.
8818
    *
8819
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
8820
    * the "ref" fields.
8821
    */
8822
0
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
8823
0
  node, "itemType", &(type->baseNs), &(type->base));
8824
    /*
8825
    * And now for the children...
8826
    */
8827
0
    child = node->children;
8828
0
    if (IS_SCHEMA(child, "annotation")) {
8829
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8830
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8831
0
        child = child->next;
8832
0
    }
8833
0
    if (IS_SCHEMA(child, "simpleType")) {
8834
  /*
8835
  * src-list-itemType-or-simpleType
8836
  * Either the itemType [attribute] or the <simpleType> [child] of
8837
  * the <list> element must be present, but not both.
8838
  */
8839
0
  if (type->base != NULL) {
8840
0
      xmlSchemaPCustomErr(ctxt,
8841
0
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
8842
0
    NULL, node,
8843
0
    "The attribute 'itemType' and the <simpleType> child "
8844
0
    "are mutually exclusive", NULL);
8845
0
  } else {
8846
0
      type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8847
0
  }
8848
0
        child = child->next;
8849
0
    } else if (type->base == NULL) {
8850
0
  xmlSchemaPCustomErr(ctxt,
8851
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
8852
0
      NULL, node,
8853
0
      "Either the attribute 'itemType' or the <simpleType> child "
8854
0
      "must be present", NULL);
8855
0
    }
8856
0
    if (child != NULL) {
8857
0
  xmlSchemaPContentErr(ctxt,
8858
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8859
0
      NULL, node, child, NULL, "(annotation?, simpleType?)");
8860
0
    }
8861
0
    if ((type->base == NULL) &&
8862
0
  (type->subtypes == NULL) &&
8863
0
  (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
8864
0
  xmlSchemaPCustomErr(ctxt,
8865
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
8866
0
      NULL, node,
8867
0
      "Either the attribute 'itemType' or the <simpleType> child "
8868
0
      "must be present", NULL);
8869
0
    }
8870
0
    return (NULL);
8871
0
}
8872
8873
/**
8874
 * parse a XML schema Simple Type definition
8875
 * *WARNING* this interface is highly subject to change
8876
 *
8877
 * @param ctxt  a schema validation context
8878
 * @param schema  the schema being built
8879
 * @param node  a subtree containing XML Schema information
8880
 * @param topLevel  whether this is a top-level element
8881
 * @returns -1 in case of error, 0 if the declaration is improper and
8882
 * 1 in case of success.
8883
 */
8884
static xmlSchemaTypePtr
8885
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8886
                         xmlNodePtr node, int topLevel)
8887
0
{
8888
0
    xmlSchemaTypePtr type, oldCtxtType;
8889
0
    xmlNodePtr child = NULL;
8890
0
    const xmlChar *attrValue = NULL;
8891
0
    xmlAttrPtr attr;
8892
0
    int hasRestriction = 0;
8893
8894
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8895
0
        return (NULL);
8896
8897
0
    if (topLevel) {
8898
0
  attr = xmlSchemaGetPropNode(node, "name");
8899
0
  if (attr == NULL) {
8900
0
      xmlSchemaPMissingAttrErr(ctxt,
8901
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8902
0
    NULL, node,
8903
0
    "name", NULL);
8904
0
      return (NULL);
8905
0
  } else {
8906
0
      if (xmlSchemaPValAttrNode(ctxt,
8907
0
    NULL, attr,
8908
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
8909
0
    return (NULL);
8910
      /*
8911
      * Skip built-in types.
8912
      */
8913
0
      if (ctxt->isS4S) {
8914
0
    xmlSchemaTypePtr biType;
8915
8916
0
    if (ctxt->isRedefine) {
8917
        /*
8918
        * REDEFINE: Disallow redefinition of built-in-types.
8919
        * TODO: It seems that the spec does not say anything
8920
        * about this case.
8921
        */
8922
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
8923
0
      NULL, node,
8924
0
      "Redefinition of built-in simple types is not "
8925
0
      "supported", NULL);
8926
0
        return(NULL);
8927
0
    }
8928
0
    biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
8929
0
    if (biType != NULL)
8930
0
        return (biType);
8931
0
      }
8932
0
  }
8933
0
    }
8934
    /*
8935
    * TargetNamespace:
8936
    * SPEC "The `actual value` of the targetNamespace [attribute]
8937
    * of the <schema> ancestor element information item if present,
8938
    * otherwise `absent`.
8939
    */
8940
0
    if (topLevel == 0) {
8941
#ifdef ENABLE_NAMED_LOCALS
8942
        char buf[40];
8943
#endif
8944
  /*
8945
  * Parse as local simple type definition.
8946
  */
8947
#ifdef ENABLE_NAMED_LOCALS
8948
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
8949
  type = xmlSchemaAddType(ctxt, schema,
8950
      XML_SCHEMA_TYPE_SIMPLE,
8951
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
8952
      ctxt->targetNamespace, node, 0);
8953
#else
8954
0
  type = xmlSchemaAddType(ctxt, schema,
8955
0
      XML_SCHEMA_TYPE_SIMPLE,
8956
0
      NULL, ctxt->targetNamespace, node, 0);
8957
0
#endif
8958
0
  if (type == NULL)
8959
0
      return (NULL);
8960
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
8961
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
8962
  /*
8963
  * Check for illegal attributes.
8964
  */
8965
0
  attr = node->properties;
8966
0
  while (attr != NULL) {
8967
0
      if (attr->ns == NULL) {
8968
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
8969
0
        xmlSchemaPIllegalAttrErr(ctxt,
8970
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8971
0
    }
8972
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8973
0
        xmlSchemaPIllegalAttrErr(ctxt,
8974
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8975
0
      }
8976
0
      attr = attr->next;
8977
0
  }
8978
0
    } else {
8979
  /*
8980
  * Parse as global simple type definition.
8981
  *
8982
  * Note that attrValue is the value of the attribute "name" here.
8983
  */
8984
0
  type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
8985
0
      attrValue, ctxt->targetNamespace, node, 1);
8986
0
  if (type == NULL)
8987
0
      return (NULL);
8988
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
8989
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
8990
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
8991
  /*
8992
  * Check for illegal attributes.
8993
  */
8994
0
  attr = node->properties;
8995
0
  while (attr != NULL) {
8996
0
      if (attr->ns == NULL) {
8997
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8998
0
        (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8999
0
        (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9000
0
        xmlSchemaPIllegalAttrErr(ctxt,
9001
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9002
0
    }
9003
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9004
0
    xmlSchemaPIllegalAttrErr(ctxt,
9005
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9006
0
      }
9007
0
      attr = attr->next;
9008
0
  }
9009
  /*
9010
  * Attribute "final".
9011
  */
9012
0
  attr = xmlSchemaGetPropNode(node, "final");
9013
0
  if (attr == NULL) {
9014
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9015
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9016
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9017
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9018
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9019
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9020
0
  } else {
9021
0
      attrValue = xmlSchemaGetProp(ctxt, node, "final");
9022
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9023
0
    -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9024
0
    XML_SCHEMAS_TYPE_FINAL_LIST,
9025
0
    XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9026
9027
0
    xmlSchemaPSimpleTypeErr(ctxt,
9028
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9029
0
        WXS_BASIC_CAST type, (xmlNodePtr) attr,
9030
0
        NULL, "(#all | List of (list | union | restriction)",
9031
0
        attrValue, NULL, NULL, NULL);
9032
0
      }
9033
0
  }
9034
0
    }
9035
0
    type->targetNamespace = ctxt->targetNamespace;
9036
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9037
    /*
9038
    * And now for the children...
9039
    */
9040
0
    oldCtxtType = ctxt->ctxtType;
9041
9042
0
    ctxt->ctxtType = type;
9043
9044
0
    child = node->children;
9045
0
    if (IS_SCHEMA(child, "annotation")) {
9046
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9047
0
        child = child->next;
9048
0
    }
9049
0
    if (child == NULL) {
9050
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9051
0
      NULL, node, child, NULL,
9052
0
      "(annotation?, (restriction | list | union))");
9053
0
    } else if (IS_SCHEMA(child, "restriction")) {
9054
0
        xmlSchemaParseRestriction(ctxt, schema, child,
9055
0
      XML_SCHEMA_TYPE_SIMPLE);
9056
0
  hasRestriction = 1;
9057
0
        child = child->next;
9058
0
    } else if (IS_SCHEMA(child, "list")) {
9059
0
        xmlSchemaParseList(ctxt, schema, child);
9060
0
        child = child->next;
9061
0
    } else if (IS_SCHEMA(child, "union")) {
9062
0
        xmlSchemaParseUnion(ctxt, schema, child);
9063
0
        child = child->next;
9064
0
    }
9065
0
    if (child != NULL) {
9066
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9067
0
      NULL, node, child, NULL,
9068
0
      "(annotation?, (restriction | list | union))");
9069
0
    }
9070
    /*
9071
    * REDEFINE: SPEC src-redefine (5)
9072
    * "Within the [children], each <simpleType> must have a
9073
    * <restriction> among its [children] ... the `actual value` of whose
9074
    * base [attribute] must be the same as the `actual value` of its own
9075
    * name attribute plus target namespace;"
9076
    */
9077
0
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9078
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9079
0
      NULL, node, "This is a redefinition, thus the "
9080
0
      "<simpleType> must have a <restriction> child", NULL);
9081
0
    }
9082
9083
0
    ctxt->ctxtType = oldCtxtType;
9084
0
    return (type);
9085
0
}
9086
9087
/**
9088
 * Parses a reference to a model group definition.
9089
 *
9090
 * We will return a particle component with a qname-component or
9091
 * NULL in case of an error.
9092
 *
9093
 * @param ctxt  the parser context
9094
 * @param schema  the schema being built
9095
 * @param node  the node
9096
 */
9097
static xmlSchemaTreeItemPtr
9098
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9099
             xmlSchemaPtr schema,
9100
             xmlNodePtr node)
9101
0
{
9102
0
    xmlSchemaParticlePtr item;
9103
0
    xmlNodePtr child = NULL;
9104
0
    xmlAttrPtr attr;
9105
0
    const xmlChar *ref = NULL, *refNs = NULL;
9106
0
    int min, max;
9107
9108
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9109
0
        return (NULL);
9110
9111
0
    attr = xmlSchemaGetPropNode(node, "ref");
9112
0
    if (attr == NULL) {
9113
0
  xmlSchemaPMissingAttrErr(ctxt,
9114
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9115
0
      NULL, node, "ref", NULL);
9116
0
  return (NULL);
9117
0
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9118
0
  attr, &refNs, &ref) != 0) {
9119
0
  return (NULL);
9120
0
    }
9121
0
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9122
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9123
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9124
0
  "(xs:nonNegativeInteger | unbounded)");
9125
    /*
9126
    * Check for illegal attributes.
9127
    */
9128
0
    attr = node->properties;
9129
0
    while (attr != NULL) {
9130
0
  if (attr->ns == NULL) {
9131
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9132
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9133
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9134
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9135
0
    xmlSchemaPIllegalAttrErr(ctxt,
9136
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9137
0
      }
9138
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9139
0
      xmlSchemaPIllegalAttrErr(ctxt,
9140
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9141
0
  }
9142
0
  attr = attr->next;
9143
0
    }
9144
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9145
0
    item = xmlSchemaAddParticle(ctxt, node, min, max);
9146
0
    if (item == NULL)
9147
0
  return (NULL);
9148
    /*
9149
    * Create a qname-reference and set as the term; it will be substituted
9150
    * for the model group after the reference has been resolved.
9151
    */
9152
0
    item->children = (xmlSchemaTreeItemPtr)
9153
0
  xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9154
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9155
    /*
9156
    * And now for the children...
9157
    */
9158
0
    child = node->children;
9159
    /* TODO: Is annotation even allowed for a model group reference? */
9160
0
    if (IS_SCHEMA(child, "annotation")) {
9161
  /*
9162
  * TODO: What to do exactly with the annotation?
9163
  */
9164
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9165
0
  child = child->next;
9166
0
    }
9167
0
    if (child != NULL) {
9168
0
  xmlSchemaPContentErr(ctxt,
9169
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9170
0
      NULL, node, child, NULL,
9171
0
      "(annotation?)");
9172
0
    }
9173
    /*
9174
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
9175
    */
9176
0
    if ((min == 0) && (max == 0))
9177
0
  return (NULL);
9178
9179
0
    return ((xmlSchemaTreeItemPtr) item);
9180
0
}
9181
9182
/**
9183
 * Parses a XML schema model group definition.
9184
 *
9185
 * Note that the constraint src-redefine (6.2) can't be applied until
9186
 * references have been resolved. So we will do this at the
9187
 * component fixup level.
9188
 *
9189
 * *WARNING* this interface is highly subject to change
9190
 *
9191
 * @param ctxt  a schema validation context
9192
 * @param schema  the schema being built
9193
 * @param node  a subtree containing XML Schema information
9194
 * @returns -1 in case of error, 0 if the declaration is improper and
9195
 *         1 in case of success.
9196
 */
9197
static xmlSchemaModelGroupDefPtr
9198
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9199
           xmlSchemaPtr schema,
9200
           xmlNodePtr node)
9201
0
{
9202
0
    xmlSchemaModelGroupDefPtr item;
9203
0
    xmlNodePtr child = NULL;
9204
0
    xmlAttrPtr attr;
9205
0
    const xmlChar *name;
9206
9207
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9208
0
        return (NULL);
9209
9210
0
    attr = xmlSchemaGetPropNode(node, "name");
9211
0
    if (attr == NULL) {
9212
0
  xmlSchemaPMissingAttrErr(ctxt,
9213
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9214
0
      NULL, node,
9215
0
      "name", NULL);
9216
0
  return (NULL);
9217
0
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9218
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9219
0
  return (NULL);
9220
0
    }
9221
0
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9222
0
  ctxt->targetNamespace, node);
9223
0
    if (item == NULL)
9224
0
  return (NULL);
9225
    /*
9226
    * Check for illegal attributes.
9227
    */
9228
0
    attr = node->properties;
9229
0
    while (attr != NULL) {
9230
0
  if (attr->ns == NULL) {
9231
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9232
0
    (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9233
0
    xmlSchemaPIllegalAttrErr(ctxt,
9234
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9235
0
      }
9236
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9237
0
      xmlSchemaPIllegalAttrErr(ctxt,
9238
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9239
0
  }
9240
0
  attr = attr->next;
9241
0
    }
9242
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9243
    /*
9244
    * And now for the children...
9245
    */
9246
0
    child = node->children;
9247
0
    if (IS_SCHEMA(child, "annotation")) {
9248
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9249
0
  child = child->next;
9250
0
    }
9251
0
    if (IS_SCHEMA(child, "all")) {
9252
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9253
0
      XML_SCHEMA_TYPE_ALL, 0);
9254
0
  child = child->next;
9255
0
    } else if (IS_SCHEMA(child, "choice")) {
9256
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9257
0
      XML_SCHEMA_TYPE_CHOICE, 0);
9258
0
  child = child->next;
9259
0
    } else if (IS_SCHEMA(child, "sequence")) {
9260
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9261
0
      XML_SCHEMA_TYPE_SEQUENCE, 0);
9262
0
  child = child->next;
9263
0
    }
9264
9265
9266
9267
0
    if (child != NULL) {
9268
0
  xmlSchemaPContentErr(ctxt,
9269
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9270
0
      NULL, node, child, NULL,
9271
0
      "(annotation?, (all | choice | sequence)?)");
9272
0
    }
9273
0
    return (item);
9274
0
}
9275
9276
/**
9277
 * removes unwanted nodes in a schemas document tree
9278
 *
9279
 * @param ctxt  a schema validation context
9280
 * @param root  the root of the document.
9281
 */
9282
static void
9283
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9284
0
{
9285
0
    xmlNodePtr delete, cur;
9286
9287
0
    if ((ctxt == NULL) || (root == NULL)) return;
9288
9289
    /*
9290
     * Remove all the blank text nodes
9291
     */
9292
0
    delete = NULL;
9293
0
    cur = root;
9294
0
    while (cur != NULL) {
9295
0
        if (delete != NULL) {
9296
0
            xmlUnlinkNode(delete);
9297
0
            xmlFreeNode(delete);
9298
0
            delete = NULL;
9299
0
        }
9300
0
        if (cur->type == XML_TEXT_NODE) {
9301
0
            if (IS_BLANK_NODE(cur)) {
9302
0
                if (xmlNodeGetSpacePreserve(cur) != 1) {
9303
0
                    delete = cur;
9304
0
                }
9305
0
            }
9306
0
        } else if ((cur->type != XML_ELEMENT_NODE) &&
9307
0
                   (cur->type != XML_CDATA_SECTION_NODE)) {
9308
0
            delete = cur;
9309
0
            goto skip_children;
9310
0
        }
9311
9312
        /*
9313
         * Skip to next node
9314
         */
9315
0
        if (cur->children != NULL) {
9316
0
            if ((cur->children->type != XML_ENTITY_DECL) &&
9317
0
                (cur->children->type != XML_ENTITY_REF_NODE) &&
9318
0
                (cur->children->type != XML_ENTITY_NODE)) {
9319
0
                cur = cur->children;
9320
0
                continue;
9321
0
            }
9322
0
        }
9323
0
      skip_children:
9324
0
        if (cur->next != NULL) {
9325
0
            cur = cur->next;
9326
0
            continue;
9327
0
        }
9328
9329
0
        do {
9330
0
            cur = cur->parent;
9331
0
            if (cur == NULL)
9332
0
                break;
9333
0
            if (cur == root) {
9334
0
                cur = NULL;
9335
0
                break;
9336
0
            }
9337
0
            if (cur->next != NULL) {
9338
0
                cur = cur->next;
9339
0
                break;
9340
0
            }
9341
0
        } while (cur != NULL);
9342
0
    }
9343
0
    if (delete != NULL) {
9344
0
        xmlUnlinkNode(delete);
9345
0
        xmlFreeNode(delete);
9346
0
        delete = NULL;
9347
0
    }
9348
0
}
9349
9350
9351
static void
9352
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9353
0
{
9354
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9355
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9356
9357
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9358
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9359
9360
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9361
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9362
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9363
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9364
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9365
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9366
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9367
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9368
9369
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9370
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9371
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9372
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9373
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9374
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9375
0
}
9376
9377
static int
9378
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9379
           xmlSchemaPtr schema,
9380
           xmlNodePtr node)
9381
0
{
9382
0
    xmlAttrPtr attr;
9383
0
    const xmlChar *val;
9384
0
    int res = 0, oldErrs = ctxt->nberrors;
9385
9386
    /*
9387
    * Those flags should be moved to the parser context flags,
9388
    * since they are not visible at the component level. I.e.
9389
    * they are used if processing schema *documents* only.
9390
    */
9391
0
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9392
0
    HFAILURE;
9393
9394
    /*
9395
    * Since the version is of type xs:token, we won't bother to
9396
    * check it.
9397
    */
9398
    /* REMOVED:
9399
    attr = xmlSchemaGetPropNode(node, "version");
9400
    if (attr != NULL) {
9401
  res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9402
      xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9403
  HFAILURE;
9404
    }
9405
    */
9406
0
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
9407
0
    if (attr != NULL) {
9408
0
  res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9409
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9410
0
  HFAILURE;
9411
0
  if (res != 0) {
9412
0
      ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9413
0
      goto exit;
9414
0
  }
9415
0
    }
9416
0
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9417
0
    if (attr != NULL) {
9418
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9419
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9420
0
      XML_SCHEMAS_QUALIF_ELEM);
9421
0
  HFAILURE;
9422
0
  if (res != 0) {
9423
0
      xmlSchemaPSimpleTypeErr(ctxt,
9424
0
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9425
0
    NULL, (xmlNodePtr) attr, NULL,
9426
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9427
0
  }
9428
0
    }
9429
0
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9430
0
    if (attr != NULL) {
9431
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9432
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9433
0
      XML_SCHEMAS_QUALIF_ATTR);
9434
0
  HFAILURE;
9435
0
  if (res != 0) {
9436
0
      xmlSchemaPSimpleTypeErr(ctxt,
9437
0
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9438
0
    NULL, (xmlNodePtr) attr, NULL,
9439
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9440
0
  }
9441
0
    }
9442
0
    attr = xmlSchemaGetPropNode(node, "finalDefault");
9443
0
    if (attr != NULL) {
9444
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9445
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9446
0
      XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9447
0
      XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9448
0
      -1,
9449
0
      XML_SCHEMAS_FINAL_DEFAULT_LIST,
9450
0
      XML_SCHEMAS_FINAL_DEFAULT_UNION);
9451
0
  HFAILURE;
9452
0
  if (res != 0) {
9453
0
      xmlSchemaPSimpleTypeErr(ctxt,
9454
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9455
0
    NULL, (xmlNodePtr) attr, NULL,
9456
0
    "(#all | List of (extension | restriction | list | union))",
9457
0
    val, NULL, NULL, NULL);
9458
0
  }
9459
0
    }
9460
0
    attr = xmlSchemaGetPropNode(node, "blockDefault");
9461
0
    if (attr != NULL) {
9462
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9463
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9464
0
      XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9465
0
      XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9466
0
      XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9467
0
  HFAILURE;
9468
0
  if (res != 0) {
9469
0
      xmlSchemaPSimpleTypeErr(ctxt,
9470
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9471
0
    NULL, (xmlNodePtr) attr, NULL,
9472
0
    "(#all | List of (extension | restriction | substitution))",
9473
0
    val, NULL, NULL, NULL);
9474
0
  }
9475
0
    }
9476
9477
0
exit:
9478
0
    if (oldErrs != ctxt->nberrors)
9479
0
  res = ctxt->err;
9480
0
    return(res);
9481
0
exit_failure:
9482
0
    return(-1);
9483
0
}
9484
9485
/**
9486
 * @param ctxt  a schema validation context
9487
 * @param schema  the schemas
9488
 * @param nodes  the list of top level nodes
9489
 * @returns the internal XML Schema structure built from the resource or
9490
 *         NULL in case of error
9491
 */
9492
static int
9493
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9494
                             xmlSchemaPtr schema, xmlNodePtr nodes)
9495
0
{
9496
0
    xmlNodePtr child;
9497
0
    xmlSchemaAnnotPtr annot;
9498
0
    int res = 0, oldErrs, tmpOldErrs;
9499
9500
0
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9501
0
        return(-1);
9502
9503
0
    oldErrs = ctxt->nberrors;
9504
0
    child = nodes;
9505
0
    while ((IS_SCHEMA(child, "include")) ||
9506
0
     (IS_SCHEMA(child, "import")) ||
9507
0
     (IS_SCHEMA(child, "redefine")) ||
9508
0
     (IS_SCHEMA(child, "annotation"))) {
9509
0
  if (IS_SCHEMA(child, "annotation")) {
9510
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9511
0
      if (schema->annot == NULL)
9512
0
    schema->annot = annot;
9513
0
      else
9514
0
    xmlSchemaFreeAnnot(annot);
9515
0
  } else if (IS_SCHEMA(child, "import")) {
9516
0
      tmpOldErrs = ctxt->nberrors;
9517
0
      res = xmlSchemaParseImport(ctxt, schema, child);
9518
0
      HFAILURE;
9519
0
      HSTOP(ctxt);
9520
0
      if (tmpOldErrs != ctxt->nberrors)
9521
0
    goto exit;
9522
0
  } else if (IS_SCHEMA(child, "include")) {
9523
0
      tmpOldErrs = ctxt->nberrors;
9524
0
      res = xmlSchemaParseInclude(ctxt, schema, child);
9525
0
      HFAILURE;
9526
0
      HSTOP(ctxt);
9527
0
      if (tmpOldErrs != ctxt->nberrors)
9528
0
    goto exit;
9529
0
  } else if (IS_SCHEMA(child, "redefine")) {
9530
0
      tmpOldErrs = ctxt->nberrors;
9531
0
      res = xmlSchemaParseRedefine(ctxt, schema, child);
9532
0
      HFAILURE;
9533
0
      HSTOP(ctxt);
9534
0
      if (tmpOldErrs != ctxt->nberrors)
9535
0
    goto exit;
9536
0
  }
9537
0
  child = child->next;
9538
0
    }
9539
    /*
9540
    * URGENT TODO: Change the functions to return int results.
9541
    * We need especially to catch internal errors.
9542
    */
9543
0
    while (child != NULL) {
9544
0
  if (IS_SCHEMA(child, "complexType")) {
9545
0
      xmlSchemaParseComplexType(ctxt, schema, child, 1);
9546
0
      child = child->next;
9547
0
  } else if (IS_SCHEMA(child, "simpleType")) {
9548
0
      xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9549
0
      child = child->next;
9550
0
  } else if (IS_SCHEMA(child, "element")) {
9551
0
      xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9552
0
      child = child->next;
9553
0
  } else if (IS_SCHEMA(child, "attribute")) {
9554
0
      xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9555
0
      child = child->next;
9556
0
  } else if (IS_SCHEMA(child, "attributeGroup")) {
9557
0
      xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9558
0
      child = child->next;
9559
0
  } else if (IS_SCHEMA(child, "group")) {
9560
0
      xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9561
0
      child = child->next;
9562
0
  } else if (IS_SCHEMA(child, "notation")) {
9563
0
      xmlSchemaParseNotation(ctxt, schema, child);
9564
0
      child = child->next;
9565
0
  } else {
9566
0
      xmlSchemaPContentErr(ctxt,
9567
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9568
0
    NULL, child->parent, child,
9569
0
    NULL, "((include | import | redefine | annotation)*, "
9570
0
    "(((simpleType | complexType | group | attributeGroup) "
9571
0
    "| element | attribute | notation), annotation*)*)");
9572
0
      child = child->next;
9573
0
  }
9574
0
  while (IS_SCHEMA(child, "annotation")) {
9575
      /*
9576
      * TODO: We should add all annotations.
9577
      */
9578
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9579
0
      if (schema->annot == NULL)
9580
0
    schema->annot = annot;
9581
0
      else
9582
0
    xmlSchemaFreeAnnot(annot);
9583
0
      child = child->next;
9584
0
  }
9585
0
    }
9586
0
exit:
9587
0
    ctxt->ctxtType = NULL;
9588
0
    if (oldErrs != ctxt->nberrors)
9589
0
  res = ctxt->err;
9590
0
    return(res);
9591
0
exit_failure:
9592
0
    return(-1);
9593
0
}
9594
9595
static xmlSchemaSchemaRelationPtr
9596
xmlSchemaSchemaRelationCreate(void)
9597
0
{
9598
0
    xmlSchemaSchemaRelationPtr ret;
9599
9600
0
    ret = (xmlSchemaSchemaRelationPtr)
9601
0
  xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9602
0
    if (ret == NULL) {
9603
0
  xmlSchemaPErrMemory(NULL);
9604
0
  return(NULL);
9605
0
    }
9606
0
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9607
0
    return(ret);
9608
0
}
9609
9610
#if 0
9611
static void
9612
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9613
{
9614
    xmlFree(rel);
9615
}
9616
#endif
9617
9618
static void
9619
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9620
0
{
9621
0
    xmlSchemaRedefPtr prev;
9622
9623
0
    while (redef != NULL) {
9624
0
  prev = redef;
9625
0
  redef = redef->next;
9626
0
  xmlFree(prev);
9627
0
    }
9628
0
}
9629
9630
static void
9631
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9632
0
{
9633
    /*
9634
    * After the construction context has been freed, there will be
9635
    * no schema graph available any more. Only the schema buckets
9636
    * will stay alive, which are put into the "schemasImports" and
9637
    * "includes" slots of the xmlSchema.
9638
    */
9639
0
    if (con->buckets != NULL)
9640
0
  xmlSchemaItemListFree(con->buckets);
9641
0
    if (con->pending != NULL)
9642
0
  xmlSchemaItemListFree(con->pending);
9643
0
    if (con->substGroups != NULL)
9644
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9645
0
    if (con->redefs != NULL)
9646
0
  xmlSchemaRedefListFree(con->redefs);
9647
0
    if (con->dict != NULL)
9648
0
  xmlDictFree(con->dict);
9649
0
    xmlFree(con);
9650
0
}
9651
9652
static xmlSchemaConstructionCtxtPtr
9653
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9654
0
{
9655
0
    xmlSchemaConstructionCtxtPtr ret;
9656
9657
0
    ret = (xmlSchemaConstructionCtxtPtr)
9658
0
  xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9659
0
    if (ret == NULL) {
9660
0
        xmlSchemaPErrMemory(NULL);
9661
0
        return (NULL);
9662
0
    }
9663
0
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9664
9665
0
    ret->buckets = xmlSchemaItemListCreate();
9666
0
    if (ret->buckets == NULL) {
9667
0
  xmlSchemaPErrMemory(NULL);
9668
0
  xmlFree(ret);
9669
0
        return (NULL);
9670
0
    }
9671
0
    ret->pending = xmlSchemaItemListCreate();
9672
0
    if (ret->pending == NULL) {
9673
0
  xmlSchemaPErrMemory(NULL);
9674
0
  xmlSchemaConstructionCtxtFree(ret);
9675
0
        return (NULL);
9676
0
    }
9677
0
    ret->dict = dict;
9678
0
    xmlDictReference(dict);
9679
0
    return(ret);
9680
0
}
9681
9682
static xmlSchemaParserCtxtPtr
9683
xmlSchemaParserCtxtCreate(void)
9684
0
{
9685
0
    xmlSchemaParserCtxtPtr ret;
9686
9687
0
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9688
0
    if (ret == NULL) {
9689
0
        xmlSchemaPErrMemory(NULL);
9690
0
        return (NULL);
9691
0
    }
9692
0
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9693
0
    ret->type = XML_SCHEMA_CTXT_PARSER;
9694
0
    ret->attrProhibs = xmlSchemaItemListCreate();
9695
0
    if (ret->attrProhibs == NULL) {
9696
0
  xmlFree(ret);
9697
0
  return(NULL);
9698
0
    }
9699
0
    return(ret);
9700
0
}
9701
9702
/**
9703
 * Create an XML Schemas parse context for that file/resource expected
9704
 * to contain an XML Schemas file.
9705
 *
9706
 * @param URL  the location of the schema
9707
 * @param dict  the dictionary to be used
9708
 * @returns the parser context or NULL in case of error
9709
 */
9710
static xmlSchemaParserCtxtPtr
9711
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9712
0
{
9713
0
    xmlSchemaParserCtxtPtr ret;
9714
9715
0
    ret = xmlSchemaParserCtxtCreate();
9716
0
    if (ret == NULL)
9717
0
        return (NULL);
9718
0
    ret->dict = dict;
9719
0
    xmlDictReference(dict);
9720
0
    if (URL != NULL)
9721
0
  ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9722
0
    return (ret);
9723
0
}
9724
9725
static int
9726
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9727
0
{
9728
0
    if (vctxt->pctxt == NULL) {
9729
0
        if (vctxt->schema != NULL)
9730
0
      vctxt->pctxt =
9731
0
    xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9732
0
  else
9733
0
      vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9734
0
  if (vctxt->pctxt == NULL) {
9735
0
      VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
9736
0
    "failed to create a temp. parser context");
9737
0
      return (-1);
9738
0
  }
9739
  /* TODO: Pass user data. */
9740
0
  xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9741
0
      vctxt->warning, vctxt->errCtxt);
9742
0
  xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9743
0
      vctxt->errCtxt);
9744
0
    }
9745
0
    return (0);
9746
0
}
9747
9748
/**
9749
 * @param pctxt  the schema parser context
9750
 * @param schemaLocation  the URI of the schema document
9751
 * @returns a schema bucket if it was already parsed from
9752
 *         `schemaLocation`, NULL otherwise.
9753
 */
9754
static xmlSchemaBucketPtr
9755
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9756
          const xmlChar *schemaLocation)
9757
0
{
9758
0
    xmlSchemaBucketPtr cur;
9759
0
    xmlSchemaItemListPtr list;
9760
9761
0
    list = pctxt->constructor->buckets;
9762
0
    if (list->nbItems == 0)
9763
0
  return(NULL);
9764
0
    else {
9765
0
  int i;
9766
0
  for (i = 0; i < list->nbItems; i++) {
9767
0
      cur = (xmlSchemaBucketPtr) list->items[i];
9768
      /* Pointer comparison! */
9769
0
      if (cur->schemaLocation == schemaLocation)
9770
0
    return(cur);
9771
0
  }
9772
0
    }
9773
0
    return(NULL);
9774
0
}
9775
9776
static xmlSchemaBucketPtr
9777
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9778
             const xmlChar *schemaLocation,
9779
             const xmlChar *targetNamespace)
9780
0
{
9781
0
    xmlSchemaBucketPtr cur;
9782
0
    xmlSchemaItemListPtr list;
9783
9784
0
    list = pctxt->constructor->buckets;
9785
0
    if (list->nbItems == 0)
9786
0
  return(NULL);
9787
0
    else {
9788
0
  int i;
9789
0
  for (i = 0; i < list->nbItems; i++) {
9790
0
      cur = (xmlSchemaBucketPtr) list->items[i];
9791
      /* Pointer comparison! */
9792
0
      if ((cur->origTargetNamespace == NULL) &&
9793
0
    (cur->schemaLocation == schemaLocation) &&
9794
0
    (cur->targetNamespace == targetNamespace))
9795
0
    return(cur);
9796
0
  }
9797
0
    }
9798
0
    return(NULL);
9799
0
}
9800
9801
9802
#define IS_BAD_SCHEMA_DOC(b) \
9803
0
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
9804
9805
static xmlSchemaBucketPtr
9806
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
9807
         const xmlChar *targetNamespace,
9808
         int imported)
9809
0
{
9810
0
    xmlSchemaBucketPtr cur;
9811
0
    xmlSchemaItemListPtr list;
9812
9813
0
    list = pctxt->constructor->buckets;
9814
0
    if (list->nbItems == 0)
9815
0
  return(NULL);
9816
0
    else {
9817
0
  int i;
9818
0
  for (i = 0; i < list->nbItems; i++) {
9819
0
      cur = (xmlSchemaBucketPtr) list->items[i];
9820
0
      if ((! IS_BAD_SCHEMA_DOC(cur)) &&
9821
0
    (cur->origTargetNamespace == targetNamespace) &&
9822
0
    ((imported && cur->imported) ||
9823
0
     ((!imported) && (!cur->imported))))
9824
0
    return(cur);
9825
0
  }
9826
0
    }
9827
0
    return(NULL);
9828
0
}
9829
9830
static int
9831
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
9832
         xmlSchemaPtr schema,
9833
         xmlSchemaBucketPtr bucket)
9834
0
{
9835
0
    int oldFlags;
9836
0
    xmlDocPtr oldDoc;
9837
0
    xmlNodePtr node;
9838
0
    int ret, oldErrs;
9839
0
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
9840
9841
    /*
9842
    * Save old values; reset the *main* schema.
9843
    * URGENT TODO: This is not good; move the per-document information
9844
    * to the parser. Get rid of passing the main schema to the
9845
    * parsing functions.
9846
    */
9847
0
    oldFlags = schema->flags;
9848
0
    oldDoc = schema->doc;
9849
0
    if (schema->flags != 0)
9850
0
  xmlSchemaClearSchemaDefaults(schema);
9851
0
    schema->doc = bucket->doc;
9852
0
    pctxt->schema = schema;
9853
    /*
9854
    * Keep the current target namespace on the parser *not* on the
9855
    * main schema.
9856
    */
9857
0
    pctxt->targetNamespace = bucket->targetNamespace;
9858
0
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
9859
9860
0
    if ((bucket->targetNamespace != NULL) &&
9861
0
  xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
9862
  /*
9863
  * We are parsing the schema for schemas!
9864
  */
9865
0
  pctxt->isS4S = 1;
9866
0
    }
9867
    /* Mark it as parsed, even if parsing fails. */
9868
0
    bucket->parsed++;
9869
    /* Compile the schema doc. */
9870
0
    node = xmlDocGetRootElement(bucket->doc);
9871
0
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
9872
0
    if (ret != 0)
9873
0
  goto exit;
9874
    /* An empty schema; just get out. */
9875
0
    if (node->children == NULL)
9876
0
  goto exit;
9877
0
    oldErrs = pctxt->nberrors;
9878
0
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
9879
0
    if (ret != 0)
9880
0
  goto exit;
9881
    /*
9882
    * TODO: Not nice, but I'm not 100% sure we will get always an error
9883
    * as a result of the above functions; so better rely on pctxt->err
9884
    * as well.
9885
    */
9886
0
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
9887
0
  ret = pctxt->err;
9888
0
  goto exit;
9889
0
    }
9890
9891
0
exit:
9892
0
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
9893
    /* Restore schema values. */
9894
0
    schema->doc = oldDoc;
9895
0
    schema->flags = oldFlags;
9896
0
    return(ret);
9897
0
}
9898
9899
static int
9900
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
9901
         xmlSchemaPtr schema,
9902
         xmlSchemaBucketPtr bucket)
9903
0
{
9904
0
    xmlSchemaParserCtxtPtr newpctxt;
9905
0
    int res = 0;
9906
9907
0
    if (bucket == NULL)
9908
0
  return(0);
9909
0
    if (bucket->parsed) {
9910
0
  PERROR_INT("xmlSchemaParseNewDoc",
9911
0
      "reparsing a schema doc");
9912
0
  return(-1);
9913
0
    }
9914
0
    if (bucket->doc == NULL) {
9915
0
  PERROR_INT("xmlSchemaParseNewDoc",
9916
0
      "parsing a schema doc, but there's no doc");
9917
0
  return(-1);
9918
0
    }
9919
0
    if (pctxt->constructor == NULL) {
9920
0
  PERROR_INT("xmlSchemaParseNewDoc",
9921
0
      "no constructor");
9922
0
  return(-1);
9923
0
    }
9924
    /* Create and init the temporary parser context. */
9925
0
    newpctxt = xmlSchemaNewParserCtxtUseDict(
9926
0
  (const char *) bucket->schemaLocation, pctxt->dict);
9927
0
    if (newpctxt == NULL)
9928
0
  return(-1);
9929
0
    newpctxt->constructor = pctxt->constructor;
9930
    /*
9931
    * TODO: Can we avoid that the parser knows about the main schema?
9932
    * It would be better if he knows about the current schema bucket
9933
    * only.
9934
    */
9935
0
    newpctxt->schema = schema;
9936
0
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
9937
0
  pctxt->errCtxt);
9938
0
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
9939
0
  pctxt->errCtxt);
9940
0
    newpctxt->counter = pctxt->counter;
9941
9942
9943
0
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
9944
9945
    /* Channel back errors and cleanup the temporary parser context. */
9946
0
    if (res != 0)
9947
0
  pctxt->err = res;
9948
0
    pctxt->nberrors += newpctxt->nberrors;
9949
0
    pctxt->counter = newpctxt->counter;
9950
0
    newpctxt->constructor = NULL;
9951
    /* Free the parser context. */
9952
0
    xmlSchemaFreeParserCtxt(newpctxt);
9953
0
    return(res);
9954
0
}
9955
9956
static void
9957
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
9958
        xmlSchemaSchemaRelationPtr rel)
9959
0
{
9960
0
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
9961
9962
0
    if (cur == NULL) {
9963
0
  bucket->relations = rel;
9964
0
  return;
9965
0
    }
9966
0
    while (cur->next != NULL)
9967
0
  cur = cur->next;
9968
0
    cur->next = rel;
9969
0
}
9970
9971
9972
static const xmlChar *
9973
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
9974
        xmlNodePtr ctxtNode,
9975
        const xmlChar *baseURI)
9976
0
{
9977
    /*
9978
    * Build an absolute location URI.
9979
    */
9980
0
    if (location != NULL) {
9981
0
  xmlChar *URI;
9982
0
  const xmlChar *ret;
9983
9984
0
  if (ctxtNode != NULL) {
9985
0
      xmlChar *base;
9986
9987
0
      base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
9988
0
      if (base == NULL) {
9989
0
    URI = xmlBuildURI(location, ctxtNode->doc->URL);
9990
0
      } else {
9991
0
    URI = xmlBuildURI(location, base);
9992
0
    xmlFree(base);
9993
0
      }
9994
0
  } else if (baseURI != NULL) {
9995
0
      URI = xmlBuildURI(location, baseURI);
9996
0
  } else {
9997
0
      return(location);
9998
0
  }
9999
0
  if (URI != NULL) {
10000
0
      ret = xmlDictLookup(dict, URI, -1);
10001
0
      xmlFree(URI);
10002
0
      return(ret);
10003
0
  }
10004
0
    }
10005
0
    return(NULL);
10006
0
}
10007
10008
10009
10010
/**
10011
 * Parse an included (and to-be-redefined) XML schema document.
10012
 *
10013
 * @param pctxt  a schema validation context
10014
 * @param type  import or include or redefine
10015
 * @param schemaLocation  schema location
10016
 * @param schemaDoc  schema document
10017
 * @param schemaBuffer  document buffer
10018
 * @param schemaBufferLen  buffer size
10019
 * @param invokingNode  invoking node
10020
 * @param sourceTargetNamespace  source target namespace
10021
 * @param importNamespace  import namespace
10022
 * @param bucket  bucket
10023
 * @returns 0 on success, a positive error code on errors and
10024
 *         -1 in case of an internal or API error.
10025
 */
10026
10027
static int
10028
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10029
    int type,
10030
    const xmlChar *schemaLocation,
10031
    xmlDocPtr schemaDoc,
10032
    const char *schemaBuffer,
10033
    int schemaBufferLen,
10034
    xmlNodePtr invokingNode,
10035
    const xmlChar *sourceTargetNamespace,
10036
    const xmlChar *importNamespace,
10037
    xmlSchemaBucketPtr *bucket)
10038
0
{
10039
0
    const xmlChar *targetNamespace = NULL;
10040
0
    xmlSchemaSchemaRelationPtr relation = NULL;
10041
0
    xmlDocPtr doc = NULL;
10042
0
    int res = 0, err = 0, located = 0, preserveDoc = 0;
10043
0
    xmlSchemaBucketPtr bkt = NULL;
10044
10045
0
    if (bucket != NULL)
10046
0
  *bucket = NULL;
10047
10048
0
    switch (type) {
10049
0
  case XML_SCHEMA_SCHEMA_IMPORT:
10050
0
  case XML_SCHEMA_SCHEMA_MAIN:
10051
0
      err = XML_SCHEMAP_SRC_IMPORT;
10052
0
      break;
10053
0
  case XML_SCHEMA_SCHEMA_INCLUDE:
10054
0
      err = XML_SCHEMAP_SRC_INCLUDE;
10055
0
      break;
10056
0
  case XML_SCHEMA_SCHEMA_REDEFINE:
10057
0
      err = XML_SCHEMAP_SRC_REDEFINE;
10058
0
      break;
10059
0
    }
10060
10061
10062
    /* Special handling for the main schema:
10063
    * skip the location and relation logic and just parse the doc.
10064
    * We need just a bucket to be returned in this case.
10065
    */
10066
0
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10067
0
  goto doc_load;
10068
10069
    /* Note that we expect the location to be an absolute URI. */
10070
0
    if (schemaLocation != NULL) {
10071
0
  bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10072
0
  if ((bkt != NULL) &&
10073
0
      (pctxt->constructor->bucket == bkt)) {
10074
      /* Report self-imports/inclusions/redefinitions. */
10075
10076
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10077
0
    invokingNode, NULL,
10078
0
    "The schema must not import/include/redefine itself",
10079
0
    NULL, NULL);
10080
0
      goto exit;
10081
0
  }
10082
0
    }
10083
    /*
10084
    * Create a relation for the graph of schemas.
10085
    */
10086
0
    relation = xmlSchemaSchemaRelationCreate();
10087
0
    if (relation == NULL)
10088
0
  return(-1);
10089
0
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10090
0
  relation);
10091
0
    relation->type = type;
10092
10093
    /*
10094
    * Save the namespace import information.
10095
    */
10096
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10097
0
  relation->importNamespace = importNamespace;
10098
0
  if (schemaLocation == NULL) {
10099
      /*
10100
      * No location; this is just an import of the namespace.
10101
      * Note that we don't assign a bucket to the relation
10102
      * in this case.
10103
      */
10104
0
      goto exit;
10105
0
  }
10106
0
  targetNamespace = importNamespace;
10107
0
    }
10108
10109
    /* Did we already fetch the doc? */
10110
0
    if (bkt != NULL) {
10111
0
  if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10112
      /*
10113
      * We included/redefined and then try to import a schema,
10114
      * but the new location provided for import was different.
10115
      */
10116
0
      if (schemaLocation == NULL)
10117
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10118
0
      if (!xmlStrEqual(schemaLocation,
10119
0
    bkt->schemaLocation)) {
10120
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10121
0
        invokingNode, NULL,
10122
0
        "The schema document '%s' cannot be imported, since "
10123
0
        "it was already included or redefined",
10124
0
        schemaLocation, NULL);
10125
0
    goto exit;
10126
0
      }
10127
0
  } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10128
      /*
10129
      * We imported and then try to include/redefine a schema,
10130
      * but the new location provided for the include/redefine
10131
      * was different.
10132
      */
10133
0
      if (schemaLocation == NULL)
10134
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10135
0
      if (!xmlStrEqual(schemaLocation,
10136
0
    bkt->schemaLocation)) {
10137
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10138
0
        invokingNode, NULL,
10139
0
        "The schema document '%s' cannot be included or "
10140
0
        "redefined, since it was already imported",
10141
0
        schemaLocation, NULL);
10142
0
    goto exit;
10143
0
      }
10144
0
  }
10145
0
    }
10146
10147
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10148
  /*
10149
  * Given that the schemaLocation [attribute] is only a hint, it is open
10150
  * to applications to ignore all but the first <import> for a given
10151
  * namespace, regardless of the `actual value` of schemaLocation, but
10152
  * such a strategy risks missing useful information when new
10153
  * schemaLocations are offered.
10154
  *
10155
  * We will use the first <import> that comes with a location.
10156
  * Further <import>s *with* a location, will result in an error.
10157
  * TODO: Better would be to just report a warning here, but
10158
  * we'll try it this way until someone complains.
10159
  *
10160
  * Schema Document Location Strategy:
10161
  * 3 Based on the namespace name, identify an existing schema document,
10162
  * either as a resource which is an XML document or a <schema> element
10163
  * information item, in some local schema repository;
10164
  * 5 Attempt to resolve the namespace name to locate such a resource.
10165
  *
10166
  * NOTE: (3) and (5) are not supported.
10167
  */
10168
0
  if (bkt != NULL) {
10169
0
      relation->bucket = bkt;
10170
0
      goto exit;
10171
0
  }
10172
0
  bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10173
0
      importNamespace, 1);
10174
10175
0
  if (bkt != NULL) {
10176
0
      relation->bucket = bkt;
10177
0
      if (bkt->schemaLocation == NULL) {
10178
    /* First given location of the schema; load the doc. */
10179
0
    bkt->schemaLocation = schemaLocation;
10180
0
      } else {
10181
0
    if (!xmlStrEqual(schemaLocation,
10182
0
        bkt->schemaLocation)) {
10183
        /*
10184
        * Additional location given; just skip it.
10185
        * URGENT TODO: We should report a warning here.
10186
        * res = XML_SCHEMAP_SRC_IMPORT;
10187
        */
10188
0
        if (schemaLocation == NULL)
10189
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10190
10191
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10192
0
      XML_SCHEMAP_WARN_SKIP_SCHEMA,
10193
0
      invokingNode, NULL,
10194
0
      "Skipping import of schema located at '%s' for the "
10195
0
      "namespace '%s', since this namespace was already "
10196
0
      "imported with the schema located at '%s'",
10197
0
      schemaLocation, importNamespace, bkt->schemaLocation);
10198
0
    }
10199
0
    goto exit;
10200
0
      }
10201
0
  }
10202
  /*
10203
  * No bucket + first location: load the doc and create a
10204
  * bucket.
10205
  */
10206
0
    } else {
10207
  /* <include> and <redefine> */
10208
0
  if (bkt != NULL) {
10209
10210
0
      if ((bkt->origTargetNamespace == NULL) &&
10211
0
    (bkt->targetNamespace != sourceTargetNamespace)) {
10212
0
    xmlSchemaBucketPtr chamel;
10213
10214
    /*
10215
    * Chameleon include/redefine: skip loading only if it was
10216
    * already build for the targetNamespace of the including
10217
    * schema.
10218
    */
10219
    /*
10220
    * URGENT TODO: If the schema is a chameleon-include then copy
10221
    * the components into the including schema and modify the
10222
    * targetNamespace of those components, do nothing otherwise.
10223
    * NOTE: This is currently worked-around by compiling the
10224
    * chameleon for every distinct including targetNamespace; thus
10225
    * not performant at the moment.
10226
    * TODO: Check when the namespace in wildcards for chameleons
10227
    * needs to be converted: before we built wildcard intersections
10228
    * or after.
10229
    *   Answer: after!
10230
    */
10231
0
    chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10232
0
        schemaLocation, sourceTargetNamespace);
10233
0
    if (chamel != NULL) {
10234
        /* A fitting chameleon was already parsed; NOP. */
10235
0
        relation->bucket = chamel;
10236
0
        goto exit;
10237
0
    }
10238
    /*
10239
    * We need to parse the chameleon again for a different
10240
    * targetNamespace.
10241
    * CHAMELEON TODO: Optimize this by only parsing the
10242
    * chameleon once, and then copying the components to
10243
    * the new targetNamespace.
10244
    */
10245
0
    bkt = NULL;
10246
0
      } else {
10247
0
    relation->bucket = bkt;
10248
0
    goto exit;
10249
0
      }
10250
0
  }
10251
0
    }
10252
0
    if ((bkt != NULL) && (bkt->doc != NULL)) {
10253
0
  PERROR_INT("xmlSchemaAddSchemaDoc",
10254
0
      "trying to load a schema doc, but a doc is already "
10255
0
      "assigned to the schema bucket");
10256
0
  goto exit_failure;
10257
0
    }
10258
10259
0
doc_load:
10260
    /*
10261
    * Load the document.
10262
    */
10263
0
    if (schemaDoc != NULL) {
10264
0
  doc = schemaDoc;
10265
  /* Don' free this one, since it was provided by the caller. */
10266
0
  preserveDoc = 1;
10267
  /* TODO: Does the context or the doc hold the location? */
10268
0
  if (schemaDoc->URL != NULL)
10269
0
      schemaLocation = xmlDictLookup(pctxt->dict,
10270
0
    schemaDoc->URL, -1);
10271
0
        else
10272
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10273
0
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10274
0
  xmlParserCtxtPtr parserCtxt;
10275
10276
0
  parserCtxt = xmlNewParserCtxt();
10277
0
  if (parserCtxt == NULL) {
10278
0
      xmlSchemaPErrMemory(NULL);
10279
0
      goto exit_failure;
10280
0
  }
10281
10282
0
        if (pctxt->serror != NULL)
10283
0
            xmlCtxtSetErrorHandler(parserCtxt, pctxt->serror, pctxt->errCtxt);
10284
0
        if (pctxt->resourceLoader != NULL)
10285
0
            xmlCtxtSetResourceLoader(parserCtxt, pctxt->resourceLoader,
10286
0
                                     pctxt->resourceCtxt);
10287
10288
0
  if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10289
      /*
10290
      * TODO: Do we have to burden the schema parser dict with all
10291
      * the content of the schema doc?
10292
      */
10293
0
      xmlDictFree(parserCtxt->dict);
10294
0
      parserCtxt->dict = pctxt->dict;
10295
0
      xmlDictReference(parserCtxt->dict);
10296
0
  }
10297
0
  if (schemaLocation != NULL) {
10298
      /* Parse from file. */
10299
0
      doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10300
0
    NULL, SCHEMAS_PARSE_OPTIONS);
10301
0
  } else if (schemaBuffer != NULL) {
10302
      /* Parse from memory buffer. */
10303
0
      doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10304
0
    NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10305
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10306
0
      if (doc != NULL)
10307
0
    doc->URL = xmlStrdup(schemaLocation);
10308
0
  }
10309
  /*
10310
  * For <import>:
10311
  * 2.1 The referent is (a fragment of) a resource which is an
10312
  * XML document (see clause 1.1), which in turn corresponds to
10313
  * a <schema> element information item in a well-formed information
10314
  * set, which in turn corresponds to a valid schema.
10315
  * TODO: (2.1) fragments of XML documents are not supported.
10316
  *
10317
  * 2.2 The referent is a <schema> element information item in
10318
  * a well-formed information set, which in turn corresponds
10319
  * to a valid schema.
10320
  * TODO: (2.2) is not supported.
10321
  */
10322
0
  if (doc == NULL) {
10323
0
      const xmlError *lerr;
10324
0
      lerr = xmlGetLastError();
10325
      /*
10326
      * Check if this a parser error, or if the document could
10327
      * just not be located.
10328
      * TODO: Try to find specific error codes to react only on
10329
      * localisation failures.
10330
      */
10331
0
      if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10332
    /*
10333
    * We assume a parser error here.
10334
    */
10335
0
    located = 1;
10336
    /* TODO: Error code ?? */
10337
0
    res = XML_SCHEMAP_SRC_IMPORT_2_1;
10338
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10339
0
        invokingNode, NULL,
10340
0
        "Failed to parse the XML resource '%s'",
10341
0
        schemaLocation, NULL);
10342
0
      }
10343
0
  }
10344
0
  xmlFreeParserCtxt(parserCtxt);
10345
0
  if ((doc == NULL) && located)
10346
0
      goto exit_error;
10347
0
    } else {
10348
0
  xmlSchemaPErr(pctxt, NULL,
10349
0
      XML_SCHEMAP_NOTHING_TO_PARSE,
10350
0
      "No information for parsing was provided with the "
10351
0
      "given schema parser context.\n",
10352
0
      NULL, NULL);
10353
0
  goto exit_failure;
10354
0
    }
10355
    /*
10356
    * Preprocess the document.
10357
    */
10358
0
    if (doc != NULL) {
10359
0
  xmlNodePtr docElem = NULL;
10360
10361
0
  located = 1;
10362
0
  docElem = xmlDocGetRootElement(doc);
10363
0
  if (docElem == NULL) {
10364
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10365
0
    invokingNode, NULL,
10366
0
    "The document '%s' has no document element",
10367
0
    schemaLocation, NULL);
10368
0
      goto exit_error;
10369
0
  }
10370
  /*
10371
  * Remove all the blank text nodes.
10372
  */
10373
0
  xmlSchemaCleanupDoc(pctxt, docElem);
10374
  /*
10375
  * Check the schema's top level element.
10376
  */
10377
0
  if (!IS_SCHEMA(docElem, "schema")) {
10378
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10379
0
    invokingNode, NULL,
10380
0
    "The XML document '%s' is not a schema document",
10381
0
    schemaLocation, NULL);
10382
0
      goto exit_error;
10383
0
  }
10384
  /*
10385
  * Note that we don't apply a type check for the
10386
  * targetNamespace value here.
10387
  */
10388
0
  targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10389
0
      "targetNamespace");
10390
0
    }
10391
10392
/* after_doc_loading: */
10393
0
    if ((bkt == NULL) && located) {
10394
  /* Only create a bucket if the schema was located. */
10395
0
        bkt = xmlSchemaBucketCreate(pctxt, type,
10396
0
      targetNamespace);
10397
0
  if (bkt == NULL)
10398
0
      goto exit_failure;
10399
0
    }
10400
0
    if (bkt != NULL) {
10401
0
  bkt->schemaLocation = schemaLocation;
10402
0
  bkt->located = located;
10403
0
  if (doc != NULL) {
10404
0
      bkt->doc = doc;
10405
0
      bkt->targetNamespace = targetNamespace;
10406
0
      bkt->origTargetNamespace = targetNamespace;
10407
0
      if (preserveDoc)
10408
0
    bkt->preserveDoc = 1;
10409
0
  }
10410
0
  if (WXS_IS_BUCKET_IMPMAIN(type))
10411
0
      bkt->imported++;
10412
      /*
10413
      * Add it to the graph of schemas.
10414
      */
10415
0
  if (relation != NULL)
10416
0
      relation->bucket = bkt;
10417
0
    }
10418
10419
0
exit:
10420
    /*
10421
    * Return the bucket explicitly; this is needed for the
10422
    * main schema.
10423
    */
10424
0
    if (bucket != NULL)
10425
0
  *bucket = bkt;
10426
0
    return (0);
10427
10428
0
exit_error:
10429
0
    if ((doc != NULL) && (! preserveDoc)) {
10430
0
  xmlFreeDoc(doc);
10431
0
  if (bkt != NULL)
10432
0
      bkt->doc = NULL;
10433
0
    }
10434
0
    return(pctxt->err);
10435
10436
0
exit_failure:
10437
0
    if ((doc != NULL) && (! preserveDoc)) {
10438
0
  xmlFreeDoc(doc);
10439
0
  if (bkt != NULL)
10440
0
      bkt->doc = NULL;
10441
0
    }
10442
0
    return (-1);
10443
0
}
10444
10445
/**
10446
 * parse a XML schema Import definition
10447
 * *WARNING* this interface is highly subject to change
10448
 *
10449
 * @param pctxt  a schema validation context
10450
 * @param schema  the schema being built
10451
 * @param node  a subtree containing XML Schema information
10452
 * @returns 0 in case of success, a positive error code if
10453
 * not valid and -1 in case of an internal error.
10454
 */
10455
static int
10456
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10457
                     xmlNodePtr node)
10458
0
{
10459
0
    xmlNodePtr child;
10460
0
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10461
0
    const xmlChar *thisTargetNamespace;
10462
0
    xmlAttrPtr attr;
10463
0
    int ret = 0;
10464
0
    xmlSchemaBucketPtr bucket = NULL;
10465
10466
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10467
0
        return (-1);
10468
10469
    /*
10470
    * Check for illegal attributes.
10471
    */
10472
0
    attr = node->properties;
10473
0
    while (attr != NULL) {
10474
0
  if (attr->ns == NULL) {
10475
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10476
0
    (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10477
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10478
0
    xmlSchemaPIllegalAttrErr(pctxt,
10479
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10480
0
      }
10481
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10482
0
      xmlSchemaPIllegalAttrErr(pctxt,
10483
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10484
0
  }
10485
0
  attr = attr->next;
10486
0
    }
10487
    /*
10488
    * Extract and validate attributes.
10489
    */
10490
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10491
0
  "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10492
0
  &namespaceName) != 0) {
10493
0
  xmlSchemaPSimpleTypeErr(pctxt,
10494
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10495
0
      NULL, node,
10496
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10497
0
      NULL, namespaceName, NULL, NULL, NULL);
10498
0
  return (pctxt->err);
10499
0
    }
10500
10501
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10502
0
  "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10503
0
  &schemaLocation) != 0) {
10504
0
  xmlSchemaPSimpleTypeErr(pctxt,
10505
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10506
0
      NULL, node,
10507
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10508
0
      NULL, schemaLocation, NULL, NULL, NULL);
10509
0
  return (pctxt->err);
10510
0
    }
10511
    /*
10512
    * And now for the children...
10513
    */
10514
0
    child = node->children;
10515
0
    if (IS_SCHEMA(child, "annotation")) {
10516
        /*
10517
         * the annotation here is simply discarded ...
10518
   * TODO: really?
10519
         */
10520
0
        child = child->next;
10521
0
    }
10522
0
    if (child != NULL) {
10523
0
  xmlSchemaPContentErr(pctxt,
10524
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10525
0
      NULL, node, child, NULL,
10526
0
      "(annotation?)");
10527
0
    }
10528
    /*
10529
    * Apply additional constraints.
10530
    *
10531
    * Note that it is important to use the original @targetNamespace
10532
    * (or none at all), to rule out imports of schemas _with_ a
10533
    * @targetNamespace if the importing schema is a chameleon schema
10534
    * (with no @targetNamespace).
10535
    */
10536
0
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10537
0
    if (namespaceName != NULL) {
10538
  /*
10539
  * 1.1 If the namespace [attribute] is present, then its `actual value`
10540
  * must not match the `actual value` of the enclosing <schema>'s
10541
  * targetNamespace [attribute].
10542
  */
10543
0
  if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10544
0
      xmlSchemaPCustomErr(pctxt,
10545
0
    XML_SCHEMAP_SRC_IMPORT_1_1,
10546
0
    NULL, node,
10547
0
    "The value of the attribute 'namespace' must not match "
10548
0
    "the target namespace '%s' of the importing schema",
10549
0
    thisTargetNamespace);
10550
0
      return (pctxt->err);
10551
0
  }
10552
0
    } else {
10553
  /*
10554
  * 1.2 If the namespace [attribute] is not present, then the enclosing
10555
  * <schema> must have a targetNamespace [attribute].
10556
  */
10557
0
  if (thisTargetNamespace == NULL) {
10558
0
      xmlSchemaPCustomErr(pctxt,
10559
0
    XML_SCHEMAP_SRC_IMPORT_1_2,
10560
0
    NULL, node,
10561
0
    "The attribute 'namespace' must be existent if "
10562
0
    "the importing schema has no target namespace",
10563
0
    NULL);
10564
0
      return (pctxt->err);
10565
0
  }
10566
0
    }
10567
    /*
10568
    * Locate and acquire the schema document.
10569
    */
10570
0
    if (schemaLocation != NULL)
10571
0
  schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10572
0
      schemaLocation, node, NULL);
10573
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10574
0
  schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10575
0
  namespaceName, &bucket);
10576
10577
0
    if (ret != 0)
10578
0
  return(ret);
10579
10580
    /*
10581
    * For <import>: "It is *not* an error for the application
10582
    * schema reference strategy to fail."
10583
    * So just don't parse if no schema document was found.
10584
    * Note that we will get no bucket if the schema could not be
10585
    * located or if there was no schemaLocation.
10586
    */
10587
0
    if ((bucket == NULL) && (schemaLocation != NULL)) {
10588
0
  xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10589
0
      XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10590
0
      node, NULL,
10591
0
      "Failed to locate a schema at location '%s'. "
10592
0
      "Skipping the import", schemaLocation, NULL, NULL);
10593
0
    }
10594
10595
0
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10596
0
  ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10597
0
    }
10598
10599
0
    return (ret);
10600
0
}
10601
10602
static int
10603
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10604
             xmlSchemaPtr schema,
10605
             xmlNodePtr node,
10606
             xmlChar **schemaLocation,
10607
             int type)
10608
0
{
10609
0
    xmlAttrPtr attr;
10610
10611
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10612
0
  (schemaLocation == NULL))
10613
0
        return (-1);
10614
10615
0
    *schemaLocation = NULL;
10616
    /*
10617
    * Check for illegal attributes.
10618
    * Applies for both <include> and <redefine>.
10619
    */
10620
0
    attr = node->properties;
10621
0
    while (attr != NULL) {
10622
0
  if (attr->ns == NULL) {
10623
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10624
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10625
0
    xmlSchemaPIllegalAttrErr(pctxt,
10626
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10627
0
      }
10628
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10629
0
      xmlSchemaPIllegalAttrErr(pctxt,
10630
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10631
0
  }
10632
0
  attr = attr->next;
10633
0
    }
10634
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10635
    /*
10636
    * Preliminary step, extract the URI-Reference and make an URI
10637
    * from the base.
10638
    */
10639
    /*
10640
    * Attribute "schemaLocation" is mandatory.
10641
    */
10642
0
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
10643
0
    if (attr != NULL) {
10644
0
        xmlChar *base = NULL;
10645
0
        xmlChar *uri = NULL;
10646
10647
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10648
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10649
0
      (const xmlChar **) schemaLocation) != 0)
10650
0
      goto exit_error;
10651
0
  base = xmlNodeGetBase(node->doc, node);
10652
0
  if (base == NULL) {
10653
0
      uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10654
0
  } else {
10655
0
      uri = xmlBuildURI(*schemaLocation, base);
10656
0
      xmlFree(base);
10657
0
  }
10658
0
  if (uri == NULL) {
10659
0
      PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10660
0
    "could not build an URI from the schemaLocation")
10661
0
      goto exit_failure;
10662
0
  }
10663
0
  (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10664
0
  xmlFree(uri);
10665
0
    } else {
10666
0
  xmlSchemaPMissingAttrErr(pctxt,
10667
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
10668
0
      NULL, node, "schemaLocation", NULL);
10669
0
  goto exit_error;
10670
0
    }
10671
    /*
10672
    * Report self-inclusion and self-redefinition.
10673
    */
10674
0
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10675
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10676
0
      xmlSchemaPCustomErr(pctxt,
10677
0
    XML_SCHEMAP_SRC_REDEFINE,
10678
0
    NULL, node,
10679
0
    "The schema document '%s' cannot redefine itself.",
10680
0
    *schemaLocation);
10681
0
  } else {
10682
0
      xmlSchemaPCustomErr(pctxt,
10683
0
    XML_SCHEMAP_SRC_INCLUDE,
10684
0
    NULL, node,
10685
0
    "The schema document '%s' cannot include itself.",
10686
0
    *schemaLocation);
10687
0
  }
10688
0
  goto exit_error;
10689
0
    }
10690
10691
0
    return(0);
10692
0
exit_error:
10693
0
    return(pctxt->err);
10694
0
exit_failure:
10695
0
    return(-1);
10696
0
}
10697
10698
static int
10699
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10700
        xmlSchemaPtr schema,
10701
        xmlNodePtr node,
10702
        int type)
10703
0
{
10704
0
    xmlNodePtr child = NULL;
10705
0
    const xmlChar *schemaLocation = NULL;
10706
0
    int res = 0; /* hasRedefinitions = 0 */
10707
0
    int isChameleon = 0, wasChameleon = 0;
10708
0
    xmlSchemaBucketPtr bucket = NULL;
10709
10710
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10711
0
        return (-1);
10712
10713
    /*
10714
    * Parse attributes. Note that the returned schemaLocation will
10715
    * be already converted to an absolute URI.
10716
    */
10717
0
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10718
0
  node, (xmlChar **) (&schemaLocation), type);
10719
0
    if (res != 0)
10720
0
  return(res);
10721
    /*
10722
    * Load and add the schema document.
10723
    */
10724
0
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10725
0
  NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10726
0
    if (res != 0)
10727
0
  return(res);
10728
    /*
10729
    * If we get no schema bucket back, then this means that the schema
10730
    * document could not be located or was broken XML or was not
10731
    * a schema document.
10732
    */
10733
0
    if ((bucket == NULL) || (bucket->doc == NULL)) {
10734
0
  if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10735
      /*
10736
      * WARNING for <include>:
10737
      * We will raise an error if the schema cannot be located
10738
      * for inclusions, since the that was the feedback from the
10739
      * schema people. I.e. the following spec piece will *not* be
10740
      * satisfied:
10741
      * SPEC src-include: "It is not an error for the `actual value` of the
10742
      * schemaLocation [attribute] to fail to resolve it all, in which
10743
      * case no corresponding inclusion is performed.
10744
      * So do we need a warning report here?"
10745
      */
10746
0
      res = XML_SCHEMAP_SRC_INCLUDE;
10747
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10748
0
    node, NULL,
10749
0
    "Failed to load the document '%s' for inclusion",
10750
0
    schemaLocation, NULL);
10751
0
  } else {
10752
      /*
10753
      * NOTE: This was changed to raise an error even if no redefinitions
10754
      * are specified.
10755
      *
10756
      * SPEC src-redefine (1)
10757
      * "If there are any element information items among the [children]
10758
      * other than <annotation> then the `actual value` of the
10759
      * schemaLocation [attribute] must successfully resolve."
10760
      * TODO: Ask the WG if a the location has always to resolve
10761
      * here as well!
10762
      */
10763
0
      res = XML_SCHEMAP_SRC_REDEFINE;
10764
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10765
0
    node, NULL,
10766
0
    "Failed to load the document '%s' for redefinition",
10767
0
    schemaLocation, NULL);
10768
0
  }
10769
0
    } else {
10770
  /*
10771
  * Check targetNamespace sanity before parsing the new schema.
10772
  * TODO: Note that we won't check further content if the
10773
  * targetNamespace was bad.
10774
  */
10775
0
  if (bucket->origTargetNamespace != NULL) {
10776
      /*
10777
      * SPEC src-include (2.1)
10778
      * "SII has a targetNamespace [attribute], and its `actual
10779
      * value` is identical to the `actual value` of the targetNamespace
10780
      * [attribute] of SII' (which must have such an [attribute])."
10781
      */
10782
0
      if (pctxt->targetNamespace == NULL) {
10783
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
10784
0
        XML_SCHEMAP_SRC_INCLUDE,
10785
0
        node, NULL,
10786
0
        "The target namespace of the included/redefined schema "
10787
0
        "'%s' has to be absent, since the including/redefining "
10788
0
        "schema has no target namespace",
10789
0
        schemaLocation, NULL);
10790
0
    goto exit_error;
10791
0
      } else if (!xmlStrEqual(bucket->origTargetNamespace,
10792
0
    pctxt->targetNamespace)) {
10793
    /* TODO: Change error function. */
10794
0
    xmlSchemaPCustomErrExt(pctxt,
10795
0
        XML_SCHEMAP_SRC_INCLUDE,
10796
0
        NULL, node,
10797
0
        "The target namespace '%s' of the included/redefined "
10798
0
        "schema '%s' differs from '%s' of the "
10799
0
        "including/redefining schema",
10800
0
        bucket->origTargetNamespace, schemaLocation,
10801
0
        pctxt->targetNamespace);
10802
0
    goto exit_error;
10803
0
      }
10804
0
  } else if (pctxt->targetNamespace != NULL) {
10805
      /*
10806
      * Chameleons: the original target namespace will
10807
      * differ from the resulting namespace.
10808
      */
10809
0
      isChameleon = 1;
10810
0
      bucket->targetNamespace = pctxt->targetNamespace;
10811
0
  }
10812
0
    }
10813
    /*
10814
    * Parse the schema.
10815
    */
10816
0
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
10817
0
  if (isChameleon) {
10818
      /* TODO: Get rid of this flag on the schema itself. */
10819
0
      if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
10820
0
    schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
10821
0
      } else
10822
0
    wasChameleon = 1;
10823
0
  }
10824
0
  xmlSchemaParseNewDoc(pctxt, schema, bucket);
10825
  /* Restore chameleon flag. */
10826
0
  if (isChameleon && (!wasChameleon))
10827
0
      schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
10828
0
    }
10829
    /*
10830
    * And now for the children...
10831
    */
10832
0
    child = node->children;
10833
0
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10834
  /*
10835
  * Parse (simpleType | complexType | group | attributeGroup))*
10836
  */
10837
0
  pctxt->redefined = bucket;
10838
  /*
10839
  * How to proceed if the redefined schema was not located?
10840
  */
10841
0
  pctxt->isRedefine = 1;
10842
0
  while (IS_SCHEMA(child, "annotation") ||
10843
0
      IS_SCHEMA(child, "simpleType") ||
10844
0
      IS_SCHEMA(child, "complexType") ||
10845
0
      IS_SCHEMA(child, "group") ||
10846
0
      IS_SCHEMA(child, "attributeGroup")) {
10847
0
      if (IS_SCHEMA(child, "annotation")) {
10848
    /*
10849
    * TODO: discard or not?
10850
    */
10851
0
      } else if (IS_SCHEMA(child, "simpleType")) {
10852
0
    xmlSchemaParseSimpleType(pctxt, schema, child, 1);
10853
0
      } else if (IS_SCHEMA(child, "complexType")) {
10854
0
    xmlSchemaParseComplexType(pctxt, schema, child, 1);
10855
    /* hasRedefinitions = 1; */
10856
0
      } else if (IS_SCHEMA(child, "group")) {
10857
    /* hasRedefinitions = 1; */
10858
0
    xmlSchemaParseModelGroupDefinition(pctxt,
10859
0
        schema, child);
10860
0
      } else if (IS_SCHEMA(child, "attributeGroup")) {
10861
    /* hasRedefinitions = 1; */
10862
0
    xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
10863
0
        child);
10864
0
      }
10865
0
      child = child->next;
10866
0
  }
10867
0
  pctxt->redefined = NULL;
10868
0
  pctxt->isRedefine = 0;
10869
0
    } else {
10870
0
  if (IS_SCHEMA(child, "annotation")) {
10871
      /*
10872
      * TODO: discard or not?
10873
      */
10874
0
      child = child->next;
10875
0
  }
10876
0
    }
10877
0
    if (child != NULL) {
10878
0
  res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
10879
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10880
0
      xmlSchemaPContentErr(pctxt, res,
10881
0
    NULL, node, child, NULL,
10882
0
    "(annotation | (simpleType | complexType | group | attributeGroup))*");
10883
0
  } else {
10884
0
       xmlSchemaPContentErr(pctxt, res,
10885
0
    NULL, node, child, NULL,
10886
0
    "(annotation?)");
10887
0
  }
10888
0
    }
10889
0
    return(res);
10890
10891
0
exit_error:
10892
0
    return(pctxt->err);
10893
0
}
10894
10895
static int
10896
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10897
                       xmlNodePtr node)
10898
0
{
10899
0
    int res;
10900
#ifndef ENABLE_REDEFINE
10901
    TODO
10902
    return(0);
10903
#endif
10904
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
10905
0
  XML_SCHEMA_SCHEMA_REDEFINE);
10906
0
    if (res != 0)
10907
0
  return(res);
10908
0
    return(0);
10909
0
}
10910
10911
static int
10912
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10913
                       xmlNodePtr node)
10914
0
{
10915
0
    int res;
10916
10917
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
10918
0
  XML_SCHEMA_SCHEMA_INCLUDE);
10919
0
    if (res != 0)
10920
0
  return(res);
10921
0
    return(0);
10922
0
}
10923
10924
/**
10925
 * parse a XML schema Sequence definition.
10926
 * Applies parts of:
10927
 *   Schema Representation Constraint:
10928
 *     Redefinition Constraints and Semantics (src-redefine)
10929
 *     (6.1), (6.1.1), (6.1.2)
10930
 *
10931
 *   Schema Component Constraint:
10932
 *     All Group Limited (cos-all-limited) (2)
10933
 *     TODO: Actually this should go to component-level checks,
10934
 *     but is done here due to performance. Move it to an other layer
10935
 *     is schema construction via an API is implemented.
10936
 *
10937
 * *WARNING* this interface is highly subject to change
10938
 *
10939
 * @param ctxt  a schema validation context
10940
 * @param schema  the schema being built
10941
 * @param node  a subtree containing XML Schema information
10942
 * @param type  the "compositor" type
10943
 * @param withParticle  if a a model group with a particle
10944
 * @returns -1 in case of error, 0 if the declaration is improper and
10945
 *         1 in case of success.
10946
 */
10947
static xmlSchemaTreeItemPtr
10948
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
10949
       xmlNodePtr node, xmlSchemaTypeType type,
10950
       int withParticle)
10951
0
{
10952
0
    xmlSchemaModelGroupPtr item;
10953
0
    xmlSchemaParticlePtr particle = NULL;
10954
0
    xmlNodePtr child = NULL;
10955
0
    xmlAttrPtr attr;
10956
0
    int min = 1, max = 1, isElemRef, hasRefs = 0;
10957
10958
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
10959
0
        return (NULL);
10960
    /*
10961
    * Create a model group with the given compositor.
10962
    */
10963
0
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
10964
0
    if (item == NULL)
10965
0
  return (NULL);
10966
10967
0
    if (withParticle) {
10968
0
  if (type == XML_SCHEMA_TYPE_ALL) {
10969
0
      min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
10970
0
      max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
10971
0
  } else {
10972
      /* choice + sequence */
10973
0
      min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
10974
0
      max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
10975
0
    "(xs:nonNegativeInteger | unbounded)");
10976
0
  }
10977
0
  xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
10978
  /*
10979
  * Create a particle
10980
  */
10981
0
  particle = xmlSchemaAddParticle(ctxt, node, min, max);
10982
0
  if (particle == NULL)
10983
0
      return (NULL);
10984
0
  particle->children = (xmlSchemaTreeItemPtr) item;
10985
  /*
10986
  * Check for illegal attributes.
10987
  */
10988
0
  attr = node->properties;
10989
0
  while (attr != NULL) {
10990
0
      if (attr->ns == NULL) {
10991
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10992
0
        (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
10993
0
        (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
10994
0
        xmlSchemaPIllegalAttrErr(ctxt,
10995
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10996
0
    }
10997
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10998
0
    xmlSchemaPIllegalAttrErr(ctxt,
10999
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11000
0
      }
11001
0
      attr = attr->next;
11002
0
  }
11003
0
    } else {
11004
  /*
11005
  * Check for illegal attributes.
11006
  */
11007
0
  attr = node->properties;
11008
0
  while (attr != NULL) {
11009
0
      if (attr->ns == NULL) {
11010
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11011
0
        xmlSchemaPIllegalAttrErr(ctxt,
11012
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11013
0
    }
11014
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11015
0
    xmlSchemaPIllegalAttrErr(ctxt,
11016
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11017
0
      }
11018
0
      attr = attr->next;
11019
0
  }
11020
0
    }
11021
11022
    /*
11023
    * Extract and validate attributes.
11024
    */
11025
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11026
    /*
11027
    * And now for the children...
11028
    */
11029
0
    child = node->children;
11030
0
    if (IS_SCHEMA(child, "annotation")) {
11031
0
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11032
0
        child = child->next;
11033
0
    }
11034
0
    if (type == XML_SCHEMA_TYPE_ALL) {
11035
0
  xmlSchemaParticlePtr part, last = NULL;
11036
11037
0
  while (IS_SCHEMA(child, "element")) {
11038
0
      part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11039
0
    schema, child, &isElemRef, 0);
11040
      /*
11041
      * SPEC cos-all-limited (2)
11042
      * "The {max occurs} of all the particles in the {particles}
11043
      * of the ('all') group must be 0 or 1.
11044
      */
11045
0
      if (part != NULL) {
11046
0
    if (isElemRef)
11047
0
        hasRefs++;
11048
0
    if (part->minOccurs > 1) {
11049
0
        xmlSchemaPCustomErr(ctxt,
11050
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11051
0
      NULL, child,
11052
0
      "Invalid value for minOccurs (must be 0 or 1)",
11053
0
      NULL);
11054
        /* Reset to 1. */
11055
0
        part->minOccurs = 1;
11056
0
    }
11057
0
    if (part->maxOccurs > 1) {
11058
0
        xmlSchemaPCustomErr(ctxt,
11059
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11060
0
      NULL, child,
11061
0
      "Invalid value for maxOccurs (must be 0 or 1)",
11062
0
      NULL);
11063
        /* Reset to 1. */
11064
0
        part->maxOccurs = 1;
11065
0
    }
11066
0
    if (last == NULL)
11067
0
        item->children = (xmlSchemaTreeItemPtr) part;
11068
0
    else
11069
0
        last->next = (xmlSchemaTreeItemPtr) part;
11070
0
    last = part;
11071
0
      }
11072
0
      child = child->next;
11073
0
  }
11074
0
  if (child != NULL) {
11075
0
      xmlSchemaPContentErr(ctxt,
11076
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11077
0
    NULL, node, child, NULL,
11078
0
    "(annotation?, (annotation?, element*)");
11079
0
  }
11080
0
    } else {
11081
  /* choice + sequence */
11082
0
  xmlSchemaTreeItemPtr part = NULL, last = NULL;
11083
11084
0
  while ((IS_SCHEMA(child, "element")) ||
11085
0
      (IS_SCHEMA(child, "group")) ||
11086
0
      (IS_SCHEMA(child, "any")) ||
11087
0
      (IS_SCHEMA(child, "choice")) ||
11088
0
      (IS_SCHEMA(child, "sequence"))) {
11089
11090
0
      if (IS_SCHEMA(child, "element")) {
11091
0
    part = (xmlSchemaTreeItemPtr)
11092
0
        xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11093
0
    if (part && isElemRef)
11094
0
        hasRefs++;
11095
0
      } else if (IS_SCHEMA(child, "group")) {
11096
0
    part =
11097
0
        xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11098
0
    if (part != NULL)
11099
0
        hasRefs++;
11100
    /*
11101
    * Handle redefinitions.
11102
    */
11103
0
    if (ctxt->isRedefine && ctxt->redef &&
11104
0
        (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11105
0
        part && part->children)
11106
0
    {
11107
0
        if ((xmlSchemaGetQNameRefName(part->children) ==
11108
0
          ctxt->redef->refName) &&
11109
0
      (xmlSchemaGetQNameRefTargetNs(part->children) ==
11110
0
          ctxt->redef->refTargetNs))
11111
0
        {
11112
      /*
11113
      * SPEC src-redefine:
11114
      * (6.1) "If it has a <group> among its contents at
11115
      * some level the `actual value` of whose ref
11116
      * [attribute] is the same as the `actual value` of
11117
      * its own name attribute plus target namespace, then
11118
      * all of the following must be true:"
11119
      * (6.1.1) "It must have exactly one such group."
11120
      */
11121
0
      if (ctxt->redefCounter != 0) {
11122
0
          xmlChar *str = NULL;
11123
11124
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11125
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11126
0
        "The redefining model group definition "
11127
0
        "'%s' must not contain more than one "
11128
0
        "reference to the redefined definition",
11129
0
        xmlSchemaFormatQName(&str,
11130
0
            ctxt->redef->refTargetNs,
11131
0
            ctxt->redef->refName),
11132
0
        NULL);
11133
0
          FREE_AND_NULL(str)
11134
0
          part = NULL;
11135
0
      } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11136
0
          ((WXS_PARTICLE(part))->maxOccurs != 1))
11137
0
      {
11138
0
          xmlChar *str = NULL;
11139
          /*
11140
          * SPEC src-redefine:
11141
          * (6.1.2) "The `actual value` of both that
11142
          * group's minOccurs and maxOccurs [attribute]
11143
          * must be 1 (or `absent`).
11144
          */
11145
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11146
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11147
0
        "The redefining model group definition "
11148
0
        "'%s' must not contain a reference to the "
11149
0
        "redefined definition with a "
11150
0
        "maxOccurs/minOccurs other than 1",
11151
0
        xmlSchemaFormatQName(&str,
11152
0
            ctxt->redef->refTargetNs,
11153
0
            ctxt->redef->refName),
11154
0
        NULL);
11155
0
          FREE_AND_NULL(str)
11156
0
          part = NULL;
11157
0
      }
11158
0
      ctxt->redef->reference = WXS_BASIC_CAST part;
11159
0
      ctxt->redefCounter++;
11160
0
        }
11161
0
    }
11162
0
      } else if (IS_SCHEMA(child, "any")) {
11163
0
    part = (xmlSchemaTreeItemPtr)
11164
0
        xmlSchemaParseAny(ctxt, schema, child);
11165
0
      } else if (IS_SCHEMA(child, "choice")) {
11166
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11167
0
        XML_SCHEMA_TYPE_CHOICE, 1);
11168
0
      } else if (IS_SCHEMA(child, "sequence")) {
11169
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11170
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11171
0
      }
11172
0
      if (part != NULL) {
11173
0
    if (last == NULL)
11174
0
        item->children = part;
11175
0
    else
11176
0
        last->next = part;
11177
0
    last = part;
11178
0
      }
11179
0
      child = child->next;
11180
0
  }
11181
0
  if (child != NULL) {
11182
0
      xmlSchemaPContentErr(ctxt,
11183
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11184
0
    NULL, node, child, NULL,
11185
0
    "(annotation?, (element | group | choice | sequence | any)*)");
11186
0
  }
11187
0
    }
11188
0
    if ((max == 0) && (min == 0))
11189
0
  return (NULL);
11190
0
    if (hasRefs) {
11191
  /*
11192
  * We need to resolve references.
11193
  */
11194
0
  WXS_ADD_PENDING(ctxt, item);
11195
0
    }
11196
0
    if (withParticle)
11197
0
  return ((xmlSchemaTreeItemPtr) particle);
11198
0
    else
11199
0
  return ((xmlSchemaTreeItemPtr) item);
11200
0
}
11201
11202
/**
11203
 * parse a XML schema Restriction definition
11204
 * *WARNING* this interface is highly subject to change
11205
 *
11206
 * @param ctxt  a schema validation context
11207
 * @param schema  the schema being built
11208
 * @param node  a subtree containing XML Schema information
11209
 * @param parentType  the parent type
11210
 * @returns the type definition or NULL in case of error
11211
 */
11212
static xmlSchemaTypePtr
11213
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11214
                          xmlNodePtr node, xmlSchemaTypeType parentType)
11215
0
{
11216
0
    xmlSchemaTypePtr type;
11217
0
    xmlNodePtr child = NULL;
11218
0
    xmlAttrPtr attr;
11219
11220
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11221
0
        return (NULL);
11222
    /* Not a component, don't create it. */
11223
0
    type = ctxt->ctxtType;
11224
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11225
11226
    /*
11227
    * Check for illegal attributes.
11228
    */
11229
0
    attr = node->properties;
11230
0
    while (attr != NULL) {
11231
0
  if (attr->ns == NULL) {
11232
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11233
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11234
0
    xmlSchemaPIllegalAttrErr(ctxt,
11235
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11236
0
      }
11237
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11238
0
      xmlSchemaPIllegalAttrErr(ctxt,
11239
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11240
0
  }
11241
0
  attr = attr->next;
11242
0
    }
11243
    /*
11244
    * Extract and validate attributes.
11245
    */
11246
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11247
    /*
11248
    * Attribute
11249
    */
11250
    /*
11251
    * Extract the base type. The "base" attribute is mandatory if inside
11252
    * a complex type or if redefining.
11253
    *
11254
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11255
    * among its [children]), the simple type definition which is
11256
    * the {content type} of the type definition `resolved` to by
11257
    * the `actual value` of the base [attribute]"
11258
    */
11259
0
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11260
0
  &(type->baseNs), &(type->base)) == 0)
11261
0
    {
11262
0
  if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11263
0
      xmlSchemaPMissingAttrErr(ctxt,
11264
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
11265
0
    NULL, node, "base", NULL);
11266
0
  } else if ((ctxt->isRedefine) &&
11267
0
      (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11268
0
  {
11269
0
      if (type->base == NULL) {
11270
0
    xmlSchemaPMissingAttrErr(ctxt,
11271
0
        XML_SCHEMAP_S4S_ATTR_MISSING,
11272
0
        NULL, node, "base", NULL);
11273
0
      } else if ((! xmlStrEqual(type->base, type->name)) ||
11274
0
    (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11275
0
      {
11276
0
    xmlChar *str1 = NULL, *str2 = NULL;
11277
    /*
11278
    * REDEFINE: SPEC src-redefine (5)
11279
    * "Within the [children], each <simpleType> must have a
11280
    * <restriction> among its [children] ... the `actual value` of
11281
    * whose base [attribute] must be the same as the `actual value`
11282
    * of its own name attribute plus target namespace;"
11283
    */
11284
0
    xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11285
0
        NULL, node, "This is a redefinition, but the QName "
11286
0
        "value '%s' of the 'base' attribute does not match the "
11287
0
        "type's designation '%s'",
11288
0
        xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11289
0
        xmlSchemaFormatQName(&str2, type->targetNamespace,
11290
0
      type->name), NULL);
11291
0
    FREE_AND_NULL(str1);
11292
0
    FREE_AND_NULL(str2);
11293
    /* Avoid confusion and erase the values. */
11294
0
    type->base = NULL;
11295
0
    type->baseNs = NULL;
11296
0
      }
11297
0
  }
11298
0
    }
11299
    /*
11300
    * And now for the children...
11301
    */
11302
0
    child = node->children;
11303
0
    if (IS_SCHEMA(child, "annotation")) {
11304
  /*
11305
  * Add the annotation to the simple type ancestor.
11306
  */
11307
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11308
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11309
0
        child = child->next;
11310
0
    }
11311
0
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11312
  /*
11313
  * Corresponds to <simpleType><restriction><simpleType>.
11314
  */
11315
0
  if (IS_SCHEMA(child, "simpleType")) {
11316
0
      if (type->base != NULL) {
11317
    /*
11318
    * src-restriction-base-or-simpleType
11319
    * Either the base [attribute] or the simpleType [child] of the
11320
    * <restriction> element must be present, but not both.
11321
    */
11322
0
    xmlSchemaPContentErr(ctxt,
11323
0
        XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11324
0
        NULL, node, child,
11325
0
        "The attribute 'base' and the <simpleType> child are "
11326
0
        "mutually exclusive", NULL);
11327
0
      } else {
11328
0
    type->baseType = (xmlSchemaTypePtr)
11329
0
        xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11330
0
      }
11331
0
      child = child->next;
11332
0
  } else if (type->base == NULL) {
11333
0
      xmlSchemaPContentErr(ctxt,
11334
0
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11335
0
    NULL, node, child,
11336
0
    "Either the attribute 'base' or a <simpleType> child "
11337
0
    "must be present", NULL);
11338
0
  }
11339
0
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11340
  /*
11341
  * Corresponds to <complexType><complexContent><restriction>...
11342
  * followed by:
11343
  *
11344
  * Model groups <all>, <choice> and <sequence>.
11345
  */
11346
0
  if (IS_SCHEMA(child, "all")) {
11347
0
      type->subtypes = (xmlSchemaTypePtr)
11348
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11349
0
        XML_SCHEMA_TYPE_ALL, 1);
11350
0
      child = child->next;
11351
0
  } else if (IS_SCHEMA(child, "choice")) {
11352
0
      type->subtypes = (xmlSchemaTypePtr)
11353
0
    xmlSchemaParseModelGroup(ctxt,
11354
0
        schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11355
0
      child = child->next;
11356
0
  } else if (IS_SCHEMA(child, "sequence")) {
11357
0
      type->subtypes = (xmlSchemaTypePtr)
11358
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11359
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11360
0
      child = child->next;
11361
  /*
11362
  * Model group reference <group>.
11363
  */
11364
0
  } else if (IS_SCHEMA(child, "group")) {
11365
0
      type->subtypes = (xmlSchemaTypePtr)
11366
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11367
      /*
11368
      * Note that the reference will be resolved in
11369
      * xmlSchemaResolveTypeReferences();
11370
      */
11371
0
      child = child->next;
11372
0
  }
11373
0
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11374
  /*
11375
  * Corresponds to <complexType><simpleContent><restriction>...
11376
  *
11377
  * "1.1 the simple type definition corresponding to the <simpleType>
11378
  * among the [children] of <restriction> if there is one;"
11379
  */
11380
0
  if (IS_SCHEMA(child, "simpleType")) {
11381
      /*
11382
      * We will store the to-be-restricted simple type in
11383
      * type->contentTypeDef *temporarily*.
11384
      */
11385
0
      type->contentTypeDef = (xmlSchemaTypePtr)
11386
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11387
0
      if ( type->contentTypeDef == NULL)
11388
0
    return (NULL);
11389
0
      child = child->next;
11390
0
  }
11391
0
    }
11392
11393
0
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11394
0
  (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11395
0
  xmlSchemaFacetPtr facet, lastfacet = NULL;
11396
  /*
11397
  * Corresponds to <complexType><simpleContent><restriction>...
11398
  * <simpleType><restriction>...
11399
  */
11400
11401
  /*
11402
  * Add the facets to the simple type ancestor.
11403
  */
11404
  /*
11405
  * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11406
  * Simple Type Definition Schema Representation Constraint:
11407
  * *Single Facet Value*
11408
  */
11409
0
  while ((IS_SCHEMA(child, "minInclusive")) ||
11410
0
      (IS_SCHEMA(child, "minExclusive")) ||
11411
0
      (IS_SCHEMA(child, "maxInclusive")) ||
11412
0
      (IS_SCHEMA(child, "maxExclusive")) ||
11413
0
      (IS_SCHEMA(child, "totalDigits")) ||
11414
0
      (IS_SCHEMA(child, "fractionDigits")) ||
11415
0
      (IS_SCHEMA(child, "pattern")) ||
11416
0
      (IS_SCHEMA(child, "enumeration")) ||
11417
0
      (IS_SCHEMA(child, "whiteSpace")) ||
11418
0
      (IS_SCHEMA(child, "length")) ||
11419
0
      (IS_SCHEMA(child, "maxLength")) ||
11420
0
      (IS_SCHEMA(child, "minLength"))) {
11421
0
      facet = xmlSchemaParseFacet(ctxt, schema, child);
11422
0
      if (facet != NULL) {
11423
0
    if (lastfacet == NULL)
11424
0
        type->facets = facet;
11425
0
    else
11426
0
        lastfacet->next = facet;
11427
0
    lastfacet = facet;
11428
0
    lastfacet->next = NULL;
11429
0
      }
11430
0
      child = child->next;
11431
0
  }
11432
  /*
11433
  * Create links for derivation and validation.
11434
  */
11435
0
  if (type->facets != NULL) {
11436
0
      xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11437
11438
0
      facet = type->facets;
11439
0
      do {
11440
0
    facetLink = (xmlSchemaFacetLinkPtr)
11441
0
        xmlMalloc(sizeof(xmlSchemaFacetLink));
11442
0
    if (facetLink == NULL) {
11443
0
        xmlSchemaPErrMemory(ctxt);
11444
0
        xmlFree(facetLink);
11445
0
        return (NULL);
11446
0
    }
11447
0
    facetLink->facet = facet;
11448
0
    facetLink->next = NULL;
11449
0
    if (lastFacetLink == NULL)
11450
0
        type->facetSet = facetLink;
11451
0
    else
11452
0
        lastFacetLink->next = facetLink;
11453
0
    lastFacetLink = facetLink;
11454
0
    facet = facet->next;
11455
0
      } while (facet != NULL);
11456
0
  }
11457
0
    }
11458
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11459
  /*
11460
  * Attribute uses/declarations.
11461
  */
11462
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11463
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11464
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11465
0
      return(NULL);
11466
  /*
11467
  * Attribute wildcard.
11468
  */
11469
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11470
0
      type->attributeWildcard =
11471
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11472
0
      child = child->next;
11473
0
  }
11474
0
    }
11475
0
    if (child != NULL) {
11476
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11477
0
      xmlSchemaPContentErr(ctxt,
11478
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11479
0
    NULL, node, child, NULL,
11480
0
    "annotation?, (group | all | choice | sequence)?, "
11481
0
    "((attribute | attributeGroup)*, anyAttribute?))");
11482
0
  } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11483
0
       xmlSchemaPContentErr(ctxt,
11484
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11485
0
    NULL, node, child, NULL,
11486
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11487
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11488
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11489
0
    "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11490
0
  } else {
11491
      /* Simple type */
11492
0
      xmlSchemaPContentErr(ctxt,
11493
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11494
0
    NULL, node, child, NULL,
11495
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11496
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11497
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11498
0
    "pattern)*))");
11499
0
  }
11500
0
    }
11501
0
    return (NULL);
11502
0
}
11503
11504
/**
11505
 * Parses an `<extension>`, which is found inside a
11506
 * `<simpleContent>` or `<complexContent>`.
11507
 * *WARNING* this interface is highly subject to change.
11508
 *
11509
 * @param ctxt  a schema validation context
11510
 * @param schema  the schema being built
11511
 * @param node  a subtree containing XML Schema information
11512
 * @param parentType  parent type
11513
 * @returns the type definition or NULL in case of error
11514
 */
11515
static xmlSchemaTypePtr
11516
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11517
                        xmlNodePtr node, xmlSchemaTypeType parentType)
11518
0
{
11519
0
    xmlSchemaTypePtr type;
11520
0
    xmlNodePtr child = NULL;
11521
0
    xmlAttrPtr attr;
11522
11523
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11524
0
        return (NULL);
11525
    /* Not a component, don't create it. */
11526
0
    type = ctxt->ctxtType;
11527
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11528
11529
    /*
11530
    * Check for illegal attributes.
11531
    */
11532
0
    attr = node->properties;
11533
0
    while (attr != NULL) {
11534
0
  if (attr->ns == NULL) {
11535
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11536
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11537
0
    xmlSchemaPIllegalAttrErr(ctxt,
11538
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11539
0
      }
11540
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11541
0
      xmlSchemaPIllegalAttrErr(ctxt,
11542
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11543
0
  }
11544
0
  attr = attr->next;
11545
0
    }
11546
11547
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11548
11549
    /*
11550
    * Attribute "base" - mandatory.
11551
    */
11552
0
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11553
0
  "base", &(type->baseNs), &(type->base)) == 0) &&
11554
0
  (type->base == NULL)) {
11555
0
  xmlSchemaPMissingAttrErr(ctxt,
11556
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11557
0
      NULL, node, "base", NULL);
11558
0
    }
11559
    /*
11560
    * And now for the children...
11561
    */
11562
0
    child = node->children;
11563
0
    if (IS_SCHEMA(child, "annotation")) {
11564
  /*
11565
  * Add the annotation to the type ancestor.
11566
  */
11567
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11568
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11569
0
        child = child->next;
11570
0
    }
11571
0
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11572
  /*
11573
  * Corresponds to <complexType><complexContent><extension>... and:
11574
  *
11575
  * Model groups <all>, <choice>, <sequence> and <group>.
11576
  */
11577
0
  if (IS_SCHEMA(child, "all")) {
11578
0
      type->subtypes = (xmlSchemaTypePtr)
11579
0
    xmlSchemaParseModelGroup(ctxt, schema,
11580
0
        child, XML_SCHEMA_TYPE_ALL, 1);
11581
0
      child = child->next;
11582
0
  } else if (IS_SCHEMA(child, "choice")) {
11583
0
      type->subtypes = (xmlSchemaTypePtr)
11584
0
    xmlSchemaParseModelGroup(ctxt, schema,
11585
0
        child, XML_SCHEMA_TYPE_CHOICE, 1);
11586
0
      child = child->next;
11587
0
  } else if (IS_SCHEMA(child, "sequence")) {
11588
0
      type->subtypes = (xmlSchemaTypePtr)
11589
0
    xmlSchemaParseModelGroup(ctxt, schema,
11590
0
    child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11591
0
      child = child->next;
11592
0
  } else if (IS_SCHEMA(child, "group")) {
11593
0
      type->subtypes = (xmlSchemaTypePtr)
11594
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11595
      /*
11596
      * Note that the reference will be resolved in
11597
      * xmlSchemaResolveTypeReferences();
11598
      */
11599
0
      child = child->next;
11600
0
  }
11601
0
    }
11602
0
    if (child != NULL) {
11603
  /*
11604
  * Attribute uses/declarations.
11605
  */
11606
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11607
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11608
0
      XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11609
0
      return(NULL);
11610
  /*
11611
  * Attribute wildcard.
11612
  */
11613
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11614
0
      ctxt->ctxtType->attributeWildcard =
11615
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11616
0
      child = child->next;
11617
0
  }
11618
0
    }
11619
0
    if (child != NULL) {
11620
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11621
      /* Complex content extension. */
11622
0
      xmlSchemaPContentErr(ctxt,
11623
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11624
0
    NULL, node, child, NULL,
11625
0
    "(annotation?, ((group | all | choice | sequence)?, "
11626
0
    "((attribute | attributeGroup)*, anyAttribute?)))");
11627
0
  } else {
11628
      /* Simple content extension. */
11629
0
      xmlSchemaPContentErr(ctxt,
11630
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11631
0
    NULL, node, child, NULL,
11632
0
    "(annotation?, ((attribute | attributeGroup)*, "
11633
0
    "anyAttribute?))");
11634
0
  }
11635
0
    }
11636
0
    return (NULL);
11637
0
}
11638
11639
/**
11640
 * parse a XML schema SimpleContent definition
11641
 * *WARNING* this interface is highly subject to change
11642
 *
11643
 * @param ctxt  a schema validation context
11644
 * @param schema  the schema being built
11645
 * @param node  a subtree containing XML Schema information
11646
 * @param hasRestrictionOrExtension  set if restriction or extension was found
11647
 * @returns the type definition or NULL in case of error
11648
 */
11649
static int
11650
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11651
                            xmlSchemaPtr schema, xmlNodePtr node,
11652
          int *hasRestrictionOrExtension)
11653
0
{
11654
0
    xmlSchemaTypePtr type;
11655
0
    xmlNodePtr child = NULL;
11656
0
    xmlAttrPtr attr;
11657
11658
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11659
0
  (hasRestrictionOrExtension == NULL))
11660
0
        return (-1);
11661
0
    *hasRestrictionOrExtension = 0;
11662
    /* Not a component, don't create it. */
11663
0
    type = ctxt->ctxtType;
11664
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11665
    /*
11666
    * Check for illegal attributes.
11667
    */
11668
0
    attr = node->properties;
11669
0
    while (attr != NULL) {
11670
0
  if (attr->ns == NULL) {
11671
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11672
0
    xmlSchemaPIllegalAttrErr(ctxt,
11673
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11674
0
      }
11675
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11676
0
      xmlSchemaPIllegalAttrErr(ctxt,
11677
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11678
0
  }
11679
0
  attr = attr->next;
11680
0
    }
11681
11682
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11683
11684
    /*
11685
    * And now for the children...
11686
    */
11687
0
    child = node->children;
11688
0
    if (IS_SCHEMA(child, "annotation")) {
11689
  /*
11690
  * Add the annotation to the complex type ancestor.
11691
  */
11692
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11693
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11694
0
        child = child->next;
11695
0
    }
11696
0
    if (child == NULL) {
11697
0
  xmlSchemaPContentErr(ctxt,
11698
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11699
0
      NULL, node, NULL, NULL,
11700
0
      "(annotation?, (restriction | extension))");
11701
0
    }
11702
0
    if (child == NULL) {
11703
0
  xmlSchemaPContentErr(ctxt,
11704
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11705
0
      NULL, node, NULL, NULL,
11706
0
      "(annotation?, (restriction | extension))");
11707
0
    }
11708
0
    if (IS_SCHEMA(child, "restriction")) {
11709
0
        xmlSchemaParseRestriction(ctxt, schema, child,
11710
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11711
0
  (*hasRestrictionOrExtension) = 1;
11712
0
        child = child->next;
11713
0
    } else if (IS_SCHEMA(child, "extension")) {
11714
0
        xmlSchemaParseExtension(ctxt, schema, child,
11715
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11716
0
  (*hasRestrictionOrExtension) = 1;
11717
0
        child = child->next;
11718
0
    }
11719
0
    if (child != NULL) {
11720
0
  xmlSchemaPContentErr(ctxt,
11721
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11722
0
      NULL, node, child, NULL,
11723
0
      "(annotation?, (restriction | extension))");
11724
0
    }
11725
0
    return (0);
11726
0
}
11727
11728
/**
11729
 * parse a XML schema ComplexContent definition
11730
 * *WARNING* this interface is highly subject to change
11731
 *
11732
 * @param ctxt  a schema validation context
11733
 * @param schema  the schema being built
11734
 * @param node  a subtree containing XML Schema information
11735
 * @param hasRestrictionOrExtension  set if restriction or extension was found
11736
 * @returns the type definition or NULL in case of error
11737
 */
11738
static int
11739
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11740
                             xmlSchemaPtr schema, xmlNodePtr node,
11741
           int *hasRestrictionOrExtension)
11742
0
{
11743
0
    xmlSchemaTypePtr type;
11744
0
    xmlNodePtr child = NULL;
11745
0
    xmlAttrPtr attr;
11746
11747
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11748
0
  (hasRestrictionOrExtension == NULL))
11749
0
        return (-1);
11750
0
    *hasRestrictionOrExtension = 0;
11751
    /* Not a component, don't create it. */
11752
0
    type = ctxt->ctxtType;
11753
    /*
11754
    * Check for illegal attributes.
11755
    */
11756
0
    attr = node->properties;
11757
0
    while (attr != NULL) {
11758
0
  if (attr->ns == NULL) {
11759
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11760
0
    (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
11761
0
      {
11762
0
    xmlSchemaPIllegalAttrErr(ctxt,
11763
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11764
0
      }
11765
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11766
0
      xmlSchemaPIllegalAttrErr(ctxt,
11767
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11768
0
  }
11769
0
  attr = attr->next;
11770
0
    }
11771
11772
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11773
11774
    /*
11775
    * Set the 'mixed' on the complex type ancestor.
11776
    */
11777
0
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
11778
0
  if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
11779
0
      type->flags |= XML_SCHEMAS_TYPE_MIXED;
11780
0
    }
11781
0
    child = node->children;
11782
0
    if (IS_SCHEMA(child, "annotation")) {
11783
  /*
11784
  * Add the annotation to the complex type ancestor.
11785
  */
11786
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11787
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11788
0
        child = child->next;
11789
0
    }
11790
0
    if (child == NULL) {
11791
0
  xmlSchemaPContentErr(ctxt,
11792
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11793
0
      NULL, node, NULL,
11794
0
      NULL, "(annotation?, (restriction | extension))");
11795
0
    }
11796
0
    if (child == NULL) {
11797
0
  xmlSchemaPContentErr(ctxt,
11798
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11799
0
      NULL, node, NULL,
11800
0
      NULL, "(annotation?, (restriction | extension))");
11801
0
    }
11802
0
    if (IS_SCHEMA(child, "restriction")) {
11803
0
        xmlSchemaParseRestriction(ctxt, schema, child,
11804
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
11805
0
  (*hasRestrictionOrExtension) = 1;
11806
0
        child = child->next;
11807
0
    } else if (IS_SCHEMA(child, "extension")) {
11808
0
        xmlSchemaParseExtension(ctxt, schema, child,
11809
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
11810
0
  (*hasRestrictionOrExtension) = 1;
11811
0
        child = child->next;
11812
0
    }
11813
0
    if (child != NULL) {
11814
0
  xmlSchemaPContentErr(ctxt,
11815
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11816
0
      NULL, node, child,
11817
0
      NULL, "(annotation?, (restriction | extension))");
11818
0
    }
11819
0
    return (0);
11820
0
}
11821
11822
/**
11823
 * parse a XML schema Complex Type definition
11824
 * *WARNING* this interface is highly subject to change
11825
 *
11826
 * @param ctxt  a schema validation context
11827
 * @param schema  the schema being built
11828
 * @param node  a subtree containing XML Schema information
11829
 * @param topLevel  whether this is a top-level element
11830
 * @returns the type definition or NULL in case of error
11831
 */
11832
static xmlSchemaTypePtr
11833
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11834
                          xmlNodePtr node, int topLevel)
11835
0
{
11836
0
    xmlSchemaTypePtr type, ctxtType;
11837
0
    xmlNodePtr child = NULL;
11838
0
    const xmlChar *name = NULL;
11839
0
    xmlAttrPtr attr;
11840
0
    const xmlChar *attrValue;
11841
#ifdef ENABLE_NAMED_LOCALS
11842
    char buf[40];
11843
#endif
11844
0
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
11845
11846
11847
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11848
0
        return (NULL);
11849
11850
0
    ctxtType = ctxt->ctxtType;
11851
11852
0
    if (topLevel) {
11853
0
  attr = xmlSchemaGetPropNode(node, "name");
11854
0
  if (attr == NULL) {
11855
0
      xmlSchemaPMissingAttrErr(ctxt,
11856
0
    XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
11857
0
      return (NULL);
11858
0
  } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
11859
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
11860
0
      return (NULL);
11861
0
  }
11862
0
    }
11863
11864
0
    if (topLevel == 0) {
11865
  /*
11866
  * Parse as local complex type definition.
11867
  */
11868
#ifdef ENABLE_NAMED_LOCALS
11869
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
11870
  type = xmlSchemaAddType(ctxt, schema,
11871
      XML_SCHEMA_TYPE_COMPLEX,
11872
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
11873
      ctxt->targetNamespace, node, 0);
11874
#else
11875
0
  type = xmlSchemaAddType(ctxt, schema,
11876
0
      XML_SCHEMA_TYPE_COMPLEX,
11877
0
      NULL, ctxt->targetNamespace, node, 0);
11878
0
#endif
11879
0
  if (type == NULL)
11880
0
      return (NULL);
11881
0
  name = type->name;
11882
0
  type->node = node;
11883
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
11884
  /*
11885
  * TODO: We need the target namespace.
11886
  */
11887
0
    } else {
11888
  /*
11889
  * Parse as global complex type definition.
11890
  */
11891
0
  type = xmlSchemaAddType(ctxt, schema,
11892
0
      XML_SCHEMA_TYPE_COMPLEX,
11893
0
      name, ctxt->targetNamespace, node, 1);
11894
0
  if (type == NULL)
11895
0
      return (NULL);
11896
0
  type->node = node;
11897
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
11898
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
11899
0
    }
11900
0
    type->targetNamespace = ctxt->targetNamespace;
11901
    /*
11902
    * Handle attributes.
11903
    */
11904
0
    attr = node->properties;
11905
0
    while (attr != NULL) {
11906
0
  if (attr->ns == NULL) {
11907
0
      if (xmlStrEqual(attr->name, BAD_CAST "id")) {
11908
    /*
11909
    * Attribute "id".
11910
    */
11911
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11912
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
11913
    /*
11914
    * Attribute "mixed".
11915
    */
11916
0
    if (xmlSchemaPGetBoolNodeValue(ctxt,
11917
0
      NULL, (xmlNodePtr) attr))
11918
0
        type->flags |= XML_SCHEMAS_TYPE_MIXED;
11919
0
      } else if (topLevel) {
11920
    /*
11921
    * Attributes of global complex type definitions.
11922
    */
11923
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
11924
        /* Pass. */
11925
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
11926
        /*
11927
        * Attribute "abstract".
11928
        */
11929
0
        if (xmlSchemaPGetBoolNodeValue(ctxt,
11930
0
          NULL, (xmlNodePtr) attr))
11931
0
      type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
11932
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
11933
        /*
11934
        * Attribute "final".
11935
        */
11936
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
11937
0
      (xmlNodePtr) attr);
11938
0
        if (xmlSchemaPValAttrBlockFinal(attrValue,
11939
0
      &(type->flags),
11940
0
      -1,
11941
0
      XML_SCHEMAS_TYPE_FINAL_EXTENSION,
11942
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
11943
0
      -1, -1, -1) != 0)
11944
0
        {
11945
0
      xmlSchemaPSimpleTypeErr(ctxt,
11946
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
11947
0
          NULL, (xmlNodePtr) attr, NULL,
11948
0
          "(#all | List of (extension | restriction))",
11949
0
          attrValue, NULL, NULL, NULL);
11950
0
        } else
11951
0
      final = 1;
11952
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
11953
        /*
11954
        * Attribute "block".
11955
        */
11956
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
11957
0
      (xmlNodePtr) attr);
11958
0
        if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
11959
0
      -1,
11960
0
      XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
11961
0
      XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
11962
0
      -1, -1, -1) != 0) {
11963
0
      xmlSchemaPSimpleTypeErr(ctxt,
11964
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
11965
0
          NULL, (xmlNodePtr) attr, NULL,
11966
0
          "(#all | List of (extension | restriction)) ",
11967
0
          attrValue, NULL, NULL, NULL);
11968
0
        } else
11969
0
      block = 1;
11970
0
    } else {
11971
0
      xmlSchemaPIllegalAttrErr(ctxt,
11972
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11973
0
    }
11974
0
      } else {
11975
0
    xmlSchemaPIllegalAttrErr(ctxt,
11976
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11977
0
      }
11978
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11979
0
      xmlSchemaPIllegalAttrErr(ctxt,
11980
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11981
0
  }
11982
0
  attr = attr->next;
11983
0
    }
11984
0
    if (! block) {
11985
  /*
11986
  * Apply default "block" values.
11987
  */
11988
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
11989
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
11990
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
11991
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
11992
0
    }
11993
0
    if (! final) {
11994
  /*
11995
  * Apply default "block" values.
11996
  */
11997
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
11998
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
11999
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12000
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12001
0
    }
12002
    /*
12003
    * And now for the children...
12004
    */
12005
0
    child = node->children;
12006
0
    if (IS_SCHEMA(child, "annotation")) {
12007
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12008
0
        child = child->next;
12009
0
    }
12010
0
    ctxt->ctxtType = type;
12011
0
    if (IS_SCHEMA(child, "simpleContent")) {
12012
  /*
12013
  * <complexType><simpleContent>...
12014
  * 3.4.3 : 2.2
12015
  * Specifying mixed='true' when the <simpleContent>
12016
  * alternative is chosen has no effect
12017
  */
12018
0
  if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12019
0
      type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12020
0
        xmlSchemaParseSimpleContent(ctxt, schema, child,
12021
0
      &hasRestrictionOrExtension);
12022
0
        child = child->next;
12023
0
    } else if (IS_SCHEMA(child, "complexContent")) {
12024
  /*
12025
  * <complexType><complexContent>...
12026
  */
12027
0
  type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12028
0
        xmlSchemaParseComplexContent(ctxt, schema, child,
12029
0
      &hasRestrictionOrExtension);
12030
0
        child = child->next;
12031
0
    } else {
12032
  /*
12033
  * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12034
  *
12035
  * SPEC
12036
  * "...the third alternative (neither <simpleContent> nor
12037
  * <complexContent>) is chosen. This case is understood as shorthand
12038
  * for complex content restricting the `ur-type definition`, and the
12039
  * details of the mappings should be modified as necessary.
12040
  */
12041
0
  type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12042
0
  type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12043
  /*
12044
  * Parse model groups.
12045
  */
12046
0
        if (IS_SCHEMA(child, "all")) {
12047
0
            type->subtypes = (xmlSchemaTypePtr)
12048
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12049
0
        XML_SCHEMA_TYPE_ALL, 1);
12050
0
            child = child->next;
12051
0
        } else if (IS_SCHEMA(child, "choice")) {
12052
0
            type->subtypes = (xmlSchemaTypePtr)
12053
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12054
0
        XML_SCHEMA_TYPE_CHOICE, 1);
12055
0
            child = child->next;
12056
0
        } else if (IS_SCHEMA(child, "sequence")) {
12057
0
            type->subtypes = (xmlSchemaTypePtr)
12058
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12059
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
12060
0
            child = child->next;
12061
0
        } else if (IS_SCHEMA(child, "group")) {
12062
0
            type->subtypes = (xmlSchemaTypePtr)
12063
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12064
      /*
12065
      * Note that the reference will be resolved in
12066
      * xmlSchemaResolveTypeReferences();
12067
      */
12068
0
            child = child->next;
12069
0
        }
12070
  /*
12071
  * Parse attribute decls/refs.
12072
  */
12073
0
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12074
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
12075
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12076
0
      return(NULL);
12077
  /*
12078
  * Parse attribute wildcard.
12079
  */
12080
0
  if (IS_SCHEMA(child, "anyAttribute")) {
12081
0
      type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12082
0
      child = child->next;
12083
0
  }
12084
0
    }
12085
0
    if (child != NULL) {
12086
0
  xmlSchemaPContentErr(ctxt,
12087
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12088
0
      NULL, node, child,
12089
0
      NULL, "(annotation?, (simpleContent | complexContent | "
12090
0
      "((group | all | choice | sequence)?, ((attribute | "
12091
0
      "attributeGroup)*, anyAttribute?))))");
12092
0
    }
12093
    /*
12094
    * REDEFINE: SPEC src-redefine (5)
12095
    */
12096
0
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12097
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12098
0
      NULL, node, "This is a redefinition, thus the "
12099
0
      "<complexType> must have a <restriction> or <extension> "
12100
0
      "grand-child", NULL);
12101
0
    }
12102
0
    ctxt->ctxtType = ctxtType;
12103
0
    return (type);
12104
0
}
12105
12106
/************************************************************************
12107
 *                  *
12108
 *      Validating using Schemas      *
12109
 *                  *
12110
 ************************************************************************/
12111
12112
/************************************************************************
12113
 *                  *
12114
 *      Reading/Writing Schemas       *
12115
 *                  *
12116
 ************************************************************************/
12117
12118
#if 0 /* Will be enabled if it is clear what options are needed. */
12119
/**
12120
 * Sets the options to be used during the parse.
12121
 *
12122
 * @param ctxt    a schema parser context
12123
 * @param options  a combination of xmlSchemaParserOption
12124
 * @returns 0 in case of success, -1 in case of an
12125
 * API error.
12126
 */
12127
static int
12128
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12129
            int options)
12130
12131
{
12132
    int i;
12133
12134
    if (ctxt == NULL)
12135
  return (-1);
12136
    /*
12137
    * WARNING: Change the start value if adding to the
12138
    * xmlSchemaParseOption.
12139
    */
12140
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
12141
        if (options & 1<<i) {
12142
      return (-1);
12143
        }
12144
    }
12145
    ctxt->options = options;
12146
    return (0);
12147
}
12148
12149
/**
12150
 * @param ctxt  a schema parser context
12151
 * @returns the option combination of the parser context.
12152
 */
12153
static int
12154
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12155
12156
{
12157
    if (ctxt == NULL)
12158
  return (-1);
12159
    else
12160
  return (ctxt->options);
12161
}
12162
#endif
12163
12164
/**
12165
 * Create an XML Schemas parse context for that file/resource expected
12166
 * to contain an XML Schemas file.
12167
 *
12168
 * @param URL  the location of the schema
12169
 * @returns the parser context or NULL in case of error
12170
 */
12171
xmlSchemaParserCtxt *
12172
xmlSchemaNewParserCtxt(const char *URL)
12173
0
{
12174
0
    xmlSchemaParserCtxtPtr ret;
12175
12176
0
    if (URL == NULL)
12177
0
        return (NULL);
12178
12179
0
    ret = xmlSchemaParserCtxtCreate();
12180
0
    if (ret == NULL)
12181
0
  return(NULL);
12182
0
    ret->dict = xmlDictCreate();
12183
0
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12184
0
    return (ret);
12185
0
}
12186
12187
/**
12188
 * Create an XML Schemas parse context for that memory buffer expected
12189
 * to contain an XML Schemas file.
12190
 *
12191
 * @param buffer  a pointer to a char array containing the schemas
12192
 * @param size  the size of the array
12193
 * @returns the parser context or NULL in case of error
12194
 */
12195
xmlSchemaParserCtxt *
12196
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12197
0
{
12198
0
    xmlSchemaParserCtxtPtr ret;
12199
12200
0
    if ((buffer == NULL) || (size <= 0))
12201
0
        return (NULL);
12202
0
    ret = xmlSchemaParserCtxtCreate();
12203
0
    if (ret == NULL)
12204
0
  return(NULL);
12205
0
    ret->buffer = buffer;
12206
0
    ret->size = size;
12207
0
    ret->dict = xmlDictCreate();
12208
0
    return (ret);
12209
0
}
12210
12211
/**
12212
 * Create an XML Schemas parse context for that document.
12213
 * NB. The document may be modified during the parsing process.
12214
 *
12215
 * @param doc  a preparsed document tree
12216
 * @returns the parser context or NULL in case of error
12217
 */
12218
xmlSchemaParserCtxt *
12219
xmlSchemaNewDocParserCtxt(xmlDoc *doc)
12220
0
{
12221
0
    xmlSchemaParserCtxtPtr ret;
12222
12223
0
    if (doc == NULL)
12224
0
      return (NULL);
12225
0
    ret = xmlSchemaParserCtxtCreate();
12226
0
    if (ret == NULL)
12227
0
  return(NULL);
12228
0
    ret->doc = doc;
12229
0
    ret->dict = xmlDictCreate();
12230
    /* The application has responsibility for the document */
12231
0
    ret->preserve = 1;
12232
12233
0
    return (ret);
12234
0
}
12235
12236
/**
12237
 * Free the resources associated to the schema parser context
12238
 *
12239
 * @param ctxt  the schema parser context
12240
 */
12241
void
12242
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxt *ctxt)
12243
0
{
12244
0
    if (ctxt == NULL)
12245
0
        return;
12246
0
    if (ctxt->doc != NULL && !ctxt->preserve)
12247
0
        xmlFreeDoc(ctxt->doc);
12248
0
    if (ctxt->vctxt != NULL) {
12249
0
  xmlSchemaFreeValidCtxt(ctxt->vctxt);
12250
0
    }
12251
0
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12252
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
12253
0
  ctxt->constructor = NULL;
12254
0
  ctxt->ownsConstructor = 0;
12255
0
    }
12256
0
    if (ctxt->attrProhibs != NULL)
12257
0
  xmlSchemaItemListFree(ctxt->attrProhibs);
12258
0
    xmlDictFree(ctxt->dict);
12259
0
    xmlFree(ctxt);
12260
0
}
12261
12262
/************************************************************************
12263
 *                  *
12264
 *      Building the content models     *
12265
 *                  *
12266
 ************************************************************************/
12267
12268
/**
12269
 * @returns 1 if nillable, 0 otherwise
12270
 */
12271
static int
12272
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12273
  xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12274
0
{
12275
0
    xmlAutomataStatePtr start, tmp;
12276
0
    xmlSchemaElementPtr elemDecl, member;
12277
0
    xmlSchemaSubstGroupPtr substGroup;
12278
0
    int i;
12279
0
    int ret = 0;
12280
12281
0
    elemDecl = (xmlSchemaElementPtr) particle->children;
12282
    /*
12283
    * Wrap the substitution group with a CHOICE.
12284
    */
12285
0
    start = pctxt->state;
12286
0
    if (end == NULL)
12287
0
  end = xmlAutomataNewState(pctxt->am);
12288
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12289
0
    if (substGroup == NULL) {
12290
0
  xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12291
0
      XML_SCHEMAP_INTERNAL,
12292
0
      "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12293
0
      "declaration is marked having a subst. group but none "
12294
0
      "available.\n", elemDecl->name, NULL);
12295
0
  return(0);
12296
0
    }
12297
0
    if (counter >= 0) {
12298
  /*
12299
  * NOTE that we put the declaration in, even if it's abstract.
12300
  * However, an error will be raised during *validation* if an element
12301
  * information item shall be validated against an abstract element
12302
  * declaration.
12303
  */
12304
0
  tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12305
0
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
12306
0
              elemDecl->name, elemDecl->targetNamespace, elemDecl);
12307
  /*
12308
  * Add subst. group members.
12309
  */
12310
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12311
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12312
0
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
12313
0
                   member->name, member->targetNamespace, member);
12314
0
  }
12315
0
    } else if (particle->maxOccurs == 1) {
12316
  /*
12317
  * NOTE that we put the declaration in, even if it's abstract,
12318
  */
12319
0
  xmlAutomataNewEpsilon(pctxt->am,
12320
0
      xmlAutomataNewTransition2(pctxt->am,
12321
0
      start, NULL,
12322
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12323
  /*
12324
  * Add subst. group members.
12325
  */
12326
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12327
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12328
      /*
12329
      * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12330
      *  was incorrectly used instead of xmlAutomataNewTransition2()
12331
      *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12332
      *  section in xmlSchemaBuildAContentModel() ).
12333
      * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12334
      *  intended for the above "counter" section originally. I.e.,
12335
      *  check xs:all with subst-groups.
12336
      *
12337
      * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12338
      *                member->name, member->targetNamespace,
12339
      *          1, 1, member);
12340
      */
12341
0
      tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12342
0
    member->name, member->targetNamespace, member);
12343
0
      xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12344
0
  }
12345
0
    } else {
12346
0
  xmlAutomataStatePtr hop;
12347
0
  int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12348
0
      UNBOUNDED : particle->maxOccurs - 1;
12349
0
  int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12350
12351
0
  counter =
12352
0
      xmlAutomataNewCounter(pctxt->am, minOccurs,
12353
0
      maxOccurs);
12354
0
  hop = xmlAutomataNewState(pctxt->am);
12355
12356
0
  xmlAutomataNewEpsilon(pctxt->am,
12357
0
      xmlAutomataNewTransition2(pctxt->am,
12358
0
      start, NULL,
12359
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl),
12360
0
      hop);
12361
  /*
12362
   * Add subst. group members.
12363
   */
12364
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12365
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12366
0
      xmlAutomataNewEpsilon(pctxt->am,
12367
0
    xmlAutomataNewTransition2(pctxt->am,
12368
0
    start, NULL,
12369
0
    member->name, member->targetNamespace, member),
12370
0
    hop);
12371
0
  }
12372
0
  xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12373
0
  xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12374
0
    }
12375
0
    if (particle->minOccurs == 0) {
12376
0
  xmlAutomataNewEpsilon(pctxt->am, start, end);
12377
0
        ret = 1;
12378
0
    }
12379
0
    pctxt->state = end;
12380
0
    return(ret);
12381
0
}
12382
12383
/**
12384
 * @returns 1 if nillable, 0 otherwise
12385
 */
12386
static int
12387
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12388
             xmlSchemaParticlePtr particle)
12389
0
{
12390
0
    int ret = 0;
12391
12392
0
    if (((xmlSchemaElementPtr) particle->children)->flags &
12393
0
  XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12394
  /*
12395
  * Substitution groups.
12396
  */
12397
0
  ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12398
0
    } else {
12399
0
  xmlSchemaElementPtr elemDecl;
12400
0
  xmlAutomataStatePtr start;
12401
12402
0
  elemDecl = (xmlSchemaElementPtr) particle->children;
12403
12404
0
  if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12405
0
      return(0);
12406
0
  if (particle->maxOccurs == 1) {
12407
0
      start = ctxt->state;
12408
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12409
0
        elemDecl->name, elemDecl->targetNamespace, elemDecl);
12410
0
  } else if ((particle->maxOccurs >= UNBOUNDED) &&
12411
0
             (particle->minOccurs < 2)) {
12412
      /* Special case. */
12413
0
      start = ctxt->state;
12414
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12415
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12416
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12417
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12418
0
  } else {
12419
0
      int counter;
12420
0
      int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12421
0
          UNBOUNDED : particle->maxOccurs - 1;
12422
0
      int minOccurs = particle->minOccurs < 1 ?
12423
0
          0 : particle->minOccurs - 1;
12424
12425
0
      start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12426
0
      counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12427
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12428
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12429
0
      xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12430
0
      ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12431
0
    NULL, counter);
12432
0
  }
12433
0
  if (particle->minOccurs == 0) {
12434
0
      xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12435
0
            ret = 1;
12436
0
        }
12437
0
    }
12438
0
    return(ret);
12439
0
}
12440
12441
/**
12442
 * Create the automaton for the {content type} of a complex type.
12443
 *
12444
 * @param pctxt  the schema parser context
12445
 * @param particle  the particle component
12446
 * @returns 1 if the content is nillable, 0 otherwise
12447
 */
12448
static int
12449
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12450
          xmlSchemaParticlePtr particle)
12451
0
{
12452
0
    int ret = 0, tmp2;
12453
12454
0
    if (particle == NULL) {
12455
0
  PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12456
0
  return(1);
12457
0
    }
12458
0
    if (particle->children == NULL) {
12459
  /*
12460
  * Just return in this case. A missing "term" of the particle
12461
  * might arise due to an invalid "term" component.
12462
  */
12463
0
  return(1);
12464
0
    }
12465
12466
0
    switch (particle->children->type) {
12467
0
  case XML_SCHEMA_TYPE_ANY: {
12468
0
      xmlAutomataStatePtr start, end;
12469
0
      xmlSchemaWildcardPtr wild;
12470
0
      xmlSchemaWildcardNsPtr ns;
12471
12472
0
      wild = (xmlSchemaWildcardPtr) particle->children;
12473
12474
0
      start = pctxt->state;
12475
0
      end = xmlAutomataNewState(pctxt->am);
12476
12477
0
      if (particle->maxOccurs == 1) {
12478
0
    if (wild->any == 1) {
12479
        /*
12480
        * We need to add both transitions:
12481
        *
12482
        * 1. the {"*", "*"} for elements in a namespace.
12483
        */
12484
0
        pctxt->state =
12485
0
      xmlAutomataNewTransition2(pctxt->am,
12486
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12487
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12488
        /*
12489
        * 2. the {"*"} for elements in no namespace.
12490
        */
12491
0
        pctxt->state =
12492
0
      xmlAutomataNewTransition2(pctxt->am,
12493
0
      start, NULL, BAD_CAST "*", NULL, wild);
12494
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12495
12496
0
    } else if (wild->nsSet != NULL) {
12497
0
        ns = wild->nsSet;
12498
0
        do {
12499
0
      pctxt->state = start;
12500
0
      pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12501
0
          pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12502
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12503
0
      ns = ns->next;
12504
0
        } while (ns != NULL);
12505
12506
0
    } else if (wild->negNsSet != NULL) {
12507
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12508
0
      start, end, BAD_CAST "*", wild->negNsSet->value,
12509
0
      wild);
12510
0
    }
12511
0
      } else {
12512
0
    int counter;
12513
0
    xmlAutomataStatePtr hop;
12514
0
    int maxOccurs =
12515
0
        particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12516
0
                                           particle->maxOccurs - 1;
12517
0
    int minOccurs =
12518
0
        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12519
12520
0
    counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12521
0
    hop = xmlAutomataNewState(pctxt->am);
12522
0
    if (wild->any == 1) {
12523
0
        pctxt->state =
12524
0
      xmlAutomataNewTransition2(pctxt->am,
12525
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12526
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12527
0
        pctxt->state =
12528
0
      xmlAutomataNewTransition2(pctxt->am,
12529
0
      start, NULL, BAD_CAST "*", NULL, wild);
12530
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12531
0
    } else if (wild->nsSet != NULL) {
12532
0
        ns = wild->nsSet;
12533
0
        do {
12534
0
      pctxt->state =
12535
0
          xmlAutomataNewTransition2(pctxt->am,
12536
0
        start, NULL, BAD_CAST "*", ns->value, wild);
12537
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12538
0
      ns = ns->next;
12539
0
        } while (ns != NULL);
12540
12541
0
    } else if (wild->negNsSet != NULL) {
12542
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12543
0
      start, hop, BAD_CAST "*", wild->negNsSet->value,
12544
0
      wild);
12545
0
    }
12546
0
    xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12547
0
    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12548
0
      }
12549
0
      if (particle->minOccurs == 0) {
12550
0
    xmlAutomataNewEpsilon(pctxt->am, start, end);
12551
0
                ret = 1;
12552
0
      }
12553
0
      pctxt->state = end;
12554
0
            break;
12555
0
  }
12556
0
        case XML_SCHEMA_TYPE_ELEMENT:
12557
0
      ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12558
0
      break;
12559
0
        case XML_SCHEMA_TYPE_SEQUENCE:{
12560
0
            xmlSchemaTreeItemPtr sub;
12561
12562
0
            ret = 1;
12563
            /*
12564
             * If max and min occurrences are default (1) then
12565
             * simply iterate over the particles of the <sequence>.
12566
             */
12567
0
            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12568
0
                sub = particle->children->children;
12569
12570
0
                while (sub != NULL) {
12571
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12572
0
                                        (xmlSchemaParticlePtr) sub);
12573
0
                    if (tmp2 != 1) ret = 0;
12574
0
                    sub = sub->next;
12575
0
                }
12576
0
            } else {
12577
0
                xmlAutomataStatePtr oldstate = pctxt->state;
12578
12579
0
                if (particle->maxOccurs >= UNBOUNDED) {
12580
0
                    if (particle->minOccurs > 1) {
12581
0
                        xmlAutomataStatePtr tmp;
12582
0
                        int counter;
12583
12584
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12585
0
                            oldstate, NULL);
12586
0
                        oldstate = pctxt->state;
12587
12588
0
                        counter = xmlAutomataNewCounter(pctxt->am,
12589
0
                            particle->minOccurs - 1, UNBOUNDED);
12590
12591
0
                        sub = particle->children->children;
12592
0
                        while (sub != NULL) {
12593
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12594
0
                                            (xmlSchemaParticlePtr) sub);
12595
0
                            if (tmp2 != 1) ret = 0;
12596
0
                            sub = sub->next;
12597
0
                        }
12598
0
                        tmp = pctxt->state;
12599
0
                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
12600
0
                                                   oldstate, counter);
12601
0
                        pctxt->state =
12602
0
                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
12603
0
                                                       NULL, counter);
12604
0
                        if (ret == 1)
12605
0
                            xmlAutomataNewEpsilon(pctxt->am,
12606
0
                                                oldstate, pctxt->state);
12607
12608
0
                    } else {
12609
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12610
0
                            oldstate, NULL);
12611
0
                        oldstate = pctxt->state;
12612
12613
0
                        sub = particle->children->children;
12614
0
                        while (sub != NULL) {
12615
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12616
0
                                        (xmlSchemaParticlePtr) sub);
12617
0
                            if (tmp2 != 1) ret = 0;
12618
0
                            sub = sub->next;
12619
0
                        }
12620
0
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12621
0
                                              oldstate);
12622
                        /*
12623
                         * epsilon needed to block previous trans from
12624
                         * being allowed to enter back from another
12625
                         * construct
12626
                         */
12627
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12628
0
                                            pctxt->state, NULL);
12629
0
                        if (particle->minOccurs == 0) {
12630
0
                            xmlAutomataNewEpsilon(pctxt->am,
12631
0
                                oldstate, pctxt->state);
12632
0
                            ret = 1;
12633
0
                        }
12634
0
                    }
12635
0
                } else if ((particle->maxOccurs > 1)
12636
0
                           || (particle->minOccurs > 1)) {
12637
0
                    xmlAutomataStatePtr tmp;
12638
0
                    int counter;
12639
12640
0
                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12641
0
                        oldstate, NULL);
12642
0
                    oldstate = pctxt->state;
12643
12644
0
                    counter = xmlAutomataNewCounter(pctxt->am,
12645
0
                        particle->minOccurs - 1,
12646
0
                        particle->maxOccurs - 1);
12647
12648
0
                    sub = particle->children->children;
12649
0
                    while (sub != NULL) {
12650
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12651
0
                                        (xmlSchemaParticlePtr) sub);
12652
0
                        if (tmp2 != 1) ret = 0;
12653
0
                        sub = sub->next;
12654
0
                    }
12655
0
                    tmp = pctxt->state;
12656
0
                    xmlAutomataNewCountedTrans(pctxt->am,
12657
0
                        tmp, oldstate, counter);
12658
0
                    pctxt->state =
12659
0
                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12660
0
                                                   counter);
12661
0
                    if ((particle->minOccurs == 0) || (ret == 1)) {
12662
0
                        xmlAutomataNewEpsilon(pctxt->am,
12663
0
                                            oldstate, pctxt->state);
12664
0
                        ret = 1;
12665
0
                    }
12666
0
                } else {
12667
0
                    sub = particle->children->children;
12668
0
                    while (sub != NULL) {
12669
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12670
0
                                        (xmlSchemaParticlePtr) sub);
12671
0
                        if (tmp2 != 1) ret = 0;
12672
0
                        sub = sub->next;
12673
0
                    }
12674
12675
        /*
12676
         * epsilon needed to block previous trans from
12677
         * being allowed to enter back from another
12678
         * construct
12679
         */
12680
0
        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12681
0
          pctxt->state, NULL);
12682
12683
0
                    if (particle->minOccurs == 0) {
12684
0
                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
12685
0
                                              pctxt->state);
12686
0
                        ret = 1;
12687
0
                    }
12688
0
                }
12689
0
            }
12690
0
            break;
12691
0
        }
12692
0
        case XML_SCHEMA_TYPE_CHOICE:{
12693
0
            xmlSchemaTreeItemPtr sub;
12694
0
            xmlAutomataStatePtr start, end;
12695
12696
0
            ret = 0;
12697
0
            start = pctxt->state;
12698
0
            end = xmlAutomataNewState(pctxt->am);
12699
12700
            /*
12701
             * iterate over the subtypes and remerge the end with an
12702
             * epsilon transition
12703
             */
12704
0
            if (particle->maxOccurs == 1) {
12705
0
                sub = particle->children->children;
12706
0
                while (sub != NULL) {
12707
0
                    pctxt->state = start;
12708
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12709
0
                                        (xmlSchemaParticlePtr) sub);
12710
0
                    if (tmp2 == 1) ret = 1;
12711
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12712
0
                    sub = sub->next;
12713
0
                }
12714
0
            } else {
12715
0
                int counter;
12716
0
                xmlAutomataStatePtr hop, base;
12717
0
                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12718
0
                    UNBOUNDED : particle->maxOccurs - 1;
12719
0
                int minOccurs =
12720
0
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12721
12722
                /*
12723
                 * use a counter to keep track of the number of transitions
12724
                 * which went through the choice.
12725
                 */
12726
0
                counter =
12727
0
                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12728
0
                hop = xmlAutomataNewState(pctxt->am);
12729
0
                base = xmlAutomataNewState(pctxt->am);
12730
12731
0
                sub = particle->children->children;
12732
0
                while (sub != NULL) {
12733
0
                    pctxt->state = base;
12734
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12735
0
                                        (xmlSchemaParticlePtr) sub);
12736
0
                    if (tmp2 == 1) ret = 1;
12737
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12738
0
                    sub = sub->next;
12739
0
                }
12740
0
                xmlAutomataNewEpsilon(pctxt->am, start, base);
12741
0
                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
12742
0
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12743
0
                if (ret == 1)
12744
0
                    xmlAutomataNewEpsilon(pctxt->am, base, end);
12745
0
            }
12746
0
            if (particle->minOccurs == 0) {
12747
0
                xmlAutomataNewEpsilon(pctxt->am, start, end);
12748
0
                ret = 1;
12749
0
            }
12750
0
            pctxt->state = end;
12751
0
            break;
12752
0
        }
12753
0
        case XML_SCHEMA_TYPE_ALL:{
12754
0
            xmlAutomataStatePtr start, tmp;
12755
0
            xmlSchemaParticlePtr sub;
12756
0
            xmlSchemaElementPtr elemDecl;
12757
12758
0
            ret = 1;
12759
12760
0
            sub = (xmlSchemaParticlePtr) particle->children->children;
12761
0
            if (sub == NULL)
12762
0
                break;
12763
12764
0
            ret = 0;
12765
12766
0
            start = pctxt->state;
12767
0
            tmp = xmlAutomataNewState(pctxt->am);
12768
0
            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
12769
0
            pctxt->state = tmp;
12770
0
            while (sub != NULL) {
12771
0
                pctxt->state = tmp;
12772
12773
0
                elemDecl = (xmlSchemaElementPtr) sub->children;
12774
0
                if (elemDecl == NULL) {
12775
0
                    PERROR_INT("xmlSchemaBuildAContentModel",
12776
0
                        "<element> particle has no term");
12777
0
                    return(ret);
12778
0
                };
12779
                /*
12780
                * NOTE: The {max occurs} of all the particles in the
12781
                * {particles} of the group must be 0 or 1; this is
12782
                * already ensured during the parse of the content of
12783
                * <all>.
12784
                */
12785
0
                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12786
0
                    int counter;
12787
12788
                    /*
12789
                     * This is an abstract group, we need to share
12790
                     * the same counter for all the element transitions
12791
                     * derived from the group
12792
                     */
12793
0
                    counter = xmlAutomataNewCounter(pctxt->am,
12794
0
                                       sub->minOccurs, sub->maxOccurs);
12795
0
                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
12796
0
                                       sub, counter, pctxt->state);
12797
0
                } else {
12798
0
                    if ((sub->minOccurs == 1) &&
12799
0
                        (sub->maxOccurs == 1)) {
12800
0
                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
12801
0
                                                pctxt->state,
12802
0
                                                elemDecl->name,
12803
0
                                                elemDecl->targetNamespace,
12804
0
                                                1, 1, elemDecl);
12805
0
                    } else if ((sub->minOccurs == 0) &&
12806
0
                        (sub->maxOccurs == 1)) {
12807
12808
0
                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
12809
0
                                                 pctxt->state,
12810
0
                                                 elemDecl->name,
12811
0
                                                 elemDecl->targetNamespace,
12812
0
                                                 0,
12813
0
                                                 1,
12814
0
                                                 elemDecl);
12815
0
                    }
12816
0
                }
12817
0
                sub = (xmlSchemaParticlePtr) sub->next;
12818
0
            }
12819
0
            pctxt->state =
12820
0
                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
12821
0
            if (particle->minOccurs == 0) {
12822
0
                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
12823
0
                ret = 1;
12824
0
            }
12825
0
            break;
12826
0
        }
12827
0
  case XML_SCHEMA_TYPE_GROUP:
12828
      /*
12829
      * If we hit a model group definition, then this means that
12830
      * it was empty, thus was not substituted for the containing
12831
      * model group. Just do nothing in this case.
12832
      * TODO: But the group should be substituted and not occur at
12833
      * all in the content model at this point. Fix this.
12834
      */
12835
0
            ret = 1;
12836
0
      break;
12837
0
        default:
12838
0
      xmlSchemaInternalErr2(ACTXT_CAST pctxt,
12839
0
    "xmlSchemaBuildAContentModel",
12840
0
    "found unexpected term of type '%s' in content model",
12841
0
    WXS_ITEM_TYPE_NAME(particle->children), NULL);
12842
0
            return(ret);
12843
0
    }
12844
0
    return(ret);
12845
0
}
12846
12847
/**
12848
 * Builds the content model of the complex type.
12849
 *
12850
 * @param type  the complex type definition
12851
 * @param ctxt  the schema parser context
12852
 */
12853
static void
12854
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
12855
         xmlSchemaParserCtxtPtr ctxt)
12856
0
{
12857
0
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
12858
0
  (type->contModel != NULL) ||
12859
0
  ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
12860
0
  (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
12861
0
  return;
12862
12863
0
    ctxt->am = NULL;
12864
0
    ctxt->am = xmlNewAutomata();
12865
0
    if (ctxt->am == NULL) {
12866
0
  xmlSchemaPErrMemory(ctxt);
12867
0
        return;
12868
0
    }
12869
0
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
12870
    /*
12871
    * Build the automaton.
12872
    */
12873
0
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
12874
0
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
12875
0
    type->contModel = xmlAutomataCompile(ctxt->am);
12876
0
    if (type->contModel == NULL) {
12877
0
        xmlSchemaPCustomErr(ctxt,
12878
0
      XML_SCHEMAP_INTERNAL,
12879
0
      WXS_BASIC_CAST type, type->node,
12880
0
      "Failed to compile the content model", NULL);
12881
0
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
12882
0
        xmlSchemaPCustomErr(ctxt,
12883
0
      XML_SCHEMAP_NOT_DETERMINISTIC,
12884
      /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
12885
0
      WXS_BASIC_CAST type, type->node,
12886
0
      "The content model is not determinist", NULL);
12887
0
    } else {
12888
0
    }
12889
0
    ctxt->state = NULL;
12890
0
    xmlFreeAutomata(ctxt->am);
12891
0
    ctxt->am = NULL;
12892
0
}
12893
12894
/**
12895
 * Resolves the references of an element declaration
12896
 * or particle, which has an element declaration as it's
12897
 * term.
12898
 *
12899
 * @param elemDecl  the schema element context
12900
 * @param ctxt  the schema parser context
12901
 */
12902
static void
12903
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
12904
          xmlSchemaParserCtxtPtr ctxt)
12905
0
{
12906
0
    if ((ctxt == NULL) || (elemDecl == NULL) ||
12907
0
  ((elemDecl != NULL) &&
12908
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
12909
0
        return;
12910
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
12911
12912
0
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
12913
0
  xmlSchemaTypePtr type;
12914
12915
  /* (type definition) ... otherwise the type definition `resolved`
12916
  * to by the `actual value` of the type [attribute] ...
12917
  */
12918
0
  type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
12919
0
      elemDecl->namedTypeNs);
12920
0
  if (type == NULL) {
12921
0
      xmlSchemaPResCompAttrErr(ctxt,
12922
0
    XML_SCHEMAP_SRC_RESOLVE,
12923
0
    WXS_BASIC_CAST elemDecl, elemDecl->node,
12924
0
    "type", elemDecl->namedType, elemDecl->namedTypeNs,
12925
0
    XML_SCHEMA_TYPE_BASIC, "type definition");
12926
0
  } else
12927
0
      elemDecl->subtypes = type;
12928
0
    }
12929
0
    if (elemDecl->substGroup != NULL) {
12930
0
  xmlSchemaElementPtr substHead;
12931
12932
  /*
12933
  * FIXME TODO: Do we need a new field in _xmlSchemaElement for
12934
  * substitutionGroup?
12935
  */
12936
0
  substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
12937
0
      elemDecl->substGroupNs);
12938
0
  if (substHead == NULL) {
12939
0
      xmlSchemaPResCompAttrErr(ctxt,
12940
0
    XML_SCHEMAP_SRC_RESOLVE,
12941
0
    WXS_BASIC_CAST elemDecl, NULL,
12942
0
    "substitutionGroup", elemDecl->substGroup,
12943
0
    elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
12944
0
  } else {
12945
0
      xmlSchemaResolveElementReferences(substHead, ctxt);
12946
      /*
12947
      * Set the "substitution group affiliation".
12948
      * NOTE that now we use the "refDecl" field for this.
12949
      */
12950
0
      WXS_SUBST_HEAD(elemDecl) = substHead;
12951
      /*
12952
      * The type definitions is set to:
12953
      * SPEC "...the {type definition} of the element
12954
      * declaration `resolved` to by the `actual value`
12955
      * of the substitutionGroup [attribute], if present"
12956
      */
12957
0
      if (elemDecl->subtypes == NULL) {
12958
0
                if (substHead->subtypes == NULL) {
12959
                    /*
12960
                     * This can happen with self-referencing substitution
12961
                     * groups. The cycle will be detected later, but we have
12962
                     * to set subtypes to avoid null-pointer dereferences.
12963
                     */
12964
0
              elemDecl->subtypes = xmlSchemaGetBuiltInType(
12965
0
                            XML_SCHEMAS_ANYTYPE);
12966
0
                } else {
12967
0
        elemDecl->subtypes = substHead->subtypes;
12968
0
                }
12969
0
            }
12970
0
  }
12971
0
    }
12972
    /*
12973
    * SPEC "The definition of anyType serves as the default type definition
12974
    * for element declarations whose XML representation does not specify one."
12975
    */
12976
0
    if ((elemDecl->subtypes == NULL) &&
12977
0
  (elemDecl->namedType == NULL) &&
12978
0
  (elemDecl->substGroup == NULL))
12979
0
  elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12980
0
}
12981
12982
/**
12983
 * Checks and builds the "member type definitions" property of the union
12984
 * simple type. This handles part (1), part (2) is done in
12985
 * xmlSchemaFinishMemberTypeDefinitionsProperty
12986
 *
12987
 * @param ctxt  the schema parser context
12988
 * @param type  the schema simple type definition
12989
 * @returns -1 in case of an internal error, 0 otherwise.
12990
 */
12991
static int
12992
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
12993
         xmlSchemaTypePtr type)
12994
0
{
12995
12996
0
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
12997
0
    xmlSchemaTypePtr memberType;
12998
12999
    /*
13000
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13001
    * define the explicit members as the type definitions `resolved`
13002
    * to by the items in the `actual value` of the memberTypes [attribute],
13003
    * if any, followed by the type definitions corresponding to the
13004
    * <simpleType>s among the [children] of <union>, if any."
13005
    */
13006
    /*
13007
    * Resolve references.
13008
    */
13009
0
    link = type->memberTypes;
13010
0
    lastLink = NULL;
13011
0
    while (link != NULL) {
13012
0
  const xmlChar *name, *nsName;
13013
13014
0
  name = ((xmlSchemaQNameRefPtr) link->type)->name;
13015
0
  nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13016
13017
0
  memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13018
0
  if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13019
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13020
0
    WXS_BASIC_CAST type, type->node, "memberTypes",
13021
0
    name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13022
      /*
13023
      * Remove the member type link.
13024
      */
13025
0
      if (lastLink == NULL)
13026
0
    type->memberTypes = link->next;
13027
0
      else
13028
0
    lastLink->next = link->next;
13029
0
      newLink = link;
13030
0
      link = link->next;
13031
0
      xmlFree(newLink);
13032
0
  } else {
13033
0
      link->type = memberType;
13034
0
      lastLink = link;
13035
0
      link = link->next;
13036
0
  }
13037
0
    }
13038
    /*
13039
    * Add local simple types,
13040
    */
13041
0
    memberType = type->subtypes;
13042
0
    while (memberType != NULL) {
13043
0
  link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13044
0
  if (link == NULL) {
13045
0
      xmlSchemaPErrMemory(ctxt);
13046
0
      return (-1);
13047
0
  }
13048
0
  link->type = memberType;
13049
0
  link->next = NULL;
13050
0
  if (lastLink == NULL)
13051
0
      type->memberTypes = link;
13052
0
  else
13053
0
      lastLink->next = link;
13054
0
  lastLink = link;
13055
0
  memberType = memberType->next;
13056
0
    }
13057
0
    return (0);
13058
0
}
13059
13060
/**
13061
 *
13062
 * @param type  the type definition
13063
 * @param valType  the value type
13064
 * @returns 1 if the type has the given value type, or
13065
 * is derived from such a type.
13066
 */
13067
static int
13068
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13069
0
{
13070
0
    if (type == NULL)
13071
0
  return (0);
13072
0
    if (WXS_IS_COMPLEX(type))
13073
0
  return (0);
13074
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13075
0
  if (type->builtInType == valType)
13076
0
      return(1);
13077
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13078
0
      (type->builtInType == XML_SCHEMAS_ANYTYPE))
13079
0
      return (0);
13080
0
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13081
0
    }
13082
0
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13083
0
}
13084
13085
#if 0
13086
/**
13087
 *
13088
 * @param ctxt  the schema parser context
13089
 * @param type  the type definition
13090
 * @param valType  the value type
13091
 * @returns 1 if the type has the given value type, or
13092
 * is derived from such a type.
13093
 */
13094
static int
13095
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13096
{
13097
    if (type == NULL)
13098
  return (0);
13099
    if (WXS_IS_COMPLEX(type))
13100
  return (0);
13101
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13102
  if (type->builtInType == valType)
13103
      return(1);
13104
  return (0);
13105
    } else
13106
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13107
13108
    return (0);
13109
}
13110
13111
static xmlSchemaTypePtr
13112
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13113
{
13114
    if (type == NULL)
13115
  return (NULL);
13116
    if (WXS_IS_COMPLEX(type))
13117
  return (NULL);
13118
    if (type->type == XML_SCHEMA_TYPE_BASIC)
13119
  return(type);
13120
    return(xmlSchemaQueryBuiltInType(type->subtypes));
13121
}
13122
#endif
13123
13124
/**
13125
 * @param type  the simpleType definition
13126
 * @returns the primitive type of the given type or
13127
 * NULL in case of error.
13128
 */
13129
static xmlSchemaTypePtr
13130
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13131
0
{
13132
13133
0
    while (type != NULL) {
13134
  /*
13135
  * Note that anySimpleType is actually not a primitive type
13136
  * but we need that here.
13137
  */
13138
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13139
0
     (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13140
0
      return (type);
13141
0
  type = type->baseType;
13142
0
    }
13143
13144
0
    return (NULL);
13145
0
}
13146
13147
#if 0
13148
/**
13149
 * @param type  the simpleType definition
13150
 * @returns the primitive type of the given type or
13151
 * NULL in case of error.
13152
 */
13153
static xmlSchemaTypePtr
13154
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13155
{
13156
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13157
  return (0);
13158
    while (type != NULL) {
13159
  if (type->type == XML_SCHEMA_TYPE_BASIC)
13160
      return (type);
13161
  type = type->baseType;
13162
    }
13163
13164
    return (NULL);
13165
}
13166
#endif
13167
13168
/**
13169
 * Clones the namespace constraints of source
13170
 * and assigns them to dest.
13171
 *
13172
 * @param ctxt  the schema parser context
13173
 * @param dest  the destination wildcard
13174
 * @param source  the source wildcard
13175
 * @returns -1 on internal error, 0 otherwise.
13176
 */
13177
static int
13178
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13179
            xmlSchemaWildcardPtr dest,
13180
            xmlSchemaWildcardPtr source)
13181
0
{
13182
0
    xmlSchemaWildcardNsPtr cur, tmp, last;
13183
13184
0
    if ((source == NULL) || (dest == NULL))
13185
0
  return(-1);
13186
0
    dest->any = source->any;
13187
0
    cur = source->nsSet;
13188
0
    last = NULL;
13189
0
    while (cur != NULL) {
13190
0
  tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13191
0
  if (tmp == NULL)
13192
0
      return(-1);
13193
0
  tmp->value = cur->value;
13194
0
  if (last == NULL)
13195
0
      dest->nsSet = tmp;
13196
0
  else
13197
0
      last->next = tmp;
13198
0
  last = tmp;
13199
0
  cur = cur->next;
13200
0
    }
13201
0
    if (dest->negNsSet != NULL)
13202
0
  xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13203
0
    if (source->negNsSet != NULL) {
13204
0
  dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13205
0
  if (dest->negNsSet == NULL)
13206
0
      return(-1);
13207
0
  dest->negNsSet->value = source->negNsSet->value;
13208
0
    } else
13209
0
  dest->negNsSet = NULL;
13210
0
    return(0);
13211
0
}
13212
13213
/**
13214
 * Unions the namespace constraints of the given wildcards.
13215
 * `completeWild` will hold the resulting union.
13216
 *
13217
 * @param ctxt  the schema parser context
13218
 * @param completeWild  the first wildcard
13219
 * @param curWild  the second wildcard
13220
 * @returns a positive error code on failure, -1 in case of an
13221
 * internal error, 0 otherwise.
13222
 */
13223
static int
13224
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13225
          xmlSchemaWildcardPtr completeWild,
13226
          xmlSchemaWildcardPtr curWild)
13227
0
{
13228
0
    xmlSchemaWildcardNsPtr cur, curB, tmp;
13229
13230
    /*
13231
    * 1 If O1 and O2 are the same value, then that value must be the
13232
    * value.
13233
    */
13234
0
    if ((completeWild->any == curWild->any) &&
13235
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13236
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13237
13238
0
  if ((completeWild->negNsSet == NULL) ||
13239
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13240
13241
0
      if (completeWild->nsSet != NULL) {
13242
0
    int found = 0;
13243
13244
    /*
13245
    * Check equality of sets.
13246
    */
13247
0
    cur = completeWild->nsSet;
13248
0
    while (cur != NULL) {
13249
0
        found = 0;
13250
0
        curB = curWild->nsSet;
13251
0
        while (curB != NULL) {
13252
0
      if (cur->value == curB->value) {
13253
0
          found = 1;
13254
0
          break;
13255
0
      }
13256
0
      curB = curB->next;
13257
0
        }
13258
0
        if (!found)
13259
0
      break;
13260
0
        cur = cur->next;
13261
0
    }
13262
0
    if (found)
13263
0
        return(0);
13264
0
      } else
13265
0
    return(0);
13266
0
  }
13267
0
    }
13268
    /*
13269
    * 2 If either O1 or O2 is any, then any must be the value
13270
    */
13271
0
    if (completeWild->any != curWild->any) {
13272
0
  if (completeWild->any == 0) {
13273
0
      completeWild->any = 1;
13274
0
      if (completeWild->nsSet != NULL) {
13275
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13276
0
    completeWild->nsSet = NULL;
13277
0
      }
13278
0
      if (completeWild->negNsSet != NULL) {
13279
0
    xmlFree(completeWild->negNsSet);
13280
0
    completeWild->negNsSet = NULL;
13281
0
      }
13282
0
  }
13283
0
  return (0);
13284
0
    }
13285
    /*
13286
    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13287
    * then the union of those sets must be the value.
13288
    */
13289
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13290
0
  int found;
13291
0
  xmlSchemaWildcardNsPtr start;
13292
13293
0
  cur = curWild->nsSet;
13294
0
  start = completeWild->nsSet;
13295
0
  while (cur != NULL) {
13296
0
      found = 0;
13297
0
      curB = start;
13298
0
      while (curB != NULL) {
13299
0
    if (cur->value == curB->value) {
13300
0
        found = 1;
13301
0
        break;
13302
0
    }
13303
0
    curB = curB->next;
13304
0
      }
13305
0
      if (!found) {
13306
0
    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13307
0
    if (tmp == NULL)
13308
0
        return (-1);
13309
0
    tmp->value = cur->value;
13310
0
    tmp->next = completeWild->nsSet;
13311
0
    completeWild->nsSet = tmp;
13312
0
      }
13313
0
      cur = cur->next;
13314
0
  }
13315
13316
0
  return(0);
13317
0
    }
13318
    /*
13319
    * 4 If the two are negations of different values (namespace names
13320
    * or `absent`), then a pair of not and `absent` must be the value.
13321
    */
13322
0
    if ((completeWild->negNsSet != NULL) &&
13323
0
  (curWild->negNsSet != NULL) &&
13324
0
  (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13325
0
  completeWild->negNsSet->value = NULL;
13326
13327
0
  return(0);
13328
0
    }
13329
    /*
13330
     * 5.
13331
     */
13332
0
    if (((completeWild->negNsSet != NULL) &&
13333
0
  (completeWild->negNsSet->value != NULL) &&
13334
0
  (curWild->nsSet != NULL)) ||
13335
0
  ((curWild->negNsSet != NULL) &&
13336
0
  (curWild->negNsSet->value != NULL) &&
13337
0
  (completeWild->nsSet != NULL))) {
13338
13339
0
  int nsFound, absentFound = 0;
13340
13341
0
  if (completeWild->nsSet != NULL) {
13342
0
      cur = completeWild->nsSet;
13343
0
      curB = curWild->negNsSet;
13344
0
  } else {
13345
0
      cur = curWild->nsSet;
13346
0
      curB = completeWild->negNsSet;
13347
0
  }
13348
0
  nsFound = 0;
13349
0
  while (cur != NULL) {
13350
0
      if (cur->value == NULL)
13351
0
    absentFound = 1;
13352
0
      else if (cur->value == curB->value)
13353
0
    nsFound = 1;
13354
0
      if (nsFound && absentFound)
13355
0
    break;
13356
0
      cur = cur->next;
13357
0
  }
13358
13359
0
  if (nsFound && absentFound) {
13360
      /*
13361
      * 5.1 If the set S includes both the negated namespace
13362
      * name and `absent`, then any must be the value.
13363
      */
13364
0
      completeWild->any = 1;
13365
0
      if (completeWild->nsSet != NULL) {
13366
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13367
0
    completeWild->nsSet = NULL;
13368
0
      }
13369
0
      if (completeWild->negNsSet != NULL) {
13370
0
    xmlFree(completeWild->negNsSet);
13371
0
    completeWild->negNsSet = NULL;
13372
0
      }
13373
0
  } else if (nsFound && (!absentFound)) {
13374
      /*
13375
      * 5.2 If the set S includes the negated namespace name
13376
      * but not `absent`, then a pair of not and `absent` must
13377
      * be the value.
13378
      */
13379
0
      if (completeWild->nsSet != NULL) {
13380
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13381
0
    completeWild->nsSet = NULL;
13382
0
      }
13383
0
      if (completeWild->negNsSet == NULL) {
13384
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13385
0
    if (completeWild->negNsSet == NULL)
13386
0
        return (-1);
13387
0
      }
13388
0
      completeWild->negNsSet->value = NULL;
13389
0
  } else if ((!nsFound) && absentFound) {
13390
      /*
13391
      * 5.3 If the set S includes `absent` but not the negated
13392
      * namespace name, then the union is not expressible.
13393
      */
13394
0
      xmlSchemaPErr(ctxt, completeWild->node,
13395
0
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13396
0
    "The union of the wildcard is not expressible.\n",
13397
0
    NULL, NULL);
13398
0
      return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13399
0
  } else if ((!nsFound) && (!absentFound)) {
13400
      /*
13401
      * 5.4 If the set S does not include either the negated namespace
13402
      * name or `absent`, then whichever of O1 or O2 is a pair of not
13403
      * and a namespace name must be the value.
13404
      */
13405
0
      if (completeWild->negNsSet == NULL) {
13406
0
    if (completeWild->nsSet != NULL) {
13407
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13408
0
        completeWild->nsSet = NULL;
13409
0
    }
13410
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13411
0
    if (completeWild->negNsSet == NULL)
13412
0
        return (-1);
13413
0
    completeWild->negNsSet->value = curWild->negNsSet->value;
13414
0
      }
13415
0
  }
13416
0
  return (0);
13417
0
    }
13418
    /*
13419
     * 6.
13420
     */
13421
0
    if (((completeWild->negNsSet != NULL) &&
13422
0
  (completeWild->negNsSet->value == NULL) &&
13423
0
  (curWild->nsSet != NULL)) ||
13424
0
  ((curWild->negNsSet != NULL) &&
13425
0
  (curWild->negNsSet->value == NULL) &&
13426
0
  (completeWild->nsSet != NULL))) {
13427
13428
0
  if (completeWild->nsSet != NULL) {
13429
0
      cur = completeWild->nsSet;
13430
0
  } else {
13431
0
      cur = curWild->nsSet;
13432
0
  }
13433
0
  while (cur != NULL) {
13434
0
      if (cur->value == NULL) {
13435
    /*
13436
    * 6.1 If the set S includes `absent`, then any must be the
13437
    * value.
13438
    */
13439
0
    completeWild->any = 1;
13440
0
    if (completeWild->nsSet != NULL) {
13441
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13442
0
        completeWild->nsSet = NULL;
13443
0
    }
13444
0
    if (completeWild->negNsSet != NULL) {
13445
0
        xmlFree(completeWild->negNsSet);
13446
0
        completeWild->negNsSet = NULL;
13447
0
    }
13448
0
    return (0);
13449
0
      }
13450
0
      cur = cur->next;
13451
0
  }
13452
0
  if (completeWild->negNsSet == NULL) {
13453
      /*
13454
      * 6.2 If the set S does not include `absent`, then a pair of not
13455
      * and `absent` must be the value.
13456
      */
13457
0
      if (completeWild->nsSet != NULL) {
13458
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13459
0
    completeWild->nsSet = NULL;
13460
0
      }
13461
0
      completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13462
0
      if (completeWild->negNsSet == NULL)
13463
0
    return (-1);
13464
0
      completeWild->negNsSet->value = NULL;
13465
0
  }
13466
0
  return (0);
13467
0
    }
13468
0
    return (0);
13469
13470
0
}
13471
13472
/**
13473
 * Intersects the namespace constraints of the given wildcards.
13474
 * `completeWild` will hold the resulting intersection.
13475
 *
13476
 * @param ctxt  the schema parser context
13477
 * @param completeWild  the first wildcard
13478
 * @param curWild  the second wildcard
13479
 * @returns a positive error code on failure, -1 in case of an
13480
 * internal error, 0 otherwise.
13481
 */
13482
static int
13483
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13484
          xmlSchemaWildcardPtr completeWild,
13485
          xmlSchemaWildcardPtr curWild)
13486
0
{
13487
0
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13488
13489
    /*
13490
    * 1 If O1 and O2 are the same value, then that value must be the
13491
    * value.
13492
    */
13493
0
    if ((completeWild->any == curWild->any) &&
13494
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13495
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13496
13497
0
  if ((completeWild->negNsSet == NULL) ||
13498
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13499
13500
0
      if (completeWild->nsSet != NULL) {
13501
0
    int found = 0;
13502
13503
    /*
13504
    * Check equality of sets.
13505
    */
13506
0
    cur = completeWild->nsSet;
13507
0
    while (cur != NULL) {
13508
0
        found = 0;
13509
0
        curB = curWild->nsSet;
13510
0
        while (curB != NULL) {
13511
0
      if (cur->value == curB->value) {
13512
0
          found = 1;
13513
0
          break;
13514
0
      }
13515
0
      curB = curB->next;
13516
0
        }
13517
0
        if (!found)
13518
0
      break;
13519
0
        cur = cur->next;
13520
0
    }
13521
0
    if (found)
13522
0
        return(0);
13523
0
      } else
13524
0
    return(0);
13525
0
  }
13526
0
    }
13527
    /*
13528
    * 2 If either O1 or O2 is any, then the other must be the value.
13529
    */
13530
0
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
13531
0
  if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13532
0
      return(-1);
13533
0
  return(0);
13534
0
    }
13535
    /*
13536
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
13537
    * name or `absent`) and the other is a set of (namespace names or
13538
    * `absent`), then that set, minus the negated value if it was in
13539
    * the set, minus `absent` if it was in the set, must be the value.
13540
    */
13541
0
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13542
0
  ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13543
0
  const xmlChar *neg;
13544
13545
0
  if (completeWild->nsSet == NULL) {
13546
0
      neg = completeWild->negNsSet->value;
13547
0
      if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13548
0
    return(-1);
13549
0
  } else
13550
0
      neg = curWild->negNsSet->value;
13551
  /*
13552
  * Remove absent and negated.
13553
  */
13554
0
  prev = NULL;
13555
0
  cur = completeWild->nsSet;
13556
0
  while (cur != NULL) {
13557
0
      if (cur->value == NULL) {
13558
0
    if (prev == NULL)
13559
0
        completeWild->nsSet = cur->next;
13560
0
    else
13561
0
        prev->next = cur->next;
13562
0
    xmlFree(cur);
13563
0
    break;
13564
0
      }
13565
0
      prev = cur;
13566
0
      cur = cur->next;
13567
0
  }
13568
0
  if (neg != NULL) {
13569
0
      prev = NULL;
13570
0
      cur = completeWild->nsSet;
13571
0
      while (cur != NULL) {
13572
0
    if (cur->value == neg) {
13573
0
        if (prev == NULL)
13574
0
      completeWild->nsSet = cur->next;
13575
0
        else
13576
0
      prev->next = cur->next;
13577
0
        xmlFree(cur);
13578
0
        break;
13579
0
    }
13580
0
    prev = cur;
13581
0
    cur = cur->next;
13582
0
      }
13583
0
  }
13584
13585
0
  return(0);
13586
0
    }
13587
    /*
13588
    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13589
    * then the intersection of those sets must be the value.
13590
    */
13591
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13592
0
  int found;
13593
13594
0
  cur = completeWild->nsSet;
13595
0
  prev = NULL;
13596
0
  while (cur != NULL) {
13597
0
      found = 0;
13598
0
      curB = curWild->nsSet;
13599
0
      while (curB != NULL) {
13600
0
    if (cur->value == curB->value) {
13601
0
        found = 1;
13602
0
        break;
13603
0
    }
13604
0
    curB = curB->next;
13605
0
      }
13606
0
      if (!found) {
13607
0
    if (prev == NULL)
13608
0
        completeWild->nsSet = cur->next;
13609
0
    else
13610
0
        prev->next = cur->next;
13611
0
    tmp = cur->next;
13612
0
    xmlFree(cur);
13613
0
    cur = tmp;
13614
0
    continue;
13615
0
      }
13616
0
      prev = cur;
13617
0
      cur = cur->next;
13618
0
  }
13619
13620
0
  return(0);
13621
0
    }
13622
    /* 5 If the two are negations of different namespace names,
13623
    * then the intersection is not expressible
13624
    */
13625
0
    if ((completeWild->negNsSet != NULL) &&
13626
0
  (curWild->negNsSet != NULL) &&
13627
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13628
0
  (completeWild->negNsSet->value != NULL) &&
13629
0
  (curWild->negNsSet->value != NULL)) {
13630
13631
0
  xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13632
0
      "The intersection of the wildcard is not expressible.\n",
13633
0
      NULL, NULL);
13634
0
  return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13635
0
    }
13636
    /*
13637
    * 6 If the one is a negation of a namespace name and the other
13638
    * is a negation of `absent`, then the one which is the negation
13639
    * of a namespace name must be the value.
13640
    */
13641
0
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13642
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13643
0
  (completeWild->negNsSet->value == NULL)) {
13644
0
  completeWild->negNsSet->value =  curWild->negNsSet->value;
13645
0
    }
13646
0
    return(0);
13647
0
}
13648
13649
/**
13650
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13651
 *
13652
 * @param sub  the first wildcard
13653
 * @param super  the second wildcard
13654
 * @returns 0 if the namespace constraint of `sub` is an intensional
13655
 * subset of `super`, 1 otherwise.
13656
 */
13657
static int
13658
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13659
        xmlSchemaWildcardPtr super)
13660
0
{
13661
    /*
13662
    * 1 super must be any.
13663
    */
13664
0
    if (super->any)
13665
0
  return (0);
13666
    /*
13667
    * 2.1 sub must be a pair of not and a namespace name or `absent`.
13668
    * 2.2 super must be a pair of not and the same value.
13669
    */
13670
0
    if ((sub->negNsSet != NULL) &&
13671
0
  (super->negNsSet != NULL) &&
13672
0
  (sub->negNsSet->value == super->negNsSet->value))
13673
0
  return (0);
13674
    /*
13675
    * 3.1 sub must be a set whose members are either namespace names or `absent`.
13676
    */
13677
0
    if (sub->nsSet != NULL) {
13678
  /*
13679
  * 3.2.1 super must be the same set or a superset thereof.
13680
  */
13681
0
  if (super->nsSet != NULL) {
13682
0
      xmlSchemaWildcardNsPtr cur, curB;
13683
0
      int found = 0;
13684
13685
0
      cur = sub->nsSet;
13686
0
      while (cur != NULL) {
13687
0
    found = 0;
13688
0
    curB = super->nsSet;
13689
0
    while (curB != NULL) {
13690
0
        if (cur->value == curB->value) {
13691
0
      found = 1;
13692
0
      break;
13693
0
        }
13694
0
        curB = curB->next;
13695
0
    }
13696
0
    if (!found)
13697
0
        return (1);
13698
0
    cur = cur->next;
13699
0
      }
13700
0
      if (found)
13701
0
    return (0);
13702
0
  } else if (super->negNsSet != NULL) {
13703
0
      xmlSchemaWildcardNsPtr cur;
13704
      /*
13705
      * 3.2.2 super must be a pair of not and a namespace name or
13706
      * `absent` and that value must not be in sub's set.
13707
      */
13708
0
      cur = sub->nsSet;
13709
0
      while (cur != NULL) {
13710
0
    if (cur->value == super->negNsSet->value)
13711
0
        return (1);
13712
0
    cur = cur->next;
13713
0
      }
13714
0
      return (0);
13715
0
  }
13716
0
    }
13717
0
    return (1);
13718
0
}
13719
13720
static int
13721
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13722
             int *fixed,
13723
             const xmlChar **value,
13724
             xmlSchemaValPtr *val)
13725
0
{
13726
0
    *fixed = 0;
13727
0
    *value = NULL;
13728
0
    if (val != 0)
13729
0
  *val = NULL;
13730
13731
0
    if (attruse->defValue != NULL) {
13732
0
  *value = attruse->defValue;
13733
0
  if (val != NULL)
13734
0
      *val = attruse->defVal;
13735
0
  if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
13736
0
      *fixed = 1;
13737
0
  return(1);
13738
0
    } else if ((attruse->attrDecl != NULL) &&
13739
0
  (attruse->attrDecl->defValue != NULL)) {
13740
0
  *value = attruse->attrDecl->defValue;
13741
0
  if (val != NULL)
13742
0
      *val = attruse->attrDecl->defVal;
13743
0
  if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
13744
0
      *fixed = 1;
13745
0
  return(1);
13746
0
    }
13747
0
    return(0);
13748
0
}
13749
/**
13750
 * Validation Rule: Wildcard allows Namespace Name
13751
 * (cvc-wildcard-namespace)
13752
 *
13753
 * @param wild  the wildcard
13754
 * @param ns  the namespace
13755
 * @returns 0 if the given namespace matches the wildcard,
13756
 * 1 otherwise and -1 on API errors.
13757
 */
13758
static int
13759
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
13760
           const xmlChar* ns)
13761
0
{
13762
0
    if (wild == NULL)
13763
0
  return(-1);
13764
13765
0
    if (wild->any)
13766
0
  return(0);
13767
0
    else if (wild->nsSet != NULL) {
13768
0
  xmlSchemaWildcardNsPtr cur;
13769
13770
0
  cur = wild->nsSet;
13771
0
  while (cur != NULL) {
13772
0
      if (xmlStrEqual(cur->value, ns))
13773
0
    return(0);
13774
0
      cur = cur->next;
13775
0
  }
13776
0
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
13777
0
  (!xmlStrEqual(wild->negNsSet->value, ns)))
13778
0
  return(0);
13779
13780
0
    return(1);
13781
0
}
13782
13783
0
#define XML_SCHEMA_ACTION_DERIVE 0
13784
0
#define XML_SCHEMA_ACTION_REDEFINE 1
13785
13786
0
#define WXS_ACTION_STR(a) \
13787
0
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
13788
13789
/*
13790
* Schema Component Constraint:
13791
*   Derivation Valid (Restriction, Complex)
13792
*   derivation-ok-restriction (2) - (4)
13793
*
13794
* ATTENTION:
13795
* In XML Schema 1.1 this will be:
13796
* Validation Rule:
13797
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
13798
*
13799
*/
13800
static int
13801
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
13802
               int action,
13803
               xmlSchemaBasicItemPtr item,
13804
               xmlSchemaBasicItemPtr baseItem,
13805
               xmlSchemaItemListPtr uses,
13806
               xmlSchemaItemListPtr baseUses,
13807
               xmlSchemaWildcardPtr wild,
13808
               xmlSchemaWildcardPtr baseWild)
13809
0
{
13810
0
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
13811
0
    int i, j, found; /* err = 0; */
13812
0
    const xmlChar *bEffValue;
13813
0
    int effFixed;
13814
13815
0
    if (uses != NULL) {
13816
0
  for (i = 0; i < uses->nbItems; i++) {
13817
0
      cur = uses->items[i];
13818
0
      found = 0;
13819
0
      if (baseUses == NULL)
13820
0
    goto not_found;
13821
0
      for (j = 0; j < baseUses->nbItems; j++) {
13822
0
    bcur = baseUses->items[j];
13823
0
    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
13824
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
13825
0
        (WXS_ATTRUSE_DECL_TNS(cur) ==
13826
0
      WXS_ATTRUSE_DECL_TNS(bcur)))
13827
0
    {
13828
        /*
13829
        * (2.1) "If there is an attribute use in the {attribute
13830
        * uses} of the {base type definition} (call this B) whose
13831
        * {attribute declaration} has the same {name} and {target
13832
        * namespace}, then  all of the following must be true:"
13833
        */
13834
0
        found = 1;
13835
13836
0
        if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
13837
0
      (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
13838
0
        {
13839
0
      xmlChar *str = NULL;
13840
      /*
13841
      * (2.1.1) "one of the following must be true:"
13842
      * (2.1.1.1) "B's {required} is false."
13843
      * (2.1.1.2) "R's {required} is true."
13844
      */
13845
0
      xmlSchemaPAttrUseErr4(pctxt,
13846
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
13847
0
          WXS_ITEM_NODE(item), item, cur,
13848
0
          "The 'optional' attribute use is inconsistent "
13849
0
          "with the corresponding 'required' attribute use of "
13850
0
          "the %s %s",
13851
0
          WXS_ACTION_STR(action),
13852
0
          xmlSchemaGetComponentDesignation(&str, baseItem),
13853
0
          NULL, NULL);
13854
0
      FREE_AND_NULL(str);
13855
      /* err = pctxt->err; */
13856
0
        } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
13857
0
      WXS_ATTRUSE_TYPEDEF(cur),
13858
0
      WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
13859
0
        {
13860
0
      xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
13861
13862
      /*
13863
      * SPEC (2.1.2) "R's {attribute declaration}'s
13864
      * {type definition} must be validly derived from
13865
      * B's {type definition} given the empty set as
13866
      * defined in Type Derivation OK (Simple) ($3.14.6)."
13867
      */
13868
0
      xmlSchemaPAttrUseErr4(pctxt,
13869
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
13870
0
          WXS_ITEM_NODE(item), item, cur,
13871
0
          "The attribute declaration's %s "
13872
0
          "is not validly derived from "
13873
0
          "the corresponding %s of the "
13874
0
          "attribute declaration in the %s %s",
13875
0
          xmlSchemaGetComponentDesignation(&strA,
13876
0
        WXS_ATTRUSE_TYPEDEF(cur)),
13877
0
          xmlSchemaGetComponentDesignation(&strB,
13878
0
        WXS_ATTRUSE_TYPEDEF(bcur)),
13879
0
          WXS_ACTION_STR(action),
13880
0
          xmlSchemaGetComponentDesignation(&strC, baseItem));
13881
          /* xmlSchemaGetComponentDesignation(&str, baseItem), */
13882
0
      FREE_AND_NULL(strA);
13883
0
      FREE_AND_NULL(strB);
13884
0
      FREE_AND_NULL(strC);
13885
      /* err = pctxt->err; */
13886
0
        } else {
13887
      /*
13888
      * 2.1.3 [Definition:]  Let the effective value
13889
      * constraint of an attribute use be its {value
13890
      * constraint}, if present, otherwise its {attribute
13891
      * declaration}'s {value constraint} .
13892
      */
13893
0
      xmlSchemaGetEffectiveValueConstraint(bcur,
13894
0
          &effFixed, &bEffValue, NULL);
13895
      /*
13896
      * 2.1.3 ... one of the following must be true
13897
      *
13898
      * 2.1.3.1 B's `effective value constraint` is
13899
      * `absent` or default.
13900
      */
13901
0
      if ((bEffValue != NULL) &&
13902
0
          (effFixed == 1)) {
13903
0
          const xmlChar *rEffValue = NULL;
13904
13905
0
          xmlSchemaGetEffectiveValueConstraint(bcur,
13906
0
        &effFixed, &rEffValue, NULL);
13907
          /*
13908
          * 2.1.3.2 R's `effective value constraint` is
13909
          * fixed with the same string as B's.
13910
          * MAYBE TODO: Compare the computed values.
13911
          *       Hmm, it says "same string" so
13912
          *       string-equality might really be sufficient.
13913
          */
13914
0
          if ((effFixed == 0) ||
13915
0
        (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
13916
0
          {
13917
0
        xmlChar *str = NULL;
13918
13919
0
        xmlSchemaPAttrUseErr4(pctxt,
13920
0
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
13921
0
            WXS_ITEM_NODE(item), item, cur,
13922
0
            "The effective value constraint of the "
13923
0
            "attribute use is inconsistent with "
13924
0
            "its correspondent in the %s %s",
13925
0
            WXS_ACTION_STR(action),
13926
0
            xmlSchemaGetComponentDesignation(&str,
13927
0
          baseItem),
13928
0
            NULL, NULL);
13929
0
        FREE_AND_NULL(str);
13930
        /* err = pctxt->err; */
13931
0
          }
13932
0
      }
13933
0
        }
13934
0
        break;
13935
0
    }
13936
0
      }
13937
0
not_found:
13938
0
      if (!found) {
13939
    /*
13940
    * (2.2) "otherwise the {base type definition} must have an
13941
    * {attribute wildcard} and the {target namespace} of the
13942
    * R's {attribute declaration} must be `valid` with respect
13943
    * to that wildcard, as defined in Wildcard allows Namespace
13944
    * Name ($3.10.4)."
13945
    */
13946
0
    if ((baseWild == NULL) ||
13947
0
        (xmlSchemaCheckCVCWildcardNamespace(baseWild,
13948
0
        (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
13949
0
    {
13950
0
        xmlChar *str = NULL;
13951
13952
0
        xmlSchemaPAttrUseErr4(pctxt,
13953
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
13954
0
      WXS_ITEM_NODE(item), item, cur,
13955
0
      "Neither a matching attribute use, "
13956
0
      "nor a matching wildcard exists in the %s %s",
13957
0
      WXS_ACTION_STR(action),
13958
0
      xmlSchemaGetComponentDesignation(&str, baseItem),
13959
0
      NULL, NULL);
13960
0
        FREE_AND_NULL(str);
13961
        /* err = pctxt->err; */
13962
0
    }
13963
0
      }
13964
0
  }
13965
0
    }
13966
    /*
13967
    * SPEC derivation-ok-restriction (3):
13968
    * (3) "For each attribute use in the {attribute uses} of the {base type
13969
    * definition} whose {required} is true, there must be an attribute
13970
    * use with an {attribute declaration} with the same {name} and
13971
    * {target namespace} as its {attribute declaration} in the {attribute
13972
    * uses} of the complex type definition itself whose {required} is true.
13973
    */
13974
0
    if (baseUses != NULL) {
13975
0
  for (j = 0; j < baseUses->nbItems; j++) {
13976
0
      bcur = baseUses->items[j];
13977
0
      if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
13978
0
    continue;
13979
0
      found = 0;
13980
0
      if (uses != NULL) {
13981
0
    for (i = 0; i < uses->nbItems; i++) {
13982
0
        cur = uses->items[i];
13983
0
        if ((WXS_ATTRUSE_DECL_NAME(cur) ==
13984
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
13985
0
      (WXS_ATTRUSE_DECL_TNS(cur) ==
13986
0
      WXS_ATTRUSE_DECL_TNS(bcur))) {
13987
0
      found = 1;
13988
0
      break;
13989
0
        }
13990
0
    }
13991
0
      }
13992
0
      if (!found) {
13993
0
    xmlChar *strA = NULL, *strB = NULL;
13994
13995
0
    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
13996
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
13997
0
        NULL, item,
13998
0
        "A matching attribute use for the "
13999
0
        "'required' %s of the %s %s is missing",
14000
0
        xmlSchemaGetComponentDesignation(&strA, bcur),
14001
0
        WXS_ACTION_STR(action),
14002
0
        xmlSchemaGetComponentDesignation(&strB, baseItem),
14003
0
        NULL);
14004
0
    FREE_AND_NULL(strA);
14005
0
    FREE_AND_NULL(strB);
14006
0
      }
14007
0
  }
14008
0
    }
14009
    /*
14010
    * derivation-ok-restriction (4)
14011
    */
14012
0
    if (wild != NULL) {
14013
  /*
14014
  * (4) "If there is an {attribute wildcard}, all of the
14015
  * following must be true:"
14016
  */
14017
0
  if (baseWild == NULL) {
14018
0
      xmlChar *str = NULL;
14019
14020
      /*
14021
      * (4.1) "The {base type definition} must also have one."
14022
      */
14023
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14024
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14025
0
    NULL, item,
14026
0
    "The %s has an attribute wildcard, "
14027
0
    "but the %s %s '%s' does not have one",
14028
0
    WXS_ITEM_TYPE_NAME(item),
14029
0
    WXS_ACTION_STR(action),
14030
0
    WXS_ITEM_TYPE_NAME(baseItem),
14031
0
    xmlSchemaGetComponentQName(&str, baseItem));
14032
0
      FREE_AND_NULL(str);
14033
0
      return(pctxt->err);
14034
0
  } else if ((baseWild->any == 0) &&
14035
0
    xmlSchemaCheckCOSNSSubset(wild, baseWild))
14036
0
  {
14037
0
      xmlChar *str = NULL;
14038
      /*
14039
      * (4.2) "The complex type definition's {attribute wildcard}'s
14040
      * {namespace constraint} must be a subset of the {base type
14041
      * definition}'s {attribute wildcard}'s {namespace constraint},
14042
      * as defined by Wildcard Subset ($3.10.6)."
14043
      */
14044
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14045
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14046
0
    NULL, item,
14047
0
    "The attribute wildcard is not a valid "
14048
0
    "subset of the wildcard in the %s %s '%s'",
14049
0
    WXS_ACTION_STR(action),
14050
0
    WXS_ITEM_TYPE_NAME(baseItem),
14051
0
    xmlSchemaGetComponentQName(&str, baseItem),
14052
0
    NULL);
14053
0
      FREE_AND_NULL(str);
14054
0
      return(pctxt->err);
14055
0
  }
14056
  /* 4.3 Unless the {base type definition} is the `ur-type
14057
  * definition`, the complex type definition's {attribute
14058
  * wildcard}'s {process contents} must be identical to or
14059
  * stronger than the {base type definition}'s {attribute
14060
  * wildcard}'s {process contents}, where strict is stronger
14061
  * than lax is stronger than skip.
14062
  */
14063
0
  if ((! WXS_IS_ANYTYPE(baseItem)) &&
14064
0
      (wild->processContents < baseWild->processContents)) {
14065
0
      xmlChar *str = NULL;
14066
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14067
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14068
0
    NULL, baseItem,
14069
0
    "The {process contents} of the attribute wildcard is "
14070
0
    "weaker than the one in the %s %s '%s'",
14071
0
    WXS_ACTION_STR(action),
14072
0
    WXS_ITEM_TYPE_NAME(baseItem),
14073
0
    xmlSchemaGetComponentQName(&str, baseItem),
14074
0
    NULL);
14075
0
      FREE_AND_NULL(str)
14076
0
    return(pctxt->err);
14077
0
  }
14078
0
    }
14079
0
    return(0);
14080
0
}
14081
14082
14083
static int
14084
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14085
          xmlSchemaBasicItemPtr item,
14086
          xmlSchemaWildcardPtr *completeWild,
14087
          xmlSchemaItemListPtr list,
14088
          xmlSchemaItemListPtr prohibs);
14089
/**
14090
 * Builds the wildcard and the attribute uses on the given complex type.
14091
 *
14092
 *
14093
 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14094
 * strings, so recheck this if we start to hardcode some schemata, since
14095
 * they might not be in the same dict.
14096
 * NOTE: It is allowed to "extend" the xs:anyType type.
14097
 *
14098
 * @param pctxt  the schema parser context
14099
 * @param type  the complex type definition
14100
 * @returns -1 if an internal error occurs, 0 otherwise.
14101
 */
14102
static int
14103
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14104
          xmlSchemaTypePtr type)
14105
0
{
14106
0
    xmlSchemaTypePtr baseType = NULL;
14107
0
    xmlSchemaAttributeUsePtr use;
14108
0
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14109
14110
0
    if (type->baseType == NULL) {
14111
0
  PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14112
0
      "no base type");
14113
0
        return (-1);
14114
0
    }
14115
0
    baseType = type->baseType;
14116
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14117
0
  if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14118
0
      return(-1);
14119
14120
0
    uses = type->attrUses;
14121
0
    baseUses = baseType->attrUses;
14122
    /*
14123
    * Expand attribute group references. And build the 'complete'
14124
    * wildcard, i.e. intersect multiple wildcards.
14125
    * Move attribute prohibitions into a separate list.
14126
    */
14127
0
    if (uses != NULL) {
14128
0
  if (WXS_IS_RESTRICTION(type)) {
14129
      /*
14130
      * This one will transfer all attr. prohibitions
14131
      * into pctxt->attrProhibs.
14132
      */
14133
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14134
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14135
0
    pctxt->attrProhibs) == -1)
14136
0
      {
14137
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14138
0
    "failed to expand attributes");
14139
0
                return(-1);
14140
0
      }
14141
0
      if (pctxt->attrProhibs->nbItems != 0)
14142
0
    prohibs = pctxt->attrProhibs;
14143
0
  } else {
14144
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14145
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14146
0
    NULL) == -1)
14147
0
      {
14148
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14149
0
    "failed to expand attributes");
14150
0
                return(-1);
14151
0
      }
14152
0
  }
14153
0
    }
14154
    /*
14155
    * Inherit the attribute uses of the base type.
14156
    */
14157
0
    if (baseUses != NULL) {
14158
0
  int i, j;
14159
0
  xmlSchemaAttributeUseProhibPtr pro;
14160
14161
0
  if (WXS_IS_RESTRICTION(type)) {
14162
0
      int usesCount;
14163
0
      xmlSchemaAttributeUsePtr tmp;
14164
14165
0
      if (uses != NULL)
14166
0
    usesCount = uses->nbItems;
14167
0
      else
14168
0
    usesCount = 0;
14169
14170
      /* Restriction. */
14171
0
      for (i = 0; i < baseUses->nbItems; i++) {
14172
0
    use = baseUses->items[i];
14173
0
    if (prohibs) {
14174
        /*
14175
        * Filter out prohibited uses.
14176
        */
14177
0
        for (j = 0; j < prohibs->nbItems; j++) {
14178
0
      pro = prohibs->items[j];
14179
0
      if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14180
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14181
0
        pro->targetNamespace))
14182
0
      {
14183
0
          goto inherit_next;
14184
0
      }
14185
0
        }
14186
0
    }
14187
0
    if (usesCount) {
14188
        /*
14189
        * Filter out existing uses.
14190
        */
14191
0
        for (j = 0; j < usesCount; j++) {
14192
0
      tmp = uses->items[j];
14193
0
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
14194
0
        WXS_ATTRUSE_DECL_NAME(tmp)) &&
14195
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14196
0
        WXS_ATTRUSE_DECL_TNS(tmp)))
14197
0
      {
14198
0
          goto inherit_next;
14199
0
      }
14200
0
        }
14201
0
    }
14202
0
    if (uses == NULL) {
14203
0
        type->attrUses = xmlSchemaItemListCreate();
14204
0
        if (type->attrUses == NULL)
14205
0
      goto exit_failure;
14206
0
        uses = type->attrUses;
14207
0
    }
14208
0
    xmlSchemaItemListAddSize(uses, 2, use);
14209
0
inherit_next: {}
14210
0
      }
14211
0
  } else {
14212
      /* Extension. */
14213
0
      for (i = 0; i < baseUses->nbItems; i++) {
14214
0
    use = baseUses->items[i];
14215
0
    if (uses == NULL) {
14216
0
        type->attrUses = xmlSchemaItemListCreate();
14217
0
        if (type->attrUses == NULL)
14218
0
      goto exit_failure;
14219
0
        uses = type->attrUses;
14220
0
    }
14221
0
    xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14222
0
      }
14223
0
  }
14224
0
    }
14225
    /*
14226
    * Shrink attr. uses.
14227
    */
14228
0
    if (uses) {
14229
0
  if (uses->nbItems == 0) {
14230
0
      xmlSchemaItemListFree(uses);
14231
0
      type->attrUses = NULL;
14232
0
  }
14233
  /*
14234
  * TODO: We could shrink the size of the array
14235
  * to fit the actual number of items.
14236
  */
14237
0
    }
14238
    /*
14239
    * Compute the complete wildcard.
14240
    */
14241
0
    if (WXS_IS_EXTENSION(type)) {
14242
0
  if (baseType->attributeWildcard != NULL) {
14243
      /*
14244
      * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14245
      * the appropriate case among the following:"
14246
      */
14247
0
      if (type->attributeWildcard != NULL) {
14248
    /*
14249
    * Union the complete wildcard with the base wildcard.
14250
    * SPEC {attribute wildcard}
14251
    * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14252
    * and {annotation} are those of the `complete wildcard`,
14253
    * and whose {namespace constraint} is the intensional union
14254
    * of the {namespace constraint} of the `complete wildcard`
14255
    * and of the `base wildcard`, as defined in Attribute
14256
    * Wildcard Union ($3.10.6)."
14257
    */
14258
0
    if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14259
0
        baseType->attributeWildcard) == -1)
14260
0
        goto exit_failure;
14261
0
      } else {
14262
    /*
14263
    * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14264
    * then the `base wildcard`."
14265
    */
14266
0
    type->attributeWildcard = baseType->attributeWildcard;
14267
0
      }
14268
0
  } else {
14269
      /*
14270
      * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14271
      * `complete wildcard`"
14272
      * NOOP
14273
      */
14274
0
  }
14275
0
    } else {
14276
  /*
14277
  * SPEC {attribute wildcard}
14278
  * (3.1) "If the <restriction> alternative is chosen, then the
14279
  * `complete wildcard`;"
14280
  * NOOP
14281
  */
14282
0
    }
14283
14284
0
    return (0);
14285
14286
0
exit_failure:
14287
0
    return(-1);
14288
0
}
14289
14290
/**
14291
 * Evaluates if a type definition contains the given "final".
14292
 * This does take "finalDefault" into account as well.
14293
 *
14294
 * @param type  the type definition
14295
 * @param final  the final
14296
 * @returns 1 if the type does contain the given "final",
14297
 * 0 otherwise.
14298
 */
14299
static int
14300
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14301
0
{
14302
0
    if (type == NULL)
14303
0
  return (0);
14304
0
    if (type->flags & final)
14305
0
  return (1);
14306
0
    else
14307
0
  return (0);
14308
0
}
14309
14310
/**
14311
 * @param type  the Union Simple Type
14312
 * @returns  a list of member types of `type` if existing,
14313
 *           NULL otherwise.
14314
 */
14315
static xmlSchemaTypeLinkPtr
14316
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14317
0
{
14318
0
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14319
0
  if (type->memberTypes != NULL)
14320
0
      return (type->memberTypes);
14321
0
  else
14322
0
      type = type->baseType;
14323
0
    }
14324
0
    return (NULL);
14325
0
}
14326
14327
#if 0
14328
/**
14329
 * Schema Component Constraint: Effective Total Range
14330
 * (all and sequence) + (choice)
14331
 *
14332
 * @param particle  the particle
14333
 * @returns the minimum Effective Total Range.
14334
 */
14335
static int
14336
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14337
{
14338
    if ((particle->children == NULL) ||
14339
  (particle->minOccurs == 0))
14340
  return (0);
14341
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14342
  int min = -1, cur;
14343
  xmlSchemaParticlePtr part =
14344
      (xmlSchemaParticlePtr) particle->children->children;
14345
14346
  if (part == NULL)
14347
      return (0);
14348
  while (part != NULL) {
14349
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14350
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14351
    cur = part->minOccurs;
14352
      else
14353
    cur = xmlSchemaGetParticleTotalRangeMin(part);
14354
      if (cur == 0)
14355
    return (0);
14356
      if ((min > cur) || (min == -1))
14357
    min = cur;
14358
      part = (xmlSchemaParticlePtr) part->next;
14359
  }
14360
  return (particle->minOccurs * min);
14361
    } else {
14362
  /* <all> and <sequence> */
14363
  int sum = 0;
14364
  xmlSchemaParticlePtr part =
14365
      (xmlSchemaParticlePtr) particle->children->children;
14366
14367
  if (part == NULL)
14368
      return (0);
14369
  do {
14370
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14371
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14372
    sum += part->minOccurs;
14373
      else
14374
    sum += xmlSchemaGetParticleTotalRangeMin(part);
14375
      part = (xmlSchemaParticlePtr) part->next;
14376
  } while (part != NULL);
14377
  return (particle->minOccurs * sum);
14378
    }
14379
}
14380
14381
/**
14382
 * Schema Component Constraint: Effective Total Range
14383
 * (all and sequence) + (choice)
14384
 *
14385
 * @param particle  the particle
14386
 * @returns the maximum Effective Total Range.
14387
 */
14388
static int
14389
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14390
{
14391
    if ((particle->children == NULL) ||
14392
  (particle->children->children == NULL))
14393
  return (0);
14394
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14395
  int max = -1, cur;
14396
  xmlSchemaParticlePtr part =
14397
      (xmlSchemaParticlePtr) particle->children->children;
14398
14399
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14400
      if (part->children == NULL)
14401
    continue;
14402
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14403
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14404
    cur = part->maxOccurs;
14405
      else
14406
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14407
      if (cur == UNBOUNDED)
14408
    return (UNBOUNDED);
14409
      if ((max < cur) || (max == -1))
14410
    max = cur;
14411
  }
14412
  /* TODO: Handle overflows? */
14413
  return (particle->maxOccurs * max);
14414
    } else {
14415
  /* <all> and <sequence> */
14416
  int sum = 0, cur;
14417
  xmlSchemaParticlePtr part =
14418
      (xmlSchemaParticlePtr) particle->children->children;
14419
14420
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14421
      if (part->children == NULL)
14422
    continue;
14423
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14424
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14425
    cur = part->maxOccurs;
14426
      else
14427
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14428
      if (cur == UNBOUNDED)
14429
    return (UNBOUNDED);
14430
      if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14431
    return (UNBOUNDED);
14432
      sum += cur;
14433
  }
14434
  /* TODO: Handle overflows? */
14435
  return (particle->maxOccurs * sum);
14436
    }
14437
}
14438
#endif
14439
14440
/**
14441
 * @param particle  the particle
14442
 * @returns 1 if emptiable, 0 otherwise.
14443
 */
14444
static int
14445
xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14446
0
{
14447
0
    xmlSchemaParticlePtr part;
14448
0
    int emptiable;
14449
14450
0
    if ((particle->children == NULL) || (particle->minOccurs == 0))
14451
0
  return (1);
14452
14453
0
    part = (xmlSchemaParticlePtr) particle->children->children;
14454
0
    if (part == NULL)
14455
0
        return (1);
14456
14457
0
    while (part != NULL) {
14458
0
        if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14459
0
            (part->children->type == XML_SCHEMA_TYPE_ANY))
14460
0
            emptiable = (part->minOccurs == 0);
14461
0
        else
14462
0
            emptiable = xmlSchemaGetParticleEmptiable(part);
14463
0
        if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14464
0
            if (emptiable)
14465
0
                return (1);
14466
0
        } else {
14467
      /* <all> and <sequence> */
14468
0
            if (!emptiable)
14469
0
                return (0);
14470
0
        }
14471
0
        part = (xmlSchemaParticlePtr) part->next;
14472
0
    }
14473
14474
0
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14475
0
        return (0);
14476
0
    else
14477
0
        return (1);
14478
0
}
14479
14480
/**
14481
 * Schema Component Constraint: Particle Emptiable
14482
 * Checks whether the given particle is emptiable.
14483
 *
14484
 * @param particle  the particle
14485
 * @returns 1 if emptiable, 0 otherwise.
14486
 */
14487
static int
14488
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14489
0
{
14490
    /*
14491
    * SPEC (1) "Its {min occurs} is 0."
14492
    */
14493
0
    if ((particle == NULL) || (particle->minOccurs == 0) ||
14494
0
  (particle->children == NULL))
14495
0
  return (1);
14496
    /*
14497
    * SPEC (2) "Its {term} is a group and the minimum part of the
14498
    * effective total range of that group, [...] is 0."
14499
    */
14500
0
    if (WXS_IS_MODEL_GROUP(particle->children))
14501
0
  return (xmlSchemaGetParticleEmptiable(particle));
14502
0
    return (0);
14503
0
}
14504
14505
/**
14506
 * Schema Component Constraint:
14507
 * Type Derivation OK (Simple) (cos-st-derived-OK)
14508
 *
14509
 * Checks whether `type` can be validly
14510
 * derived from `baseType`.
14511
 *
14512
 * @param actxt  a context
14513
 * @param type  the derived simple type definition
14514
 * @param baseType  the base type definition
14515
 * @param subset  the subset of ('restriction', etc.)
14516
 * @returns 0 on success, an positive error code otherwise.
14517
 */
14518
static int
14519
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14520
           xmlSchemaTypePtr type,
14521
           xmlSchemaTypePtr baseType,
14522
           int subset)
14523
0
{
14524
    /*
14525
    * 1 They are the same type definition.
14526
    * TODO: The identity check might have to be more complex than this.
14527
    */
14528
0
    if (type == baseType)
14529
0
  return (0);
14530
    /*
14531
    * 2.1 restriction is not in the subset, or in the {final}
14532
    * of its own {base type definition};
14533
    *
14534
    * NOTE that this will be used also via "xsi:type".
14535
    *
14536
    * TODO: Revise this, it looks strange. How can the "type"
14537
    * not be fixed or *in* fixing?
14538
    */
14539
0
    if (WXS_IS_TYPE_NOT_FIXED(type))
14540
0
  if (xmlSchemaTypeFixup(type, actxt) == -1)
14541
0
      return(-1);
14542
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14543
0
  if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14544
0
      return(-1);
14545
0
    if ((subset & SUBSET_RESTRICTION) ||
14546
0
  (xmlSchemaTypeFinalContains(type->baseType,
14547
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14548
0
  return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14549
0
    }
14550
    /* 2.2 */
14551
0
    if (type->baseType == baseType) {
14552
  /*
14553
  * 2.2.1 D's `base type definition` is B.
14554
  */
14555
0
  return (0);
14556
0
    }
14557
    /*
14558
    * 2.2.2 D's `base type definition` is not the `ur-type definition`
14559
    * and is validly derived from B given the subset, as defined by this
14560
    * constraint.
14561
    */
14562
0
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14563
0
  (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14564
0
      baseType, subset) == 0)) {
14565
0
  return (0);
14566
0
    }
14567
    /*
14568
    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14569
    * definition`.
14570
    */
14571
0
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14572
0
  (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14573
0
  return (0);
14574
0
    }
14575
    /*
14576
    * 2.2.4 B's {variety} is union and D is validly derived from a type
14577
    * definition in B's {member type definitions} given the subset, as
14578
    * defined by this constraint.
14579
    *
14580
    * NOTE: This seems not to involve built-in types, since there is no
14581
    * built-in Union Simple Type.
14582
    */
14583
0
    if (WXS_IS_UNION(baseType)) {
14584
0
  xmlSchemaTypeLinkPtr cur;
14585
14586
0
  cur = baseType->memberTypes;
14587
0
  while (cur != NULL) {
14588
0
      if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14589
0
    if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14590
0
        return(-1);
14591
0
      if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14592
0
        type, cur->type, subset) == 0)
14593
0
      {
14594
    /*
14595
    * It just has to be validly derived from at least one
14596
    * member-type.
14597
    */
14598
0
    return (0);
14599
0
      }
14600
0
      cur = cur->next;
14601
0
  }
14602
0
    }
14603
0
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14604
0
}
14605
14606
/**
14607
 * Checks st-props-correct (2) + ct-props-correct (3).
14608
 * Circular type definitions are not allowed.
14609
 *
14610
 * @param pctxt  the schema parser context
14611
 * @param ctxtType  the type definition
14612
 * @param ancestor  an ancestor of `ctxtType`
14613
 * @returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14614
 * circular, 0 otherwise.
14615
 */
14616
static int
14617
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14618
         xmlSchemaTypePtr ctxtType,
14619
         xmlSchemaTypePtr ancestor)
14620
0
{
14621
0
    int ret;
14622
14623
0
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14624
0
  return (0);
14625
14626
0
    if (ctxtType == ancestor) {
14627
0
  xmlSchemaPCustomErr(pctxt,
14628
0
      XML_SCHEMAP_ST_PROPS_CORRECT_2,
14629
0
      WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14630
0
      "The definition is circular", NULL);
14631
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14632
0
    }
14633
0
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14634
  /*
14635
  * Avoid infinite recursion on circular types not yet checked.
14636
  */
14637
0
  return (0);
14638
0
    }
14639
0
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14640
0
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14641
0
  ancestor->baseType);
14642
0
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14643
0
    return (ret);
14644
0
}
14645
14646
/**
14647
 * Checks for circular type definitions.
14648
 *
14649
 * @param item  the complex/simple type definition
14650
 * @param ctxt  the parser context
14651
 */
14652
static void
14653
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14654
            xmlSchemaParserCtxtPtr ctxt)
14655
0
{
14656
0
    if ((item == NULL) ||
14657
0
  (item->type == XML_SCHEMA_TYPE_BASIC) ||
14658
0
  (item->baseType == NULL))
14659
0
  return;
14660
0
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14661
0
  item->baseType);
14662
0
}
14663
14664
/*
14665
* Simple Type Definition Representation OK (src-simple-type) 4
14666
*
14667
* "4 Circular union type definition is disallowed. That is, if the
14668
* <union> alternative is chosen, there must not be any entries in the
14669
* memberTypes [attribute] at any depth which resolve to the component
14670
* corresponding to the <simpleType>."
14671
*
14672
* Note that this should work on the *representation* of a component,
14673
* thus assumes any union types in the member types not being yet
14674
* substituted. At this stage we need the variety of the types
14675
* to be already computed.
14676
*/
14677
static int
14678
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14679
          xmlSchemaTypePtr ctxType,
14680
          xmlSchemaTypeLinkPtr members)
14681
0
{
14682
0
    xmlSchemaTypeLinkPtr member;
14683
0
    xmlSchemaTypePtr memberType;
14684
14685
0
    member = members;
14686
0
    while (member != NULL) {
14687
0
  memberType = member->type;
14688
0
  while ((memberType != NULL) &&
14689
0
      (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14690
0
      if (memberType == ctxType) {
14691
0
    xmlSchemaPCustomErr(pctxt,
14692
0
        XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14693
0
        WXS_BASIC_CAST ctxType, NULL,
14694
0
        "The union type definition is circular", NULL);
14695
0
    return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14696
0
      }
14697
0
      if ((WXS_IS_UNION(memberType)) &&
14698
0
    ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14699
0
      {
14700
0
    int res;
14701
0
    memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14702
0
    res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14703
0
        ctxType,
14704
0
        xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14705
0
    memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14706
0
    if (res != 0)
14707
0
        return(res);
14708
0
      }
14709
0
      memberType = memberType->baseType;
14710
0
  }
14711
0
  member = member->next;
14712
0
    }
14713
0
    return(0);
14714
0
}
14715
14716
static int
14717
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
14718
           xmlSchemaTypePtr type)
14719
0
{
14720
0
    if (! WXS_IS_UNION(type))
14721
0
  return(0);
14722
0
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
14723
0
  type->memberTypes));
14724
0
}
14725
14726
/**
14727
 * Resolves type definition references
14728
 *
14729
 * @param typeDef  the complex/simple type definition
14730
 * @param ctxt  the parser context
14731
 */
14732
static void
14733
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
14734
       xmlSchemaParserCtxtPtr ctxt)
14735
0
{
14736
0
    if (typeDef == NULL)
14737
0
  return;
14738
14739
    /*
14740
    * Resolve the base type.
14741
    */
14742
0
    if (typeDef->baseType == NULL) {
14743
0
  typeDef->baseType = xmlSchemaGetType(ctxt->schema,
14744
0
      typeDef->base, typeDef->baseNs);
14745
0
  if (typeDef->baseType == NULL) {
14746
0
      xmlSchemaPResCompAttrErr(ctxt,
14747
0
    XML_SCHEMAP_SRC_RESOLVE,
14748
0
    WXS_BASIC_CAST typeDef, typeDef->node,
14749
0
    "base", typeDef->base, typeDef->baseNs,
14750
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
14751
0
      return;
14752
0
  }
14753
0
    }
14754
0
    if (WXS_IS_SIMPLE(typeDef)) {
14755
0
  if (WXS_IS_UNION(typeDef)) {
14756
      /*
14757
      * Resolve the memberTypes.
14758
      */
14759
0
      xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
14760
0
      return;
14761
0
  } else if (WXS_IS_LIST(typeDef)) {
14762
      /*
14763
      * Resolve the itemType.
14764
      */
14765
0
      if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
14766
14767
0
    typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
14768
0
        typeDef->base, typeDef->baseNs);
14769
14770
0
    if ((typeDef->subtypes == NULL) ||
14771
0
        (! WXS_IS_SIMPLE(typeDef->subtypes)))
14772
0
    {
14773
0
        typeDef->subtypes = NULL;
14774
0
        xmlSchemaPResCompAttrErr(ctxt,
14775
0
      XML_SCHEMAP_SRC_RESOLVE,
14776
0
      WXS_BASIC_CAST typeDef, typeDef->node,
14777
0
      "itemType", typeDef->base, typeDef->baseNs,
14778
0
      XML_SCHEMA_TYPE_SIMPLE, NULL);
14779
0
    }
14780
0
      }
14781
0
      return;
14782
0
  }
14783
0
    }
14784
    /*
14785
    * The ball of letters below means, that if we have a particle
14786
    * which has a QName-helper component as its {term}, we want
14787
    * to resolve it...
14788
    */
14789
0
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
14790
0
  ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
14791
0
      XML_SCHEMA_TYPE_PARTICLE) &&
14792
0
  (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
14793
0
  ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
14794
0
      XML_SCHEMA_EXTRA_QNAMEREF))
14795
0
    {
14796
0
  xmlSchemaQNameRefPtr ref =
14797
0
      WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
14798
0
  xmlSchemaModelGroupDefPtr groupDef;
14799
14800
  /*
14801
  * URGENT TODO: Test this.
14802
  */
14803
0
  WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
14804
  /*
14805
  * Resolve the MG definition reference.
14806
  */
14807
0
  groupDef =
14808
0
      WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
14809
0
    ref->itemType, ref->name, ref->targetNamespace);
14810
0
  if (groupDef == NULL) {
14811
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
14812
0
    NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
14813
0
    "ref", ref->name, ref->targetNamespace, ref->itemType,
14814
0
    NULL);
14815
      /* Remove the particle. */
14816
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
14817
0
  } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
14818
      /* Remove the particle. */
14819
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
14820
0
  else {
14821
      /*
14822
      * Assign the MG definition's {model group} to the
14823
      * particle's {term}.
14824
      */
14825
0
      WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
14826
14827
0
      if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
14828
    /*
14829
    * SPEC cos-all-limited (1.2)
14830
    * "1.2 the {term} property of a particle with
14831
    * {max occurs}=1 which is part of a pair which constitutes
14832
    * the {content type} of a complex type definition."
14833
    */
14834
0
    if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
14835
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
14836
      /* TODO: error code */
14837
0
      XML_SCHEMAP_COS_ALL_LIMITED,
14838
0
      WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
14839
0
      "The particle's {max occurs} must be 1, since the "
14840
0
      "reference resolves to an 'all' model group",
14841
0
      NULL, NULL);
14842
0
    }
14843
0
      }
14844
0
  }
14845
0
    }
14846
0
}
14847
14848
14849
14850
/**
14851
 * Checks st-props-correct.
14852
 *
14853
 * @param ctxt  the schema parser context
14854
 * @param type  the simple type definition
14855
 * @returns 0 if the properties are correct,
14856
 * if not, a positive error code and -1 on internal
14857
 * errors.
14858
 */
14859
static int
14860
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
14861
           xmlSchemaTypePtr type)
14862
0
{
14863
0
    xmlSchemaTypePtr baseType = type->baseType;
14864
0
    xmlChar *str = NULL;
14865
14866
    /* STATE: error funcs converted. */
14867
    /*
14868
    * Schema Component Constraint: Simple Type Definition Properties Correct
14869
    *
14870
    * NOTE: This is somehow redundant, since we actually built a simple type
14871
    * to have all the needed information; this acts as an self test.
14872
    */
14873
    /* Base type: If the datatype has been `derived` by `restriction`
14874
    * then the Simple Type Definition component from which it is `derived`,
14875
    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
14876
    */
14877
0
    if (baseType == NULL) {
14878
  /*
14879
  * TODO: Think about: "modulo the impact of Missing
14880
  * Sub-components ($5.3)."
14881
  */
14882
0
  xmlSchemaPCustomErr(ctxt,
14883
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
14884
0
      WXS_BASIC_CAST type, NULL,
14885
0
      "No base type existent", NULL);
14886
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
14887
14888
0
    }
14889
0
    if (! WXS_IS_SIMPLE(baseType)) {
14890
0
  xmlSchemaPCustomErr(ctxt,
14891
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
14892
0
      WXS_BASIC_CAST type, NULL,
14893
0
      "The base type '%s' is not a simple type",
14894
0
      xmlSchemaGetComponentQName(&str, baseType));
14895
0
  FREE_AND_NULL(str)
14896
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
14897
0
    }
14898
0
    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
14899
0
  (WXS_IS_RESTRICTION(type) == 0) &&
14900
0
  ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
14901
0
         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
14902
0
  xmlSchemaPCustomErr(ctxt,
14903
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
14904
0
      WXS_BASIC_CAST type, NULL,
14905
0
      "A type, derived by list or union, must have "
14906
0
      "the simple ur-type definition as base type, not '%s'",
14907
0
      xmlSchemaGetComponentQName(&str, baseType));
14908
0
  FREE_AND_NULL(str)
14909
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
14910
0
    }
14911
    /*
14912
    * Variety: One of {atomic, list, union}.
14913
    */
14914
0
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
14915
0
  (! WXS_IS_LIST(type))) {
14916
0
  xmlSchemaPCustomErr(ctxt,
14917
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
14918
0
      WXS_BASIC_CAST type, NULL,
14919
0
      "The variety is absent", NULL);
14920
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
14921
0
    }
14922
    /* TODO: Finish this. Hmm, is this finished? */
14923
14924
    /*
14925
    * 3 The {final} of the {base type definition} must not contain restriction.
14926
    */
14927
0
    if (xmlSchemaTypeFinalContains(baseType,
14928
0
  XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
14929
0
  xmlSchemaPCustomErr(ctxt,
14930
0
      XML_SCHEMAP_ST_PROPS_CORRECT_3,
14931
0
      WXS_BASIC_CAST type, NULL,
14932
0
      "The 'final' of its base type '%s' must not contain "
14933
0
      "'restriction'",
14934
0
      xmlSchemaGetComponentQName(&str, baseType));
14935
0
  FREE_AND_NULL(str)
14936
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
14937
0
    }
14938
14939
    /*
14940
    * 2 All simple type definitions must be derived ultimately from the `simple
14941
    * ur-type definition` (so circular definitions are disallowed). That is, it
14942
    * must be possible to reach a built-in primitive datatype or the `simple
14943
    * ur-type definition` by repeatedly following the {base type definition}.
14944
    *
14945
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
14946
    */
14947
0
    return (0);
14948
0
}
14949
14950
/**
14951
 * Schema Component Constraint:
14952
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
14953
14954
 * Checks if the given `type` (simpleType) is derived validly by restriction.
14955
 * STATUS:
14956
 *
14957
 * @param pctxt  the schema parser context
14958
 * @param type  the simple type definition
14959
 * @returns -1 on internal errors, 0 if the type is validly derived,
14960
 * a positive error code otherwise.
14961
 */
14962
static int
14963
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
14964
           xmlSchemaTypePtr type)
14965
0
{
14966
0
    xmlChar *str = NULL;
14967
14968
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
14969
0
  PERROR_INT("xmlSchemaCheckCOSSTRestricts",
14970
0
      "given type is not a user-derived simpleType");
14971
0
  return (-1);
14972
0
    }
14973
14974
0
    if (WXS_IS_ATOMIC(type)) {
14975
0
  xmlSchemaTypePtr primitive;
14976
  /*
14977
  * 1.1 The {base type definition} must be an atomic simple
14978
  * type definition or a built-in primitive datatype.
14979
  */
14980
0
  if (! WXS_IS_ATOMIC(type->baseType)) {
14981
0
      xmlSchemaPCustomErr(pctxt,
14982
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
14983
0
    WXS_BASIC_CAST type, NULL,
14984
0
    "The base type '%s' is not an atomic simple type",
14985
0
    xmlSchemaGetComponentQName(&str, type->baseType));
14986
0
      FREE_AND_NULL(str)
14987
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
14988
0
  }
14989
  /* 1.2 The {final} of the {base type definition} must not contain
14990
  * restriction.
14991
  */
14992
  /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
14993
0
  if (xmlSchemaTypeFinalContains(type->baseType,
14994
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
14995
0
      xmlSchemaPCustomErr(pctxt,
14996
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
14997
0
    WXS_BASIC_CAST type, NULL,
14998
0
    "The final of its base type '%s' must not contain 'restriction'",
14999
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15000
0
      FREE_AND_NULL(str)
15001
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15002
0
  }
15003
15004
  /*
15005
  * 1.3.1 DF must be an allowed constraining facet for the {primitive
15006
  * type definition}, as specified in the appropriate subsection of 3.2
15007
  * Primitive datatypes.
15008
  */
15009
0
  if (type->facets != NULL) {
15010
0
      xmlSchemaFacetPtr facet;
15011
0
      int ok = 1;
15012
15013
0
      primitive = xmlSchemaGetPrimitiveType(type);
15014
0
      if (primitive == NULL) {
15015
0
    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15016
0
        "failed to get primitive type");
15017
0
    return (-1);
15018
0
      }
15019
0
      facet = type->facets;
15020
0
      do {
15021
0
    if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15022
0
        ok = 0;
15023
0
        xmlSchemaPIllegalFacetAtomicErr(pctxt,
15024
0
      XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15025
0
      type, primitive, facet);
15026
0
    }
15027
0
    facet = facet->next;
15028
0
      } while (facet != NULL);
15029
0
      if (ok == 0)
15030
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15031
0
  }
15032
  /*
15033
  * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15034
  * of the {base type definition} (call this BF),then the DF's {value}
15035
  * must be a valid restriction of BF's {value} as defined in
15036
  * [XML Schemas: Datatypes]."
15037
  *
15038
  * NOTE (1.3.2) Facet derivation constraints are currently handled in
15039
  * xmlSchemaDeriveAndValidateFacets()
15040
  */
15041
0
    } else if (WXS_IS_LIST(type)) {
15042
0
  xmlSchemaTypePtr itemType = NULL;
15043
15044
0
  itemType = type->subtypes;
15045
0
  if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15046
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15047
0
    "failed to evaluate the item type");
15048
0
      return (-1);
15049
0
  }
15050
0
  if (WXS_IS_TYPE_NOT_FIXED(itemType))
15051
0
      xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15052
  /*
15053
  * 2.1 The {item type definition} must have a {variety} of atomic or
15054
  * union (in which case all the {member type definitions}
15055
  * must be atomic).
15056
  */
15057
0
  if ((! WXS_IS_ATOMIC(itemType)) &&
15058
0
      (! WXS_IS_UNION(itemType))) {
15059
0
      xmlSchemaPCustomErr(pctxt,
15060
0
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15061
0
    WXS_BASIC_CAST type, NULL,
15062
0
    "The item type '%s' does not have a variety of atomic or union",
15063
0
    xmlSchemaGetComponentQName(&str, itemType));
15064
0
      FREE_AND_NULL(str)
15065
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15066
0
  } else if (WXS_IS_UNION(itemType)) {
15067
0
      xmlSchemaTypeLinkPtr member;
15068
15069
0
      member = itemType->memberTypes;
15070
0
      while (member != NULL) {
15071
0
    if (! WXS_IS_ATOMIC(member->type)) {
15072
0
        xmlSchemaPCustomErr(pctxt,
15073
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15074
0
      WXS_BASIC_CAST type, NULL,
15075
0
      "The item type is a union type, but the "
15076
0
      "member type '%s' of this item type is not atomic",
15077
0
      xmlSchemaGetComponentQName(&str, member->type));
15078
0
        FREE_AND_NULL(str)
15079
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15080
0
    }
15081
0
    member = member->next;
15082
0
      }
15083
0
  }
15084
15085
0
  if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15086
0
      xmlSchemaFacetPtr facet;
15087
      /*
15088
      * This is the case if we have: <simpleType><list ..
15089
      */
15090
      /*
15091
      * 2.3.1
15092
      * 2.3.1.1 The {final} of the {item type definition} must not
15093
      * contain list.
15094
      */
15095
0
      if (xmlSchemaTypeFinalContains(itemType,
15096
0
    XML_SCHEMAS_TYPE_FINAL_LIST)) {
15097
0
    xmlSchemaPCustomErr(pctxt,
15098
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15099
0
        WXS_BASIC_CAST type, NULL,
15100
0
        "The final of its item type '%s' must not contain 'list'",
15101
0
        xmlSchemaGetComponentQName(&str, itemType));
15102
0
    FREE_AND_NULL(str)
15103
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15104
0
      }
15105
      /*
15106
      * 2.3.1.2 The {facets} must only contain the whiteSpace
15107
      * facet component.
15108
      * OPTIMIZE TODO: the S4S already disallows any facet
15109
      * to be specified.
15110
      */
15111
0
      if (type->facets != NULL) {
15112
0
    facet = type->facets;
15113
0
    do {
15114
0
        if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15115
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15116
0
          XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15117
0
          type, facet);
15118
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15119
0
        }
15120
0
        facet = facet->next;
15121
0
    } while (facet != NULL);
15122
0
      }
15123
      /*
15124
      * MAYBE TODO: (Hmm, not really) Datatypes states:
15125
      * A `list` datatype can be `derived` from an `atomic` datatype
15126
      * whose `lexical space` allows space (such as string or anyURI)or
15127
      * a `union` datatype any of whose {member type definitions}'s
15128
      * `lexical space` allows space.
15129
      */
15130
0
  } else {
15131
      /*
15132
      * This is the case if we have: <simpleType><restriction ...
15133
      * I.e. the variety of "list" is inherited.
15134
      */
15135
      /*
15136
      * 2.3.2
15137
      * 2.3.2.1 The {base type definition} must have a {variety} of list.
15138
      */
15139
0
      if (! WXS_IS_LIST(type->baseType)) {
15140
0
    xmlSchemaPCustomErr(pctxt,
15141
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15142
0
        WXS_BASIC_CAST type, NULL,
15143
0
        "The base type '%s' must be a list type",
15144
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15145
0
    FREE_AND_NULL(str)
15146
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15147
0
      }
15148
      /*
15149
      * 2.3.2.2 The {final} of the {base type definition} must not
15150
      * contain restriction.
15151
      */
15152
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15153
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15154
0
    xmlSchemaPCustomErr(pctxt,
15155
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15156
0
        WXS_BASIC_CAST type, NULL,
15157
0
        "The 'final' of the base type '%s' must not contain 'restriction'",
15158
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15159
0
    FREE_AND_NULL(str)
15160
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15161
0
      }
15162
      /*
15163
      * 2.3.2.3 The {item type definition} must be validly derived
15164
      * from the {base type definition}'s {item type definition} given
15165
      * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15166
      */
15167
0
      {
15168
0
    xmlSchemaTypePtr baseItemType;
15169
15170
0
    baseItemType = type->baseType->subtypes;
15171
0
    if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15172
0
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15173
0
      "failed to eval the item type of a base type");
15174
0
        return (-1);
15175
0
    }
15176
0
    if ((itemType != baseItemType) &&
15177
0
        (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15178
0
      baseItemType, 0) != 0)) {
15179
0
        xmlChar *strBIT = NULL, *strBT = NULL;
15180
0
        xmlSchemaPCustomErrExt(pctxt,
15181
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15182
0
      WXS_BASIC_CAST type, NULL,
15183
0
      "The item type '%s' is not validly derived from "
15184
0
      "the item type '%s' of the base type '%s'",
15185
0
      xmlSchemaGetComponentQName(&str, itemType),
15186
0
      xmlSchemaGetComponentQName(&strBIT, baseItemType),
15187
0
      xmlSchemaGetComponentQName(&strBT, type->baseType));
15188
15189
0
        FREE_AND_NULL(str)
15190
0
        FREE_AND_NULL(strBIT)
15191
0
        FREE_AND_NULL(strBT)
15192
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15193
0
    }
15194
0
      }
15195
15196
0
      if (type->facets != NULL) {
15197
0
    xmlSchemaFacetPtr facet;
15198
0
    int ok = 1;
15199
    /*
15200
    * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15201
    * and enumeration facet components are allowed among the {facets}.
15202
    */
15203
0
    facet = type->facets;
15204
0
    do {
15205
0
        switch (facet->type) {
15206
0
      case XML_SCHEMA_FACET_LENGTH:
15207
0
      case XML_SCHEMA_FACET_MINLENGTH:
15208
0
      case XML_SCHEMA_FACET_MAXLENGTH:
15209
0
      case XML_SCHEMA_FACET_WHITESPACE:
15210
          /*
15211
          * TODO: 2.5.1.2 List datatypes
15212
          * The value of `whiteSpace` is fixed to the value collapse.
15213
          */
15214
0
      case XML_SCHEMA_FACET_PATTERN:
15215
0
      case XML_SCHEMA_FACET_ENUMERATION:
15216
0
          break;
15217
0
      default: {
15218
0
          xmlSchemaPIllegalFacetListUnionErr(pctxt,
15219
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15220
0
        type, facet);
15221
          /*
15222
          * We could return, but it's nicer to report all
15223
          * invalid facets.
15224
          */
15225
0
          ok = 0;
15226
0
      }
15227
0
        }
15228
0
        facet = facet->next;
15229
0
    } while (facet != NULL);
15230
0
    if (ok == 0)
15231
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15232
    /*
15233
    * SPEC (2.3.2.5) (same as 1.3.2)
15234
    *
15235
    * NOTE (2.3.2.5) This is currently done in
15236
    * xmlSchemaDeriveAndValidateFacets()
15237
    */
15238
0
      }
15239
0
  }
15240
0
    } else if (WXS_IS_UNION(type)) {
15241
  /*
15242
  * 3.1 The {member type definitions} must all have {variety} of
15243
  * atomic or list.
15244
  */
15245
0
  xmlSchemaTypeLinkPtr member;
15246
15247
0
  member = type->memberTypes;
15248
0
  while (member != NULL) {
15249
0
      if (WXS_IS_TYPE_NOT_FIXED(member->type))
15250
0
    xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15251
15252
0
      if ((! WXS_IS_ATOMIC(member->type)) &&
15253
0
    (! WXS_IS_LIST(member->type))) {
15254
0
    xmlSchemaPCustomErr(pctxt,
15255
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15256
0
        WXS_BASIC_CAST type, NULL,
15257
0
        "The member type '%s' is neither an atomic, nor a list type",
15258
0
        xmlSchemaGetComponentQName(&str, member->type));
15259
0
    FREE_AND_NULL(str)
15260
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15261
0
      }
15262
0
      member = member->next;
15263
0
  }
15264
  /*
15265
  * 3.3.1 If the {base type definition} is the `simple ur-type
15266
  * definition`
15267
  */
15268
0
  if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15269
      /*
15270
      * 3.3.1.1 All of the {member type definitions} must have a
15271
      * {final} which does not contain union.
15272
      */
15273
0
      member = type->memberTypes;
15274
0
      while (member != NULL) {
15275
0
    if (xmlSchemaTypeFinalContains(member->type,
15276
0
        XML_SCHEMAS_TYPE_FINAL_UNION)) {
15277
0
        xmlSchemaPCustomErr(pctxt,
15278
0
      XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15279
0
      WXS_BASIC_CAST type, NULL,
15280
0
      "The 'final' of member type '%s' contains 'union'",
15281
0
      xmlSchemaGetComponentQName(&str, member->type));
15282
0
        FREE_AND_NULL(str)
15283
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15284
0
    }
15285
0
    member = member->next;
15286
0
      }
15287
      /*
15288
      * 3.3.1.2 The {facets} must be empty.
15289
      */
15290
0
      if (type->facetSet != NULL) {
15291
0
    xmlSchemaPCustomErr(pctxt,
15292
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15293
0
        WXS_BASIC_CAST type, NULL,
15294
0
        "No facets allowed", NULL);
15295
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15296
0
      }
15297
0
  } else {
15298
      /*
15299
      * 3.3.2.1 The {base type definition} must have a {variety} of union.
15300
      * I.e. the variety of "list" is inherited.
15301
      */
15302
0
      if (! WXS_IS_UNION(type->baseType)) {
15303
0
    xmlSchemaPCustomErr(pctxt,
15304
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15305
0
        WXS_BASIC_CAST type, NULL,
15306
0
        "The base type '%s' is not a union type",
15307
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15308
0
    FREE_AND_NULL(str)
15309
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15310
0
      }
15311
      /*
15312
      * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15313
      */
15314
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15315
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15316
0
    xmlSchemaPCustomErr(pctxt,
15317
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15318
0
        WXS_BASIC_CAST type, NULL,
15319
0
        "The 'final' of its base type '%s' must not contain 'restriction'",
15320
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15321
0
    FREE_AND_NULL(str)
15322
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15323
0
      }
15324
      /*
15325
      * 3.3.2.3 The {member type definitions}, in order, must be validly
15326
      * derived from the corresponding type definitions in the {base
15327
      * type definition}'s {member type definitions} given the empty set,
15328
      * as defined in Type Derivation OK (Simple) ($3.14.6).
15329
      */
15330
0
      {
15331
0
    xmlSchemaTypeLinkPtr baseMember;
15332
15333
    /*
15334
    * OPTIMIZE: if the type is restricting, it has no local defined
15335
    * member types and inherits the member types of the base type;
15336
    * thus a check for equality can be skipped.
15337
    */
15338
    /*
15339
    * Even worse: I cannot see a scenario where a restricting
15340
    * union simple type can have other member types as the member
15341
    * types of it's base type. This check seems not necessary with
15342
    * respect to the derivation process in libxml2.
15343
    * But necessary if constructing types with an API.
15344
    */
15345
0
    if (type->memberTypes != NULL) {
15346
0
        member = type->memberTypes;
15347
0
        baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15348
0
        if ((member == NULL) && (baseMember != NULL)) {
15349
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15350
0
          "different number of member types in base");
15351
0
        }
15352
0
        while (member != NULL) {
15353
0
      if (baseMember == NULL) {
15354
0
          PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15355
0
          "different number of member types in base");
15356
0
      } else if ((member->type != baseMember->type) &&
15357
0
          (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15358
0
        member->type, baseMember->type, 0) != 0)) {
15359
0
          xmlChar *strBMT = NULL, *strBT = NULL;
15360
15361
0
          xmlSchemaPCustomErrExt(pctxt,
15362
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15363
0
        WXS_BASIC_CAST type, NULL,
15364
0
        "The member type %s is not validly "
15365
0
        "derived from its corresponding member "
15366
0
        "type %s of the base type %s",
15367
0
        xmlSchemaGetComponentQName(&str, member->type),
15368
0
        xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15369
0
        xmlSchemaGetComponentQName(&strBT, type->baseType));
15370
0
          FREE_AND_NULL(str)
15371
0
          FREE_AND_NULL(strBMT)
15372
0
          FREE_AND_NULL(strBT)
15373
0
          return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15374
0
      }
15375
0
      member = member->next;
15376
0
                        if (baseMember != NULL)
15377
0
                            baseMember = baseMember->next;
15378
0
        }
15379
0
    }
15380
0
      }
15381
      /*
15382
      * 3.3.2.4 Only pattern and enumeration facet components are
15383
      * allowed among the {facets}.
15384
      */
15385
0
      if (type->facets != NULL) {
15386
0
    xmlSchemaFacetPtr facet;
15387
0
    int ok = 1;
15388
15389
0
    facet = type->facets;
15390
0
    do {
15391
0
        if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15392
0
      (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15393
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15394
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15395
0
        type, facet);
15396
0
      ok = 0;
15397
0
        }
15398
0
        facet = facet->next;
15399
0
    } while (facet != NULL);
15400
0
    if (ok == 0)
15401
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15402
15403
0
      }
15404
      /*
15405
      * SPEC (3.3.2.5) (same as 1.3.2)
15406
      *
15407
      * NOTE (3.3.2.5) This is currently done in
15408
      * xmlSchemaDeriveAndValidateFacets()
15409
      */
15410
0
  }
15411
0
    }
15412
15413
0
    return (0);
15414
0
}
15415
15416
#if 0
15417
/**
15418
 * Checks crc-simple-type constraints.
15419
 *
15420
 * @param ctxt  the schema parser context
15421
 * @param type  the simple type definition
15422
 * @returns 0 if the constraints are satisfied,
15423
 * if not a positive error code and -1 on internal
15424
 * errors.
15425
 */
15426
static int
15427
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15428
          xmlSchemaTypePtr type)
15429
{
15430
    /*
15431
    * src-simple-type.1 The corresponding simple type definition, if any,
15432
    * must satisfy the conditions set out in Constraints on Simple Type
15433
    * Definition Schema Components ($3.14.6).
15434
    */
15435
    if (WXS_IS_RESTRICTION(type)) {
15436
  /*
15437
  * src-simple-type.2 "If the <restriction> alternative is chosen,
15438
  * either it must have a base [attribute] or a <simpleType> among its
15439
  * [children], but not both."
15440
  * NOTE: This is checked in the parse function of <restriction>.
15441
  */
15442
  /*
15443
  *
15444
  */
15445
    } else if (WXS_IS_LIST(type)) {
15446
  /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15447
  * an itemType [attribute] or a <simpleType> among its [children],
15448
  * but not both."
15449
  *
15450
  * NOTE: This is checked in the parse function of <list>.
15451
  */
15452
    } else if (WXS_IS_UNION(type)) {
15453
  /*
15454
  * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15455
  */
15456
    }
15457
    return (0);
15458
}
15459
#endif
15460
15461
static int
15462
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15463
0
{
15464
0
   if (ctxt->vctxt == NULL) {
15465
0
  ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15466
0
  if (ctxt->vctxt == NULL) {
15467
0
      xmlSchemaPErr(ctxt, NULL,
15468
0
    XML_SCHEMAP_INTERNAL,
15469
0
    "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15470
0
    "failed to create a temp. validation context.\n",
15471
0
    NULL, NULL);
15472
0
      return (-1);
15473
0
  }
15474
  /* TODO: Pass user data. */
15475
0
  xmlSchemaSetValidErrors(ctxt->vctxt,
15476
0
      ctxt->error, ctxt->warning, ctxt->errCtxt);
15477
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15478
0
      ctxt->serror, ctxt->errCtxt);
15479
0
    }
15480
0
    return (0);
15481
0
}
15482
15483
static int
15484
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15485
           xmlNodePtr node,
15486
           xmlSchemaTypePtr type,
15487
           const xmlChar *value,
15488
           xmlSchemaValPtr *retVal,
15489
           int fireErrors,
15490
           int normalize,
15491
           int isNormalized);
15492
15493
/**
15494
 * Schema Component Constraint: Element Default Valid (Immediate)
15495
 * (cos-valid-default)
15496
 * This will be used by the parser only. For the validator there's
15497
 * an other version.
15498
 *
15499
 * @param pctxt  the schema parser context
15500
 * @param node  an optional node (the holder of the value)
15501
 * @param type  the simple type definition
15502
 * @param value  the default value
15503
 * @param val  resulting value
15504
 * @returns 0 if the constraints are satisfied,
15505
 * if not, a positive error code and -1 on internal
15506
 * errors.
15507
 */
15508
static int
15509
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15510
           xmlNodePtr node,
15511
           xmlSchemaTypePtr type,
15512
           const xmlChar *value,
15513
           xmlSchemaValPtr *val)
15514
0
{
15515
0
    int ret = 0;
15516
15517
    /*
15518
    * cos-valid-default:
15519
    * Schema Component Constraint: Element Default Valid (Immediate)
15520
    * For a string to be a valid default with respect to a type
15521
    * definition the appropriate case among the following must be true:
15522
    */
15523
0
    if WXS_IS_COMPLEX(type) {
15524
  /*
15525
  * Complex type.
15526
  *
15527
  * SPEC (2.1) "its {content type} must be a simple type definition
15528
  * or mixed."
15529
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15530
  * type}'s particle must be `emptiable` as defined by
15531
  * Particle Emptiable ($3.9.6)."
15532
  */
15533
0
  if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15534
0
      ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15535
      /* NOTE that this covers (2.2.2) as well. */
15536
0
      xmlSchemaPCustomErr(pctxt,
15537
0
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15538
0
    WXS_BASIC_CAST type, type->node,
15539
0
    "For a string to be a valid default, the type definition "
15540
0
    "must be a simple type or a complex type with mixed content "
15541
0
    "and a particle emptiable", NULL);
15542
0
      return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15543
0
  }
15544
0
    }
15545
    /*
15546
    * 1 If the type definition is a simple type definition, then the string
15547
    * must be `valid` with respect to that definition as defined by String
15548
    * Valid ($3.14.4).
15549
    *
15550
    * AND
15551
    *
15552
    * 2.2.1 If the {content type} is a simple type definition, then the
15553
    * string must be `valid` with respect to that simple type definition
15554
    * as defined by String Valid ($3.14.4).
15555
    */
15556
0
    if (WXS_IS_SIMPLE(type))
15557
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15558
0
      type, value, val, 1, 1, 0);
15559
0
    else if (WXS_HAS_SIMPLE_CONTENT(type))
15560
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15561
0
      type->contentTypeDef, value, val, 1, 1, 0);
15562
0
    else
15563
0
  return (ret);
15564
15565
0
    if (ret < 0) {
15566
0
  PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15567
0
      "calling xmlSchemaVCheckCVCSimpleType()");
15568
0
    }
15569
15570
0
    return (ret);
15571
0
}
15572
15573
/**
15574
 * (4.6) Constraints on Complex Type Definition Schema Components
15575
 * Schema Component Constraint:
15576
 * Complex Type Definition Properties Correct (ct-props-correct)
15577
 * STATUS: (seems) complete
15578
 *
15579
 * @param pctxt  the schema parser context
15580
 * @param type  the complex type definition
15581
 * @returns 0 if the constraints are satisfied, a positive
15582
 * error code if not and -1 if an internal error occurred.
15583
 */
15584
static int
15585
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15586
           xmlSchemaTypePtr type)
15587
0
{
15588
    /*
15589
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15590
    *
15591
    * SPEC (1) "The values of the properties of a complex type definition must
15592
    * be as described in the property tableau in The Complex Type Definition
15593
    * Schema Component ($3.4.1), modulo the impact of Missing
15594
    * Sub-components ($5.3)."
15595
    */
15596
0
    if ((type->baseType != NULL) &&
15597
0
  (WXS_IS_SIMPLE(type->baseType)) &&
15598
0
  (WXS_IS_EXTENSION(type) == 0)) {
15599
  /*
15600
  * SPEC (2) "If the {base type definition} is a simple type definition,
15601
  * the {derivation method} must be extension."
15602
  */
15603
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
15604
0
      XML_SCHEMAP_SRC_CT_1,
15605
0
      NULL, WXS_BASIC_CAST type,
15606
0
      "If the base type is a simple type, the derivation method must be "
15607
0
      "'extension'", NULL, NULL);
15608
0
  return (XML_SCHEMAP_SRC_CT_1);
15609
0
    }
15610
    /*
15611
    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
15612
    * definition`. That is, it must be possible to reach the `ur-type
15613
    * definition` by repeatedly following the {base type definition}."
15614
    *
15615
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15616
    */
15617
    /*
15618
    * NOTE that (4) and (5) need the following:
15619
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
15620
    *   - attribute group references need to be expanded already
15621
    *   - simple types need to be typefixed already
15622
    */
15623
0
    if (type->attrUses &&
15624
0
  (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15625
0
    {
15626
0
  xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15627
0
  xmlSchemaAttributeUsePtr use, tmp;
15628
0
  int i, j, hasId = 0;
15629
15630
0
  for (i = uses->nbItems -1; i >= 0; i--) {
15631
0
      use = uses->items[i];
15632
15633
      /*
15634
      * SPEC ct-props-correct
15635
      * (4) "Two distinct attribute declarations in the
15636
      * {attribute uses} must not have identical {name}s and
15637
      * {target namespace}s."
15638
      */
15639
0
      if (i > 0) {
15640
0
    for (j = i -1; j >= 0; j--) {
15641
0
        tmp = uses->items[j];
15642
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
15643
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
15644
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
15645
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
15646
0
        {
15647
0
      xmlChar *str = NULL;
15648
15649
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15650
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15651
0
          NULL, WXS_BASIC_CAST type,
15652
0
          "Duplicate %s",
15653
0
          xmlSchemaGetComponentDesignation(&str, use),
15654
0
          NULL);
15655
0
      FREE_AND_NULL(str);
15656
      /*
15657
      * Remove the duplicate.
15658
      */
15659
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15660
0
          goto exit_failure;
15661
0
      goto next_use;
15662
0
        }
15663
0
    }
15664
0
      }
15665
      /*
15666
      * SPEC ct-props-correct
15667
      * (5) "Two distinct attribute declarations in the
15668
      * {attribute uses} must not have {type definition}s which
15669
      * are or are derived from ID."
15670
      */
15671
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15672
0
    if (xmlSchemaIsDerivedFromBuiltInType(
15673
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15674
0
    {
15675
0
        if (hasId) {
15676
0
      xmlChar *str = NULL;
15677
15678
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15679
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15680
0
          NULL, WXS_BASIC_CAST type,
15681
0
          "There must not exist more than one attribute "
15682
0
          "declaration of type 'xs:ID' "
15683
0
          "(or derived from 'xs:ID'). The %s violates this "
15684
0
          "constraint",
15685
0
          xmlSchemaGetComponentDesignation(&str, use),
15686
0
          NULL);
15687
0
      FREE_AND_NULL(str);
15688
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15689
0
          goto exit_failure;
15690
0
        }
15691
15692
0
        hasId = 1;
15693
0
    }
15694
0
      }
15695
0
next_use: {}
15696
0
  }
15697
0
    }
15698
0
    return (0);
15699
0
exit_failure:
15700
0
    return(-1);
15701
0
}
15702
15703
static int
15704
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
15705
           xmlSchemaTypePtr typeB)
15706
0
{
15707
    /*
15708
    * TODO: This should implement component-identity
15709
    * in the future.
15710
    */
15711
0
    if ((typeA == NULL) || (typeB == NULL))
15712
0
  return (0);
15713
0
    return (typeA == typeB);
15714
0
}
15715
15716
/**
15717
 * Schema Component Constraint:
15718
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
15719
 *
15720
 * STATUS: completed
15721
 *
15722
 * @param actxt  the schema parser context
15723
 * @param type  the to-be derived complex type definition
15724
 * @param baseType  the base complex type definition
15725
 * @param set  the given set
15726
 * @returns 0 if the constraints are satisfied, or 1
15727
 * if not.
15728
 */
15729
static int
15730
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
15731
           xmlSchemaTypePtr type,
15732
           xmlSchemaTypePtr baseType,
15733
           int set)
15734
0
{
15735
0
    int equal = xmlSchemaAreEqualTypes(type, baseType);
15736
    /* TODO: Error codes. */
15737
    /*
15738
    * SPEC "For a complex type definition (call it D, for derived)
15739
    * to be validly derived from a type definition (call this
15740
    * B, for base) given a subset of {extension, restriction}
15741
    * all of the following must be true:"
15742
    */
15743
0
    if (! equal) {
15744
  /*
15745
  * SPEC (1) "If B and D are not the same type definition, then the
15746
  * {derivation method} of D must not be in the subset."
15747
  */
15748
0
  if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
15749
0
      ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
15750
0
      return (1);
15751
0
    } else {
15752
  /*
15753
  * SPEC (2.1) "B and D must be the same type definition."
15754
  */
15755
0
  return (0);
15756
0
    }
15757
    /*
15758
    * SPEC (2.2) "B must be D's {base type definition}."
15759
    */
15760
0
    if (type->baseType == baseType)
15761
0
  return (0);
15762
    /*
15763
    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
15764
    * definition`."
15765
    */
15766
0
    if (WXS_IS_ANYTYPE(type->baseType))
15767
0
  return (1);
15768
15769
0
    if (WXS_IS_COMPLEX(type->baseType)) {
15770
  /*
15771
  * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
15772
  * must be validly derived from B given the subset as defined by this
15773
  * constraint."
15774
  */
15775
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
15776
0
      baseType, set));
15777
0
    } else {
15778
  /*
15779
  * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
15780
  * must be validly derived from B given the subset as defined in Type
15781
  * Derivation OK (Simple) ($3.14.6).
15782
  */
15783
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
15784
0
      baseType, set));
15785
0
    }
15786
0
}
15787
15788
/**
15789
 * Calls:
15790
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
15791
 *
15792
 * Checks whether `type` can be validly derived from `baseType`.
15793
 *
15794
 * @param actxt  the schema parser context
15795
 * @param type  the derived simple type definition
15796
 * @param baseType  the base type definition
15797
 * @param set  the given set
15798
 * @returns 0 on success, an positive error code otherwise.
15799
 */
15800
static int
15801
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
15802
         xmlSchemaTypePtr type,
15803
         xmlSchemaTypePtr baseType,
15804
         int set)
15805
0
{
15806
0
    if (WXS_IS_SIMPLE(type))
15807
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
15808
0
    else
15809
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
15810
0
}
15811
15812
/**
15813
 * (3.4.6) Constraints on Complex Type Definition Schema Components
15814
 * Schema Component Constraint:
15815
 * Derivation Valid (Extension) (cos-ct-extends)
15816
 *
15817
 * STATUS:
15818
 *   missing:
15819
 *     (1.5)
15820
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
15821
 *
15822
 * @param ctxt  the schema parser context
15823
 * @param type  the complex type definition
15824
 * @returns 0 if the constraints are satisfied, a positive
15825
 * error code if not and -1 if an internal error occurred.
15826
 */
15827
static int
15828
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
15829
         xmlSchemaTypePtr type)
15830
0
{
15831
0
    xmlSchemaTypePtr base = type->baseType;
15832
    /*
15833
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
15834
    * temporarily only.
15835
    */
15836
    /*
15837
    * SPEC (1) "If the {base type definition} is a complex type definition,
15838
    * then all of the following must be true:"
15839
    */
15840
0
    if (WXS_IS_COMPLEX(base)) {
15841
  /*
15842
  * SPEC (1.1) "The {final} of the {base type definition} must not
15843
  * contain extension."
15844
  */
15845
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
15846
0
      xmlSchemaPCustomErr(ctxt,
15847
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
15848
0
    WXS_BASIC_CAST type, NULL,
15849
0
    "The 'final' of the base type definition "
15850
0
    "contains 'extension'", NULL);
15851
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
15852
0
  }
15853
15854
  /*
15855
  * ATTENTION: The constrains (1.2) and (1.3) are not applied,
15856
  * since they are automatically satisfied through the
15857
  * inheriting mechanism.
15858
  * Note that even if redefining components, the inheriting mechanism
15859
  * is used.
15860
  */
15861
#if 0
15862
  /*
15863
  * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
15864
  * uses}
15865
  * of the complex type definition itself, that is, for every attribute
15866
  * use in the {attribute uses} of the {base type definition}, there
15867
  * must be an attribute use in the {attribute uses} of the complex
15868
  * type definition itself whose {attribute declaration} has the same
15869
  * {name}, {target namespace} and {type definition} as its attribute
15870
  * declaration"
15871
  */
15872
  if (base->attrUses != NULL) {
15873
      int i, j, found;
15874
      xmlSchemaAttributeUsePtr use, buse;
15875
15876
      for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
15877
    buse = (WXS_LIST_CAST base->attrUses)->items[i];
15878
    found = 0;
15879
    if (type->attrUses != NULL) {
15880
        use = (WXS_LIST_CAST type->attrUses)->items[j];
15881
        for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
15882
        {
15883
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
15884
        WXS_ATTRUSE_DECL_NAME(buse)) &&
15885
          (WXS_ATTRUSE_DECL_TNS(use) ==
15886
        WXS_ATTRUSE_DECL_TNS(buse)) &&
15887
          (WXS_ATTRUSE_TYPEDEF(use) ==
15888
        WXS_ATTRUSE_TYPEDEF(buse))
15889
      {
15890
          found = 1;
15891
          break;
15892
      }
15893
        }
15894
    }
15895
    if (! found) {
15896
        xmlChar *str = NULL;
15897
15898
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
15899
      XML_SCHEMAP_COS_CT_EXTENDS_1_2,
15900
      NULL, WXS_BASIC_CAST type,
15901
      /*
15902
      * TODO: The report does not indicate that also the
15903
      * type needs to be the same.
15904
      */
15905
      "This type is missing a matching correspondent "
15906
      "for its {base type}'s %s in its {attribute uses}",
15907
      xmlSchemaGetComponentDesignation(&str,
15908
          buse->children),
15909
      NULL);
15910
        FREE_AND_NULL(str)
15911
    }
15912
      }
15913
  }
15914
  /*
15915
  * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
15916
  * definition must also have one, and the base type definition's
15917
  * {attribute  wildcard}'s {namespace constraint} must be a subset
15918
  * of the complex  type definition's {attribute wildcard}'s {namespace
15919
  * constraint}, as defined by Wildcard Subset ($3.10.6)."
15920
  */
15921
15922
  /*
15923
  * MAYBE TODO: Enable if ever needed. But this will be needed only
15924
  * if created the type via a schema construction API.
15925
  */
15926
  if (base->attributeWildcard != NULL) {
15927
      if (type->attributeWildcard == NULL) {
15928
    xmlChar *str = NULL;
15929
15930
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
15931
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
15932
        NULL, type,
15933
        "The base %s has an attribute wildcard, "
15934
        "but this type is missing an attribute wildcard",
15935
        xmlSchemaGetComponentDesignation(&str, base));
15936
    FREE_AND_NULL(str)
15937
15938
      } else if (xmlSchemaCheckCOSNSSubset(
15939
    base->attributeWildcard, type->attributeWildcard))
15940
      {
15941
    xmlChar *str = NULL;
15942
15943
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
15944
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
15945
        NULL, type,
15946
        "The attribute wildcard is not a valid "
15947
        "superset of the one in the base %s",
15948
        xmlSchemaGetComponentDesignation(&str, base));
15949
    FREE_AND_NULL(str)
15950
      }
15951
  }
15952
#endif
15953
  /*
15954
  * SPEC (1.4) "One of the following must be true:"
15955
  */
15956
0
  if ((type->contentTypeDef != NULL) &&
15957
0
      (type->contentTypeDef == base->contentTypeDef)) {
15958
      /*
15959
      * SPEC (1.4.1) "The {content type} of the {base type definition}
15960
      * and the {content type} of the complex type definition itself
15961
      * must be the same simple type definition"
15962
      * PASS
15963
      */
15964
0
  } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
15965
0
      (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
15966
      /*
15967
      * SPEC (1.4.2) "The {content type} of both the {base type
15968
      * definition} and the complex type definition itself must
15969
      * be empty."
15970
      * PASS
15971
      */
15972
0
  } else {
15973
      /*
15974
      * SPEC (1.4.3) "All of the following must be true:"
15975
      */
15976
0
      if (type->subtypes == NULL) {
15977
    /*
15978
    * SPEC 1.4.3.1 The {content type} of the complex type
15979
    * definition itself must specify a particle.
15980
    */
15981
0
    xmlSchemaPCustomErr(ctxt,
15982
0
        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
15983
0
        WXS_BASIC_CAST type, NULL,
15984
0
        "The content type must specify a particle", NULL);
15985
0
    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
15986
0
      }
15987
      /*
15988
      * SPEC (1.4.3.2) "One of the following must be true:"
15989
      */
15990
0
      if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
15991
    /*
15992
    * SPEC (1.4.3.2.1) "The {content type} of the {base type
15993
    * definition} must be empty.
15994
    * PASS
15995
    */
15996
0
      } else {
15997
    /*
15998
    * SPEC (1.4.3.2.2) "All of the following must be true:"
15999
    */
16000
0
    if ((type->contentType != base->contentType) ||
16001
0
        ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16002
0
        (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16003
        /*
16004
        * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16005
        * or both must be element-only."
16006
        */
16007
0
        xmlSchemaPCustomErr(ctxt,
16008
0
      XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16009
0
      WXS_BASIC_CAST type, NULL,
16010
0
      "The content type of both, the type and its base "
16011
0
      "type, must either 'mixed' or 'element-only'", NULL);
16012
0
        return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16013
0
    }
16014
    /*
16015
    * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16016
    * complex type definition must be a `valid extension`
16017
    * of the {base type definition}'s particle, as defined
16018
    * in Particle Valid (Extension) ($3.9.6)."
16019
    *
16020
    * NOTE that we won't check "Particle Valid (Extension)",
16021
    * since it is ensured by the derivation process in
16022
    * xmlSchemaTypeFixup(). We need to implement this when heading
16023
    * for a construction API
16024
    * TODO: !! This is needed to be checked if redefining a type !!
16025
    */
16026
0
      }
16027
      /*
16028
      * URGENT TODO (1.5)
16029
      */
16030
0
  }
16031
0
    } else {
16032
  /*
16033
  * SPEC (2) "If the {base type definition} is a simple type definition,
16034
  * then all of the following must be true:"
16035
  */
16036
0
  if (type->contentTypeDef != base) {
16037
      /*
16038
      * SPEC (2.1) "The {content type} must be the same simple type
16039
      * definition."
16040
      */
16041
0
      xmlSchemaPCustomErr(ctxt,
16042
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16043
0
    WXS_BASIC_CAST type, NULL,
16044
0
    "The content type must be the simple base type", NULL);
16045
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16046
0
  }
16047
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16048
      /*
16049
      * SPEC (2.2) "The {final} of the {base type definition} must not
16050
      * contain extension"
16051
      * NOTE that this is the same as (1.1).
16052
      */
16053
0
      xmlSchemaPCustomErr(ctxt,
16054
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16055
0
    WXS_BASIC_CAST type, NULL,
16056
0
    "The 'final' of the base type definition "
16057
0
    "contains 'extension'", NULL);
16058
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16059
0
  }
16060
0
    }
16061
0
    return (0);
16062
0
}
16063
16064
/**
16065
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16066
 * Schema Component Constraint:
16067
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16068
 *
16069
 * STATUS:
16070
 *   missing:
16071
 *     (5.4.2) ???
16072
 *
16073
 * ATTENTION:
16074
 * In XML Schema 1.1 this will be:
16075
 * Validation Rule: Checking complex type subsumption
16076
 *
16077
 * @param ctxt  the schema parser context
16078
 * @param type  the complex type definition
16079
 * @returns 0 if the constraints are satisfied, a positive
16080
 * error code if not and -1 if an internal error occurred.
16081
 */
16082
static int
16083
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16084
              xmlSchemaTypePtr type)
16085
0
{
16086
0
    xmlSchemaTypePtr base;
16087
16088
    /*
16089
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16090
    * temporarily only.
16091
    */
16092
0
    base = type->baseType;
16093
0
    if (! WXS_IS_COMPLEX(base)) {
16094
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16095
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16096
0
      type->node, WXS_BASIC_CAST type,
16097
0
      "The base type must be a complex type", NULL, NULL);
16098
0
  return(ctxt->err);
16099
0
    }
16100
0
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16101
  /*
16102
  * SPEC (1) "The {base type definition} must be a complex type
16103
  * definition whose {final} does not contain restriction."
16104
  */
16105
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16106
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16107
0
      type->node, WXS_BASIC_CAST type,
16108
0
      "The 'final' of the base type definition "
16109
0
      "contains 'restriction'", NULL, NULL);
16110
0
  return (ctxt->err);
16111
0
    }
16112
    /*
16113
    * SPEC (2), (3) and (4)
16114
    * Those are handled in a separate function, since the
16115
    * same constraints are needed for redefinition of
16116
    * attribute groups as well.
16117
    */
16118
0
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16119
0
  XML_SCHEMA_ACTION_DERIVE,
16120
0
  WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16121
0
  type->attrUses, base->attrUses,
16122
0
  type->attributeWildcard,
16123
0
  base->attributeWildcard) == -1)
16124
0
    {
16125
0
  return(-1);
16126
0
    }
16127
    /*
16128
    * SPEC (5) "One of the following must be true:"
16129
    */
16130
0
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16131
  /*
16132
  * SPEC (5.1) "The {base type definition} must be the
16133
  * `ur-type definition`."
16134
  * PASS
16135
  */
16136
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16137
0
      (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16138
  /*
16139
  * SPEC (5.2.1) "The {content type} of the complex type definition
16140
  * must be a simple type definition"
16141
  *
16142
  * SPEC (5.2.2) "One of the following must be true:"
16143
  */
16144
0
  if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16145
0
      (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16146
0
  {
16147
0
      int err;
16148
      /*
16149
      * SPEC (5.2.2.1) "The {content type} of the {base type
16150
      * definition} must be a simple type definition from which
16151
      * the {content type} is validly derived given the empty
16152
      * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16153
      *
16154
      * ATTENTION TODO: This seems not needed if the type implicitly
16155
      * derived from the base type.
16156
      *
16157
      */
16158
0
      err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16159
0
    type->contentTypeDef, base->contentTypeDef, 0);
16160
0
      if (err != 0) {
16161
0
    xmlChar *strA = NULL, *strB = NULL;
16162
16163
0
    if (err == -1)
16164
0
        return(-1);
16165
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16166
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16167
0
        NULL, WXS_BASIC_CAST type,
16168
0
        "The {content type} %s is not validly derived from the "
16169
0
        "base type's {content type} %s",
16170
0
        xmlSchemaGetComponentDesignation(&strA,
16171
0
      type->contentTypeDef),
16172
0
        xmlSchemaGetComponentDesignation(&strB,
16173
0
      base->contentTypeDef));
16174
0
    FREE_AND_NULL(strA);
16175
0
    FREE_AND_NULL(strB);
16176
0
    return(ctxt->err);
16177
0
      }
16178
0
  } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16179
0
      (xmlSchemaIsParticleEmptiable(
16180
0
    (xmlSchemaParticlePtr) base->subtypes))) {
16181
      /*
16182
      * SPEC (5.2.2.2) "The {base type definition} must be mixed
16183
      * and have a particle which is `emptiable` as defined in
16184
      * Particle Emptiable ($3.9.6)."
16185
      * PASS
16186
      */
16187
0
  } else {
16188
0
      xmlSchemaPCustomErr(ctxt,
16189
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16190
0
    WXS_BASIC_CAST type, NULL,
16191
0
    "The content type of the base type must be either "
16192
0
    "a simple type or 'mixed' and an emptiable particle", NULL);
16193
0
      return (ctxt->err);
16194
0
  }
16195
0
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16196
  /*
16197
  * SPEC (5.3.1) "The {content type} of the complex type itself must
16198
  * be empty"
16199
  */
16200
0
  if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16201
      /*
16202
      * SPEC (5.3.2.1) "The {content type} of the {base type
16203
      * definition} must also be empty."
16204
      * PASS
16205
      */
16206
0
  } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16207
0
      (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16208
0
      xmlSchemaIsParticleEmptiable(
16209
0
    (xmlSchemaParticlePtr) base->subtypes)) {
16210
      /*
16211
      * SPEC (5.3.2.2) "The {content type} of the {base type
16212
      * definition} must be elementOnly or mixed and have a particle
16213
      * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16214
      * PASS
16215
      */
16216
0
  } else {
16217
0
      xmlSchemaPCustomErr(ctxt,
16218
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16219
0
    WXS_BASIC_CAST type, NULL,
16220
0
    "The content type of the base type must be either "
16221
0
    "empty or 'mixed' (or 'elements-only') and an emptiable "
16222
0
    "particle", NULL);
16223
0
      return (ctxt->err);
16224
0
  }
16225
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16226
0
  WXS_HAS_MIXED_CONTENT(type)) {
16227
  /*
16228
  * SPEC (5.4.1.1) "The {content type} of the complex type definition
16229
  * itself must be element-only"
16230
  */
16231
0
  if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16232
      /*
16233
      * SPEC (5.4.1.2) "The {content type} of the complex type
16234
      * definition itself and of the {base type definition} must be
16235
      * mixed"
16236
      */
16237
0
      xmlSchemaPCustomErr(ctxt,
16238
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16239
0
    WXS_BASIC_CAST type, NULL,
16240
0
    "If the content type is 'mixed', then the content type of the "
16241
0
    "base type must also be 'mixed'", NULL);
16242
0
      return (ctxt->err);
16243
0
  }
16244
  /*
16245
  * SPEC (5.4.2) "The particle of the complex type definition itself
16246
  * must be a `valid restriction` of the particle of the {content
16247
  * type} of the {base type definition} as defined in Particle Valid
16248
  * (Restriction) ($3.9.6).
16249
  *
16250
  * URGENT TODO: (5.4.2)
16251
  */
16252
0
    } else {
16253
0
  xmlSchemaPCustomErr(ctxt,
16254
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16255
0
      WXS_BASIC_CAST type, NULL,
16256
0
      "The type is not a valid restriction of its base type", NULL);
16257
0
  return (ctxt->err);
16258
0
    }
16259
0
    return (0);
16260
0
}
16261
16262
/**
16263
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16264
 *
16265
 * @param ctxt  the schema parser context
16266
 * @param type  the complex type definition
16267
 * @returns 0 if the constraints are satisfied, a positive
16268
 * error code if not and -1 if an internal error occurred.
16269
 */
16270
static int
16271
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16272
        xmlSchemaTypePtr type)
16273
0
{
16274
0
    int ret;
16275
    /*
16276
    * Complex Type Definition Properties Correct
16277
    */
16278
0
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16279
0
    if (ret != 0)
16280
0
  return (ret);
16281
0
    if (WXS_IS_EXTENSION(type))
16282
0
  ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16283
0
    else
16284
0
  ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16285
0
    return (ret);
16286
0
}
16287
16288
/**
16289
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16290
 * Schema Representation Constraint:
16291
 * Complex Type Definition Representation OK (src-ct)
16292
 *
16293
 * @param ctxt  the schema parser context
16294
 * @param type  the complex type definition
16295
 * @returns 0 if the constraints are satisfied, a positive
16296
 * error code if not and -1 if an internal error occurred.
16297
 */
16298
static int
16299
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16300
        xmlSchemaTypePtr type)
16301
0
{
16302
0
    xmlSchemaTypePtr base;
16303
0
    int ret = 0;
16304
16305
    /*
16306
    * TODO: Adjust the error codes here, as I used
16307
    * XML_SCHEMAP_SRC_CT_1 only yet.
16308
    */
16309
0
    base = type->baseType;
16310
0
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16311
  /*
16312
  * 1 If the <complexContent> alternative is chosen, the type definition
16313
  * `resolved` to by the `actual value` of the base [attribute]
16314
  * must be a complex type definition;
16315
  */
16316
0
  if (! WXS_IS_COMPLEX(base)) {
16317
0
      xmlChar *str = NULL;
16318
0
      xmlSchemaPCustomErr(ctxt,
16319
0
    XML_SCHEMAP_SRC_CT_1,
16320
0
    WXS_BASIC_CAST type, type->node,
16321
0
    "If using <complexContent>, the base type is expected to be "
16322
0
    "a complex type. The base type '%s' is a simple type",
16323
0
    xmlSchemaFormatQName(&str, base->targetNamespace,
16324
0
    base->name));
16325
0
      FREE_AND_NULL(str)
16326
0
      return (XML_SCHEMAP_SRC_CT_1);
16327
0
  }
16328
0
    } else {
16329
  /*
16330
  * SPEC
16331
  * 2 If the <simpleContent> alternative is chosen, all of the
16332
  * following must be true:
16333
  * 2.1 The type definition `resolved` to by the `actual value` of the
16334
  * base [attribute] must be one of the following:
16335
  */
16336
0
  if (WXS_IS_SIMPLE(base)) {
16337
0
      if (WXS_IS_EXTENSION(type) == 0) {
16338
0
    xmlChar *str = NULL;
16339
    /*
16340
    * 2.1.3 only if the <extension> alternative is also
16341
    * chosen, a simple type definition.
16342
    */
16343
    /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16344
0
    xmlSchemaPCustomErr(ctxt,
16345
0
        XML_SCHEMAP_SRC_CT_1,
16346
0
        WXS_BASIC_CAST type, NULL,
16347
0
        "If using <simpleContent> and <restriction>, the base "
16348
0
        "type must be a complex type. The base type '%s' is "
16349
0
        "a simple type",
16350
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16351
0
      base->name));
16352
0
    FREE_AND_NULL(str)
16353
0
    return (XML_SCHEMAP_SRC_CT_1);
16354
0
      }
16355
0
  } else {
16356
      /* Base type is a complex type. */
16357
0
      if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16358
0
    (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16359
    /*
16360
    * 2.1.1 a complex type definition whose {content type} is a
16361
    * simple type definition;
16362
    * PASS
16363
    */
16364
0
    if (base->contentTypeDef == NULL) {
16365
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16366
0
      WXS_BASIC_CAST type, NULL,
16367
0
      "Internal error: xmlSchemaCheckSRCCT, "
16368
0
      "'%s', base type has no content type",
16369
0
      type->name);
16370
0
        return (-1);
16371
0
    }
16372
0
      } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16373
0
    (WXS_IS_RESTRICTION(type))) {
16374
16375
    /*
16376
    * 2.1.2 only if the <restriction> alternative is also
16377
    * chosen, a complex type definition whose {content type}
16378
    * is mixed and a particle emptiable.
16379
    */
16380
0
    if (! xmlSchemaIsParticleEmptiable(
16381
0
        (xmlSchemaParticlePtr) base->subtypes)) {
16382
0
        ret = XML_SCHEMAP_SRC_CT_1;
16383
0
    } else
16384
        /*
16385
        * Attention: at this point the <simpleType> child is in
16386
        * ->contentTypeDef (put there during parsing).
16387
        */
16388
0
        if (type->contentTypeDef == NULL) {
16389
0
        xmlChar *str = NULL;
16390
        /*
16391
        * 2.2 If clause 2.1.2 above is satisfied, then there
16392
        * must be a <simpleType> among the [children] of
16393
        * <restriction>.
16394
        */
16395
        /* TODO: Change error code to ..._SRC_CT_2_2. */
16396
0
        xmlSchemaPCustomErr(ctxt,
16397
0
      XML_SCHEMAP_SRC_CT_1,
16398
0
      WXS_BASIC_CAST type, NULL,
16399
0
      "A <simpleType> is expected among the children "
16400
0
      "of <restriction>, if <simpleContent> is used and "
16401
0
      "the base type '%s' is a complex type",
16402
0
      xmlSchemaFormatQName(&str, base->targetNamespace,
16403
0
      base->name));
16404
0
        FREE_AND_NULL(str)
16405
0
        return (XML_SCHEMAP_SRC_CT_1);
16406
0
    }
16407
0
      } else {
16408
0
    ret = XML_SCHEMAP_SRC_CT_1;
16409
0
      }
16410
0
  }
16411
0
  if (ret > 0) {
16412
0
      xmlChar *str = NULL;
16413
0
      if (WXS_IS_RESTRICTION(type)) {
16414
0
    xmlSchemaPCustomErr(ctxt,
16415
0
        XML_SCHEMAP_SRC_CT_1,
16416
0
        WXS_BASIC_CAST type, NULL,
16417
0
        "If <simpleContent> and <restriction> is used, the "
16418
0
        "base type must be a simple type or a complex type with "
16419
0
        "mixed content and particle emptiable. The base type "
16420
0
        "'%s' is none of those",
16421
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16422
0
        base->name));
16423
0
      } else {
16424
0
    xmlSchemaPCustomErr(ctxt,
16425
0
        XML_SCHEMAP_SRC_CT_1,
16426
0
        WXS_BASIC_CAST type, NULL,
16427
0
        "If <simpleContent> and <extension> is used, the "
16428
0
        "base type must be a simple type. The base type '%s' "
16429
0
        "is a complex type",
16430
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16431
0
        base->name));
16432
0
      }
16433
0
      FREE_AND_NULL(str)
16434
0
  }
16435
0
    }
16436
    /*
16437
    * SPEC (3) "The corresponding complex type definition component must
16438
    * satisfy the conditions set out in Constraints on Complex Type
16439
    * Definition Schema Components ($3.4.6);"
16440
    * NOTE (3) will be done in xmlSchemaTypeFixup().
16441
    */
16442
    /*
16443
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16444
    * above for {attribute wildcard} is satisfied, the intensional
16445
    * intersection must be expressible, as defined in Attribute Wildcard
16446
    * Intersection ($3.10.6).
16447
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16448
    */
16449
0
    return (ret);
16450
0
}
16451
16452
#ifdef ENABLE_PARTICLE_RESTRICTION
16453
/**
16454
 * (3.9.6) Constraints on Particle Schema Components
16455
 * Schema Component Constraint:
16456
 * Occurrence Range OK (range-ok)
16457
 *
16458
 * STATUS: complete
16459
 *
16460
 * @param ctxt  the schema parser context
16461
 * @param type  the complex type definition
16462
 * @returns 0 if the constraints are satisfied, a positive
16463
 * error code if not and -1 if an internal error occurred.
16464
 */
16465
static int
16466
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16467
            int bmin, int bmax)
16468
{
16469
    if (rmin < bmin)
16470
  return (1);
16471
    if ((bmax != UNBOUNDED) &&
16472
  (rmax > bmax))
16473
  return (1);
16474
    return (0);
16475
}
16476
16477
/**
16478
 * (3.9.6) Constraints on Particle Schema Components
16479
 * Schema Component Constraint:
16480
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16481
 * (rcase-NameAndTypeOK)
16482
 *
16483
 * STATUS:
16484
 *   MISSING (3.2.3)
16485
 *   CLARIFY: (3.2.2)
16486
 *
16487
 * @param ctxt  the schema parser context
16488
 * @param r  the restricting element declaration particle
16489
 * @param b  the base element declaration particle
16490
 * @returns 0 if the constraints are satisfied, a positive
16491
 * error code if not and -1 if an internal error occurred.
16492
 */
16493
static int
16494
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16495
         xmlSchemaParticlePtr r,
16496
         xmlSchemaParticlePtr b)
16497
{
16498
    xmlSchemaElementPtr elemR, elemB;
16499
16500
    /* TODO: Error codes (rcase-NameAndTypeOK). */
16501
    elemR = (xmlSchemaElementPtr) r->children;
16502
    elemB = (xmlSchemaElementPtr) b->children;
16503
    /*
16504
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
16505
    * the same."
16506
    */
16507
    if ((elemR != elemB) &&
16508
  ((! xmlStrEqual(elemR->name, elemB->name)) ||
16509
  (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16510
  return (1);
16511
    /*
16512
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16513
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16514
    */
16515
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16516
      b->minOccurs, b->maxOccurs) != 0)
16517
  return (1);
16518
    /*
16519
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16520
    * {scope} are global."
16521
    */
16522
    if (elemR == elemB)
16523
  return (0);
16524
    /*
16525
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16526
    */
16527
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16528
  (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16529
   return (1);
16530
    /*
16531
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16532
    * or is not fixed, or R's declaration's {value constraint} is fixed
16533
    * with the same value."
16534
    */
16535
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16536
  ((elemR->value == NULL) ||
16537
   ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16538
   /* TODO: Equality of the initial value or normalized or canonical? */
16539
   (! xmlStrEqual(elemR->value, elemB->value))))
16540
   return (1);
16541
    /*
16542
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16543
    * definitions} is a subset of B's declaration's {identity-constraint
16544
    * definitions}, if any."
16545
    */
16546
    if (elemB->idcs != NULL) {
16547
  /* TODO */
16548
    }
16549
    /*
16550
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16551
    * superset of B's declaration's {disallowed substitutions}."
16552
    */
16553
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16554
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16555
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16556
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16557
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16558
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16559
   return (1);
16560
    /*
16561
    * SPEC (3.2.5) "R's {type definition} is validly derived given
16562
    * {extension, list, union} from B's {type definition}"
16563
    *
16564
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
16565
    * set, if the corresponding constraints handle "restriction" and
16566
    * "extension" only?
16567
    *
16568
    */
16569
    {
16570
  int set = 0;
16571
16572
  set |= SUBSET_EXTENSION;
16573
  set |= SUBSET_LIST;
16574
  set |= SUBSET_UNION;
16575
  if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16576
      elemB->subtypes, set) != 0)
16577
      return (1);
16578
    }
16579
    return (0);
16580
}
16581
16582
/**
16583
 * (3.9.6) Constraints on Particle Schema Components
16584
 * Schema Component Constraint:
16585
 * Particle Derivation OK (Elt:Any -- NSCompat)
16586
 * (rcase-NSCompat)
16587
 *
16588
 * STATUS: complete
16589
 *
16590
 * @param ctxt  the schema parser context
16591
 * @param r  the restricting element declaration particle
16592
 * @param b  the base wildcard particle
16593
 * @returns 0 if the constraints are satisfied, a positive
16594
 * error code if not and -1 if an internal error occurred.
16595
 */
16596
static int
16597
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16598
          xmlSchemaParticlePtr r,
16599
          xmlSchemaParticlePtr b)
16600
{
16601
    /* TODO:Error codes (rcase-NSCompat). */
16602
    /*
16603
    * SPEC "For an element declaration particle to be a `valid restriction`
16604
    * of a wildcard particle all of the following must be true:"
16605
    *
16606
    * SPEC (1) "The element declaration's {target namespace} is `valid`
16607
    * with respect to the wildcard's {namespace constraint} as defined by
16608
    * Wildcard allows Namespace Name ($3.10.4)."
16609
    */
16610
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16611
  ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16612
  return (1);
16613
    /*
16614
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16615
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16616
    */
16617
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16618
      b->minOccurs, b->maxOccurs) != 0)
16619
  return (1);
16620
16621
    return (0);
16622
}
16623
16624
/**
16625
 * (3.9.6) Constraints on Particle Schema Components
16626
 * Schema Component Constraint:
16627
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16628
 * (rcase-RecurseAsIfGroup)
16629
 *
16630
 * STATUS: TODO
16631
 *
16632
 * @param ctxt  the schema parser context
16633
 * @param r  the restricting element declaration particle
16634
 * @param b  the base model group particle
16635
 * @returns 0 if the constraints are satisfied, a positive
16636
 * error code if not and -1 if an internal error occurred.
16637
 */
16638
static int
16639
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16640
            xmlSchemaParticlePtr r,
16641
            xmlSchemaParticlePtr b)
16642
{
16643
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16644
    TODO
16645
    return (0);
16646
}
16647
16648
/**
16649
 * (3.9.6) Constraints on Particle Schema Components
16650
 * Schema Component Constraint:
16651
 * Particle Derivation OK (Any:Any -- NSSubset)
16652
 * (rcase-NSSubset)
16653
 *
16654
 * STATUS: complete
16655
 *
16656
 * @param ctxt  the schema parser context
16657
 * @param r  the restricting wildcard particle
16658
 * @param b  the base wildcard particle
16659
 * @returns 0 if the constraints are satisfied, a positive
16660
 * error code if not and -1 if an internal error occurred.
16661
 */
16662
static int
16663
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16664
            xmlSchemaParticlePtr r,
16665
            xmlSchemaParticlePtr b,
16666
            int isAnyTypeBase)
16667
{
16668
    /* TODO: Error codes (rcase-NSSubset). */
16669
    /*
16670
    * SPEC (1) "R's occurrence range is a valid restriction of B's
16671
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16672
    */
16673
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16674
      b->minOccurs, b->maxOccurs))
16675
  return (1);
16676
    /*
16677
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
16678
    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
16679
    */
16680
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
16681
  (xmlSchemaWildcardPtr) b->children))
16682
  return (1);
16683
    /*
16684
    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
16685
    * definition`, R's {process contents} must be identical to or stronger
16686
    * than B's {process contents}, where strict is stronger than lax is
16687
    * stronger than skip."
16688
    */
16689
    if (! isAnyTypeBase) {
16690
  if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
16691
      ((xmlSchemaWildcardPtr) b->children)->processContents)
16692
      return (1);
16693
    }
16694
16695
    return (0);
16696
}
16697
16698
/**
16699
 * (3.9.6) Constraints on Particle Schema Components
16700
 * Schema Component Constraint:
16701
 * Particle Valid (Restriction) (cos-particle-restrict)
16702
 *
16703
 * STATUS: TODO
16704
 *
16705
 * @param ctxt  the schema parser context
16706
 * @param type  the complex type definition
16707
 * @returns 0 if the constraints are satisfied, a positive
16708
 * error code if not and -1 if an internal error occurred.
16709
 */
16710
static int
16711
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
16712
          xmlSchemaParticlePtr r,
16713
          xmlSchemaParticlePtr b)
16714
{
16715
    int ret = 0;
16716
16717
    /*part = WXS_TYPE_PARTICLE(type);
16718
    basePart = WXS_TYPE_PARTICLE(base);
16719
    */
16720
16721
    TODO
16722
16723
    /*
16724
    * SPEC (1) "They are the same particle."
16725
    */
16726
    if (r == b)
16727
  return (0);
16728
16729
16730
    return (0);
16731
}
16732
16733
#if 0
16734
/**
16735
 * (3.9.6) Constraints on Particle Schema Components
16736
 * Schema Component Constraint:
16737
 * Particle Derivation OK (All/Choice/Sequence:Any --
16738
 *                         NSRecurseCheckCardinality)
16739
 * (rcase-NSRecurseCheckCardinality)
16740
 *
16741
 * STATUS: TODO: subst-groups
16742
 *
16743
 * @param ctxt  the schema parser context
16744
 * @param r  the model group particle
16745
 * @param b  the base wildcard particle
16746
 * @returns 0 if the constraints are satisfied, a positive
16747
 * error code if not and -1 if an internal error occurred.
16748
 */
16749
static int
16750
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
16751
               xmlSchemaParticlePtr r,
16752
               xmlSchemaParticlePtr b)
16753
{
16754
    xmlSchemaParticlePtr part;
16755
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
16756
    if ((r->children == NULL) || (r->children->children == NULL))
16757
  return (-1);
16758
    /*
16759
    * SPEC "For a group particle to be a `valid restriction` of a
16760
    * wildcard particle..."
16761
    *
16762
    * SPEC (1) "Every member of the {particles} of the group is a `valid
16763
    * restriction` of the wildcard as defined by
16764
    * Particle Valid (Restriction) ($3.9.6)."
16765
    */
16766
    part = (xmlSchemaParticlePtr) r->children->children;
16767
    do {
16768
  if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
16769
      return (1);
16770
  part = (xmlSchemaParticlePtr) part->next;
16771
    } while (part != NULL);
16772
    /*
16773
    * SPEC (2) "The effective total range of the group [...] is a
16774
    * valid restriction of B's occurrence range as defined by
16775
    * Occurrence Range OK ($3.9.6)."
16776
    */
16777
    if (xmlSchemaCheckParticleRangeOK(
16778
      xmlSchemaGetParticleTotalRangeMin(r),
16779
      xmlSchemaGetParticleTotalRangeMax(r),
16780
      b->minOccurs, b->maxOccurs) != 0)
16781
  return (1);
16782
    return (0);
16783
}
16784
#endif
16785
16786
/**
16787
 * (3.9.6) Constraints on Particle Schema Components
16788
 * Schema Component Constraint:
16789
 * Particle Derivation OK (All:All,Sequence:Sequence --
16790
                           Recurse)
16791
 * (rcase-Recurse)
16792
 *
16793
 * STATUS:  ?
16794
 * TODO: subst-groups
16795
 *
16796
 * @param ctxt  the schema parser context
16797
 * @param r  the <all> or <sequence> model group particle
16798
 * @param b  the base <all> or <sequence> model group particle
16799
 * @returns 0 if the constraints are satisfied, a positive
16800
 * error code if not and -1 if an internal error occurred.
16801
 */
16802
static int
16803
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
16804
         xmlSchemaParticlePtr r,
16805
         xmlSchemaParticlePtr b)
16806
{
16807
    /* xmlSchemaParticlePtr part; */
16808
    /* TODO: Error codes (rcase-Recurse). */
16809
    if ((r->children == NULL) || (b->children == NULL) ||
16810
  (r->children->type != b->children->type))
16811
  return (-1);
16812
    /*
16813
    * SPEC "For an all or sequence group particle to be a `valid
16814
    * restriction` of another group particle with the same {compositor}..."
16815
    *
16816
    * SPEC (1) "R's occurrence range is a valid restriction of B's
16817
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16818
    */
16819
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16820
      b->minOccurs, b->maxOccurs))
16821
  return (1);
16822
16823
16824
    return (0);
16825
}
16826
16827
#endif
16828
16829
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
16830
0
    xmlSchemaPCustomErrExt(pctxt,      \
16831
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
16832
0
  WXS_BASIC_CAST fac1, fac1->node, \
16833
0
  "It is an error for both '%s' and '%s' to be specified on the "\
16834
0
  "same type definition", \
16835
0
  BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
16836
0
  BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
16837
16838
#define FACET_RESTR_ERR(fac1, msg) \
16839
0
    xmlSchemaPCustomErr(pctxt,      \
16840
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
16841
0
  WXS_BASIC_CAST fac1, fac1->node, \
16842
0
  msg, NULL);
16843
16844
#define FACET_RESTR_FIXED_ERR(fac) \
16845
0
    xmlSchemaPCustomErr(pctxt, \
16846
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
16847
0
  WXS_BASIC_CAST fac, fac->node, \
16848
0
  "The base type's facet is 'fixed', thus the value must not " \
16849
0
  "differ", NULL);
16850
16851
static void
16852
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
16853
      xmlSchemaFacetPtr facet1,
16854
      xmlSchemaFacetPtr facet2,
16855
      int lessGreater,
16856
      int orEqual,
16857
      int ofBase)
16858
0
{
16859
0
    xmlChar *msg = NULL;
16860
16861
0
    msg = xmlStrdup(BAD_CAST "'");
16862
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
16863
0
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
16864
0
    if (lessGreater == 0)
16865
0
  msg = xmlStrcat(msg, BAD_CAST " equal to");
16866
0
    if (lessGreater == 1)
16867
0
  msg = xmlStrcat(msg, BAD_CAST " greater than");
16868
0
    else
16869
0
  msg = xmlStrcat(msg, BAD_CAST " less than");
16870
16871
0
    if (orEqual)
16872
0
  msg = xmlStrcat(msg, BAD_CAST " or equal to");
16873
0
    msg = xmlStrcat(msg, BAD_CAST " '");
16874
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
16875
0
    if (ofBase)
16876
0
  msg = xmlStrcat(msg, BAD_CAST "' of the base type");
16877
0
    else
16878
0
  msg = xmlStrcat(msg, BAD_CAST "'");
16879
16880
0
    xmlSchemaPCustomErr(pctxt,
16881
0
  XML_SCHEMAP_INVALID_FACET_VALUE,
16882
0
  WXS_BASIC_CAST facet1, NULL,
16883
0
  (const char *) msg, NULL);
16884
16885
0
    if (msg != NULL)
16886
0
  xmlFree(msg);
16887
0
}
16888
16889
/*
16890
* xmlSchemaDeriveAndValidateFacets:
16891
*
16892
* Schema Component Constraint: Simple Type Restriction (Facets)
16893
* (st-restrict-facets)
16894
*/
16895
static int
16896
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
16897
         xmlSchemaTypePtr type)
16898
0
{
16899
0
    xmlSchemaTypePtr base = type->baseType;
16900
0
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
16901
0
    xmlSchemaFacetPtr facet, bfacet,
16902
0
  flength = NULL, ftotdig = NULL, ffracdig = NULL,
16903
0
  fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
16904
0
  fmininc = NULL, fmaxinc = NULL,
16905
0
  fminexc = NULL, fmaxexc = NULL,
16906
0
  bflength = NULL, bftotdig = NULL, bffracdig = NULL,
16907
0
  bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
16908
0
  bfmininc = NULL, bfmaxinc = NULL,
16909
0
  bfminexc = NULL, bfmaxexc = NULL;
16910
0
    int res; /* err = 0, fixedErr; */
16911
16912
    /*
16913
    * SPEC st-restrict-facets 1:
16914
    * "The {variety} of R is the same as that of B."
16915
    */
16916
    /*
16917
    * SPEC st-restrict-facets 2:
16918
    * "If {variety} is atomic, the {primitive type definition}
16919
    * of R is the same as that of B."
16920
    *
16921
    * NOTE: we leave 1 & 2 out for now, since this will be
16922
    * satisfied by the derivation process.
16923
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
16924
    */
16925
    /*
16926
    * SPEC st-restrict-facets 3:
16927
    * "The {facets} of R are the union of S and the {facets}
16928
    * of B, eliminating duplicates. To eliminate duplicates,
16929
    * when a facet of the same kind occurs in both S and the
16930
    * {facets} of B, the one in the {facets} of B is not
16931
    * included, with the exception of enumeration and pattern
16932
    * facets, for which multiple occurrences with distinct values
16933
    * are allowed."
16934
    */
16935
16936
0
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
16937
0
  return (0);
16938
16939
0
    last = type->facetSet;
16940
0
    if (last != NULL)
16941
0
  while (last->next != NULL)
16942
0
      last = last->next;
16943
16944
0
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
16945
0
  facet = cur->facet;
16946
0
  switch (facet->type) {
16947
0
      case XML_SCHEMA_FACET_LENGTH:
16948
0
    flength = facet; break;
16949
0
      case XML_SCHEMA_FACET_MINLENGTH:
16950
0
    fminlen = facet; break;
16951
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
16952
0
    fmininc = facet; break;
16953
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
16954
0
    fminexc = facet; break;
16955
0
      case XML_SCHEMA_FACET_MAXLENGTH:
16956
0
    fmaxlen = facet; break;
16957
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
16958
0
    fmaxinc = facet; break;
16959
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
16960
0
    fmaxexc = facet; break;
16961
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
16962
0
    ftotdig = facet; break;
16963
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
16964
0
    ffracdig = facet; break;
16965
0
      default:
16966
0
    break;
16967
0
  }
16968
0
    }
16969
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
16970
0
  facet = cur->facet;
16971
0
  switch (facet->type) {
16972
0
      case XML_SCHEMA_FACET_LENGTH:
16973
0
    bflength = facet; break;
16974
0
      case XML_SCHEMA_FACET_MINLENGTH:
16975
0
    bfminlen = facet; break;
16976
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
16977
0
    bfmininc = facet; break;
16978
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
16979
0
    bfminexc = facet; break;
16980
0
      case XML_SCHEMA_FACET_MAXLENGTH:
16981
0
    bfmaxlen = facet; break;
16982
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
16983
0
    bfmaxinc = facet; break;
16984
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
16985
0
    bfmaxexc = facet; break;
16986
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
16987
0
    bftotdig = facet; break;
16988
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
16989
0
    bffracdig = facet; break;
16990
0
      default:
16991
0
    break;
16992
0
  }
16993
0
    }
16994
    /*
16995
    * length and minLength or maxLength (2.2) + (3.2)
16996
    */
16997
0
    if (flength && (fminlen || fmaxlen)) {
16998
0
  FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
16999
0
      "either of 'minLength' or 'maxLength' to be specified on "
17000
0
      "the same type definition")
17001
0
    }
17002
    /*
17003
    * Mutual exclusions in the same derivation step.
17004
    */
17005
0
    if ((fmaxinc) && (fmaxexc)) {
17006
  /*
17007
  * SCC "maxInclusive and maxExclusive"
17008
  */
17009
0
  FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17010
0
    }
17011
0
    if ((fmininc) && (fminexc)) {
17012
  /*
17013
  * SCC "minInclusive and minExclusive"
17014
  */
17015
0
  FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17016
0
    }
17017
17018
0
    if (flength && bflength) {
17019
  /*
17020
  * SCC "length valid restriction"
17021
  * The values have to be equal.
17022
  */
17023
0
  res = xmlSchemaCompareValues(flength->val, bflength->val);
17024
0
  if (res == -2)
17025
0
      goto internal_error;
17026
0
  if (res != 0)
17027
0
      xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17028
0
  if ((res != 0) && (bflength->fixed)) {
17029
0
      FACET_RESTR_FIXED_ERR(flength)
17030
0
  }
17031
17032
0
    }
17033
0
    if (fminlen && bfminlen) {
17034
  /*
17035
  * SCC "minLength valid restriction"
17036
  * minLength >= BASE minLength
17037
  */
17038
0
  res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17039
0
  if (res == -2)
17040
0
      goto internal_error;
17041
0
  if (res == -1)
17042
0
      xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17043
0
  if ((res != 0) && (bfminlen->fixed)) {
17044
0
      FACET_RESTR_FIXED_ERR(fminlen)
17045
0
  }
17046
0
    }
17047
0
    if (fmaxlen && bfmaxlen) {
17048
  /*
17049
  * SCC "maxLength valid restriction"
17050
  * maxLength <= BASE minLength
17051
  */
17052
0
  res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17053
0
  if (res == -2)
17054
0
      goto internal_error;
17055
0
  if (res == 1)
17056
0
      xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17057
0
  if ((res != 0) && (bfmaxlen->fixed)) {
17058
0
      FACET_RESTR_FIXED_ERR(fmaxlen)
17059
0
  }
17060
0
    }
17061
    /*
17062
    * SCC "length and minLength or maxLength"
17063
    */
17064
0
    if (! flength)
17065
0
  flength = bflength;
17066
0
    if (flength) {
17067
0
  if (! fminlen)
17068
0
      fminlen = bfminlen;
17069
0
  if (fminlen) {
17070
      /* (1.1) length >= minLength */
17071
0
      res = xmlSchemaCompareValues(flength->val, fminlen->val);
17072
0
      if (res == -2)
17073
0
    goto internal_error;
17074
0
      if (res == -1)
17075
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17076
0
  }
17077
0
  if (! fmaxlen)
17078
0
      fmaxlen = bfmaxlen;
17079
0
  if (fmaxlen) {
17080
      /* (2.1) length <= maxLength */
17081
0
      res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17082
0
      if (res == -2)
17083
0
    goto internal_error;
17084
0
      if (res == 1)
17085
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17086
0
  }
17087
0
    }
17088
0
    if (fmaxinc) {
17089
  /*
17090
  * "maxInclusive"
17091
  */
17092
0
  if (fmininc) {
17093
      /* SCC "maxInclusive >= minInclusive" */
17094
0
      res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17095
0
      if (res == -2)
17096
0
    goto internal_error;
17097
0
      if (res == -1) {
17098
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17099
0
      }
17100
0
  }
17101
  /*
17102
  * SCC "maxInclusive valid restriction"
17103
  */
17104
0
  if (bfmaxinc) {
17105
      /* maxInclusive <= BASE maxInclusive */
17106
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17107
0
      if (res == -2)
17108
0
    goto internal_error;
17109
0
      if (res == 1)
17110
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17111
0
      if ((res != 0) && (bfmaxinc->fixed)) {
17112
0
    FACET_RESTR_FIXED_ERR(fmaxinc)
17113
0
      }
17114
0
  }
17115
0
  if (bfmaxexc) {
17116
      /* maxInclusive < BASE maxExclusive */
17117
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17118
0
      if (res == -2)
17119
0
    goto internal_error;
17120
0
      if (res != -1) {
17121
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17122
0
      }
17123
0
  }
17124
0
  if (bfmininc) {
17125
      /* maxInclusive >= BASE minInclusive */
17126
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17127
0
      if (res == -2)
17128
0
    goto internal_error;
17129
0
      if (res == -1) {
17130
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17131
0
      }
17132
0
  }
17133
0
  if (bfminexc) {
17134
      /* maxInclusive > BASE minExclusive */
17135
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17136
0
      if (res == -2)
17137
0
    goto internal_error;
17138
0
      if (res != 1) {
17139
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17140
0
      }
17141
0
  }
17142
0
    }
17143
0
    if (fmaxexc) {
17144
  /*
17145
  * "maxExclusive >= minExclusive"
17146
  */
17147
0
  if (fminexc) {
17148
0
      res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17149
0
      if (res == -2)
17150
0
    goto internal_error;
17151
0
      if (res == -1) {
17152
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17153
0
      }
17154
0
  }
17155
  /*
17156
  * "maxExclusive valid restriction"
17157
  */
17158
0
  if (bfmaxexc) {
17159
      /* maxExclusive <= BASE maxExclusive */
17160
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17161
0
      if (res == -2)
17162
0
    goto internal_error;
17163
0
      if (res == 1) {
17164
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17165
0
      }
17166
0
      if ((res != 0) && (bfmaxexc->fixed)) {
17167
0
    FACET_RESTR_FIXED_ERR(fmaxexc)
17168
0
      }
17169
0
  }
17170
0
  if (bfmaxinc) {
17171
      /* maxExclusive <= BASE maxInclusive */
17172
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17173
0
      if (res == -2)
17174
0
    goto internal_error;
17175
0
      if (res == 1) {
17176
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17177
0
      }
17178
0
  }
17179
0
  if (bfmininc) {
17180
      /* maxExclusive > BASE minInclusive */
17181
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17182
0
      if (res == -2)
17183
0
    goto internal_error;
17184
0
      if (res != 1) {
17185
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17186
0
      }
17187
0
  }
17188
0
  if (bfminexc) {
17189
      /* maxExclusive > BASE minExclusive */
17190
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17191
0
      if (res == -2)
17192
0
    goto internal_error;
17193
0
      if (res != 1) {
17194
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17195
0
      }
17196
0
  }
17197
0
    }
17198
0
    if (fminexc) {
17199
  /*
17200
  * "minExclusive < maxInclusive"
17201
  */
17202
0
  if (fmaxinc) {
17203
0
      res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17204
0
      if (res == -2)
17205
0
    goto internal_error;
17206
0
      if (res != -1) {
17207
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17208
0
      }
17209
0
  }
17210
  /*
17211
  * "minExclusive valid restriction"
17212
  */
17213
0
  if (bfminexc) {
17214
      /* minExclusive >= BASE minExclusive */
17215
0
      res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17216
0
      if (res == -2)
17217
0
    goto internal_error;
17218
0
      if (res == -1) {
17219
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17220
0
      }
17221
0
      if ((res != 0) && (bfminexc->fixed)) {
17222
0
    FACET_RESTR_FIXED_ERR(fminexc)
17223
0
      }
17224
0
  }
17225
0
  if (bfmaxinc) {
17226
      /* minExclusive <= BASE maxInclusive */
17227
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17228
0
      if (res == -2)
17229
0
    goto internal_error;
17230
0
      if (res == 1) {
17231
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17232
0
      }
17233
0
  }
17234
0
  if (bfmininc) {
17235
      /* minExclusive >= BASE minInclusive */
17236
0
      res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17237
0
      if (res == -2)
17238
0
    goto internal_error;
17239
0
      if (res == -1) {
17240
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17241
0
      }
17242
0
  }
17243
0
  if (bfmaxexc) {
17244
      /* minExclusive < BASE maxExclusive */
17245
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17246
0
      if (res == -2)
17247
0
    goto internal_error;
17248
0
      if (res != -1) {
17249
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17250
0
      }
17251
0
  }
17252
0
    }
17253
0
    if (fmininc) {
17254
  /*
17255
  * "minInclusive < maxExclusive"
17256
  */
17257
0
  if (fmaxexc) {
17258
0
      res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17259
0
      if (res == -2)
17260
0
    goto internal_error;
17261
0
      if (res != -1) {
17262
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17263
0
      }
17264
0
  }
17265
  /*
17266
  * "minExclusive valid restriction"
17267
  */
17268
0
  if (bfmininc) {
17269
      /* minInclusive >= BASE minInclusive */
17270
0
      res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17271
0
      if (res == -2)
17272
0
    goto internal_error;
17273
0
      if (res == -1) {
17274
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17275
0
      }
17276
0
      if ((res != 0) && (bfmininc->fixed)) {
17277
0
    FACET_RESTR_FIXED_ERR(fmininc)
17278
0
      }
17279
0
  }
17280
0
  if (bfmaxinc) {
17281
      /* minInclusive <= BASE maxInclusive */
17282
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17283
0
      if (res == -2)
17284
0
    goto internal_error;
17285
0
      if (res == 1) {
17286
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17287
0
      }
17288
0
  }
17289
0
  if (bfminexc) {
17290
      /* minInclusive > BASE minExclusive */
17291
0
      res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17292
0
      if (res == -2)
17293
0
    goto internal_error;
17294
0
      if (res != 1)
17295
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17296
0
  }
17297
0
  if (bfmaxexc) {
17298
      /* minInclusive < BASE maxExclusive */
17299
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17300
0
      if (res == -2)
17301
0
    goto internal_error;
17302
0
      if (res != -1)
17303
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17304
0
  }
17305
0
    }
17306
0
    if (ftotdig && bftotdig) {
17307
  /*
17308
  * SCC " totalDigits valid restriction"
17309
  * totalDigits <= BASE totalDigits
17310
  */
17311
0
  res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17312
0
  if (res == -2)
17313
0
      goto internal_error;
17314
0
  if (res == 1)
17315
0
      xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17316
0
      -1, 1, 1);
17317
0
  if ((res != 0) && (bftotdig->fixed)) {
17318
0
      FACET_RESTR_FIXED_ERR(ftotdig)
17319
0
  }
17320
0
    }
17321
0
    if (ffracdig && bffracdig) {
17322
  /*
17323
  * SCC  "fractionDigits valid restriction"
17324
  * fractionDigits <= BASE fractionDigits
17325
  */
17326
0
  res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17327
0
  if (res == -2)
17328
0
      goto internal_error;
17329
0
  if (res == 1)
17330
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17331
0
      -1, 1, 1);
17332
0
  if ((res != 0) && (bffracdig->fixed)) {
17333
0
      FACET_RESTR_FIXED_ERR(ffracdig)
17334
0
  }
17335
0
    }
17336
    /*
17337
    * SCC "fractionDigits less than or equal to totalDigits"
17338
    */
17339
0
    if (! ftotdig)
17340
0
  ftotdig = bftotdig;
17341
0
    if (! ffracdig)
17342
0
  ffracdig = bffracdig;
17343
0
    if (ftotdig && ffracdig) {
17344
0
  res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17345
0
  if (res == -2)
17346
0
      goto internal_error;
17347
0
  if (res == 1)
17348
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17349
0
    -1, 1, 0);
17350
0
    }
17351
    /*
17352
    * *Enumerations* won' be added here, since only the first set
17353
    * of enumerations in the ancestor-or-self axis is used
17354
    * for validation, plus we need to use the base type of those
17355
    * enumerations for whitespace.
17356
    *
17357
    * *Patterns*: won't be add here, since they are ORed at
17358
    * type level and ANDed at ancestor level. This will
17359
    * happen during validation by walking the base axis
17360
    * of the type.
17361
    */
17362
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17363
0
  bfacet = cur->facet;
17364
  /*
17365
  * Special handling of enumerations and patterns.
17366
  * TODO: hmm, they should not appear in the set, so remove this.
17367
  */
17368
0
  if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17369
0
      (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17370
0
      continue;
17371
  /*
17372
  * Search for a duplicate facet in the current type.
17373
  */
17374
0
  link = type->facetSet;
17375
  /* err = 0; */
17376
  /* fixedErr = 0; */
17377
0
  while (link != NULL) {
17378
0
      facet = link->facet;
17379
0
      if (facet->type == bfacet->type) {
17380
0
    switch (facet->type) {
17381
0
        case XML_SCHEMA_FACET_WHITESPACE:
17382
      /*
17383
      * The whitespace must be stronger.
17384
      */
17385
0
      if (facet->whitespace < bfacet->whitespace) {
17386
0
          FACET_RESTR_ERR(facet,
17387
0
        "The 'whitespace' value has to be equal to "
17388
0
        "or stronger than the 'whitespace' value of "
17389
0
        "the base type")
17390
0
      }
17391
0
      if ((bfacet->fixed) &&
17392
0
          (facet->whitespace != bfacet->whitespace)) {
17393
0
          FACET_RESTR_FIXED_ERR(facet)
17394
0
      }
17395
0
      break;
17396
0
        default:
17397
0
      break;
17398
0
    }
17399
    /* Duplicate found. */
17400
0
    break;
17401
0
      }
17402
0
      link = link->next;
17403
0
  }
17404
  /*
17405
  * If no duplicate was found: add the base types's facet
17406
  * to the set.
17407
  */
17408
0
  if (link == NULL) {
17409
0
      link = (xmlSchemaFacetLinkPtr)
17410
0
    xmlMalloc(sizeof(xmlSchemaFacetLink));
17411
0
      if (link == NULL) {
17412
0
    xmlSchemaPErrMemory(pctxt);
17413
0
    return (-1);
17414
0
      }
17415
0
      link->facet = cur->facet;
17416
0
      link->next = NULL;
17417
0
      if (last == NULL)
17418
0
    type->facetSet = link;
17419
0
      else
17420
0
    last->next = link;
17421
0
      last = link;
17422
0
  }
17423
17424
0
    }
17425
17426
0
    return (0);
17427
0
internal_error:
17428
0
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17429
0
  "an error occurred");
17430
0
    return (-1);
17431
0
}
17432
17433
static int
17434
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17435
               xmlSchemaTypePtr type)
17436
0
{
17437
0
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17438
    /*
17439
    * The actual value is then formed by replacing any union type
17440
    * definition in the `explicit members` with the members of their
17441
    * {member type definitions}, in order.
17442
    *
17443
    * TODO: There's a bug entry at
17444
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17445
    * which indicates that we'll keep the union types the future.
17446
    */
17447
0
    link = type->memberTypes;
17448
0
    while (link != NULL) {
17449
17450
0
  if (WXS_IS_TYPE_NOT_FIXED(link->type))
17451
0
      xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17452
17453
0
  if (WXS_IS_UNION(link->type)) {
17454
0
      subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17455
0
      if (subLink != NULL) {
17456
0
    link->type = subLink->type;
17457
0
    if (subLink->next != NULL) {
17458
0
        lastLink = link->next;
17459
0
        subLink = subLink->next;
17460
0
        prevLink = link;
17461
0
        while (subLink != NULL) {
17462
0
      newLink = (xmlSchemaTypeLinkPtr)
17463
0
          xmlMalloc(sizeof(xmlSchemaTypeLink));
17464
0
      if (newLink == NULL) {
17465
0
          xmlSchemaPErrMemory(pctxt);
17466
0
          return (-1);
17467
0
      }
17468
0
      newLink->type = subLink->type;
17469
0
      prevLink->next = newLink;
17470
0
      prevLink = newLink;
17471
0
      newLink->next = lastLink;
17472
17473
0
      subLink = subLink->next;
17474
0
        }
17475
0
    }
17476
0
      }
17477
0
  }
17478
0
  link = link->next;
17479
0
    }
17480
0
    return (0);
17481
0
}
17482
17483
static void
17484
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17485
0
{
17486
0
    int has = 0, needVal = 0, normVal = 0;
17487
17488
0
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17489
0
    if (has) {
17490
0
  needVal = (type->baseType->flags &
17491
0
      XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17492
0
  normVal = (type->baseType->flags &
17493
0
      XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17494
0
    }
17495
0
    if (type->facets != NULL) {
17496
0
  xmlSchemaFacetPtr fac;
17497
17498
0
  for (fac = type->facets; fac != NULL; fac = fac->next) {
17499
0
      switch (fac->type) {
17500
0
    case XML_SCHEMA_FACET_WHITESPACE:
17501
0
        break;
17502
0
    case XML_SCHEMA_FACET_PATTERN:
17503
0
        normVal = 1;
17504
0
        has = 1;
17505
0
        break;
17506
0
    case XML_SCHEMA_FACET_ENUMERATION:
17507
0
        needVal = 1;
17508
0
        normVal = 1;
17509
0
        has = 1;
17510
0
        break;
17511
0
    default:
17512
0
        has = 1;
17513
0
        break;
17514
0
      }
17515
0
  }
17516
0
    }
17517
0
    if (normVal)
17518
0
  type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17519
0
    if (needVal)
17520
0
  type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17521
0
    if (has)
17522
0
  type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17523
17524
0
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17525
0
  xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17526
  /*
17527
  * OPTIMIZE VAL TODO: Some facets need a computed value.
17528
  */
17529
0
  if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17530
0
      (prim->builtInType != XML_SCHEMAS_STRING)) {
17531
0
      type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17532
0
  }
17533
0
    }
17534
0
}
17535
17536
static int
17537
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17538
0
{
17539
17540
17541
    /*
17542
    * Evaluate the whitespace-facet value.
17543
    */
17544
0
    if (WXS_IS_LIST(type)) {
17545
0
  type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17546
0
  return (0);
17547
0
    } else if (WXS_IS_UNION(type))
17548
0
  return (0);
17549
17550
0
    if (type->facetSet != NULL) {
17551
0
  xmlSchemaFacetLinkPtr lin;
17552
17553
0
  for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17554
0
      if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17555
0
    switch (lin->facet->whitespace) {
17556
0
    case XML_SCHEMAS_FACET_PRESERVE:
17557
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17558
0
        break;
17559
0
    case XML_SCHEMAS_FACET_REPLACE:
17560
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17561
0
        break;
17562
0
    case XML_SCHEMAS_FACET_COLLAPSE:
17563
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17564
0
        break;
17565
0
    default:
17566
0
        return (-1);
17567
0
    }
17568
0
    return (0);
17569
0
      }
17570
0
  }
17571
0
    }
17572
    /*
17573
    * For all `atomic` datatypes other than string (and types `derived`
17574
    * by `restriction` from it) the value of whiteSpace is fixed to
17575
    * collapse
17576
    */
17577
0
    {
17578
0
  xmlSchemaTypePtr anc;
17579
17580
0
  for (anc = type->baseType; anc != NULL &&
17581
0
    anc->builtInType != XML_SCHEMAS_ANYTYPE;
17582
0
    anc = anc->baseType) {
17583
17584
0
      if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17585
0
    if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17586
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17587
17588
0
    } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17589
0
        (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17590
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17591
17592
0
    } else
17593
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17594
0
    break;
17595
0
      }
17596
0
  }
17597
0
    }
17598
0
    return (0);
17599
0
}
17600
17601
static int
17602
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17603
        xmlSchemaTypePtr type)
17604
0
{
17605
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17606
0
  return(0);
17607
0
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17608
0
  return(0);
17609
0
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17610
17611
0
    if (WXS_IS_LIST(type)) {
17612
  /*
17613
  * Corresponds to <simpleType><list>...
17614
  */
17615
0
  if (type->subtypes == NULL) {
17616
      /*
17617
      * This one is really needed, so get out.
17618
      */
17619
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17620
0
    "list type has no item-type assigned");
17621
0
      return(-1);
17622
0
  }
17623
0
    } else if (WXS_IS_UNION(type)) {
17624
  /*
17625
  * Corresponds to <simpleType><union>...
17626
  */
17627
0
  if (type->memberTypes == NULL) {
17628
      /*
17629
      * This one is really needed, so get out.
17630
      */
17631
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17632
0
    "union type has no member-types assigned");
17633
0
      return(-1);
17634
0
  }
17635
0
    } else {
17636
  /*
17637
  * Corresponds to <simpleType><restriction>...
17638
  */
17639
0
  if (type->baseType == NULL) {
17640
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17641
0
    "type has no base-type assigned");
17642
0
      return(-1);
17643
0
  }
17644
0
  if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17645
0
      if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17646
0
    return(-1);
17647
  /*
17648
  * Variety
17649
  * If the <restriction> alternative is chosen, then the
17650
  * {variety} of the {base type definition}.
17651
  */
17652
0
  if (WXS_IS_ATOMIC(type->baseType))
17653
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17654
0
  else if (WXS_IS_LIST(type->baseType)) {
17655
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17656
      /*
17657
      * Inherit the itemType.
17658
      */
17659
0
      type->subtypes = type->baseType->subtypes;
17660
0
  } else if (WXS_IS_UNION(type->baseType)) {
17661
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17662
      /*
17663
      * NOTE that we won't assign the memberTypes of the base,
17664
      * since this will make trouble when freeing them; we will
17665
      * use a lookup function to access them instead.
17666
      */
17667
0
  }
17668
0
    }
17669
0
    return(0);
17670
0
}
17671
17672
/*
17673
* 3.14.6 Constraints on Simple Type Definition Schema Components
17674
*/
17675
static int
17676
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
17677
         xmlSchemaTypePtr type)
17678
0
{
17679
0
    int res, olderrs = pctxt->nberrors;
17680
17681
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17682
0
  return(-1);
17683
17684
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
17685
0
  return(0);
17686
17687
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
17688
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
17689
17690
0
    if (type->baseType == NULL) {
17691
0
  PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
17692
0
      "missing baseType");
17693
0
  goto exit_failure;
17694
0
    }
17695
0
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
17696
0
  xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
17697
    /*
17698
    * If a member type of a union is a union itself, we need to substitute
17699
    * that member type for its member types.
17700
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
17701
    * types in WXS 1.1.
17702
    */
17703
0
    if ((type->memberTypes != NULL) &&
17704
0
  (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
17705
0
  return(-1);
17706
    /*
17707
    * SPEC src-simple-type 1
17708
    * "The corresponding simple type definition, if any, must satisfy
17709
    * the conditions set out in Constraints on Simple Type Definition
17710
    * Schema Components ($3.14.6)."
17711
    */
17712
    /*
17713
    * Schema Component Constraint: Simple Type Definition Properties Correct
17714
    * (st-props-correct)
17715
    */
17716
0
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
17717
0
    HFAILURE HERROR
17718
    /*
17719
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
17720
    * (cos-st-restricts)
17721
    */
17722
0
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
17723
0
    HFAILURE HERROR
17724
    /*
17725
    * TODO: Removed the error report, since it got annoying to get an
17726
    * extra error report, if anything failed until now.
17727
    * Enable this if needed.
17728
    *
17729
    * xmlSchemaPErr(ctxt, type->node,
17730
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
17731
    *    "Simple type '%s' does not satisfy the constraints "
17732
    *    "on simple type definitions.\n",
17733
    *    type->name, NULL);
17734
    */
17735
    /*
17736
    * Schema Component Constraint: Simple Type Restriction (Facets)
17737
    * (st-restrict-facets)
17738
    */
17739
0
    res = xmlSchemaCheckFacetValues(type, pctxt);
17740
0
    HFAILURE HERROR
17741
0
    if ((type->facetSet != NULL) ||
17742
0
  (type->baseType->facetSet != NULL)) {
17743
0
  res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
17744
0
  HFAILURE HERROR
17745
0
    }
17746
    /*
17747
    * Whitespace value.
17748
    */
17749
0
    res = xmlSchemaTypeFixupWhitespace(type);
17750
0
    HFAILURE HERROR
17751
0
    xmlSchemaTypeFixupOptimFacets(type);
17752
17753
0
exit_error:
17754
0
    if (olderrs != pctxt->nberrors)
17755
0
  return(pctxt->err);
17756
0
    return(0);
17757
17758
0
exit_failure:
17759
0
    return(-1);
17760
0
}
17761
17762
static int
17763
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
17764
        xmlSchemaTypePtr type)
17765
0
{
17766
0
    int res = 0, olderrs = pctxt->nberrors;
17767
0
    xmlSchemaTypePtr baseType = type->baseType;
17768
17769
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
17770
0
  return(0);
17771
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
17772
0
    if (baseType == NULL) {
17773
0
  PERROR_INT("xmlSchemaFixupComplexType",
17774
0
      "missing baseType");
17775
0
  goto exit_failure;
17776
0
    }
17777
    /*
17778
    * Fixup the base type.
17779
    */
17780
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
17781
0
  xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
17782
0
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
17783
  /*
17784
  * Skip fixup if the base type is invalid.
17785
  * TODO: Generate a warning!
17786
  */
17787
0
  return(0);
17788
0
    }
17789
    /*
17790
    * This basically checks if the base type can be derived.
17791
    */
17792
0
    res = xmlSchemaCheckSRCCT(pctxt, type);
17793
0
    HFAILURE HERROR
17794
    /*
17795
    * Fixup the content type.
17796
    */
17797
0
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
17798
  /*
17799
  * Corresponds to <complexType><simpleContent>...
17800
  */
17801
0
  if ((WXS_IS_COMPLEX(baseType)) &&
17802
0
      (baseType->contentTypeDef != NULL) &&
17803
0
      (WXS_IS_RESTRICTION(type))) {
17804
0
      xmlSchemaTypePtr contentBase, content;
17805
#ifdef ENABLE_NAMED_LOCALS
17806
      char buf[30];
17807
      const xmlChar *tmpname;
17808
#endif
17809
      /*
17810
      * SPEC (1) If <restriction> + base type is <complexType>,
17811
      * "whose own {content type} is a simple type..."
17812
      */
17813
0
      if (type->contentTypeDef != NULL) {
17814
    /*
17815
    * SPEC (1.1) "the simple type definition corresponding to the
17816
    * <simpleType> among the [children] of <restriction> if there
17817
    * is one;"
17818
    * Note that this "<simpleType> among the [children]" was put
17819
    * into ->contentTypeDef during parsing.
17820
    */
17821
0
    contentBase = type->contentTypeDef;
17822
0
    type->contentTypeDef = NULL;
17823
0
      } else {
17824
    /*
17825
    * (1.2) "...otherwise (<restriction> has no <simpleType>
17826
    * among its [children]), the simple type definition which
17827
    * is the {content type} of the ... base type."
17828
    */
17829
0
    contentBase = baseType->contentTypeDef;
17830
0
      }
17831
      /*
17832
      * SPEC
17833
      * "... a simple type definition which restricts the simple
17834
      * type definition identified in clause 1.1 or clause 1.2
17835
      * with a set of facet components"
17836
      *
17837
      * Create the anonymous simple type, which will be the content
17838
      * type of the complex type.
17839
      */
17840
#ifdef ENABLE_NAMED_LOCALS
17841
      snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
17842
      tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
17843
      content = xmlSchemaAddType(pctxt, pctxt->schema,
17844
    XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
17845
    type->node, 0);
17846
#else
17847
0
      content = xmlSchemaAddType(pctxt, pctxt->schema,
17848
0
    XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
17849
0
    type->node, 0);
17850
0
#endif
17851
0
      if (content == NULL)
17852
0
    goto exit_failure;
17853
      /*
17854
      * We will use the same node as for the <complexType>
17855
      * to have it somehow anchored in the schema doc.
17856
      */
17857
0
      content->type = XML_SCHEMA_TYPE_SIMPLE;
17858
0
      content->baseType = contentBase;
17859
      /*
17860
      * Move the facets, previously anchored on the
17861
      * complexType during parsing.
17862
      */
17863
0
      content->facets = type->facets;
17864
0
      type->facets = NULL;
17865
0
      content->facetSet = type->facetSet;
17866
0
      type->facetSet = NULL;
17867
17868
0
      type->contentTypeDef = content;
17869
0
      if (WXS_IS_TYPE_NOT_FIXED(contentBase))
17870
0
    xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
17871
      /*
17872
      * Fixup the newly created type. We don't need to check
17873
      * for circularity here.
17874
      */
17875
0
      res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
17876
0
      HFAILURE HERROR
17877
0
      res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
17878
0
      HFAILURE HERROR
17879
17880
0
  } else if ((WXS_IS_COMPLEX(baseType)) &&
17881
0
      (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
17882
0
      (WXS_IS_RESTRICTION(type))) {
17883
      /*
17884
      * SPEC (2) If <restriction> + base is a mixed <complexType> with
17885
      * an emptiable particle, then a simple type definition which
17886
      * restricts the <restriction>'s <simpleType> child.
17887
      */
17888
0
      if ((type->contentTypeDef == NULL) ||
17889
0
    (type->contentTypeDef->baseType == NULL)) {
17890
    /*
17891
    * TODO: Check if this ever happens.
17892
    */
17893
0
    xmlSchemaPCustomErr(pctxt,
17894
0
        XML_SCHEMAP_INTERNAL,
17895
0
        WXS_BASIC_CAST type, NULL,
17896
0
        "Internal error: xmlSchemaTypeFixup, "
17897
0
        "complex type '%s': the <simpleContent><restriction> "
17898
0
        "is missing a <simpleType> child, but was not caught "
17899
0
        "by xmlSchemaCheckSRCCT()", type->name);
17900
0
    goto exit_failure;
17901
0
      }
17902
0
  } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
17903
      /*
17904
      * SPEC (3) If <extension> + base is <complexType> with
17905
      * <simpleType> content, "...then the {content type} of that
17906
      * complex type definition"
17907
      */
17908
0
      if (baseType->contentTypeDef == NULL) {
17909
    /*
17910
    * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
17911
    * should have caught this already.
17912
    */
17913
0
    xmlSchemaPCustomErr(pctxt,
17914
0
        XML_SCHEMAP_INTERNAL,
17915
0
        WXS_BASIC_CAST type, NULL,
17916
0
        "Internal error: xmlSchemaTypeFixup, "
17917
0
        "complex type '%s': the <extension>ed base type is "
17918
0
        "a complex type with no simple content type",
17919
0
        type->name);
17920
0
    goto exit_failure;
17921
0
      }
17922
0
      type->contentTypeDef = baseType->contentTypeDef;
17923
0
  } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
17924
      /*
17925
      * SPEC (4) <extension> + base is <simpleType>
17926
      * "... then that simple type definition"
17927
      */
17928
0
      type->contentTypeDef = baseType;
17929
0
  } else {
17930
      /*
17931
      * TODO: Check if this ever happens.
17932
      */
17933
0
      xmlSchemaPCustomErr(pctxt,
17934
0
    XML_SCHEMAP_INTERNAL,
17935
0
    WXS_BASIC_CAST type, NULL,
17936
0
    "Internal error: xmlSchemaTypeFixup, "
17937
0
    "complex type '%s' with <simpleContent>: unhandled "
17938
0
    "derivation case", type->name);
17939
0
      goto exit_failure;
17940
0
  }
17941
0
    } else {
17942
0
  int dummySequence = 0;
17943
0
  xmlSchemaParticlePtr particle =
17944
0
      (xmlSchemaParticlePtr) type->subtypes;
17945
  /*
17946
  * Corresponds to <complexType><complexContent>...
17947
  *
17948
  * NOTE that the effective mixed was already set during parsing of
17949
  * <complexType> and <complexContent>; its flag value is
17950
  * XML_SCHEMAS_TYPE_MIXED.
17951
  *
17952
  * Compute the "effective content":
17953
  * (2.1.1) + (2.1.2) + (2.1.3)
17954
  */
17955
0
  if ((particle == NULL) ||
17956
0
      ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
17957
0
      ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
17958
0
      (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
17959
0
      ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
17960
0
      (particle->minOccurs == 0))) &&
17961
0
      ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
17962
0
      if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
17963
    /*
17964
    * SPEC (2.1.4) "If the `effective mixed` is true, then
17965
    * a particle whose properties are as follows:..."
17966
    *
17967
    * Empty sequence model group with
17968
    * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
17969
    * NOTE that we sill assign it the <complexType> node to
17970
    * somehow anchor it in the doc.
17971
    */
17972
0
    if ((particle == NULL) ||
17973
0
        (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
17974
        /*
17975
        * Create the particle.
17976
        */
17977
0
        particle = xmlSchemaAddParticle(pctxt,
17978
0
      type->node, 1, 1);
17979
0
        if (particle == NULL)
17980
0
      goto exit_failure;
17981
        /*
17982
        * Create the model group.
17983
        */ /* URGENT TODO: avoid adding to pending items. */
17984
0
        particle->children = (xmlSchemaTreeItemPtr)
17985
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
17986
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
17987
0
        if (particle->children == NULL)
17988
0
      goto exit_failure;
17989
17990
0
        type->subtypes = (xmlSchemaTypePtr) particle;
17991
0
    }
17992
0
    dummySequence = 1;
17993
0
    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
17994
0
      } else {
17995
    /*
17996
    * SPEC (2.1.5) "otherwise empty"
17997
    */
17998
0
    type->contentType = XML_SCHEMA_CONTENT_EMPTY;
17999
0
      }
18000
0
  } else {
18001
      /*
18002
      * SPEC (2.2) "otherwise the particle corresponding to the
18003
      * <all>, <choice>, <group> or <sequence> among the
18004
      * [children]."
18005
      */
18006
0
      type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18007
0
  }
18008
  /*
18009
  * Compute the "content type".
18010
  */
18011
0
  if (WXS_IS_RESTRICTION(type)) {
18012
      /*
18013
      * SPEC (3.1) "If <restriction>..."
18014
      * (3.1.1) + (3.1.2) */
18015
0
      if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18016
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18017
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18018
0
      }
18019
0
  } else {
18020
      /*
18021
      * SPEC (3.2) "If <extension>..."
18022
      */
18023
0
      if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18024
    /*
18025
    * SPEC (3.2.1)
18026
    * "If the `effective content` is empty, then the
18027
    *  {content type} of the [...] base ..."
18028
    */
18029
0
    type->contentType = baseType->contentType;
18030
0
    type->subtypes = baseType->subtypes;
18031
    /*
18032
    * Fixes bug #347316:
18033
    * This is the case when the base type has a simple
18034
    * type definition as content.
18035
    */
18036
0
    type->contentTypeDef = baseType->contentTypeDef;
18037
    /*
18038
    * NOTE that the effective mixed is ignored here.
18039
    */
18040
0
      } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18041
    /*
18042
    * SPEC (3.2.2)
18043
    */
18044
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18045
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18046
0
      } else {
18047
    /*
18048
    * SPEC (3.2.3)
18049
    */
18050
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18051
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18052
        /*
18053
        * "A model group whose {compositor} is sequence and whose
18054
        * {particles} are..."
18055
        */
18056
0
    if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18057
0
        (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18058
0
        ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18059
0
      XML_SCHEMA_TYPE_ALL))
18060
0
    {
18061
        /*
18062
        * SPEC cos-all-limited (1)
18063
        */
18064
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18065
      /* TODO: error code */
18066
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18067
0
      WXS_ITEM_NODE(type), NULL,
18068
0
      "The type has an 'all' model group in its "
18069
0
      "{content type} and thus cannot be derived from "
18070
0
      "a non-empty type, since this would produce a "
18071
0
      "'sequence' model group containing the 'all' "
18072
0
      "model group; 'all' model groups are not "
18073
0
      "allowed to appear inside other model groups",
18074
0
      NULL, NULL);
18075
18076
0
    } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18077
0
        (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18078
0
        ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18079
0
      XML_SCHEMA_TYPE_ALL))
18080
0
    {
18081
        /*
18082
        * SPEC cos-all-limited (1)
18083
        */
18084
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18085
      /* TODO: error code */
18086
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18087
0
      WXS_ITEM_NODE(type), NULL,
18088
0
      "A type cannot be derived by extension from a type "
18089
0
      "which has an 'all' model group in its "
18090
0
      "{content type}, since this would produce a "
18091
0
      "'sequence' model group containing the 'all' "
18092
0
      "model group; 'all' model groups are not "
18093
0
      "allowed to appear inside other model groups",
18094
0
      NULL, NULL);
18095
18096
0
    } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
18097
0
        xmlSchemaTreeItemPtr effectiveContent =
18098
0
      (xmlSchemaTreeItemPtr) type->subtypes;
18099
        /*
18100
        * Create the particle.
18101
        */
18102
0
        particle = xmlSchemaAddParticle(pctxt,
18103
0
      type->node, 1, 1);
18104
0
        if (particle == NULL)
18105
0
      goto exit_failure;
18106
        /*
18107
        * Create the "sequence" model group.
18108
        */
18109
0
        particle->children = (xmlSchemaTreeItemPtr)
18110
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18111
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18112
0
        if (particle->children == NULL)
18113
0
      goto exit_failure;
18114
0
        WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18115
        /*
18116
        * SPEC "the particle of the {content type} of
18117
        * the ... base ..."
18118
        * Create a duplicate of the base type's particle
18119
        * and assign its "term" to it.
18120
        */
18121
0
        particle->children->children =
18122
0
      (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18123
0
      type->node,
18124
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18125
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18126
0
        if (particle->children->children == NULL)
18127
0
      goto exit_failure;
18128
0
        particle = (xmlSchemaParticlePtr)
18129
0
      particle->children->children;
18130
0
        particle->children =
18131
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18132
        /*
18133
        * SPEC "followed by the `effective content`."
18134
        */
18135
0
        particle->next = effectiveContent;
18136
        /*
18137
        * This all will result in:
18138
        * new-particle
18139
        *   --> new-sequence(
18140
        *         new-particle
18141
        *           --> base-model,
18142
        *         this-particle
18143
        *         --> this-model
18144
        *     )
18145
        */
18146
0
    } else {
18147
        /*
18148
        * This is the case when there is already an empty
18149
        * <sequence> with minOccurs==maxOccurs==1.
18150
        * Just add the base types's content type.
18151
        * NOTE that, although we miss to add an intermediate
18152
        * <sequence>, this should produce no difference to
18153
        * neither the regex compilation of the content model,
18154
        * nor to the complex type constraints.
18155
        */
18156
0
        particle->children->children =
18157
0
      (xmlSchemaTreeItemPtr) baseType->subtypes;
18158
0
    }
18159
0
      }
18160
0
  }
18161
0
    }
18162
    /*
18163
    * Now fixup attribute uses:
18164
    *   - expand attr. group references
18165
    *     - intersect attribute wildcards
18166
    *   - inherit attribute uses of the base type
18167
    *   - inherit or union attr. wildcards if extending
18168
    *   - apply attr. use prohibitions if restricting
18169
    */
18170
0
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18171
0
    HFAILURE HERROR
18172
    /*
18173
    * Apply the complex type component constraints; this will not
18174
    * check attributes, since this is done in
18175
    * xmlSchemaFixupTypeAttributeUses().
18176
    */
18177
0
    res = xmlSchemaCheckCTComponent(pctxt, type);
18178
0
    HFAILURE HERROR
18179
18180
0
    if (olderrs != pctxt->nberrors)
18181
0
  return(pctxt->err);
18182
0
    else
18183
0
  return(0);
18184
18185
0
exit_error:
18186
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18187
0
    return(pctxt->err);
18188
18189
0
exit_failure:
18190
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18191
0
    return(-1);
18192
0
}
18193
18194
18195
/**
18196
 * Fixes the content model of the type.
18197
 * URGENT TODO: We need an int result!
18198
 *
18199
 * @param type  the schema type definition
18200
 * @param actxt  the schema parser context
18201
 */
18202
static int
18203
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18204
                   xmlSchemaAbstractCtxtPtr actxt)
18205
0
{
18206
0
    if (type == NULL)
18207
0
        return(0);
18208
0
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18209
0
  AERROR_INT("xmlSchemaTypeFixup",
18210
0
      "this function needs a parser context");
18211
0
  return(-1);
18212
0
    }
18213
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18214
0
  return(0);
18215
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18216
0
  return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18217
0
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18218
0
  return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18219
0
    return(0);
18220
0
}
18221
18222
/**
18223
 * Checks and computes the values of facets.
18224
 *
18225
 * @param facet  the facet
18226
 * @param typeDecl  the schema type definition
18227
 * @param pctxt  the schema parser context or NULL
18228
 * @param name  the optional name of the type
18229
 * @returns 0 if valid, a positive error code if not valid and
18230
 *         -1 in case of an internal or API error.
18231
 */
18232
int
18233
xmlSchemaCheckFacet(xmlSchemaFacet *facet,
18234
                    xmlSchemaType *typeDecl,
18235
                    xmlSchemaParserCtxt *pctxt,
18236
        const xmlChar * name ATTRIBUTE_UNUSED)
18237
0
{
18238
0
    int ret = 0, ctxtGiven;
18239
18240
0
    if ((facet == NULL) || (typeDecl == NULL))
18241
0
        return(-1);
18242
    /*
18243
    * TODO: will the parser context be given if used from
18244
    * the relaxNG module?
18245
    */
18246
0
    if (pctxt == NULL)
18247
0
  ctxtGiven = 0;
18248
0
    else
18249
0
  ctxtGiven = 1;
18250
18251
0
    switch (facet->type) {
18252
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
18253
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
18254
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
18255
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18256
0
  case XML_SCHEMA_FACET_ENUMERATION: {
18257
                /*
18258
                 * Okay we need to validate the value
18259
                 * at that point.
18260
                 */
18261
0
    xmlSchemaTypePtr base;
18262
18263
    /* 4.3.5.5 Constraints on enumeration Schema Components
18264
    * Schema Component Constraint: enumeration valid restriction
18265
    * It is an `error` if any member of {value} is not in the
18266
    * `value space` of {base type definition}.
18267
    *
18268
    * minInclusive, maxInclusive, minExclusive, maxExclusive:
18269
    * The value `must` be in the
18270
    * `value space` of the `base type`.
18271
    */
18272
    /*
18273
    * This function is intended to deliver a compiled value
18274
    * on the facet. In this implementation of XML Schemata the
18275
    * type holding a facet, won't be a built-in type.
18276
    * Thus to ensure that other API
18277
    * calls (relaxng) do work, if the given type is a built-in
18278
    * type, we will assume that the given built-in type *is
18279
    * already* the base type.
18280
    */
18281
0
    if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18282
0
        base = typeDecl->baseType;
18283
0
        if (base == NULL) {
18284
0
      PERROR_INT("xmlSchemaCheckFacet",
18285
0
          "a type user derived type has no base type");
18286
0
      return (-1);
18287
0
        }
18288
0
    } else
18289
0
        base = typeDecl;
18290
18291
0
    if (! ctxtGiven) {
18292
        /*
18293
        * A context is needed if called from RelaxNG.
18294
        */
18295
0
        pctxt = xmlSchemaNewParserCtxt("*");
18296
0
        if (pctxt == NULL)
18297
0
      return (-1);
18298
0
    }
18299
    /*
18300
    * NOTE: This call does not check the content nodes,
18301
    * since they are not available:
18302
    * facet->node is just the node holding the facet
18303
    * definition, *not* the attribute holding the *value*
18304
    * of the facet.
18305
    */
18306
0
    ret = xmlSchemaVCheckCVCSimpleType(
18307
0
        ACTXT_CAST pctxt, facet->node, base,
18308
0
        facet->value, &(facet->val), 1, 1, 0);
18309
0
                if (ret != 0) {
18310
0
        if (ret < 0) {
18311
      /* No error message for RelaxNG. */
18312
0
      if (ctxtGiven) {
18313
0
          xmlSchemaCustomErr(ACTXT_CAST pctxt,
18314
0
        XML_SCHEMAP_INTERNAL, facet->node, NULL,
18315
0
        "Internal error: xmlSchemaCheckFacet, "
18316
0
        "failed to validate the value '%s' of the "
18317
0
        "facet '%s' against the base type",
18318
0
        facet->value, xmlSchemaFacetTypeToString(facet->type));
18319
0
      }
18320
0
      goto internal_error;
18321
0
        }
18322
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18323
        /* No error message for RelaxNG. */
18324
0
        if (ctxtGiven) {
18325
0
      xmlChar *str = NULL;
18326
18327
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18328
0
          ret, facet->node, WXS_BASIC_CAST facet,
18329
0
          "The value '%s' of the facet does not validate "
18330
0
          "against the base type '%s'",
18331
0
          facet->value,
18332
0
          xmlSchemaFormatQName(&str,
18333
0
        base->targetNamespace, base->name));
18334
0
      FREE_AND_NULL(str);
18335
0
        }
18336
0
        goto exit;
18337
0
                } else if (facet->val == NULL) {
18338
0
        if (ctxtGiven) {
18339
0
      PERROR_INT("xmlSchemaCheckFacet",
18340
0
          "value was not computed");
18341
0
        }
18342
        /* TODO */
18343
0
    }
18344
0
                break;
18345
0
            }
18346
0
        case XML_SCHEMA_FACET_PATTERN:
18347
0
            facet->regexp = xmlRegexpCompile(facet->value);
18348
0
            if (facet->regexp == NULL) {
18349
0
    ret = XML_SCHEMAP_REGEXP_INVALID;
18350
    /* No error message for RelaxNG. */
18351
0
    if (ctxtGiven) {
18352
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18353
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18354
0
      "The value '%s' of the facet 'pattern' is not a "
18355
0
      "valid regular expression",
18356
0
      facet->value, NULL);
18357
0
    }
18358
0
            }
18359
0
            break;
18360
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
18361
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
18362
0
        case XML_SCHEMA_FACET_LENGTH:
18363
0
        case XML_SCHEMA_FACET_MAXLENGTH:
18364
0
        case XML_SCHEMA_FACET_MINLENGTH:
18365
18366
0
      if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18367
0
    ret = xmlSchemaValidatePredefinedType(
18368
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18369
0
        facet->value, &(facet->val));
18370
0
      } else {
18371
0
    ret = xmlSchemaValidatePredefinedType(
18372
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18373
0
        facet->value, &(facet->val));
18374
0
      }
18375
0
      if (ret != 0) {
18376
0
    if (ret < 0) {
18377
        /* No error message for RelaxNG. */
18378
0
        if (ctxtGiven) {
18379
0
      PERROR_INT("xmlSchemaCheckFacet",
18380
0
          "validating facet value");
18381
0
        }
18382
0
        goto internal_error;
18383
0
    }
18384
0
    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18385
    /* No error message for RelaxNG. */
18386
0
    if (ctxtGiven) {
18387
        /* error code */
18388
0
        xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18389
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18390
0
      "The value '%s' of the facet '%s' is not a valid '%s'",
18391
0
      facet->value,
18392
0
      xmlSchemaFacetTypeToString(facet->type),
18393
0
      (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18394
0
          BAD_CAST "nonNegativeInteger" :
18395
0
          BAD_CAST "positiveInteger",
18396
0
      NULL);
18397
0
    }
18398
0
      }
18399
0
      break;
18400
18401
0
        case XML_SCHEMA_FACET_WHITESPACE:{
18402
0
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18403
0
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18404
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18405
0
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18406
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18407
0
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18408
0
                } else {
18409
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18410
                    /* No error message for RelaxNG. */
18411
0
        if (ctxtGiven) {
18412
      /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18413
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18414
0
          ret, facet->node, WXS_BASIC_CAST typeDecl,
18415
0
          "The value '%s' of the facet 'whitespace' is not "
18416
0
          "valid", facet->value, NULL);
18417
0
                    }
18418
0
                }
18419
0
            }
18420
0
        default:
18421
0
            break;
18422
0
    }
18423
0
exit:
18424
0
    if ((! ctxtGiven) && (pctxt != NULL))
18425
0
  xmlSchemaFreeParserCtxt(pctxt);
18426
0
    return (ret);
18427
0
internal_error:
18428
0
    if ((! ctxtGiven) && (pctxt != NULL))
18429
0
  xmlSchemaFreeParserCtxt(pctxt);
18430
0
    return (-1);
18431
0
}
18432
18433
/**
18434
 * Checks the default values types, especially for facets
18435
 *
18436
 * @param typeDecl  the schema type definition
18437
 * @param pctxt  the schema parser context
18438
 */
18439
static int
18440
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18441
        xmlSchemaParserCtxtPtr pctxt)
18442
0
{
18443
0
    int res, olderrs = pctxt->nberrors;
18444
0
    const xmlChar *name = typeDecl->name;
18445
    /*
18446
    * NOTE: It is intended to use the facets list, instead
18447
    * of facetSet.
18448
    */
18449
0
    if (typeDecl->facets != NULL) {
18450
0
  xmlSchemaFacetPtr facet = typeDecl->facets;
18451
18452
  /*
18453
  * Temporarily assign the "schema" to the validation context
18454
  * of the parser context. This is needed for NOTATION validation.
18455
  */
18456
0
  if (pctxt->vctxt == NULL) {
18457
0
      if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18458
0
    return(-1);
18459
0
  }
18460
0
  pctxt->vctxt->schema = pctxt->schema;
18461
0
  while (facet != NULL) {
18462
0
      res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18463
0
      HFAILURE
18464
0
      facet = facet->next;
18465
0
  }
18466
0
  pctxt->vctxt->schema = NULL;
18467
0
    }
18468
0
    if (olderrs != pctxt->nberrors)
18469
0
  return(pctxt->err);
18470
0
    return(0);
18471
0
exit_failure:
18472
0
    return(-1);
18473
0
}
18474
18475
/**
18476
 * This one is intended to be used by
18477
 * xmlSchemaCheckGroupDefCircular only.
18478
 *
18479
 * @param groupDef  the searched model group
18480
 * @param particle  the first particle
18481
 * @returns the particle with the circular model group definition reference,
18482
 * otherwise NULL.
18483
 */
18484
static xmlSchemaTreeItemPtr
18485
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18486
            xmlSchemaTreeItemPtr particle)
18487
0
{
18488
0
    xmlSchemaTreeItemPtr circ = NULL;
18489
0
    xmlSchemaTreeItemPtr term;
18490
0
    xmlSchemaModelGroupDefPtr gdef;
18491
18492
0
    for (; particle != NULL; particle = particle->next) {
18493
0
  term = particle->children;
18494
0
  if (term == NULL)
18495
0
      continue;
18496
0
  switch (term->type) {
18497
0
      case XML_SCHEMA_TYPE_GROUP:
18498
0
    gdef = (xmlSchemaModelGroupDefPtr) term;
18499
0
    if (gdef == groupDef)
18500
0
        return (particle);
18501
    /*
18502
    * Mark this model group definition to avoid infinite
18503
    * recursion on circular references not yet examined.
18504
    */
18505
0
    if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18506
0
        continue;
18507
0
    if (gdef->children != NULL) {
18508
0
        gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18509
0
        circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18510
0
      gdef->children->children);
18511
0
        gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18512
0
        if (circ != NULL)
18513
0
      return (circ);
18514
0
    }
18515
0
    break;
18516
0
      case XML_SCHEMA_TYPE_SEQUENCE:
18517
0
      case XML_SCHEMA_TYPE_CHOICE:
18518
0
      case XML_SCHEMA_TYPE_ALL:
18519
0
    circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18520
0
    if (circ != NULL)
18521
0
        return (circ);
18522
0
    break;
18523
0
      default:
18524
0
    break;
18525
0
  }
18526
0
    }
18527
0
    return (NULL);
18528
0
}
18529
18530
/**
18531
 * Checks for circular references to model group definitions.
18532
 *
18533
 * @param item  the model group definition
18534
 * @param ctxt  the parser context
18535
 */
18536
static void
18537
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18538
             xmlSchemaParserCtxtPtr ctxt)
18539
0
{
18540
    /*
18541
    * Schema Component Constraint: Model Group Correct
18542
    * 2 Circular groups are disallowed. That is, within the {particles}
18543
    * of a group there must not be at any depth a particle whose {term}
18544
    * is the group itself.
18545
    */
18546
0
    if ((item == NULL) ||
18547
0
  (item->type != XML_SCHEMA_TYPE_GROUP) ||
18548
0
  (item->children == NULL))
18549
0
  return;
18550
0
    {
18551
0
  xmlSchemaTreeItemPtr circ;
18552
18553
0
  circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18554
0
  if (circ != NULL) {
18555
0
      xmlChar *str = NULL;
18556
      /*
18557
      * TODO: The error report is not adequate: this constraint
18558
      * is defined for model groups but not definitions, but since
18559
      * there cannot be any circular model groups without a model group
18560
      * definition (if not using a construction API), we check those
18561
      * definitions only.
18562
      */
18563
0
      xmlSchemaPCustomErr(ctxt,
18564
0
    XML_SCHEMAP_MG_PROPS_CORRECT_2,
18565
0
    NULL, WXS_ITEM_NODE(circ),
18566
0
    "Circular reference to the model group definition '%s' "
18567
0
    "defined", xmlSchemaFormatQName(&str,
18568
0
        item->targetNamespace, item->name));
18569
0
      FREE_AND_NULL(str)
18570
      /*
18571
      * NOTE: We will cut the reference to avoid further
18572
      * confusion of the processor. This is a fatal error.
18573
      */
18574
0
      circ->children = NULL;
18575
0
  }
18576
0
    }
18577
0
}
18578
18579
/**
18580
 * Assigns the model group of model group definitions to the "term"
18581
 * of the referencing particle.
18582
 * In xmlSchemaResolveModelGroupParticleReferences the model group
18583
 * definitions were assigned to the "term", since needed for the
18584
 * circularity check.
18585
 *
18586
 * Schema Component Constraint:
18587
 *     All Group Limited (cos-all-limited) (1.2)
18588
 * @param ctxt  the parser context
18589
 * @param mg  the model group
18590
 */
18591
static void
18592
xmlSchemaModelGroupToModelGroupDefFixup(
18593
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18594
    xmlSchemaModelGroupPtr mg)
18595
0
{
18596
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18597
18598
0
    while (particle != NULL) {
18599
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18600
0
      ((WXS_PARTICLE_TERM(particle))->type !=
18601
0
    XML_SCHEMA_TYPE_GROUP))
18602
0
  {
18603
0
      particle = WXS_PTC_CAST particle->next;
18604
0
      continue;
18605
0
  }
18606
0
  if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18607
      /*
18608
      * TODO: Remove the particle.
18609
      */
18610
0
      WXS_PARTICLE_TERM(particle) = NULL;
18611
0
      particle = WXS_PTC_CAST particle->next;
18612
0
      continue;
18613
0
  }
18614
  /*
18615
  * Assign the model group to the {term} of the particle.
18616
  */
18617
0
  WXS_PARTICLE_TERM(particle) =
18618
0
      WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18619
18620
0
  particle = WXS_PTC_CAST particle->next;
18621
0
    }
18622
0
}
18623
18624
/**
18625
 * This one is intended to be used by
18626
 * xmlSchemaCheckAttrGroupCircular only.
18627
 *
18628
 * @param ctxtGr  the searched attribute group
18629
 * @param list  the current attribute list to be processed
18630
 * @returns the circular attribute group reference, otherwise NULL.
18631
 */
18632
static xmlSchemaQNameRefPtr
18633
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
18634
             xmlSchemaItemListPtr list)
18635
0
{
18636
0
    xmlSchemaAttributeGroupPtr gr;
18637
0
    xmlSchemaQNameRefPtr ref, circ;
18638
0
    int i;
18639
    /*
18640
    * We will search for an attribute group reference which
18641
    * references the context attribute group.
18642
    */
18643
0
    for (i = 0; i < list->nbItems; i++) {
18644
0
  ref = list->items[i];
18645
0
  if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18646
0
      (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
18647
0
      (ref->item != NULL))
18648
0
  {
18649
0
      gr = WXS_ATTR_GROUP_CAST ref->item;
18650
0
      if (gr == ctxtGr)
18651
0
    return(ref);
18652
0
      if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
18653
0
    continue;
18654
      /*
18655
      * Mark as visited to avoid infinite recursion on
18656
      * circular references not yet examined.
18657
      */
18658
0
      if ((gr->attrUses) &&
18659
0
    (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
18660
0
      {
18661
0
    gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
18662
0
    circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
18663
0
        (xmlSchemaItemListPtr) gr->attrUses);
18664
0
    gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
18665
0
    if (circ != NULL)
18666
0
        return (circ);
18667
0
      }
18668
18669
0
  }
18670
0
    }
18671
0
    return (NULL);
18672
0
}
18673
18674
/**
18675
 * Checks for circular references of attribute groups.
18676
 *
18677
 * @param attrGr  the attribute group definition
18678
 * @param ctxt  the parser context
18679
 */
18680
static int
18681
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
18682
        xmlSchemaParserCtxtPtr ctxt)
18683
0
{
18684
    /*
18685
    * Schema Representation Constraint:
18686
    * Attribute Group Definition Representation OK
18687
    * 3 Circular group reference is disallowed outside <redefine>.
18688
    * That is, unless this element information item's parent is
18689
    * <redefine>, then among the [children], if any, there must
18690
    * not be an <attributeGroup> with ref [attribute] which resolves
18691
    * to the component corresponding to this <attributeGroup>. Indirect
18692
    * circularity is also ruled out. That is, when QName resolution
18693
    * (Schema Document) ($3.15.3) is applied to a `QName` arising from
18694
    * any <attributeGroup>s with a ref [attribute] among the [children],
18695
    * it must not be the case that a `QName` is encountered at any depth
18696
    * which resolves to the component corresponding to this <attributeGroup>.
18697
    */
18698
0
    if (attrGr->attrUses == NULL)
18699
0
  return(0);
18700
0
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
18701
0
  return(0);
18702
0
    else {
18703
0
  xmlSchemaQNameRefPtr circ;
18704
18705
0
  circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
18706
0
      (xmlSchemaItemListPtr) attrGr->attrUses);
18707
0
  if (circ != NULL) {
18708
0
      xmlChar *str = NULL;
18709
      /*
18710
      * TODO: Report the referenced attr group as QName.
18711
      */
18712
0
      xmlSchemaPCustomErr(ctxt,
18713
0
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
18714
0
    NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
18715
0
    "Circular reference to the attribute group '%s' "
18716
0
    "defined", xmlSchemaGetComponentQName(&str, attrGr));
18717
0
      FREE_AND_NULL(str);
18718
      /*
18719
      * NOTE: We will cut the reference to avoid further
18720
      * confusion of the processor.
18721
      * BADSPEC TODO: The spec should define how to process in this case.
18722
      */
18723
0
      circ->item = NULL;
18724
0
      return(ctxt->err);
18725
0
  }
18726
0
    }
18727
0
    return(0);
18728
0
}
18729
18730
static int
18731
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
18732
          xmlSchemaAttributeGroupPtr attrGr);
18733
18734
/**
18735
 * Substitutes contained attribute group references
18736
 * for their attribute uses. Wildcards are intersected.
18737
 * Attribute use prohibitions are removed from the list
18738
 * and returned via the `prohibs` list.
18739
 * Pointlessness of attr. prohibs, if a matching attr. decl
18740
 * is existent a well, are checked.
18741
 *
18742
 * @param pctxt  the parser context
18743
 * @param item  the schema item
18744
 * @param completeWild  the intersected wildcard to be returned
18745
 * @param list  the attribute uses
18746
 * @param prohibs  the attribute prohibitions
18747
 */
18748
static int
18749
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
18750
          xmlSchemaBasicItemPtr item,
18751
          xmlSchemaWildcardPtr *completeWild,
18752
          xmlSchemaItemListPtr list,
18753
          xmlSchemaItemListPtr prohibs)
18754
0
{
18755
0
    xmlSchemaAttributeGroupPtr gr;
18756
0
    xmlSchemaAttributeUsePtr use;
18757
0
    xmlSchemaItemListPtr sublist;
18758
0
    int i, j;
18759
0
    int created = (*completeWild == NULL) ? 0 : 1;
18760
18761
0
    if (prohibs)
18762
0
  prohibs->nbItems = 0;
18763
18764
0
    for (i = 0; i < list->nbItems; i++) {
18765
0
  use = list->items[i];
18766
18767
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
18768
0
      if (prohibs == NULL) {
18769
0
    PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
18770
0
        "unexpected attr prohibition found");
18771
0
    return(-1);
18772
0
      }
18773
      /*
18774
      * Remove from attribute uses.
18775
      */
18776
0
      if (xmlSchemaItemListRemove(list, i) == -1)
18777
0
    return(-1);
18778
0
      i--;
18779
      /*
18780
      * Note that duplicate prohibitions were already
18781
      * handled at parsing time.
18782
      */
18783
      /*
18784
      * Add to list of prohibitions.
18785
      */
18786
0
      xmlSchemaItemListAddSize(prohibs, 2, use);
18787
0
      continue;
18788
0
  }
18789
0
  if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18790
0
      ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
18791
0
  {
18792
0
      if ((WXS_QNAME_CAST use)->item == NULL)
18793
0
    return(-1);
18794
0
      gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
18795
      /*
18796
      * Expand the referenced attr. group.
18797
      * TODO: remove this, this is done in a previous step, so
18798
      * already done here.
18799
      */
18800
0
      if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
18801
0
    if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
18802
0
        return(-1);
18803
0
      }
18804
      /*
18805
      * Build the 'complete' wildcard; i.e. intersect multiple
18806
      * wildcards.
18807
      */
18808
0
      if (gr->attributeWildcard != NULL) {
18809
0
    if (*completeWild == NULL) {
18810
0
        *completeWild = gr->attributeWildcard;
18811
0
    } else {
18812
0
        if (! created) {
18813
0
      xmlSchemaWildcardPtr tmpWild;
18814
18815
       /*
18816
      * Copy the first encountered wildcard as context,
18817
      * except for the annotation.
18818
      *
18819
      * Although the complete wildcard might not correspond
18820
      * to any node in the schema, we will anchor it on
18821
      * the node of the owner component.
18822
      */
18823
0
      tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
18824
0
          XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
18825
0
          WXS_ITEM_NODE(item));
18826
0
      if (tmpWild == NULL)
18827
0
          return(-1);
18828
0
      if (xmlSchemaCloneWildcardNsConstraints(pctxt,
18829
0
          tmpWild, *completeWild) == -1)
18830
0
          return (-1);
18831
0
      tmpWild->processContents = (*completeWild)->processContents;
18832
0
      *completeWild = tmpWild;
18833
0
      created = 1;
18834
0
        }
18835
18836
0
        if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
18837
0
      gr->attributeWildcard) == -1)
18838
0
      return(-1);
18839
0
    }
18840
0
      }
18841
      /*
18842
      * Just remove the reference if the referenced group does not
18843
      * contain any attribute uses.
18844
      */
18845
0
      sublist = ((xmlSchemaItemListPtr) gr->attrUses);
18846
0
      if ((sublist == NULL) || sublist->nbItems == 0) {
18847
0
    if (xmlSchemaItemListRemove(list, i) == -1)
18848
0
        return(-1);
18849
0
    i--;
18850
0
    continue;
18851
0
      }
18852
      /*
18853
      * Add the attribute uses.
18854
      */
18855
0
      list->items[i] = sublist->items[0];
18856
0
      if (sublist->nbItems != 1) {
18857
0
    for (j = 1; j < sublist->nbItems; j++) {
18858
0
        i++;
18859
0
        if (xmlSchemaItemListInsert(list,
18860
0
          sublist->items[j], i) == -1)
18861
0
      return(-1);
18862
0
    }
18863
0
      }
18864
0
  }
18865
18866
0
    }
18867
    /*
18868
    * Handle pointless prohibitions of declared attributes.
18869
    */
18870
0
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
18871
0
  xmlSchemaAttributeUseProhibPtr prohib;
18872
18873
0
  for (i = prohibs->nbItems -1; i >= 0; i--) {
18874
0
      prohib = prohibs->items[i];
18875
0
      for (j = 0; j < list->nbItems; j++) {
18876
0
    use = list->items[j];
18877
18878
0
    if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
18879
0
        (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
18880
0
    {
18881
0
        xmlChar *str = NULL;
18882
18883
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
18884
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
18885
0
      prohib->node, NULL,
18886
0
      "Skipping pointless attribute use prohibition "
18887
0
      "'%s', since a corresponding attribute use "
18888
0
      "exists already in the type definition",
18889
0
      xmlSchemaFormatQName(&str,
18890
0
          prohib->targetNamespace, prohib->name),
18891
0
      NULL, NULL);
18892
0
        FREE_AND_NULL(str);
18893
        /*
18894
        * Remove the prohibition.
18895
        */
18896
0
        if (xmlSchemaItemListRemove(prohibs, i) == -1)
18897
0
      return(-1);
18898
0
        break;
18899
0
    }
18900
0
      }
18901
0
  }
18902
0
    }
18903
0
    return(0);
18904
0
}
18905
18906
/**
18907
 * Computation of:
18908
 * {attribute uses} property
18909
 * {attribute wildcard} property
18910
 *
18911
 * Substitutes contained attribute group references
18912
 * for their attribute uses. Wildcards are intersected.
18913
 *
18914
 * @param pctxt  the parser context
18915
 * @param attrGr  the attribute group definition
18916
 */
18917
static int
18918
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
18919
          xmlSchemaAttributeGroupPtr attrGr)
18920
0
{
18921
0
    if ((attrGr->attrUses == NULL) ||
18922
0
  (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
18923
0
  return(0);
18924
18925
0
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
18926
0
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
18927
0
  &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
18928
0
  return(-1);
18929
0
    return(0);
18930
0
}
18931
18932
/**
18933
 * Substitutes contained attribute group references
18934
 * for their attribute uses. Wildcards are intersected.
18935
 *
18936
 * Schema Component Constraint:
18937
 *    Attribute Group Definition Properties Correct (ag-props-correct)
18938
 * @param pctxt  the parser context
18939
 * @param attrGr  the attribute group definition
18940
 */
18941
static int
18942
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
18943
          xmlSchemaAttributeGroupPtr attrGr)
18944
0
{
18945
    /*
18946
    * SPEC ag-props-correct
18947
    * (1) "The values of the properties of an attribute group definition
18948
    * must be as described in the property tableau in The Attribute
18949
    * Group Definition Schema Component ($3.6.1), modulo the impact of
18950
    * Missing Sub-components ($5.3);"
18951
    */
18952
18953
0
    if ((attrGr->attrUses != NULL) &&
18954
0
  (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
18955
0
    {
18956
0
  xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
18957
0
  xmlSchemaAttributeUsePtr use, tmp;
18958
0
  int i, j, hasId = 0;
18959
18960
0
  for (i = uses->nbItems -1; i >= 0; i--) {
18961
0
      use = uses->items[i];
18962
      /*
18963
      * SPEC ag-props-correct
18964
      * (2) "Two distinct members of the {attribute uses} must not have
18965
      * {attribute declaration}s both of whose {name}s match and whose
18966
      * {target namespace}s are identical."
18967
      */
18968
0
      if (i > 0) {
18969
0
    for (j = i -1; j >= 0; j--) {
18970
0
        tmp = uses->items[j];
18971
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
18972
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
18973
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
18974
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
18975
0
        {
18976
0
      xmlChar *str = NULL;
18977
18978
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18979
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
18980
0
          attrGr->node, WXS_BASIC_CAST attrGr,
18981
0
          "Duplicate %s",
18982
0
          xmlSchemaGetComponentDesignation(&str, use),
18983
0
          NULL);
18984
0
      FREE_AND_NULL(str);
18985
      /*
18986
      * Remove the duplicate.
18987
      */
18988
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
18989
0
          return(-1);
18990
0
      goto next_use;
18991
0
        }
18992
0
    }
18993
0
      }
18994
      /*
18995
      * SPEC ag-props-correct
18996
      * (3) "Two distinct members of the {attribute uses} must not have
18997
      * {attribute declaration}s both of whose {type definition}s are or
18998
      * are derived from ID."
18999
      * TODO: Does 'derived' include member-types of unions?
19000
      */
19001
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19002
0
    if (xmlSchemaIsDerivedFromBuiltInType(
19003
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19004
0
    {
19005
0
        if (hasId) {
19006
0
      xmlChar *str = NULL;
19007
19008
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19009
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19010
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19011
0
          "There must not exist more than one attribute "
19012
0
          "declaration of type 'xs:ID' "
19013
0
          "(or derived from 'xs:ID'). The %s violates this "
19014
0
          "constraint",
19015
0
          xmlSchemaGetComponentDesignation(&str, use),
19016
0
          NULL);
19017
0
      FREE_AND_NULL(str);
19018
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19019
0
          return(-1);
19020
0
        }
19021
0
        hasId = 1;
19022
0
    }
19023
0
      }
19024
0
next_use: {}
19025
0
  }
19026
0
    }
19027
0
    return(0);
19028
0
}
19029
19030
/**
19031
 * Resolves references to attribute group definitions.
19032
 *
19033
 * @param ref  the schema attribute definition
19034
 * @param ctxt  the schema parser context
19035
 */
19036
static int
19037
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19038
            xmlSchemaParserCtxtPtr ctxt)
19039
0
{
19040
0
    xmlSchemaAttributeGroupPtr group;
19041
19042
0
    if (ref->item != NULL)
19043
0
        return(0);
19044
0
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
19045
0
  ref->name,
19046
0
  ref->targetNamespace);
19047
0
    if (group == NULL) {
19048
0
  xmlSchemaPResCompAttrErr(ctxt,
19049
0
      XML_SCHEMAP_SRC_RESOLVE,
19050
0
      NULL, ref->node,
19051
0
      "ref", ref->name, ref->targetNamespace,
19052
0
      ref->itemType, NULL);
19053
0
  return(ctxt->err);
19054
0
    }
19055
0
    ref->item = WXS_BASIC_CAST group;
19056
0
    return(0);
19057
0
}
19058
19059
/**
19060
 * Schema Component Constraint:
19061
 *    Attribute Declaration Properties Correct (a-props-correct)
19062
 *
19063
 * Validates the value constraints of an attribute declaration/use.
19064
 * NOTE that this needs the simple type definitions to be already
19065
 *   built and checked.
19066
 * @param pctxt  a schema parser context
19067
 * @param attr  an schema attribute declaration/use
19068
 */
19069
static int
19070
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19071
             xmlSchemaAttributePtr attr)
19072
0
{
19073
19074
    /*
19075
    * SPEC a-props-correct (1)
19076
    * "The values of the properties of an attribute declaration must
19077
    * be as described in the property tableau in The Attribute
19078
    * Declaration Schema Component ($3.2.1), modulo the impact of
19079
    * Missing Sub-components ($5.3)."
19080
    */
19081
19082
0
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
19083
0
  return(0);
19084
19085
0
    if (attr->defValue != NULL) {
19086
0
  int ret;
19087
19088
  /*
19089
  * SPEC a-props-correct (3)
19090
  * "If the {type definition} is or is derived from ID then there
19091
  * must not be a {value constraint}."
19092
  */
19093
0
  if (xmlSchemaIsDerivedFromBuiltInType(
19094
0
      WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19095
0
  {
19096
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19097
0
    XML_SCHEMAP_A_PROPS_CORRECT_3,
19098
0
    NULL, WXS_BASIC_CAST attr,
19099
0
    "Value constraints are not allowed if the type definition "
19100
0
    "is or is derived from xs:ID",
19101
0
    NULL, NULL);
19102
0
      return(pctxt->err);
19103
0
  }
19104
  /*
19105
  * SPEC a-props-correct (2)
19106
  * "if there is a {value constraint}, the canonical lexical
19107
  * representation of its value must be `valid` with respect
19108
  * to the {type definition} as defined in String Valid ($3.14.4)."
19109
  * TODO: Don't care about the *canonical* stuff here, this requirement
19110
  * will be removed in WXS 1.1 anyway.
19111
  */
19112
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19113
0
      attr->node, WXS_ATTR_TYPEDEF(attr),
19114
0
      attr->defValue, &(attr->defVal),
19115
0
      1, 1, 0);
19116
0
  if (ret != 0) {
19117
0
      if (ret < 0) {
19118
0
    PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19119
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19120
0
    return(-1);
19121
0
      }
19122
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19123
0
    XML_SCHEMAP_A_PROPS_CORRECT_2,
19124
0
    NULL, WXS_BASIC_CAST attr,
19125
0
    "The value of the value constraint is not valid",
19126
0
    NULL, NULL);
19127
0
      return(pctxt->err);
19128
0
  }
19129
0
    }
19130
19131
0
    return(0);
19132
0
}
19133
19134
static xmlSchemaElementPtr
19135
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19136
         xmlSchemaElementPtr ancestor)
19137
0
{
19138
0
    xmlSchemaElementPtr ret;
19139
19140
0
    if (WXS_SUBST_HEAD(ancestor) == NULL)
19141
0
  return (NULL);
19142
0
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19143
0
  return (ancestor);
19144
19145
0
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19146
0
  return (NULL);
19147
0
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19148
0
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19149
0
  WXS_SUBST_HEAD(ancestor));
19150
0
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19151
19152
0
    return (ret);
19153
0
}
19154
19155
/**
19156
 * Schema Component Constraint:
19157
 * Element Declaration Properties Correct (e-props-correct)
19158
 *
19159
 * STATUS:
19160
 *   missing: (6)
19161
 * @param pctxt  a schema parser context
19162
 * @param elemDecl  the element declaration
19163
 */
19164
static int
19165
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19166
             xmlSchemaElementPtr elemDecl)
19167
0
{
19168
0
    int ret = 0;
19169
0
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19170
    /*
19171
    * SPEC (1) "The values of the properties of an element declaration
19172
    * must be as described in the property tableau in The Element
19173
    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19174
    * Sub-components ($5.3)."
19175
    */
19176
0
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19177
0
  xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19178
19179
0
  xmlSchemaCheckElementDeclComponent(head, pctxt);
19180
  /*
19181
  * SPEC (3) "If there is a non-`absent` {substitution group
19182
  * affiliation}, then {scope} must be global."
19183
  */
19184
0
  if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19185
0
      xmlSchemaPCustomErr(pctxt,
19186
0
    XML_SCHEMAP_E_PROPS_CORRECT_3,
19187
0
    WXS_BASIC_CAST elemDecl, NULL,
19188
0
    "Only global element declarations can have a "
19189
0
    "substitution group affiliation", NULL);
19190
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19191
0
  }
19192
  /*
19193
  * TODO: SPEC (6) "Circular substitution groups are disallowed.
19194
  * That is, it must not be possible to return to an element declaration
19195
  * by repeatedly following the {substitution group affiliation}
19196
  * property."
19197
  */
19198
0
  if (head == elemDecl)
19199
0
      circ = head;
19200
0
  else if (WXS_SUBST_HEAD(head) != NULL)
19201
0
      circ = xmlSchemaCheckSubstGroupCircular(head, head);
19202
0
  else
19203
0
      circ = NULL;
19204
0
  if (circ != NULL) {
19205
0
      xmlChar *strA = NULL, *strB = NULL;
19206
19207
0
      xmlSchemaPCustomErrExt(pctxt,
19208
0
    XML_SCHEMAP_E_PROPS_CORRECT_6,
19209
0
    WXS_BASIC_CAST circ, NULL,
19210
0
    "The element declaration '%s' defines a circular "
19211
0
    "substitution group to element declaration '%s'",
19212
0
    xmlSchemaGetComponentQName(&strA, circ),
19213
0
    xmlSchemaGetComponentQName(&strB, head),
19214
0
    NULL);
19215
0
      FREE_AND_NULL(strA)
19216
0
      FREE_AND_NULL(strB)
19217
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19218
0
  }
19219
  /*
19220
  * SPEC (4) "If there is a {substitution group affiliation},
19221
  * the {type definition}
19222
  * of the element declaration must be validly derived from the {type
19223
  * definition} of the {substitution group affiliation}, given the value
19224
  * of the {substitution group exclusions} of the {substitution group
19225
  * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19226
  * (if the {type definition} is complex) or as defined in
19227
  * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19228
  * simple)."
19229
  *
19230
  * NOTE: {substitution group exclusions} means the values of the
19231
  * attribute "final".
19232
  */
19233
19234
0
  if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19235
0
      int set = 0;
19236
19237
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19238
0
    set |= SUBSET_EXTENSION;
19239
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19240
0
    set |= SUBSET_RESTRICTION;
19241
19242
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19243
0
    WXS_ELEM_TYPEDEF(head), set) != 0) {
19244
0
    xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19245
19246
0
    ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19247
0
    xmlSchemaPCustomErrExt(pctxt,
19248
0
        XML_SCHEMAP_E_PROPS_CORRECT_4,
19249
0
        WXS_BASIC_CAST elemDecl, NULL,
19250
0
        "The type definition '%s' was "
19251
0
        "either rejected by the substitution group "
19252
0
        "affiliation '%s', or not validly derived from its type "
19253
0
        "definition '%s'",
19254
0
        xmlSchemaGetComponentQName(&strA, typeDef),
19255
0
        xmlSchemaGetComponentQName(&strB, head),
19256
0
        xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19257
0
    FREE_AND_NULL(strA)
19258
0
    FREE_AND_NULL(strB)
19259
0
    FREE_AND_NULL(strC)
19260
0
      }
19261
0
  }
19262
0
    }
19263
    /*
19264
    * SPEC (5) "If the {type definition} or {type definition}'s
19265
    * {content type}
19266
    * is or is derived from ID then there must not be a {value constraint}.
19267
    * Note: The use of ID as a type definition for elements goes beyond
19268
    * XML 1.0, and should be avoided if backwards compatibility is desired"
19269
    */
19270
0
    if ((elemDecl->value != NULL) &&
19271
0
  ((WXS_IS_SIMPLE(typeDef) &&
19272
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19273
0
   (WXS_IS_COMPLEX(typeDef) &&
19274
0
    WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19275
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19276
0
      XML_SCHEMAS_ID)))) {
19277
19278
0
  ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19279
0
  xmlSchemaPCustomErr(pctxt,
19280
0
      XML_SCHEMAP_E_PROPS_CORRECT_5,
19281
0
      WXS_BASIC_CAST elemDecl, NULL,
19282
0
      "The type definition (or type definition's content type) is or "
19283
0
      "is derived from ID; value constraints are not allowed in "
19284
0
      "conjunction with such a type definition", NULL);
19285
0
    } else if (elemDecl->value != NULL) {
19286
0
  int vcret;
19287
0
  xmlNodePtr node = NULL;
19288
19289
  /*
19290
  * SPEC (2) "If there is a {value constraint}, the canonical lexical
19291
  * representation of its value must be `valid` with respect to the
19292
  * {type definition} as defined in Element Default Valid (Immediate)
19293
  * ($3.3.6)."
19294
  */
19295
0
  if (typeDef == NULL) {
19296
0
      xmlSchemaPErr(pctxt, elemDecl->node,
19297
0
    XML_SCHEMAP_INTERNAL,
19298
0
    "Internal error: xmlSchemaCheckElemPropsCorrect, "
19299
0
    "type is missing... skipping validation of "
19300
0
    "the value constraint", NULL, NULL);
19301
0
      return (-1);
19302
0
  }
19303
0
  if (elemDecl->node != NULL) {
19304
0
      if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19305
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19306
0
        BAD_CAST "fixed");
19307
0
      else
19308
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19309
0
        BAD_CAST "default");
19310
0
  }
19311
0
  vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19312
0
      typeDef, elemDecl->value, &(elemDecl->defVal));
19313
0
  if (vcret != 0) {
19314
0
      if (vcret < 0) {
19315
0
    PERROR_INT("xmlSchemaElemCheckValConstr",
19316
0
        "failed to validate the value constraint of an "
19317
0
        "element declaration");
19318
0
    return (-1);
19319
0
      }
19320
0
      return (vcret);
19321
0
  }
19322
0
    }
19323
19324
0
    return (ret);
19325
0
}
19326
19327
/**
19328
 * Schema Component Constraint:
19329
 * Substitution Group (cos-equiv-class)
19330
 *
19331
 * In Libxml2 the subst. groups will be precomputed, in terms of that
19332
 * a list will be built for each subst. group head, holding all direct
19333
 * referents to this head.
19334
 * NOTE that this function needs:
19335
 *   1. circular subst. groups to be checked beforehand
19336
 *   2. the declaration's type to be derived from the head's type
19337
 *
19338
 * STATUS:
19339
 *
19340
 * @param ctxt  a schema parser context
19341
 * @param elemDecl  the element declaration
19342
 */
19343
static void
19344
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19345
           xmlSchemaElementPtr elemDecl)
19346
0
{
19347
0
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19348
  /* SPEC (1) "Its {abstract} is false." */
19349
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19350
0
  return;
19351
0
    {
19352
0
  xmlSchemaElementPtr head;
19353
0
  xmlSchemaTypePtr headType, type;
19354
0
  int set, methSet;
19355
  /*
19356
  * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19357
  * {disallowed substitutions} as the blocking constraint, as defined in
19358
  * Substitution Group OK (Transitive) ($3.3.6)."
19359
  */
19360
0
  for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19361
0
      head = WXS_SUBST_HEAD(head)) {
19362
0
      set = 0;
19363
0
      methSet = 0;
19364
      /*
19365
      * The blocking constraints.
19366
      */
19367
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19368
0
    continue;
19369
0
      headType = head->subtypes;
19370
0
      type = elemDecl->subtypes;
19371
0
      if (headType == type)
19372
0
    goto add_member;
19373
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19374
0
    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19375
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19376
0
    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19377
      /*
19378
      * SPEC: Substitution Group OK (Transitive) (2.3)
19379
      * "The set of all {derivation method}s involved in the
19380
      * derivation of D's {type definition} from C's {type definition}
19381
      * does not intersect with the union of the blocking constraint,
19382
      * C's {prohibited substitutions} (if C is complex, otherwise the
19383
      * empty set) and the {prohibited substitutions} (respectively the
19384
      * empty set) of any intermediate {type definition}s in the
19385
      * derivation of D's {type definition} from C's {type definition}."
19386
      */
19387
      /*
19388
      * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19389
      * subst.head axis, the methSet does not need to be computed for
19390
      * the full depth over and over.
19391
      */
19392
      /*
19393
      * The set of all {derivation method}s involved in the derivation
19394
      */
19395
0
      while ((type != NULL) && (type != headType) &&
19396
0
                   (type != type->baseType)) {
19397
0
    if ((WXS_IS_EXTENSION(type)) &&
19398
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19399
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19400
19401
0
    if (WXS_IS_RESTRICTION(type) &&
19402
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19403
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19404
19405
0
    type = type->baseType;
19406
0
      }
19407
      /*
19408
      * The {prohibited substitutions} of all intermediate types +
19409
      * the head's type.
19410
      */
19411
0
      type = elemDecl->subtypes->baseType;
19412
0
      while (type != NULL) {
19413
0
    if (WXS_IS_COMPLEX(type)) {
19414
0
        if ((type->flags &
19415
0
          XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19416
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19417
0
        set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19418
0
        if ((type->flags &
19419
0
          XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19420
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19421
0
        set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19422
0
    } else
19423
0
        break;
19424
0
    if (type == headType)
19425
0
        break;
19426
0
    type = type->baseType;
19427
0
      }
19428
0
      if ((set != 0) &&
19429
0
    (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19430
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19431
0
    ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19432
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19433
0
    continue;
19434
0
      }
19435
0
add_member:
19436
0
      xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19437
0
      if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19438
0
    head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19439
0
  }
19440
0
    }
19441
0
}
19442
19443
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19444
/**
19445
 * xmlSchemaCheckElementDeclComponent
19446
 *
19447
 * Schema Component Constraint: Element Declarations Consistent
19448
 *
19449
 * @param pctxt  the schema parser context
19450
 * @param ctxtComponent  the context component (an element declaration)
19451
 * @param ctxtParticle  the first particle of the context component
19452
 * @param searchParticle  the element declaration particle to be analysed
19453
 * @param curParticle  the current particle
19454
 * @param search  search flag
19455
 */
19456
static int
19457
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19458
            xmlSchemaBasicItemPtr ctxtComponent,
19459
            xmlSchemaParticlePtr ctxtParticle,
19460
            xmlSchemaParticlePtr searchParticle,
19461
            xmlSchemaParticlePtr curParticle,
19462
            int search)
19463
{
19464
    return(0);
19465
19466
    int ret = 0;
19467
    xmlSchemaParticlePtr cur = curParticle;
19468
    if (curParticle == NULL) {
19469
  return(0);
19470
    }
19471
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19472
  /*
19473
  * Just return in this case. A missing "term" of the particle
19474
  * might arise due to an invalid "term" component.
19475
  */
19476
  return(0);
19477
    }
19478
    while (cur != NULL) {
19479
  switch (WXS_PARTICLE_TERM(cur)->type) {
19480
      case XML_SCHEMA_TYPE_ANY:
19481
    break;
19482
      case XML_SCHEMA_TYPE_ELEMENT:
19483
    if (search == 0) {
19484
        ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19485
      ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19486
        if (ret != 0)
19487
      return(ret);
19488
    } else {
19489
        xmlSchemaElementPtr elem =
19490
      WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19491
        /*
19492
        * SPEC Element Declarations Consistent:
19493
        * "If the {particles} contains, either directly,
19494
        * indirectly (that is, within the {particles} of a
19495
        * contained model group, recursively) or `implicitly`
19496
        * two or more element declaration particles with
19497
        * the same {name} and {target namespace}, then
19498
        * all their type definitions must be the same
19499
        * top-level definition [...]"
19500
        */
19501
        if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19502
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19503
      xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19504
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19505
        {
19506
      xmlChar *strA = NULL, *strB = NULL;
19507
19508
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19509
          /* TODO: error code */
19510
          XML_SCHEMAP_COS_NONAMBIG,
19511
          WXS_ITEM_NODE(cur), NULL,
19512
          "In the content model of %s, there are multiple "
19513
          "element declarations for '%s' with different "
19514
          "type definitions",
19515
          xmlSchemaGetComponentDesignation(&strA,
19516
        ctxtComponent),
19517
          xmlSchemaFormatQName(&strB,
19518
        WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19519
        WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19520
      FREE_AND_NULL(strA);
19521
      FREE_AND_NULL(strB);
19522
      return(XML_SCHEMAP_COS_NONAMBIG);
19523
        }
19524
    }
19525
    break;
19526
      case XML_SCHEMA_TYPE_SEQUENCE: {
19527
    break;
19528
    }
19529
      case XML_SCHEMA_TYPE_CHOICE:{
19530
    /*
19531
    xmlSchemaTreeItemPtr sub;
19532
19533
    sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19534
    while (sub != NULL) {
19535
        ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19536
      ctxtParticle, ctxtElem);
19537
        if (ret != 0)
19538
      return(ret);
19539
        sub = sub->next;
19540
    }
19541
    */
19542
    break;
19543
    }
19544
      case XML_SCHEMA_TYPE_ALL:
19545
    break;
19546
      case XML_SCHEMA_TYPE_GROUP:
19547
    break;
19548
      default:
19549
    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19550
        "xmlSchemaCheckElementDeclConsistent",
19551
        "found unexpected term of type '%s' in content model",
19552
        WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19553
    return(-1);
19554
  }
19555
  cur = (xmlSchemaParticlePtr) cur->next;
19556
    }
19557
19558
exit:
19559
    return(ret);
19560
}
19561
#endif
19562
19563
/**
19564
 * xmlSchemaCheckElementDeclComponent
19565
 *
19566
 * Validates the value constraints of an element declaration.
19567
 * Adds substitution group members.
19568
 *
19569
 * @param elemDecl  an schema element declaration/particle
19570
 * @param ctxt  a schema parser context
19571
 */
19572
static void
19573
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19574
           xmlSchemaParserCtxtPtr ctxt)
19575
0
{
19576
0
    if (elemDecl == NULL)
19577
0
  return;
19578
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19579
0
  return;
19580
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19581
0
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19582
  /*
19583
  * Adds substitution group members.
19584
  */
19585
0
  xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19586
0
    }
19587
0
}
19588
19589
/**
19590
 * Resolves references of a model group's {particles} to
19591
 * model group definitions and to element declarations.
19592
 *
19593
 * @param ctxt  a parser context
19594
 * @param mg  a model group
19595
 */
19596
static void
19597
xmlSchemaResolveModelGroupParticleReferences(
19598
    xmlSchemaParserCtxtPtr ctxt,
19599
    xmlSchemaModelGroupPtr mg)
19600
0
{
19601
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19602
0
    xmlSchemaQNameRefPtr ref;
19603
0
    xmlSchemaBasicItemPtr refItem;
19604
19605
    /*
19606
    * URGENT TODO: Test this.
19607
    */
19608
0
    while (particle != NULL) {
19609
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19610
0
      ((WXS_PARTICLE_TERM(particle))->type !=
19611
0
    XML_SCHEMA_EXTRA_QNAMEREF))
19612
0
  {
19613
0
      goto next_particle;
19614
0
  }
19615
0
  ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
19616
  /*
19617
  * Resolve the reference.
19618
  * NULL the {term} by default.
19619
  */
19620
0
  particle->children = NULL;
19621
19622
0
  refItem = xmlSchemaGetNamedComponent(ctxt->schema,
19623
0
      ref->itemType, ref->name, ref->targetNamespace);
19624
0
  if (refItem == NULL) {
19625
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
19626
0
    NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
19627
0
    ref->targetNamespace, ref->itemType, NULL);
19628
      /* TODO: remove the particle. */
19629
0
      goto next_particle;
19630
0
  }
19631
0
  if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
19632
0
      if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
19633
    /* TODO: remove the particle. */
19634
0
    goto next_particle;
19635
      /*
19636
      * NOTE that we will assign the model group definition
19637
      * itself to the "term" of the particle. This will ease
19638
      * the check for circular model group definitions. After
19639
      * that the "term" will be assigned the model group of the
19640
      * model group definition.
19641
      */
19642
0
      if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
19643
0
        XML_SCHEMA_TYPE_ALL) {
19644
    /*
19645
    * SPEC cos-all-limited (1)
19646
    * SPEC cos-all-limited (1.2)
19647
    * "It appears only as the value of one or both of the
19648
    * following properties:"
19649
    * (1.1) "the {model group} property of a model group
19650
    *        definition."
19651
    * (1.2) "the {term} property of a particle [... of] the "
19652
    * {content type} of a complex type definition."
19653
    */
19654
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
19655
        /* TODO: error code */
19656
0
        XML_SCHEMAP_COS_ALL_LIMITED,
19657
0
        WXS_ITEM_NODE(particle), NULL,
19658
0
        "A model group definition is referenced, but "
19659
0
        "it contains an 'all' model group, which "
19660
0
        "cannot be contained by model groups",
19661
0
        NULL, NULL);
19662
    /* TODO: remove the particle. */
19663
0
    goto next_particle;
19664
0
      }
19665
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
19666
0
  } else {
19667
      /*
19668
      * TODO: Are referenced element declarations the only
19669
      * other components we expect here?
19670
      */
19671
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
19672
0
  }
19673
0
next_particle:
19674
0
  particle = WXS_PTC_CAST particle->next;
19675
0
    }
19676
0
}
19677
19678
static int
19679
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
19680
           xmlSchemaValPtr y)
19681
0
{
19682
0
    xmlSchemaTypePtr tx, ty, ptx, pty;
19683
0
    int ret;
19684
19685
0
    while (x != NULL) {
19686
  /* Same types. */
19687
0
  tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
19688
0
  ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
19689
0
  ptx = xmlSchemaGetPrimitiveType(tx);
19690
0
  pty = xmlSchemaGetPrimitiveType(ty);
19691
  /*
19692
  * (1) if a datatype T' is `derived` by `restriction` from an
19693
  * atomic datatype T then the `value space` of T' is a subset of
19694
  * the `value space` of T. */
19695
  /*
19696
  * (2) if datatypes T' and T'' are `derived` by `restriction`
19697
  * from a common atomic ancestor T then the `value space`s of T'
19698
  * and T'' may overlap.
19699
  */
19700
0
  if (ptx != pty)
19701
0
      return(0);
19702
  /*
19703
  * We assume computed values to be normalized, so do a fast
19704
  * string comparison for string based types.
19705
  */
19706
0
  if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
19707
0
      WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
19708
0
      if (! xmlStrEqual(
19709
0
    xmlSchemaValueGetAsString(x),
19710
0
    xmlSchemaValueGetAsString(y)))
19711
0
    return (0);
19712
0
  } else {
19713
0
      ret = xmlSchemaCompareValuesWhtsp(
19714
0
    x, XML_SCHEMA_WHITESPACE_PRESERVE,
19715
0
    y, XML_SCHEMA_WHITESPACE_PRESERVE);
19716
0
      if (ret == -2)
19717
0
    return(-1);
19718
0
      if (ret != 0)
19719
0
    return(0);
19720
0
  }
19721
  /*
19722
  * Lists.
19723
  */
19724
0
  x = xmlSchemaValueGetNext(x);
19725
0
  if (x != NULL) {
19726
0
      y = xmlSchemaValueGetNext(y);
19727
0
      if (y == NULL)
19728
0
    return (0);
19729
0
  } else if (xmlSchemaValueGetNext(y) != NULL)
19730
0
      return (0);
19731
0
  else
19732
0
      return (1);
19733
0
    }
19734
0
    return (0);
19735
0
}
19736
19737
/**
19738
 * Resolves the referenced attribute declaration.
19739
 *
19740
 * @param ause  an attribute use
19741
 * @param ctxt  a parser context
19742
 */
19743
static int
19744
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
19745
          xmlSchemaParserCtxtPtr ctxt)
19746
0
{
19747
0
    if ((ctxt == NULL) || (ause == NULL))
19748
0
  return(-1);
19749
0
    if ((ause->attrDecl == NULL) ||
19750
0
  (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
19751
0
  return(0);
19752
19753
0
    {
19754
0
  xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
19755
19756
  /*
19757
  * TODO: Evaluate, what errors could occur if the declaration is not
19758
  * found.
19759
  */
19760
0
  ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
19761
0
      ref->name, ref->targetNamespace);
19762
0
        if (ause->attrDecl == NULL) {
19763
0
      xmlSchemaPResCompAttrErr(ctxt,
19764
0
    XML_SCHEMAP_SRC_RESOLVE,
19765
0
    WXS_BASIC_CAST ause, ause->node,
19766
0
    "ref", ref->name, ref->targetNamespace,
19767
0
    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
19768
0
            return(ctxt->err);;
19769
0
        }
19770
0
    }
19771
0
    return(0);
19772
0
}
19773
19774
/**
19775
 * Schema Component Constraint:
19776
 * Attribute Use Correct (au-props-correct)
19777
 *
19778
 * @param ctxt  a parser context
19779
 * @param use  an attribute use
19780
 */
19781
static int
19782
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
19783
           xmlSchemaAttributeUsePtr use)
19784
0
{
19785
0
    if ((ctxt == NULL) || (use == NULL))
19786
0
  return(-1);
19787
0
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
19788
0
  ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
19789
0
  return(0);
19790
19791
    /*
19792
    * SPEC au-props-correct (1)
19793
    * "The values of the properties of an attribute use must be as
19794
    * described in the property tableau in The Attribute Use Schema
19795
    * Component ($3.5.1), modulo the impact of Missing
19796
    * Sub-components ($5.3)."
19797
    */
19798
19799
0
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
19800
0
  ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
19801
0
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
19802
0
    {
19803
0
  xmlSchemaPCustomErr(ctxt,
19804
0
      XML_SCHEMAP_AU_PROPS_CORRECT_2,
19805
0
      WXS_BASIC_CAST use, NULL,
19806
0
      "The attribute declaration has a 'fixed' value constraint "
19807
0
      ", thus the attribute use must also have a 'fixed' value "
19808
0
      "constraint",
19809
0
      NULL);
19810
0
  return(ctxt->err);
19811
0
    }
19812
    /*
19813
    * Compute and check the value constraint's value.
19814
    */
19815
0
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
19816
0
  int ret;
19817
  /*
19818
  * TODO: The spec seems to be missing a check of the
19819
  * value constraint of the attribute use. We will do it here.
19820
  */
19821
  /*
19822
  * SPEC a-props-correct (3)
19823
  */
19824
0
  if (xmlSchemaIsDerivedFromBuiltInType(
19825
0
      WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19826
0
  {
19827
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
19828
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
19829
0
    NULL, WXS_BASIC_CAST use,
19830
0
    "Value constraints are not allowed if the type definition "
19831
0
    "is or is derived from xs:ID",
19832
0
    NULL, NULL);
19833
0
      return(ctxt->err);
19834
0
  }
19835
19836
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
19837
0
      use->node, WXS_ATTRUSE_TYPEDEF(use),
19838
0
      use->defValue, &(use->defVal),
19839
0
      1, 1, 0);
19840
0
  if (ret != 0) {
19841
0
      if (ret < 0) {
19842
0
    PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
19843
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19844
0
    return(-1);
19845
0
      }
19846
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
19847
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
19848
0
    NULL, WXS_BASIC_CAST use,
19849
0
    "The value of the value constraint is not valid",
19850
0
    NULL, NULL);
19851
0
      return(ctxt->err);
19852
0
  }
19853
0
    }
19854
    /*
19855
    * SPEC au-props-correct (2)
19856
    * "If the {attribute declaration} has a fixed
19857
    * {value constraint}, then if the attribute use itself has a
19858
    * {value constraint}, it must also be fixed and its value must match
19859
    * that of the {attribute declaration}'s {value constraint}."
19860
    */
19861
0
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
19862
0
  (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
19863
0
    {
19864
0
  if (! xmlSchemaAreValuesEqual(use->defVal,
19865
0
    (WXS_ATTRUSE_DECL(use))->defVal))
19866
0
  {
19867
0
      xmlSchemaPCustomErr(ctxt,
19868
0
    XML_SCHEMAP_AU_PROPS_CORRECT_2,
19869
0
    WXS_BASIC_CAST use, NULL,
19870
0
    "The 'fixed' value constraint of the attribute use "
19871
0
    "must match the attribute declaration's value "
19872
0
    "constraint '%s'",
19873
0
    (WXS_ATTRUSE_DECL(use))->defValue);
19874
0
  }
19875
0
  return(ctxt->err);
19876
0
    }
19877
0
    return(0);
19878
0
}
19879
19880
19881
19882
19883
/**
19884
 * Resolves the referenced type definition component.
19885
 *
19886
 * @param item  an attribute declaration
19887
 * @param ctxt  a parser context
19888
 */
19889
static int
19890
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
19891
           xmlSchemaParserCtxtPtr ctxt)
19892
0
{
19893
    /*
19894
    * The simple type definition corresponding to the <simpleType> element
19895
    * information item in the [children], if present, otherwise the simple
19896
    * type definition `resolved` to by the `actual value` of the type
19897
    * [attribute], if present, otherwise the `simple ur-type definition`.
19898
    */
19899
0
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
19900
0
  return(0);
19901
0
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
19902
0
    if (item->subtypes != NULL)
19903
0
        return(0);
19904
0
    if (item->typeName != NULL) {
19905
0
        xmlSchemaTypePtr type;
19906
19907
0
  type = xmlSchemaGetType(ctxt->schema, item->typeName,
19908
0
      item->typeNs);
19909
0
  if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
19910
0
      xmlSchemaPResCompAttrErr(ctxt,
19911
0
    XML_SCHEMAP_SRC_RESOLVE,
19912
0
    WXS_BASIC_CAST item, item->node,
19913
0
    "type", item->typeName, item->typeNs,
19914
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
19915
0
      return(ctxt->err);
19916
0
  } else
19917
0
      item->subtypes = type;
19918
19919
0
    } else {
19920
  /*
19921
  * The type defaults to the xs:anySimpleType.
19922
  */
19923
0
  item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
19924
0
    }
19925
0
    return(0);
19926
0
}
19927
19928
/**
19929
 * Resolve keyRef references to key/unique IDCs.
19930
 * Schema Component Constraint:
19931
 *   Identity-constraint Definition Properties Correct (c-props-correct)
19932
 *
19933
 * @param idc  the identity-constraint definition
19934
 * @param pctxt  the schema parser context
19935
 */
19936
static int
19937
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
19938
        xmlSchemaParserCtxtPtr pctxt)
19939
0
{
19940
0
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
19941
0
        return(0);
19942
0
    if (idc->ref->name != NULL) {
19943
0
  idc->ref->item = (xmlSchemaBasicItemPtr)
19944
0
      xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
19945
0
    idc->ref->targetNamespace);
19946
0
        if (idc->ref->item == NULL) {
19947
      /*
19948
      * TODO: It is actually not an error to fail to resolve
19949
      * at this stage. BUT we need to be that strict!
19950
      */
19951
0
      xmlSchemaPResCompAttrErr(pctxt,
19952
0
    XML_SCHEMAP_SRC_RESOLVE,
19953
0
    WXS_BASIC_CAST idc, idc->node,
19954
0
    "refer", idc->ref->name,
19955
0
    idc->ref->targetNamespace,
19956
0
    XML_SCHEMA_TYPE_IDC_KEY, NULL);
19957
0
            return(pctxt->err);
19958
0
  } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
19959
      /*
19960
      * SPEC c-props-correct (1)
19961
      */
19962
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19963
0
    XML_SCHEMAP_C_PROPS_CORRECT,
19964
0
    NULL, WXS_BASIC_CAST idc,
19965
0
    "The keyref references a keyref",
19966
0
    NULL, NULL);
19967
0
      idc->ref->item = NULL;
19968
0
      return(pctxt->err);
19969
0
  } else {
19970
0
      if (idc->nbFields !=
19971
0
    ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
19972
0
    xmlChar *str = NULL;
19973
0
    xmlSchemaIDCPtr refer;
19974
19975
0
    refer = (xmlSchemaIDCPtr) idc->ref->item;
19976
    /*
19977
    * SPEC c-props-correct(2)
19978
    * "If the {identity-constraint category} is keyref,
19979
    * the cardinality of the {fields} must equal that of
19980
    * the {fields} of the {referenced key}.
19981
    */
19982
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
19983
0
        XML_SCHEMAP_C_PROPS_CORRECT,
19984
0
        NULL, WXS_BASIC_CAST idc,
19985
0
        "The cardinality of the keyref differs from the "
19986
0
        "cardinality of the referenced key/unique '%s'",
19987
0
        xmlSchemaFormatQName(&str, refer->targetNamespace,
19988
0
      refer->name),
19989
0
        NULL);
19990
0
    FREE_AND_NULL(str)
19991
0
    return(pctxt->err);
19992
0
      }
19993
0
  }
19994
0
    }
19995
0
    return(0);
19996
0
}
19997
19998
static int
19999
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20000
               xmlSchemaParserCtxtPtr pctxt)
20001
0
{
20002
0
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20003
0
  prohib->targetNamespace) == NULL) {
20004
20005
0
  xmlSchemaPResCompAttrErr(pctxt,
20006
0
      XML_SCHEMAP_SRC_RESOLVE,
20007
0
      NULL, prohib->node,
20008
0
      "ref", prohib->name, prohib->targetNamespace,
20009
0
      XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20010
0
  return(XML_SCHEMAP_SRC_RESOLVE);
20011
0
    }
20012
0
    return(0);
20013
0
}
20014
20015
0
#define WXS_REDEFINED_TYPE(c) \
20016
0
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20017
20018
0
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20019
0
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20020
20021
0
#define WXS_REDEFINED_ATTR_GROUP(c) \
20022
0
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20023
20024
static int
20025
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20026
0
{
20027
0
    int err = 0;
20028
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20029
0
    xmlSchemaBasicItemPtr prev, item;
20030
0
    int wasRedefined;
20031
20032
0
    if (redef == NULL)
20033
0
  return(0);
20034
20035
0
    do {
20036
0
  item = redef->item;
20037
  /*
20038
  * First try to locate the redefined component in the
20039
  * schema graph starting with the redefined schema.
20040
  * NOTE: According to this schema bug entry:
20041
  *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20042
  *   it's not clear if the referenced component needs to originate
20043
  *   from the <redefine>d schema _document_ or the schema; the latter
20044
  *   would include all imported and included sub-schemas of the
20045
  *   <redefine>d schema. Currently the latter approach is used.
20046
  *   SUPPLEMENT: It seems that the WG moves towards the latter
20047
  *   approach, so we are doing it right.
20048
  *
20049
  */
20050
0
  prev = xmlSchemaFindRedefCompInGraph(
20051
0
      redef->targetBucket, item->type,
20052
0
      redef->refName, redef->refTargetNs);
20053
0
  if (prev == NULL) {
20054
0
      xmlChar *str = NULL;
20055
0
      xmlNodePtr node;
20056
20057
      /*
20058
      * SPEC src-redefine:
20059
      * (6.2.1) "The `actual value` of its own name attribute plus
20060
      * target namespace must successfully `resolve` to a model
20061
      * group definition in I."
20062
      * (7.2.1) "The `actual value` of its own name attribute plus
20063
      * target namespace must successfully `resolve` to an attribute
20064
      * group definition in I."
20065
20066
      *
20067
      * Note that, if we are redefining with the use of references
20068
      * to components, the spec assumes the src-resolve to be used;
20069
      * but this won't assure that we search only *inside* the
20070
      * redefined schema.
20071
      */
20072
0
      if (redef->reference)
20073
0
    node = WXS_ITEM_NODE(redef->reference);
20074
0
      else
20075
0
    node = WXS_ITEM_NODE(item);
20076
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20077
    /*
20078
    * TODO: error code.
20079
    * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20080
    * reference kind.
20081
    */
20082
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20083
0
    "The %s '%s' to be redefined could not be found in "
20084
0
    "the redefined schema",
20085
0
    WXS_ITEM_TYPE_NAME(item),
20086
0
    xmlSchemaFormatQName(&str, redef->refTargetNs,
20087
0
        redef->refName));
20088
0
      FREE_AND_NULL(str);
20089
0
      err = pctxt->err;
20090
0
      redef = redef->next;
20091
0
      continue;
20092
0
  }
20093
  /*
20094
  * TODO: Obtaining and setting the redefinition state is really
20095
  * clumsy.
20096
  */
20097
0
  wasRedefined = 0;
20098
0
  switch (item->type) {
20099
0
      case XML_SCHEMA_TYPE_COMPLEX:
20100
0
      case XML_SCHEMA_TYPE_SIMPLE:
20101
0
    if ((WXS_TYPE_CAST prev)->flags &
20102
0
        XML_SCHEMAS_TYPE_REDEFINED)
20103
0
    {
20104
0
        wasRedefined = 1;
20105
0
        break;
20106
0
    }
20107
    /* Mark it as redefined. */
20108
0
    (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20109
    /*
20110
    * Assign the redefined type to the
20111
    * base type of the redefining type.
20112
    * TODO: How
20113
    */
20114
0
    ((xmlSchemaTypePtr) item)->baseType =
20115
0
        (xmlSchemaTypePtr) prev;
20116
0
    break;
20117
0
      case XML_SCHEMA_TYPE_GROUP:
20118
0
    if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20119
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20120
0
    {
20121
0
        wasRedefined = 1;
20122
0
        break;
20123
0
    }
20124
    /* Mark it as redefined. */
20125
0
    (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20126
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20127
0
    if (redef->reference != NULL) {
20128
        /*
20129
        * Overwrite the QName-reference with the
20130
        * referenced model group def.
20131
        */
20132
0
        (WXS_PTC_CAST redef->reference)->children =
20133
0
      WXS_TREE_CAST prev;
20134
0
    }
20135
0
    redef->target = prev;
20136
0
    break;
20137
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20138
0
    if ((WXS_ATTR_GROUP_CAST prev)->flags &
20139
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED)
20140
0
    {
20141
0
        wasRedefined = 1;
20142
0
        break;
20143
0
    }
20144
0
    (WXS_ATTR_GROUP_CAST prev)->flags |=
20145
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED;
20146
0
    if (redef->reference != NULL) {
20147
        /*
20148
        * Assign the redefined attribute group to the
20149
        * QName-reference component.
20150
        * This is the easy case, since we will just
20151
        * expand the redefined group.
20152
        */
20153
0
        (WXS_QNAME_CAST redef->reference)->item = prev;
20154
0
        redef->target = NULL;
20155
0
    } else {
20156
        /*
20157
        * This is the complicated case: we need
20158
        * to apply src-redefine (7.2.2) at a later
20159
        * stage, i.e. when attribute group references
20160
        * have been expanded and simple types have
20161
        * been fixed.
20162
        */
20163
0
        redef->target = prev;
20164
0
    }
20165
0
    break;
20166
0
      default:
20167
0
    PERROR_INT("xmlSchemaResolveRedefReferences",
20168
0
        "Unexpected redefined component type");
20169
0
    return(-1);
20170
0
  }
20171
0
  if (wasRedefined) {
20172
0
      xmlChar *str = NULL;
20173
0
      xmlNodePtr node;
20174
20175
0
      if (redef->reference)
20176
0
    node = WXS_ITEM_NODE(redef->reference);
20177
0
      else
20178
0
    node = WXS_ITEM_NODE(redef->item);
20179
20180
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20181
    /* TODO: error code. */
20182
0
    XML_SCHEMAP_SRC_REDEFINE,
20183
0
    node, NULL,
20184
0
    "The referenced %s was already redefined. Multiple "
20185
0
    "redefinition of the same component is not supported",
20186
0
    xmlSchemaGetComponentDesignation(&str, prev),
20187
0
    NULL);
20188
0
      FREE_AND_NULL(str)
20189
0
      err = pctxt->err;
20190
0
      redef = redef->next;
20191
0
      continue;
20192
0
  }
20193
0
  redef = redef->next;
20194
0
    } while (redef != NULL);
20195
20196
0
    return(err);
20197
0
}
20198
20199
static int
20200
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20201
0
{
20202
0
    int err = 0;
20203
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20204
0
    xmlSchemaBasicItemPtr item;
20205
20206
0
    if (redef == NULL)
20207
0
  return(0);
20208
20209
0
    do {
20210
0
  if (redef->target == NULL) {
20211
0
      redef = redef->next;
20212
0
      continue;
20213
0
  }
20214
0
  item = redef->item;
20215
20216
0
  switch (item->type) {
20217
0
      case XML_SCHEMA_TYPE_SIMPLE:
20218
0
      case XML_SCHEMA_TYPE_COMPLEX:
20219
    /*
20220
    * Since the spec wants the {name} of the redefined
20221
    * type to be 'absent', we'll NULL it.
20222
    */
20223
0
    (WXS_TYPE_CAST redef->target)->name = NULL;
20224
20225
    /*
20226
    * TODO: Seems like there's nothing more to do. The normal
20227
    * inheritance mechanism is used. But not 100% sure.
20228
    */
20229
0
    break;
20230
0
      case XML_SCHEMA_TYPE_GROUP:
20231
    /*
20232
    * URGENT TODO:
20233
    * SPEC src-redefine:
20234
    * (6.2.2) "The {model group} of the model group definition
20235
    * which corresponds to it per XML Representation of Model
20236
    * Group Definition Schema Components ($3.7.2) must be a
20237
    * `valid restriction` of the {model group} of that model
20238
    * group definition in I, as defined in Particle Valid
20239
    * (Restriction) ($3.9.6)."
20240
    */
20241
0
    break;
20242
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20243
    /*
20244
    * SPEC src-redefine:
20245
    * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20246
    * the attribute group definition which corresponds to it
20247
    * per XML Representation of Attribute Group Definition Schema
20248
    * Components ($3.6.2) must be `valid restrictions` of the
20249
    * {attribute uses} and {attribute wildcard} of that attribute
20250
    * group definition in I, as defined in clause 2, clause 3 and
20251
    * clause 4 of Derivation Valid (Restriction, Complex)
20252
    * ($3.4.6) (where references to the base type definition are
20253
    * understood as references to the attribute group definition
20254
    * in I)."
20255
    */
20256
0
    err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20257
0
        XML_SCHEMA_ACTION_REDEFINE,
20258
0
        item, redef->target,
20259
0
        (WXS_ATTR_GROUP_CAST item)->attrUses,
20260
0
        (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20261
0
        (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20262
0
        (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20263
0
    if (err == -1)
20264
0
        return(-1);
20265
0
    break;
20266
0
      default:
20267
0
    break;
20268
0
  }
20269
0
  redef = redef->next;
20270
0
    } while (redef != NULL);
20271
0
    return(0);
20272
0
}
20273
20274
20275
static int
20276
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20277
           xmlSchemaBucketPtr bucket)
20278
0
{
20279
0
    xmlSchemaBasicItemPtr item;
20280
0
    int err;
20281
0
    xmlHashTablePtr *table;
20282
0
    const xmlChar *name;
20283
0
    int i;
20284
20285
0
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20286
0
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20287
0
  table = &(WXS_IMPBUCKET((c))->schema->slot); \
20288
0
    else \
20289
0
  table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20290
20291
    /*
20292
    * Add global components to the schema's hash tables.
20293
    * This is the place where duplicate components will be
20294
    * detected.
20295
    * TODO: I think normally we should support imports of the
20296
    *   same namespace from multiple locations. We don't do currently,
20297
    *   but if we do then according to:
20298
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20299
    *   we would need, if imported directly, to import redefined
20300
    *   components as well to be able to catch clashing components.
20301
    *   (I hope I'll still know what this means after some months :-()
20302
    */
20303
0
    if (bucket == NULL)
20304
0
  return(-1);
20305
0
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20306
0
  return(0);
20307
0
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20308
20309
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
20310
0
  item = bucket->globals->items[i];
20311
0
  table = NULL;
20312
0
  switch (item->type) {
20313
0
      case XML_SCHEMA_TYPE_COMPLEX:
20314
0
      case XML_SCHEMA_TYPE_SIMPLE:
20315
0
    if (WXS_REDEFINED_TYPE(item))
20316
0
        continue;
20317
0
    name = (WXS_TYPE_CAST item)->name;
20318
0
    WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20319
0
    break;
20320
0
      case XML_SCHEMA_TYPE_ELEMENT:
20321
0
    name = (WXS_ELEM_CAST item)->name;
20322
0
    WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20323
0
    break;
20324
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20325
0
    name = (WXS_ATTR_CAST item)->name;
20326
0
    WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20327
0
    break;
20328
0
      case XML_SCHEMA_TYPE_GROUP:
20329
0
    if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20330
0
        continue;
20331
0
    name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20332
0
    WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20333
0
    break;
20334
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20335
0
    if (WXS_REDEFINED_ATTR_GROUP(item))
20336
0
        continue;
20337
0
    name = (WXS_ATTR_GROUP_CAST item)->name;
20338
0
    WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20339
0
    break;
20340
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20341
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20342
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20343
0
    name = (WXS_IDC_CAST item)->name;
20344
0
    WXS_GET_GLOBAL_HASH(bucket, idcDef)
20345
0
    break;
20346
0
      case XML_SCHEMA_TYPE_NOTATION:
20347
0
    name = ((xmlSchemaNotationPtr) item)->name;
20348
0
    WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20349
0
    break;
20350
0
      default:
20351
0
    PERROR_INT("xmlSchemaAddComponents",
20352
0
        "Unexpected global component type");
20353
0
    continue;
20354
0
  }
20355
0
  if (*table == NULL) {
20356
0
      *table = xmlHashCreateDict(10, pctxt->dict);
20357
0
      if (*table == NULL) {
20358
0
    PERROR_INT("xmlSchemaAddComponents",
20359
0
        "failed to create a component hash table");
20360
0
    return(-1);
20361
0
      }
20362
0
  }
20363
0
  err = xmlHashAddEntry(*table, name, item);
20364
0
  if (err != 0) {
20365
0
      xmlChar *str = NULL;
20366
20367
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20368
0
    XML_SCHEMAP_REDEFINED_TYPE,
20369
0
    WXS_ITEM_NODE(item),
20370
0
    WXS_BASIC_CAST item,
20371
0
    "A global %s '%s' does already exist",
20372
0
    WXS_ITEM_TYPE_NAME(item),
20373
0
    xmlSchemaGetComponentQName(&str, item));
20374
0
      FREE_AND_NULL(str);
20375
0
  }
20376
0
    }
20377
    /*
20378
    * Process imported/included schemas.
20379
    */
20380
0
    if (bucket->relations != NULL) {
20381
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
20382
0
  do {
20383
0
      if ((rel->bucket != NULL) &&
20384
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20385
0
    if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20386
0
        return(-1);
20387
0
      }
20388
0
      rel = rel->next;
20389
0
  } while (rel != NULL);
20390
0
    }
20391
0
    return(0);
20392
0
}
20393
20394
static int
20395
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20396
       xmlSchemaBucketPtr rootBucket)
20397
0
{
20398
0
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20399
0
    xmlSchemaTreeItemPtr item, *items;
20400
0
    int nbItems, i, ret = 0;
20401
0
    xmlSchemaBucketPtr oldbucket = con->bucket;
20402
0
    xmlSchemaElementPtr elemDecl;
20403
20404
0
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20405
20406
0
    if ((con->pending == NULL) ||
20407
0
  (con->pending->nbItems == 0))
20408
0
  return(0);
20409
20410
    /*
20411
    * Since xmlSchemaFixupComplexType() will create new particles
20412
    * (local components), and those particle components need a bucket
20413
    * on the constructor, we'll assure here that the constructor has
20414
    * a bucket.
20415
    * TODO: Think about storing locals _only_ on the main bucket.
20416
    */
20417
0
    if (con->bucket == NULL)
20418
0
  con->bucket = rootBucket;
20419
20420
    /* TODO:
20421
    * SPEC (src-redefine):
20422
    * (6.2) "If it has no such self-reference, then all of the
20423
    * following must be true:"
20424
20425
    * (6.2.2) The {model group} of the model group definition which
20426
    * corresponds to it per XML Representation of Model Group
20427
    * Definition Schema Components ($3.7.2) must be a `valid
20428
    * restriction` of the {model group} of that model group definition
20429
    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20430
    */
20431
0
    xmlSchemaCheckSRCRedefineFirst(pctxt);
20432
20433
    /*
20434
    * Add global components to the schemata's hash tables.
20435
    */
20436
0
    xmlSchemaAddComponents(pctxt, rootBucket);
20437
20438
0
    pctxt->ctxtType = NULL;
20439
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
20440
0
    nbItems = con->pending->nbItems;
20441
    /*
20442
    * Now that we have parsed *all* the schema document(s) and converted
20443
    * them to schema components, we can resolve references, apply component
20444
    * constraints, create the FSA from the content model, etc.
20445
    */
20446
    /*
20447
    * Resolve references of..
20448
    *
20449
    * 1. element declarations:
20450
    *   - the type definition
20451
    *   - the substitution group affiliation
20452
    * 2. simple/complex types:
20453
    *   - the base type definition
20454
    *   - the memberTypes of union types
20455
    *   - the itemType of list types
20456
    * 3. attributes declarations and attribute uses:
20457
    *   - the type definition
20458
    *   - if an attribute use, then the attribute declaration
20459
    * 4. attribute group references:
20460
    *   - the attribute group definition
20461
    * 5. particles:
20462
    *   - the term of the particle (e.g. a model group)
20463
    * 6. IDC key-references:
20464
    *   - the referenced IDC 'key' or 'unique' definition
20465
    * 7. Attribute prohibitions which had a "ref" attribute.
20466
    */
20467
0
    for (i = 0; i < nbItems; i++) {
20468
0
  item = items[i];
20469
0
  switch (item->type) {
20470
0
      case XML_SCHEMA_TYPE_ELEMENT:
20471
0
    xmlSchemaResolveElementReferences(
20472
0
        (xmlSchemaElementPtr) item, pctxt);
20473
0
    FIXHFAILURE;
20474
0
    break;
20475
0
      case XML_SCHEMA_TYPE_COMPLEX:
20476
0
      case XML_SCHEMA_TYPE_SIMPLE:
20477
0
    xmlSchemaResolveTypeReferences(
20478
0
        (xmlSchemaTypePtr) item, pctxt);
20479
0
    FIXHFAILURE;
20480
0
    break;
20481
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20482
0
    xmlSchemaResolveAttrTypeReferences(
20483
0
        (xmlSchemaAttributePtr) item, pctxt);
20484
0
    FIXHFAILURE;
20485
0
    break;
20486
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20487
0
    xmlSchemaResolveAttrUseReferences(
20488
0
        (xmlSchemaAttributeUsePtr) item, pctxt);
20489
0
    FIXHFAILURE;
20490
0
    break;
20491
0
      case XML_SCHEMA_EXTRA_QNAMEREF:
20492
0
    if ((WXS_QNAME_CAST item)->itemType ==
20493
0
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20494
0
    {
20495
0
        xmlSchemaResolveAttrGroupReferences(
20496
0
      WXS_QNAME_CAST item, pctxt);
20497
0
    }
20498
0
    FIXHFAILURE;
20499
0
    break;
20500
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20501
0
      case XML_SCHEMA_TYPE_CHOICE:
20502
0
      case XML_SCHEMA_TYPE_ALL:
20503
0
    xmlSchemaResolveModelGroupParticleReferences(pctxt,
20504
0
        WXS_MODEL_GROUP_CAST item);
20505
0
    FIXHFAILURE;
20506
0
    break;
20507
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20508
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20509
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20510
0
    xmlSchemaResolveIDCKeyReferences(
20511
0
        (xmlSchemaIDCPtr) item, pctxt);
20512
0
    FIXHFAILURE;
20513
0
    break;
20514
0
      case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20515
    /*
20516
    * Handle attribute prohibition which had a
20517
    * "ref" attribute.
20518
    */
20519
0
    xmlSchemaResolveAttrUseProhibReferences(
20520
0
        WXS_ATTR_PROHIB_CAST item, pctxt);
20521
0
    FIXHFAILURE;
20522
0
    break;
20523
0
      default:
20524
0
    break;
20525
0
  }
20526
0
    }
20527
0
    if (pctxt->nberrors != 0)
20528
0
  goto exit_error;
20529
20530
    /*
20531
    * Now that all references are resolved we
20532
    * can check for circularity of...
20533
    * 1. the base axis of type definitions
20534
    * 2. nested model group definitions
20535
    * 3. nested attribute group definitions
20536
    * TODO: check for circular substitution groups.
20537
    */
20538
0
    for (i = 0; i < nbItems; i++) {
20539
0
  item = items[i];
20540
  /*
20541
  * Let's better stop on the first error here.
20542
  */
20543
0
  switch (item->type) {
20544
0
      case XML_SCHEMA_TYPE_COMPLEX:
20545
0
      case XML_SCHEMA_TYPE_SIMPLE:
20546
0
    xmlSchemaCheckTypeDefCircular(
20547
0
        (xmlSchemaTypePtr) item, pctxt);
20548
0
    FIXHFAILURE;
20549
0
    if (pctxt->nberrors != 0)
20550
0
        goto exit_error;
20551
0
    break;
20552
0
      case XML_SCHEMA_TYPE_GROUP:
20553
0
    xmlSchemaCheckGroupDefCircular(
20554
0
        (xmlSchemaModelGroupDefPtr) item, pctxt);
20555
0
    FIXHFAILURE;
20556
0
    if (pctxt->nberrors != 0)
20557
0
        goto exit_error;
20558
0
    break;
20559
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20560
0
    xmlSchemaCheckAttrGroupCircular(
20561
0
        (xmlSchemaAttributeGroupPtr) item, pctxt);
20562
0
    FIXHFAILURE;
20563
0
    if (pctxt->nberrors != 0)
20564
0
        goto exit_error;
20565
0
    break;
20566
0
      default:
20567
0
    break;
20568
0
  }
20569
0
    }
20570
0
    if (pctxt->nberrors != 0)
20571
0
  goto exit_error;
20572
    /*
20573
    * Model group definition references:
20574
    * Such a reference is reflected by a particle at the component
20575
    * level. Until now the 'term' of such particles pointed
20576
    * to the model group definition; this was done, in order to
20577
    * ease circularity checks. Now we need to set the 'term' of
20578
    * such particles to the model group of the model group definition.
20579
    */
20580
0
    for (i = 0; i < nbItems; i++) {
20581
0
  item = items[i];
20582
0
  switch (item->type) {
20583
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20584
0
      case XML_SCHEMA_TYPE_CHOICE:
20585
0
    xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20586
0
        WXS_MODEL_GROUP_CAST item);
20587
0
    break;
20588
0
      default:
20589
0
    break;
20590
0
  }
20591
0
    }
20592
0
    if (pctxt->nberrors != 0)
20593
0
  goto exit_error;
20594
    /*
20595
    * Expand attribute group references of attribute group definitions.
20596
    */
20597
0
    for (i = 0; i < nbItems; i++) {
20598
0
  item = items[i];
20599
0
  switch (item->type) {
20600
0
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20601
0
    if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20602
0
        WXS_ATTR_GROUP_HAS_REFS(item))
20603
0
    {
20604
0
        xmlSchemaAttributeGroupExpandRefs(pctxt,
20605
0
      WXS_ATTR_GROUP_CAST item);
20606
0
        FIXHFAILURE;
20607
0
    }
20608
0
    break;
20609
0
      default:
20610
0
    break;
20611
0
  }
20612
0
    }
20613
0
    if (pctxt->nberrors != 0)
20614
0
  goto exit_error;
20615
    /*
20616
    * First compute the variety of simple types. This is needed as
20617
    * a separate step, since otherwise we won't be able to detect
20618
    * circular union types in all cases.
20619
    */
20620
0
    for (i = 0; i < nbItems; i++) {
20621
0
  item = items[i];
20622
0
  switch (item->type) {
20623
0
            case XML_SCHEMA_TYPE_SIMPLE:
20624
0
    if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
20625
0
        xmlSchemaFixupSimpleTypeStageOne(pctxt,
20626
0
      (xmlSchemaTypePtr) item);
20627
0
        FIXHFAILURE;
20628
0
    }
20629
0
    break;
20630
0
      default:
20631
0
    break;
20632
0
  }
20633
0
    }
20634
0
    if (pctxt->nberrors != 0)
20635
0
  goto exit_error;
20636
    /*
20637
    * Detect circular union types. Note that this needs the variety to
20638
    * be already computed.
20639
    */
20640
0
    for (i = 0; i < nbItems; i++) {
20641
0
  item = items[i];
20642
0
  switch (item->type) {
20643
0
            case XML_SCHEMA_TYPE_SIMPLE:
20644
0
    if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
20645
0
        xmlSchemaCheckUnionTypeDefCircular(pctxt,
20646
0
      (xmlSchemaTypePtr) item);
20647
0
        FIXHFAILURE;
20648
0
    }
20649
0
    break;
20650
0
      default:
20651
0
    break;
20652
0
  }
20653
0
    }
20654
0
    if (pctxt->nberrors != 0)
20655
0
  goto exit_error;
20656
20657
    /*
20658
    * Do the complete type fixup for simple types.
20659
    */
20660
0
    for (i = 0; i < nbItems; i++) {
20661
0
  item = items[i];
20662
0
  switch (item->type) {
20663
0
            case XML_SCHEMA_TYPE_SIMPLE:
20664
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
20665
0
        xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
20666
0
        FIXHFAILURE;
20667
0
    }
20668
0
    break;
20669
0
      default:
20670
0
    break;
20671
0
  }
20672
0
    }
20673
0
    if (pctxt->nberrors != 0)
20674
0
  goto exit_error;
20675
    /*
20676
    * At this point we need build and check all simple types.
20677
    */
20678
    /*
20679
    * Apply constraints for attribute declarations.
20680
    */
20681
0
    for (i = 0; i < nbItems; i++) {
20682
0
  item = items[i];
20683
0
  switch (item->type) {
20684
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20685
0
    xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
20686
0
    FIXHFAILURE;
20687
0
    break;
20688
0
      default:
20689
0
    break;
20690
0
  }
20691
0
    }
20692
0
    if (pctxt->nberrors != 0)
20693
0
  goto exit_error;
20694
    /*
20695
    * Apply constraints for attribute uses.
20696
    */
20697
0
    for (i = 0; i < nbItems; i++) {
20698
0
  item = items[i];
20699
0
  switch (item->type) {
20700
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20701
0
    if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
20702
0
        xmlSchemaCheckAttrUsePropsCorrect(pctxt,
20703
0
      WXS_ATTR_USE_CAST item);
20704
0
        FIXHFAILURE;
20705
0
    }
20706
0
    break;
20707
0
      default:
20708
0
    break;
20709
0
  }
20710
0
    }
20711
0
    if (pctxt->nberrors != 0)
20712
0
  goto exit_error;
20713
20714
    /*
20715
    * Apply constraints for attribute group definitions.
20716
    */
20717
0
    for (i = 0; i < nbItems; i++) {
20718
0
  item = items[i];
20719
0
  switch (item->type) {
20720
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20721
0
      if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
20722
0
    ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
20723
0
      {
20724
0
    xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
20725
0
    FIXHFAILURE;
20726
0
      }
20727
0
      break;
20728
0
  default:
20729
0
      break;
20730
0
  }
20731
0
    }
20732
0
    if (pctxt->nberrors != 0)
20733
0
  goto exit_error;
20734
20735
    /*
20736
    * Apply constraints for redefinitions.
20737
    */
20738
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
20739
0
  xmlSchemaCheckSRCRedefineSecond(pctxt);
20740
0
    if (pctxt->nberrors != 0)
20741
0
  goto exit_error;
20742
20743
    /*
20744
    * Complex types are built and checked.
20745
    */
20746
0
    for (i = 0; i < nbItems; i++) {
20747
0
  item = con->pending->items[i];
20748
0
  switch (item->type) {
20749
0
      case XML_SCHEMA_TYPE_COMPLEX:
20750
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
20751
0
        xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
20752
0
        FIXHFAILURE;
20753
0
    }
20754
0
    break;
20755
0
      default:
20756
0
    break;
20757
0
  }
20758
0
    }
20759
0
    if (pctxt->nberrors != 0)
20760
0
  goto exit_error;
20761
20762
    /*
20763
    * The list could have changed, since xmlSchemaFixupComplexType()
20764
    * will create particles and model groups in some cases.
20765
    */
20766
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
20767
0
    nbItems = con->pending->nbItems;
20768
20769
    /*
20770
    * Apply some constraints for element declarations.
20771
    */
20772
0
    for (i = 0; i < nbItems; i++) {
20773
0
  item = items[i];
20774
0
  switch (item->type) {
20775
0
      case XML_SCHEMA_TYPE_ELEMENT:
20776
0
    elemDecl = (xmlSchemaElementPtr) item;
20777
20778
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
20779
0
    {
20780
0
        xmlSchemaCheckElementDeclComponent(
20781
0
      (xmlSchemaElementPtr) elemDecl, pctxt);
20782
0
        FIXHFAILURE;
20783
0
    }
20784
20785
#ifdef WXS_ELEM_DECL_CONS_ENABLED
20786
    /*
20787
    * Schema Component Constraint: Element Declarations Consistent
20788
    * Apply this constraint to local types of element declarations.
20789
    */
20790
    if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
20791
        (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
20792
        (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
20793
    {
20794
        xmlSchemaCheckElementDeclConsistent(pctxt,
20795
      WXS_BASIC_CAST elemDecl,
20796
      WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
20797
      NULL, NULL, 0);
20798
    }
20799
#endif
20800
0
    break;
20801
0
      default:
20802
0
    break;
20803
0
  }
20804
0
    }
20805
0
    if (pctxt->nberrors != 0)
20806
0
  goto exit_error;
20807
20808
    /*
20809
    * Finally we can build the automaton from the content model of
20810
    * complex types.
20811
    */
20812
20813
0
    for (i = 0; i < nbItems; i++) {
20814
0
  item = items[i];
20815
0
  switch (item->type) {
20816
0
      case XML_SCHEMA_TYPE_COMPLEX:
20817
0
    xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
20818
    /* FIXHFAILURE; */
20819
0
    break;
20820
0
      default:
20821
0
    break;
20822
0
  }
20823
0
    }
20824
0
    if (pctxt->nberrors != 0)
20825
0
  goto exit_error;
20826
    /*
20827
    * URGENT TODO: cos-element-consistent
20828
    */
20829
0
    goto exit;
20830
20831
0
exit_error:
20832
0
    ret = pctxt->err;
20833
0
    goto exit;
20834
20835
0
exit_failure:
20836
0
    ret = -1;
20837
20838
0
exit:
20839
    /*
20840
    * Reset the constructor. This is needed for XSI acquisition, since
20841
    * those items will be processed over and over again for every XSI
20842
    * if not cleared here.
20843
    */
20844
0
    con->bucket = oldbucket;
20845
0
    con->pending->nbItems = 0;
20846
0
    if (con->substGroups != NULL) {
20847
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
20848
0
  con->substGroups = NULL;
20849
0
    }
20850
0
    if (con->redefs != NULL) {
20851
0
  xmlSchemaRedefListFree(con->redefs);
20852
0
  con->redefs = NULL;
20853
0
    }
20854
0
    return(ret);
20855
0
}
20856
/**
20857
 * parse a schema definition resource and build an internal
20858
 * XML Schema structure which can be used to validate instances.
20859
 *
20860
 * @param ctxt  a schema validation context
20861
 * @returns the internal XML Schema structure built from the resource or
20862
 *         NULL in case of error
20863
 */
20864
xmlSchema *
20865
xmlSchemaParse(xmlSchemaParserCtxt *ctxt)
20866
0
{
20867
0
    xmlSchemaPtr mainSchema = NULL;
20868
0
    xmlSchemaBucketPtr bucket = NULL;
20869
0
    int res;
20870
20871
    /*
20872
    * This one is used if the schema to be parsed was specified via
20873
    * the API; i.e. not automatically by the validated instance document.
20874
    */
20875
20876
0
    if (xmlSchemaInitTypes() < 0)
20877
0
        return (NULL);
20878
20879
0
    if (ctxt == NULL)
20880
0
        return (NULL);
20881
20882
    /* TODO: Init the context. Is this all we need?*/
20883
0
    ctxt->nberrors = 0;
20884
0
    ctxt->err = 0;
20885
0
    ctxt->counter = 0;
20886
20887
    /* Create the *main* schema. */
20888
0
    mainSchema = xmlSchemaNewSchema(ctxt);
20889
0
    if (mainSchema == NULL)
20890
0
  goto exit_failure;
20891
    /*
20892
    * Create the schema constructor.
20893
    */
20894
0
    if (ctxt->constructor == NULL) {
20895
0
  ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
20896
0
  if (ctxt->constructor == NULL)
20897
0
      goto exit_failure;
20898
  /* Take ownership of the constructor to be able to free it. */
20899
0
  ctxt->ownsConstructor = 1;
20900
0
    }
20901
0
    ctxt->constructor->mainSchema = mainSchema;
20902
    /*
20903
    * Locate and add the schema document.
20904
    */
20905
0
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
20906
0
  ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
20907
0
  NULL, NULL, &bucket);
20908
0
    if (res == -1)
20909
0
  goto exit_failure;
20910
0
    if (res != 0)
20911
0
  goto exit;
20912
20913
0
    if (bucket == NULL) {
20914
  /* TODO: Error code, actually we failed to *locate* the schema. */
20915
0
  if (ctxt->URL)
20916
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
20917
0
    NULL, NULL,
20918
0
    "Failed to locate the main schema resource at '%s'",
20919
0
    ctxt->URL, NULL);
20920
0
  else
20921
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
20922
0
    NULL, NULL,
20923
0
    "Failed to locate the main schema resource",
20924
0
        NULL, NULL);
20925
0
  goto exit;
20926
0
    }
20927
    /* Then do the parsing for good. */
20928
0
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
20929
0
  goto exit_failure;
20930
0
    if (ctxt->nberrors != 0)
20931
0
  goto exit;
20932
20933
0
    mainSchema->doc = bucket->doc;
20934
0
    mainSchema->preserve = ctxt->preserve;
20935
20936
0
    ctxt->schema = mainSchema;
20937
20938
0
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
20939
0
  goto exit_failure;
20940
20941
    /*
20942
    * TODO: This is not nice, since we cannot distinguish from the
20943
    * result if there was an internal error or not.
20944
    */
20945
0
exit:
20946
0
    if (ctxt->nberrors != 0) {
20947
0
  if (mainSchema) {
20948
0
      xmlSchemaFree(mainSchema);
20949
0
      mainSchema = NULL;
20950
0
  }
20951
0
  if (ctxt->constructor) {
20952
0
      xmlSchemaConstructionCtxtFree(ctxt->constructor);
20953
0
      ctxt->constructor = NULL;
20954
0
      ctxt->ownsConstructor = 0;
20955
0
  }
20956
0
    }
20957
0
    ctxt->schema = NULL;
20958
0
    return(mainSchema);
20959
0
exit_failure:
20960
    /*
20961
    * Quite verbose, but should catch internal errors, which were
20962
    * not communicated.
20963
    */
20964
0
    if (mainSchema) {
20965
0
        xmlSchemaFree(mainSchema);
20966
0
  mainSchema = NULL;
20967
0
    }
20968
0
    if (ctxt->constructor) {
20969
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
20970
0
  ctxt->constructor = NULL;
20971
0
  ctxt->ownsConstructor = 0;
20972
0
    }
20973
0
    PERROR_INT2("xmlSchemaParse",
20974
0
  "An internal error occurred");
20975
0
    ctxt->schema = NULL;
20976
0
    return(NULL);
20977
0
}
20978
20979
/**
20980
 * Set the callback functions used to handle errors for a validation context
20981
 *
20982
 * @deprecated Use xmlSchemaSetParserStructuredErrors.
20983
 *
20984
 * @param ctxt  a schema validation context
20985
 * @param err  the error callback
20986
 * @param warn  the warning callback
20987
 * @param ctx  contextual data for the callbacks
20988
 */
20989
void
20990
xmlSchemaSetParserErrors(xmlSchemaParserCtxt *ctxt,
20991
                         xmlSchemaValidityErrorFunc err,
20992
                         xmlSchemaValidityWarningFunc warn, void *ctx)
20993
0
{
20994
0
    if (ctxt == NULL)
20995
0
        return;
20996
0
    ctxt->error = err;
20997
0
    ctxt->warning = warn;
20998
0
    ctxt->errCtxt = ctx;
20999
0
    if (ctxt->vctxt != NULL)
21000
0
  xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21001
0
}
21002
21003
/**
21004
 * Set the structured error callback
21005
 *
21006
 * @param ctxt  a schema parser context
21007
 * @param serror  the structured error function
21008
 * @param ctx  the functions context
21009
 */
21010
void
21011
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxt *ctxt,
21012
           xmlStructuredErrorFunc serror,
21013
           void *ctx)
21014
0
{
21015
0
    if (ctxt == NULL)
21016
0
  return;
21017
0
    ctxt->serror = serror;
21018
0
    ctxt->errCtxt = ctx;
21019
0
    if (ctxt->vctxt != NULL)
21020
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21021
0
}
21022
21023
/**
21024
 * Get the callback information used to handle errors for a parser context
21025
 *
21026
 * @param ctxt  a XMl-Schema parser context
21027
 * @param err  the error callback result
21028
 * @param warn  the warning callback result
21029
 * @param ctx  contextual data for the callbacks result
21030
 * @returns -1 in case of failure, 0 otherwise
21031
 */
21032
int
21033
xmlSchemaGetParserErrors(xmlSchemaParserCtxt *ctxt,
21034
       xmlSchemaValidityErrorFunc * err,
21035
       xmlSchemaValidityWarningFunc * warn, void **ctx)
21036
0
{
21037
0
  if (ctxt == NULL)
21038
0
    return(-1);
21039
0
  if (err != NULL)
21040
0
    *err = ctxt->error;
21041
0
  if (warn != NULL)
21042
0
    *warn = ctxt->warning;
21043
0
  if (ctx != NULL)
21044
0
    *ctx = ctxt->errCtxt;
21045
0
  return(0);
21046
0
}
21047
21048
/**
21049
 * Register a callback function that will be called to load documents
21050
 * or external entities.
21051
 *
21052
 * @since 2.14.0
21053
 * @param ctxt  schema parser
21054
 * @param loader  resource loader
21055
 * @param data  user data which will be passed to the loader
21056
 */
21057
void
21058
xmlSchemaSetResourceLoader(xmlSchemaParserCtxt *ctxt,
21059
0
                           xmlResourceLoader loader, void *data) {
21060
0
    if (ctxt == NULL)
21061
0
        return;
21062
0
    ctxt->resourceLoader = loader;
21063
0
    ctxt->resourceCtxt = data;
21064
0
}
21065
21066
/**
21067
 * Convert the xmlSchemaTypeType to a char string.
21068
 *
21069
 * @param type  the facet type
21070
 * @returns the char string representation of the facet type if the
21071
 *     type is a facet and an "Internal Error" string otherwise.
21072
 */
21073
static const xmlChar *
21074
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21075
0
{
21076
0
    switch (type) {
21077
0
        case XML_SCHEMA_FACET_PATTERN:
21078
0
            return (BAD_CAST "pattern");
21079
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21080
0
            return (BAD_CAST "maxExclusive");
21081
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
21082
0
            return (BAD_CAST "maxInclusive");
21083
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
21084
0
            return (BAD_CAST "minExclusive");
21085
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
21086
0
            return (BAD_CAST "minInclusive");
21087
0
        case XML_SCHEMA_FACET_WHITESPACE:
21088
0
            return (BAD_CAST "whiteSpace");
21089
0
        case XML_SCHEMA_FACET_ENUMERATION:
21090
0
            return (BAD_CAST "enumeration");
21091
0
        case XML_SCHEMA_FACET_LENGTH:
21092
0
            return (BAD_CAST "length");
21093
0
        case XML_SCHEMA_FACET_MAXLENGTH:
21094
0
            return (BAD_CAST "maxLength");
21095
0
        case XML_SCHEMA_FACET_MINLENGTH:
21096
0
            return (BAD_CAST "minLength");
21097
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
21098
0
            return (BAD_CAST "totalDigits");
21099
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
21100
0
            return (BAD_CAST "fractionDigits");
21101
0
        default:
21102
0
            break;
21103
0
    }
21104
0
    return (BAD_CAST "Internal Error");
21105
0
}
21106
21107
static xmlSchemaWhitespaceValueType
21108
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21109
0
{
21110
    /*
21111
    * The normalization type can be changed only for types which are derived
21112
    * from xsd:string.
21113
    */
21114
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
21115
  /*
21116
  * Note that we assume a whitespace of preserve for anySimpleType.
21117
  */
21118
0
  if ((type->builtInType == XML_SCHEMAS_STRING) ||
21119
0
      (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21120
0
      return(XML_SCHEMA_WHITESPACE_PRESERVE);
21121
0
  else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21122
0
      return(XML_SCHEMA_WHITESPACE_REPLACE);
21123
0
  else {
21124
      /*
21125
      * For all `atomic` datatypes other than string (and types `derived`
21126
      * by `restriction` from it) the value of whiteSpace is fixed to
21127
      * collapse
21128
      * Note that this includes built-in list datatypes.
21129
      */
21130
0
      return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21131
0
  }
21132
0
    } else if (WXS_IS_LIST(type)) {
21133
  /*
21134
  * For list types the facet "whiteSpace" is fixed to "collapse".
21135
  */
21136
0
  return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21137
0
    } else if (WXS_IS_UNION(type)) {
21138
0
  return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21139
0
    } else if (WXS_IS_ATOMIC(type)) {
21140
0
  if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21141
0
      return (XML_SCHEMA_WHITESPACE_PRESERVE);
21142
0
  else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21143
0
      return (XML_SCHEMA_WHITESPACE_REPLACE);
21144
0
  else
21145
0
      return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21146
0
    }
21147
0
    return (-1);
21148
0
}
21149
21150
/************************************************************************
21151
 *                  *
21152
 *      Simple type validation        *
21153
 *                  *
21154
 ************************************************************************/
21155
21156
21157
/************************************************************************
21158
 *                  *
21159
 *      DOM Validation code       *
21160
 *                  *
21161
 ************************************************************************/
21162
21163
/**
21164
 * Expands an existing schema by an additional schema.
21165
 *
21166
 * @param vctxt  a schema validation context
21167
 * @param schema  the existing schema
21168
 * @param node  the node that fired the assembling
21169
 * @param nsName  the namespace name of the new schema
21170
 * @param location  the location of the schema
21171
 * @returns 0 if the new schema is correct, a positive error code
21172
 * number otherwise and -1 in case of an internal or API error.
21173
 */
21174
static int
21175
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21176
          xmlSchemaPtr schema,
21177
          xmlNodePtr node,
21178
          const xmlChar *nsName,
21179
          const xmlChar *location)
21180
0
{
21181
0
    int ret = 0;
21182
0
    xmlSchemaParserCtxtPtr pctxt;
21183
0
    xmlSchemaBucketPtr bucket = NULL;
21184
0
    const xmlChar *baseURI = NULL;
21185
21186
0
    if ((vctxt == NULL) || (schema == NULL))
21187
0
  return (-1);
21188
21189
0
    if (vctxt->pctxt == NULL) {
21190
0
  VERROR_INT("xmlSchemaAssembleByLocation",
21191
0
      "no parser context available");
21192
0
  return(-1);
21193
0
    }
21194
0
    pctxt = vctxt->pctxt;
21195
0
    if (pctxt->constructor == NULL) {
21196
0
  PERROR_INT("xmlSchemaAssembleByLocation",
21197
0
      "no constructor");
21198
0
  return(-1);
21199
0
    }
21200
    /*
21201
    * Acquire the schema document.
21202
    * In streaming mode, node is NULL, so pass the input document's
21203
    * filename as the base URI for resolving relative locations.
21204
    */
21205
0
    if ((node == NULL) &&
21206
0
        (vctxt->parserCtxt != NULL) &&
21207
0
        (vctxt->parserCtxt->input != NULL))
21208
0
        baseURI = BAD_CAST vctxt->parserCtxt->input->filename;
21209
0
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21210
0
        location, node, baseURI);
21211
    /*
21212
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21213
    * the process will automatically change this to
21214
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21215
    */
21216
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21217
0
  location, NULL, NULL, 0, node, NULL, nsName,
21218
0
  &bucket);
21219
0
    if (ret != 0)
21220
0
  return(ret);
21221
0
    if (bucket == NULL) {
21222
  /*
21223
  * Generate a warning that the document could not be located.
21224
  */
21225
0
  xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21226
0
      node, NULL,
21227
0
      "The document at location '%s' could not be acquired",
21228
0
      location, NULL, NULL);
21229
0
  return(ret);
21230
0
    }
21231
    /*
21232
    * The first located schema will be handled as if all other
21233
    * schemas imported by XSI were imported by this first schema.
21234
    */
21235
0
    if ((bucket != NULL) &&
21236
0
  (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21237
0
  WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21238
    /*
21239
    * TODO: Is this handled like an import? I.e. is it not an error
21240
    * if the schema cannot be located?
21241
    */
21242
0
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21243
0
  return(0);
21244
    /*
21245
    * We will reuse the parser context for every schema imported
21246
    * directly via XSI. So reset the context.
21247
    */
21248
0
    pctxt->nberrors = 0;
21249
0
    pctxt->err = 0;
21250
0
    pctxt->doc = bucket->doc;
21251
21252
0
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21253
0
    if (ret == -1) {
21254
0
  pctxt->doc = NULL;
21255
0
  goto exit_failure;
21256
0
    }
21257
    /* Paranoid error channelling. */
21258
0
    if ((ret == 0) && (pctxt->nberrors != 0))
21259
0
  ret = pctxt->err;
21260
0
    if (pctxt->nberrors == 0) {
21261
  /*
21262
  * Only bother to fixup pending components, if there was
21263
  * no error yet.
21264
  * For every XSI acquired schema (and its sub-schemata) we will
21265
  * fixup the components.
21266
  */
21267
0
  xmlSchemaFixupComponents(pctxt, bucket);
21268
0
  ret = pctxt->err;
21269
  /*
21270
  * Not nice, but we need somehow to channel the schema parser
21271
  * error to the validation context.
21272
  */
21273
0
  if ((ret != 0) && (vctxt->err == 0))
21274
0
      vctxt->err = ret;
21275
0
  vctxt->nberrors += pctxt->nberrors;
21276
0
    } else {
21277
  /* Add to validation error sum. */
21278
0
  vctxt->nberrors += pctxt->nberrors;
21279
0
    }
21280
0
    pctxt->doc = NULL;
21281
0
    return(ret);
21282
0
exit_failure:
21283
0
    pctxt->doc = NULL;
21284
0
    return (-1);
21285
0
}
21286
21287
static xmlSchemaAttrInfoPtr
21288
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21289
       int metaType)
21290
0
{
21291
0
    if (vctxt->nbAttrInfos == 0)
21292
0
  return (NULL);
21293
0
    {
21294
0
  int i;
21295
0
  xmlSchemaAttrInfoPtr iattr;
21296
21297
0
  for (i = 0; i < vctxt->nbAttrInfos; i++) {
21298
0
      iattr = vctxt->attrInfos[i];
21299
0
      if (iattr->metaType == metaType)
21300
0
    return (iattr);
21301
0
  }
21302
21303
0
    }
21304
0
    return (NULL);
21305
0
}
21306
21307
/**
21308
 * Expands an existing schema by an additional schema using
21309
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21310
 * of an instance. If xsi:noNamespaceSchemaLocation is used, `noNamespace`
21311
 * must be set to 1.
21312
 *
21313
 * @param vctxt  a schema validation context
21314
 * @returns 0 if the new schema is correct, a positive error code
21315
 * number otherwise and -1 in case of an internal or API error.
21316
 */
21317
static int
21318
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21319
0
{
21320
0
    const xmlChar *cur, *end;
21321
0
    const xmlChar *nsname = NULL, *location;
21322
0
    int ret = 0;
21323
0
    xmlSchemaAttrInfoPtr iattr;
21324
21325
    /*
21326
    * Parse the value; we will assume an even number of values
21327
    * to be given (this is how Xerces and XSV work).
21328
    *
21329
    * URGENT TODO: !! This needs to work for both
21330
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
21331
    * element !!
21332
    */
21333
0
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21334
0
  XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21335
0
    if (iattr == NULL)
21336
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21337
0
  XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21338
0
    if (iattr == NULL)
21339
0
  return (0);
21340
0
    cur = iattr->value;
21341
0
    do {
21342
  /*
21343
  * TODO: Move the string parsing mechanism away from here.
21344
  */
21345
0
  if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21346
      /*
21347
      * Get the namespace name.
21348
      */
21349
0
      while (IS_BLANK_CH(*cur))
21350
0
    cur++;
21351
0
      end = cur;
21352
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21353
0
    end++;
21354
0
      if (end == cur)
21355
0
    break;
21356
      /* TODO: Don't use the schema's dict. */
21357
0
      nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21358
0
      cur = end;
21359
0
  }
21360
  /*
21361
  * Get the URI.
21362
  */
21363
0
  while (IS_BLANK_CH(*cur))
21364
0
      cur++;
21365
0
  end = cur;
21366
0
  while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21367
0
      end++;
21368
0
  if (end == cur) {
21369
0
      if (iattr->metaType ==
21370
0
    XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21371
0
      {
21372
    /*
21373
    * If using @schemaLocation then tuples are expected.
21374
    * I.e. the namespace name *and* the document's URI.
21375
    */
21376
0
    xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21377
0
        iattr->node, NULL,
21378
0
        "The value must consist of tuples: the target namespace "
21379
0
        "name and the document's URI", NULL, NULL, NULL);
21380
0
      }
21381
0
      break;
21382
0
  }
21383
  /* TODO: Don't use the schema's dict. */
21384
0
  location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21385
0
  cur = end;
21386
0
  ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21387
0
      iattr->node, nsname, location);
21388
0
  if (ret == -1) {
21389
0
      VERROR_INT("xmlSchemaAssembleByXSI",
21390
0
    "assembling schemata");
21391
0
      return (-1);
21392
0
  }
21393
0
    } while (*cur != 0);
21394
0
    return (ret);
21395
0
}
21396
21397
static const xmlChar *
21398
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21399
       const xmlChar *prefix)
21400
0
{
21401
0
    if (vctxt->sax != NULL) {
21402
0
  int i, j;
21403
0
  xmlSchemaNodeInfoPtr inode;
21404
21405
0
  for (i = vctxt->depth; i >= 0; i--) {
21406
0
      if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21407
0
    inode = vctxt->elemInfos[i];
21408
0
    for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21409
0
        if (((prefix == NULL) &&
21410
0
          (inode->nsBindings[j] == NULL)) ||
21411
0
      ((prefix != NULL) && xmlStrEqual(prefix,
21412
0
          inode->nsBindings[j]))) {
21413
21414
      /*
21415
      * Note that the namespace bindings are already
21416
      * in a string dict.
21417
      */
21418
0
      return (inode->nsBindings[j+1]);
21419
0
        }
21420
0
    }
21421
0
      }
21422
0
  }
21423
0
  return (NULL);
21424
0
#ifdef LIBXML_READER_ENABLED
21425
0
    } else if (vctxt->reader != NULL) {
21426
0
  xmlChar *nsName;
21427
21428
0
  nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21429
0
  if (nsName != NULL) {
21430
0
      const xmlChar *ret;
21431
21432
0
      ret = xmlDictLookup(vctxt->dict, nsName, -1);
21433
0
      xmlFree(nsName);
21434
0
      return (ret);
21435
0
  } else
21436
0
      return (NULL);
21437
0
#endif
21438
0
    } else {
21439
0
  xmlNsPtr ns;
21440
21441
0
  if ((vctxt->inode->node == NULL) ||
21442
0
      (vctxt->inode->node->doc == NULL)) {
21443
0
      VERROR_INT("xmlSchemaLookupNamespace",
21444
0
    "no node or node's doc available");
21445
0
      return (NULL);
21446
0
  }
21447
0
  ns = xmlSearchNs(vctxt->inode->node->doc,
21448
0
      vctxt->inode->node, prefix);
21449
0
  if (ns != NULL)
21450
0
      return (ns->href);
21451
0
  return (NULL);
21452
0
    }
21453
0
}
21454
21455
/*
21456
* This one works on the schema of the validation context.
21457
*/
21458
static int
21459
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21460
        xmlSchemaPtr schema,
21461
        xmlNodePtr node,
21462
        const xmlChar *value,
21463
        xmlSchemaValPtr *val,
21464
        int valNeeded)
21465
0
{
21466
0
    int ret;
21467
21468
0
    if (vctxt && (vctxt->schema == NULL)) {
21469
0
  VERROR_INT("xmlSchemaValidateNotation",
21470
0
      "a schema is needed on the validation context");
21471
0
  return (-1);
21472
0
    }
21473
0
    ret = xmlValidateQName(value, 1);
21474
0
    if (ret != 0)
21475
0
  return (ret);
21476
0
    {
21477
0
  xmlChar *localName = NULL;
21478
0
  xmlChar *prefix = NULL;
21479
21480
0
  localName = xmlSplitQName2(value, &prefix);
21481
0
  if (prefix != NULL) {
21482
0
      const xmlChar *nsName = NULL;
21483
21484
0
      if (vctxt != NULL)
21485
0
    nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21486
0
      else if (node != NULL) {
21487
0
    xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21488
0
    if (ns != NULL)
21489
0
        nsName = ns->href;
21490
0
      } else {
21491
0
    xmlFree(prefix);
21492
0
    xmlFree(localName);
21493
0
    return (1);
21494
0
      }
21495
0
      if (nsName == NULL) {
21496
0
    xmlFree(prefix);
21497
0
    xmlFree(localName);
21498
0
    return (1);
21499
0
      }
21500
0
      if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21501
0
    if ((valNeeded) && (val != NULL)) {
21502
0
        (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21503
0
                   xmlStrdup(nsName));
21504
0
        if (*val == NULL)
21505
0
      ret = -1;
21506
0
    }
21507
0
      } else
21508
0
    ret = 1;
21509
0
      xmlFree(prefix);
21510
0
      xmlFree(localName);
21511
0
  } else {
21512
0
      if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21513
0
    if (valNeeded && (val != NULL)) {
21514
0
        (*val) = xmlSchemaNewNOTATIONValue(
21515
0
      BAD_CAST xmlStrdup(value), NULL);
21516
0
        if (*val == NULL)
21517
0
      ret = -1;
21518
0
    }
21519
0
      } else
21520
0
    return (1);
21521
0
  }
21522
0
    }
21523
0
    return (ret);
21524
0
}
21525
21526
static int
21527
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21528
           const xmlChar* lname,
21529
           const xmlChar* nsname)
21530
0
{
21531
0
    int i;
21532
21533
0
    lname = xmlDictLookup(vctxt->dict, lname, -1);
21534
0
    if (lname == NULL)
21535
0
  return(-1);
21536
0
    if (nsname != NULL) {
21537
0
  nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21538
0
  if (nsname == NULL)
21539
0
      return(-1);
21540
0
    }
21541
0
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21542
0
  if ((vctxt->nodeQNames->items [i] == lname) &&
21543
0
      (vctxt->nodeQNames->items[i +1] == nsname))
21544
      /* Already there */
21545
0
      return(i);
21546
0
    }
21547
    /* Add new entry. */
21548
0
    i = vctxt->nodeQNames->nbItems;
21549
0
    if (xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname) < 0) {
21550
0
        xmlSchemaVErrMemory(vctxt);
21551
0
        return(-1);
21552
0
    }
21553
0
    if (xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname) < 0) {
21554
0
        vctxt->nodeQNames->nbItems--;
21555
0
        xmlSchemaVErrMemory(vctxt);
21556
0
        return(-1);
21557
0
    }
21558
0
    return(i);
21559
0
}
21560
21561
/************************************************************************
21562
 *                  *
21563
 *  Validation of identity-constraints (IDC)                            *
21564
 *                  *
21565
 ************************************************************************/
21566
21567
/**
21568
 * Creates an augmented IDC definition item.
21569
 *
21570
 * @param payload  the IDC definition
21571
 * @param data  validation context
21572
 * @param name  unused
21573
 * @returns the item, or NULL on internal errors.
21574
 */
21575
static void
21576
xmlSchemaAugmentIDC(void *payload, void *data,
21577
                    const xmlChar *name ATTRIBUTE_UNUSED)
21578
0
{
21579
0
    xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
21580
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21581
0
    xmlSchemaIDCAugPtr aidc;
21582
21583
0
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21584
0
    if (aidc == NULL) {
21585
0
  xmlSchemaVErrMemory(vctxt);
21586
0
  return;
21587
0
    }
21588
0
    aidc->keyrefDepth = -1;
21589
0
    aidc->def = idcDef;
21590
0
    aidc->next = NULL;
21591
0
    if (vctxt->aidcs == NULL)
21592
0
  vctxt->aidcs = aidc;
21593
0
    else {
21594
0
  aidc->next = vctxt->aidcs;
21595
0
  vctxt->aidcs = aidc;
21596
0
    }
21597
    /*
21598
    * Save if we have keyrefs at all.
21599
    */
21600
0
    if ((vctxt->hasKeyrefs == 0) &&
21601
0
  (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21602
0
  vctxt->hasKeyrefs = 1;
21603
0
}
21604
21605
/**
21606
 * Creates an augmented IDC definition for the imported schema.
21607
 *
21608
 * @param payload  the imported schema
21609
 * @param data  validation context
21610
 * @param name  unused
21611
 */
21612
static void
21613
xmlSchemaAugmentImportedIDC(void *payload, void *data,
21614
0
                            const xmlChar *name ATTRIBUTE_UNUSED) {
21615
0
    xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
21616
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21617
0
    if (imported->schema->idcDef != NULL) {
21618
0
      xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
21619
0
    }
21620
0
}
21621
21622
/**
21623
 * Creates a new IDC binding.
21624
 *
21625
 * @param idcDef  the IDC definition of this binding
21626
 * @returns the new IDC binding, NULL on internal errors.
21627
 */
21628
static xmlSchemaPSVIIDCBindingPtr
21629
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
21630
0
{
21631
0
    xmlSchemaPSVIIDCBindingPtr ret;
21632
21633
0
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
21634
0
      sizeof(xmlSchemaPSVIIDCBinding));
21635
0
    if (ret == NULL) {
21636
0
  xmlSchemaVErrMemory(NULL);
21637
0
  return (NULL);
21638
0
    }
21639
0
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
21640
0
    ret->definition = idcDef;
21641
0
    return (ret);
21642
0
}
21643
21644
/**
21645
 * The validation context is used to store IDC node table items.
21646
 * They are stored to avoid copying them if IDC node-tables are merged
21647
 * with corresponding parent IDC node-tables (bubbling).
21648
 *
21649
 * @param vctxt  the WXS validation context
21650
 * @param item  the IDC node table item
21651
 * @returns 0 if succeeded, -1 on internal errors.
21652
 */
21653
static int
21654
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
21655
             xmlSchemaPSVIIDCNodePtr item)
21656
0
{
21657
    /*
21658
    * Add to global list.
21659
    */
21660
0
    if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
21661
0
        xmlSchemaPSVIIDCNodePtr *tmp;
21662
0
        int newSize;
21663
21664
0
        newSize = xmlGrowCapacity(vctxt->sizeIdcNodes, sizeof(tmp[0]),
21665
0
                                  20, XML_MAX_ITEMS);
21666
0
  if (newSize < 0) {
21667
0
      xmlSchemaVErrMemory(vctxt);
21668
0
      return (-1);
21669
0
  }
21670
0
  tmp = xmlRealloc(vctxt->idcNodes, newSize * sizeof(tmp[0]));
21671
0
  if (tmp == NULL) {
21672
0
      xmlSchemaVErrMemory(vctxt);
21673
0
      return (-1);
21674
0
  }
21675
21676
0
        vctxt->idcNodes = tmp;
21677
0
        vctxt->sizeIdcNodes = newSize;
21678
0
    }
21679
21680
0
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
21681
0
    return (0);
21682
0
}
21683
21684
/**
21685
 * The validation context is used to store an IDC key.
21686
 *
21687
 * @param vctxt  the WXS validation context
21688
 * @param key  the IDC key
21689
 * @returns 0 if succeeded, -1 on internal errors.
21690
 */
21691
static int
21692
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
21693
         xmlSchemaPSVIIDCKeyPtr key)
21694
0
{
21695
    /*
21696
    * Add to global list.
21697
    */
21698
0
    if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
21699
0
        xmlSchemaPSVIIDCKeyPtr *tmp;
21700
0
        int newSize;
21701
21702
0
        newSize = xmlGrowCapacity(vctxt->sizeIdcKeys, sizeof(tmp[0]),
21703
0
                                  20, XML_MAX_ITEMS);
21704
0
  if (newSize < 0) {
21705
0
      xmlSchemaVErrMemory(vctxt);
21706
0
      return (-1);
21707
0
  }
21708
0
  tmp = xmlRealloc(vctxt->idcKeys, newSize * sizeof(tmp[0]));
21709
0
  if (tmp == NULL) {
21710
0
      xmlSchemaVErrMemory(vctxt);
21711
0
      return (-1);
21712
0
  }
21713
21714
0
        vctxt->idcKeys = tmp;
21715
0
        vctxt->sizeIdcKeys = newSize;
21716
0
    }
21717
21718
0
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
21719
0
    return (0);
21720
0
}
21721
21722
/**
21723
 * Appends the IDC node-table item to the binding.
21724
 *
21725
 * @param bind  the IDC binding
21726
 * @param ntItem  the node-table item
21727
 * @returns 0 on success and -1 on internal errors.
21728
 */
21729
static int
21730
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
21731
        xmlSchemaPSVIIDCNodePtr ntItem)
21732
0
{
21733
0
    if (bind->sizeNodes <= bind->nbNodes) {
21734
0
        xmlSchemaPSVIIDCNodePtr *tmp;
21735
0
        int newSize;
21736
21737
0
        newSize = xmlGrowCapacity(bind->sizeNodes, sizeof(tmp[0]),
21738
0
                                  10, XML_MAX_ITEMS);
21739
0
  if (newSize < 0) {
21740
0
      xmlSchemaVErrMemory(NULL);
21741
0
      return(-1);
21742
0
  }
21743
0
  tmp = xmlRealloc(bind->nodeTable, newSize * sizeof(tmp[0]));
21744
0
  if (tmp == NULL) {
21745
0
      xmlSchemaVErrMemory(NULL);
21746
0
      return(-1);
21747
0
  }
21748
21749
0
        bind->nodeTable = tmp;
21750
0
        bind->sizeNodes = newSize;
21751
0
    }
21752
21753
0
    bind->nodeTable[bind->nbNodes++] = ntItem;
21754
0
    return(0);
21755
0
}
21756
21757
/**
21758
 * Looks up an PSVI IDC binding, for the IDC definition and
21759
 * of the given matcher. If none found, a new one is created
21760
 * and added to the IDC table.
21761
 *
21762
 * @param vctxt  the WXS validation context
21763
 * @param matcher  the IDC matcher
21764
 * @returns an IDC binding or NULL on internal errors.
21765
 */
21766
static xmlSchemaPSVIIDCBindingPtr
21767
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
21768
        xmlSchemaIDCMatcherPtr matcher)
21769
0
{
21770
0
    xmlSchemaNodeInfoPtr ielem;
21771
21772
0
    ielem = vctxt->elemInfos[matcher->depth];
21773
21774
0
    if (ielem->idcTable == NULL) {
21775
0
  ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
21776
0
  if (ielem->idcTable == NULL)
21777
0
      return (NULL);
21778
0
  return(ielem->idcTable);
21779
0
    } else {
21780
0
  xmlSchemaPSVIIDCBindingPtr bind = NULL;
21781
21782
0
  bind = ielem->idcTable;
21783
0
  do {
21784
0
      if (bind->definition == matcher->aidc->def)
21785
0
    return(bind);
21786
0
      if (bind->next == NULL) {
21787
0
    bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
21788
0
    if (bind->next == NULL)
21789
0
        return (NULL);
21790
0
    return(bind->next);
21791
0
      }
21792
0
      bind = bind->next;
21793
0
  } while (bind != NULL);
21794
0
    }
21795
0
    return (NULL);
21796
0
}
21797
21798
static xmlSchemaItemListPtr
21799
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt,
21800
            xmlSchemaIDCMatcherPtr matcher)
21801
0
{
21802
0
    if (matcher->targets == NULL) {
21803
0
  matcher->targets = xmlSchemaItemListCreate();
21804
0
        if (matcher->targets == NULL)
21805
0
            xmlSchemaVErrMemory(vctxt);
21806
0
    }
21807
0
    return(matcher->targets);
21808
0
}
21809
21810
/**
21811
 * Frees an IDC key together with its compiled value.
21812
 *
21813
 * @param key  the IDC key
21814
 */
21815
static void
21816
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
21817
0
{
21818
0
    if (key->val != NULL)
21819
0
  xmlSchemaFreeValue(key->val);
21820
0
    xmlFree(key);
21821
0
}
21822
21823
/**
21824
 * Frees an IDC binding. Note that the node table-items
21825
 * are not freed.
21826
 */
21827
static void
21828
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
21829
0
{
21830
0
    if (bind->nodeTable != NULL)
21831
0
  xmlFree(bind->nodeTable);
21832
0
    if (bind->dupls != NULL)
21833
0
  xmlSchemaItemListFree(bind->dupls);
21834
0
    xmlFree(bind);
21835
0
}
21836
21837
/**
21838
 * Frees an IDC table, i.e. all the IDC bindings in the list.
21839
 *
21840
 * @param bind  the first IDC binding in the list
21841
 */
21842
static void
21843
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
21844
0
{
21845
0
    xmlSchemaPSVIIDCBindingPtr prev;
21846
21847
0
    while (bind != NULL) {
21848
0
  prev = bind;
21849
0
  bind = bind->next;
21850
0
  xmlSchemaIDCFreeBinding(prev);
21851
0
    }
21852
0
}
21853
21854
static void
21855
xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
21856
0
{
21857
0
    xmlIDCHashEntryPtr e = payload, n;
21858
0
    while (e) {
21859
0
  n = e->next;
21860
0
  xmlFree(e);
21861
0
  e = n;
21862
0
    }
21863
0
}
21864
21865
/**
21866
 * Frees a list of IDC matchers.
21867
 *
21868
 * @param matcher  the first IDC matcher in the list
21869
 */
21870
static void
21871
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
21872
0
{
21873
0
    xmlSchemaIDCMatcherPtr next;
21874
21875
0
    while (matcher != NULL) {
21876
0
  next = matcher->next;
21877
0
  if (matcher->keySeqs != NULL) {
21878
0
      int i;
21879
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
21880
0
    if (matcher->keySeqs[i] != NULL)
21881
0
        xmlFree(matcher->keySeqs[i]);
21882
0
      xmlFree(matcher->keySeqs);
21883
0
  }
21884
0
  if (matcher->targets != NULL) {
21885
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
21886
0
    int i;
21887
0
    xmlSchemaPSVIIDCNodePtr idcNode;
21888
    /*
21889
    * Node-table items for keyrefs are not stored globally
21890
    * to the validation context, since they are not bubbled.
21891
    * We need to free them here.
21892
    */
21893
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
21894
0
        idcNode =
21895
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
21896
0
        xmlFree(idcNode->keys);
21897
0
        xmlFree(idcNode);
21898
0
    }
21899
0
      }
21900
0
      xmlSchemaItemListFree(matcher->targets);
21901
0
  }
21902
0
  if (matcher->htab != NULL)
21903
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
21904
0
  xmlFree(matcher);
21905
0
  matcher = next;
21906
0
    }
21907
0
}
21908
21909
/**
21910
 * Caches a list of IDC matchers for reuse.
21911
 *
21912
 * @param vctxt  the WXS validation context
21913
 * @param matcher  the first IDC matcher in the list
21914
 */
21915
static void
21916
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
21917
             xmlSchemaIDCMatcherPtr matcher)
21918
0
{
21919
0
    xmlSchemaIDCMatcherPtr next;
21920
21921
0
    while (matcher != NULL) {
21922
0
  next = matcher->next;
21923
0
  if (matcher->keySeqs != NULL) {
21924
0
      int i;
21925
      /*
21926
      * Don't free the array, but only the content.
21927
      */
21928
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
21929
0
    if (matcher->keySeqs[i] != NULL) {
21930
0
        xmlFree(matcher->keySeqs[i]);
21931
0
        matcher->keySeqs[i] = NULL;
21932
0
    }
21933
0
  }
21934
0
  if (matcher->targets) {
21935
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
21936
0
    int i;
21937
0
    xmlSchemaPSVIIDCNodePtr idcNode;
21938
    /*
21939
    * Node-table items for keyrefs are not stored globally
21940
    * to the validation context, since they are not bubbled.
21941
    * We need to free them here.
21942
    */
21943
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
21944
0
        idcNode =
21945
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
21946
0
        xmlFree(idcNode->keys);
21947
0
        xmlFree(idcNode);
21948
0
    }
21949
0
      }
21950
0
      xmlSchemaItemListFree(matcher->targets);
21951
0
      matcher->targets = NULL;
21952
0
  }
21953
0
  if (matcher->htab != NULL) {
21954
0
      xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
21955
0
      matcher->htab = NULL;
21956
0
  }
21957
0
  matcher->next = NULL;
21958
  /*
21959
  * Cache the matcher.
21960
  */
21961
0
  if (vctxt->idcMatcherCache != NULL)
21962
0
      matcher->nextCached = vctxt->idcMatcherCache;
21963
0
  vctxt->idcMatcherCache = matcher;
21964
21965
0
  matcher = next;
21966
0
    }
21967
0
}
21968
21969
/**
21970
 * Creates/reuses and activates state objects for the given
21971
 * XPath information; if the XPath expression consists of unions,
21972
 * multiple state objects are created for every unioned expression.
21973
 *
21974
 * @param vctxt  the WXS validation context
21975
 * @param matcher  the IDC matcher
21976
 * @param sel  the XPath information
21977
 * @param type  "selector" or "field"
21978
 * @returns 0 on success and -1 on internal errors.
21979
 */
21980
static int
21981
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
21982
      xmlSchemaIDCMatcherPtr matcher,
21983
      xmlSchemaIDCSelectPtr sel,
21984
      int type)
21985
0
{
21986
0
    xmlSchemaIDCStateObjPtr sto;
21987
21988
    /*
21989
    * Reuse the state objects from the pool.
21990
    */
21991
0
    if (vctxt->xpathStatePool != NULL) {
21992
0
  sto = vctxt->xpathStatePool;
21993
0
  vctxt->xpathStatePool = sto->next;
21994
0
  sto->next = NULL;
21995
0
    } else {
21996
  /*
21997
  * Create a new state object.
21998
  */
21999
0
  sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22000
0
  if (sto == NULL) {
22001
0
      xmlSchemaVErrMemory(NULL);
22002
0
      return (-1);
22003
0
  }
22004
0
  memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22005
0
    }
22006
    /*
22007
    * Add to global list.
22008
    */
22009
0
    if (vctxt->xpathStates != NULL)
22010
0
  sto->next = vctxt->xpathStates;
22011
0
    vctxt->xpathStates = sto;
22012
22013
    /*
22014
    * Free the old xpath validation context.
22015
    */
22016
0
    if (sto->xpathCtxt != NULL)
22017
0
  xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22018
22019
    /*
22020
    * Create a new XPath (pattern) validation context.
22021
    */
22022
0
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22023
0
  (xmlPatternPtr) sel->xpathComp);
22024
0
    if (sto->xpathCtxt == NULL) {
22025
0
  VERROR_INT("xmlSchemaIDCAddStateObject",
22026
0
      "failed to create an XPath validation context");
22027
0
  return (-1);
22028
0
    }
22029
0
    sto->type = type;
22030
0
    sto->depth = vctxt->depth;
22031
0
    sto->matcher = matcher;
22032
0
    sto->sel = sel;
22033
0
    sto->nbHistory = 0;
22034
22035
0
    return (0);
22036
0
}
22037
22038
/**
22039
 * Evaluates all active XPath state objects.
22040
 *
22041
 * @param vctxt  the WXS validation context
22042
 * @param nodeType  the nodeType of the current node
22043
 * @returns the number of IC "field" state objects which resolved to
22044
 * this node, 0 if none resolved and -1 on internal errors.
22045
 */
22046
static int
22047
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22048
           xmlElementType nodeType)
22049
0
{
22050
0
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22051
0
    int res, resolved = 0, depth = vctxt->depth;
22052
22053
0
    if (vctxt->xpathStates == NULL)
22054
0
  return (0);
22055
22056
0
    if (nodeType == XML_ATTRIBUTE_NODE)
22057
0
  depth++;
22058
    /*
22059
    * Process all active XPath state objects.
22060
    */
22061
0
    first = vctxt->xpathStates;
22062
0
    sto = first;
22063
0
    while (sto != head) {
22064
0
  if (nodeType == XML_ELEMENT_NODE)
22065
0
      res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22066
0
    vctxt->inode->localName, vctxt->inode->nsName);
22067
0
  else
22068
0
      res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22069
0
    vctxt->inode->localName, vctxt->inode->nsName);
22070
22071
0
  if (res == -1) {
22072
0
      VERROR_INT("xmlSchemaXPathEvaluate",
22073
0
    "calling xmlStreamPush()");
22074
0
      return (-1);
22075
0
  }
22076
0
  if (res == 0)
22077
0
      goto next_sto;
22078
  /*
22079
  * Full match.
22080
  */
22081
  /*
22082
  * Register a match in the state object history.
22083
  */
22084
0
        if (sto->sizeHistory <= sto->nbHistory) {
22085
0
            int *tmp;
22086
0
            int newSize;
22087
22088
0
            newSize = xmlGrowCapacity(sto->sizeHistory, sizeof(tmp[0]),
22089
0
                                      5, XML_MAX_ITEMS);
22090
0
            if (newSize < 0) {
22091
0
                xmlSchemaVErrMemory(vctxt);
22092
0
                return (-1);
22093
0
            }
22094
0
            tmp = xmlRealloc(sto->history, newSize * sizeof(tmp[0]));
22095
0
            if (tmp == NULL) {
22096
0
                xmlSchemaVErrMemory(vctxt);
22097
0
                return (-1);
22098
0
            }
22099
22100
0
            sto->history = tmp;
22101
0
            sto->sizeHistory = newSize;
22102
0
  }
22103
0
  sto->history[sto->nbHistory++] = depth;
22104
22105
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22106
0
      xmlSchemaIDCSelectPtr sel;
22107
      /*
22108
      * Activate state objects for the IDC fields of
22109
      * the IDC selector.
22110
      */
22111
0
      sel = sto->matcher->aidc->def->fields;
22112
0
      while (sel != NULL) {
22113
0
    if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22114
0
        sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22115
0
        return (-1);
22116
0
    sel = sel->next;
22117
0
      }
22118
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22119
      /*
22120
      * An IDC key node was found by the IDC field.
22121
      */
22122
      /*
22123
      * Notify that the character value of this node is
22124
      * needed.
22125
      */
22126
0
      if (resolved == 0) {
22127
0
    if ((vctxt->inode->flags &
22128
0
        XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22129
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22130
0
      }
22131
0
      resolved++;
22132
0
  }
22133
0
next_sto:
22134
0
  if (sto->next == NULL) {
22135
      /*
22136
      * Evaluate field state objects created on this node as well.
22137
      */
22138
0
      head = first;
22139
0
      sto = vctxt->xpathStates;
22140
0
  } else
22141
0
      sto = sto->next;
22142
0
    }
22143
0
    return (resolved);
22144
0
}
22145
22146
static const xmlChar *
22147
xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22148
        xmlChar **buf,
22149
        xmlSchemaPSVIIDCKeyPtr *seq,
22150
        int count, int for_hash)
22151
0
{
22152
0
    int i, res;
22153
0
    xmlChar *value = NULL;
22154
22155
0
    *buf = xmlStrdup(BAD_CAST "[");
22156
0
    for (i = 0; i < count; i++) {
22157
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
22158
0
  if (!for_hash)
22159
0
      res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22160
0
        xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22161
0
        &value);
22162
0
  else {
22163
0
      res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22164
0
  }
22165
0
  if (res == 0)
22166
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
22167
0
  else {
22168
0
      VERROR_INT("xmlSchemaFormatIDCKeySequence",
22169
0
    "failed to compute a canonical value");
22170
0
      *buf = xmlStrcat(*buf, BAD_CAST "???");
22171
0
  }
22172
0
  if (i < count -1)
22173
0
      *buf = xmlStrcat(*buf, BAD_CAST "', ");
22174
0
  else
22175
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
22176
0
  if (value != NULL) {
22177
0
      xmlFree(value);
22178
0
      value = NULL;
22179
0
  }
22180
0
    }
22181
0
    *buf = xmlStrcat(*buf, BAD_CAST "]");
22182
22183
0
    return (BAD_CAST *buf);
22184
0
}
22185
22186
static const xmlChar *
22187
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22188
            xmlChar **buf,
22189
            xmlSchemaPSVIIDCKeyPtr *seq,
22190
            int count)
22191
0
{
22192
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22193
0
}
22194
22195
static const xmlChar *
22196
xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22197
       xmlChar **buf,
22198
       xmlSchemaPSVIIDCKeyPtr *seq,
22199
       int count)
22200
0
{
22201
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22202
0
}
22203
22204
/**
22205
 * Pops all XPath states.
22206
 *
22207
 * @param vctxt  the WXS validation context
22208
 * @returns 0 on success and -1 on internal errors.
22209
 */
22210
static int
22211
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22212
0
{
22213
0
    xmlSchemaIDCStateObjPtr sto;
22214
0
    int res;
22215
22216
0
    if (vctxt->xpathStates == NULL)
22217
0
  return(0);
22218
0
    sto = vctxt->xpathStates;
22219
0
    do {
22220
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22221
0
  if (res == -1)
22222
0
      return (-1);
22223
0
  sto = sto->next;
22224
0
    } while (sto != NULL);
22225
0
    return(0);
22226
0
}
22227
22228
/**
22229
 * Processes and pops the history items of the IDC state objects.
22230
 * IDC key-sequences are validated/created on IDC bindings.
22231
 *
22232
 * @param vctxt  the WXS validation context
22233
 * @param depth  depth
22234
 * @returns 0 on success and -1 on internal errors.
22235
 */
22236
static int
22237
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22238
           int depth)
22239
0
{
22240
0
    xmlSchemaIDCStateObjPtr sto, nextsto;
22241
0
    int res, matchDepth;
22242
0
    xmlSchemaPSVIIDCKeyPtr key = NULL;
22243
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22244
22245
0
    if (vctxt->xpathStates == NULL)
22246
0
  return (0);
22247
0
    sto = vctxt->xpathStates;
22248
22249
    /*
22250
    * Evaluate the state objects.
22251
    */
22252
0
    while (sto != NULL) {
22253
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22254
0
  if (res == -1) {
22255
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22256
0
    "calling xmlStreamPop()");
22257
0
      return (-1);
22258
0
  }
22259
0
  if (sto->nbHistory == 0)
22260
0
      goto deregister_check;
22261
22262
0
  matchDepth = sto->history[sto->nbHistory -1];
22263
22264
  /*
22265
  * Only matches at the current depth are of interest.
22266
  */
22267
0
  if (matchDepth != depth) {
22268
0
      sto = sto->next;
22269
0
      continue;
22270
0
  }
22271
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22272
      /*
22273
      * NOTE: According to
22274
      *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22275
      *   ... the simple-content of complex types is also allowed.
22276
      */
22277
22278
0
      if (WXS_IS_COMPLEX(type)) {
22279
0
    if (WXS_HAS_SIMPLE_CONTENT(type)) {
22280
        /*
22281
        * Sanity check for complex types with simple content.
22282
        */
22283
0
        simpleType = type->contentTypeDef;
22284
0
        if (simpleType == NULL) {
22285
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22286
0
          "field resolves to a CT with simple content "
22287
0
          "but the CT is missing the ST definition");
22288
0
      return (-1);
22289
0
        }
22290
0
    } else
22291
0
        simpleType = NULL;
22292
0
      } else
22293
0
    simpleType = type;
22294
0
      if (simpleType == NULL) {
22295
0
    xmlChar *str = NULL;
22296
22297
    /*
22298
    * Not qualified if the field resolves to a node of non
22299
    * simple type.
22300
    */
22301
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22302
0
        XML_SCHEMAV_CVC_IDC, NULL,
22303
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22304
0
        "The XPath '%s' of a field of %s does evaluate to a node of "
22305
0
        "non-simple type",
22306
0
        sto->sel->xpath,
22307
0
        xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22308
0
    FREE_AND_NULL(str);
22309
0
    sto->nbHistory--;
22310
0
    goto deregister_check;
22311
0
      }
22312
22313
0
      if ((key == NULL) && (vctxt->inode->val == NULL)) {
22314
    /*
22315
    * Failed to provide the normalized value; maybe
22316
    * the value was invalid.
22317
    */
22318
0
    VERROR(XML_SCHEMAV_CVC_IDC,
22319
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22320
0
        "Warning: No precomputed value available, the value "
22321
0
        "was either invalid or something strange happened");
22322
0
    sto->nbHistory--;
22323
0
    goto deregister_check;
22324
0
      } else {
22325
0
    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22326
0
    xmlSchemaPSVIIDCKeyPtr *keySeq;
22327
0
    int pos, idx;
22328
22329
    /*
22330
    * The key will be anchored on the matcher's list of
22331
    * key-sequences. The position in this list is determined
22332
    * by the target node's depth relative to the matcher's
22333
    * depth of creation (i.e. the depth of the scope element).
22334
    *
22335
    * Element        Depth    Pos   List-entries
22336
    * <scope>          0              NULL
22337
    *   <bar>          1              NULL
22338
    *     <target/>    2       2      target
22339
    *   <bar>
22340
                * </scope>
22341
    *
22342
    * The size of the list is only dependent on the depth of
22343
    * the tree.
22344
    * An entry will be NULLed in selector_leave, i.e. when
22345
    * we hit the target's
22346
    */
22347
0
    pos = sto->depth - matcher->depth;
22348
0
    idx = sto->sel->index;
22349
22350
    /*
22351
    * Create/grow the array of key-sequences.
22352
    */
22353
0
                if (pos >= matcher->sizeKeySeqs) {
22354
0
                    xmlSchemaPSVIIDCKeyPtr **tmp;
22355
0
                    int oldSize = matcher->sizeKeySeqs;
22356
0
                    int newSize, i;
22357
22358
0
                    newSize = xmlGrowCapacity(pos, sizeof(tmp[0]),
22359
0
                                              10, XML_MAX_ITEMS);
22360
0
                    if (newSize < 0) {
22361
0
                        xmlSchemaVErrMemory(vctxt);
22362
0
                        return (-1);
22363
0
                    }
22364
0
                    tmp = xmlRealloc(matcher->keySeqs,
22365
0
                                     newSize * sizeof(tmp[0]));
22366
0
                    if (tmp == NULL) {
22367
0
                        xmlSchemaVErrMemory(vctxt);
22368
0
                        return (-1);
22369
0
                    }
22370
22371
0
                    matcher->keySeqs = tmp;
22372
0
                    matcher->sizeKeySeqs = newSize;
22373
22374
        /*
22375
        * The array needs to be NULLed.
22376
        * TODO: Use memset?
22377
        */
22378
0
        for (i = oldSize; i < newSize; i++)
22379
0
      matcher->keySeqs[i] = NULL;
22380
0
    }
22381
22382
    /*
22383
    * Get/create the key-sequence.
22384
    */
22385
0
    keySeq = matcher->keySeqs[pos];
22386
0
    if (keySeq == NULL) {
22387
0
        goto create_sequence;
22388
0
    } else if (keySeq[idx] != NULL) {
22389
0
        xmlChar *str = NULL;
22390
        /*
22391
        * cvc-identity-constraint:
22392
        * 3 For each node in the `target node set` all
22393
        * of the {fields}, with that node as the context
22394
        * node, evaluate to either an empty node-set or
22395
        * a node-set with exactly one member, which must
22396
        * have a simple type.
22397
        *
22398
        * The key was already set; report an error.
22399
        */
22400
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22401
0
      XML_SCHEMAV_CVC_IDC, NULL,
22402
0
      WXS_BASIC_CAST matcher->aidc->def,
22403
0
      "The XPath '%s' of a field of %s evaluates to a "
22404
0
      "node-set with more than one member",
22405
0
      sto->sel->xpath,
22406
0
      xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22407
0
        FREE_AND_NULL(str);
22408
0
        sto->nbHistory--;
22409
0
        goto deregister_check;
22410
0
    } else
22411
0
        goto create_key;
22412
22413
0
create_sequence:
22414
    /*
22415
    * Create a key-sequence.
22416
    */
22417
0
    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22418
0
        matcher->aidc->def->nbFields *
22419
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22420
0
    if (keySeq == NULL) {
22421
0
        xmlSchemaVErrMemory(NULL);
22422
0
        return(-1);
22423
0
    }
22424
0
    memset(keySeq, 0, matcher->aidc->def->nbFields *
22425
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22426
0
    matcher->keySeqs[pos] = keySeq;
22427
0
create_key:
22428
    /*
22429
    * Create a key once per node only.
22430
    */
22431
0
    if (key == NULL) {
22432
0
        key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22433
0
      sizeof(xmlSchemaPSVIIDCKey));
22434
0
        if (key == NULL) {
22435
0
      xmlSchemaVErrMemory(NULL);
22436
0
      xmlFree(keySeq);
22437
0
      matcher->keySeqs[pos] = NULL;
22438
0
      return(-1);
22439
0
        }
22440
        /*
22441
        * Consume the compiled value.
22442
        */
22443
0
        key->type = simpleType;
22444
0
        key->val = vctxt->inode->val;
22445
0
        vctxt->inode->val = NULL;
22446
        /*
22447
        * Store the key in a global list.
22448
        */
22449
0
        if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22450
0
      xmlSchemaIDCFreeKey(key);
22451
0
      return (-1);
22452
0
        }
22453
0
    }
22454
0
    keySeq[idx] = key;
22455
0
      }
22456
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22457
22458
0
      xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22459
      /* xmlSchemaPSVIIDCBindingPtr bind; */
22460
0
      xmlSchemaPSVIIDCNodePtr ntItem;
22461
0
      xmlSchemaIDCMatcherPtr matcher;
22462
0
      xmlSchemaIDCPtr idc;
22463
0
      xmlSchemaItemListPtr targets;
22464
0
      int pos, i, j, nbKeys;
22465
      /*
22466
      * Here we have the following scenario:
22467
      * An IDC 'selector' state object resolved to a target node,
22468
      * during the time this target node was in the
22469
      * ancestor-or-self axis, the 'field' state object(s) looked
22470
      * out for matching nodes to create a key-sequence for this
22471
      * target node. Now we are back to this target node and need
22472
      * to put the key-sequence, together with the target node
22473
      * itself, into the node-table of the corresponding IDC
22474
      * binding.
22475
      */
22476
0
      matcher = sto->matcher;
22477
0
      idc = matcher->aidc->def;
22478
0
      nbKeys = idc->nbFields;
22479
0
      pos = depth - matcher->depth;
22480
      /*
22481
      * Check if the matcher has any key-sequences at all, plus
22482
      * if it has a key-sequence for the current target node.
22483
      */
22484
0
      if ((matcher->keySeqs == NULL) ||
22485
0
    (matcher->sizeKeySeqs <= pos)) {
22486
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22487
0
        goto selector_key_error;
22488
0
    else
22489
0
        goto selector_leave;
22490
0
      }
22491
22492
0
      keySeq = &(matcher->keySeqs[pos]);
22493
0
      if (*keySeq == NULL) {
22494
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22495
0
        goto selector_key_error;
22496
0
    else
22497
0
        goto selector_leave;
22498
0
      }
22499
22500
0
      for (i = 0; i < nbKeys; i++) {
22501
0
    if ((*keySeq)[i] == NULL) {
22502
        /*
22503
        * Not qualified, if not all fields did resolve.
22504
        */
22505
0
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22506
      /*
22507
      * All fields of a "key" IDC must resolve.
22508
      */
22509
0
      goto selector_key_error;
22510
0
        }
22511
0
        goto selector_leave;
22512
0
    }
22513
0
      }
22514
      /*
22515
      * All fields did resolve.
22516
      */
22517
22518
      /*
22519
      * 4.1 If the {identity-constraint category} is unique(/key),
22520
      * then no two members of the `qualified node set` have
22521
      * `key-sequences` whose members are pairwise equal, as
22522
      * defined by Equal in [XML Schemas: Datatypes].
22523
      *
22524
      * Get the IDC binding from the matcher and check for
22525
      * duplicate key-sequences.
22526
      */
22527
#if 0
22528
      bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22529
#endif
22530
0
      targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22531
0
            if (targets == NULL)
22532
0
                return(-1);
22533
22534
0
      if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22535
0
    (targets->nbItems != 0)) {
22536
0
    xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22537
0
    xmlIDCHashEntryPtr e;
22538
22539
0
    res = 0;
22540
22541
0
    if (!matcher->htab)
22542
0
        e = NULL;
22543
0
    else {
22544
0
        xmlChar *value = NULL;
22545
0
        xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
22546
0
        e = xmlHashLookup(matcher->htab, value);
22547
0
        FREE_AND_NULL(value);
22548
0
    }
22549
22550
    /*
22551
    * Compare the key-sequences, key by key.
22552
    */
22553
0
    for (;e; e = e->next) {
22554
0
        bkeySeq =
22555
0
      ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
22556
0
        for (j = 0; j < nbKeys; j++) {
22557
0
      ckey = (*keySeq)[j];
22558
0
      bkey = bkeySeq[j];
22559
0
      res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22560
0
      if (res == -1) {
22561
0
          return (-1);
22562
0
      } else if (res == 0) {
22563
          /*
22564
          * One of the keys differs, so the key-sequence
22565
          * won't be equal; get out.
22566
          */
22567
0
          break;
22568
0
      }
22569
0
        }
22570
0
        if (res == 1) {
22571
      /*
22572
      * Duplicate key-sequence found.
22573
      */
22574
0
      break;
22575
0
        }
22576
0
    }
22577
0
    if (e) {
22578
0
        xmlChar *str = NULL, *strB = NULL;
22579
        /*
22580
        * TODO: Try to report the key-sequence.
22581
        */
22582
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22583
0
      XML_SCHEMAV_CVC_IDC, NULL,
22584
0
      WXS_BASIC_CAST idc,
22585
0
      "Duplicate key-sequence %s in %s",
22586
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
22587
0
          (*keySeq), nbKeys),
22588
0
      xmlSchemaGetIDCDesignation(&strB, idc));
22589
0
        FREE_AND_NULL(str);
22590
0
        FREE_AND_NULL(strB);
22591
0
        goto selector_leave;
22592
0
    }
22593
0
      }
22594
      /*
22595
      * Add a node-table item to the IDC binding.
22596
      */
22597
0
      ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
22598
0
    sizeof(xmlSchemaPSVIIDCNode));
22599
0
      if (ntItem == NULL) {
22600
0
    xmlSchemaVErrMemory(NULL);
22601
0
    xmlFree(*keySeq);
22602
0
    *keySeq = NULL;
22603
0
    return(-1);
22604
0
      }
22605
0
      memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
22606
22607
      /*
22608
      * Store the node-table item in a global list.
22609
      */
22610
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22611
0
    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
22612
0
        xmlFree(ntItem);
22613
0
        xmlFree(*keySeq);
22614
0
        *keySeq = NULL;
22615
0
        return (-1);
22616
0
    }
22617
0
    ntItem->nodeQNameID = -1;
22618
0
      } else {
22619
    /*
22620
    * Save a cached QName for this node on the IDC node, to be
22621
    * able to report it, even if the node is not saved.
22622
    */
22623
0
    ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
22624
0
        vctxt->inode->localName, vctxt->inode->nsName);
22625
0
    if (ntItem->nodeQNameID == -1) {
22626
0
        xmlFree(ntItem);
22627
0
        xmlFree(*keySeq);
22628
0
        *keySeq = NULL;
22629
0
        return (-1);
22630
0
    }
22631
0
      }
22632
      /*
22633
      * Init the node-table item: Save the node, position and
22634
      * consume the key-sequence.
22635
      */
22636
0
      ntItem->node = vctxt->node;
22637
0
      ntItem->nodeLine = vctxt->inode->nodeLine;
22638
0
      ntItem->keys = *keySeq;
22639
0
      *keySeq = NULL;
22640
#if 0
22641
      if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
22642
#endif
22643
0
      if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
22644
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
22645
        /*
22646
        * Free the item, since keyref items won't be
22647
        * put on a global list.
22648
        */
22649
0
        xmlFree(ntItem->keys);
22650
0
        xmlFree(ntItem);
22651
0
    }
22652
0
    return (-1);
22653
0
      }
22654
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22655
0
    xmlChar *value = NULL;
22656
0
    xmlIDCHashEntryPtr r, e;
22657
0
    if (!matcher->htab)
22658
0
      matcher->htab = xmlHashCreate(4);
22659
0
    xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
22660
0
    e = xmlMalloc(sizeof *e);
22661
0
                if (e == NULL) {
22662
0
                    xmlSchemaVErrMemory(vctxt);
22663
0
                    goto mem_error;
22664
0
                }
22665
0
    e->index = targets->nbItems - 1;
22666
0
    r = xmlHashLookup(matcher->htab, value);
22667
0
    if (r) {
22668
0
        e->next = r->next;
22669
0
        r->next = e;
22670
0
    } else {
22671
0
        e->next = NULL;
22672
0
        if (xmlHashAddEntry(matcher->htab, value, e) < 0) {
22673
0
                        xmlSchemaVErrMemory(vctxt);
22674
0
                        xmlFree(e);
22675
0
                    }
22676
0
    }
22677
0
mem_error:
22678
0
    FREE_AND_NULL(value);
22679
0
      }
22680
22681
0
      goto selector_leave;
22682
0
selector_key_error:
22683
0
      {
22684
0
    xmlChar *str = NULL;
22685
    /*
22686
    * 4.2.1 (KEY) The `target node set` and the
22687
    * `qualified node set` are equal, that is, every
22688
    * member of the `target node set` is also a member
22689
    * of the `qualified node set` and vice versa.
22690
    */
22691
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22692
0
        XML_SCHEMAV_CVC_IDC, NULL,
22693
0
        WXS_BASIC_CAST idc,
22694
0
        "Not all fields of %s evaluate to a node",
22695
0
        xmlSchemaGetIDCDesignation(&str, idc), NULL);
22696
0
    FREE_AND_NULL(str);
22697
0
      }
22698
0
selector_leave:
22699
      /*
22700
      * Free the key-sequence if not added to the IDC table.
22701
      */
22702
0
      if ((keySeq != NULL) && (*keySeq != NULL)) {
22703
0
    xmlFree(*keySeq);
22704
0
    *keySeq = NULL;
22705
0
      }
22706
0
  } /* if selector */
22707
22708
0
  sto->nbHistory--;
22709
22710
0
deregister_check:
22711
  /*
22712
  * Deregister state objects if they reach the depth of creation.
22713
  */
22714
0
  if ((sto->nbHistory == 0) && (sto->depth == depth)) {
22715
0
      if (vctxt->xpathStates != sto) {
22716
0
    VERROR_INT("xmlSchemaXPathProcessHistory",
22717
0
        "The state object to be removed is not the first "
22718
0
        "in the list");
22719
0
      }
22720
0
      nextsto = sto->next;
22721
      /*
22722
      * Unlink from the list of active XPath state objects.
22723
      */
22724
0
      vctxt->xpathStates = sto->next;
22725
0
      sto->next = vctxt->xpathStatePool;
22726
      /*
22727
      * Link it to the pool of reusable state objects.
22728
      */
22729
0
      vctxt->xpathStatePool = sto;
22730
0
      sto = nextsto;
22731
0
  } else
22732
0
      sto = sto->next;
22733
0
    } /* while (sto != NULL) */
22734
0
    return (0);
22735
0
}
22736
22737
/**
22738
 * Creates helper objects to evaluate IDC selectors/fields
22739
 * successively.
22740
 *
22741
 * @param vctxt  the WXS validation context
22742
 * @param elemDecl  the element declaration
22743
 * @returns 0 if OK and -1 on internal errors.
22744
 */
22745
static int
22746
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
22747
           xmlSchemaElementPtr elemDecl)
22748
0
{
22749
0
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
22750
0
    xmlSchemaIDCPtr idc, refIdc;
22751
0
    xmlSchemaIDCAugPtr aidc;
22752
22753
0
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
22754
0
    if (idc == NULL)
22755
0
  return (0);
22756
22757
0
    if (vctxt->inode->idcMatchers != NULL) {
22758
0
  VERROR_INT("xmlSchemaIDCRegisterMatchers",
22759
0
      "The chain of IDC matchers is expected to be empty");
22760
0
  return (-1);
22761
0
    }
22762
0
    do {
22763
0
  if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
22764
      /*
22765
      * Since IDCs bubbles are expensive we need to know the
22766
      * depth at which the bubbles should stop; this will be
22767
      * the depth of the top-most keyref IDC. If no keyref
22768
      * references a key/unique IDC, the keyrefDepth will
22769
      * be -1, indicating that no bubbles are needed.
22770
      */
22771
0
      refIdc = (xmlSchemaIDCPtr) idc->ref->item;
22772
0
      if (refIdc != NULL) {
22773
    /*
22774
    * Remember that we have keyrefs on this node.
22775
    */
22776
0
    vctxt->inode->hasKeyrefs = 1;
22777
    /*
22778
    * Lookup the referenced augmented IDC info.
22779
    */
22780
0
    aidc = vctxt->aidcs;
22781
0
    while (aidc != NULL) {
22782
0
        if (aidc->def == refIdc)
22783
0
      break;
22784
0
        aidc = aidc->next;
22785
0
    }
22786
0
    if (aidc == NULL) {
22787
0
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
22788
0
      "Could not find an augmented IDC item for an IDC "
22789
0
      "definition");
22790
0
        return (-1);
22791
0
    }
22792
0
    if ((aidc->keyrefDepth == -1) ||
22793
0
        (vctxt->depth < aidc->keyrefDepth))
22794
0
        aidc->keyrefDepth = vctxt->depth;
22795
0
      }
22796
0
  }
22797
  /*
22798
  * Lookup the augmented IDC item for the IDC definition.
22799
  */
22800
0
  aidc = vctxt->aidcs;
22801
0
  while (aidc != NULL) {
22802
0
      if (aidc->def == idc)
22803
0
    break;
22804
0
      aidc = aidc->next;
22805
0
  }
22806
0
  if (aidc == NULL) {
22807
0
      VERROR_INT("xmlSchemaIDCRegisterMatchers",
22808
0
    "Could not find an augmented IDC item for an IDC definition");
22809
0
      return (-1);
22810
0
  }
22811
  /*
22812
  * Create an IDC matcher for every IDC definition.
22813
  */
22814
0
  if (vctxt->idcMatcherCache != NULL) {
22815
      /*
22816
      * Reuse a cached matcher.
22817
      */
22818
0
      matcher = vctxt->idcMatcherCache;
22819
0
      vctxt->idcMatcherCache = matcher->nextCached;
22820
0
      matcher->nextCached = NULL;
22821
0
  } else {
22822
0
      matcher = (xmlSchemaIDCMatcherPtr)
22823
0
    xmlMalloc(sizeof(xmlSchemaIDCMatcher));
22824
0
      if (matcher == NULL) {
22825
0
    xmlSchemaVErrMemory(vctxt);
22826
0
    return (-1);
22827
0
      }
22828
0
      memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
22829
0
  }
22830
0
  if (last == NULL)
22831
0
      vctxt->inode->idcMatchers = matcher;
22832
0
  else
22833
0
      last->next = matcher;
22834
0
  last = matcher;
22835
22836
0
  matcher->type = IDC_MATCHER;
22837
0
  matcher->depth = vctxt->depth;
22838
0
  matcher->aidc = aidc;
22839
0
  matcher->idcType = aidc->def->type;
22840
  /*
22841
  * Init the automaton state object.
22842
  */
22843
0
  if (xmlSchemaIDCAddStateObject(vctxt, matcher,
22844
0
      idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
22845
0
      return (-1);
22846
22847
0
  idc = idc->next;
22848
0
    } while (idc != NULL);
22849
0
    return (0);
22850
0
}
22851
22852
static int
22853
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
22854
         xmlSchemaNodeInfoPtr ielem)
22855
0
{
22856
0
    xmlSchemaPSVIIDCBindingPtr bind;
22857
0
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
22858
0
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
22859
0
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
22860
22861
0
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
22862
    /* vctxt->createIDCNodeTables */
22863
0
    while (matcher != NULL) {
22864
  /*
22865
  * Skip keyref IDCs and empty IDC target-lists.
22866
  */
22867
0
  if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
22868
0
      WXS_ILIST_IS_EMPTY(matcher->targets))
22869
0
  {
22870
0
      matcher = matcher->next;
22871
0
      continue;
22872
0
  }
22873
  /*
22874
  * If we _want_ the IDC node-table to be created in any case
22875
  * then do so. Otherwise create them only if keyrefs need them.
22876
  */
22877
0
  if ((! vctxt->createIDCNodeTables) &&
22878
0
      ((matcher->aidc->keyrefDepth == -1) ||
22879
0
       (matcher->aidc->keyrefDepth > vctxt->depth)))
22880
0
  {
22881
0
      matcher = matcher->next;
22882
0
      continue;
22883
0
  }
22884
  /*
22885
  * Get/create the IDC binding on this element for the IDC definition.
22886
  */
22887
0
  bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22888
0
  if (bind == NULL)
22889
0
     goto internal_error;
22890
22891
0
  if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
22892
0
      dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
22893
0
      nbDupls = bind->dupls->nbItems;
22894
0
  } else {
22895
0
      dupls = NULL;
22896
0
      nbDupls = 0;
22897
0
  }
22898
0
  if (bind->nodeTable != NULL) {
22899
0
      nbNodeTable = bind->nbNodes;
22900
0
  } else {
22901
0
      nbNodeTable = 0;
22902
0
  }
22903
22904
0
  if ((nbNodeTable == 0) && (nbDupls == 0)) {
22905
      /*
22906
      * Transfer all IDC target-nodes to the IDC node-table.
22907
      */
22908
0
            if (bind->nodeTable != NULL)
22909
0
                xmlFree(bind->nodeTable);
22910
0
      bind->nodeTable =
22911
0
    (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
22912
0
      bind->sizeNodes = matcher->targets->sizeItems;
22913
0
      bind->nbNodes = matcher->targets->nbItems;
22914
22915
0
      matcher->targets->items = NULL;
22916
0
      matcher->targets->sizeItems = 0;
22917
0
      matcher->targets->nbItems = 0;
22918
0
      if (matcher->htab) {
22919
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22920
0
    matcher->htab = NULL;
22921
0
      }
22922
0
  } else {
22923
      /*
22924
      * Compare the key-sequences and add to the IDC node-table.
22925
      */
22926
0
      nbTargets = matcher->targets->nbItems;
22927
0
      targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
22928
0
      nbFields = matcher->aidc->def->nbFields;
22929
0
      i = 0;
22930
0
      do {
22931
0
    keys = targets[i]->keys;
22932
0
    if (nbDupls) {
22933
        /*
22934
        * Search in already found duplicates first.
22935
        */
22936
0
        j = 0;
22937
0
        do {
22938
0
      if (nbFields == 1) {
22939
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
22940
0
        dupls[j]->keys[0]->val);
22941
0
          if (res == -1)
22942
0
        goto internal_error;
22943
0
          if (res == 1) {
22944
        /*
22945
        * Equal key-sequence.
22946
        */
22947
0
        goto next_target;
22948
0
          }
22949
0
      } else {
22950
0
          res = 0;
22951
0
          ntkeys = dupls[j]->keys;
22952
0
          for (k = 0; k < nbFields; k++) {
22953
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
22954
0
            ntkeys[k]->val);
22955
0
        if (res == -1)
22956
0
            goto internal_error;
22957
0
        if (res == 0) {
22958
            /*
22959
            * One of the keys differs.
22960
            */
22961
0
            break;
22962
0
        }
22963
0
          }
22964
0
          if (res == 1) {
22965
        /*
22966
        * Equal key-sequence found.
22967
        */
22968
0
        goto next_target;
22969
0
          }
22970
0
      }
22971
0
      j++;
22972
0
        } while (j < nbDupls);
22973
0
    }
22974
0
    if (bind->nbNodes) {
22975
0
        j = 0;
22976
0
        do {
22977
0
      if (nbFields == 1) {
22978
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
22979
0
        bind->nodeTable[j]->keys[0]->val);
22980
0
          if (res == -1)
22981
0
        goto internal_error;
22982
0
          if (res == 0) {
22983
        /*
22984
        * The key-sequence differs.
22985
        */
22986
0
        goto next_node_table_entry;
22987
0
          }
22988
0
      } else {
22989
0
          res = 0;
22990
0
          ntkeys = bind->nodeTable[j]->keys;
22991
0
          for (k = 0; k < nbFields; k++) {
22992
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
22993
0
            ntkeys[k]->val);
22994
0
        if (res == -1)
22995
0
            goto internal_error;
22996
0
        if (res == 0) {
22997
            /*
22998
            * One of the keys differs.
22999
            */
23000
0
            goto next_node_table_entry;
23001
0
        }
23002
0
          }
23003
0
      }
23004
      /*
23005
      * Add the duplicate to the list of duplicates.
23006
      */
23007
0
      if (bind->dupls == NULL) {
23008
0
          bind->dupls = xmlSchemaItemListCreate();
23009
0
          if (bind->dupls == NULL)
23010
0
        goto internal_error;
23011
0
      }
23012
0
      if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23013
0
          goto internal_error;
23014
0
                        dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23015
      /*
23016
      * Remove the duplicate entry from the IDC node-table.
23017
      */
23018
0
      bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23019
0
      bind->nbNodes--;
23020
23021
0
      goto next_target;
23022
23023
0
next_node_table_entry:
23024
0
      j++;
23025
0
        } while (j < bind->nbNodes);
23026
0
    }
23027
    /*
23028
    * If everything is fine, then add the IDC target-node to
23029
    * the IDC node-table.
23030
    */
23031
0
    if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23032
0
        goto internal_error;
23033
23034
0
next_target:
23035
0
    i++;
23036
0
      } while (i < nbTargets);
23037
0
  }
23038
0
  matcher = matcher->next;
23039
0
    }
23040
0
    return(0);
23041
23042
0
internal_error:
23043
0
    return(-1);
23044
0
}
23045
23046
/**
23047
 * Merges IDC bindings of an element at `depth` into the corresponding IDC
23048
 * bindings of its parent element. If a duplicate note-table entry is found,
23049
 * both, the parent node-table entry and child entry are discarded from the
23050
 * node-table of the parent.
23051
 *
23052
 * @param vctxt  the WXS validation context
23053
 * @returns 0 if OK and -1 on internal errors.
23054
 */
23055
static int
23056
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23057
0
{
23058
0
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23059
0
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23060
0
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23061
0
    xmlSchemaIDCAugPtr aidc;
23062
0
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23063
23064
0
    bind = vctxt->inode->idcTable;
23065
0
    if (bind == NULL) {
23066
  /* Fine, no table, no bubbles. */
23067
0
  return (0);
23068
0
    }
23069
23070
0
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23071
    /*
23072
    * Walk all bindings; create new or add to existing bindings.
23073
    * Remove duplicate key-sequences.
23074
    */
23075
0
    while (bind != NULL) {
23076
23077
0
  if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23078
0
      goto next_binding;
23079
  /*
23080
  * Check if the key/unique IDC table needs to be bubbled.
23081
  */
23082
0
  if (! vctxt->createIDCNodeTables) {
23083
0
      aidc = vctxt->aidcs;
23084
0
      do {
23085
0
    if (aidc->def == bind->definition) {
23086
0
        if ((aidc->keyrefDepth == -1) ||
23087
0
      (aidc->keyrefDepth >= vctxt->depth)) {
23088
0
      goto next_binding;
23089
0
        }
23090
0
        break;
23091
0
    }
23092
0
    aidc = aidc->next;
23093
0
      } while (aidc != NULL);
23094
0
  }
23095
23096
0
  if (parTable != NULL)
23097
0
      parBind = *parTable;
23098
  /*
23099
  * Search a matching parent binding for the
23100
  * IDC definition.
23101
  */
23102
0
  while (parBind != NULL) {
23103
0
      if (parBind->definition == bind->definition)
23104
0
    break;
23105
0
      parBind = parBind->next;
23106
0
  }
23107
23108
0
  if (parBind != NULL) {
23109
      /*
23110
      * Compare every node-table entry of the child node,
23111
      * i.e. the key-sequence within, ...
23112
      */
23113
0
      oldNum = parBind->nbNodes; /* Skip newly added items. */
23114
23115
0
      if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23116
0
    oldDupls = parBind->dupls->nbItems;
23117
0
    dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23118
0
      } else {
23119
0
    dupls = NULL;
23120
0
    oldDupls = 0;
23121
0
      }
23122
23123
0
      parNodes = parBind->nodeTable;
23124
0
      nbFields = bind->definition->nbFields;
23125
23126
0
      for (i = 0; i < bind->nbNodes; i++) {
23127
0
    node = bind->nodeTable[i];
23128
0
    if (node == NULL)
23129
0
        continue;
23130
    /*
23131
    * ...with every key-sequence of the parent node, already
23132
    * evaluated to be a duplicate key-sequence.
23133
    */
23134
0
    if (oldDupls) {
23135
0
        j = 0;
23136
0
        while (j < oldDupls) {
23137
0
      if (nbFields == 1) {
23138
0
          ret = xmlSchemaAreValuesEqual(
23139
0
        node->keys[0]->val,
23140
0
        dupls[j]->keys[0]->val);
23141
0
          if (ret == -1)
23142
0
        goto internal_error;
23143
0
          if (ret == 0) {
23144
0
        j++;
23145
0
        continue;
23146
0
          }
23147
0
      } else {
23148
0
          parNode = dupls[j];
23149
0
          for (k = 0; k < nbFields; k++) {
23150
0
        ret = xmlSchemaAreValuesEqual(
23151
0
            node->keys[k]->val,
23152
0
            parNode->keys[k]->val);
23153
0
        if (ret == -1)
23154
0
            goto internal_error;
23155
0
        if (ret == 0)
23156
0
            break;
23157
0
          }
23158
0
      }
23159
0
      if (ret == 1)
23160
          /* Duplicate found. */
23161
0
          break;
23162
0
      j++;
23163
0
        }
23164
0
        if (j != oldDupls) {
23165
      /* Duplicate found. Skip this entry. */
23166
0
      continue;
23167
0
        }
23168
0
    }
23169
    /*
23170
    * ... and with every key-sequence of the parent node.
23171
    */
23172
0
    if (oldNum) {
23173
0
        j = 0;
23174
0
        while (j < oldNum) {
23175
0
      parNode = parNodes[j];
23176
0
      if (nbFields == 1) {
23177
0
          ret = xmlSchemaAreValuesEqual(
23178
0
        node->keys[0]->val,
23179
0
        parNode->keys[0]->val);
23180
0
          if (ret == -1)
23181
0
        goto internal_error;
23182
0
          if (ret == 0) {
23183
0
        j++;
23184
0
        continue;
23185
0
          }
23186
0
      } else {
23187
0
          for (k = 0; k < nbFields; k++) {
23188
0
        ret = xmlSchemaAreValuesEqual(
23189
0
            node->keys[k]->val,
23190
0
            parNode->keys[k]->val);
23191
0
        if (ret == -1)
23192
0
            goto internal_error;
23193
0
        if (ret == 0)
23194
0
            break;
23195
0
          }
23196
0
      }
23197
0
      if (ret == 1)
23198
          /* Duplicate found. */
23199
0
          break;
23200
0
      j++;
23201
0
        }
23202
0
        if (j != oldNum) {
23203
      /*
23204
      * Handle duplicates. Move the duplicate in
23205
      * the parent's node-table to the list of
23206
      * duplicates.
23207
      */
23208
0
      oldNum--;
23209
0
      parBind->nbNodes--;
23210
      /*
23211
      * Move last old item to pos of duplicate.
23212
      */
23213
0
      parNodes[j] = parNodes[oldNum];
23214
23215
0
      if (parBind->nbNodes != oldNum) {
23216
          /*
23217
          * If new items exist, move last new item to
23218
          * last of old items.
23219
          */
23220
0
          parNodes[oldNum] =
23221
0
        parNodes[parBind->nbNodes];
23222
0
      }
23223
0
      if (parBind->dupls == NULL) {
23224
0
          parBind->dupls = xmlSchemaItemListCreate();
23225
0
          if (parBind->dupls == NULL)
23226
0
        goto internal_error;
23227
0
      }
23228
0
      xmlSchemaItemListAdd(parBind->dupls, parNode);
23229
0
            dupls = (xmlSchemaPSVIIDCNodePtr *)
23230
0
                            parBind->dupls->items;
23231
0
        } else {
23232
      /*
23233
      * Add the node-table entry (node and key-sequence) of
23234
      * the child node to the node table of the parent node.
23235
      */
23236
0
                        if (parBind->nbNodes >= parBind->sizeNodes) {
23237
0
                            xmlSchemaPSVIIDCNodePtr *tmp;
23238
0
                            int newSize;
23239
23240
0
                            newSize = xmlGrowCapacity(parBind->sizeNodes,
23241
0
                                                      sizeof(tmp[0]),
23242
0
                                                      10, XML_MAX_ITEMS);
23243
0
                            if (newSize < 0) {
23244
0
                                xmlSchemaVErrMemory(vctxt);
23245
0
                                goto internal_error;
23246
0
                            }
23247
0
                            tmp = xmlRealloc(parBind->nodeTable,
23248
0
                                             newSize * sizeof(tmp[0]));
23249
0
                            if (tmp == NULL) {
23250
0
                                xmlSchemaVErrMemory(vctxt);
23251
0
                                goto internal_error;
23252
0
                            }
23253
23254
0
                            parBind->nodeTable = tmp;
23255
0
                            parBind->sizeNodes = newSize;
23256
0
      }
23257
0
      parNodes = parBind->nodeTable;
23258
      /*
23259
      * Append the new node-table entry to the 'new node-table
23260
      * entries' section.
23261
      */
23262
0
      parNodes[parBind->nbNodes++] = node;
23263
0
        }
23264
23265
0
    }
23266
23267
0
      }
23268
0
  } else {
23269
      /*
23270
      * No binding for the IDC was found: create a new one and
23271
      * copy all node-tables.
23272
      */
23273
0
      parBind = xmlSchemaIDCNewBinding(bind->definition);
23274
0
      if (parBind == NULL)
23275
0
    goto internal_error;
23276
23277
      /*
23278
      * TODO: Hmm, how to optimize the initial number of
23279
      * allocated entries?
23280
      */
23281
0
      if (bind->nbNodes != 0) {
23282
    /*
23283
    * Add all IDC node-table entries.
23284
    */
23285
0
    if (! vctxt->psviExposeIDCNodeTables) {
23286
        /*
23287
        * Just move the entries.
23288
        * NOTE: this is quite save here, since
23289
        * all the keyref lookups have already been
23290
        * performed.
23291
        */
23292
0
        parBind->nodeTable = bind->nodeTable;
23293
0
        bind->nodeTable = NULL;
23294
0
        parBind->sizeNodes = bind->sizeNodes;
23295
0
        bind->sizeNodes = 0;
23296
0
        parBind->nbNodes = bind->nbNodes;
23297
0
        bind->nbNodes = 0;
23298
0
    } else {
23299
        /*
23300
        * Copy the entries.
23301
        */
23302
0
        parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23303
0
      xmlMalloc(bind->nbNodes *
23304
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
23305
0
        if (parBind->nodeTable == NULL) {
23306
0
      xmlSchemaVErrMemory(NULL);
23307
0
      xmlSchemaIDCFreeBinding(parBind);
23308
0
      goto internal_error;
23309
0
        }
23310
0
        parBind->sizeNodes = bind->nbNodes;
23311
0
        parBind->nbNodes = bind->nbNodes;
23312
0
        memcpy(parBind->nodeTable, bind->nodeTable,
23313
0
      bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23314
0
    }
23315
0
      }
23316
0
      if (bind->dupls) {
23317
    /*
23318
    * Move the duplicates.
23319
    */
23320
0
    if (parBind->dupls != NULL)
23321
0
        xmlSchemaItemListFree(parBind->dupls);
23322
0
    parBind->dupls = bind->dupls;
23323
0
    bind->dupls = NULL;
23324
0
      }
23325
0
            if (parTable != NULL) {
23326
0
                if (*parTable == NULL)
23327
0
                    *parTable = parBind;
23328
0
                else {
23329
0
                    parBind->next = *parTable;
23330
0
                    *parTable = parBind;
23331
0
                }
23332
0
            }
23333
0
  }
23334
23335
0
next_binding:
23336
0
  bind = bind->next;
23337
0
    }
23338
0
    return (0);
23339
23340
0
internal_error:
23341
0
    return(-1);
23342
0
}
23343
23344
/**
23345
 * Check the cvc-idc-keyref constraints.
23346
 *
23347
 * @param vctxt  the WXS validation context
23348
 */
23349
static int
23350
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23351
0
{
23352
0
    xmlSchemaIDCMatcherPtr matcher;
23353
0
    xmlSchemaPSVIIDCBindingPtr bind;
23354
23355
0
    matcher = vctxt->inode->idcMatchers;
23356
    /*
23357
    * Find a keyref.
23358
    */
23359
0
    while (matcher != NULL) {
23360
0
  if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23361
0
      matcher->targets &&
23362
0
      matcher->targets->nbItems)
23363
0
  {
23364
0
      int i, j, k, res, nbFields, hasDupls;
23365
0
      xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23366
0
      xmlSchemaPSVIIDCNodePtr refNode = NULL;
23367
0
      xmlHashTablePtr table = NULL;
23368
23369
0
      nbFields = matcher->aidc->def->nbFields;
23370
23371
      /*
23372
      * Find the IDC node-table for the referenced IDC key/unique.
23373
      */
23374
0
      bind = vctxt->inode->idcTable;
23375
0
      while (bind != NULL) {
23376
0
    if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23377
0
        bind->definition)
23378
0
        break;
23379
0
    bind = bind->next;
23380
0
      }
23381
0
      hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23382
      /*
23383
      * Search for a matching key-sequences.
23384
      */
23385
0
      if (bind) {
23386
0
    table = xmlHashCreate(bind->nbNodes * 2);
23387
0
    for (j = 0; j < bind->nbNodes; j++) {
23388
0
        xmlChar *value;
23389
0
        xmlIDCHashEntryPtr r, e;
23390
0
        keys = bind->nodeTable[j]->keys;
23391
0
        xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
23392
0
        e = xmlMalloc(sizeof *e);
23393
0
                    if (e == NULL) {
23394
0
                        xmlSchemaVErrMemory(vctxt);
23395
0
                        goto mem_error;
23396
0
                    }
23397
0
        e->index = j;
23398
0
        r = xmlHashLookup(table, value);
23399
0
        if (r) {
23400
0
      e->next = r->next;
23401
0
      r->next = e;
23402
0
        } else {
23403
0
      e->next = NULL;
23404
0
                        if (xmlHashAddEntry(table, value, e) < 0) {
23405
0
                            xmlSchemaVErrMemory(vctxt);
23406
0
                            xmlFree(e);
23407
0
                        }
23408
0
        }
23409
0
mem_error:
23410
0
        FREE_AND_NULL(value);
23411
0
    }
23412
0
      }
23413
0
      for (i = 0; i < matcher->targets->nbItems; i++) {
23414
0
    res = 0;
23415
0
    refNode = matcher->targets->items[i];
23416
0
    if (bind != NULL) {
23417
0
        xmlChar *value;
23418
0
        xmlIDCHashEntryPtr e;
23419
0
        refKeys = refNode->keys;
23420
0
        xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
23421
0
        e = xmlHashLookup(table, value);
23422
0
        FREE_AND_NULL(value);
23423
0
        res = 0;
23424
0
        for (;e; e = e->next) {
23425
0
      keys = bind->nodeTable[e->index]->keys;
23426
0
      for (k = 0; k < nbFields; k++) {
23427
0
          res = xmlSchemaAreValuesEqual(keys[k]->val,
23428
0
                refKeys[k]->val);
23429
0
          if (res == 0)
23430
0
              break;
23431
0
          else if (res == -1) {
23432
0
        return (-1);
23433
0
          }
23434
0
      }
23435
0
      if (res == 1) {
23436
          /*
23437
           * Match found.
23438
           */
23439
0
          break;
23440
0
      }
23441
0
        }
23442
0
        if ((res == 0) && hasDupls) {
23443
      /*
23444
      * Search in duplicates
23445
      */
23446
0
      for (j = 0; j < bind->dupls->nbItems; j++) {
23447
0
          keys = ((xmlSchemaPSVIIDCNodePtr)
23448
0
        bind->dupls->items[j])->keys;
23449
0
          for (k = 0; k < nbFields; k++) {
23450
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23451
0
            refKeys[k]->val);
23452
0
        if (res == 0)
23453
0
            break;
23454
0
        else if (res == -1) {
23455
0
            return (-1);
23456
0
        }
23457
0
          }
23458
0
          if (res == 1) {
23459
        /*
23460
        * Match in duplicates found.
23461
        */
23462
0
        xmlChar *str = NULL, *strB = NULL;
23463
0
        xmlSchemaKeyrefErr(vctxt,
23464
0
            XML_SCHEMAV_CVC_IDC, refNode,
23465
0
            (xmlSchemaTypePtr) matcher->aidc->def,
23466
0
            "More than one match found for "
23467
0
            "key-sequence %s of keyref '%s'",
23468
0
            xmlSchemaFormatIDCKeySequence(vctxt, &str,
23469
0
          refNode->keys, nbFields),
23470
0
            xmlSchemaGetComponentQName(&strB,
23471
0
          matcher->aidc->def));
23472
0
        FREE_AND_NULL(str);
23473
0
        FREE_AND_NULL(strB);
23474
0
        break;
23475
0
          }
23476
0
      }
23477
0
        }
23478
0
    }
23479
23480
0
    if (res == 0) {
23481
0
        xmlChar *str = NULL, *strB = NULL;
23482
0
        xmlSchemaKeyrefErr(vctxt,
23483
0
      XML_SCHEMAV_CVC_IDC, refNode,
23484
0
      (xmlSchemaTypePtr) matcher->aidc->def,
23485
0
      "No match found for key-sequence %s of keyref '%s'",
23486
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
23487
0
          refNode->keys, nbFields),
23488
0
      xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23489
0
        FREE_AND_NULL(str);
23490
0
        FREE_AND_NULL(strB);
23491
0
    }
23492
0
      }
23493
0
      if (table) {
23494
0
    xmlHashFree(table, xmlFreeIDCHashEntry);
23495
0
      }
23496
0
  }
23497
0
  matcher = matcher->next;
23498
0
    }
23499
    /* TODO: Return an error if any error encountered. */
23500
0
    return (0);
23501
0
}
23502
23503
/************************************************************************
23504
 *                  *
23505
 *      XML Reader validation code                      *
23506
 *                  *
23507
 ************************************************************************/
23508
23509
static xmlSchemaAttrInfoPtr
23510
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23511
0
{
23512
0
    xmlSchemaAttrInfoPtr iattr;
23513
    /*
23514
    * Grow/create list of attribute infos.
23515
    */
23516
0
    if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23517
0
        xmlSchemaAttrInfoPtr *tmp;
23518
0
        int oldSize = vctxt->sizeAttrInfos;
23519
0
        int newSize, i;
23520
23521
0
        newSize = xmlGrowCapacity(oldSize, sizeof(tmp[0]), 5, XML_MAX_ITEMS);
23522
0
  if (newSize < 0) {
23523
0
      xmlSchemaVErrMemory(vctxt);
23524
0
      return (NULL);
23525
0
  }
23526
0
  tmp = xmlRealloc(vctxt->attrInfos, newSize * sizeof(tmp[0]));
23527
0
  if (tmp == NULL) {
23528
0
      xmlSchemaVErrMemory(vctxt);
23529
0
      return (NULL);
23530
0
  }
23531
23532
0
        vctxt->attrInfos = tmp;
23533
0
        vctxt->sizeAttrInfos = newSize;
23534
23535
0
        for (i = oldSize; i < newSize; i++)
23536
0
            vctxt->attrInfos[i] = NULL;
23537
0
    }
23538
23539
0
    iattr = vctxt->attrInfos[vctxt->nbAttrInfos];
23540
0
    if (iattr != NULL) {
23541
0
  if (iattr->localName != NULL) {
23542
0
      VERROR_INT("xmlSchemaGetFreshAttrInfo",
23543
0
    "attr info not cleared");
23544
0
      return (NULL);
23545
0
  }
23546
0
  iattr->nodeType = XML_ATTRIBUTE_NODE;
23547
0
        vctxt->nbAttrInfos++;
23548
0
  return (iattr);
23549
0
    }
23550
23551
    /*
23552
    * Create an attribute info.
23553
    */
23554
0
    iattr = (xmlSchemaAttrInfoPtr)
23555
0
  xmlMalloc(sizeof(xmlSchemaAttrInfo));
23556
0
    if (iattr == NULL) {
23557
0
  xmlSchemaVErrMemory(vctxt);
23558
0
  return (NULL);
23559
0
    }
23560
0
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23561
0
    iattr->nodeType = XML_ATTRIBUTE_NODE;
23562
0
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23563
23564
0
    return (iattr);
23565
0
}
23566
23567
static int
23568
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23569
      xmlNodePtr attrNode,
23570
      int nodeLine,
23571
      const xmlChar *localName,
23572
      const xmlChar *nsName,
23573
      int ownedNames,
23574
      xmlChar *value,
23575
      int ownedValue)
23576
0
{
23577
0
    xmlSchemaAttrInfoPtr attr;
23578
23579
0
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
23580
0
    if (attr == NULL) {
23581
0
  VERROR_INT("xmlSchemaPushAttribute",
23582
0
      "calling xmlSchemaGetFreshAttrInfo()");
23583
0
  return (-1);
23584
0
    }
23585
0
    attr->node = attrNode;
23586
0
    attr->nodeLine = nodeLine;
23587
0
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23588
0
    attr->localName = localName;
23589
0
    attr->nsName = nsName;
23590
0
    if (ownedNames)
23591
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23592
    /*
23593
    * Evaluate if it's an XSI attribute.
23594
    */
23595
0
    if (nsName != NULL) {
23596
0
  if (xmlStrEqual(localName, BAD_CAST "nil")) {
23597
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23598
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23599
0
      }
23600
0
  } else if (xmlStrEqual(localName, BAD_CAST "type")) {
23601
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23602
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23603
0
      }
23604
0
  } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23605
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23606
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23607
0
      }
23608
0
  } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23609
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23610
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23611
0
      }
23612
0
  } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23613
0
      attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23614
0
  }
23615
0
    }
23616
0
    attr->value = value;
23617
0
    if (ownedValue)
23618
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23619
0
    if (attr->metaType != 0)
23620
0
  attr->state = XML_SCHEMAS_ATTR_META;
23621
0
    return (0);
23622
0
}
23623
23624
/**
23625
 * @param vctxt  the WXS validation context
23626
 * @param ielem  the element information item
23627
 */
23628
static void
23629
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23630
           xmlSchemaNodeInfoPtr ielem)
23631
0
{
23632
0
    ielem->hasKeyrefs = 0;
23633
0
    ielem->appliedXPath = 0;
23634
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23635
0
  FREE_AND_NULL(ielem->localName);
23636
0
  FREE_AND_NULL(ielem->nsName);
23637
0
    } else {
23638
0
  ielem->localName = NULL;
23639
0
  ielem->nsName = NULL;
23640
0
    }
23641
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
23642
0
  FREE_AND_NULL(ielem->value);
23643
0
    } else {
23644
0
  ielem->value = NULL;
23645
0
    }
23646
0
    if (ielem->val != NULL) {
23647
  /*
23648
  * PSVI TODO: Be careful not to free it when the value is
23649
  * exposed via PSVI.
23650
  */
23651
0
  xmlSchemaFreeValue(ielem->val);
23652
0
  ielem->val = NULL;
23653
0
    }
23654
0
    if (ielem->idcMatchers != NULL) {
23655
  /*
23656
  * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
23657
  *   Does it work?
23658
  */
23659
0
  xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
23660
#if 0
23661
  xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
23662
#endif
23663
0
  ielem->idcMatchers = NULL;
23664
0
    }
23665
0
    if (ielem->idcTable != NULL) {
23666
  /*
23667
  * OPTIMIZE TODO: Use a pool of IDC tables??.
23668
  */
23669
0
  xmlSchemaIDCFreeIDCTable(ielem->idcTable);
23670
0
  ielem->idcTable = NULL;
23671
0
    }
23672
0
    if (ielem->regexCtxt != NULL) {
23673
0
  xmlRegFreeExecCtxt(ielem->regexCtxt);
23674
0
  ielem->regexCtxt = NULL;
23675
0
    }
23676
0
    if (ielem->nsBindings != NULL) {
23677
0
  xmlFree((xmlChar **)ielem->nsBindings);
23678
0
  ielem->nsBindings = NULL;
23679
0
  ielem->nbNsBindings = 0;
23680
0
  ielem->sizeNsBindings = 0;
23681
0
    }
23682
0
}
23683
23684
/**
23685
 * Creates/reuses and initializes the element info item for
23686
 * the current tree depth.
23687
 *
23688
 * @param vctxt  the schema validation context
23689
 * @returns the element info item or NULL on API or internal errors.
23690
 */
23691
static xmlSchemaNodeInfoPtr
23692
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
23693
0
{
23694
0
    xmlSchemaNodeInfoPtr info = NULL;
23695
23696
0
    if (vctxt->depth > vctxt->sizeElemInfos) {
23697
0
  VERROR_INT("xmlSchemaGetFreshElemInfo",
23698
0
      "inconsistent depth encountered");
23699
0
  return (NULL);
23700
0
    }
23701
0
    if (vctxt->sizeElemInfos <= vctxt->depth) {
23702
0
        xmlSchemaNodeInfoPtr *tmp;
23703
0
        int oldSize = vctxt->sizeElemInfos;
23704
0
        int newSize, i;
23705
23706
0
        newSize = xmlGrowCapacity(oldSize, sizeof(tmp[0]), 10, XML_MAX_ITEMS);
23707
0
        if (newSize < 0) {
23708
0
            xmlSchemaVErrMemory(vctxt);
23709
0
            return (NULL);
23710
0
        }
23711
0
        tmp = xmlRealloc(vctxt->elemInfos, newSize * sizeof(tmp[0]));
23712
0
        if (tmp == NULL) {
23713
0
            xmlSchemaVErrMemory(vctxt);
23714
0
            return (NULL);
23715
0
        }
23716
23717
0
        vctxt->elemInfos = tmp;
23718
0
        vctxt->sizeElemInfos = newSize;
23719
23720
  /*
23721
  * We need the new memory to be NULLed.
23722
  * TODO: Use memset instead?
23723
  */
23724
0
  for (i = oldSize; i < newSize; i++)
23725
0
      vctxt->elemInfos[i] = NULL;
23726
0
    } else
23727
0
  info = vctxt->elemInfos[vctxt->depth];
23728
23729
0
    if (info == NULL) {
23730
0
  info = (xmlSchemaNodeInfoPtr)
23731
0
      xmlMalloc(sizeof(xmlSchemaNodeInfo));
23732
0
  if (info == NULL) {
23733
0
      xmlSchemaVErrMemory(vctxt);
23734
0
      return (NULL);
23735
0
  }
23736
0
  vctxt->elemInfos[vctxt->depth] = info;
23737
0
    } else {
23738
0
  if (info->localName != NULL) {
23739
0
      VERROR_INT("xmlSchemaGetFreshElemInfo",
23740
0
    "elem info has not been cleared");
23741
0
      return (NULL);
23742
0
  }
23743
0
    }
23744
0
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
23745
0
    info->nodeType = XML_ELEMENT_NODE;
23746
0
    info->depth = vctxt->depth;
23747
23748
0
    return (info);
23749
0
}
23750
23751
0
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
23752
0
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
23753
0
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
23754
23755
static int
23756
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
23757
      xmlNodePtr node,
23758
      xmlSchemaTypePtr type,
23759
      xmlSchemaValType valType,
23760
      const xmlChar * value,
23761
      xmlSchemaValPtr val,
23762
      unsigned long length,
23763
      int fireErrors)
23764
0
{
23765
0
    int ret, error = 0, found;
23766
23767
0
    xmlSchemaTypePtr tmpType;
23768
0
    xmlSchemaFacetLinkPtr facetLink;
23769
0
    xmlSchemaFacetPtr facet;
23770
0
    unsigned long len = 0;
23771
0
    xmlSchemaWhitespaceValueType ws;
23772
23773
    /*
23774
    * In Libxml2, derived built-in types have currently no explicit facets.
23775
    */
23776
0
    if (type->type == XML_SCHEMA_TYPE_BASIC)
23777
0
  return (0);
23778
23779
    /*
23780
    * NOTE: Do not jump away, if the facetSet of the given type is
23781
    * empty: until now, "pattern" and "enumeration" facets of the
23782
    * *base types* need to be checked as well.
23783
    */
23784
0
    if (type->facetSet == NULL)
23785
0
  goto pattern_and_enum;
23786
23787
0
    if (! WXS_IS_ATOMIC(type)) {
23788
0
  if (WXS_IS_LIST(type))
23789
0
      goto WXS_IS_LIST;
23790
0
  else
23791
0
      goto pattern_and_enum;
23792
0
    }
23793
23794
    /*
23795
    * Whitespace handling is only of importance for string-based
23796
    * types.
23797
    */
23798
0
    tmpType = xmlSchemaGetPrimitiveType(type);
23799
0
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
23800
0
  WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
23801
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type);
23802
0
    } else
23803
0
  ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
23804
23805
    /*
23806
    * If the value was not computed (for string or
23807
    * anySimpleType based types), then use the provided
23808
    * type.
23809
    */
23810
0
    if (val != NULL)
23811
0
  valType = xmlSchemaGetValType(val);
23812
23813
0
    ret = 0;
23814
0
    for (facetLink = type->facetSet; facetLink != NULL;
23815
0
  facetLink = facetLink->next) {
23816
  /*
23817
  * Skip the pattern "whiteSpace": it is used to
23818
  * format the character content beforehand.
23819
  */
23820
0
  switch (facetLink->facet->type) {
23821
0
      case XML_SCHEMA_FACET_WHITESPACE:
23822
0
      case XML_SCHEMA_FACET_PATTERN:
23823
0
      case XML_SCHEMA_FACET_ENUMERATION:
23824
0
    continue;
23825
0
      case XML_SCHEMA_FACET_LENGTH:
23826
0
      case XML_SCHEMA_FACET_MINLENGTH:
23827
0
      case XML_SCHEMA_FACET_MAXLENGTH:
23828
0
    ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
23829
0
        valType, value, val, &len, ws);
23830
0
    break;
23831
0
      default:
23832
0
    ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
23833
0
        valType, value, val, ws);
23834
0
    break;
23835
0
  }
23836
0
  if (ret < 0) {
23837
0
      AERROR_INT("xmlSchemaValidateFacets",
23838
0
    "validating against a atomic type facet");
23839
0
      return (-1);
23840
0
  } else if (ret > 0) {
23841
0
      if (fireErrors)
23842
0
    xmlSchemaFacetErr(actxt, ret, node,
23843
0
    value, len, type, facetLink->facet, NULL, NULL, NULL);
23844
0
      else
23845
0
    return (ret);
23846
0
      if (error == 0)
23847
0
    error = ret;
23848
0
  }
23849
0
  ret = 0;
23850
0
    }
23851
23852
0
WXS_IS_LIST:
23853
0
    if (! WXS_IS_LIST(type))
23854
0
  goto pattern_and_enum;
23855
    /*
23856
    * "length", "minLength" and "maxLength" of list types.
23857
    */
23858
0
    ret = 0;
23859
0
    for (facetLink = type->facetSet; facetLink != NULL;
23860
0
  facetLink = facetLink->next) {
23861
23862
0
  switch (facetLink->facet->type) {
23863
0
      case XML_SCHEMA_FACET_LENGTH:
23864
0
      case XML_SCHEMA_FACET_MINLENGTH:
23865
0
      case XML_SCHEMA_FACET_MAXLENGTH:
23866
0
    ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
23867
0
        value, length, NULL);
23868
0
    break;
23869
0
      default:
23870
0
    continue;
23871
0
  }
23872
0
  if (ret < 0) {
23873
0
      AERROR_INT("xmlSchemaValidateFacets",
23874
0
    "validating against a list type facet");
23875
0
      return (-1);
23876
0
  } else if (ret > 0) {
23877
0
      if (fireErrors)
23878
0
    xmlSchemaFacetErr(actxt, ret, node,
23879
0
    value, length, type, facetLink->facet, NULL, NULL, NULL);
23880
0
      else
23881
0
    return (ret);
23882
0
      if (error == 0)
23883
0
    error = ret;
23884
0
  }
23885
0
  ret = 0;
23886
0
    }
23887
23888
0
pattern_and_enum:
23889
0
    found = 0;
23890
    /*
23891
    * Process enumerations. Facet values are in the value space
23892
    * of the defining type's base type. This seems to be a bug in the
23893
    * XML Schema 1.0 spec. Use the whitespace type of the base type.
23894
    * Only the first set of enumerations in the ancestor-or-self axis
23895
    * is used for validation.
23896
    */
23897
0
    ret = 0;
23898
0
    tmpType = type;
23899
0
    do {
23900
0
        for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
23901
0
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
23902
0
                continue;
23903
0
            found = 1;
23904
0
            ret = xmlSchemaAreValuesEqual(facet->val, val);
23905
0
            if (ret == 1)
23906
0
                break;
23907
0
            else if (ret < 0) {
23908
0
                AERROR_INT("xmlSchemaValidateFacets",
23909
0
                    "validating against an enumeration facet");
23910
0
                return (-1);
23911
0
            }
23912
0
        }
23913
0
        if (ret != 0)
23914
0
            break;
23915
        /*
23916
        * Break on the first set of enumerations. Any additional
23917
        *  enumerations which might be existent on the ancestors
23918
        *  of the current type are restricted by this set; thus
23919
        *  *must* *not* be taken into account.
23920
        */
23921
0
        if (found)
23922
0
            break;
23923
0
        tmpType = tmpType->baseType;
23924
0
    } while ((tmpType != NULL) &&
23925
0
        (tmpType->type != XML_SCHEMA_TYPE_BASIC));
23926
0
    if (found && (ret == 0)) {
23927
0
        ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
23928
0
        if (fireErrors) {
23929
0
            xmlSchemaFacetErr(actxt, ret, node,
23930
0
                value, 0, type, NULL, NULL, NULL, NULL);
23931
0
        } else
23932
0
            return (ret);
23933
0
        if (error == 0)
23934
0
            error = ret;
23935
0
    }
23936
23937
    /*
23938
    * Process patters. Pattern facets are ORed at type level
23939
    * and ANDed if derived. Walk the base type axis.
23940
    */
23941
0
    tmpType = type;
23942
0
    facet = NULL;
23943
0
    do {
23944
0
        found = 0;
23945
0
        for (facetLink = tmpType->facetSet; facetLink != NULL;
23946
0
            facetLink = facetLink->next) {
23947
0
            if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
23948
0
                continue;
23949
0
            found = 1;
23950
            /*
23951
            * NOTE that for patterns, @value needs to be the
23952
            * normalized value.
23953
            */
23954
0
            ret = xmlRegexpExec(facetLink->facet->regexp, value);
23955
0
            if (ret == 1)
23956
0
                break;
23957
0
            else if (ret < 0) {
23958
0
                AERROR_INT("xmlSchemaValidateFacets",
23959
0
                    "validating against a pattern facet");
23960
0
                return (-1);
23961
0
            } else {
23962
                /*
23963
                * Save the last non-validating facet.
23964
                */
23965
0
                facet = facetLink->facet;
23966
0
            }
23967
0
        }
23968
0
        if (found && (ret != 1)) {
23969
0
            ret = XML_SCHEMAV_CVC_PATTERN_VALID;
23970
0
            if (fireErrors) {
23971
0
                xmlSchemaFacetErr(actxt, ret, node,
23972
0
                    value, 0, type, facet, NULL, NULL, NULL);
23973
0
            } else
23974
0
                return (ret);
23975
0
            if (error == 0)
23976
0
                error = ret;
23977
0
            break;
23978
0
        }
23979
0
        tmpType = tmpType->baseType;
23980
0
    } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
23981
23982
0
    return (error);
23983
0
}
23984
23985
static xmlChar *
23986
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
23987
      const xmlChar *value)
23988
0
{
23989
0
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
23990
0
  case XML_SCHEMA_WHITESPACE_COLLAPSE:
23991
0
      return (xmlSchemaCollapseString(value));
23992
0
  case XML_SCHEMA_WHITESPACE_REPLACE:
23993
0
      return (xmlSchemaWhiteSpaceReplace(value));
23994
0
  default:
23995
0
      return (NULL);
23996
0
    }
23997
0
}
23998
23999
static int
24000
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24001
           const xmlChar *value,
24002
           xmlSchemaValPtr *val,
24003
           int valNeeded)
24004
0
{
24005
0
    int ret;
24006
0
    xmlChar *stripped;
24007
0
    const xmlChar *nsName;
24008
0
    xmlChar *local, *prefix = NULL;
24009
24010
0
    ret = xmlValidateQName(value, 1);
24011
0
    if (ret != 0) {
24012
0
  if (ret == -1) {
24013
0
      VERROR_INT("xmlSchemaValidateQName",
24014
0
    "calling xmlValidateQName()");
24015
0
      return (-1);
24016
0
  }
24017
0
  return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24018
0
    }
24019
    /*
24020
    * NOTE: xmlSplitQName2 will always return a duplicated
24021
    * strings.
24022
    */
24023
    /* TODO: Export and use xmlSchemaStrip instead */
24024
0
    stripped = xmlSchemaCollapseString(value);
24025
0
    local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24026
0
    xmlFree(stripped);
24027
0
    if (local == NULL)
24028
0
  local = xmlStrdup(value);
24029
    /*
24030
    * OPTIMIZE TODO: Use flags for:
24031
    *  - is there any namespace binding?
24032
    *  - is there a default namespace?
24033
    */
24034
0
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24035
24036
0
    if (prefix != NULL) {
24037
0
  xmlFree(prefix);
24038
  /*
24039
  * A namespace must be found if the prefix is
24040
  * NOT NULL.
24041
  */
24042
0
  if (nsName == NULL) {
24043
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24044
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24045
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24046
0
    "The QName value '%s' has no "
24047
0
    "corresponding namespace declaration in "
24048
0
    "scope", value, NULL);
24049
0
      if (local != NULL)
24050
0
    xmlFree(local);
24051
0
      return (ret);
24052
0
  }
24053
0
    }
24054
0
    if (valNeeded && val) {
24055
0
  if (nsName != NULL)
24056
0
      *val = xmlSchemaNewQNameValue(
24057
0
    BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24058
0
  else
24059
0
      *val = xmlSchemaNewQNameValue(NULL,
24060
0
    BAD_CAST local);
24061
0
    } else
24062
0
  xmlFree(local);
24063
0
    return (0);
24064
0
}
24065
24066
/*
24067
* cvc-simple-type
24068
*/
24069
static int
24070
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24071
           xmlNodePtr node,
24072
           xmlSchemaTypePtr type,
24073
           const xmlChar *value,
24074
           xmlSchemaValPtr *retVal,
24075
           int fireErrors,
24076
           int normalize,
24077
           int isNormalized)
24078
0
{
24079
0
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
24080
0
    xmlSchemaValPtr val = NULL;
24081
    /* xmlSchemaWhitespaceValueType ws; */
24082
0
    xmlChar *normValue = NULL;
24083
24084
0
#define NORMALIZE(atype) \
24085
0
    if ((! isNormalized) && \
24086
0
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24087
0
  normValue = xmlSchemaNormalizeValue(atype, value); \
24088
0
  if (normValue != NULL) \
24089
0
      value = normValue; \
24090
0
  isNormalized = 1; \
24091
0
    }
24092
24093
0
    if ((retVal != NULL) && (*retVal != NULL)) {
24094
0
  xmlSchemaFreeValue(*retVal);
24095
0
  *retVal = NULL;
24096
0
    }
24097
    /*
24098
    * 3.14.4 Simple Type Definition Validation Rules
24099
    * Validation Rule: String Valid
24100
    */
24101
    /*
24102
    * 1 It is schema-valid with respect to that definition as defined
24103
    * by Datatype Valid in [XML Schemas: Datatypes].
24104
    */
24105
    /*
24106
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24107
    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24108
    * the string must be a `declared entity name`.
24109
    */
24110
    /*
24111
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24112
    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24113
    * then every whitespace-delimited substring of the string must be a `declared
24114
    * entity name`.
24115
    */
24116
    /*
24117
    * 2.3 otherwise no further condition applies.
24118
    */
24119
0
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24120
0
  valNeeded = 1;
24121
0
    if (value == NULL)
24122
0
  value = BAD_CAST "";
24123
0
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24124
0
  xmlSchemaTypePtr biType; /* The built-in type. */
24125
  /*
24126
  * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24127
  * a literal in the `lexical space` of {base type definition}"
24128
  */
24129
  /*
24130
  * Whitespace-normalize.
24131
  */
24132
0
  NORMALIZE(type);
24133
0
  if (type->type != XML_SCHEMA_TYPE_BASIC) {
24134
      /*
24135
      * Get the built-in type.
24136
      */
24137
0
      biType = type->baseType;
24138
0
      while ((biType != NULL) &&
24139
0
    (biType->type != XML_SCHEMA_TYPE_BASIC))
24140
0
    biType = biType->baseType;
24141
24142
0
      if (biType == NULL) {
24143
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24144
0
        "could not get the built-in type");
24145
0
    goto internal_error;
24146
0
      }
24147
0
  } else
24148
0
      biType = type;
24149
  /*
24150
  * NOTATIONs need to be processed here, since they need
24151
  * to lookup in the hashtable of NOTATION declarations of the schema.
24152
  */
24153
0
  if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24154
0
      switch (biType->builtInType) {
24155
0
    case XML_SCHEMAS_NOTATION:
24156
0
        ret = xmlSchemaValidateNotation(
24157
0
      (xmlSchemaValidCtxtPtr) actxt,
24158
0
      ((xmlSchemaValidCtxtPtr) actxt)->schema,
24159
0
      NULL, value, &val, valNeeded);
24160
0
        break;
24161
0
    case XML_SCHEMAS_QNAME:
24162
0
        ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24163
0
      value, &val, valNeeded);
24164
0
        break;
24165
0
    default:
24166
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24167
0
        if (valNeeded)
24168
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24169
0
          value, &val, node);
24170
0
        else
24171
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24172
0
          value, NULL, node);
24173
0
        break;
24174
0
      }
24175
0
  } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24176
0
      switch (biType->builtInType) {
24177
0
    case XML_SCHEMAS_NOTATION:
24178
0
        ret = xmlSchemaValidateNotation(NULL,
24179
0
      ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24180
0
      value, &val, valNeeded);
24181
0
        break;
24182
0
    default:
24183
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24184
0
        if (valNeeded)
24185
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24186
0
          value, &val, node);
24187
0
        else
24188
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24189
0
          value, NULL, node);
24190
0
        break;
24191
0
      }
24192
0
  } else {
24193
      /*
24194
      * Validation via a public API is not implemented yet.
24195
      */
24196
0
      goto internal_error;
24197
0
  }
24198
0
  if (ret != 0) {
24199
0
      if (ret < 0) {
24200
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24201
0
        "validating against a built-in type");
24202
0
    goto internal_error;
24203
0
      }
24204
0
      if (WXS_IS_LIST(type))
24205
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24206
0
      else
24207
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24208
0
  }
24209
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24210
      /*
24211
      * Check facets.
24212
      */
24213
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24214
0
    (xmlSchemaValType) biType->builtInType, value, val,
24215
0
    0, fireErrors);
24216
0
      if (ret != 0) {
24217
0
    if (ret < 0) {
24218
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24219
0
      "validating facets of atomic simple type");
24220
0
        goto internal_error;
24221
0
    }
24222
0
    if (WXS_IS_LIST(type))
24223
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24224
0
    else
24225
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24226
0
      }
24227
0
  }
24228
0
  else if (fireErrors && (ret > 0))
24229
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24230
0
    } else if (WXS_IS_LIST(type)) {
24231
24232
0
  xmlSchemaTypePtr itemType;
24233
0
  const xmlChar *cur, *end;
24234
0
  xmlChar *tmpValue = NULL;
24235
0
  unsigned long len = 0;
24236
0
  xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24237
  /* 1.2.2 if {variety} is `list` then the string must be a sequence
24238
  * of white space separated tokens, each of which `match`es a literal
24239
  * in the `lexical space` of {item type definition}
24240
  */
24241
  /*
24242
  * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24243
  * the list type has an enum or pattern facet.
24244
  */
24245
0
  NORMALIZE(type);
24246
  /*
24247
  * VAL TODO: Optimize validation of empty values.
24248
  * VAL TODO: We do not have computed values for lists.
24249
  */
24250
0
  itemType = WXS_LIST_ITEMTYPE(type);
24251
0
  cur = value;
24252
0
  do {
24253
0
      while (IS_BLANK_CH(*cur))
24254
0
    cur++;
24255
0
      end = cur;
24256
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24257
0
    end++;
24258
0
      if (end == cur)
24259
0
    break;
24260
0
      tmpValue = xmlStrndup(cur, end - cur);
24261
0
      len++;
24262
24263
0
      if (valNeeded)
24264
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24265
0
        tmpValue, &curVal, fireErrors, 0, 1);
24266
0
      else
24267
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24268
0
        tmpValue, NULL, fireErrors, 0, 1);
24269
0
      FREE_AND_NULL(tmpValue);
24270
0
      if (curVal != NULL) {
24271
    /*
24272
    * Add to list of computed values.
24273
    */
24274
0
    if (val == NULL)
24275
0
        val = curVal;
24276
0
    else
24277
0
        xmlSchemaValueAppend(prevVal, curVal);
24278
0
    prevVal = curVal;
24279
0
    curVal = NULL;
24280
0
      }
24281
0
      if (ret != 0) {
24282
0
    if (ret < 0) {
24283
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24284
0
      "validating an item of list simple type");
24285
0
        goto internal_error;
24286
0
    }
24287
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24288
0
    break;
24289
0
      }
24290
0
      cur = end;
24291
0
  } while (*cur != 0);
24292
0
  FREE_AND_NULL(tmpValue);
24293
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24294
      /*
24295
      * Apply facets (pattern, enumeration).
24296
      */
24297
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24298
0
    XML_SCHEMAS_UNKNOWN, value, val,
24299
0
    len, fireErrors);
24300
0
      if (ret != 0) {
24301
0
    if (ret < 0) {
24302
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24303
0
      "validating facets of list simple type");
24304
0
        goto internal_error;
24305
0
    }
24306
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24307
0
      }
24308
0
  }
24309
0
  if (fireErrors && (ret > 0)) {
24310
      /*
24311
      * Report the normalized value.
24312
      */
24313
0
      normalize = 1;
24314
0
      NORMALIZE(type);
24315
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24316
0
  }
24317
0
    } else if (WXS_IS_UNION(type)) {
24318
0
  xmlSchemaTypeLinkPtr memberLink;
24319
  /*
24320
  * TODO: For all datatypes `derived` by `union`  whiteSpace does
24321
  * not apply directly; however, the normalization behavior of `union`
24322
  * types is controlled by the value of whiteSpace on that one of the
24323
  * `memberTypes` against which the `union` is successfully validated.
24324
  *
24325
  * This means that the value is normalized by the first validating
24326
  * member type, then the facets of the union type are applied. This
24327
  * needs changing of the value!
24328
  */
24329
24330
  /*
24331
  * 1.2.3 if {variety} is `union` then the string must `match` a
24332
  * literal in the `lexical space` of at least one member of
24333
  * {member type definitions}
24334
  */
24335
0
  memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24336
0
  if (memberLink == NULL) {
24337
0
      AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24338
0
    "union simple type has no member types");
24339
0
      goto internal_error;
24340
0
  }
24341
  /*
24342
  * Always normalize union type values, since we currently
24343
  * cannot store the whitespace information with the value
24344
  * itself; otherwise a later value-comparison would be
24345
  * not possible.
24346
  */
24347
0
  while (memberLink != NULL) {
24348
0
      if (valNeeded)
24349
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24350
0
        memberLink->type, value, &val, 0, 1, 0);
24351
0
      else
24352
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24353
0
        memberLink->type, value, NULL, 0, 1, 0);
24354
0
      if (ret <= 0)
24355
0
    break;
24356
0
      memberLink = memberLink->next;
24357
0
  }
24358
0
  if (ret != 0) {
24359
0
      if (ret < 0) {
24360
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24361
0
        "validating members of union simple type");
24362
0
    goto internal_error;
24363
0
      }
24364
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24365
0
  }
24366
  /*
24367
  * Apply facets (pattern, enumeration).
24368
  */
24369
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24370
      /*
24371
      * The normalization behavior of `union` types is controlled by
24372
      * the value of whiteSpace on that one of the `memberTypes`
24373
      * against which the `union` is successfully validated.
24374
      */
24375
0
      NORMALIZE(memberLink->type);
24376
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24377
0
    XML_SCHEMAS_UNKNOWN, value, val,
24378
0
    0, fireErrors);
24379
0
      if (ret != 0) {
24380
0
    if (ret < 0) {
24381
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24382
0
      "validating facets of union simple type");
24383
0
        goto internal_error;
24384
0
    }
24385
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24386
0
      }
24387
0
  }
24388
0
  if (fireErrors && (ret > 0))
24389
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24390
0
    }
24391
24392
0
    if (normValue != NULL)
24393
0
  xmlFree(normValue);
24394
0
    if (ret == 0) {
24395
0
  if (retVal != NULL)
24396
0
      *retVal = val;
24397
0
  else if (val != NULL)
24398
0
      xmlSchemaFreeValue(val);
24399
0
    } else if (val != NULL)
24400
0
  xmlSchemaFreeValue(val);
24401
0
    return (ret);
24402
0
internal_error:
24403
0
    if (normValue != NULL)
24404
0
  xmlFree(normValue);
24405
0
    if (val != NULL)
24406
0
  xmlSchemaFreeValue(val);
24407
0
    return (-1);
24408
0
}
24409
24410
static int
24411
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24412
         const xmlChar *value,
24413
         const xmlChar **nsName,
24414
         const xmlChar **localName)
24415
0
{
24416
0
    int ret = 0;
24417
24418
0
    if ((nsName == NULL) || (localName == NULL))
24419
0
  return (-1);
24420
0
    *nsName = NULL;
24421
0
    *localName = NULL;
24422
24423
0
    ret = xmlValidateQName(value, 1);
24424
0
    if (ret == -1)
24425
0
  return (-1);
24426
0
    if (ret > 0) {
24427
0
  xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24428
0
      XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24429
0
      value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24430
0
  return (1);
24431
0
    }
24432
0
    {
24433
0
  xmlChar *local = NULL;
24434
0
  xmlChar *prefix;
24435
24436
  /*
24437
  * NOTE: xmlSplitQName2 will return a duplicated
24438
  * string.
24439
  */
24440
0
  local = xmlSplitQName2(value, &prefix);
24441
0
  if (local == NULL)
24442
0
      *localName = xmlDictLookup(vctxt->dict, value, -1);
24443
0
  else {
24444
0
      *localName = xmlDictLookup(vctxt->dict, local, -1);
24445
0
      xmlFree(local);
24446
0
  }
24447
24448
0
  *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24449
24450
0
  if (prefix != NULL) {
24451
0
      xmlFree(prefix);
24452
      /*
24453
      * A namespace must be found if the prefix is NOT NULL.
24454
      */
24455
0
      if (*nsName == NULL) {
24456
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24457
0
        XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24458
0
        WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24459
0
        "The QName value '%s' has no "
24460
0
        "corresponding namespace declaration in scope",
24461
0
        value, NULL);
24462
0
    return (2);
24463
0
      }
24464
0
  }
24465
0
    }
24466
0
    return (0);
24467
0
}
24468
24469
static int
24470
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24471
      xmlSchemaAttrInfoPtr iattr,
24472
      xmlSchemaTypePtr *localType,
24473
      xmlSchemaElementPtr elemDecl)
24474
0
{
24475
0
    int ret = 0;
24476
    /*
24477
    * cvc-elt (3.3.4) : (4)
24478
    * AND
24479
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
24480
    *   (1.2.1.2.1) - (1.2.1.2.4)
24481
    * Handle 'xsi:type'.
24482
    */
24483
0
    if (localType == NULL)
24484
0
  return (-1);
24485
0
    *localType = NULL;
24486
0
    if (iattr == NULL)
24487
0
  return (0);
24488
0
    else {
24489
0
  const xmlChar *nsName = NULL, *local = NULL;
24490
  /*
24491
  * TODO: We should report a *warning* that the type was overridden
24492
  * by the instance.
24493
  */
24494
0
  ACTIVATE_ATTRIBUTE(iattr);
24495
  /*
24496
  * (cvc-elt) (3.3.4) : (4.1)
24497
  * (cvc-assess-elt) (1.2.1.2.2)
24498
  */
24499
0
  ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24500
0
      &nsName, &local);
24501
0
  if (ret != 0) {
24502
0
      if (ret < 0) {
24503
0
    VERROR_INT("xmlSchemaValidateElementByDeclaration",
24504
0
        "calling xmlSchemaQNameExpand() to validate the "
24505
0
        "attribute 'xsi:type'");
24506
0
    goto internal_error;
24507
0
      }
24508
0
      goto exit;
24509
0
  }
24510
  /*
24511
  * (cvc-elt) (3.3.4) : (4.2)
24512
  * (cvc-assess-elt) (1.2.1.2.3)
24513
  */
24514
0
  *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24515
0
  if (*localType == NULL) {
24516
0
      xmlChar *str = NULL;
24517
24518
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
24519
0
    XML_SCHEMAV_CVC_ELT_4_2, NULL,
24520
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24521
0
    "The QName value '%s' of the xsi:type attribute does not "
24522
0
    "resolve to a type definition",
24523
0
    xmlSchemaFormatQName(&str, nsName, local), NULL);
24524
0
      FREE_AND_NULL(str);
24525
0
      ret = vctxt->err;
24526
0
      goto exit;
24527
0
  }
24528
0
  if (elemDecl != NULL) {
24529
0
      int set = 0;
24530
24531
      /*
24532
      * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24533
      * "The `local type definition` must be validly
24534
      * derived from the {type definition} given the union of
24535
      * the {disallowed substitutions} and the {type definition}'s
24536
      * {prohibited substitutions}, as defined in
24537
      * Type Derivation OK (Complex) ($3.4.6)
24538
      * (if it is a complex type definition),
24539
      * or given {disallowed substitutions} as defined in Type
24540
      * Derivation OK (Simple) ($3.14.6) (if it is a simple type
24541
      * definition)."
24542
      *
24543
      * {disallowed substitutions}: the "block" on the element decl.
24544
      * {prohibited substitutions}: the "block" on the type def.
24545
      */
24546
      /*
24547
      * OPTIMIZE TODO: We could map types already evaluated
24548
      * to be validly derived from other types to avoid checking
24549
      * this over and over for the same types.
24550
      */
24551
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24552
0
    (elemDecl->subtypes->flags &
24553
0
        XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24554
0
    set |= SUBSET_EXTENSION;
24555
24556
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24557
0
    (elemDecl->subtypes->flags &
24558
0
        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24559
0
    set |= SUBSET_RESTRICTION;
24560
24561
      /*
24562
      * REMOVED and CHANGED since this produced a parser context
24563
      * which adds to the string dict of the schema. So this would
24564
      * change the schema and we don't want this. We don't need
24565
      * the parser context anymore.
24566
      *
24567
      * if ((vctxt->pctxt == NULL) &&
24568
      * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24569
      *     return (-1);
24570
      */
24571
24572
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24573
0
    elemDecl->subtypes, set) != 0) {
24574
0
    xmlChar *str = NULL;
24575
24576
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24577
0
        XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24578
0
        "The type definition '%s', specified by xsi:type, is "
24579
0
        "blocked or not validly derived from the type definition "
24580
0
        "of the element declaration",
24581
0
        xmlSchemaFormatQName(&str,
24582
0
      (*localType)->targetNamespace,
24583
0
      (*localType)->name),
24584
0
        NULL);
24585
0
    FREE_AND_NULL(str);
24586
0
    ret = vctxt->err;
24587
0
    *localType = NULL;
24588
0
      }
24589
0
  }
24590
0
    }
24591
0
exit:
24592
0
    ACTIVATE_ELEM;
24593
0
    return (ret);
24594
0
internal_error:
24595
0
    ACTIVATE_ELEM;
24596
0
    return (-1);
24597
0
}
24598
24599
static int
24600
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24601
0
{
24602
0
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24603
0
    xmlSchemaTypePtr actualType;
24604
24605
    /*
24606
    * cvc-elt (3.3.4) : 1
24607
    */
24608
0
    if (elemDecl == NULL) {
24609
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24610
0
      "No matching declaration available");
24611
0
        return (vctxt->err);
24612
0
    }
24613
0
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
24614
    /*
24615
    * cvc-elt (3.3.4) : 2
24616
    */
24617
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24618
0
  VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24619
0
      "The element declaration is abstract");
24620
0
        return (vctxt->err);
24621
0
    }
24622
0
    if (actualType == NULL) {
24623
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24624
0
      "The type definition is absent");
24625
0
  return (XML_SCHEMAV_CVC_TYPE_1);
24626
0
    }
24627
0
    if (vctxt->nbAttrInfos != 0) {
24628
0
  int ret;
24629
0
  xmlSchemaAttrInfoPtr iattr;
24630
  /*
24631
  * cvc-elt (3.3.4) : 3
24632
  * Handle 'xsi:nil'.
24633
  */
24634
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
24635
0
      XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
24636
0
  if (iattr) {
24637
0
      ACTIVATE_ATTRIBUTE(iattr);
24638
      /*
24639
      * Validate the value.
24640
      */
24641
0
      ret = xmlSchemaVCheckCVCSimpleType(
24642
0
    ACTXT_CAST vctxt, NULL,
24643
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
24644
0
    iattr->value, &(iattr->val), 1, 0, 0);
24645
0
      ACTIVATE_ELEM;
24646
0
      if (ret < 0) {
24647
0
    VERROR_INT("xmlSchemaValidateElemDecl",
24648
0
        "calling xmlSchemaVCheckCVCSimpleType() to "
24649
0
        "validate the attribute 'xsi:nil'");
24650
0
    return (-1);
24651
0
      }
24652
0
      if (ret == 0) {
24653
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
24654
        /*
24655
        * cvc-elt (3.3.4) : 3.1
24656
        */
24657
0
        VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
24658
0
      "The element is not 'nillable'");
24659
        /* Does not return an error on purpose. */
24660
0
    } else {
24661
0
        if (xmlSchemaValueGetAsBoolean(iattr->val)) {
24662
      /*
24663
      * cvc-elt (3.3.4) : 3.2.2
24664
      */
24665
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
24666
0
          (elemDecl->value != NULL)) {
24667
0
          VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
24668
0
        "The element cannot be 'nilled' because "
24669
0
        "there is a fixed value constraint defined "
24670
0
        "for it");
24671
           /* Does not return an error on purpose. */
24672
0
      } else
24673
0
          vctxt->inode->flags |=
24674
0
        XML_SCHEMA_ELEM_INFO_NILLED;
24675
0
        }
24676
0
    }
24677
0
      }
24678
0
  }
24679
  /*
24680
  * cvc-elt (3.3.4) : 4
24681
  * Handle 'xsi:type'.
24682
  */
24683
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
24684
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
24685
0
  if (iattr) {
24686
0
      xmlSchemaTypePtr localType = NULL;
24687
24688
0
      ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
24689
0
    elemDecl);
24690
0
      if (ret != 0) {
24691
0
    if (ret == -1) {
24692
0
        VERROR_INT("xmlSchemaValidateElemDecl",
24693
0
      "calling xmlSchemaProcessXSIType() to "
24694
0
      "process the attribute 'xsi:type'");
24695
0
        return (-1);
24696
0
    }
24697
    /* Does not return an error on purpose. */
24698
0
      }
24699
0
      if (localType != NULL) {
24700
0
    vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
24701
0
    actualType = localType;
24702
0
      }
24703
0
  }
24704
0
    }
24705
    /*
24706
    * IDC: Register identity-constraint XPath matchers.
24707
    */
24708
0
    if ((elemDecl->idcs != NULL) &&
24709
0
  (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
24710
0
      return (-1);
24711
    /*
24712
    * No actual type definition.
24713
    */
24714
0
    if (actualType == NULL) {
24715
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24716
0
      "The type definition is absent");
24717
0
  return (XML_SCHEMAV_CVC_TYPE_1);
24718
0
    }
24719
    /*
24720
    * Remember the actual type definition.
24721
    */
24722
0
    vctxt->inode->typeDef = actualType;
24723
24724
0
    return (0);
24725
0
}
24726
24727
static int
24728
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
24729
0
{
24730
0
    xmlSchemaAttrInfoPtr iattr;
24731
0
    int ret = 0, i;
24732
24733
    /*
24734
    * SPEC cvc-type (3.1.1)
24735
    * "The attributes of must be empty, excepting those whose namespace
24736
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
24737
    * whose local name is one of type, nil, schemaLocation or
24738
    * noNamespaceSchemaLocation."
24739
    */
24740
0
    if (vctxt->nbAttrInfos == 0)
24741
0
  return (0);
24742
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
24743
0
  iattr = vctxt->attrInfos[i];
24744
0
  if (! iattr->metaType) {
24745
0
      ACTIVATE_ATTRIBUTE(iattr)
24746
0
      xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
24747
0
    XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
24748
0
      ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
24749
0
        }
24750
0
    }
24751
0
    ACTIVATE_ELEM
24752
0
    return (ret);
24753
0
}
24754
24755
/*
24756
* Cleanup currently used attribute infos.
24757
*/
24758
static void
24759
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
24760
0
{
24761
0
    int i;
24762
0
    xmlSchemaAttrInfoPtr attr;
24763
24764
0
    if (vctxt->nbAttrInfos == 0)
24765
0
  return;
24766
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
24767
0
  attr = vctxt->attrInfos[i];
24768
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
24769
0
      if (attr->localName != NULL)
24770
0
    xmlFree((xmlChar *) attr->localName);
24771
0
      if (attr->nsName != NULL)
24772
0
    xmlFree((xmlChar *) attr->nsName);
24773
0
  }
24774
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24775
0
      if (attr->value != NULL)
24776
0
    xmlFree((xmlChar *) attr->value);
24777
0
  }
24778
0
  if (attr->val != NULL) {
24779
0
      xmlSchemaFreeValue(attr->val);
24780
0
      attr->val = NULL;
24781
0
  }
24782
0
  memset(attr, 0, sizeof(xmlSchemaAttrInfo));
24783
0
    }
24784
0
    vctxt->nbAttrInfos = 0;
24785
0
}
24786
24787
/*
24788
* 3.4.4 Complex Type Definition Validation Rules
24789
*   Element Locally Valid (Complex Type) (cvc-complex-type)
24790
* 3.2.4 Attribute Declaration Validation Rules
24791
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
24792
*   Attribute Locally Valid (Use) (cvc-au)
24793
*
24794
* Only "assessed" attribute information items will be visible to
24795
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
24796
*/
24797
static int
24798
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
24799
0
{
24800
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef;
24801
0
    xmlSchemaItemListPtr attrUseList;
24802
0
    xmlSchemaAttributeUsePtr attrUse = NULL;
24803
0
    xmlSchemaAttributePtr attrDecl = NULL;
24804
0
    xmlSchemaAttrInfoPtr iattr, tmpiattr;
24805
0
    int i, j, found, nbAttrs, nbUses;
24806
0
    int xpathRes = 0, res, wildIDs = 0, fixed;
24807
0
    xmlNodePtr defAttrOwnerElem = NULL;
24808
24809
    /*
24810
    * SPEC (cvc-attribute)
24811
    * (1) "The declaration must not be `absent` (see Missing
24812
    * Sub-components ($5.3) for how this can fail to be
24813
    * the case)."
24814
    * (2) "Its {type definition} must not be absent."
24815
    *
24816
    * NOTE (1) + (2): This is not handled here, since we currently do not
24817
    * allow validation against schemas which have missing sub-components.
24818
    *
24819
    * SPEC (cvc-complex-type)
24820
    * (3) "For each attribute information item in the element information
24821
    * item's [attributes] excepting those whose [namespace name] is
24822
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
24823
    * [local name] is one of type, nil, schemaLocation or
24824
    * noNamespaceSchemaLocation, the appropriate case among the following
24825
    * must be true:
24826
    *
24827
    */
24828
0
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
24829
    /*
24830
    * @nbAttrs is the number of attributes present in the instance.
24831
    */
24832
0
    nbAttrs = vctxt->nbAttrInfos;
24833
0
    if (attrUseList != NULL)
24834
0
  nbUses = attrUseList->nbItems;
24835
0
    else
24836
0
  nbUses = 0;
24837
0
    for (i = 0; i < nbUses; i++) {
24838
0
        found = 0;
24839
0
  attrUse = attrUseList->items[i];
24840
0
  attrDecl = WXS_ATTRUSE_DECL(attrUse);
24841
0
        for (j = 0; j < nbAttrs; j++) {
24842
0
      iattr = vctxt->attrInfos[j];
24843
      /*
24844
      * SPEC (cvc-complex-type) (3)
24845
      * Skip meta attributes.
24846
      */
24847
0
      if (iattr->metaType)
24848
0
    continue;
24849
0
      if (iattr->localName[0] != attrDecl->name[0])
24850
0
    continue;
24851
0
      if (!xmlStrEqual(iattr->localName, attrDecl->name))
24852
0
    continue;
24853
0
      if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
24854
0
    continue;
24855
0
      found = 1;
24856
      /*
24857
      * SPEC (cvc-complex-type)
24858
      * (3.1) "If there is among the {attribute uses} an attribute
24859
      * use with an {attribute declaration} whose {name} matches
24860
      * the attribute information item's [local name] and whose
24861
      * {target namespace} is identical to the attribute information
24862
      * item's [namespace name] (where an `absent` {target namespace}
24863
      * is taken to be identical to a [namespace name] with no value),
24864
      * then the attribute information must be `valid` with respect
24865
      * to that attribute use as per Attribute Locally Valid (Use)
24866
      * ($3.5.4). In this case the {attribute declaration} of that
24867
      * attribute use is the `context-determined declaration` for the
24868
      * attribute information item with respect to Schema-Validity
24869
      * Assessment (Attribute) ($3.2.4) and
24870
      * Assessment Outcome (Attribute) ($3.2.5).
24871
      */
24872
0
      iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
24873
0
      iattr->use = attrUse;
24874
      /*
24875
      * Context-determined declaration.
24876
      */
24877
0
      iattr->decl = attrDecl;
24878
0
      iattr->typeDef = attrDecl->subtypes;
24879
0
      break;
24880
0
  }
24881
24882
0
  if (found)
24883
0
      continue;
24884
24885
0
  if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
24886
      /*
24887
      * Handle non-existent, required attributes.
24888
      *
24889
      * SPEC (cvc-complex-type)
24890
      * (4) "The {attribute declaration} of each attribute use in
24891
      * the {attribute uses} whose {required} is true matches one
24892
      * of the attribute information items in the element information
24893
      * item's [attributes] as per clause 3.1 above."
24894
      */
24895
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
24896
0
      if (tmpiattr == NULL) {
24897
0
    VERROR_INT(
24898
0
        "xmlSchemaVAttributesComplex",
24899
0
        "calling xmlSchemaGetFreshAttrInfo()");
24900
0
    return (-1);
24901
0
      }
24902
0
      tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
24903
0
      tmpiattr->use = attrUse;
24904
0
      tmpiattr->decl = attrDecl;
24905
0
  } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
24906
0
      ((attrUse->defValue != NULL) ||
24907
0
       (attrDecl->defValue != NULL))) {
24908
      /*
24909
      * Handle non-existent, optional, default/fixed attributes.
24910
      */
24911
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
24912
0
      if (tmpiattr == NULL) {
24913
0
    VERROR_INT(
24914
0
        "xmlSchemaVAttributesComplex",
24915
0
        "calling xmlSchemaGetFreshAttrInfo()");
24916
0
    return (-1);
24917
0
      }
24918
0
      tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
24919
0
      tmpiattr->use = attrUse;
24920
0
      tmpiattr->decl = attrDecl;
24921
0
      tmpiattr->typeDef = attrDecl->subtypes;
24922
0
      tmpiattr->localName = attrDecl->name;
24923
0
      tmpiattr->nsName = attrDecl->targetNamespace;
24924
0
  }
24925
0
    }
24926
24927
0
    if (vctxt->nbAttrInfos == 0)
24928
0
  return (0);
24929
    /*
24930
    * Validate against the wildcard.
24931
    */
24932
0
    if (type->attributeWildcard != NULL) {
24933
  /*
24934
  * SPEC (cvc-complex-type)
24935
  * (3.2.1) "There must be an {attribute wildcard}."
24936
  */
24937
0
  for (i = 0; i < nbAttrs; i++) {
24938
0
      iattr = vctxt->attrInfos[i];
24939
      /*
24940
      * SPEC (cvc-complex-type) (3)
24941
      * Skip meta attributes.
24942
      */
24943
0
      if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
24944
0
    continue;
24945
      /*
24946
      * SPEC (cvc-complex-type)
24947
      * (3.2.2) "The attribute information item must be `valid` with
24948
      * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
24949
      *
24950
      * SPEC Item Valid (Wildcard) (cvc-wildcard)
24951
      * "... its [namespace name] must be `valid` with respect to
24952
      * the wildcard constraint, as defined in Wildcard allows
24953
      * Namespace Name ($3.10.4)."
24954
      */
24955
0
      if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
24956
0
        iattr->nsName) == 0) {
24957
    /*
24958
    * Handle processContents.
24959
    *
24960
    * SPEC (cvc-wildcard):
24961
    * processContents | context-determined declaration:
24962
    * "strict"          "mustFind"
24963
    * "lax"             "none"
24964
    * "skip"            "skip"
24965
    */
24966
0
    if (type->attributeWildcard->processContents ==
24967
0
        XML_SCHEMAS_ANY_SKIP) {
24968
         /*
24969
        * context-determined declaration = "skip"
24970
        *
24971
        * SPEC PSVI Assessment Outcome (Attribute)
24972
        * [validity] = "notKnown"
24973
        * [validation attempted] = "none"
24974
        */
24975
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
24976
0
        continue;
24977
0
    }
24978
    /*
24979
    * Find an attribute declaration.
24980
    */
24981
0
    iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
24982
0
        iattr->localName, iattr->nsName);
24983
0
    if (iattr->decl != NULL) {
24984
0
        iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
24985
        /*
24986
        * SPEC (cvc-complex-type)
24987
        * (5) "Let [Definition:]  the wild IDs be the set of
24988
        * all attribute information item to which clause 3.2
24989
        * applied and whose `validation` resulted in a
24990
        * `context-determined declaration` of mustFind or no
24991
        * `context-determined declaration` at all, and whose
24992
        * [local name] and [namespace name] resolve (as
24993
        * defined by QName resolution (Instance) ($3.15.4)) to
24994
        * an attribute declaration whose {type definition} is
24995
        * or is derived from ID. Then all of the following
24996
        * must be true:"
24997
        */
24998
0
        iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
24999
0
        if (xmlSchemaIsDerivedFromBuiltInType(
25000
0
      iattr->typeDef, XML_SCHEMAS_ID)) {
25001
      /*
25002
      * SPEC (5.1) "There must be no more than one
25003
      * item in `wild IDs`."
25004
      */
25005
0
      if (wildIDs != 0) {
25006
          /* VAL TODO */
25007
0
          iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25008
0
          continue;
25009
0
      }
25010
0
      wildIDs++;
25011
      /*
25012
      * SPEC (cvc-complex-type)
25013
      * (5.2) "If `wild IDs` is non-empty, there must not
25014
      * be any attribute uses among the {attribute uses}
25015
      * whose {attribute declaration}'s {type definition}
25016
      * is or is derived from ID."
25017
      */
25018
0
                        if (attrUseList != NULL) {
25019
0
                            for (j = 0; j < attrUseList->nbItems; j++) {
25020
0
                                if (xmlSchemaIsDerivedFromBuiltInType(
25021
0
                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25022
0
                                    XML_SCHEMAS_ID)) {
25023
                                    /* URGENT VAL TODO: implement */
25024
0
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25025
0
                                    break;
25026
0
                                }
25027
0
                            }
25028
0
                        }
25029
0
        }
25030
0
    } else if (type->attributeWildcard->processContents ==
25031
0
        XML_SCHEMAS_ANY_LAX) {
25032
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25033
        /*
25034
        * SPEC PSVI Assessment Outcome (Attribute)
25035
        * [validity] = "notKnown"
25036
        * [validation attempted] = "none"
25037
        */
25038
0
    } else {
25039
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25040
0
    }
25041
0
      }
25042
0
  }
25043
0
    }
25044
25045
0
    if (vctxt->nbAttrInfos == 0)
25046
0
  return (0);
25047
25048
    /*
25049
    * Get the owner element; needed for creation of default attributes.
25050
    * This fixes bug #341337, reported by David Grohmann.
25051
    */
25052
0
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25053
0
  xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25054
0
  if (ielem && ielem->node && ielem->node->doc)
25055
0
      defAttrOwnerElem = ielem->node;
25056
0
    }
25057
    /*
25058
    * Validate values, create default attributes, evaluate IDCs.
25059
    */
25060
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25061
0
  iattr = vctxt->attrInfos[i];
25062
  /*
25063
  * VAL TODO: Note that we won't try to resolve IDCs to
25064
  * "lax" and "skip" validated attributes. Check what to
25065
  * do in this case.
25066
  */
25067
0
  if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25068
0
      (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25069
0
      continue;
25070
  /*
25071
  * VAL TODO: What to do if the type definition is missing?
25072
  */
25073
0
  if (iattr->typeDef == NULL) {
25074
0
      iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25075
0
      continue;
25076
0
  }
25077
25078
0
  ACTIVATE_ATTRIBUTE(iattr);
25079
0
  fixed = 0;
25080
0
  xpathRes = 0;
25081
25082
0
  if (vctxt->xpathStates != NULL) {
25083
      /*
25084
      * Evaluate IDCs.
25085
      */
25086
0
      xpathRes = xmlSchemaXPathEvaluate(vctxt,
25087
0
    XML_ATTRIBUTE_NODE);
25088
0
      if (xpathRes == -1) {
25089
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25090
0
        "calling xmlSchemaXPathEvaluate()");
25091
0
    goto internal_error;
25092
0
      }
25093
0
  }
25094
25095
0
  if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25096
      /*
25097
      * Default/fixed attributes.
25098
      * We need the value only if we need to resolve IDCs or
25099
      * will create default attributes.
25100
      */
25101
0
      if ((xpathRes) || (defAttrOwnerElem)) {
25102
0
    if (iattr->use->defValue != NULL) {
25103
0
        iattr->value = (xmlChar *) iattr->use->defValue;
25104
0
        iattr->val = iattr->use->defVal;
25105
0
    } else {
25106
0
        iattr->value = (xmlChar *) iattr->decl->defValue;
25107
0
        iattr->val = iattr->decl->defVal;
25108
0
    }
25109
    /*
25110
    * IDCs will consume the precomputed default value,
25111
    * so we need to clone it.
25112
    */
25113
0
    if (iattr->val == NULL) {
25114
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25115
0
      "default/fixed value on an attribute use was "
25116
0
      "not precomputed");
25117
0
        goto internal_error;
25118
0
    }
25119
0
    iattr->val = xmlSchemaCopyValue(iattr->val);
25120
0
    if (iattr->val == NULL) {
25121
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25122
0
      "calling xmlSchemaCopyValue()");
25123
0
        goto internal_error;
25124
0
    }
25125
0
      }
25126
      /*
25127
      * PSVI: Add the default attribute to the current element.
25128
      * VAL TODO: Should we use the *normalized* value? This currently
25129
      *   uses the *initial* value.
25130
      */
25131
25132
0
      if (defAttrOwnerElem) {
25133
0
    xmlChar *normValue;
25134
0
    const xmlChar *value;
25135
25136
0
    value = iattr->value;
25137
    /*
25138
    * Normalize the value.
25139
    */
25140
0
    normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25141
0
        iattr->value);
25142
0
    if (normValue != NULL)
25143
0
        value = BAD_CAST normValue;
25144
25145
0
    if (iattr->nsName == NULL) {
25146
0
        if (xmlNewProp(defAttrOwnerElem,
25147
0
      iattr->localName, value) == NULL) {
25148
0
      VERROR_INT("xmlSchemaVAttributesComplex",
25149
0
          "calling xmlNewProp()");
25150
0
      if (normValue != NULL)
25151
0
          xmlFree(normValue);
25152
0
      goto internal_error;
25153
0
        }
25154
0
    } else {
25155
0
        xmlNsPtr ns;
25156
25157
0
        ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25158
0
      defAttrOwnerElem, iattr->nsName);
25159
0
        if (ns == NULL) {
25160
0
      xmlChar prefix[13];
25161
0
      int counter = 0;
25162
25163
      /*
25164
      * Create a namespace declaration on the validation
25165
      * root node if no namespace declaration is in scope.
25166
      */
25167
0
      do {
25168
0
          snprintf((char *) prefix, 13, "p%d", counter++);
25169
0
          ns = xmlSearchNs(defAttrOwnerElem->doc,
25170
0
        defAttrOwnerElem, BAD_CAST prefix);
25171
0
          if (counter > 1000) {
25172
0
        VERROR_INT(
25173
0
            "xmlSchemaVAttributesComplex",
25174
0
            "could not compute a ns prefix for a "
25175
0
            "default/fixed attribute");
25176
0
        if (normValue != NULL)
25177
0
            xmlFree(normValue);
25178
0
        goto internal_error;
25179
0
          }
25180
0
      } while (ns != NULL);
25181
0
      ns = xmlNewNs(vctxt->validationRoot,
25182
0
          iattr->nsName, BAD_CAST prefix);
25183
0
        }
25184
        /*
25185
        * TODO:
25186
        * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25187
        * If we have QNames: do we need to ensure there's a
25188
        * prefix defined for the QName?
25189
        */
25190
0
        xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25191
0
    }
25192
0
    if (normValue != NULL)
25193
0
        xmlFree(normValue);
25194
0
      }
25195
      /*
25196
      * Go directly to IDC evaluation.
25197
      */
25198
0
      goto eval_idcs;
25199
0
  }
25200
  /*
25201
  * Validate the value.
25202
  */
25203
0
  if (vctxt->value != NULL) {
25204
      /*
25205
      * Free last computed value; just for safety reasons.
25206
      */
25207
0
      xmlSchemaFreeValue(vctxt->value);
25208
0
      vctxt->value = NULL;
25209
0
  }
25210
  /*
25211
  * Note that the attribute *use* can be unavailable, if
25212
  * the attribute was a wild attribute.
25213
  */
25214
0
  if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25215
0
      ((iattr->use != NULL) &&
25216
0
       (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25217
0
      fixed = 1;
25218
0
  else
25219
0
      fixed = 0;
25220
  /*
25221
  * SPEC (cvc-attribute)
25222
  * (3) "The item's `normalized value` must be locally `valid`
25223
  * with respect to that {type definition} as per
25224
  * String Valid ($3.14.4)."
25225
  *
25226
  * VAL TODO: Do we already have the
25227
  * "normalized attribute value" here?
25228
  */
25229
0
  if (xpathRes || fixed) {
25230
0
      iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25231
      /*
25232
      * Request a computed value.
25233
      */
25234
0
      res = xmlSchemaVCheckCVCSimpleType(
25235
0
    ACTXT_CAST vctxt,
25236
0
    iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25237
0
    1, 1, 0);
25238
0
  } else {
25239
0
      res = xmlSchemaVCheckCVCSimpleType(
25240
0
    ACTXT_CAST vctxt,
25241
0
    iattr->node, iattr->typeDef, iattr->value, NULL,
25242
0
    1, 0, 0);
25243
0
  }
25244
25245
0
  if (res != 0) {
25246
0
      if (res == -1) {
25247
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25248
0
        "calling xmlSchemaStreamValidateSimpleTypeValue()");
25249
0
    goto internal_error;
25250
0
      }
25251
0
      iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25252
      /*
25253
      * SPEC PSVI Assessment Outcome (Attribute)
25254
      * [validity] = "invalid"
25255
      */
25256
0
      goto eval_idcs;
25257
0
  }
25258
25259
0
  if (fixed) {
25260
      /*
25261
      * SPEC Attribute Locally Valid (Use) (cvc-au)
25262
      * "For an attribute information item to be `valid`
25263
      * with respect to an attribute use its *normalized*
25264
      * value must match the *canonical* lexical
25265
      * representation of the attribute use's {value
25266
      * constraint}value, if it is present and fixed."
25267
      *
25268
      * VAL TODO: The requirement for the *canonical* value
25269
      * will be removed in XML Schema 1.1.
25270
      */
25271
      /*
25272
      * SPEC Attribute Locally Valid (cvc-attribute)
25273
      * (4) "The item's *actual* value must match the *value* of
25274
      * the {value constraint}, if it is present and fixed."
25275
      */
25276
0
      if (iattr->val == NULL) {
25277
    /* VAL TODO: A value was not precomputed. */
25278
0
    goto eval_idcs;
25279
0
      }
25280
0
      if ((iattr->use != NULL) &&
25281
0
    (iattr->use->defValue != NULL)) {
25282
0
    if (iattr->use->defVal == NULL) {
25283
        /* VAL TODO: A default value was not precomputed. */
25284
0
        goto eval_idcs;
25285
0
    }
25286
0
    iattr->vcValue = iattr->use->defValue;
25287
    /*
25288
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25289
        (xmlSchemaWhitespaceValueType) ws,
25290
        attr->use->defVal,
25291
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25292
    */
25293
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25294
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25295
0
      } else {
25296
0
    if (iattr->decl->defVal == NULL) {
25297
        /* VAL TODO: A default value was not precomputed. */
25298
0
        goto eval_idcs;
25299
0
    }
25300
0
    iattr->vcValue = iattr->decl->defValue;
25301
    /*
25302
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25303
        (xmlSchemaWhitespaceValueType) ws,
25304
        attrDecl->defVal,
25305
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25306
    */
25307
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25308
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25309
0
      }
25310
      /*
25311
      * [validity] = "valid"
25312
      */
25313
0
  }
25314
0
eval_idcs:
25315
  /*
25316
  * Evaluate IDCs.
25317
  */
25318
0
  if (xpathRes) {
25319
0
      if (xmlSchemaXPathProcessHistory(vctxt,
25320
0
    vctxt->depth +1) == -1) {
25321
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25322
0
        "calling xmlSchemaXPathEvaluate()");
25323
0
    goto internal_error;
25324
0
      }
25325
0
  } else if (vctxt->xpathStates != NULL)
25326
0
      xmlSchemaXPathPop(vctxt);
25327
0
    }
25328
25329
    /*
25330
    * Report errors.
25331
    */
25332
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25333
0
  iattr = vctxt->attrInfos[i];
25334
0
  if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25335
0
      (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25336
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25337
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25338
0
      continue;
25339
0
  ACTIVATE_ATTRIBUTE(iattr);
25340
0
  switch (iattr->state) {
25341
0
      case XML_SCHEMAS_ATTR_ERR_MISSING: {
25342
0
        xmlChar *str = NULL;
25343
0
        ACTIVATE_ELEM;
25344
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
25345
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25346
0
      "The attribute '%s' is required but missing",
25347
0
      xmlSchemaFormatQName(&str,
25348
0
          iattr->decl->targetNamespace,
25349
0
          iattr->decl->name),
25350
0
      NULL);
25351
0
        FREE_AND_NULL(str)
25352
0
        break;
25353
0
    }
25354
0
      case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25355
0
    VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25356
0
        "The type definition is absent");
25357
0
    break;
25358
0
      case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25359
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25360
0
        XML_SCHEMAV_CVC_AU, NULL, NULL,
25361
0
        "The value '%s' does not match the fixed "
25362
0
        "value constraint '%s'",
25363
0
        iattr->value, iattr->vcValue);
25364
0
    break;
25365
0
      case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25366
0
    VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25367
0
        "No matching global attribute declaration available, but "
25368
0
        "demanded by the strict wildcard");
25369
0
    break;
25370
0
      case XML_SCHEMAS_ATTR_UNKNOWN:
25371
0
    if (iattr->metaType)
25372
0
        break;
25373
    /*
25374
    * MAYBE VAL TODO: One might report different error messages
25375
    * for the following errors.
25376
    */
25377
0
    if (type->attributeWildcard == NULL) {
25378
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25379
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25380
0
    } else {
25381
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25382
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25383
0
    }
25384
0
    break;
25385
0
      default:
25386
0
    break;
25387
0
  }
25388
0
    }
25389
25390
0
    ACTIVATE_ELEM;
25391
0
    return (0);
25392
0
internal_error:
25393
0
    ACTIVATE_ELEM;
25394
0
    return (-1);
25395
0
}
25396
25397
static int
25398
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25399
            int *skip)
25400
0
{
25401
0
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25402
    /*
25403
    * The namespace of the element was already identified to be
25404
    * matching the wildcard.
25405
    */
25406
0
    if ((skip == NULL) || (wild == NULL) ||
25407
0
  (wild->type != XML_SCHEMA_TYPE_ANY)) {
25408
0
  VERROR_INT("xmlSchemaValidateElemWildcard",
25409
0
      "bad arguments");
25410
0
  return (-1);
25411
0
    }
25412
0
    *skip = 0;
25413
0
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25414
  /*
25415
  * URGENT VAL TODO: Either we need to position the stream to the
25416
  * next sibling, or walk the whole subtree.
25417
  */
25418
0
  *skip = 1;
25419
0
  return (0);
25420
0
    }
25421
0
    {
25422
0
  xmlSchemaElementPtr decl = NULL;
25423
25424
0
  decl = xmlSchemaGetElem(vctxt->schema,
25425
0
      vctxt->inode->localName, vctxt->inode->nsName);
25426
0
  if (decl != NULL) {
25427
0
      vctxt->inode->decl = decl;
25428
0
      return (0);
25429
0
  }
25430
0
    }
25431
0
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25432
  /* VAL TODO: Change to proper error code. */
25433
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25434
0
      "No matching global element declaration available, but "
25435
0
      "demanded by the strict wildcard");
25436
0
  return (vctxt->err);
25437
0
    }
25438
0
    if (vctxt->nbAttrInfos != 0) {
25439
0
  xmlSchemaAttrInfoPtr iattr;
25440
  /*
25441
  * SPEC Validation Rule: Schema-Validity Assessment (Element)
25442
  * (1.2.1.2.1) - (1.2.1.2.3 )
25443
  *
25444
  * Use the xsi:type attribute for the type definition.
25445
  */
25446
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25447
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25448
0
  if (iattr != NULL) {
25449
0
      if (xmlSchemaProcessXSIType(vctxt, iattr,
25450
0
    &(vctxt->inode->typeDef), NULL) == -1) {
25451
0
    VERROR_INT("xmlSchemaValidateElemWildcard",
25452
0
        "calling xmlSchemaProcessXSIType() to "
25453
0
        "process the attribute 'xsi:nil'");
25454
0
    return (-1);
25455
0
      }
25456
      /*
25457
      * Don't return an error on purpose.
25458
      */
25459
0
      return (0);
25460
0
  }
25461
0
    }
25462
    /*
25463
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
25464
    *
25465
    * Fallback to "anyType".
25466
    */
25467
0
    vctxt->inode->typeDef =
25468
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25469
0
    return (0);
25470
0
}
25471
25472
/*
25473
* xmlSchemaCheckCOSValidDefault:
25474
*
25475
* This will be called if: not nilled, no content and a default/fixed
25476
* value is provided.
25477
*/
25478
25479
static int
25480
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25481
            const xmlChar *value,
25482
            xmlSchemaValPtr *val)
25483
0
{
25484
0
    int ret = 0;
25485
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25486
25487
    /*
25488
    * cos-valid-default:
25489
    * Schema Component Constraint: Element Default Valid (Immediate)
25490
    * For a string to be a valid default with respect to a type
25491
    * definition the appropriate case among the following must be true:
25492
    */
25493
0
    if WXS_IS_COMPLEX(inode->typeDef) {
25494
  /*
25495
  * Complex type.
25496
  *
25497
  * SPEC (2.1) "its {content type} must be a simple type definition
25498
  * or mixed."
25499
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
25500
  * type}'s particle must be `emptiable` as defined by
25501
  * Particle Emptiable ($3.9.6)."
25502
  */
25503
0
  if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25504
0
      ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25505
0
       (! WXS_EMPTIABLE(inode->typeDef)))) {
25506
0
      ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25507
      /* NOTE that this covers (2.2.2) as well. */
25508
0
      VERROR(ret, NULL,
25509
0
    "For a string to be a valid default, the type definition "
25510
0
    "must be a simple type or a complex type with simple content "
25511
0
    "or mixed content and a particle emptiable");
25512
0
      return(ret);
25513
0
  }
25514
0
    }
25515
    /*
25516
    * 1 If the type definition is a simple type definition, then the string
25517
    * must be `valid` with respect to that definition as defined by String
25518
    * Valid ($3.14.4).
25519
    *
25520
    * AND
25521
    *
25522
    * 2.2.1 If the {content type} is a simple type definition, then the
25523
    * string must be `valid` with respect to that simple type definition
25524
    * as defined by String Valid ($3.14.4).
25525
    */
25526
0
    if (WXS_IS_SIMPLE(inode->typeDef)) {
25527
25528
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25529
0
      NULL, inode->typeDef, value, val, 1, 1, 0);
25530
25531
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25532
25533
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25534
0
      NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25535
0
    }
25536
0
    if (ret < 0) {
25537
0
  VERROR_INT("xmlSchemaCheckCOSValidDefault",
25538
0
      "calling xmlSchemaVCheckCVCSimpleType()");
25539
0
    }
25540
0
    return (ret);
25541
0
}
25542
25543
static void
25544
xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
25545
             const xmlChar * name ATTRIBUTE_UNUSED,
25546
             void *transdata, void *inputdata)
25547
0
{
25548
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
25549
0
    xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
25550
0
    inode->decl = item;
25551
0
}
25552
25553
static int
25554
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25555
0
{
25556
0
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25557
0
    if (vctxt->inode == NULL) {
25558
0
  VERROR_INT("xmlSchemaValidatorPushElem",
25559
0
      "calling xmlSchemaGetFreshElemInfo()");
25560
0
  return (-1);
25561
0
    }
25562
0
    vctxt->nbAttrInfos = 0;
25563
0
    return (0);
25564
0
}
25565
25566
static int
25567
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25568
           xmlSchemaNodeInfoPtr inode,
25569
           xmlSchemaTypePtr type,
25570
           const xmlChar *value)
25571
0
{
25572
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25573
0
  return (xmlSchemaVCheckCVCSimpleType(
25574
0
      ACTXT_CAST vctxt, NULL,
25575
0
      type, value, &(inode->val), 1, 1, 0));
25576
0
    else
25577
0
  return (xmlSchemaVCheckCVCSimpleType(
25578
0
      ACTXT_CAST vctxt, NULL,
25579
0
      type, value, NULL, 1, 0, 0));
25580
0
}
25581
25582
25583
25584
/*
25585
* Process END of element.
25586
*/
25587
static int
25588
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25589
0
{
25590
0
    int ret = 0;
25591
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25592
25593
0
    if (vctxt->nbAttrInfos != 0)
25594
0
  xmlSchemaClearAttrInfos(vctxt);
25595
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25596
  /*
25597
  * This element was not expected;
25598
  * we will not validate child elements of broken parents.
25599
  * Skip validation of all content of the parent.
25600
  */
25601
0
  vctxt->skipDepth = vctxt->depth -1;
25602
0
  goto end_elem;
25603
0
    }
25604
0
    if ((inode->typeDef == NULL) ||
25605
0
  (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25606
  /*
25607
  * 1. the type definition might be missing if the element was
25608
  *    error prone
25609
  * 2. it might be abstract.
25610
  */
25611
0
  goto end_elem;
25612
0
    }
25613
    /*
25614
    * Check the content model.
25615
    */
25616
0
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
25617
0
  (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
25618
25619
  /*
25620
  * Workaround for "anyType".
25621
  */
25622
0
  if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
25623
0
      goto character_content;
25624
25625
0
  if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
25626
0
      xmlChar *values[10];
25627
0
      int terminal, nbval = 10, nbneg;
25628
25629
0
      if (inode->regexCtxt == NULL) {
25630
    /*
25631
    * Create the regex context.
25632
    */
25633
0
    inode->regexCtxt =
25634
0
        xmlRegNewExecCtxt(inode->typeDef->contModel,
25635
0
        xmlSchemaVContentModelCallback, vctxt);
25636
0
    if (inode->regexCtxt == NULL) {
25637
0
        VERROR_INT("xmlSchemaValidatorPopElem",
25638
0
      "failed to create a regex context");
25639
0
        goto internal_error;
25640
0
    }
25641
0
      }
25642
25643
      /*
25644
       * Do not check further content if the node has been nilled
25645
       */
25646
0
      if (INODE_NILLED(inode)) {
25647
0
    ret = 0;
25648
0
                goto skip_nilled;
25649
0
      }
25650
25651
      /*
25652
      * Get hold of the still expected content, since a further
25653
      * call to xmlRegExecPushString() will lose this information.
25654
      */
25655
0
      xmlRegExecNextValues(inode->regexCtxt,
25656
0
    &nbval, &nbneg, &values[0], &terminal);
25657
0
      ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
25658
0
      if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
25659
    /*
25660
    * Still missing something.
25661
    */
25662
0
    ret = 1;
25663
0
    inode->flags |=
25664
0
        XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
25665
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
25666
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
25667
0
        "Missing child element(s)",
25668
0
        nbval, nbneg, values);
25669
0
      } else {
25670
    /*
25671
    * Content model is satisfied.
25672
    */
25673
0
    ret = 0;
25674
0
      }
25675
25676
0
  }
25677
0
    }
25678
25679
0
skip_nilled:
25680
25681
0
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
25682
0
  goto end_elem;
25683
25684
0
character_content:
25685
25686
0
    if (vctxt->value != NULL) {
25687
0
  xmlSchemaFreeValue(vctxt->value);
25688
0
  vctxt->value = NULL;
25689
0
    }
25690
    /*
25691
    * Check character content.
25692
    */
25693
0
    if (inode->decl == NULL) {
25694
  /*
25695
  * Speedup if no declaration exists.
25696
  */
25697
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
25698
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
25699
0
    inode, inode->typeDef, inode->value);
25700
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25701
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
25702
0
    inode, inode->typeDef->contentTypeDef,
25703
0
    inode->value);
25704
0
  }
25705
0
  if (ret < 0) {
25706
0
      VERROR_INT("xmlSchemaValidatorPopElem",
25707
0
    "calling xmlSchemaVCheckCVCSimpleType()");
25708
0
      goto internal_error;
25709
0
  }
25710
0
  goto end_elem;
25711
0
    }
25712
    /*
25713
    * cvc-elt (3.3.4) : 5
25714
    * The appropriate case among the following must be true:
25715
    */
25716
    /*
25717
    * cvc-elt (3.3.4) : 5.1
25718
    * If the declaration has a {value constraint},
25719
    * the item has neither element nor character [children] and
25720
    * clause 3.2 has not applied, then all of the following must be true:
25721
    */
25722
0
    if ((inode->decl->value != NULL) &&
25723
0
  (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
25724
0
  (! INODE_NILLED(inode))) {
25725
  /*
25726
  * cvc-elt (3.3.4) : 5.1.1
25727
  * If the `actual type definition` is a `local type definition`
25728
  * then the canonical lexical representation of the {value constraint}
25729
  * value must be a valid default for the `actual type definition` as
25730
  * defined in Element Default Valid (Immediate) ($3.3.6).
25731
  */
25732
  /*
25733
  * NOTE: 'local' above means types acquired by xsi:type.
25734
  * NOTE: Although the *canonical* value is stated, it is not
25735
  * relevant if canonical or not. Additionally XML Schema 1.1
25736
  * will removed this requirement as well.
25737
  */
25738
0
  if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
25739
25740
0
      ret = xmlSchemaCheckCOSValidDefault(vctxt,
25741
0
    inode->decl->value, &(inode->val));
25742
0
      if (ret != 0) {
25743
0
    if (ret < 0) {
25744
0
        VERROR_INT("xmlSchemaValidatorPopElem",
25745
0
      "calling xmlSchemaCheckCOSValidDefault()");
25746
0
        goto internal_error;
25747
0
    }
25748
0
    goto end_elem;
25749
0
      }
25750
      /*
25751
      * Stop here, to avoid redundant validation of the value
25752
      * (see following).
25753
      */
25754
0
      goto default_psvi;
25755
0
  }
25756
  /*
25757
  * cvc-elt (3.3.4) : 5.1.2
25758
  * The element information item with the canonical lexical
25759
  * representation of the {value constraint} value used as its
25760
  * `normalized value` must be `valid` with respect to the
25761
  * `actual type definition` as defined by Element Locally Valid (Type)
25762
  * ($3.3.4).
25763
  */
25764
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
25765
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
25766
0
    inode, inode->typeDef, inode->decl->value);
25767
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25768
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
25769
0
    inode, inode->typeDef->contentTypeDef,
25770
0
    inode->decl->value);
25771
0
  }
25772
0
  if (ret != 0) {
25773
0
      if (ret < 0) {
25774
0
    VERROR_INT("xmlSchemaValidatorPopElem",
25775
0
        "calling xmlSchemaVCheckCVCSimpleType()");
25776
0
    goto internal_error;
25777
0
      }
25778
0
      goto end_elem;
25779
0
  }
25780
25781
0
default_psvi:
25782
  /*
25783
  * PSVI: Create a text node on the instance element.
25784
  */
25785
0
  if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
25786
0
      (inode->node != NULL)) {
25787
0
      xmlNodePtr textChild;
25788
0
      xmlChar *normValue;
25789
      /*
25790
      * VAL TODO: Normalize the value.
25791
      */
25792
0
      normValue = xmlSchemaNormalizeValue(inode->typeDef,
25793
0
    inode->decl->value);
25794
0
      if (normValue != NULL) {
25795
0
    textChild = xmlNewDocText(inode->node->doc,
25796
0
                        BAD_CAST normValue);
25797
0
    xmlFree(normValue);
25798
0
      } else
25799
0
    textChild = xmlNewDocText(inode->node->doc,
25800
0
                        inode->decl->value);
25801
0
      if (textChild == NULL) {
25802
0
    VERROR_INT("xmlSchemaValidatorPopElem",
25803
0
        "calling xmlNewDocText()");
25804
0
    goto internal_error;
25805
0
      } else
25806
0
    xmlAddChild(inode->node, textChild);
25807
0
  }
25808
25809
0
    } else if (! INODE_NILLED(inode)) {
25810
  /*
25811
  * 5.2.1 The element information item must be `valid` with respect
25812
  * to the `actual type definition` as defined by Element Locally
25813
  * Valid (Type) ($3.3.4).
25814
  */
25815
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
25816
       /*
25817
      * SPEC (cvc-type) (3.1)
25818
      * "If the type definition is a simple type definition, ..."
25819
      * (3.1.3) "If clause 3.2 of Element Locally Valid
25820
      * (Element) ($3.3.4) did not apply, then the `normalized value`
25821
      * must be `valid` with respect to the type definition as defined
25822
      * by String Valid ($3.14.4).
25823
      */
25824
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
25825
0
        inode, inode->typeDef, inode->value);
25826
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25827
      /*
25828
      * SPEC (cvc-type) (3.2) "If the type definition is a complex type
25829
      * definition, then the element information item must be
25830
      * `valid` with respect to the type definition as per
25831
      * Element Locally Valid (Complex Type) ($3.4.4);"
25832
      *
25833
      * SPEC (cvc-complex-type) (2.2)
25834
      * "If the {content type} is a simple type definition, ...
25835
      * the `normalized value` of the element information item is
25836
      * `valid` with respect to that simple type definition as
25837
      * defined by String Valid ($3.14.4)."
25838
      */
25839
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
25840
0
    inode, inode->typeDef->contentTypeDef, inode->value);
25841
0
  }
25842
0
  if (ret != 0) {
25843
0
      if (ret < 0) {
25844
0
    VERROR_INT("xmlSchemaValidatorPopElem",
25845
0
        "calling xmlSchemaVCheckCVCSimpleType()");
25846
0
    goto internal_error;
25847
0
      }
25848
0
      goto end_elem;
25849
0
  }
25850
  /*
25851
  * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
25852
  * not applied, all of the following must be true:
25853
  */
25854
0
  if ((inode->decl->value != NULL) &&
25855
0
      (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
25856
25857
      /*
25858
      * TODO: We will need a computed value, when comparison is
25859
      * done on computed values.
25860
      */
25861
      /*
25862
      * 5.2.2.1 The element information item must have no element
25863
      * information item [children].
25864
      */
25865
0
      if (inode->flags &
25866
0
        XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
25867
0
    ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
25868
0
    VERROR(ret, NULL,
25869
0
        "The content must not contain element nodes since "
25870
0
        "there is a fixed value constraint");
25871
0
    goto end_elem;
25872
0
      } else {
25873
    /*
25874
    * 5.2.2.2 The appropriate case among the following must
25875
    * be true:
25876
    */
25877
0
    if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
25878
        /*
25879
        * 5.2.2.2.1 If the {content type} of the `actual type
25880
        * definition` is mixed, then the *initial value* of the
25881
        * item must match the canonical lexical representation
25882
        * of the {value constraint} value.
25883
        *
25884
        * ... the *initial value* of an element information
25885
        * item is the string composed of, in order, the
25886
        * [character code] of each character information item in
25887
        * the [children] of that element information item.
25888
        */
25889
0
        if (! xmlStrEqual(inode->value, inode->decl->value)){
25890
      /*
25891
      * VAL TODO: Report invalid & expected values as well.
25892
      * VAL TODO: Implement the canonical stuff.
25893
      */
25894
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
25895
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
25896
0
          ret, NULL, NULL,
25897
0
          "The initial value '%s' does not match the fixed "
25898
0
          "value constraint '%s'",
25899
0
          inode->value, inode->decl->value);
25900
0
      goto end_elem;
25901
0
        }
25902
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25903
        /*
25904
        * 5.2.2.2.2 If the {content type} of the `actual type
25905
        * definition` is a simple type definition, then the
25906
        * *actual value* of the item must match the canonical
25907
        * lexical representation of the {value constraint} value.
25908
        */
25909
        /*
25910
        * VAL TODO: *actual value* is the normalized value, impl.
25911
        *           this.
25912
        * VAL TODO: Report invalid & expected values as well.
25913
        * VAL TODO: Implement a comparison with the computed values.
25914
        */
25915
0
        if (! xmlStrEqual(inode->value,
25916
0
          inode->decl->value)) {
25917
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
25918
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
25919
0
          ret, NULL, NULL,
25920
0
          "The actual value '%s' does not match the fixed "
25921
0
          "value constraint '%s'",
25922
0
          inode->value,
25923
0
          inode->decl->value);
25924
0
      goto end_elem;
25925
0
        }
25926
0
    }
25927
0
      }
25928
0
  }
25929
0
    }
25930
25931
0
end_elem:
25932
0
    if (vctxt->depth < 0) {
25933
  /* TODO: raise error? */
25934
0
  return (0);
25935
0
    }
25936
0
    if (vctxt->depth == vctxt->skipDepth)
25937
0
  vctxt->skipDepth = -1;
25938
    /*
25939
    * Evaluate the history of XPath state objects.
25940
    */
25941
0
    if (inode->appliedXPath &&
25942
0
  (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
25943
0
  goto internal_error;
25944
    /*
25945
    * MAYBE TODO:
25946
    * SPEC (6) "The element information item must be `valid` with
25947
    * respect to each of the {identity-constraint definitions} as per
25948
    * Identity-constraint Satisfied ($3.11.4)."
25949
    */
25950
    /*
25951
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
25952
    *   need to be built in any case.
25953
    *   We will currently build IDC node-tables and bubble them only if
25954
    *   keyrefs do exist.
25955
    */
25956
25957
    /*
25958
    * Add the current IDC target-nodes to the IDC node-tables.
25959
    */
25960
0
    if ((inode->idcMatchers != NULL) &&
25961
0
  (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
25962
0
    {
25963
0
  if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
25964
0
      goto internal_error;
25965
0
    }
25966
    /*
25967
    * Validate IDC keyrefs.
25968
    */
25969
0
    if (vctxt->inode->hasKeyrefs)
25970
0
  if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
25971
0
      goto internal_error;
25972
    /*
25973
    * Merge/free the IDC table.
25974
    */
25975
0
    if (inode->idcTable != NULL) {
25976
0
  if ((vctxt->depth > 0) &&
25977
0
      (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
25978
0
  {
25979
      /*
25980
      * Merge the IDC node table with the table of the parent node.
25981
      */
25982
0
      if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
25983
0
    goto internal_error;
25984
0
  }
25985
0
    }
25986
    /*
25987
    * Clear the current ielem.
25988
    * VAL TODO: Don't free the PSVI IDC tables if they are
25989
    * requested for the PSVI.
25990
    */
25991
0
    xmlSchemaClearElemInfo(vctxt, inode);
25992
    /*
25993
    * Skip further processing if we are on the validation root.
25994
    */
25995
0
    if (vctxt->depth == 0) {
25996
0
  vctxt->depth--;
25997
0
  vctxt->inode = NULL;
25998
0
  return (0);
25999
0
    }
26000
    /*
26001
    * Reset the keyrefDepth if needed.
26002
    */
26003
0
    if (vctxt->aidcs != NULL) {
26004
0
  xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26005
0
  do {
26006
0
      if (aidc->keyrefDepth == vctxt->depth) {
26007
    /*
26008
    * A 'keyrefDepth' of a key/unique IDC matches the current
26009
    * depth, this means that we are leaving the scope of the
26010
    * top-most keyref IDC which refers to this IDC.
26011
    */
26012
0
    aidc->keyrefDepth = -1;
26013
0
      }
26014
0
      aidc = aidc->next;
26015
0
  } while (aidc != NULL);
26016
0
    }
26017
0
    vctxt->depth--;
26018
0
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
26019
    /*
26020
    * VAL TODO: 7 If the element information item is the `validation root`, it must be
26021
    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26022
    */
26023
0
    return (ret);
26024
26025
0
internal_error:
26026
0
    vctxt->err = -1;
26027
0
    return (-1);
26028
0
}
26029
26030
/*
26031
* 3.4.4 Complex Type Definition Validation Rules
26032
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26033
*/
26034
static int
26035
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26036
0
{
26037
0
    xmlSchemaNodeInfoPtr pielem;
26038
0
    xmlSchemaTypePtr ptype;
26039
0
    int ret = 0;
26040
26041
0
    if (vctxt->depth <= 0) {
26042
0
  VERROR_INT("xmlSchemaValidateChildElem",
26043
0
      "not intended for the validation root");
26044
0
  return (-1);
26045
0
    }
26046
0
    pielem = vctxt->elemInfos[vctxt->depth -1];
26047
0
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26048
0
  pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26049
    /*
26050
    * Handle 'nilled' elements.
26051
    */
26052
0
    if (INODE_NILLED(pielem)) {
26053
  /*
26054
  * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26055
  */
26056
0
  ACTIVATE_PARENT_ELEM;
26057
0
  ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26058
0
  VERROR(ret, NULL,
26059
0
      "Neither character nor element content is allowed, "
26060
0
      "because the element was 'nilled'");
26061
0
  ACTIVATE_ELEM;
26062
0
  goto unexpected_elem;
26063
0
    }
26064
26065
0
    ptype = pielem->typeDef;
26066
26067
0
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26068
  /*
26069
  * Workaround for "anyType": we have currently no content model
26070
  * assigned for "anyType", so handle it explicitly.
26071
  * "anyType" has an unbounded, lax "any" wildcard.
26072
  */
26073
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26074
0
      vctxt->inode->localName,
26075
0
      vctxt->inode->nsName);
26076
26077
0
  if (vctxt->inode->decl == NULL) {
26078
0
      xmlSchemaAttrInfoPtr iattr;
26079
      /*
26080
      * Process "xsi:type".
26081
      * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26082
      */
26083
0
      iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26084
0
    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26085
0
      if (iattr != NULL) {
26086
0
    ret = xmlSchemaProcessXSIType(vctxt, iattr,
26087
0
        &(vctxt->inode->typeDef), NULL);
26088
0
    if (ret != 0) {
26089
0
        if (ret == -1) {
26090
0
      VERROR_INT("xmlSchemaValidateChildElem",
26091
0
          "calling xmlSchemaProcessXSIType() to "
26092
0
          "process the attribute 'xsi:nil'");
26093
0
      return (-1);
26094
0
        }
26095
0
        return (ret);
26096
0
    }
26097
0
      } else {
26098
     /*
26099
     * Fallback to "anyType".
26100
     *
26101
     * SPEC (cvc-assess-elt)
26102
     * "If the item cannot be `strictly assessed`, [...]
26103
     * an element information item's schema validity may be laxly
26104
     * assessed if its `context-determined declaration` is not
26105
     * skip by `validating` with respect to the `ur-type
26106
     * definition` as per Element Locally Valid (Type) ($3.3.4)."
26107
    */
26108
0
    vctxt->inode->typeDef =
26109
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26110
0
      }
26111
0
  }
26112
0
  return (0);
26113
0
    }
26114
26115
0
    switch (ptype->contentType) {
26116
0
  case XML_SCHEMA_CONTENT_EMPTY:
26117
      /*
26118
      * SPEC (2.1) "If the {content type} is empty, then the
26119
      * element information item has no character or element
26120
      * information item [children]."
26121
      */
26122
0
      ACTIVATE_PARENT_ELEM
26123
0
      ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26124
0
      VERROR(ret, NULL,
26125
0
    "Element content is not allowed, "
26126
0
    "because the content type is empty");
26127
0
      ACTIVATE_ELEM
26128
0
      goto unexpected_elem;
26129
0
      break;
26130
26131
0
  case XML_SCHEMA_CONTENT_MIXED:
26132
0
        case XML_SCHEMA_CONTENT_ELEMENTS: {
26133
0
      xmlRegExecCtxtPtr regexCtxt;
26134
0
      xmlChar *values[10];
26135
0
      int terminal, nbval = 10, nbneg;
26136
26137
      /* VAL TODO: Optimized "anyType" validation.*/
26138
26139
0
      if (ptype->contModel == NULL) {
26140
0
    VERROR_INT("xmlSchemaValidateChildElem",
26141
0
        "type has elem content but no content model");
26142
0
    return (-1);
26143
0
      }
26144
      /*
26145
      * Safety belt for evaluation if the cont. model was already
26146
      * examined to be invalid.
26147
      */
26148
0
      if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26149
0
    VERROR_INT("xmlSchemaValidateChildElem",
26150
0
        "validating elem, but elem content is already invalid");
26151
0
    return (-1);
26152
0
      }
26153
26154
0
      regexCtxt = pielem->regexCtxt;
26155
0
      if (regexCtxt == NULL) {
26156
    /*
26157
    * Create the regex context.
26158
    */
26159
0
    regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26160
0
        xmlSchemaVContentModelCallback, vctxt);
26161
0
    if (regexCtxt == NULL) {
26162
0
        VERROR_INT("xmlSchemaValidateChildElem",
26163
0
      "failed to create a regex context");
26164
0
        return (-1);
26165
0
    }
26166
0
    pielem->regexCtxt = regexCtxt;
26167
0
      }
26168
26169
      /*
26170
      * SPEC (2.4) "If the {content type} is element-only or mixed,
26171
      * then the sequence of the element information item's
26172
      * element information item [children], if any, taken in
26173
      * order, is `valid` with respect to the {content type}'s
26174
      * particle, as defined in Element Sequence Locally Valid
26175
      * (Particle) ($3.9.4)."
26176
      */
26177
0
      ret = xmlRegExecPushString2(regexCtxt,
26178
0
    vctxt->inode->localName,
26179
0
    vctxt->inode->nsName,
26180
0
    vctxt->inode);
26181
0
      if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26182
0
    VERROR_INT("xmlSchemaValidateChildElem",
26183
0
        "calling xmlRegExecPushString2()");
26184
0
    return (-1);
26185
0
      }
26186
0
      if (ret < 0) {
26187
0
    xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26188
0
        &values[0], &terminal);
26189
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26190
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26191
0
        "This element is not expected",
26192
0
        nbval, nbneg, values);
26193
0
    ret = vctxt->err;
26194
0
    goto unexpected_elem;
26195
0
      } else
26196
0
    ret = 0;
26197
0
  }
26198
0
      break;
26199
0
  case XML_SCHEMA_CONTENT_SIMPLE:
26200
0
  case XML_SCHEMA_CONTENT_BASIC:
26201
0
      ACTIVATE_PARENT_ELEM
26202
0
      if (WXS_IS_COMPLEX(ptype)) {
26203
    /*
26204
    * SPEC (cvc-complex-type) (2.2)
26205
    * "If the {content type} is a simple type definition, then
26206
    * the element information item has no element information
26207
    * item [children], ..."
26208
    */
26209
0
    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26210
0
    VERROR(ret, NULL, "Element content is not allowed, "
26211
0
        "because the content type is a simple type definition");
26212
0
      } else {
26213
    /*
26214
    * SPEC (cvc-type) (3.1.2) "The element information item must
26215
    * have no element information item [children]."
26216
    */
26217
0
    ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26218
0
    VERROR(ret, NULL, "Element content is not allowed, "
26219
0
        "because the type definition is simple");
26220
0
      }
26221
0
      ACTIVATE_ELEM
26222
0
      ret = vctxt->err;
26223
0
      goto unexpected_elem;
26224
0
      break;
26225
26226
0
  default:
26227
0
      break;
26228
0
    }
26229
0
    return (ret);
26230
0
unexpected_elem:
26231
    /*
26232
    * Pop this element and set the skipDepth to skip
26233
    * all further content of the parent element.
26234
    */
26235
0
    vctxt->skipDepth = vctxt->depth;
26236
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26237
0
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26238
0
    return (ret);
26239
0
}
26240
26241
0
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26242
0
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26243
0
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26244
26245
static int
26246
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26247
      int nodeType, const xmlChar *value, int len,
26248
      int mode, int *consumed)
26249
0
{
26250
    /*
26251
    * Unfortunately we have to duplicate the text sometimes.
26252
    * OPTIMIZE: Maybe we could skip it, if:
26253
    *   1. content type is simple
26254
    *   2. whitespace is "collapse"
26255
    *   3. it consists of whitespace only
26256
    *
26257
    * Process character content.
26258
    */
26259
0
    if (consumed != NULL)
26260
0
  *consumed = 0;
26261
0
    if (INODE_NILLED(vctxt->inode)) {
26262
  /*
26263
  * SPEC cvc-elt (3.3.4 - 3.2.1)
26264
  * "The element information item must have no character or
26265
  * element information item [children]."
26266
  */
26267
0
  VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26268
0
      "Neither character nor element content is allowed "
26269
0
      "because the element is 'nilled'");
26270
0
  return (vctxt->err);
26271
0
    }
26272
    /*
26273
    * SPEC (2.1) "If the {content type} is empty, then the
26274
    * element information item has no character or element
26275
    * information item [children]."
26276
    */
26277
0
    if (vctxt->inode->typeDef->contentType ==
26278
0
      XML_SCHEMA_CONTENT_EMPTY) {
26279
0
  VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26280
0
      "Character content is not allowed, "
26281
0
      "because the content type is empty");
26282
0
  return (vctxt->err);
26283
0
    }
26284
26285
0
    if (vctxt->inode->typeDef->contentType ==
26286
0
      XML_SCHEMA_CONTENT_ELEMENTS) {
26287
0
  if ((nodeType != XML_TEXT_NODE) ||
26288
0
      (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26289
      /*
26290
      * SPEC cvc-complex-type (2.3)
26291
      * "If the {content type} is element-only, then the
26292
      * element information item has no character information
26293
      * item [children] other than those whose [character
26294
      * code] is defined as a white space in [XML 1.0 (Second
26295
      * Edition)]."
26296
      */
26297
0
      VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26298
0
    "Character content other than whitespace is not allowed "
26299
0
    "because the content type is 'element-only'");
26300
0
      return (vctxt->err);
26301
0
  }
26302
0
  return (0);
26303
0
    }
26304
26305
0
    if ((value == NULL) || (value[0] == 0))
26306
0
  return (0);
26307
    /*
26308
    * Save the value.
26309
    * NOTE that even if the content type is *mixed*, we need the
26310
    * *initial value* for default/fixed value constraints.
26311
    */
26312
0
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26313
0
  ((vctxt->inode->decl == NULL) ||
26314
0
  (vctxt->inode->decl->value == NULL)))
26315
0
  return (0);
26316
26317
0
    if (vctxt->inode->value == NULL) {
26318
  /*
26319
  * Set the value.
26320
  */
26321
0
  switch (mode) {
26322
0
      case XML_SCHEMA_PUSH_TEXT_PERSIST:
26323
    /*
26324
    * When working on a tree.
26325
    */
26326
0
    vctxt->inode->value = value;
26327
0
    vctxt->inode->flags &=
26328
0
        ~XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26329
0
    break;
26330
0
      case XML_SCHEMA_PUSH_TEXT_CREATED:
26331
    /*
26332
    * When working with the reader.
26333
    * The value will be freed by the element info.
26334
    */
26335
0
    vctxt->inode->value = value;
26336
0
    if (consumed != NULL)
26337
0
        *consumed = 1;
26338
0
    vctxt->inode->flags |=
26339
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26340
0
    break;
26341
0
      case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26342
    /*
26343
    * When working with SAX.
26344
    * The value will be freed by the element info.
26345
    */
26346
0
    if (len != -1)
26347
0
        vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26348
0
    else
26349
0
        vctxt->inode->value = BAD_CAST xmlStrdup(value);
26350
0
    vctxt->inode->flags |=
26351
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26352
0
    break;
26353
0
      default:
26354
0
    break;
26355
0
  }
26356
0
    } else {
26357
0
  if (len < 0)
26358
0
      len = xmlStrlen(value);
26359
  /*
26360
  * Concat the value.
26361
  */
26362
0
  if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26363
0
      vctxt->inode->value = BAD_CAST xmlStrncat(
26364
0
    (xmlChar *) vctxt->inode->value, value, len);
26365
0
  } else {
26366
0
      vctxt->inode->value =
26367
0
    BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26368
0
      vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26369
0
  }
26370
0
    }
26371
26372
0
    return (0);
26373
0
}
26374
26375
static int
26376
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26377
0
{
26378
0
    int ret = 0;
26379
26380
0
    if ((vctxt->skipDepth != -1) &&
26381
0
  (vctxt->depth >= vctxt->skipDepth)) {
26382
0
  VERROR_INT("xmlSchemaValidateElem",
26383
0
      "in skip-state");
26384
0
  goto internal_error;
26385
0
    }
26386
0
    if (vctxt->xsiAssemble) {
26387
  /*
26388
  * We will stop validation if there was an error during
26389
  * dynamic schema construction.
26390
  * Note that we simply set @skipDepth to 0, this could
26391
  * mean that a streaming document via SAX would be
26392
  * still read to the end but it won't be validated any more.
26393
  * TODO: If we are sure how to stop the validation at once
26394
  *   for all input scenarios, then this should be changed to
26395
  *   instantly stop the validation.
26396
  */
26397
0
  ret = xmlSchemaAssembleByXSI(vctxt);
26398
0
  if (ret != 0) {
26399
0
      if (ret == -1)
26400
0
    goto internal_error;
26401
0
      vctxt->skipDepth = 0;
26402
0
      return(ret);
26403
0
  }
26404
        /*
26405
         * Augment the IDC definitions for the main schema and all imported ones
26406
         * NOTE: main schema is the first in the imported list
26407
         */
26408
0
        xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
26409
0
                    vctxt);
26410
0
    }
26411
0
    if (vctxt->depth > 0) {
26412
  /*
26413
  * Validate this element against the content model
26414
  * of the parent.
26415
  */
26416
0
  ret = xmlSchemaValidateChildElem(vctxt);
26417
0
  if (ret != 0) {
26418
0
      if (ret < 0) {
26419
0
    VERROR_INT("xmlSchemaValidateElem",
26420
0
        "calling xmlSchemaStreamValidateChildElement()");
26421
0
    goto internal_error;
26422
0
      }
26423
0
      goto exit;
26424
0
  }
26425
0
  if (vctxt->depth == vctxt->skipDepth)
26426
0
      goto exit;
26427
0
  if ((vctxt->inode->decl == NULL) &&
26428
0
      (vctxt->inode->typeDef == NULL)) {
26429
0
      VERROR_INT("xmlSchemaValidateElem",
26430
0
    "the child element was valid but neither the "
26431
0
    "declaration nor the type was set");
26432
0
      goto internal_error;
26433
0
  }
26434
0
    } else {
26435
  /*
26436
  * Get the declaration of the validation root.
26437
  */
26438
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26439
0
      vctxt->inode->localName,
26440
0
      vctxt->inode->nsName);
26441
0
  if (vctxt->inode->decl == NULL) {
26442
0
      ret = XML_SCHEMAV_CVC_ELT_1;
26443
0
      VERROR(ret, NULL,
26444
0
    "No matching global declaration available "
26445
0
    "for the validation root");
26446
0
      goto exit;
26447
0
  }
26448
0
    }
26449
26450
0
    if (vctxt->inode->decl == NULL)
26451
0
  goto type_validation;
26452
26453
0
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26454
0
  int skip;
26455
  /*
26456
  * Wildcards.
26457
  */
26458
0
  ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26459
0
  if (ret != 0) {
26460
0
      if (ret < 0) {
26461
0
    VERROR_INT("xmlSchemaValidateElem",
26462
0
        "calling xmlSchemaValidateElemWildcard()");
26463
0
    goto internal_error;
26464
0
      }
26465
0
      goto exit;
26466
0
  }
26467
0
  if (skip) {
26468
0
      vctxt->skipDepth = vctxt->depth;
26469
0
      goto exit;
26470
0
  }
26471
  /*
26472
  * The declaration might be set by the wildcard validation,
26473
  * when the processContents is "lax" or "strict".
26474
  */
26475
0
  if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26476
      /*
26477
      * Clear the "decl" field to not confuse further processing.
26478
      */
26479
0
      vctxt->inode->decl = NULL;
26480
0
      goto type_validation;
26481
0
  }
26482
0
    }
26483
    /*
26484
    * Validate against the declaration.
26485
    */
26486
0
    ret = xmlSchemaValidateElemDecl(vctxt);
26487
0
    if (ret != 0) {
26488
0
  if (ret < 0) {
26489
0
      VERROR_INT("xmlSchemaValidateElem",
26490
0
    "calling xmlSchemaValidateElemDecl()");
26491
0
      goto internal_error;
26492
0
  }
26493
0
  goto exit;
26494
0
    }
26495
    /*
26496
    * Validate against the type definition.
26497
    */
26498
0
type_validation:
26499
26500
0
    if (vctxt->inode->typeDef == NULL) {
26501
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26502
0
  ret = XML_SCHEMAV_CVC_TYPE_1;
26503
0
  VERROR(ret, NULL,
26504
0
      "The type definition is absent");
26505
0
  goto exit;
26506
0
    }
26507
0
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26508
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26509
0
  ret = XML_SCHEMAV_CVC_TYPE_2;
26510
0
      VERROR(ret, NULL,
26511
0
      "The type definition is abstract");
26512
0
  goto exit;
26513
0
    }
26514
    /*
26515
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
26516
    * during validation against the declaration. This must be done
26517
    * _before_ attribute validation.
26518
    */
26519
0
    if (vctxt->xpathStates != NULL) {
26520
0
  ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26521
0
  vctxt->inode->appliedXPath = 1;
26522
0
  if (ret == -1) {
26523
0
      VERROR_INT("xmlSchemaValidateElem",
26524
0
    "calling xmlSchemaXPathEvaluate()");
26525
0
      goto internal_error;
26526
0
  }
26527
0
    }
26528
    /*
26529
    * Validate attributes.
26530
    */
26531
0
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26532
0
  if ((vctxt->nbAttrInfos != 0) ||
26533
0
      (vctxt->inode->typeDef->attrUses != NULL)) {
26534
26535
0
      ret = xmlSchemaVAttributesComplex(vctxt);
26536
0
  }
26537
0
    } else if (vctxt->nbAttrInfos != 0) {
26538
26539
0
  ret = xmlSchemaVAttributesSimple(vctxt);
26540
0
    }
26541
    /*
26542
    * Clear registered attributes.
26543
    */
26544
0
    if (vctxt->nbAttrInfos != 0)
26545
0
  xmlSchemaClearAttrInfos(vctxt);
26546
0
    if (ret == -1) {
26547
0
  VERROR_INT("xmlSchemaValidateElem",
26548
0
      "calling attributes validation");
26549
0
  goto internal_error;
26550
0
    }
26551
    /*
26552
    * Don't return an error if attributes are invalid on purpose.
26553
    */
26554
0
    ret = 0;
26555
26556
0
exit:
26557
0
    if (ret != 0)
26558
0
  vctxt->skipDepth = vctxt->depth;
26559
0
    return (ret);
26560
0
internal_error:
26561
0
    return (-1);
26562
0
}
26563
26564
#ifdef XML_SCHEMA_READER_ENABLED
26565
static int
26566
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26567
{
26568
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26569
    int depth, nodeType, ret = 0, consumed;
26570
    xmlSchemaNodeInfoPtr ielem;
26571
26572
    vctxt->depth = -1;
26573
    ret = xmlTextReaderRead(vctxt->reader);
26574
    /*
26575
    * Move to the document element.
26576
    */
26577
    while (ret == 1) {
26578
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26579
  if (nodeType == XML_ELEMENT_NODE)
26580
      goto root_found;
26581
  ret = xmlTextReaderRead(vctxt->reader);
26582
    }
26583
    goto exit;
26584
26585
root_found:
26586
26587
    do {
26588
  depth = xmlTextReaderDepth(vctxt->reader);
26589
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26590
26591
  if (nodeType == XML_ELEMENT_NODE) {
26592
26593
      vctxt->depth++;
26594
      if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26595
    VERROR_INT("xmlSchemaVReaderWalk",
26596
        "calling xmlSchemaValidatorPushElem()");
26597
    goto internal_error;
26598
      }
26599
      ielem = vctxt->inode;
26600
      ielem->localName = xmlTextReaderLocalName(vctxt->reader);
26601
      ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
26602
      ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
26603
      /*
26604
      * Is the element empty?
26605
      */
26606
      ret = xmlTextReaderIsEmptyElement(vctxt->reader);
26607
      if (ret == -1) {
26608
    VERROR_INT("xmlSchemaVReaderWalk",
26609
        "calling xmlTextReaderIsEmptyElement()");
26610
    goto internal_error;
26611
      }
26612
      if (ret) {
26613
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
26614
      }
26615
      /*
26616
      * Register attributes.
26617
      */
26618
      vctxt->nbAttrInfos = 0;
26619
      ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
26620
      if (ret == -1) {
26621
    VERROR_INT("xmlSchemaVReaderWalk",
26622
        "calling xmlTextReaderMoveToFirstAttribute()");
26623
    goto internal_error;
26624
      }
26625
      if (ret == 1) {
26626
    do {
26627
        /*
26628
        * VAL TODO: How do we know that the reader works on a
26629
        * node tree, to be able to pass a node here?
26630
        */
26631
        if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
26632
      (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
26633
      xmlTextReaderNamespaceUri(vctxt->reader), 1,
26634
      xmlTextReaderValue(vctxt->reader), 1) == -1) {
26635
26636
      VERROR_INT("xmlSchemaVReaderWalk",
26637
          "calling xmlSchemaValidatorPushAttribute()");
26638
      goto internal_error;
26639
        }
26640
        ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
26641
        if (ret == -1) {
26642
      VERROR_INT("xmlSchemaVReaderWalk",
26643
          "calling xmlTextReaderMoveToFirstAttribute()");
26644
      goto internal_error;
26645
        }
26646
    } while (ret == 1);
26647
    /*
26648
    * Back to element position.
26649
    */
26650
    ret = xmlTextReaderMoveToElement(vctxt->reader);
26651
    if (ret == -1) {
26652
        VERROR_INT("xmlSchemaVReaderWalk",
26653
      "calling xmlTextReaderMoveToElement()");
26654
        goto internal_error;
26655
    }
26656
      }
26657
      /*
26658
      * Validate the element.
26659
      */
26660
      ret= xmlSchemaValidateElem(vctxt);
26661
      if (ret != 0) {
26662
    if (ret == -1) {
26663
        VERROR_INT("xmlSchemaVReaderWalk",
26664
      "calling xmlSchemaValidateElem()");
26665
        goto internal_error;
26666
    }
26667
    goto exit;
26668
      }
26669
      if (vctxt->depth == vctxt->skipDepth) {
26670
    int curDepth;
26671
    /*
26672
    * Skip all content.
26673
    */
26674
    if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
26675
        ret = xmlTextReaderRead(vctxt->reader);
26676
        curDepth = xmlTextReaderDepth(vctxt->reader);
26677
        while ((ret == 1) && (curDepth != depth)) {
26678
      ret = xmlTextReaderRead(vctxt->reader);
26679
      curDepth = xmlTextReaderDepth(vctxt->reader);
26680
        }
26681
        if (ret < 0) {
26682
      /*
26683
      * VAL TODO: A reader error occurred; what to do here?
26684
      */
26685
      ret = 1;
26686
      goto exit;
26687
        }
26688
    }
26689
    goto leave_elem;
26690
      }
26691
      /*
26692
      * READER VAL TODO: Is an END_ELEM really never called
26693
      * if the elem is empty?
26694
      */
26695
      if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26696
    goto leave_elem;
26697
  } else if (nodeType == END_ELEM) {
26698
      /*
26699
      * Process END of element.
26700
      */
26701
leave_elem:
26702
      ret = xmlSchemaValidatorPopElem(vctxt);
26703
      if (ret != 0) {
26704
    if (ret < 0) {
26705
        VERROR_INT("xmlSchemaVReaderWalk",
26706
      "calling xmlSchemaValidatorPopElem()");
26707
        goto internal_error;
26708
    }
26709
    goto exit;
26710
      }
26711
      if (vctxt->depth >= 0)
26712
    ielem = vctxt->inode;
26713
      else
26714
    ielem = NULL;
26715
  } else if ((nodeType == XML_TEXT_NODE) ||
26716
      (nodeType == XML_CDATA_SECTION_NODE) ||
26717
      (nodeType == WHTSP) ||
26718
      (nodeType == SIGN_WHTSP)) {
26719
      /*
26720
      * Process character content.
26721
      */
26722
      xmlChar *value;
26723
26724
      if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
26725
    nodeType = XML_TEXT_NODE;
26726
26727
      value = xmlTextReaderValue(vctxt->reader);
26728
      ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
26729
    -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
26730
      if (! consumed)
26731
    xmlFree(value);
26732
      if (ret == -1) {
26733
    VERROR_INT("xmlSchemaVReaderWalk",
26734
        "calling xmlSchemaVPushText()");
26735
    goto internal_error;
26736
      }
26737
  } else if ((nodeType == XML_ENTITY_NODE) ||
26738
      (nodeType == XML_ENTITY_REF_NODE)) {
26739
      /*
26740
      * VAL TODO: What to do with entities?
26741
      */
26742
      TODO
26743
  }
26744
  /*
26745
  * Read next node.
26746
  */
26747
  ret = xmlTextReaderRead(vctxt->reader);
26748
    } while (ret == 1);
26749
26750
exit:
26751
    return (ret);
26752
internal_error:
26753
    return (-1);
26754
}
26755
#endif
26756
26757
/************************************************************************
26758
 *                  *
26759
 *      SAX validation handlers       *
26760
 *                  *
26761
 ************************************************************************/
26762
26763
/*
26764
* Process text content.
26765
*/
26766
static void
26767
xmlSchemaSAXHandleText(void *ctx,
26768
           const xmlChar * ch,
26769
           int len)
26770
0
{
26771
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
26772
26773
0
    if (vctxt->depth < 0)
26774
0
  return;
26775
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
26776
0
  return;
26777
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26778
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26779
0
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
26780
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
26781
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
26782
0
      "calling xmlSchemaVPushText()");
26783
0
  vctxt->err = -1;
26784
0
  xmlStopParser(vctxt->parserCtxt);
26785
0
    }
26786
0
}
26787
26788
/*
26789
* Process CDATA content.
26790
*/
26791
static void
26792
xmlSchemaSAXHandleCDataSection(void *ctx,
26793
           const xmlChar * ch,
26794
           int len)
26795
0
{
26796
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
26797
26798
0
    if (vctxt->depth < 0)
26799
0
  return;
26800
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
26801
0
  return;
26802
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26803
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26804
0
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
26805
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
26806
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
26807
0
      "calling xmlSchemaVPushText()");
26808
0
  vctxt->err = -1;
26809
0
  xmlStopParser(vctxt->parserCtxt);
26810
0
    }
26811
0
}
26812
26813
static void
26814
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
26815
          const xmlChar * name ATTRIBUTE_UNUSED)
26816
0
{
26817
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
26818
26819
0
    if (vctxt->depth < 0)
26820
0
  return;
26821
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
26822
0
  return;
26823
    /* SAX VAL TODO: What to do here? */
26824
0
}
26825
26826
static void
26827
xmlSchemaSAXHandleStartElementNs(void *ctx,
26828
         const xmlChar * localname,
26829
         const xmlChar * prefix ATTRIBUTE_UNUSED,
26830
         const xmlChar * URI,
26831
         int nb_namespaces,
26832
         const xmlChar ** namespaces,
26833
         int nb_attributes,
26834
         int nb_defaulted ATTRIBUTE_UNUSED,
26835
         const xmlChar ** attributes)
26836
0
{
26837
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
26838
0
    int ret;
26839
0
    xmlSchemaNodeInfoPtr ielem;
26840
0
    int i, j;
26841
26842
    /*
26843
    * SAX VAL TODO: What to do with nb_defaulted?
26844
    */
26845
    /*
26846
    * Skip elements if inside a "skip" wildcard or invalid.
26847
    */
26848
0
    vctxt->depth++;
26849
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
26850
0
  return;
26851
    /*
26852
    * Push the element.
26853
    */
26854
0
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26855
0
  VERROR_INT("xmlSchemaSAXHandleStartElementNs",
26856
0
      "calling xmlSchemaValidatorPushElem()");
26857
0
  goto internal_error;
26858
0
    }
26859
0
    ielem = vctxt->inode;
26860
    /*
26861
    * TODO: Is this OK?
26862
    */
26863
0
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
26864
0
    ielem->localName = localname;
26865
0
    ielem->nsName = URI;
26866
0
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
26867
    /*
26868
    * Register namespaces on the elem info.
26869
    */
26870
0
    if (nb_namespaces != 0) {
26871
  /*
26872
  * Although the parser builds its own namespace list,
26873
  * we have no access to it, so we'll use an own one.
26874
  */
26875
0
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
26876
      /*
26877
      * Store prefix and namespace name.
26878
      */
26879
0
            if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
26880
0
                const xmlChar **tmp;
26881
0
                size_t elemSize = 2 * sizeof(tmp[0]);
26882
0
                int newSize;
26883
26884
0
                newSize = xmlGrowCapacity(ielem->sizeNsBindings, elemSize,
26885
0
                                          5, XML_MAX_ITEMS);
26886
0
                if (newSize < 0) {
26887
0
                    xmlSchemaVErrMemory(vctxt);
26888
0
                    goto internal_error;
26889
0
                }
26890
0
                tmp = xmlRealloc(ielem->nsBindings, newSize * elemSize);
26891
0
                if (tmp == NULL) {
26892
0
                    xmlSchemaVErrMemory(vctxt);
26893
0
                    goto internal_error;
26894
0
                }
26895
26896
0
                ielem->nsBindings = tmp;
26897
0
                ielem->sizeNsBindings = newSize;
26898
0
      }
26899
26900
0
      ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
26901
0
      if (namespaces[j+1][0] == 0) {
26902
    /*
26903
    * Handle xmlns="".
26904
    */
26905
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
26906
0
      } else
26907
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
26908
0
        namespaces[j+1];
26909
0
      ielem->nbNsBindings++;
26910
0
  }
26911
0
    }
26912
    /*
26913
    * Register attributes.
26914
    * SAX VAL TODO: We are not adding namespace declaration
26915
    * attributes yet.
26916
    */
26917
0
    if (nb_attributes != 0) {
26918
0
  int valueLen, k, l;
26919
0
  xmlChar *value;
26920
26921
0
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
26922
      /*
26923
      * Duplicate the value, changing any &#38; to a literal ampersand.
26924
      *
26925
      * libxml2 differs from normal SAX here in that it escapes all ampersands
26926
      * as &#38; instead of delivering the raw converted string. Changing the
26927
      * behavior at this point would break applications that use this API, so
26928
      * we are forced to work around it.
26929
      */
26930
0
      valueLen = attributes[j+4] - attributes[j+3];
26931
0
      value = xmlMalloc(valueLen + 1);
26932
0
      if (value == NULL) {
26933
0
    xmlSchemaVErrMemory(vctxt);
26934
0
    goto internal_error;
26935
0
      }
26936
0
      for (k = 0, l = 0; k < valueLen; l++) {
26937
0
    if (k < valueLen - 4 &&
26938
0
        attributes[j+3][k+0] == '&' &&
26939
0
        attributes[j+3][k+1] == '#' &&
26940
0
        attributes[j+3][k+2] == '3' &&
26941
0
        attributes[j+3][k+3] == '8' &&
26942
0
        attributes[j+3][k+4] == ';') {
26943
0
        value[l] = '&';
26944
0
        k += 5;
26945
0
    } else {
26946
0
        value[l] = attributes[j+3][k];
26947
0
        k++;
26948
0
    }
26949
0
      }
26950
0
      value[l] = '\0';
26951
      /*
26952
      * TODO: Set the node line.
26953
      */
26954
0
      ret = xmlSchemaValidatorPushAttribute(vctxt,
26955
0
    NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
26956
0
    value, 1);
26957
0
      if (ret == -1) {
26958
0
    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
26959
0
        "calling xmlSchemaValidatorPushAttribute()");
26960
0
    goto internal_error;
26961
0
      }
26962
0
  }
26963
0
    }
26964
    /*
26965
    * Validate the element.
26966
    */
26967
0
    ret = xmlSchemaValidateElem(vctxt);
26968
0
    if (ret != 0) {
26969
0
  if (ret == -1) {
26970
0
      VERROR_INT("xmlSchemaSAXHandleStartElementNs",
26971
0
    "calling xmlSchemaValidateElem()");
26972
0
      goto internal_error;
26973
0
  }
26974
0
  goto exit;
26975
0
    }
26976
26977
0
exit:
26978
0
    return;
26979
0
internal_error:
26980
0
    vctxt->err = -1;
26981
0
    xmlStopParser(vctxt->parserCtxt);
26982
0
}
26983
26984
static void
26985
xmlSchemaSAXHandleEndElementNs(void *ctx,
26986
             const xmlChar * localname ATTRIBUTE_UNUSED,
26987
             const xmlChar * prefix ATTRIBUTE_UNUSED,
26988
             const xmlChar * URI ATTRIBUTE_UNUSED)
26989
0
{
26990
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
26991
0
    int res;
26992
26993
    /*
26994
    * Skip elements if inside a "skip" wildcard or if invalid.
26995
    */
26996
0
    if (vctxt->skipDepth != -1) {
26997
0
  if (vctxt->depth > vctxt->skipDepth) {
26998
0
      vctxt->depth--;
26999
0
      return;
27000
0
  } else
27001
0
      vctxt->skipDepth = -1;
27002
0
    }
27003
    /*
27004
    * SAX VAL TODO: Just a temporary check.
27005
    */
27006
0
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27007
0
  (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27008
0
  VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27009
0
      "elem pop mismatch");
27010
0
    }
27011
0
    res = xmlSchemaValidatorPopElem(vctxt);
27012
0
    if (res != 0) {
27013
0
  if (res < 0) {
27014
0
      VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27015
0
    "calling xmlSchemaValidatorPopElem()");
27016
0
      goto internal_error;
27017
0
  }
27018
0
  goto exit;
27019
0
    }
27020
0
exit:
27021
0
    return;
27022
0
internal_error:
27023
0
    vctxt->err = -1;
27024
0
    xmlStopParser(vctxt->parserCtxt);
27025
0
}
27026
27027
/************************************************************************
27028
 *                  *
27029
 *      Validation interfaces       *
27030
 *                  *
27031
 ************************************************************************/
27032
27033
/**
27034
 * Create an XML Schemas validation context based on the given schema.
27035
 *
27036
 * @param schema  a precompiled XML Schemas
27037
 * @returns the validation context or NULL in case of error
27038
 */
27039
xmlSchemaValidCtxt *
27040
xmlSchemaNewValidCtxt(xmlSchema *schema)
27041
0
{
27042
0
    xmlSchemaValidCtxtPtr ret;
27043
27044
0
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27045
0
    if (ret == NULL) {
27046
0
        xmlSchemaVErrMemory(NULL);
27047
0
        return (NULL);
27048
0
    }
27049
0
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27050
0
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27051
0
    ret->dict = xmlDictCreate();
27052
0
    if (ret->dict == NULL) {
27053
0
        xmlSchemaFreeValidCtxt(ret);
27054
0
        return(NULL);
27055
0
    }
27056
0
    ret->nodeQNames = xmlSchemaItemListCreate();
27057
0
    if (ret->nodeQNames == NULL) {
27058
0
        xmlSchemaFreeValidCtxt(ret);
27059
0
        return(NULL);
27060
0
    }
27061
0
    ret->schema = schema;
27062
0
    return (ret);
27063
0
}
27064
27065
/**
27066
 * Workaround to provide file error reporting information when this is
27067
 * not provided by current APIs
27068
 *
27069
 * @param vctxt  the schema validation context
27070
 * @param filename  the file name
27071
 */
27072
void
27073
0
xmlSchemaValidateSetFilename(xmlSchemaValidCtxt *vctxt, const char *filename) {
27074
0
    if (vctxt == NULL)
27075
0
        return;
27076
0
    if (vctxt->filename != NULL)
27077
0
        xmlFree(vctxt->filename);
27078
0
    if (filename != NULL)
27079
0
        vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27080
0
    else
27081
0
        vctxt->filename = NULL;
27082
0
}
27083
27084
/**
27085
 * Free the resources associated to the schema validation context;
27086
 * leaves some fields alive intended for reuse of the context.
27087
 *
27088
 * @param vctxt  the schema validation context
27089
 */
27090
static void
27091
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27092
0
{
27093
0
    if (vctxt == NULL)
27094
0
        return;
27095
27096
    /*
27097
    * TODO: Should we clear the flags?
27098
    *   Might be problematic if one reuses the context
27099
    *   and assumes that the options remain the same.
27100
    */
27101
0
    vctxt->flags = 0;
27102
0
    vctxt->validationRoot = NULL;
27103
0
    vctxt->doc = NULL;
27104
0
#ifdef LIBXML_READER_ENABLED
27105
0
    vctxt->reader = NULL;
27106
0
#endif
27107
0
    vctxt->hasKeyrefs = 0;
27108
27109
0
    if (vctxt->value != NULL) {
27110
0
        xmlSchemaFreeValue(vctxt->value);
27111
0
  vctxt->value = NULL;
27112
0
    }
27113
    /*
27114
    * Augmented IDC information.
27115
    */
27116
0
    if (vctxt->aidcs != NULL) {
27117
0
  xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27118
0
  do {
27119
0
      next = cur->next;
27120
0
      xmlFree(cur);
27121
0
      cur = next;
27122
0
  } while (cur != NULL);
27123
0
  vctxt->aidcs = NULL;
27124
0
    }
27125
27126
0
    if (vctxt->idcNodes != NULL) {
27127
0
  int i;
27128
0
  xmlSchemaPSVIIDCNodePtr item;
27129
27130
0
  for (i = 0; i < vctxt->nbIdcNodes; i++) {
27131
0
      item = vctxt->idcNodes[i];
27132
0
      xmlFree(item->keys);
27133
0
      xmlFree(item);
27134
0
  }
27135
0
  xmlFree(vctxt->idcNodes);
27136
0
  vctxt->idcNodes = NULL;
27137
0
  vctxt->nbIdcNodes = 0;
27138
0
  vctxt->sizeIdcNodes = 0;
27139
0
    }
27140
27141
0
    if (vctxt->idcKeys != NULL) {
27142
0
  int i;
27143
0
  for (i = 0; i < vctxt->nbIdcKeys; i++)
27144
0
      xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27145
0
  xmlFree(vctxt->idcKeys);
27146
0
  vctxt->idcKeys = NULL;
27147
0
  vctxt->nbIdcKeys = 0;
27148
0
  vctxt->sizeIdcKeys = 0;
27149
0
    }
27150
27151
    /*
27152
    * Note that we won't delete the XPath state pool here.
27153
    */
27154
0
    if (vctxt->xpathStates != NULL) {
27155
0
  xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27156
0
  vctxt->xpathStates = NULL;
27157
0
    }
27158
    /*
27159
    * Attribute info.
27160
    */
27161
0
    if (vctxt->nbAttrInfos != 0) {
27162
0
  xmlSchemaClearAttrInfos(vctxt);
27163
0
    }
27164
    /*
27165
    * Element info.
27166
    */
27167
0
    if (vctxt->elemInfos != NULL) {
27168
0
  int i;
27169
0
  xmlSchemaNodeInfoPtr ei;
27170
27171
0
  for (i = 0; i < vctxt->sizeElemInfos; i++) {
27172
0
      ei = vctxt->elemInfos[i];
27173
0
      if (ei == NULL)
27174
0
    break;
27175
0
      xmlSchemaClearElemInfo(vctxt, ei);
27176
0
  }
27177
0
    }
27178
0
    xmlSchemaItemListClear(vctxt->nodeQNames);
27179
    /* Recreate the dict. */
27180
0
    xmlDictFree(vctxt->dict);
27181
    /*
27182
    * TODO: Is is save to recreate it? Do we have a scenario
27183
    * where the user provides the dict?
27184
    */
27185
0
    vctxt->dict = xmlDictCreate();
27186
27187
0
    if (vctxt->filename != NULL) {
27188
0
        xmlFree(vctxt->filename);
27189
0
  vctxt->filename = NULL;
27190
0
    }
27191
27192
    /*
27193
     * Note that some cleanup functions can move items to the cache,
27194
     * so the cache shouldn't be freed too early.
27195
     */
27196
0
    if (vctxt->idcMatcherCache != NULL) {
27197
0
  xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27198
27199
0
  while (matcher) {
27200
0
      tmp = matcher;
27201
0
      matcher = matcher->nextCached;
27202
0
      xmlSchemaIDCFreeMatcherList(tmp);
27203
0
  }
27204
0
  vctxt->idcMatcherCache = NULL;
27205
0
    }
27206
0
}
27207
27208
/**
27209
 * Free the resources associated to the schema validation context
27210
 *
27211
 * @param ctxt  the schema validation context
27212
 */
27213
void
27214
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxt *ctxt)
27215
0
{
27216
0
    if (ctxt == NULL)
27217
0
        return;
27218
0
    if (ctxt->value != NULL)
27219
0
        xmlSchemaFreeValue(ctxt->value);
27220
0
    if (ctxt->pctxt != NULL)
27221
0
  xmlSchemaFreeParserCtxt(ctxt->pctxt);
27222
0
    if (ctxt->idcNodes != NULL) {
27223
0
  int i;
27224
0
  xmlSchemaPSVIIDCNodePtr item;
27225
27226
0
  for (i = 0; i < ctxt->nbIdcNodes; i++) {
27227
0
      item = ctxt->idcNodes[i];
27228
0
      xmlFree(item->keys);
27229
0
      xmlFree(item);
27230
0
  }
27231
0
  xmlFree(ctxt->idcNodes);
27232
0
    }
27233
0
    if (ctxt->idcKeys != NULL) {
27234
0
  int i;
27235
0
  for (i = 0; i < ctxt->nbIdcKeys; i++)
27236
0
      xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27237
0
  xmlFree(ctxt->idcKeys);
27238
0
    }
27239
27240
0
    if (ctxt->xpathStates != NULL) {
27241
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27242
0
  ctxt->xpathStates = NULL;
27243
0
    }
27244
0
    if (ctxt->xpathStatePool != NULL) {
27245
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27246
0
  ctxt->xpathStatePool = NULL;
27247
0
    }
27248
27249
    /*
27250
    * Augmented IDC information.
27251
    */
27252
0
    if (ctxt->aidcs != NULL) {
27253
0
  xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27254
0
  do {
27255
0
      next = cur->next;
27256
0
      xmlFree(cur);
27257
0
      cur = next;
27258
0
  } while (cur != NULL);
27259
0
    }
27260
0
    if (ctxt->attrInfos != NULL) {
27261
0
  int i;
27262
0
  xmlSchemaAttrInfoPtr attr;
27263
27264
  /* Just a paranoid call to the cleanup. */
27265
0
  if (ctxt->nbAttrInfos != 0)
27266
0
      xmlSchemaClearAttrInfos(ctxt);
27267
0
  for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27268
0
      attr = ctxt->attrInfos[i];
27269
0
      xmlFree(attr);
27270
0
  }
27271
0
  xmlFree(ctxt->attrInfos);
27272
0
    }
27273
0
    if (ctxt->elemInfos != NULL) {
27274
0
  int i;
27275
0
  xmlSchemaNodeInfoPtr ei;
27276
27277
0
  for (i = 0; i < ctxt->sizeElemInfos; i++) {
27278
0
      ei = ctxt->elemInfos[i];
27279
0
      if (ei == NULL)
27280
0
    break;
27281
0
      xmlSchemaClearElemInfo(ctxt, ei);
27282
0
      xmlFree(ei);
27283
0
  }
27284
0
  xmlFree(ctxt->elemInfos);
27285
0
    }
27286
0
    if (ctxt->nodeQNames != NULL)
27287
0
  xmlSchemaItemListFree(ctxt->nodeQNames);
27288
0
    if (ctxt->dict != NULL)
27289
0
  xmlDictFree(ctxt->dict);
27290
0
    if (ctxt->filename != NULL)
27291
0
  xmlFree(ctxt->filename);
27292
0
    xmlFree(ctxt);
27293
0
}
27294
27295
/**
27296
 * Check if any error was detected during validation.
27297
 *
27298
 * @param ctxt  the schema validation context
27299
 * @returns 1 if valid so far, 0 if errors were detected, and -1 in case
27300
 *         of internal error.
27301
 */
27302
int
27303
xmlSchemaIsValid(xmlSchemaValidCtxt *ctxt)
27304
0
{
27305
0
    if (ctxt == NULL)
27306
0
        return(-1);
27307
0
    return(ctxt->err == 0);
27308
0
}
27309
27310
/**
27311
 * Set the error and warning callback information
27312
 *
27313
 * @deprecated Use xmlSchemaSetValidStructuredErrors.
27314
 *
27315
 * @param ctxt  a schema validation context
27316
 * @param err  the error function
27317
 * @param warn  the warning function
27318
 * @param ctx  the functions context
27319
 */
27320
void
27321
xmlSchemaSetValidErrors(xmlSchemaValidCtxt *ctxt,
27322
                        xmlSchemaValidityErrorFunc err,
27323
                        xmlSchemaValidityWarningFunc warn, void *ctx)
27324
0
{
27325
0
    if (ctxt == NULL)
27326
0
        return;
27327
0
    ctxt->error = err;
27328
0
    ctxt->warning = warn;
27329
0
    ctxt->errCtxt = ctx;
27330
0
    if (ctxt->pctxt != NULL)
27331
0
  xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27332
0
}
27333
27334
/**
27335
 * Set the structured error callback
27336
 *
27337
 * @param ctxt  a schema validation context
27338
 * @param serror  the structured error function
27339
 * @param ctx  the functions context
27340
 */
27341
void
27342
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxt *ctxt,
27343
          xmlStructuredErrorFunc serror, void *ctx)
27344
0
{
27345
0
    if (ctxt == NULL)
27346
0
        return;
27347
0
    ctxt->serror = serror;
27348
0
    ctxt->error = NULL;
27349
0
    ctxt->warning = NULL;
27350
0
    ctxt->errCtxt = ctx;
27351
0
    if (ctxt->pctxt != NULL)
27352
0
  xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27353
0
}
27354
27355
/**
27356
 * Get the error and warning callback information
27357
 *
27358
 * @param ctxt  a XML-Schema validation context
27359
 * @param err  the error function result
27360
 * @param warn  the warning function result
27361
 * @param ctx  the functions context result
27362
 * @returns -1 in case of error and 0 otherwise
27363
 */
27364
int
27365
xmlSchemaGetValidErrors(xmlSchemaValidCtxt *ctxt,
27366
      xmlSchemaValidityErrorFunc * err,
27367
      xmlSchemaValidityWarningFunc * warn, void **ctx)
27368
0
{
27369
0
  if (ctxt == NULL)
27370
0
    return (-1);
27371
0
  if (err != NULL)
27372
0
    *err = ctxt->error;
27373
0
  if (warn != NULL)
27374
0
    *warn = ctxt->warning;
27375
0
  if (ctx != NULL)
27376
0
    *ctx = ctxt->errCtxt;
27377
0
  return (0);
27378
0
}
27379
27380
27381
/**
27382
 * Sets the options to be used during the validation.
27383
 *
27384
 * @param ctxt    a schema validation context
27385
 * @param options  a combination of xmlSchemaValidOption
27386
 * @returns 0 in case of success, -1 in case of an
27387
 * API error.
27388
 */
27389
int
27390
xmlSchemaSetValidOptions(xmlSchemaValidCtxt *ctxt,
27391
       int options)
27392
27393
0
{
27394
0
    int i;
27395
27396
0
    if (ctxt == NULL)
27397
0
  return (-1);
27398
    /*
27399
    * WARNING: Change the start value if adding to the
27400
    * xmlSchemaValidOption.
27401
    * TODO: Is there an other, more easy to maintain,
27402
    * way?
27403
    */
27404
0
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
27405
0
        if (options & 1<<i)
27406
0
      return (-1);
27407
0
    }
27408
0
    ctxt->options = options;
27409
0
    return (0);
27410
0
}
27411
27412
/**
27413
 * Get the validation context options.
27414
 *
27415
 * @param ctxt  a schema validation context
27416
 * @returns the option combination or -1 on error.
27417
 */
27418
int
27419
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxt *ctxt)
27420
27421
0
{
27422
0
    if (ctxt == NULL)
27423
0
  return (-1);
27424
0
    else
27425
0
  return (ctxt->options);
27426
0
}
27427
27428
static int
27429
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27430
0
{
27431
0
    xmlAttrPtr attr;
27432
0
    int ret = 0;
27433
0
    xmlSchemaNodeInfoPtr ielem = NULL;
27434
0
    xmlNodePtr node, valRoot;
27435
0
    const xmlChar *nsName;
27436
27437
    /* DOC VAL TODO: Move this to the start function. */
27438
0
    if (vctxt->validationRoot != NULL)
27439
0
        valRoot = vctxt->validationRoot;
27440
0
    else
27441
0
  valRoot = xmlDocGetRootElement(vctxt->doc);
27442
0
    if (valRoot == NULL) {
27443
  /* VAL TODO: Error code? */
27444
0
  VERROR(1, NULL, "The document has no document element");
27445
0
  return (1);
27446
0
    }
27447
0
    vctxt->depth = -1;
27448
0
    vctxt->validationRoot = valRoot;
27449
0
    node = valRoot;
27450
0
    while (node != NULL) {
27451
0
  if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27452
0
      goto next_sibling;
27453
0
  if (node->type == XML_ELEMENT_NODE) {
27454
27455
      /*
27456
      * Init the node-info.
27457
      */
27458
0
      vctxt->depth++;
27459
0
      if (xmlSchemaValidatorPushElem(vctxt) == -1)
27460
0
    goto internal_error;
27461
0
      ielem = vctxt->inode;
27462
0
      ielem->node = node;
27463
0
      ielem->nodeLine = node->line;
27464
0
      ielem->localName = node->name;
27465
0
      if (node->ns != NULL)
27466
0
    ielem->nsName = node->ns->href;
27467
0
      ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27468
      /*
27469
      * Register attributes.
27470
      * DOC VAL TODO: We do not register namespace declaration
27471
      * attributes yet.
27472
      */
27473
0
      vctxt->nbAttrInfos = 0;
27474
0
      if (node->properties != NULL) {
27475
0
    attr = node->properties;
27476
0
    do {
27477
0
                    xmlChar *content;
27478
27479
0
        if (attr->ns != NULL)
27480
0
      nsName = attr->ns->href;
27481
0
        else
27482
0
      nsName = NULL;
27483
0
                    content = xmlNodeListGetString(attr->doc,
27484
0
                                                   attr->children, 1);
27485
0
        ret = xmlSchemaValidatorPushAttribute(vctxt,
27486
0
      (xmlNodePtr) attr,
27487
      /*
27488
      * Note that we give it the line number of the
27489
      * parent element.
27490
      */
27491
0
      ielem->nodeLine,
27492
0
      attr->name, nsName, 0,
27493
0
      content, 1);
27494
0
        if (ret == -1) {
27495
0
      VERROR_INT("xmlSchemaDocWalk",
27496
0
          "calling xmlSchemaValidatorPushAttribute()");
27497
0
                        xmlFree(content);
27498
0
      goto internal_error;
27499
0
        }
27500
0
        attr = attr->next;
27501
0
    } while (attr);
27502
0
      }
27503
      /*
27504
      * Validate the element.
27505
      */
27506
0
      ret = xmlSchemaValidateElem(vctxt);
27507
0
      if (ret != 0) {
27508
0
    if (ret == -1) {
27509
0
        VERROR_INT("xmlSchemaDocWalk",
27510
0
      "calling xmlSchemaValidateElem()");
27511
0
        goto internal_error;
27512
0
    }
27513
    /*
27514
    * Don't stop validation; just skip the content
27515
    * of this element.
27516
    */
27517
0
    goto leave_node;
27518
0
      }
27519
0
      if ((vctxt->skipDepth != -1) &&
27520
0
    (vctxt->depth >= vctxt->skipDepth))
27521
0
    goto leave_node;
27522
0
  } else if ((node->type == XML_TEXT_NODE) ||
27523
0
      (node->type == XML_CDATA_SECTION_NODE)) {
27524
      /*
27525
      * Process character content.
27526
      */
27527
0
      if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27528
0
    ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27529
0
      ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27530
0
    -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27531
0
      if (ret < 0) {
27532
0
    VERROR_INT("xmlSchemaVDocWalk",
27533
0
        "calling xmlSchemaVPushText()");
27534
0
    goto internal_error;
27535
0
      }
27536
      /*
27537
      * DOC VAL TODO: Should we skip further validation of the
27538
      * element content here?
27539
      */
27540
0
  } else if ((node->type == XML_ENTITY_NODE) ||
27541
0
      (node->type == XML_ENTITY_REF_NODE)) {
27542
      /*
27543
      * DOC VAL TODO: What to do with entities?
27544
      */
27545
0
      VERROR_INT("xmlSchemaVDocWalk",
27546
0
    "there is at least one entity reference in the node-tree "
27547
0
    "currently being validated. Processing of entities with "
27548
0
    "this XML Schema processor is not supported (yet). Please "
27549
0
    "substitute entities before validation.");
27550
0
      goto internal_error;
27551
0
  } else {
27552
0
      goto leave_node;
27553
      /*
27554
      * DOC VAL TODO: XInclude nodes, etc.
27555
      */
27556
0
  }
27557
  /*
27558
  * Walk the doc.
27559
  */
27560
0
  if (node->children != NULL) {
27561
0
      node = node->children;
27562
0
      continue;
27563
0
  }
27564
0
leave_node:
27565
0
  if (node->type == XML_ELEMENT_NODE) {
27566
      /*
27567
      * Leaving the scope of an element.
27568
      */
27569
0
      if (node != vctxt->inode->node) {
27570
0
    VERROR_INT("xmlSchemaVDocWalk",
27571
0
        "element position mismatch");
27572
0
    goto internal_error;
27573
0
      }
27574
0
      ret = xmlSchemaValidatorPopElem(vctxt);
27575
0
      if (ret != 0) {
27576
0
    if (ret < 0) {
27577
0
        VERROR_INT("xmlSchemaVDocWalk",
27578
0
      "calling xmlSchemaValidatorPopElem()");
27579
0
        goto internal_error;
27580
0
    }
27581
0
      }
27582
0
      if (node == valRoot)
27583
0
    goto exit;
27584
0
  }
27585
0
next_sibling:
27586
0
  if (node->next != NULL)
27587
0
      node = node->next;
27588
0
  else {
27589
0
      node = node->parent;
27590
0
      goto leave_node;
27591
0
  }
27592
0
    }
27593
27594
0
exit:
27595
0
    return (ret);
27596
0
internal_error:
27597
0
    return (-1);
27598
0
}
27599
27600
static int
27601
0
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27602
    /*
27603
    * Some initialization.
27604
    */
27605
0
    vctxt->err = 0;
27606
0
    vctxt->nberrors = 0;
27607
0
    vctxt->depth = -1;
27608
0
    vctxt->skipDepth = -1;
27609
0
    vctxt->hasKeyrefs = 0;
27610
#ifdef ENABLE_IDC_NODE_TABLES_TEST
27611
    vctxt->createIDCNodeTables = 1;
27612
#else
27613
0
    vctxt->createIDCNodeTables = 0;
27614
0
#endif
27615
    /*
27616
    * Create a schema + parser if necessary.
27617
    */
27618
0
    if (vctxt->schema == NULL) {
27619
0
  xmlSchemaParserCtxtPtr pctxt;
27620
27621
0
  vctxt->xsiAssemble = 1;
27622
  /*
27623
  * If not schema was given then we will create a schema
27624
  * dynamically using XSI schema locations.
27625
  *
27626
  * Create the schema parser context.
27627
  */
27628
0
  if ((vctxt->pctxt == NULL) &&
27629
0
     (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27630
0
     return (-1);
27631
0
  pctxt = vctxt->pctxt;
27632
0
  pctxt->xsiAssemble = 1;
27633
  /*
27634
  * Create the schema.
27635
  */
27636
0
  vctxt->schema = xmlSchemaNewSchema(pctxt);
27637
0
  if (vctxt->schema == NULL)
27638
0
      return (-1);
27639
  /*
27640
  * Create the schema construction context.
27641
  */
27642
0
  pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
27643
0
  if (pctxt->constructor == NULL)
27644
0
      return(-1);
27645
0
  pctxt->constructor->mainSchema = vctxt->schema;
27646
  /*
27647
  * Take ownership of the constructor to be able to free it.
27648
  */
27649
0
  pctxt->ownsConstructor = 1;
27650
0
    }
27651
    /*
27652
    * Augment the IDC definitions for the main schema and all imported ones
27653
    * NOTE: main schema if the first in the imported list
27654
    */
27655
0
    xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
27656
0
                vctxt);
27657
27658
0
    return(0);
27659
0
}
27660
27661
static void
27662
0
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
27663
0
    if (vctxt->xsiAssemble) {
27664
0
  if (vctxt->schema != NULL) {
27665
0
      xmlSchemaFree(vctxt->schema);
27666
0
      vctxt->schema = NULL;
27667
0
  }
27668
0
    }
27669
0
    xmlSchemaClearValidCtxt(vctxt);
27670
0
}
27671
27672
static int
27673
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
27674
0
{
27675
0
    int ret = 0;
27676
27677
0
    if (xmlSchemaPreRun(vctxt) < 0)
27678
0
        return(-1);
27679
27680
0
    if (vctxt->doc != NULL) {
27681
  /*
27682
   * Tree validation.
27683
   */
27684
0
  ret = xmlSchemaVDocWalk(vctxt);
27685
0
#ifdef LIBXML_READER_ENABLED
27686
0
    } else if (vctxt->reader != NULL) {
27687
  /*
27688
   * XML Reader validation.
27689
   */
27690
#ifdef XML_SCHEMA_READER_ENABLED
27691
  ret = xmlSchemaVReaderWalk(vctxt);
27692
#endif
27693
0
#endif
27694
0
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
27695
  /*
27696
   * SAX validation.
27697
   */
27698
0
  ret = xmlParseDocument(vctxt->parserCtxt);
27699
0
    } else {
27700
0
  VERROR_INT("xmlSchemaVStart",
27701
0
      "no instance to validate");
27702
0
  ret = -1;
27703
0
    }
27704
27705
0
    xmlSchemaPostRun(vctxt);
27706
0
    if (ret == 0)
27707
0
  ret = vctxt->err;
27708
0
    return (ret);
27709
0
}
27710
27711
/**
27712
 * Validate a branch of a tree, starting with the given `elem`.
27713
 *
27714
 * @param ctxt  a schema validation context
27715
 * @param elem  an element node
27716
 * @returns 0 if the element and its subtree is valid, a positive error
27717
 * code number otherwise and -1 in case of an internal or API error.
27718
 */
27719
int
27720
xmlSchemaValidateOneElement(xmlSchemaValidCtxt *ctxt, xmlNode *elem)
27721
0
{
27722
0
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
27723
0
  return (-1);
27724
27725
0
    if (ctxt->schema == NULL)
27726
0
  return (-1);
27727
27728
0
    ctxt->doc = elem->doc;
27729
0
    ctxt->node = elem;
27730
0
    ctxt->validationRoot = elem;
27731
0
    return(xmlSchemaVStart(ctxt));
27732
0
}
27733
27734
/**
27735
 * Validate a document tree in memory.
27736
 *
27737
 * @param ctxt  a schema validation context
27738
 * @param doc  a parsed document tree
27739
 * @returns 0 if the document is schemas valid, a positive error code
27740
 *     number otherwise and -1 in case of internal or API error.
27741
 */
27742
int
27743
xmlSchemaValidateDoc(xmlSchemaValidCtxt *ctxt, xmlDoc *doc)
27744
0
{
27745
0
    if ((ctxt == NULL) || (doc == NULL))
27746
0
        return (-1);
27747
27748
0
    ctxt->doc = doc;
27749
0
    ctxt->node = xmlDocGetRootElement(doc);
27750
0
    if (ctxt->node == NULL) {
27751
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
27752
0
      XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
27753
0
      (xmlNodePtr) doc, NULL,
27754
0
      "The document has no document element", NULL, NULL);
27755
0
        return (ctxt->err);
27756
0
    }
27757
0
    ctxt->validationRoot = ctxt->node;
27758
0
    return (xmlSchemaVStart(ctxt));
27759
0
}
27760
27761
27762
/************************************************************************
27763
 *                  *
27764
 *    Function and data for SAX streaming API     *
27765
 *                  *
27766
 ************************************************************************/
27767
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
27768
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
27769
27770
struct _xmlSchemaSplitSAXData {
27771
    xmlSAXHandlerPtr      user_sax;
27772
    void                 *user_data;
27773
    xmlSchemaValidCtxtPtr ctxt;
27774
    xmlSAXHandlerPtr      schemas_sax;
27775
};
27776
27777
0
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
27778
27779
struct _xmlSchemaSAXPlug {
27780
    unsigned int magic;
27781
27782
    /* the original callbacks information */
27783
    xmlSAXHandlerPtr     *user_sax_ptr;
27784
    xmlSAXHandlerPtr      user_sax;
27785
    void                **user_data_ptr;
27786
    void                 *user_data;
27787
27788
    /* the block plugged back and validation information */
27789
    xmlSAXHandler         schemas_sax;
27790
    xmlSchemaValidCtxtPtr ctxt;
27791
};
27792
27793
/* All those functions just bounces to the user provided SAX handlers */
27794
static void
27795
internalSubsetSplit(void *ctx, const xmlChar *name,
27796
         const xmlChar *ExternalID, const xmlChar *SystemID)
27797
0
{
27798
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27799
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27800
0
        (ctxt->user_sax->internalSubset != NULL))
27801
0
  ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
27802
0
                                 SystemID);
27803
0
}
27804
27805
static int
27806
isStandaloneSplit(void *ctx)
27807
0
{
27808
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27809
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27810
0
        (ctxt->user_sax->isStandalone != NULL))
27811
0
  return(ctxt->user_sax->isStandalone(ctxt->user_data));
27812
0
    return(0);
27813
0
}
27814
27815
static int
27816
hasInternalSubsetSplit(void *ctx)
27817
0
{
27818
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27819
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27820
0
        (ctxt->user_sax->hasInternalSubset != NULL))
27821
0
  return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
27822
0
    return(0);
27823
0
}
27824
27825
static int
27826
hasExternalSubsetSplit(void *ctx)
27827
0
{
27828
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27829
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27830
0
        (ctxt->user_sax->hasExternalSubset != NULL))
27831
0
  return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
27832
0
    return(0);
27833
0
}
27834
27835
static void
27836
externalSubsetSplit(void *ctx, const xmlChar *name,
27837
         const xmlChar *ExternalID, const xmlChar *SystemID)
27838
0
{
27839
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27840
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27841
0
        (ctxt->user_sax->externalSubset != NULL))
27842
0
  ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
27843
0
                                 SystemID);
27844
0
}
27845
27846
static xmlParserInputPtr
27847
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
27848
0
{
27849
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27850
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27851
0
        (ctxt->user_sax->resolveEntity != NULL))
27852
0
  return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
27853
0
                                       systemId));
27854
0
    return(NULL);
27855
0
}
27856
27857
static xmlEntityPtr
27858
getEntitySplit(void *ctx, const xmlChar *name)
27859
0
{
27860
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27861
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27862
0
        (ctxt->user_sax->getEntity != NULL))
27863
0
  return(ctxt->user_sax->getEntity(ctxt->user_data, name));
27864
0
    return(NULL);
27865
0
}
27866
27867
static xmlEntityPtr
27868
getParameterEntitySplit(void *ctx, const xmlChar *name)
27869
0
{
27870
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27871
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27872
0
        (ctxt->user_sax->getParameterEntity != NULL))
27873
0
  return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
27874
0
    return(NULL);
27875
0
}
27876
27877
27878
static void
27879
entityDeclSplit(void *ctx, const xmlChar *name, int type,
27880
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
27881
0
{
27882
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27883
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27884
0
        (ctxt->user_sax->entityDecl != NULL))
27885
0
  ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
27886
0
                             systemId, content);
27887
0
}
27888
27889
static void
27890
attributeDeclSplit(void *ctx, const xmlChar * elem,
27891
                   const xmlChar * name, int type, int def,
27892
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
27893
0
{
27894
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27895
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27896
0
        (ctxt->user_sax->attributeDecl != NULL)) {
27897
0
  ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
27898
0
                                def, defaultValue, tree);
27899
0
    } else {
27900
0
  xmlFreeEnumeration(tree);
27901
0
    }
27902
0
}
27903
27904
static void
27905
elementDeclSplit(void *ctx, const xmlChar *name, int type,
27906
      xmlElementContentPtr content)
27907
0
{
27908
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27909
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27910
0
        (ctxt->user_sax->elementDecl != NULL))
27911
0
  ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
27912
0
}
27913
27914
static void
27915
notationDeclSplit(void *ctx, const xmlChar *name,
27916
       const xmlChar *publicId, const xmlChar *systemId)
27917
0
{
27918
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27919
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27920
0
        (ctxt->user_sax->notationDecl != NULL))
27921
0
  ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
27922
0
                               systemId);
27923
0
}
27924
27925
static void
27926
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
27927
       const xmlChar *publicId, const xmlChar *systemId,
27928
       const xmlChar *notationName)
27929
0
{
27930
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27931
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27932
0
        (ctxt->user_sax->unparsedEntityDecl != NULL))
27933
0
  ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
27934
0
                                     systemId, notationName);
27935
0
}
27936
27937
static void
27938
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
27939
0
{
27940
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27941
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27942
0
        (ctxt->user_sax->setDocumentLocator != NULL))
27943
0
  ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
27944
0
}
27945
27946
static void
27947
startDocumentSplit(void *ctx)
27948
0
{
27949
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27950
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27951
0
        (ctxt->user_sax->startDocument != NULL))
27952
0
  ctxt->user_sax->startDocument(ctxt->user_data);
27953
0
}
27954
27955
static void
27956
endDocumentSplit(void *ctx)
27957
0
{
27958
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27959
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27960
0
        (ctxt->user_sax->endDocument != NULL))
27961
0
  ctxt->user_sax->endDocument(ctxt->user_data);
27962
0
}
27963
27964
static void
27965
processingInstructionSplit(void *ctx, const xmlChar *target,
27966
                      const xmlChar *data)
27967
0
{
27968
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27969
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27970
0
        (ctxt->user_sax->processingInstruction != NULL))
27971
0
  ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
27972
0
}
27973
27974
static void
27975
commentSplit(void *ctx, const xmlChar *value)
27976
0
{
27977
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27978
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27979
0
        (ctxt->user_sax->comment != NULL))
27980
0
  ctxt->user_sax->comment(ctxt->user_data, value);
27981
0
}
27982
27983
/*
27984
 * Varargs error callbacks to the user application, harder ...
27985
 */
27986
27987
static void
27988
0
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
27989
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27990
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27991
0
        (ctxt->user_sax->warning != NULL)) {
27992
  /* TODO */
27993
0
    }
27994
0
}
27995
static void
27996
0
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
27997
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
27998
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
27999
0
        (ctxt->user_sax->error != NULL)) {
28000
  /* TODO */
28001
0
    }
28002
0
}
28003
static void
28004
0
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28005
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28006
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28007
0
        (ctxt->user_sax->fatalError != NULL)) {
28008
  /* TODO */
28009
0
    }
28010
0
}
28011
28012
/*
28013
 * Those are function where both the user handler and the schemas handler
28014
 * need to be called.
28015
 */
28016
static void
28017
charactersSplit(void *ctx, const xmlChar *ch, int len)
28018
0
{
28019
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28020
0
    if (ctxt == NULL)
28021
0
        return;
28022
0
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28023
0
  ctxt->user_sax->characters(ctxt->user_data, ch, len);
28024
0
    if (ctxt->ctxt != NULL)
28025
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28026
0
}
28027
28028
static void
28029
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28030
0
{
28031
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28032
0
    if (ctxt == NULL)
28033
0
        return;
28034
0
    if ((ctxt->user_sax != NULL) &&
28035
0
        (ctxt->user_sax->ignorableWhitespace != NULL))
28036
0
  ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28037
0
    if (ctxt->ctxt != NULL)
28038
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28039
0
}
28040
28041
static void
28042
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28043
0
{
28044
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28045
0
    if (ctxt == NULL)
28046
0
        return;
28047
0
    if ((ctxt->user_sax != NULL) &&
28048
0
        (ctxt->user_sax->cdataBlock != NULL))
28049
0
  ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28050
0
    if (ctxt->ctxt != NULL)
28051
0
  xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28052
0
}
28053
28054
static void
28055
referenceSplit(void *ctx, const xmlChar *name)
28056
0
{
28057
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28058
0
    if (ctxt == NULL)
28059
0
        return;
28060
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28061
0
        (ctxt->user_sax->reference != NULL))
28062
0
  ctxt->user_sax->reference(ctxt->user_data, name);
28063
0
    if (ctxt->ctxt != NULL)
28064
0
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
28065
0
}
28066
28067
static void
28068
startElementNsSplit(void *ctx, const xmlChar * localname,
28069
        const xmlChar * prefix, const xmlChar * URI,
28070
        int nb_namespaces, const xmlChar ** namespaces,
28071
        int nb_attributes, int nb_defaulted,
28072
0
        const xmlChar ** attributes) {
28073
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28074
0
    if (ctxt == NULL)
28075
0
        return;
28076
0
    if ((ctxt->user_sax != NULL) &&
28077
0
        (ctxt->user_sax->startElementNs != NULL))
28078
0
  ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28079
0
                                 URI, nb_namespaces, namespaces,
28080
0
               nb_attributes, nb_defaulted,
28081
0
               attributes);
28082
0
    if (ctxt->ctxt != NULL)
28083
0
  xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28084
0
                                   URI, nb_namespaces, namespaces,
28085
0
           nb_attributes, nb_defaulted,
28086
0
           attributes);
28087
0
}
28088
28089
static void
28090
endElementNsSplit(void *ctx, const xmlChar * localname,
28091
0
        const xmlChar * prefix, const xmlChar * URI) {
28092
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28093
0
    if (ctxt == NULL)
28094
0
        return;
28095
0
    if ((ctxt->user_sax != NULL) &&
28096
0
        (ctxt->user_sax->endElementNs != NULL))
28097
0
  ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28098
0
    if (ctxt->ctxt != NULL)
28099
0
  xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28100
0
}
28101
28102
/**
28103
 * Plug a SAX based validation layer in a SAX parsing event flow.
28104
 * The original `saxptr` and `dataptr` data are replaced by new pointers
28105
 * but the calls to the original will be maintained.
28106
 *
28107
 * @param ctxt  a schema validation context
28108
 * @param sax  a pointer to the original xmlSAXHandler
28109
 * @param user_data  a pointer to the original SAX user data pointer
28110
 * @returns a pointer to a data structure needed to unplug the validation layer
28111
 *         or NULL in case of errors.
28112
 */
28113
xmlSchemaSAXPlugStruct *
28114
xmlSchemaSAXPlug(xmlSchemaValidCtxt *ctxt,
28115
     xmlSAXHandler **sax, void **user_data)
28116
0
{
28117
0
    xmlSchemaSAXPlugPtr ret;
28118
0
    xmlSAXHandlerPtr old_sax;
28119
28120
0
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28121
0
        return(NULL);
28122
28123
    /*
28124
     * We only allow to plug into SAX2 event streams
28125
     */
28126
0
    old_sax = *sax;
28127
0
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28128
0
        return(NULL);
28129
0
    if ((old_sax != NULL) &&
28130
0
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28131
0
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28132
0
        return(NULL);
28133
28134
    /*
28135
     * everything seems right allocate the local data needed for that layer
28136
     */
28137
0
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28138
0
    if (ret == NULL) {
28139
0
        return(NULL);
28140
0
    }
28141
0
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28142
0
    ret->magic = XML_SAX_PLUG_MAGIC;
28143
0
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28144
0
    ret->ctxt = ctxt;
28145
0
    ret->user_sax_ptr = sax;
28146
0
    ret->user_sax = old_sax;
28147
0
    if (old_sax == NULL) {
28148
        /*
28149
   * go direct, no need for the split block and functions.
28150
   */
28151
0
  ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28152
0
  ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28153
  /*
28154
   * Note that we use the same text-function for both, to prevent
28155
   * the parser from testing for ignorable whitespace.
28156
   */
28157
0
  ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28158
0
  ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28159
28160
0
  ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28161
0
  ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28162
28163
0
  ret->user_data = ctxt;
28164
0
  *user_data = ctxt;
28165
0
    } else {
28166
       /*
28167
        * for each callback unused by Schemas initialize it to the Split
28168
  * routine only if non NULL in the user block, this can speed up
28169
  * things at the SAX level.
28170
  */
28171
0
        if (old_sax->internalSubset != NULL)
28172
0
            ret->schemas_sax.internalSubset = internalSubsetSplit;
28173
0
        if (old_sax->isStandalone != NULL)
28174
0
            ret->schemas_sax.isStandalone = isStandaloneSplit;
28175
0
        if (old_sax->hasInternalSubset != NULL)
28176
0
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28177
0
        if (old_sax->hasExternalSubset != NULL)
28178
0
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28179
0
        if (old_sax->resolveEntity != NULL)
28180
0
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
28181
0
        if (old_sax->getEntity != NULL)
28182
0
            ret->schemas_sax.getEntity = getEntitySplit;
28183
0
        if (old_sax->entityDecl != NULL)
28184
0
            ret->schemas_sax.entityDecl = entityDeclSplit;
28185
0
        if (old_sax->notationDecl != NULL)
28186
0
            ret->schemas_sax.notationDecl = notationDeclSplit;
28187
0
        if (old_sax->attributeDecl != NULL)
28188
0
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
28189
0
        if (old_sax->elementDecl != NULL)
28190
0
            ret->schemas_sax.elementDecl = elementDeclSplit;
28191
0
        if (old_sax->unparsedEntityDecl != NULL)
28192
0
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28193
0
        if (old_sax->setDocumentLocator != NULL)
28194
0
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28195
0
        if (old_sax->startDocument != NULL)
28196
0
            ret->schemas_sax.startDocument = startDocumentSplit;
28197
0
        if (old_sax->endDocument != NULL)
28198
0
            ret->schemas_sax.endDocument = endDocumentSplit;
28199
0
        if (old_sax->processingInstruction != NULL)
28200
0
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
28201
0
        if (old_sax->comment != NULL)
28202
0
            ret->schemas_sax.comment = commentSplit;
28203
0
        if (old_sax->warning != NULL)
28204
0
            ret->schemas_sax.warning = warningSplit;
28205
0
        if (old_sax->error != NULL)
28206
0
            ret->schemas_sax.error = errorSplit;
28207
0
        if (old_sax->fatalError != NULL)
28208
0
            ret->schemas_sax.fatalError = fatalErrorSplit;
28209
0
        if (old_sax->getParameterEntity != NULL)
28210
0
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28211
0
        if (old_sax->externalSubset != NULL)
28212
0
            ret->schemas_sax.externalSubset = externalSubsetSplit;
28213
28214
  /*
28215
   * the 6 schemas callback have to go to the splitter functions
28216
   * Note that we use the same text-function for ignorableWhitespace
28217
   * if possible, to prevent the parser from testing for ignorable
28218
   * whitespace.
28219
   */
28220
0
        ret->schemas_sax.characters = charactersSplit;
28221
0
  if ((old_sax->ignorableWhitespace != NULL) &&
28222
0
      (old_sax->ignorableWhitespace != old_sax->characters))
28223
0
      ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28224
0
  else
28225
0
      ret->schemas_sax.ignorableWhitespace = charactersSplit;
28226
0
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
28227
0
        ret->schemas_sax.reference = referenceSplit;
28228
0
        ret->schemas_sax.startElementNs = startElementNsSplit;
28229
0
        ret->schemas_sax.endElementNs = endElementNsSplit;
28230
28231
0
  ret->user_data_ptr = user_data;
28232
0
  ret->user_data = *user_data;
28233
0
  *user_data = ret;
28234
0
    }
28235
28236
    /*
28237
     * plug the pointers back.
28238
     */
28239
0
    *sax = &(ret->schemas_sax);
28240
0
    ctxt->sax = *sax;
28241
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28242
0
    xmlSchemaPreRun(ctxt);
28243
0
    return(ret);
28244
0
}
28245
28246
/**
28247
 * Unplug a SAX based validation layer in a SAX parsing event flow.
28248
 * The original pointers used in the call are restored.
28249
 *
28250
 * @param plug  a data structure returned by xmlSchemaSAXPlug
28251
 * @returns 0 in case of success and -1 in case of failure.
28252
 */
28253
int
28254
xmlSchemaSAXUnplug(xmlSchemaSAXPlugStruct *plug)
28255
0
{
28256
0
    xmlSAXHandlerPtr *sax;
28257
0
    void **user_data;
28258
28259
0
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28260
0
        return(-1);
28261
0
    plug->magic = 0;
28262
28263
0
    xmlSchemaPostRun(plug->ctxt);
28264
    /* restore the data */
28265
0
    sax = plug->user_sax_ptr;
28266
0
    *sax = plug->user_sax;
28267
0
    if (plug->user_sax != NULL) {
28268
0
  user_data = plug->user_data_ptr;
28269
0
  *user_data = plug->user_data;
28270
0
    }
28271
28272
    /* free and return */
28273
0
    xmlFree(plug);
28274
0
    return(0);
28275
0
}
28276
28277
/**
28278
 * Allows to set a locator function to the validation context,
28279
 * which will be used to provide file and line information since
28280
 * those are not provided as part of the SAX validation flow
28281
 * Setting `f` to NULL disable the locator.
28282
 *
28283
 * @param vctxt  a schema validation context
28284
 * @param f  the locator function pointer
28285
 * @param ctxt  the locator context
28286
 */
28287
28288
void
28289
xmlSchemaValidateSetLocator(xmlSchemaValidCtxt *vctxt,
28290
                            xmlSchemaValidityLocatorFunc f,
28291
          void *ctxt)
28292
0
{
28293
0
    if (vctxt == NULL) return;
28294
0
    vctxt->locFunc = f;
28295
0
    vctxt->locCtxt = ctxt;
28296
0
}
28297
28298
/**
28299
 * Internal locator function for the readers
28300
 *
28301
 * @param ctx  the xmlTextReader used
28302
 * @param file  returned file information
28303
 * @param line  returned line information
28304
 * @returns 0 in case the Schema validation could be (de)activated and
28305
 *         -1 in case of error.
28306
 */
28307
static int
28308
xmlSchemaValidateStreamLocator(void *ctx, const char **file,
28309
0
                               unsigned long *line) {
28310
0
    xmlParserCtxtPtr ctxt;
28311
28312
0
    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
28313
0
        return(-1);
28314
28315
0
    if (file != NULL)
28316
0
        *file = NULL;
28317
0
    if (line != NULL)
28318
0
        *line = 0;
28319
28320
0
    ctxt = (xmlParserCtxtPtr) ctx;
28321
0
    if (ctxt->input != NULL) {
28322
0
       if (file != NULL)
28323
0
           *file = ctxt->input->filename;
28324
0
       if (line != NULL)
28325
0
           *line = ctxt->input->line;
28326
0
       return(0);
28327
0
    }
28328
0
    return(-1);
28329
0
}
28330
28331
/**
28332
 * @param ctxt  a schema validation context
28333
 * @param pctxt  a parser context
28334
 * @returns 0 if the document is schemas valid, a positive error code
28335
 *     number otherwise and -1 in case of internal or API error.
28336
 */
28337
static int
28338
xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
28339
0
                                 xmlParserCtxtPtr pctxt) {
28340
0
    xmlSchemaSAXPlugPtr plug = NULL;
28341
0
    int ret;
28342
28343
0
    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
28344
28345
0
    ctxt->parserCtxt = pctxt;
28346
0
    ctxt->input = pctxt->input->buf;
28347
28348
    /*
28349
     * Plug the validation and launch the parsing
28350
     */
28351
0
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28352
0
    if (plug == NULL) {
28353
0
        ret = -1;
28354
0
  goto done;
28355
0
    }
28356
0
    ctxt->input = pctxt->input->buf;
28357
0
    ctxt->sax = pctxt->sax;
28358
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28359
0
    ret = xmlSchemaVStart(ctxt);
28360
28361
0
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28362
0
  ret = ctxt->parserCtxt->errNo;
28363
0
  if (ret == 0)
28364
0
      ret = 1;
28365
0
    }
28366
28367
0
done:
28368
0
    ctxt->parserCtxt = NULL;
28369
0
    ctxt->sax = NULL;
28370
0
    ctxt->input = NULL;
28371
0
    if (plug != NULL) {
28372
0
        xmlSchemaSAXUnplug(plug);
28373
0
    }
28374
0
    return (ret);
28375
0
}
28376
28377
/**
28378
 * Validate an input based on a flow of SAX event from the parser
28379
 * and forward the events to the `sax` handler with the provided `user_data`
28380
 * the user provided `sax` handler must be a SAX2 one.
28381
 *
28382
 * @param ctxt  a schema validation context
28383
 * @param input  the input to use for reading the data
28384
 * @param enc  an optional encoding information
28385
 * @param sax  a SAX handler for the resulting events
28386
 * @param user_data  the context to provide to the SAX handler.
28387
 * @returns 0 if the document is schemas valid, a positive error code
28388
 *     number otherwise and -1 in case of internal or API error.
28389
 */
28390
int
28391
xmlSchemaValidateStream(xmlSchemaValidCtxt *ctxt,
28392
                        xmlParserInputBuffer *input, xmlCharEncoding enc,
28393
                        const xmlSAXHandler *sax, void *user_data)
28394
0
{
28395
0
    xmlParserCtxtPtr pctxt = NULL;
28396
0
    xmlParserInputPtr inputStream = NULL;
28397
0
    int ret;
28398
28399
0
    if ((ctxt == NULL) || (input == NULL))
28400
0
        return (-1);
28401
28402
    /*
28403
     * prepare the parser
28404
     */
28405
0
    if (sax != NULL) {
28406
0
        pctxt = xmlNewSAXParserCtxt(sax, user_data);
28407
0
        if (pctxt == NULL)
28408
0
            return (-1);
28409
0
    } else {
28410
0
        pctxt = xmlNewParserCtxt();
28411
0
        if (pctxt == NULL)
28412
0
            return (-1);
28413
        /* We really want pctxt->sax to be NULL here. */
28414
0
        xmlFree(pctxt->sax);
28415
0
        pctxt->sax = NULL;
28416
0
    }
28417
#if 0
28418
    if (options)
28419
        xmlCtxtUseOptions(pctxt, options);
28420
#endif
28421
28422
0
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28423
0
    if (inputStream == NULL) {
28424
0
        ret = -1;
28425
0
  goto done;
28426
0
    }
28427
0
    if (xmlCtxtPushInput(pctxt, inputStream) < 0) {
28428
0
        xmlFreeInputStream(inputStream);
28429
0
        ret = -1;
28430
0
        goto done;
28431
0
    }
28432
28433
0
    ctxt->enc = enc;
28434
28435
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28436
28437
0
done:
28438
    /* cleanup */
28439
0
    if (pctxt != NULL) {
28440
0
  xmlFreeParserCtxt(pctxt);
28441
0
    }
28442
0
    return (ret);
28443
0
}
28444
28445
/**
28446
 * Do a schemas validation of the given resource, it will use the
28447
 * SAX streamable validation internally.
28448
 *
28449
 * @param ctxt  a schema validation context
28450
 * @param filename  the URI of the instance
28451
 * @param options  a future set of options, currently unused
28452
 * @returns 0 if the document is valid, a positive error code
28453
 *     number otherwise and -1 in case of an internal or API error.
28454
 */
28455
int
28456
xmlSchemaValidateFile(xmlSchemaValidCtxt *ctxt,
28457
                      const char * filename,
28458
          int options ATTRIBUTE_UNUSED)
28459
0
{
28460
0
    int ret;
28461
0
    xmlParserCtxtPtr pctxt = NULL;
28462
28463
0
    if ((ctxt == NULL) || (filename == NULL))
28464
0
        return (-1);
28465
28466
0
    pctxt = xmlCreateURLParserCtxt(filename, 0);
28467
0
    if (pctxt == NULL)
28468
0
  return (-1);
28469
    /* We really want pctxt->sax to be NULL here. */
28470
0
    xmlFree(pctxt->sax);
28471
0
    pctxt->sax = NULL;
28472
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28473
0
    xmlFreeParserCtxt(pctxt);
28474
0
    return (ret);
28475
0
}
28476
28477
/**
28478
 * allow access to the parser context of the schema validation context
28479
 *
28480
 * @param ctxt  a schema validation context
28481
 * @returns the parser context of the schema validation context or NULL
28482
 *         in case of error.
28483
 */
28484
xmlParserCtxt *
28485
xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxt *ctxt)
28486
0
{
28487
0
    if (ctxt == NULL)
28488
0
        return(NULL);
28489
0
    return (ctxt->parserCtxt);
28490
0
}
28491
28492
#endif /* LIBXML_SCHEMAS_ENABLED */