Coverage Report

Created: 2024-02-11 06:24

/src/libxml2/xmlschemas.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * schemas.c : implementation of the XML Schema handling and
3
 *             schema validity checking
4
 *
5
 * See Copyright for the status of this software.
6
 *
7
 * Daniel Veillard <veillard@redhat.com>
8
 */
9
10
/*
11
 * TODO:
12
 *   - when types are redefined in includes, check that all
13
 *     types in the redef list are equal
14
 *     -> need a type equality operation.
15
 *   - if we don't intend to use the schema for schemas, we
16
 *     need to validate all schema attributes (ref, type, name)
17
 *     against their types.
18
 *   - Eliminate item creation for: ??
19
 *
20
 * URGENT TODO:
21
 *   - For xsi-driven schema acquisition, augment the IDCs after every
22
 *     acquisition episode (xmlSchemaAugmentIDC).
23
 *
24
 * NOTES:
25
 *   - Eliminated item creation for: <restriction>, <extension>,
26
 *     <simpleContent>, <complexContent>, <list>, <union>
27
 *
28
 * PROBLEMS:
29
 *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
30
 *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
31
 *     XPath will have trouble to resolve to this namespace, since not known.
32
 *
33
 *
34
 * CONSTRAINTS:
35
 *
36
 * Schema Component Constraint:
37
 *   All Group Limited (cos-all-limited)
38
 *   Status: complete
39
 *   (1.2)
40
 *     In xmlSchemaGroupDefReferenceTermFixup() and
41
 *   (2)
42
 *     In xmlSchemaParseModelGroup()
43
 *     TODO: Actually this should go to component-level checks,
44
 *     but is done here due to performance. Move it to an other layer
45
 *     is schema construction via an API is implemented.
46
 */
47
48
/* To avoid EBCDIC trouble when parsing on zOS */
49
#if defined(__MVS__)
50
#pragma convert("ISO8859-1")
51
#endif
52
53
#define IN_LIBXML
54
#include "libxml.h"
55
56
#ifdef LIBXML_SCHEMAS_ENABLED
57
58
#include <string.h>
59
#include <libxml/xmlmemory.h>
60
#include <libxml/parser.h>
61
#include <libxml/parserInternals.h>
62
#include <libxml/hash.h>
63
#include <libxml/uri.h>
64
#include <libxml/xmlschemas.h>
65
#include <libxml/schemasInternals.h>
66
#include <libxml/xmlschemastypes.h>
67
#include <libxml/xmlautomata.h>
68
#include <libxml/xmlregexp.h>
69
#include <libxml/dict.h>
70
#include <libxml/encoding.h>
71
#include <libxml/xmlIO.h>
72
#ifdef LIBXML_PATTERN_ENABLED
73
#include <libxml/pattern.h>
74
#endif
75
#ifdef LIBXML_READER_ENABLED
76
#include <libxml/xmlreader.h>
77
#endif
78
79
#include "private/error.h"
80
#include "private/string.h"
81
82
/* #define WXS_ELEM_DECL_CONS_ENABLED */
83
84
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
85
86
#define ENABLE_REDEFINE
87
88
/* #define ENABLE_NAMED_LOCALS */
89
90
/* #define ENABLE_IDC_NODE_TABLES_TEST */
91
92
#define DUMP_CONTENT_MODEL
93
94
#ifdef LIBXML_READER_ENABLED
95
/* #define XML_SCHEMA_READER_ENABLED */
96
#endif
97
98
45.9k
#define UNBOUNDED (1 << 30)
99
100
11.5k
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
101
102
/*
103
 * The XML Schemas namespaces
104
 */
105
static const xmlChar *xmlSchemaNs = (const xmlChar *)
106
    "http://www.w3.org/2001/XMLSchema";
107
108
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
109
    "http://www.w3.org/2001/XMLSchema-instance";
110
111
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
112
    "http://www.w3.org/2000/xmlns/";
113
114
/*
115
* Come casting macros.
116
*/
117
396k
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
118
1.06k
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
119
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
120
120k
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
121
24
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
122
70.6k
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
123
25.7k
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
124
3.21k
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
125
2.34k
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
126
4.17k
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
127
41.9k
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
128
316
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
129
258
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
130
4.10k
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
131
29
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
132
6.55k
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
133
384
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
134
135
/*
136
* Macros to query common properties of components.
137
*/
138
3.35k
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
139
140
2.52k
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
141
/*
142
* Macros for element declarations.
143
*/
144
13.1k
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
145
146
7.52k
#define WXS_SUBST_HEAD(item) (item)->refDecl
147
/*
148
* Macros for attribute declarations.
149
*/
150
4.56k
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
151
/*
152
* Macros for attribute uses.
153
*/
154
41.7k
#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
155
156
2.17k
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
157
158
33.6k
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
159
160
2.63k
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
161
/*
162
* Macros for attribute groups.
163
*/
164
310
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
165
330
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
166
/*
167
* Macros for particles.
168
*/
169
45.0k
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
170
171
45.0k
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
172
173
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
174
175
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
176
/*
177
* Macros for model groups definitions.
178
*/
179
173
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
180
/*
181
* Macros for model groups.
182
*/
183
#define WXS_IS_MODEL_GROUP(i) \
184
49
    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
185
49
     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
186
49
     ((i)->type == XML_SCHEMA_TYPE_ALL))
187
188
3.92k
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
189
/*
190
* Macros for schema buckets.
191
*/
192
25.1k
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
193
25.1k
    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
194
195
44.3k
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
196
44.3k
    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
197
198
25.8k
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
199
200
156
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
201
/*
202
* Macros for complex/simple types.
203
*/
204
#define WXS_IS_ANYTYPE(i) \
205
375
     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
206
375
      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
207
208
#define WXS_IS_COMPLEX(i) \
209
16.1k
    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
210
12.6k
     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
211
212
#define WXS_IS_SIMPLE(item) \
213
34.6k
    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
214
34.6k
     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
215
20.7k
      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
216
217
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
218
303k
    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
219
303k
      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
220
221
#define WXS_IS_RESTRICTION(t) \
222
3.00k
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
223
224
#define WXS_IS_EXTENSION(t) \
225
3.40k
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
226
227
#define WXS_IS_TYPE_NOT_FIXED(i) \
228
35.7k
    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
229
35.7k
     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
230
231
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
232
25.8k
    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
233
25.8k
     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
234
235
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
236
237
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
238
/*
239
* Macros for exclusively for complex types.
240
*/
241
#define WXS_HAS_COMPLEX_CONTENT(item) \
242
    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
243
     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
244
     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
245
246
#define WXS_HAS_SIMPLE_CONTENT(item) \
247
4.58k
    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
248
4.58k
     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
249
250
#define WXS_HAS_MIXED_CONTENT(item) \
251
31
    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
252
253
#define WXS_EMPTIABLE(t) \
254
11
    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
255
256
3.88k
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
257
258
622
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
259
260
1.99k
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
261
/*
262
* Macros for exclusively for simple types.
263
*/
264
6.33k
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
265
266
392k
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
267
268
179k
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
269
270
61.8k
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
271
/*
272
* Misc parser context macros.
273
*/
274
315k
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
275
276
17.3k
#define WXS_HAS_BUCKETS(ctx) \
277
17.3k
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
278
17.3k
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
279
280
93
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
281
282
173k
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
283
284
#define WXS_SCHEMA(ctx) (ctx)->schema
285
286
#define WXS_ADD_LOCAL(ctx, item) \
287
119k
    do { \
288
119k
        if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) < 0) { \
289
0
            xmlFree(item); \
290
0
            item = NULL; \
291
0
        } \
292
119k
    } while (0)
293
294
#define WXS_ADD_GLOBAL(ctx, item) \
295
46.6k
    do { \
296
46.6k
        if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) < 0) { \
297
0
            xmlFree(item); \
298
0
            item = NULL; \
299
0
        } \
300
46.6k
    } while (0)
301
302
#define WXS_ADD_PENDING(ctx, item) \
303
79.5k
    xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
304
/*
305
* xmlSchemaItemList macros.
306
*/
307
0
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
308
/*
309
* Misc macros.
310
*/
311
#define IS_SCHEMA(node, type) \
312
3.03M
   ((node != NULL) && (node->ns != NULL) && \
313
3.03M
    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
314
3.03M
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
315
316
2.47M
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
317
318
/*
319
* Since we put the default/fixed values into the dict, we can
320
* use pointer comparison for those values.
321
* REMOVED: (xmlStrEqual((v1), (v2)))
322
*/
323
0
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
324
325
0
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
326
327
219
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
328
329
184k
#define HFAILURE if (res == -1) goto exit_failure;
330
331
39.5k
#define HERROR if (res != 0) goto exit_error;
332
333
4.72k
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
334
/*
335
* Some flags used for various schema constraints.
336
*/
337
22
#define SUBSET_RESTRICTION  1<<0
338
3
#define SUBSET_EXTENSION    1<<1
339
#define SUBSET_SUBSTITUTION 1<<2
340
#define SUBSET_LIST         1<<3
341
#define SUBSET_UNION        1<<4
342
343
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
344
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
345
346
typedef struct _xmlSchemaItemList xmlSchemaItemList;
347
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
348
struct _xmlSchemaItemList {
349
    void **items;  /* used for dynamic addition of schemata */
350
    int nbItems; /* used for dynamic addition of schemata */
351
    int sizeItems; /* used for dynamic addition of schemata */
352
};
353
354
432k
#define XML_SCHEMA_CTXT_PARSER 1
355
407k
#define XML_SCHEMA_CTXT_VALIDATOR 2
356
357
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
358
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
359
struct _xmlSchemaAbstractCtxt {
360
    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
361
    void *dummy; /* Fix alignment issues */
362
};
363
364
typedef struct _xmlSchemaBucket xmlSchemaBucket;
365
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
366
367
152k
#define XML_SCHEMA_SCHEMA_MAIN 0
368
28.8k
#define XML_SCHEMA_SCHEMA_IMPORT 1
369
25.4k
#define XML_SCHEMA_SCHEMA_INCLUDE 2
370
25.1k
#define XML_SCHEMA_SCHEMA_REDEFINE 3
371
372
/**
373
 * xmlSchemaSchemaRelation:
374
 *
375
 * Used to create a graph of schema relationships.
376
 */
377
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
378
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
379
struct _xmlSchemaSchemaRelation {
380
    xmlSchemaSchemaRelationPtr next;
381
    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
382
    const xmlChar *importNamespace;
383
    xmlSchemaBucketPtr bucket;
384
};
385
386
0
#define XML_SCHEMA_BUCKET_MARKED 1<<0
387
16.0k
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
388
389
struct _xmlSchemaBucket {
390
    int type;
391
    int flags;
392
    const xmlChar *schemaLocation;
393
    const xmlChar *origTargetNamespace;
394
    const xmlChar *targetNamespace;
395
    xmlDocPtr doc;
396
    xmlSchemaSchemaRelationPtr relations;
397
    int located;
398
    int parsed;
399
    int imported;
400
    int preserveDoc;
401
    xmlSchemaItemListPtr globals; /* Global components. */
402
    xmlSchemaItemListPtr locals; /* Local components. */
403
};
404
405
/**
406
 * xmlSchemaImport:
407
 * (extends xmlSchemaBucket)
408
 *
409
 * Reflects a schema. Holds some information
410
 * about the schema and its toplevel components. Duplicate
411
 * toplevel components are not checked at this level.
412
 */
413
typedef struct _xmlSchemaImport xmlSchemaImport;
414
typedef xmlSchemaImport *xmlSchemaImportPtr;
415
struct _xmlSchemaImport {
416
    int type; /* Main OR import OR include. */
417
    int flags;
418
    const xmlChar *schemaLocation; /* The URI of the schema document. */
419
    /* For chameleon includes, @origTargetNamespace will be NULL */
420
    const xmlChar *origTargetNamespace;
421
    /*
422
    * For chameleon includes, @targetNamespace will be the
423
    * targetNamespace of the including schema.
424
    */
425
    const xmlChar *targetNamespace;
426
    xmlDocPtr doc; /* The schema node-tree. */
427
    /* @relations will hold any included/imported/redefined schemas. */
428
    xmlSchemaSchemaRelationPtr relations;
429
    int located;
430
    int parsed;
431
    int imported;
432
    int preserveDoc;
433
    xmlSchemaItemListPtr globals;
434
    xmlSchemaItemListPtr locals;
435
    /* The imported schema. */
436
    xmlSchemaPtr schema;
437
};
438
439
/*
440
* (extends xmlSchemaBucket)
441
*/
442
typedef struct _xmlSchemaInclude xmlSchemaInclude;
443
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
444
struct _xmlSchemaInclude {
445
    int type;
446
    int flags;
447
    const xmlChar *schemaLocation;
448
    const xmlChar *origTargetNamespace;
449
    const xmlChar *targetNamespace;
450
    xmlDocPtr doc;
451
    xmlSchemaSchemaRelationPtr relations;
452
    int located;
453
    int parsed;
454
    int imported;
455
    int preserveDoc;
456
    xmlSchemaItemListPtr globals; /* Global components. */
457
    xmlSchemaItemListPtr locals; /* Local components. */
458
459
    /* The owning main or import schema bucket. */
460
    xmlSchemaImportPtr ownerImport;
461
};
462
463
/**
464
 * xmlSchemaBasicItem:
465
 *
466
 * The abstract base type for schema components.
467
 */
468
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
469
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
470
struct _xmlSchemaBasicItem {
471
    xmlSchemaTypeType type;
472
    void *dummy; /* Fix alignment issues */
473
};
474
475
/**
476
 * xmlSchemaAnnotItem:
477
 *
478
 * The abstract base type for annotated schema components.
479
 * (Extends xmlSchemaBasicItem)
480
 */
481
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
482
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
483
struct _xmlSchemaAnnotItem {
484
    xmlSchemaTypeType type;
485
    xmlSchemaAnnotPtr annot;
486
};
487
488
/**
489
 * xmlSchemaTreeItem:
490
 *
491
 * The abstract base type for tree-like structured schema components.
492
 * (Extends xmlSchemaAnnotItem)
493
 */
494
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
495
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
496
struct _xmlSchemaTreeItem {
497
    xmlSchemaTypeType type;
498
    xmlSchemaAnnotPtr annot;
499
    xmlSchemaTreeItemPtr next;
500
    xmlSchemaTreeItemPtr children;
501
};
502
503
504
998
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
505
/**
506
 * xmlSchemaAttributeUsePtr:
507
 *
508
 * The abstract base type for tree-like structured schema components.
509
 * (Extends xmlSchemaTreeItem)
510
 */
511
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
512
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
513
struct _xmlSchemaAttributeUse {
514
    xmlSchemaTypeType type;
515
    xmlSchemaAnnotPtr annot;
516
    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
517
    /*
518
    * The attr. decl. OR a QName-ref. to an attr. decl. OR
519
    * a QName-ref. to an attribute group definition.
520
    */
521
    xmlSchemaAttributePtr attrDecl;
522
523
    int flags;
524
    xmlNodePtr node;
525
    int occurs; /* required, optional */
526
    const xmlChar * defValue;
527
    xmlSchemaValPtr defVal;
528
};
529
530
/**
531
 * xmlSchemaAttributeUseProhibPtr:
532
 *
533
 * A helper component to reflect attribute prohibitions.
534
 * (Extends xmlSchemaBasicItem)
535
 */
536
typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
537
typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
538
struct _xmlSchemaAttributeUseProhib {
539
    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
540
    xmlNodePtr node;
541
    const xmlChar *name;
542
    const xmlChar *targetNamespace;
543
    int isRef;
544
};
545
546
/**
547
 * xmlSchemaRedef:
548
 */
549
typedef struct _xmlSchemaRedef xmlSchemaRedef;
550
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
551
struct _xmlSchemaRedef {
552
    xmlSchemaRedefPtr next;
553
    xmlSchemaBasicItemPtr item; /* The redefining component. */
554
    xmlSchemaBasicItemPtr reference; /* The referencing component. */
555
    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
556
    const xmlChar *refName; /* The name of the to-be-redefined component. */
557
    const xmlChar *refTargetNs; /* The target namespace of the
558
                                   to-be-redefined comp. */
559
    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
560
};
561
562
/**
563
 * xmlSchemaConstructionCtxt:
564
 */
565
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
566
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
567
struct _xmlSchemaConstructionCtxt {
568
    xmlSchemaPtr mainSchema; /* The main schema. */
569
    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
570
    xmlDictPtr dict;
571
    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
572
    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
573
    xmlSchemaBucketPtr bucket; /* The current schema bucket */
574
    xmlSchemaItemListPtr pending; /* All Components of all schemas that
575
                                     need to be fixed. */
576
    xmlHashTablePtr substGroups;
577
    xmlSchemaRedefPtr redefs;
578
    xmlSchemaRedefPtr lastRedef;
579
};
580
581
#define XML_SCHEMAS_PARSE_ERROR   1
582
29.4k
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
583
584
struct _xmlSchemaParserCtxt {
585
    int type;
586
    void *errCtxt;             /* user specific error context */
587
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
588
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
589
    int err;
590
    int nberrors;
591
    xmlStructuredErrorFunc serror;
592
593
    xmlSchemaConstructionCtxtPtr constructor;
594
    int ownsConstructor; /* TODO: Move this to parser *flags*. */
595
596
    /* xmlSchemaPtr topschema;  */
597
    /* xmlHashTablePtr namespaces;  */
598
599
    xmlSchemaPtr schema;        /* The main schema in use */
600
    int counter;
601
602
    const xmlChar *URL;
603
    xmlDocPtr doc;
604
    int preserve;   /* Whether the doc should be freed  */
605
606
    const char *buffer;
607
    int size;
608
609
    /*
610
     * Used to build complex element content models
611
     */
612
    xmlAutomataPtr am;
613
    xmlAutomataStatePtr start;
614
    xmlAutomataStatePtr end;
615
    xmlAutomataStatePtr state;
616
617
    xmlDictPtr dict;    /* dictionary for interned string names */
618
    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
619
    int options;
620
    xmlSchemaValidCtxtPtr vctxt;
621
    int isS4S;
622
    int isRedefine;
623
    int xsiAssemble;
624
    int stop; /* If the parser should stop; i.e. a critical error. */
625
    const xmlChar *targetNamespace;
626
    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
627
628
    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
629
    int redefCounter; /* Used for redefinitions. */
630
    xmlSchemaItemListPtr attrProhibs;
631
};
632
633
/**
634
 * xmlSchemaQNameRef:
635
 *
636
 * A component reference item (not a schema component)
637
 * (Extends xmlSchemaBasicItem)
638
 */
639
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
640
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
641
struct _xmlSchemaQNameRef {
642
    xmlSchemaTypeType type;
643
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
644
    xmlSchemaTypeType itemType;
645
    const xmlChar *name;
646
    const xmlChar *targetNamespace;
647
    xmlNodePtr node;
648
};
649
650
/**
651
 * xmlSchemaParticle:
652
 *
653
 * A particle component.
654
 * (Extends xmlSchemaTreeItem)
655
 */
656
typedef struct _xmlSchemaParticle xmlSchemaParticle;
657
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
658
struct _xmlSchemaParticle {
659
    xmlSchemaTypeType type;
660
    xmlSchemaAnnotPtr annot;
661
    xmlSchemaTreeItemPtr next; /* next particle */
662
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
663
  a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
664
        etc.) */
665
    int minOccurs;
666
    int maxOccurs;
667
    xmlNodePtr node;
668
};
669
670
/**
671
 * xmlSchemaModelGroup:
672
 *
673
 * A model group component.
674
 * (Extends xmlSchemaTreeItem)
675
 */
676
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
677
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
678
struct _xmlSchemaModelGroup {
679
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
680
    xmlSchemaAnnotPtr annot;
681
    xmlSchemaTreeItemPtr next; /* not used */
682
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
683
    xmlNodePtr node;
684
};
685
686
0
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
687
208
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
688
/**
689
 * xmlSchemaModelGroupDef:
690
 *
691
 * A model group definition component.
692
 * (Extends xmlSchemaTreeItem)
693
 */
694
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
695
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
696
struct _xmlSchemaModelGroupDef {
697
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
698
    xmlSchemaAnnotPtr annot;
699
    xmlSchemaTreeItemPtr next; /* not used */
700
    xmlSchemaTreeItemPtr children; /* the "model group" */
701
    const xmlChar *name;
702
    const xmlChar *targetNamespace;
703
    xmlNodePtr node;
704
    int flags;
705
};
706
707
typedef struct _xmlSchemaIDC xmlSchemaIDC;
708
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
709
710
/**
711
 * xmlSchemaIDCSelect:
712
 *
713
 * The identity-constraint "field" and "selector" item, holding the
714
 * XPath expression.
715
 */
716
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
717
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
718
struct _xmlSchemaIDCSelect {
719
    xmlSchemaIDCSelectPtr next;
720
    xmlSchemaIDCPtr idc;
721
    int index; /* an index position if significant for IDC key-sequences */
722
    const xmlChar *xpath; /* the XPath expression */
723
    void *xpathComp; /* the compiled XPath expression */
724
};
725
726
/**
727
 * xmlSchemaIDC:
728
 *
729
 * The identity-constraint definition component.
730
 * (Extends xmlSchemaAnnotItem)
731
 */
732
733
struct _xmlSchemaIDC {
734
    xmlSchemaTypeType type;
735
    xmlSchemaAnnotPtr annot;
736
    xmlSchemaIDCPtr next;
737
    xmlNodePtr node;
738
    const xmlChar *name;
739
    const xmlChar *targetNamespace;
740
    xmlSchemaIDCSelectPtr selector;
741
    xmlSchemaIDCSelectPtr fields;
742
    int nbFields;
743
    xmlSchemaQNameRefPtr ref;
744
};
745
746
/**
747
 * xmlSchemaIDCAug:
748
 *
749
 * The augmented IDC information used for validation.
750
 */
751
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
752
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
753
struct _xmlSchemaIDCAug {
754
    xmlSchemaIDCAugPtr next; /* next in a list */
755
    xmlSchemaIDCPtr def; /* the IDC definition */
756
    int keyrefDepth; /* the lowest tree level to which IDC
757
                        tables need to be bubbled upwards */
758
};
759
760
/**
761
 * xmlSchemaPSVIIDCKeySequence:
762
 *
763
 * The key sequence of a node table item.
764
 */
765
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
766
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
767
struct _xmlSchemaPSVIIDCKey {
768
    xmlSchemaTypePtr type;
769
    xmlSchemaValPtr val;
770
};
771
772
/**
773
 * xmlSchemaPSVIIDCNode:
774
 *
775
 * The node table item of a node table.
776
 */
777
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
778
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
779
struct _xmlSchemaPSVIIDCNode {
780
    xmlNodePtr node;
781
    xmlSchemaPSVIIDCKeyPtr *keys;
782
    int nodeLine;
783
    int nodeQNameID;
784
785
};
786
787
/**
788
 * xmlSchemaPSVIIDCBinding:
789
 *
790
 * The identity-constraint binding item of the [identity-constraint table].
791
 */
792
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
793
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
794
struct _xmlSchemaPSVIIDCBinding {
795
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
796
    xmlSchemaIDCPtr definition; /* the IDC definition */
797
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
798
    int nbNodes; /* number of entries in the node table */
799
    int sizeNodes; /* size of the node table */
800
    xmlSchemaItemListPtr dupls;
801
};
802
803
804
0
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
805
0
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
806
807
#define XPATH_STATE_OBJ_MATCHES -2
808
#define XPATH_STATE_OBJ_BLOCKED -3
809
810
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
811
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
812
813
/**
814
 * xmlSchemaIDCStateObj:
815
 *
816
 * The state object used to evaluate XPath expressions.
817
 */
818
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
819
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
820
struct _xmlSchemaIDCStateObj {
821
    int type;
822
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
823
    int depth; /* depth of creation */
824
    int *history; /* list of (depth, state-id) tuples */
825
    int nbHistory;
826
    int sizeHistory;
827
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
828
                                       matcher */
829
    xmlSchemaIDCSelectPtr sel;
830
    void *xpathCtxt;
831
};
832
833
0
#define IDC_MATCHER 0
834
835
/**
836
 * xmlSchemaIDCMatcher:
837
 *
838
 * Used to evaluate IDC selectors (and fields).
839
 */
840
struct _xmlSchemaIDCMatcher {
841
    int type;
842
    int depth; /* the tree depth at creation time */
843
    xmlSchemaIDCMatcherPtr next; /* next in the list */
844
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
845
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
846
    int idcType;
847
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
848
                                         elements */
849
    int sizeKeySeqs;
850
    xmlSchemaItemListPtr targets; /* list of target-node
851
                                     (xmlSchemaPSVIIDCNodePtr) entries */
852
    xmlHashTablePtr htab;
853
};
854
855
/*
856
* Element info flags.
857
*/
858
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
859
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
860
0
#define XML_SCHEMA_ELEM_INFO_NILLED        1<<2
861
0
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        1<<3
862
863
0
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
864
0
#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
865
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
866
867
0
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
868
0
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
869
0
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
870
0
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
871
872
/**
873
 * xmlSchemaNodeInfo:
874
 *
875
 * Holds information of an element node.
876
 */
877
struct _xmlSchemaNodeInfo {
878
    int nodeType;
879
    xmlNodePtr node;
880
    int nodeLine;
881
    const xmlChar *localName;
882
    const xmlChar *nsName;
883
    const xmlChar *value;
884
    xmlSchemaValPtr val; /* the pre-computed value if any */
885
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
886
887
    int flags; /* combination of node info flags */
888
889
    int valNeeded;
890
    int normVal;
891
892
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
893
    int depth;
894
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
895
                                            for the scope element*/
896
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
897
                                           element */
898
    xmlRegExecCtxtPtr regexCtxt;
899
900
    const xmlChar **nsBindings; /* Namespace bindings on this element */
901
    int nbNsBindings;
902
    int sizeNsBindings;
903
904
    int hasKeyrefs;
905
    int appliedXPath; /* Indicates that an XPath has been applied. */
906
};
907
908
0
#define XML_SCHEMAS_ATTR_UNKNOWN 1
909
0
#define XML_SCHEMAS_ATTR_ASSESSED 2
910
#define XML_SCHEMAS_ATTR_PROHIBITED 3
911
0
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
912
0
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
913
0
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
914
0
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
915
0
#define XML_SCHEMAS_ATTR_DEFAULT 8
916
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
917
0
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
918
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
919
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
920
0
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
921
0
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
922
0
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
923
0
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
924
0
#define XML_SCHEMAS_ATTR_META 17
925
/*
926
* @metaType values of xmlSchemaAttrInfo.
927
*/
928
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
929
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
930
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
931
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
932
0
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
933
934
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
935
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
936
struct _xmlSchemaAttrInfo {
937
    int nodeType;
938
    xmlNodePtr node;
939
    int nodeLine;
940
    const xmlChar *localName;
941
    const xmlChar *nsName;
942
    const xmlChar *value;
943
    xmlSchemaValPtr val; /* the pre-computed value if any */
944
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
945
    int flags; /* combination of node info flags */
946
947
    xmlSchemaAttributePtr decl; /* the attribute declaration */
948
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
949
    int state;
950
    int metaType;
951
    const xmlChar *vcValue; /* the value constraint value */
952
    xmlSchemaNodeInfoPtr parent;
953
};
954
955
956
0
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
957
/**
958
 * xmlSchemaValidCtxt:
959
 *
960
 * A Schemas validation context
961
 */
962
struct _xmlSchemaValidCtxt {
963
    int type;
964
    void *errCtxt;             /* user specific data block */
965
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
966
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
967
    xmlStructuredErrorFunc serror;
968
969
    xmlSchemaPtr schema;        /* The schema in use */
970
    xmlDocPtr doc;
971
    xmlParserInputBufferPtr input;
972
    xmlCharEncoding enc;
973
    xmlSAXHandlerPtr sax;
974
    xmlParserCtxtPtr parserCtxt;
975
    void *user_data; /* TODO: What is this for? */
976
    char *filename;
977
978
    int err;
979
    int nberrors;
980
981
    xmlNodePtr node;
982
    xmlNodePtr cur;
983
    /* xmlSchemaTypePtr type; */
984
985
    xmlRegExecCtxtPtr regexp;
986
    xmlSchemaValPtr value;
987
988
    int valueWS;
989
    int options;
990
    xmlNodePtr validationRoot;
991
    xmlSchemaParserCtxtPtr pctxt;
992
    int xsiAssemble;
993
994
    int depth;
995
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
996
    int sizeElemInfos;
997
    xmlSchemaNodeInfoPtr inode; /* the current element information */
998
999
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1000
1001
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1002
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1003
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1004
1005
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1006
    int nbIdcNodes;
1007
    int sizeIdcNodes;
1008
1009
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1010
    int nbIdcKeys;
1011
    int sizeIdcKeys;
1012
1013
    int flags;
1014
1015
    xmlDictPtr dict;
1016
1017
#ifdef LIBXML_READER_ENABLED
1018
    xmlTextReaderPtr reader;
1019
#endif
1020
1021
    xmlSchemaAttrInfoPtr *attrInfos;
1022
    int nbAttrInfos;
1023
    int sizeAttrInfos;
1024
1025
    int skipDepth;
1026
    xmlSchemaItemListPtr nodeQNames;
1027
    int hasKeyrefs;
1028
    int createIDCNodeTables;
1029
    int psviExposeIDCNodeTables;
1030
1031
    /* Locator for error reporting in streaming mode */
1032
    xmlSchemaValidityLocatorFunc locFunc;
1033
    void *locCtxt;
1034
};
1035
1036
/**
1037
 * xmlSchemaSubstGroup:
1038
 *
1039
 *
1040
 */
1041
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1042
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1043
struct _xmlSchemaSubstGroup {
1044
    xmlSchemaElementPtr head;
1045
    xmlSchemaItemListPtr members;
1046
};
1047
1048
/**
1049
 * xmlIDCHashEntry:
1050
 *
1051
 * an entry in hash tables to quickly look up keys/uniques
1052
 */
1053
typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1054
typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1055
struct _xmlIDCHashEntry {
1056
    xmlIDCHashEntryPtr next; /* next item with same hash */
1057
    int index;               /* index into associated item list */
1058
};
1059
1060
/************************************************************************
1061
 *                  *
1062
 *      Some predeclarations        *
1063
 *                  *
1064
 ************************************************************************/
1065
1066
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1067
                                 xmlSchemaPtr schema,
1068
                                 xmlNodePtr node);
1069
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1070
                                 xmlSchemaPtr schema,
1071
                                 xmlNodePtr node);
1072
static int
1073
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1074
                   xmlSchemaAbstractCtxtPtr ctxt);
1075
static const xmlChar *
1076
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1077
static int
1078
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1079
                     xmlNodePtr node);
1080
static int
1081
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1082
                       xmlSchemaParserCtxtPtr ctxt);
1083
static void
1084
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1085
static xmlSchemaWhitespaceValueType
1086
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1087
static xmlSchemaTreeItemPtr
1088
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1089
       xmlNodePtr node, xmlSchemaTypeType type,
1090
       int withParticle);
1091
static const xmlChar *
1092
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1093
static xmlSchemaTypeLinkPtr
1094
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1095
static void
1096
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1097
         const char *funcName,
1098
         const char *message) LIBXML_ATTR_FORMAT(3,0);
1099
static int
1100
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1101
           xmlSchemaTypePtr type,
1102
           xmlSchemaTypePtr baseType,
1103
           int subset);
1104
static void
1105
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1106
           xmlSchemaParserCtxtPtr ctxt);
1107
static void
1108
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1109
static xmlSchemaQNameRefPtr
1110
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1111
        xmlSchemaPtr schema,
1112
        xmlNodePtr node);
1113
1114
/************************************************************************
1115
 *                  *
1116
 *      Helper functions              *
1117
 *                  *
1118
 ************************************************************************/
1119
1120
/**
1121
 * xmlSchemaItemTypeToStr:
1122
 * @type: the type of the schema item
1123
 *
1124
 * Returns the component name of a schema item.
1125
 */
1126
static const xmlChar *
1127
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1128
9.15k
{
1129
9.15k
    switch (type) {
1130
0
  case XML_SCHEMA_TYPE_BASIC:
1131
0
      return(BAD_CAST "simple type definition");
1132
6.24k
  case XML_SCHEMA_TYPE_SIMPLE:
1133
6.24k
      return(BAD_CAST "simple type definition");
1134
768
  case XML_SCHEMA_TYPE_COMPLEX:
1135
768
      return(BAD_CAST "complex type definition");
1136
351
  case XML_SCHEMA_TYPE_ELEMENT:
1137
351
      return(BAD_CAST "element declaration");
1138
1.10k
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1139
1.10k
      return(BAD_CAST "attribute use");
1140
84
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1141
84
      return(BAD_CAST "attribute declaration");
1142
73
  case XML_SCHEMA_TYPE_GROUP:
1143
73
      return(BAD_CAST "model group definition");
1144
521
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1145
521
      return(BAD_CAST "attribute group definition");
1146
0
  case XML_SCHEMA_TYPE_NOTATION:
1147
0
      return(BAD_CAST "notation declaration");
1148
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1149
0
      return(BAD_CAST "model group (sequence)");
1150
0
  case XML_SCHEMA_TYPE_CHOICE:
1151
0
      return(BAD_CAST "model group (choice)");
1152
0
  case XML_SCHEMA_TYPE_ALL:
1153
0
      return(BAD_CAST "model group (all)");
1154
0
  case XML_SCHEMA_TYPE_PARTICLE:
1155
0
      return(BAD_CAST "particle");
1156
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1157
0
      return(BAD_CAST "unique identity-constraint");
1158
      /* return(BAD_CAST "IDC (unique)"); */
1159
1
  case XML_SCHEMA_TYPE_IDC_KEY:
1160
1
      return(BAD_CAST "key identity-constraint");
1161
      /* return(BAD_CAST "IDC (key)"); */
1162
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1163
0
      return(BAD_CAST "keyref identity-constraint");
1164
      /* return(BAD_CAST "IDC (keyref)"); */
1165
0
  case XML_SCHEMA_TYPE_ANY:
1166
0
      return(BAD_CAST "wildcard (any)");
1167
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1168
0
      return(BAD_CAST "[helper component] QName reference");
1169
0
  case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1170
0
      return(BAD_CAST "[helper component] attribute use prohibition");
1171
0
  default:
1172
0
      return(BAD_CAST "Not a schema component");
1173
9.15k
    }
1174
9.15k
}
1175
1176
/**
1177
 * xmlSchemaGetComponentTypeStr:
1178
 * @type: the type of the schema item
1179
 *
1180
 * Returns the component name of a schema item.
1181
 */
1182
static const xmlChar *
1183
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1184
2.52k
{
1185
2.52k
    switch (item->type) {
1186
2
  case XML_SCHEMA_TYPE_BASIC:
1187
2
      if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1188
0
    return(BAD_CAST "complex type definition");
1189
2
      else
1190
2
    return(BAD_CAST "simple type definition");
1191
2.51k
  default:
1192
2.51k
      return(xmlSchemaItemTypeToStr(item->type));
1193
2.52k
    }
1194
2.52k
}
1195
1196
/**
1197
 * xmlSchemaGetComponentNode:
1198
 * @item: a schema component
1199
 *
1200
 * Returns node associated with the schema component.
1201
 * NOTE that such a node need not be available; plus, a component's
1202
 * node need not to reflect the component directly, since there is no
1203
 * one-to-one relationship between the XML Schema representation and
1204
 * the component representation.
1205
 */
1206
static xmlNodePtr
1207
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1208
3.35k
{
1209
3.35k
    switch (item->type) {
1210
201
  case XML_SCHEMA_TYPE_ELEMENT:
1211
201
      return (((xmlSchemaElementPtr) item)->node);
1212
127
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1213
127
      return (((xmlSchemaAttributePtr) item)->node);
1214
1.89k
  case XML_SCHEMA_TYPE_COMPLEX:
1215
2.23k
  case XML_SCHEMA_TYPE_SIMPLE:
1216
2.23k
      return (((xmlSchemaTypePtr) item)->node);
1217
0
  case XML_SCHEMA_TYPE_ANY:
1218
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1219
0
      return (((xmlSchemaWildcardPtr) item)->node);
1220
171
  case XML_SCHEMA_TYPE_PARTICLE:
1221
171
      return (((xmlSchemaParticlePtr) item)->node);
1222
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1223
0
  case XML_SCHEMA_TYPE_CHOICE:
1224
0
  case XML_SCHEMA_TYPE_ALL:
1225
0
      return (((xmlSchemaModelGroupPtr) item)->node);
1226
37
  case XML_SCHEMA_TYPE_GROUP:
1227
37
      return (((xmlSchemaModelGroupDefPtr) item)->node);
1228
46
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1229
46
      return (((xmlSchemaAttributeGroupPtr) item)->node);
1230
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1231
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1232
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1233
0
      return (((xmlSchemaIDCPtr) item)->node);
1234
7
  case XML_SCHEMA_EXTRA_QNAMEREF:
1235
7
      return(((xmlSchemaQNameRefPtr) item)->node);
1236
  /* TODO: What to do with NOTATIONs?
1237
  case XML_SCHEMA_TYPE_NOTATION:
1238
      return (((xmlSchemaNotationPtr) item)->node);
1239
  */
1240
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1241
0
      return (((xmlSchemaAttributeUsePtr) item)->node);
1242
534
  default:
1243
534
      return (NULL);
1244
3.35k
    }
1245
3.35k
}
1246
1247
#if 0
1248
/**
1249
 * xmlSchemaGetNextComponent:
1250
 * @item: a schema component
1251
 *
1252
 * Returns the next sibling of the schema component.
1253
 */
1254
static xmlSchemaBasicItemPtr
1255
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1256
{
1257
    switch (item->type) {
1258
  case XML_SCHEMA_TYPE_ELEMENT:
1259
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1260
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1261
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1262
  case XML_SCHEMA_TYPE_COMPLEX:
1263
  case XML_SCHEMA_TYPE_SIMPLE:
1264
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1265
  case XML_SCHEMA_TYPE_ANY:
1266
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1267
      return (NULL);
1268
  case XML_SCHEMA_TYPE_PARTICLE:
1269
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1270
  case XML_SCHEMA_TYPE_SEQUENCE:
1271
  case XML_SCHEMA_TYPE_CHOICE:
1272
  case XML_SCHEMA_TYPE_ALL:
1273
      return (NULL);
1274
  case XML_SCHEMA_TYPE_GROUP:
1275
      return (NULL);
1276
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1277
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1278
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1279
  case XML_SCHEMA_TYPE_IDC_KEY:
1280
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1281
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1282
  default:
1283
      return (NULL);
1284
    }
1285
}
1286
#endif
1287
1288
1289
/**
1290
 * xmlSchemaFormatQName:
1291
 * @buf: the string buffer
1292
 * @namespaceName:  the namespace name
1293
 * @localName: the local name
1294
 *
1295
 * Returns the given QName in the format "{namespaceName}localName" or
1296
 * just "localName" if @namespaceName is NULL.
1297
 *
1298
 * Returns the localName if @namespaceName is NULL, a formatted
1299
 * string otherwise.
1300
 */
1301
static const xmlChar*
1302
xmlSchemaFormatQName(xmlChar **buf,
1303
         const xmlChar *namespaceName,
1304
         const xmlChar *localName)
1305
714k
{
1306
714k
    FREE_AND_NULL(*buf)
1307
714k
    if (namespaceName != NULL) {
1308
550k
  *buf = xmlStrdup(BAD_CAST "{");
1309
550k
  *buf = xmlStrcat(*buf, namespaceName);
1310
550k
  *buf = xmlStrcat(*buf, BAD_CAST "}");
1311
550k
    }
1312
714k
    if (localName != NULL) {
1313
702k
  if (namespaceName == NULL)
1314
151k
      return(localName);
1315
550k
  *buf = xmlStrcat(*buf, localName);
1316
550k
    } else {
1317
12.4k
  *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1318
12.4k
    }
1319
562k
    return ((const xmlChar *) *buf);
1320
714k
}
1321
1322
static const xmlChar*
1323
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1324
28.3k
{
1325
28.3k
    if (ns != NULL)
1326
3.31k
  return (xmlSchemaFormatQName(buf, ns->href, localName));
1327
25.0k
    else
1328
25.0k
  return (xmlSchemaFormatQName(buf, NULL, localName));
1329
28.3k
}
1330
1331
static const xmlChar *
1332
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1333
3.75k
{
1334
3.75k
    if (item == NULL) {
1335
0
        return (NULL);
1336
0
    }
1337
3.75k
    switch (item->type) {
1338
214
  case XML_SCHEMA_TYPE_ELEMENT:
1339
214
      return (((xmlSchemaElementPtr) item)->name);
1340
1.25k
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1341
1.25k
      return (((xmlSchemaAttributePtr) item)->name);
1342
45
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1343
45
      return (((xmlSchemaAttributeGroupPtr) item)->name);
1344
4
  case XML_SCHEMA_TYPE_BASIC:
1345
341
  case XML_SCHEMA_TYPE_SIMPLE:
1346
1.09k
  case XML_SCHEMA_TYPE_COMPLEX:
1347
1.09k
      return (((xmlSchemaTypePtr) item)->name);
1348
37
  case XML_SCHEMA_TYPE_GROUP:
1349
37
      return (((xmlSchemaModelGroupDefPtr) item)->name);
1350
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1351
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1352
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1353
0
      return (((xmlSchemaIDCPtr) item)->name);
1354
1.10k
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1355
1.10k
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1356
1.10k
    return(xmlSchemaGetComponentName(
1357
1.10k
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1358
1.10k
      } else
1359
0
    return(NULL);
1360
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1361
0
      return (((xmlSchemaQNameRefPtr) item)->name);
1362
0
  case XML_SCHEMA_TYPE_NOTATION:
1363
0
      return (((xmlSchemaNotationPtr) item)->name);
1364
0
  default:
1365
      /*
1366
      * Other components cannot have names.
1367
      */
1368
0
      break;
1369
3.75k
    }
1370
0
    return (NULL);
1371
3.75k
}
1372
1373
0
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1374
0
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1375
/*
1376
static const xmlChar *
1377
xmlSchemaGetQNameRefName(void *ref)
1378
{
1379
    return(((xmlSchemaQNameRefPtr) ref)->name);
1380
}
1381
1382
static const xmlChar *
1383
xmlSchemaGetQNameRefTargetNs(void *ref)
1384
{
1385
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1386
}
1387
*/
1388
1389
static const xmlChar *
1390
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1391
3.75k
{
1392
3.75k
    if (item == NULL) {
1393
0
        return (NULL);
1394
0
    }
1395
3.75k
    switch (item->type) {
1396
214
  case XML_SCHEMA_TYPE_ELEMENT:
1397
214
      return (((xmlSchemaElementPtr) item)->targetNamespace);
1398
1.25k
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1399
1.25k
      return (((xmlSchemaAttributePtr) item)->targetNamespace);
1400
45
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1401
45
      return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1402
4
  case XML_SCHEMA_TYPE_BASIC:
1403
4
      return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1404
337
  case XML_SCHEMA_TYPE_SIMPLE:
1405
1.09k
  case XML_SCHEMA_TYPE_COMPLEX:
1406
1.09k
      return (((xmlSchemaTypePtr) item)->targetNamespace);
1407
37
  case XML_SCHEMA_TYPE_GROUP:
1408
37
      return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1409
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1410
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1411
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1412
0
      return (((xmlSchemaIDCPtr) item)->targetNamespace);
1413
1.10k
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1414
1.10k
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1415
1.10k
    return(xmlSchemaGetComponentTargetNs(
1416
1.10k
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1417
1.10k
      }
1418
      /* TODO: Will returning NULL break something? */
1419
0
      break;
1420
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1421
0
      return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1422
0
  case XML_SCHEMA_TYPE_NOTATION:
1423
0
      return (((xmlSchemaNotationPtr) item)->targetNamespace);
1424
0
  default:
1425
      /*
1426
      * Other components cannot have names.
1427
      */
1428
0
      break;
1429
3.75k
    }
1430
0
    return (NULL);
1431
3.75k
}
1432
1433
static const xmlChar*
1434
xmlSchemaGetComponentQName(xmlChar **buf,
1435
         void *item)
1436
2.65k
{
1437
2.65k
    return (xmlSchemaFormatQName(buf,
1438
2.65k
  xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1439
2.65k
  xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1440
2.65k
}
1441
1442
static const xmlChar*
1443
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1444
1.21k
{
1445
1.21k
    xmlChar *str = NULL;
1446
1447
1.21k
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1448
1.21k
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1449
1.21k
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1450
1.21k
  (xmlSchemaBasicItemPtr) item));
1451
1.21k
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1452
1.21k
    FREE_AND_NULL(str);
1453
1.21k
    return(*buf);
1454
1.21k
}
1455
1456
static const xmlChar*
1457
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1458
0
{
1459
0
    return(xmlSchemaGetComponentDesignation(buf, idc));
1460
0
}
1461
1462
/**
1463
 * xmlSchemaWildcardPCToString:
1464
 * @pc: the type of processContents
1465
 *
1466
 * Returns a string representation of the type of
1467
 * processContents.
1468
 */
1469
static const xmlChar *
1470
xmlSchemaWildcardPCToString(int pc)
1471
0
{
1472
0
    switch (pc) {
1473
0
  case XML_SCHEMAS_ANY_SKIP:
1474
0
      return (BAD_CAST "skip");
1475
0
  case XML_SCHEMAS_ANY_LAX:
1476
0
      return (BAD_CAST "lax");
1477
0
  case XML_SCHEMAS_ANY_STRICT:
1478
0
      return (BAD_CAST "strict");
1479
0
  default:
1480
0
      return (BAD_CAST "invalid process contents");
1481
0
    }
1482
0
}
1483
1484
/**
1485
 * xmlSchemaGetCanonValueWhtspExt:
1486
 * @val: the precomputed value
1487
 * @retValue: the returned value
1488
 * @ws: the whitespace type of the value
1489
 * @for_hash: non-zero if this is supposed to generate a string for hashing
1490
 *
1491
 * Get a the canonical representation of the value.
1492
 * The caller has to free the returned retValue.
1493
 *
1494
 * Returns 0 if the value could be built and -1 in case of
1495
 *         API errors or if the value type is not supported yet.
1496
 */
1497
static int
1498
xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1499
               xmlSchemaWhitespaceValueType ws,
1500
               xmlChar **retValue,
1501
         int for_hash)
1502
6.94k
{
1503
6.94k
    int list;
1504
6.94k
    xmlSchemaValType valType;
1505
6.94k
    const xmlChar *value, *value2 = NULL;
1506
1507
1508
6.94k
    if ((retValue == NULL) || (val == NULL))
1509
7
  return (-1);
1510
6.93k
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1511
6.93k
    *retValue = NULL;
1512
6.93k
    do {
1513
6.93k
  value = NULL;
1514
6.93k
  valType = xmlSchemaGetValType(val);
1515
6.93k
  switch (valType) {
1516
307
      case XML_SCHEMAS_STRING:
1517
307
      case XML_SCHEMAS_NORMSTRING:
1518
307
      case XML_SCHEMAS_ANYSIMPLETYPE:
1519
307
    value = xmlSchemaValueGetAsString(val);
1520
307
    if (value != NULL) {
1521
307
        if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1522
0
      value2 = xmlSchemaCollapseString(value);
1523
307
        else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1524
0
      value2 = xmlSchemaWhiteSpaceReplace(value);
1525
307
        if (value2 != NULL)
1526
0
      value = value2;
1527
307
    }
1528
307
    break;
1529
6.62k
      default:
1530
6.62k
    if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1531
0
        if (value2 != NULL)
1532
0
      xmlFree((xmlChar *) value2);
1533
0
        goto internal_error;
1534
0
    }
1535
6.62k
    if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1536
        /* We can mostly use the canonical value for hashing,
1537
           except in the case of decimal.  There the canonical
1538
           representation requires a trailing '.0' even for
1539
           non-fractional numbers, but for the derived integer
1540
           types it forbids any decimal point.  Nevertheless they
1541
           compare equal if the value is equal.  We need to generate
1542
           the same hash value for this to work, and it's easiest
1543
           to just cut off the useless '.0' suffix for the
1544
           decimal type.  */
1545
0
        int len = xmlStrlen(value2);
1546
0
        if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1547
0
          ((xmlChar*)value2)[len-2] = 0;
1548
0
    }
1549
6.62k
    value = value2;
1550
6.93k
  }
1551
6.93k
  if (*retValue == NULL)
1552
6.93k
      if (value == NULL) {
1553
0
    if (! list)
1554
0
        *retValue = xmlStrdup(BAD_CAST "");
1555
0
      } else
1556
6.93k
    *retValue = xmlStrdup(value);
1557
0
  else if (value != NULL) {
1558
      /* List. */
1559
0
      *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1560
0
      *retValue = xmlStrcat((xmlChar *) *retValue, value);
1561
0
  }
1562
6.93k
  FREE_AND_NULL(value2)
1563
6.93k
  val = xmlSchemaValueGetNext(val);
1564
6.93k
    } while (val != NULL);
1565
1566
6.93k
    return (0);
1567
0
internal_error:
1568
0
    if (*retValue != NULL)
1569
0
  xmlFree((xmlChar *) (*retValue));
1570
0
    if (value2 != NULL)
1571
0
  xmlFree((xmlChar *) value2);
1572
0
    return (-1);
1573
6.93k
}
1574
1575
static int
1576
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1577
             xmlSchemaWhitespaceValueType ws,
1578
             xmlChar **retValue)
1579
6.94k
{
1580
6.94k
    return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1581
6.94k
}
1582
1583
static int
1584
xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1585
         xmlChar **retValue)
1586
0
{
1587
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1588
0
              retValue, 1);
1589
0
}
1590
1591
/**
1592
 * xmlSchemaFormatItemForReport:
1593
 * @buf: the string buffer
1594
 * @itemDes: the designation of the item
1595
 * @itemName: the name of the item
1596
 * @item: the item as an object
1597
 * @itemNode: the node of the item
1598
 * @local: the local name
1599
 * @parsing: if the function is used during the parse
1600
 *
1601
 * Returns a representation of the given item used
1602
 * for error reports.
1603
 *
1604
 * The following order is used to build the resulting
1605
 * designation if the arguments are not NULL:
1606
 * 1a. If itemDes not NULL -> itemDes
1607
 * 1b. If (itemDes not NULL) and (itemName not NULL)
1608
 *     -> itemDes + itemName
1609
 * 2. If the preceding was NULL and (item not NULL) -> item
1610
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1611
 *
1612
 * If the itemNode is an attribute node, the name of the attribute
1613
 * will be appended to the result.
1614
 *
1615
 * Returns the formatted string and sets @buf to the resulting value.
1616
 */
1617
static xmlChar*
1618
xmlSchemaFormatItemForReport(xmlChar **buf,
1619
         const xmlChar *itemDes,
1620
         xmlSchemaBasicItemPtr item,
1621
         xmlNodePtr itemNode)
1622
136k
{
1623
136k
    xmlChar *str = NULL;
1624
136k
    int named = 1;
1625
1626
136k
    if (*buf != NULL) {
1627
0
  xmlFree(*buf);
1628
0
  *buf = NULL;
1629
0
    }
1630
1631
136k
    if (itemDes != NULL) {
1632
0
  *buf = xmlStrdup(itemDes);
1633
136k
    } else if (item != NULL) {
1634
9.42k
  switch (item->type) {
1635
305
  case XML_SCHEMA_TYPE_BASIC: {
1636
305
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1637
1638
305
      if (WXS_IS_ATOMIC(type))
1639
305
    *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1640
0
      else if (WXS_IS_LIST(type))
1641
0
    *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1642
0
      else if (WXS_IS_UNION(type))
1643
0
    *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1644
0
      else
1645
0
    *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1646
305
      *buf = xmlStrcat(*buf, type->name);
1647
305
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1648
305
      }
1649
305
      break;
1650
6.33k
  case XML_SCHEMA_TYPE_SIMPLE: {
1651
6.33k
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1652
1653
6.33k
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1654
516
    *buf = xmlStrdup(BAD_CAST"");
1655
5.81k
      } else {
1656
5.81k
    *buf = xmlStrdup(BAD_CAST "local ");
1657
5.81k
      }
1658
6.33k
      if (WXS_IS_ATOMIC(type))
1659
305
    *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1660
6.02k
      else if (WXS_IS_LIST(type))
1661
201
    *buf = xmlStrcat(*buf, BAD_CAST "list type");
1662
5.82k
      else if (WXS_IS_UNION(type))
1663
5.61k
    *buf = xmlStrcat(*buf, BAD_CAST "union type");
1664
216
      else
1665
216
    *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1666
6.33k
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1667
516
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1668
516
    *buf = xmlStrcat(*buf, type->name);
1669
516
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1670
516
      }
1671
6.33k
      }
1672
6.33k
      break;
1673
1.33k
  case XML_SCHEMA_TYPE_COMPLEX: {
1674
1.33k
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1675
1676
1.33k
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1677
1.08k
    *buf = xmlStrdup(BAD_CAST "");
1678
248
      else
1679
248
    *buf = xmlStrdup(BAD_CAST "local ");
1680
1.33k
      *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1681
1.33k
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1682
1.08k
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1683
1.08k
    *buf = xmlStrcat(*buf, type->name);
1684
1.08k
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1685
1.08k
      }
1686
1.33k
      }
1687
1.33k
      break;
1688
146
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1689
146
    xmlSchemaAttributeUsePtr ause;
1690
1691
146
    ause = WXS_ATTR_USE_CAST item;
1692
146
    *buf = xmlStrdup(BAD_CAST "attribute use ");
1693
146
    if (WXS_ATTRUSE_DECL(ause) != NULL) {
1694
107
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1695
107
        *buf = xmlStrcat(*buf,
1696
107
      xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1697
107
        FREE_AND_NULL(str)
1698
107
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1699
107
    } else {
1700
39
        *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1701
39
    }
1702
146
      }
1703
146
      break;
1704
239
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
1705
239
    xmlSchemaAttributePtr attr;
1706
1707
239
    attr = (xmlSchemaAttributePtr) item;
1708
239
    *buf = xmlStrdup(BAD_CAST "attribute decl.");
1709
239
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1710
239
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1711
239
        attr->targetNamespace, attr->name));
1712
239
    FREE_AND_NULL(str)
1713
239
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1714
239
      }
1715
239
      break;
1716
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1717
0
      xmlSchemaGetComponentDesignation(buf, item);
1718
0
      break;
1719
259
  case XML_SCHEMA_TYPE_ELEMENT: {
1720
259
    xmlSchemaElementPtr elem;
1721
1722
259
    elem = (xmlSchemaElementPtr) item;
1723
259
    *buf = xmlStrdup(BAD_CAST "element decl.");
1724
259
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1725
259
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1726
259
        elem->targetNamespace, elem->name));
1727
259
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1728
259
      }
1729
259
      break;
1730
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1731
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1732
1
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1733
1
      if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1734
0
    *buf = xmlStrdup(BAD_CAST "unique '");
1735
1
      else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1736
0
    *buf = xmlStrdup(BAD_CAST "key '");
1737
1
      else
1738
1
    *buf = xmlStrdup(BAD_CAST "keyRef '");
1739
1
      *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1740
1
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1741
1
      break;
1742
0
  case XML_SCHEMA_TYPE_ANY:
1743
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1744
0
      *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1745
0
        ((xmlSchemaWildcardPtr) item)->processContents));
1746
0
      *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1747
0
      break;
1748
117
  case XML_SCHEMA_FACET_MININCLUSIVE:
1749
271
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
1750
459
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
1751
586
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1752
588
  case XML_SCHEMA_FACET_TOTALDIGITS:
1753
606
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
1754
606
  case XML_SCHEMA_FACET_PATTERN:
1755
606
  case XML_SCHEMA_FACET_ENUMERATION:
1756
633
  case XML_SCHEMA_FACET_WHITESPACE:
1757
804
  case XML_SCHEMA_FACET_LENGTH:
1758
806
  case XML_SCHEMA_FACET_MAXLENGTH:
1759
810
  case XML_SCHEMA_FACET_MINLENGTH:
1760
810
      *buf = xmlStrdup(BAD_CAST "facet '");
1761
810
      *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1762
810
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1763
810
      break;
1764
0
  case XML_SCHEMA_TYPE_GROUP: {
1765
0
    *buf = xmlStrdup(BAD_CAST "model group def.");
1766
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1767
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1768
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1769
0
    FREE_AND_NULL(str)
1770
0
      }
1771
0
      break;
1772
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1773
0
  case XML_SCHEMA_TYPE_CHOICE:
1774
0
  case XML_SCHEMA_TYPE_ALL:
1775
0
  case XML_SCHEMA_TYPE_PARTICLE:
1776
0
      *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1777
0
      break;
1778
0
  case XML_SCHEMA_TYPE_NOTATION: {
1779
0
    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1780
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1781
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1782
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1783
0
    FREE_AND_NULL(str);
1784
0
      }
1785
            /* Falls through. */
1786
0
  default:
1787
0
      named = 0;
1788
9.42k
  }
1789
9.42k
    } else
1790
126k
  named = 0;
1791
1792
136k
    if ((named == 0) && (itemNode != NULL)) {
1793
126k
  xmlNodePtr elem;
1794
1795
126k
  if (itemNode->type == XML_ATTRIBUTE_NODE)
1796
19.5k
      elem = itemNode->parent;
1797
107k
  else
1798
107k
      elem = itemNode;
1799
126k
  *buf = xmlStrdup(BAD_CAST "Element '");
1800
126k
  if (elem->ns != NULL) {
1801
126k
      *buf = xmlStrcat(*buf,
1802
126k
    xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1803
126k
      FREE_AND_NULL(str)
1804
126k
  } else
1805
0
      *buf = xmlStrcat(*buf, elem->name);
1806
126k
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1807
1808
126k
    }
1809
136k
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1810
19.5k
  *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1811
19.5k
  if (itemNode->ns != NULL) {
1812
0
      *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1813
0
    itemNode->ns->href, itemNode->name));
1814
0
      FREE_AND_NULL(str)
1815
0
  } else
1816
19.5k
      *buf = xmlStrcat(*buf, itemNode->name);
1817
19.5k
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1818
19.5k
    }
1819
136k
    FREE_AND_NULL(str)
1820
1821
136k
    return (xmlEscapeFormatString(buf));
1822
136k
}
1823
1824
/**
1825
 * xmlSchemaFormatFacetEnumSet:
1826
 * @buf: the string buffer
1827
 * @type: the type holding the enumeration facets
1828
 *
1829
 * Builds a string consisting of all enumeration elements.
1830
 *
1831
 * Returns a string of all enumeration elements.
1832
 */
1833
static const xmlChar *
1834
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1835
          xmlChar **buf, xmlSchemaTypePtr type)
1836
6.43k
{
1837
6.43k
    xmlSchemaFacetPtr facet;
1838
6.43k
    xmlSchemaWhitespaceValueType ws;
1839
6.43k
    xmlChar *value = NULL;
1840
6.43k
    int res, found = 0;
1841
1842
6.43k
    if (*buf != NULL)
1843
0
  xmlFree(*buf);
1844
6.43k
    *buf = NULL;
1845
1846
6.46k
    do {
1847
  /*
1848
  * Use the whitespace type of the base type.
1849
  */
1850
6.46k
  ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1851
51.3k
  for (facet = type->facets; facet != NULL; facet = facet->next) {
1852
44.9k
      if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1853
37.9k
    continue;
1854
6.94k
      found = 1;
1855
6.94k
      res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1856
6.94k
    ws, &value);
1857
6.94k
      if (res == -1) {
1858
7
    xmlSchemaInternalErr(actxt,
1859
7
        "xmlSchemaFormatFacetEnumSet",
1860
7
        "compute the canonical lexical representation");
1861
7
    if (*buf != NULL)
1862
0
        xmlFree(*buf);
1863
7
    *buf = NULL;
1864
7
    return (NULL);
1865
7
      }
1866
6.93k
      if (*buf == NULL)
1867
6.42k
    *buf = xmlStrdup(BAD_CAST "'");
1868
506
      else
1869
506
    *buf = xmlStrcat(*buf, BAD_CAST ", '");
1870
6.93k
      *buf = xmlStrcat(*buf, BAD_CAST value);
1871
6.93k
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1872
6.93k
      if (value != NULL) {
1873
6.93k
    xmlFree((xmlChar *)value);
1874
6.93k
    value = NULL;
1875
6.93k
      }
1876
6.93k
  }
1877
  /*
1878
  * The enumeration facet of a type restricts the enumeration
1879
  * facet of the ancestor type; i.e., such restricted enumerations
1880
  * do not belong to the set of the given type. Thus we break
1881
  * on the first found enumeration.
1882
  */
1883
6.45k
  if (found)
1884
6.42k
      break;
1885
32
  type = type->baseType;
1886
32
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1887
1888
6.42k
    return ((const xmlChar *) *buf);
1889
6.43k
}
1890
1891
/************************************************************************
1892
 *                  *
1893
 *      Error functions               *
1894
 *                  *
1895
 ************************************************************************/
1896
1897
/**
1898
 * xmlSchemaPErrMemory:
1899
 * @node: a context node
1900
 * @extra:  extra information
1901
 *
1902
 * Handle an out of memory condition
1903
 */
1904
static void
1905
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt)
1906
0
{
1907
0
    xmlGenericErrorFunc channel = NULL;
1908
0
    xmlStructuredErrorFunc schannel = NULL;
1909
0
    void *data = NULL;
1910
1911
0
    if (ctxt != NULL) {
1912
0
        ctxt->nberrors++;
1913
0
        ctxt->err = XML_ERR_NO_MEMORY;
1914
0
        channel = ctxt->error;
1915
0
        schannel = ctxt->serror;
1916
0
        data = ctxt->errCtxt;
1917
0
    }
1918
1919
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASP, NULL);
1920
0
}
1921
1922
static void LIBXML_ATTR_FORMAT(11,12)
1923
xmlSchemaPErrFull(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1924
                  xmlErrorLevel level, const char *file, int line,
1925
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
1926
499k
                  int col, const char *msg, ...) {
1927
499k
    xmlGenericErrorFunc channel = NULL;
1928
499k
    xmlStructuredErrorFunc schannel = NULL;
1929
499k
    void *data = NULL;
1930
499k
    int res;
1931
499k
    va_list ap;
1932
1933
499k
    if (ctxt != NULL) {
1934
        /* Don't overwrite memory errors */
1935
499k
        if (ctxt->err == XML_ERR_NO_MEMORY)
1936
0
            return;
1937
1938
499k
        if (level == XML_ERR_WARNING) {
1939
111
            channel = ctxt->warning;
1940
499k
        } else {
1941
499k
            ctxt->nberrors++;
1942
499k
            ctxt->err = code;
1943
499k
            channel = ctxt->error;
1944
499k
        }
1945
499k
        data = ctxt->errCtxt;
1946
499k
        schannel = ctxt->serror;
1947
499k
    }
1948
1949
499k
    if ((channel == NULL) && (schannel == NULL)) {
1950
0
        channel = xmlGenericError;
1951
0
        data = xmlGenericErrorContext;
1952
0
    }
1953
1954
499k
    va_start(ap, msg);
1955
499k
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
1956
499k
                         XML_FROM_SCHEMASP, code, level, file, line,
1957
499k
                         (const char *) str1,
1958
499k
                         (const char *) str2,
1959
499k
                         (const char *) str3,
1960
499k
                         0, col, msg, ap);
1961
499k
    va_end(ap);
1962
1963
499k
    if (res < 0)
1964
0
        xmlSchemaPErrMemory(ctxt);
1965
499k
}
1966
1967
/**
1968
 * xmlSchemaPErr:
1969
 * @ctxt: the parsing context
1970
 * @node: the context node
1971
 * @error: the error code
1972
 * @msg: the error message
1973
 * @str1: extra data
1974
 * @str2: extra data
1975
 *
1976
 * Handle a parser error
1977
 */
1978
static void LIBXML_ATTR_FORMAT(4,0)
1979
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1980
              const char *msg, const xmlChar * str1, const xmlChar * str2)
1981
205k
{
1982
205k
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
1983
205k
                      str1, str2, NULL, 0, msg, str1, str2);
1984
205k
}
1985
1986
/**
1987
 * xmlSchemaPErr2:
1988
 * @ctxt: the parsing context
1989
 * @node: the context node
1990
 * @node: the current child
1991
 * @error: the error code
1992
 * @msg: the error message
1993
 * @str1: extra data
1994
 * @str2: extra data
1995
 *
1996
 * Handle a parser error
1997
 */
1998
static void LIBXML_ATTR_FORMAT(5,0)
1999
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
2000
               xmlNodePtr child, int error,
2001
               const char *msg, const xmlChar * str1, const xmlChar * str2)
2002
86.8k
{
2003
86.8k
    if (child != NULL)
2004
83.6k
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
2005
3.19k
    else
2006
3.19k
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
2007
86.8k
}
2008
2009
2010
/**
2011
 * xmlSchemaPErrExt:
2012
 * @ctxt: the parsing context
2013
 * @node: the context node
2014
 * @error: the error code
2015
 * @strData1: extra data
2016
 * @strData2: extra data
2017
 * @strData3: extra data
2018
 * @msg: the message
2019
 * @str1:  extra parameter for the message display
2020
 * @str2:  extra parameter for the message display
2021
 * @str3:  extra parameter for the message display
2022
 * @str4:  extra parameter for the message display
2023
 * @str5:  extra parameter for the message display
2024
 *
2025
 * Handle a parser error
2026
 */
2027
static void LIBXML_ATTR_FORMAT(7,0)
2028
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
2029
    const xmlChar * strData1, const xmlChar * strData2,
2030
    const xmlChar * strData3, const char *msg, const xmlChar * str1,
2031
    const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2032
    const xmlChar * str5)
2033
48.1k
{
2034
48.1k
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
2035
48.1k
                      strData1, strData2, strData3, 0,
2036
48.1k
                      msg, str1, str2, str3, str4, str5);
2037
48.1k
}
2038
2039
/************************************************************************
2040
 *                  *
2041
 *      Allround error functions      *
2042
 *                  *
2043
 ************************************************************************/
2044
2045
/**
2046
 * xmlSchemaVTypeErrMemory:
2047
 * @node: a context node
2048
 * @extra:  extra information
2049
 *
2050
 * Handle an out of memory condition
2051
 */
2052
static void
2053
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt)
2054
0
{
2055
0
    xmlGenericErrorFunc channel = NULL;
2056
0
    xmlStructuredErrorFunc schannel = NULL;
2057
0
    void *data = NULL;
2058
2059
0
    if (ctxt != NULL) {
2060
0
        ctxt->nberrors++;
2061
0
        ctxt->err = XML_ERR_NO_MEMORY;
2062
0
        channel = ctxt->error;
2063
0
        schannel = ctxt->serror;
2064
0
        data = ctxt->errCtxt;
2065
0
    }
2066
2067
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASV, NULL);
2068
0
}
2069
2070
static void LIBXML_ATTR_FORMAT(11,12)
2071
xmlSchemaVErrFull(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int code,
2072
                  xmlErrorLevel level, const char *file, int line,
2073
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
2074
0
                  int col, const char *msg, ...) {
2075
0
    xmlGenericErrorFunc channel = NULL;
2076
0
    xmlStructuredErrorFunc schannel = NULL;
2077
0
    void *data = NULL;
2078
0
    int res;
2079
0
    va_list ap;
2080
2081
0
    if (ctxt != NULL) {
2082
        /* Don't overwrite memory errors */
2083
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
2084
0
            return;
2085
2086
0
        if (level == XML_ERR_WARNING) {
2087
0
            channel = ctxt->warning;
2088
0
        } else {
2089
0
            ctxt->nberrors++;
2090
0
            ctxt->err = code;
2091
0
            channel = ctxt->error;
2092
0
        }
2093
0
        data = ctxt->errCtxt;
2094
0
        schannel = ctxt->serror;
2095
0
    }
2096
2097
0
    if ((channel == NULL) && (schannel == NULL)) {
2098
0
        channel = xmlGenericError;
2099
0
        data = xmlGenericErrorContext;
2100
0
    }
2101
2102
0
    va_start(ap, msg);
2103
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
2104
0
                         XML_FROM_SCHEMASV, code, level, file, line,
2105
0
                         (const char *) str1,
2106
0
                         (const char *) str2,
2107
0
                         (const char *) str3,
2108
0
                         0, col, msg, ap);
2109
0
    va_end(ap);
2110
2111
0
    if (res < 0)
2112
0
        xmlSchemaVErrMemory(ctxt);
2113
0
}
2114
2115
#define WXS_ERROR_TYPE_ERROR 1
2116
#define WXS_ERROR_TYPE_WARNING 2
2117
/**
2118
 * xmlSchemaErr4Line:
2119
 * @ctxt: the validation context
2120
 * @errorLevel: the error level
2121
 * @error: the error code
2122
 * @node: the context node
2123
 * @line: the line number
2124
 * @msg: the error message
2125
 * @str1: extra data
2126
 * @str2: extra data
2127
 * @str3: extra data
2128
 * @str4: extra data
2129
 *
2130
 * Handle a validation error
2131
 */
2132
static void LIBXML_ATTR_FORMAT(6,0)
2133
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2134
      xmlErrorLevel errorLevel,
2135
      int code, xmlNodePtr node, int line, const char *msg,
2136
      const xmlChar *str1, const xmlChar *str2,
2137
      const xmlChar *str3, const xmlChar *str4)
2138
246k
{
2139
246k
    if (ctxt != NULL) {
2140
246k
  if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2141
0
      xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2142
0
      const char *file = NULL;
2143
0
      int col = 0;
2144
2145
      /*
2146
      * Error node. If we specify a line number, then
2147
      * do not channel any node to the error function.
2148
      */
2149
0
      if (line == 0) {
2150
0
    if ((node == NULL) &&
2151
0
        (vctxt->depth >= 0) &&
2152
0
        (vctxt->inode != NULL)) {
2153
0
        node = vctxt->inode->node;
2154
0
    }
2155
    /*
2156
    * Get filename and line if no node-tree.
2157
    */
2158
0
    if ((node == NULL) &&
2159
0
        (vctxt->parserCtxt != NULL) &&
2160
0
        (vctxt->parserCtxt->input != NULL)) {
2161
0
        file = vctxt->parserCtxt->input->filename;
2162
0
                    if (vctxt->inode != NULL) {
2163
0
            line = vctxt->inode->nodeLine;
2164
0
                        col = 0;
2165
0
                    } else {
2166
                        /* This is inaccurate. */
2167
0
            line = vctxt->parserCtxt->input->line;
2168
0
            col = vctxt->parserCtxt->input->col;
2169
0
                    }
2170
0
    }
2171
0
      } else {
2172
    /*
2173
    * Override the given node's (if any) position
2174
    * and channel only the given line number.
2175
    */
2176
0
    node = NULL;
2177
    /*
2178
    * Get filename.
2179
    */
2180
0
    if (vctxt->doc != NULL)
2181
0
        file = (const char *) vctxt->doc->URL;
2182
0
    else if ((vctxt->parserCtxt != NULL) &&
2183
0
        (vctxt->parserCtxt->input != NULL))
2184
0
        file = vctxt->parserCtxt->input->filename;
2185
0
      }
2186
0
      if (vctxt->locFunc != NULL) {
2187
0
          if ((file == NULL) || (line == 0)) {
2188
0
        unsigned long l;
2189
0
        const char *f;
2190
0
        vctxt->locFunc(vctxt->locCtxt, &f, &l);
2191
0
        if (file == NULL)
2192
0
            file = f;
2193
0
        if (line == 0)
2194
0
            line = (int) l;
2195
0
    }
2196
0
      }
2197
0
      if ((file == NULL) && (vctxt->filename != NULL))
2198
0
          file = vctxt->filename;
2199
2200
0
            xmlSchemaVErrFull(vctxt, node, code, errorLevel,
2201
0
                              file, line, str1, str2, str3, col,
2202
0
                              msg, str1, str2, str3, str4);
2203
246k
  } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2204
246k
      xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2205
2206
246k
            xmlSchemaPErrFull(pctxt, node, code, errorLevel,
2207
246k
                              NULL, 0, str1, str2, str3, 0,
2208
246k
                              msg, str1, str2, str3, str4);
2209
246k
  }
2210
246k
    }
2211
246k
}
2212
2213
/**
2214
 * xmlSchemaErr3:
2215
 * @ctxt: the validation context
2216
 * @node: the context node
2217
 * @error: the error code
2218
 * @msg: the error message
2219
 * @str1: extra data
2220
 * @str2: extra data
2221
 * @str3: extra data
2222
 *
2223
 * Handle a validation error
2224
 */
2225
static void LIBXML_ATTR_FORMAT(4,0)
2226
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2227
        int error, xmlNodePtr node, const char *msg,
2228
        const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2229
247
{
2230
247
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2231
247
  msg, str1, str2, str3, NULL);
2232
247
}
2233
2234
static void LIBXML_ATTR_FORMAT(4,0)
2235
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2236
        int error, xmlNodePtr node, const char *msg,
2237
        const xmlChar *str1, const xmlChar *str2,
2238
        const xmlChar *str3, const xmlChar *str4)
2239
245k
{
2240
245k
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2241
245k
  msg, str1, str2, str3, str4);
2242
245k
}
2243
2244
static void LIBXML_ATTR_FORMAT(4,0)
2245
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2246
       int error, xmlNodePtr node, const char *msg,
2247
       const xmlChar *str1, const xmlChar *str2)
2248
104k
{
2249
104k
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2250
104k
}
2251
2252
static xmlChar *
2253
xmlSchemaFormatNodeForError(xmlChar ** msg,
2254
          xmlSchemaAbstractCtxtPtr actxt,
2255
          xmlNodePtr node)
2256
363k
{
2257
363k
    xmlChar *str = NULL;
2258
2259
363k
    *msg = NULL;
2260
363k
    if ((node != NULL) &&
2261
363k
  (node->type != XML_ELEMENT_NODE) &&
2262
363k
  (node->type != XML_ATTRIBUTE_NODE))
2263
0
    {
2264
  /*
2265
  * Don't try to format other nodes than element and
2266
  * attribute nodes.
2267
  * Play safe and return an empty string.
2268
  */
2269
0
  *msg = xmlStrdup(BAD_CAST "");
2270
0
  return(*msg);
2271
0
    }
2272
363k
    if (node != NULL) {
2273
  /*
2274
  * Work on tree nodes.
2275
  */
2276
346k
  if (node->type == XML_ATTRIBUTE_NODE) {
2277
122k
      xmlNodePtr elem = node->parent;
2278
2279
122k
      *msg = xmlStrdup(BAD_CAST "Element '");
2280
122k
      if (elem->ns != NULL)
2281
122k
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2282
122k
        elem->ns->href, elem->name));
2283
0
      else
2284
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2285
0
        NULL, elem->name));
2286
122k
      FREE_AND_NULL(str);
2287
122k
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2288
122k
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2289
223k
  } else {
2290
223k
      *msg = xmlStrdup(BAD_CAST "Element '");
2291
223k
  }
2292
346k
  if (node->ns != NULL)
2293
223k
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2294
223k
      node->ns->href, node->name));
2295
122k
  else
2296
122k
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2297
122k
      NULL, node->name));
2298
346k
  FREE_AND_NULL(str);
2299
346k
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2300
346k
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2301
0
  xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2302
  /*
2303
  * Work on node infos.
2304
  */
2305
0
  if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2306
0
      xmlSchemaNodeInfoPtr ielem =
2307
0
    vctxt->elemInfos[vctxt->depth];
2308
2309
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2310
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2311
0
    ielem->nsName, ielem->localName));
2312
0
      FREE_AND_NULL(str);
2313
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2314
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2315
0
  } else {
2316
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2317
0
  }
2318
0
  *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2319
0
      vctxt->inode->nsName, vctxt->inode->localName));
2320
0
  FREE_AND_NULL(str);
2321
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2322
16.6k
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2323
  /*
2324
  * Hmm, no node while parsing?
2325
  * Return an empty string, in case NULL will break something.
2326
  */
2327
16.6k
  *msg = xmlStrdup(BAD_CAST "");
2328
16.6k
    } else {
2329
  /* TODO */
2330
0
  return (NULL);
2331
0
    }
2332
2333
    /*
2334
     * xmlSchemaFormatItemForReport() also returns an escaped format
2335
     * string, so do this before calling it below (in the future).
2336
     */
2337
363k
    xmlEscapeFormatString(msg);
2338
2339
    /*
2340
    * VAL TODO: The output of the given schema component is currently
2341
    * disabled.
2342
    */
2343
#if 0
2344
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2345
  *msg = xmlStrcat(*msg, BAD_CAST " [");
2346
  *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2347
      NULL, type, NULL, 0));
2348
  FREE_AND_NULL(str)
2349
  *msg = xmlStrcat(*msg, BAD_CAST "]");
2350
    }
2351
#endif
2352
363k
    return (*msg);
2353
363k
}
2354
2355
static void LIBXML_ATTR_FORMAT(3,0)
2356
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2357
         const char *funcName,
2358
         const char *message,
2359
         const xmlChar *str1,
2360
         const xmlChar *str2)
2361
247
{
2362
247
    xmlChar *msg = NULL;
2363
2364
247
    if (actxt == NULL)
2365
0
        return;
2366
247
    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2367
247
    msg = xmlStrcat(msg, BAD_CAST message);
2368
247
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2369
2370
247
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2371
0
  xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2372
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2373
247
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2374
247
  xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2375
247
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2376
2377
247
    FREE_AND_NULL(msg)
2378
247
}
2379
2380
static void LIBXML_ATTR_FORMAT(3,0)
2381
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2382
         const char *funcName,
2383
         const char *message)
2384
247
{
2385
247
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2386
247
}
2387
2388
#if 0
2389
static void LIBXML_ATTR_FORMAT(3,0)
2390
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2391
         const char *funcName,
2392
         const char *message,
2393
         const xmlChar *str1,
2394
         const xmlChar *str2)
2395
{
2396
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2397
  str1, str2);
2398
}
2399
#endif
2400
2401
static void LIBXML_ATTR_FORMAT(5,0)
2402
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2403
       xmlParserErrors error,
2404
       xmlNodePtr node,
2405
       xmlSchemaBasicItemPtr item,
2406
       const char *message,
2407
       const xmlChar *str1, const xmlChar *str2,
2408
       const xmlChar *str3, const xmlChar *str4)
2409
112k
{
2410
112k
    xmlChar *msg = NULL;
2411
2412
112k
    if ((node == NULL) && (item != NULL) &&
2413
112k
  (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2414
1.20k
  node = WXS_ITEM_NODE(item);
2415
1.20k
  xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2416
1.20k
  msg = xmlStrcat(msg, BAD_CAST ": ");
2417
1.20k
    } else
2418
111k
  xmlSchemaFormatNodeForError(&msg, actxt, node);
2419
112k
    msg = xmlStrcat(msg, (const xmlChar *) message);
2420
112k
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2421
112k
    xmlSchemaErr4(actxt, error, node,
2422
112k
  (const char *) msg, str1, str2, str3, str4);
2423
112k
    FREE_AND_NULL(msg)
2424
112k
}
2425
2426
static void LIBXML_ATTR_FORMAT(5,0)
2427
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2428
       xmlParserErrors error,
2429
       xmlNodePtr node,
2430
       xmlSchemaBasicItemPtr item,
2431
       const char *message,
2432
       const xmlChar *str1,
2433
       const xmlChar *str2)
2434
111k
{
2435
111k
    xmlSchemaCustomErr4(actxt, error, node, item,
2436
111k
  message, str1, str2, NULL, NULL);
2437
111k
}
2438
2439
2440
2441
static void LIBXML_ATTR_FORMAT(5,0)
2442
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2443
       xmlParserErrors error,
2444
       xmlNodePtr node,
2445
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2446
       const char *message,
2447
       const xmlChar *str1,
2448
       const xmlChar *str2,
2449
       const xmlChar *str3)
2450
111
{
2451
111
    xmlChar *msg = NULL;
2452
2453
111
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2454
111
    msg = xmlStrcat(msg, (const xmlChar *) message);
2455
111
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2456
2457
    /* URGENT TODO: Set the error code to something sane. */
2458
111
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2459
111
  (const char *) msg, str1, str2, str3, NULL);
2460
2461
111
    FREE_AND_NULL(msg)
2462
111
}
2463
2464
2465
2466
static void LIBXML_ATTR_FORMAT(5,0)
2467
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2468
       xmlParserErrors error,
2469
       xmlSchemaPSVIIDCNodePtr idcNode,
2470
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2471
       const char *message,
2472
       const xmlChar *str1,
2473
       const xmlChar *str2)
2474
0
{
2475
0
    xmlChar *msg = NULL, *qname = NULL;
2476
2477
0
    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2478
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2479
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2480
0
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2481
0
  error, NULL, idcNode->nodeLine, (const char *) msg,
2482
0
  xmlSchemaFormatQName(&qname,
2483
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2484
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2485
0
  str1, str2, NULL);
2486
0
    FREE_AND_NULL(qname);
2487
0
    FREE_AND_NULL(msg);
2488
0
}
2489
2490
static int
2491
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2492
         xmlNodePtr node)
2493
26.4k
{
2494
26.4k
    if (node != NULL)
2495
26.4k
  return (node->type);
2496
0
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2497
0
  (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2498
0
  return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2499
0
    return (-1);
2500
0
}
2501
2502
static int
2503
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2504
346k
{
2505
346k
    switch (item->type) {
2506
0
  case XML_SCHEMA_TYPE_COMPLEX:
2507
12.7k
  case XML_SCHEMA_TYPE_SIMPLE:
2508
12.7k
      if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2509
746
    return(1);
2510
11.9k
      break;
2511
11.9k
  case XML_SCHEMA_TYPE_GROUP:
2512
0
      return (1);
2513
0
  case XML_SCHEMA_TYPE_ELEMENT:
2514
0
      if ( ((xmlSchemaElementPtr) item)->flags &
2515
0
    XML_SCHEMAS_ELEM_GLOBAL)
2516
0
    return(1);
2517
0
      break;
2518
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
2519
0
      if ( ((xmlSchemaAttributePtr) item)->flags &
2520
0
    XML_SCHEMAS_ATTR_GLOBAL)
2521
0
    return(1);
2522
0
      break;
2523
  /* Note that attribute groups are always global. */
2524
333k
  default:
2525
333k
      return(1);
2526
346k
    }
2527
11.9k
    return (0);
2528
346k
}
2529
2530
static void
2531
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2532
           xmlParserErrors error,
2533
           xmlNodePtr node,
2534
           const xmlChar *value,
2535
           xmlSchemaTypePtr type,
2536
           int displayValue)
2537
78.4k
{
2538
78.4k
    xmlChar *msg = NULL;
2539
2540
78.4k
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2541
2542
78.4k
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2543
0
      XML_ATTRIBUTE_NODE))
2544
78.4k
  msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2545
0
    else
2546
0
  msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2547
0
      "value of ");
2548
2549
78.4k
    if (! xmlSchemaIsGlobalItem(type))
2550
5.98k
  msg = xmlStrcat(msg, BAD_CAST "the local ");
2551
72.4k
    else
2552
72.4k
  msg = xmlStrcat(msg, BAD_CAST "the ");
2553
2554
78.4k
    if (WXS_IS_ATOMIC(type))
2555
75.1k
  msg = xmlStrcat(msg, BAD_CAST "atomic type");
2556
3.29k
    else if (WXS_IS_LIST(type))
2557
3.19k
  msg = xmlStrcat(msg, BAD_CAST "list type");
2558
104
    else if (WXS_IS_UNION(type))
2559
104
  msg = xmlStrcat(msg, BAD_CAST "union type");
2560
2561
78.4k
    if (xmlSchemaIsGlobalItem(type)) {
2562
72.4k
  xmlChar *str = NULL;
2563
72.4k
  msg = xmlStrcat(msg, BAD_CAST " '");
2564
72.4k
  if (type->builtInType != 0) {
2565
72.0k
      msg = xmlStrcat(msg, BAD_CAST "xs:");
2566
72.0k
      str = xmlStrdup(type->name);
2567
72.0k
  } else {
2568
373
      const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2569
373
      if (!str)
2570
269
    str = xmlStrdup(qName);
2571
373
  }
2572
72.4k
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2573
72.4k
  msg = xmlStrcat(msg, BAD_CAST "'");
2574
72.4k
  FREE_AND_NULL(str);
2575
72.4k
    }
2576
78.4k
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2577
78.4k
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2578
0
      XML_ATTRIBUTE_NODE))
2579
78.4k
  xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2580
0
    else
2581
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2582
78.4k
    FREE_AND_NULL(msg)
2583
78.4k
}
2584
2585
static const xmlChar *
2586
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2587
            xmlSchemaNodeInfoPtr ni,
2588
            xmlNodePtr node)
2589
0
{
2590
0
    if (node != NULL) {
2591
0
  if (node->ns != NULL)
2592
0
      return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2593
0
  else
2594
0
      return (xmlSchemaFormatQName(str, NULL, node->name));
2595
0
    } else if (ni != NULL)
2596
0
  return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2597
0
    return (NULL);
2598
0
}
2599
2600
static void
2601
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2602
      xmlParserErrors error,
2603
      xmlSchemaAttrInfoPtr ni,
2604
      xmlNodePtr node)
2605
0
{
2606
0
    xmlChar *msg = NULL, *str = NULL;
2607
2608
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2609
0
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2610
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2611
0
  xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2612
0
  NULL);
2613
0
    FREE_AND_NULL(str)
2614
0
    FREE_AND_NULL(msg)
2615
0
}
2616
2617
static void LIBXML_ATTR_FORMAT(5,0)
2618
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2619
            xmlParserErrors error,
2620
            xmlNodePtr node,
2621
      xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2622
      const char *message,
2623
      int nbval,
2624
      int nbneg,
2625
      xmlChar **values)
2626
0
{
2627
0
    xmlChar *str = NULL, *msg = NULL;
2628
0
    xmlChar *localName, *nsName;
2629
0
    const xmlChar *cur, *end;
2630
0
    int i;
2631
2632
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2633
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2634
0
    msg = xmlStrcat(msg, BAD_CAST ".");
2635
    /*
2636
    * Note that is does not make sense to report that we have a
2637
    * wildcard here, since the wildcard might be unfolded into
2638
    * multiple transitions.
2639
    */
2640
0
    if (nbval + nbneg > 0) {
2641
0
  if (nbval + nbneg > 1) {
2642
0
      str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2643
0
  } else
2644
0
      str = xmlStrdup(BAD_CAST " Expected is ( ");
2645
0
  nsName = NULL;
2646
2647
0
  for (i = 0; i < nbval + nbneg; i++) {
2648
0
      cur = values[i];
2649
0
      if (cur == NULL)
2650
0
          continue;
2651
0
      if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2652
0
          (cur[3] == ' ')) {
2653
0
    cur += 4;
2654
0
    str = xmlStrcat(str, BAD_CAST "##other");
2655
0
      }
2656
      /*
2657
      * Get the local name.
2658
      */
2659
0
      localName = NULL;
2660
2661
0
      end = cur;
2662
0
      if (*end == '*') {
2663
0
    localName = xmlStrdup(BAD_CAST "*");
2664
0
    end++;
2665
0
      } else {
2666
0
    while ((*end != 0) && (*end != '|'))
2667
0
        end++;
2668
0
    localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2669
0
      }
2670
0
      if (*end != 0) {
2671
0
    end++;
2672
    /*
2673
    * Skip "*|*" if they come with negated expressions, since
2674
    * they represent the same negated wildcard.
2675
    */
2676
0
    if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2677
        /*
2678
        * Get the namespace name.
2679
        */
2680
0
        cur = end;
2681
0
        if (*end == '*') {
2682
0
      nsName = xmlStrdup(BAD_CAST "{*}");
2683
0
        } else {
2684
0
      while (*end != 0)
2685
0
          end++;
2686
2687
0
      if (i >= nbval)
2688
0
          nsName = xmlStrdup(BAD_CAST "{##other:");
2689
0
      else
2690
0
          nsName = xmlStrdup(BAD_CAST "{");
2691
2692
0
      nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2693
0
      nsName = xmlStrcat(nsName, BAD_CAST "}");
2694
0
        }
2695
0
        str = xmlStrcat(str, BAD_CAST nsName);
2696
0
        FREE_AND_NULL(nsName)
2697
0
    } else {
2698
0
        FREE_AND_NULL(localName);
2699
0
        continue;
2700
0
    }
2701
0
      }
2702
0
      str = xmlStrcat(str, BAD_CAST localName);
2703
0
      FREE_AND_NULL(localName);
2704
2705
0
      if (i < nbval + nbneg -1)
2706
0
    str = xmlStrcat(str, BAD_CAST ", ");
2707
0
  }
2708
0
  str = xmlStrcat(str, BAD_CAST " ).\n");
2709
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2710
0
  FREE_AND_NULL(str)
2711
0
    } else
2712
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
2713
0
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2714
0
    xmlFree(msg);
2715
0
}
2716
2717
static void LIBXML_ATTR_FORMAT(8,0)
2718
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2719
      xmlParserErrors error,
2720
      xmlNodePtr node,
2721
      const xmlChar *value,
2722
      unsigned long length,
2723
      xmlSchemaTypePtr type,
2724
      xmlSchemaFacetPtr facet,
2725
      const char *message,
2726
      const xmlChar *str1,
2727
      const xmlChar *str2)
2728
26.4k
{
2729
26.4k
    xmlChar *str = NULL, *msg = NULL;
2730
26.4k
    xmlSchemaTypeType facetType;
2731
26.4k
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2732
2733
26.4k
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2734
26.4k
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2735
6.43k
  facetType = XML_SCHEMA_FACET_ENUMERATION;
2736
  /*
2737
  * If enumerations are validated, one must not expect the
2738
  * facet to be given.
2739
  */
2740
6.43k
    } else
2741
19.9k
  facetType = facet->type;
2742
26.4k
    msg = xmlStrcat(msg, BAD_CAST "[");
2743
26.4k
    msg = xmlStrcat(msg, BAD_CAST "facet '");
2744
26.4k
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2745
26.4k
    msg = xmlStrcat(msg, BAD_CAST "'] ");
2746
26.4k
    if (message == NULL) {
2747
  /*
2748
  * Use a default message.
2749
  */
2750
26.4k
  if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2751
26.4k
      (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2752
26.4k
      (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2753
2754
1.03k
      char len[25], actLen[25];
2755
2756
      /* FIXME, TODO: What is the max expected string length of the
2757
      * this value?
2758
      */
2759
1.03k
      if (nodeType == XML_ATTRIBUTE_NODE)
2760
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2761
1.03k
      else
2762
1.03k
    msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2763
2764
1.03k
      snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2765
1.03k
      snprintf(actLen, 24, "%lu", length);
2766
2767
1.03k
      if (facetType == XML_SCHEMA_FACET_LENGTH)
2768
428
    msg = xmlStrcat(msg,
2769
428
    BAD_CAST "this differs from the allowed length of '%s'.\n");
2770
605
      else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2771
344
    msg = xmlStrcat(msg,
2772
344
    BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2773
261
      else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2774
261
    msg = xmlStrcat(msg,
2775
261
    BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2776
2777
1.03k
      if (nodeType == XML_ATTRIBUTE_NODE)
2778
0
    xmlSchemaErr3(actxt, error, node, (const char *) msg,
2779
0
        value, (const xmlChar *) actLen, (const xmlChar *) len);
2780
1.03k
      else
2781
1.03k
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2782
1.03k
        (const xmlChar *) actLen, (const xmlChar *) len);
2783
2784
25.3k
  } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2785
6.43k
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2786
6.43k
    "of the set {%s}.\n");
2787
6.43k
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2788
6.43k
    xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2789
18.9k
  } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2790
6.77k
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2791
6.77k
    "by the pattern '%s'.\n");
2792
6.77k
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2793
6.77k
    facet->value);
2794
12.1k
  } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2795
213
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2796
213
    "minimum value allowed ('%s').\n");
2797
213
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2798
213
    facet->value);
2799
11.9k
  } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2800
7.51k
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2801
7.51k
    "maximum value allowed ('%s').\n");
2802
7.51k
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2803
7.51k
    facet->value);
2804
7.51k
  } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2805
124
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2806
124
    "'%s'.\n");
2807
124
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2808
124
    facet->value);
2809
4.32k
  } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2810
3.94k
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2811
3.94k
    "'%s'.\n");
2812
3.94k
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2813
3.94k
    facet->value);
2814
3.94k
  } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2815
374
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2816
374
    "digits than are allowed ('%s').\n");
2817
374
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2818
374
    facet->value);
2819
374
  } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2820
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2821
0
    "digits than are allowed ('%s').\n");
2822
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2823
0
    facet->value);
2824
0
  } else if (nodeType == XML_ATTRIBUTE_NODE) {
2825
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2826
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2827
0
  } else {
2828
0
      msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2829
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2830
0
  }
2831
26.4k
    } else {
2832
0
  msg = xmlStrcat(msg, (const xmlChar *) message);
2833
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
2834
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2835
0
    }
2836
26.4k
    FREE_AND_NULL(str)
2837
26.4k
    xmlFree(msg);
2838
26.4k
}
2839
2840
#define VERROR(err, type, msg) \
2841
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2842
2843
0
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2844
2845
92
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2846
100
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2847
2848
48
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2849
2850
2851
/**
2852
 * xmlSchemaPMissingAttrErr:
2853
 * @ctxt: the schema validation context
2854
 * @ownerItem: the owner as a schema object
2855
 * @ownerElem: the owner as an element node
2856
 * @node: the parent element node of the missing attribute node
2857
 * @type: the corresponding type of the attribute node
2858
 *
2859
 * Reports an illegal attribute.
2860
 */
2861
static void
2862
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2863
       xmlParserErrors error,
2864
       xmlSchemaBasicItemPtr ownerItem,
2865
       xmlNodePtr ownerElem,
2866
       const char *name,
2867
       const char *message)
2868
16.6k
{
2869
16.6k
    xmlChar *des = NULL;
2870
2871
16.6k
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2872
2873
16.6k
    if (message != NULL)
2874
0
  xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2875
16.6k
    else
2876
16.6k
  xmlSchemaPErr(ctxt, ownerElem, error,
2877
16.6k
      "%s: The attribute '%s' is required but missing.\n",
2878
16.6k
      BAD_CAST des, BAD_CAST name);
2879
16.6k
    FREE_AND_NULL(des);
2880
16.6k
}
2881
2882
2883
/**
2884
 * xmlSchemaPResCompAttrErr:
2885
 * @ctxt: the schema validation context
2886
 * @error: the error code
2887
 * @ownerItem: the owner as a schema object
2888
 * @ownerElem: the owner as an element node
2889
 * @name: the name of the attribute holding the QName
2890
 * @refName: the referenced local name
2891
 * @refURI: the referenced namespace URI
2892
 * @message: optional message
2893
 *
2894
 * Used to report QName attribute values that failed to resolve
2895
 * to schema components.
2896
 */
2897
static void
2898
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2899
       xmlParserErrors error,
2900
       xmlSchemaBasicItemPtr ownerItem,
2901
       xmlNodePtr ownerElem,
2902
       const char *name,
2903
       const xmlChar *refName,
2904
       const xmlChar *refURI,
2905
       xmlSchemaTypeType refType,
2906
       const char *refTypeStr)
2907
6.85k
{
2908
6.85k
    xmlChar *des = NULL, *strA = NULL;
2909
2910
6.85k
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2911
6.85k
    if (refTypeStr == NULL)
2912
6.63k
  refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2913
6.85k
    xmlSchemaPErrExt(ctxt, ownerElem, error,
2914
6.85k
      NULL, NULL, NULL,
2915
6.85k
      "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2916
6.85k
      "%s.\n", BAD_CAST des, BAD_CAST name,
2917
6.85k
      xmlSchemaFormatQName(&strA, refURI, refName),
2918
6.85k
      BAD_CAST refTypeStr, NULL);
2919
6.85k
    FREE_AND_NULL(des)
2920
6.85k
    FREE_AND_NULL(strA)
2921
6.85k
}
2922
2923
/**
2924
 * xmlSchemaPCustomAttrErr:
2925
 * @ctxt: the schema parser context
2926
 * @error: the error code
2927
 * @ownerDes: the designation of the owner
2928
 * @ownerItem: the owner as a schema object
2929
 * @attr: the illegal attribute node
2930
 *
2931
 * Reports an illegal attribute during the parse.
2932
 */
2933
static void
2934
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2935
      xmlParserErrors error,
2936
      xmlChar **ownerDes,
2937
      xmlSchemaBasicItemPtr ownerItem,
2938
      xmlAttrPtr attr,
2939
      const char *msg)
2940
2.17k
{
2941
2.17k
    xmlChar *des = NULL;
2942
2943
2.17k
    if (ownerDes == NULL)
2944
2.17k
  xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2945
0
    else if (*ownerDes == NULL) {
2946
0
  xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2947
0
  des = *ownerDes;
2948
0
    } else
2949
0
  des = *ownerDes;
2950
2.17k
    if (attr == NULL) {
2951
0
  xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2952
0
      "%s, attribute '%s': %s.\n",
2953
0
      BAD_CAST des, (const xmlChar *) "Unknown",
2954
0
      (const xmlChar *) msg, NULL, NULL);
2955
2.17k
    } else {
2956
2.17k
  xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2957
2.17k
      "%s, attribute '%s': %s.\n",
2958
2.17k
      BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2959
2.17k
    }
2960
2.17k
    if (ownerDes == NULL)
2961
2.17k
  FREE_AND_NULL(des);
2962
2.17k
}
2963
2964
/**
2965
 * xmlSchemaPIllegalAttrErr:
2966
 * @ctxt: the schema parser context
2967
 * @error: the error code
2968
 * @ownerItem: the attribute's owner item
2969
 * @attr: the illegal attribute node
2970
 *
2971
 * Reports an illegal attribute during the parse.
2972
 */
2973
static void
2974
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2975
       xmlParserErrors error,
2976
       xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2977
       xmlAttrPtr attr)
2978
28.3k
{
2979
28.3k
    xmlChar *strA = NULL, *strB = NULL;
2980
2981
28.3k
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2982
28.3k
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2983
28.3k
  "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2984
28.3k
  xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2985
28.3k
  NULL, NULL);
2986
28.3k
    FREE_AND_NULL(strA);
2987
28.3k
    FREE_AND_NULL(strB);
2988
28.3k
}
2989
2990
/**
2991
 * xmlSchemaPCustomErr:
2992
 * @ctxt: the schema parser context
2993
 * @error: the error code
2994
 * @itemDes: the designation of the schema item
2995
 * @item: the schema item
2996
 * @itemElem: the node of the schema item
2997
 * @message: the error message
2998
 * @str1: an optional param for the error message
2999
 * @str2: an optional param for the error message
3000
 * @str3: an optional param for the error message
3001
 *
3002
 * Reports an error during parsing.
3003
 */
3004
static void LIBXML_ATTR_FORMAT(5,0)
3005
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
3006
        xmlParserErrors error,
3007
        xmlSchemaBasicItemPtr item,
3008
        xmlNodePtr itemElem,
3009
        const char *message,
3010
        const xmlChar *str1,
3011
        const xmlChar *str2,
3012
        const xmlChar *str3)
3013
20.9k
{
3014
20.9k
    xmlChar *des = NULL, *msg = NULL;
3015
3016
20.9k
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
3017
20.9k
    msg = xmlStrdup(BAD_CAST "%s: ");
3018
20.9k
    msg = xmlStrcat(msg, (const xmlChar *) message);
3019
20.9k
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3020
20.9k
    if ((itemElem == NULL) && (item != NULL))
3021
557
  itemElem = WXS_ITEM_NODE(item);
3022
20.9k
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3023
20.9k
  (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3024
20.9k
    FREE_AND_NULL(des);
3025
20.9k
    FREE_AND_NULL(msg);
3026
20.9k
}
3027
3028
/**
3029
 * xmlSchemaPCustomErr:
3030
 * @ctxt: the schema parser context
3031
 * @error: the error code
3032
 * @itemDes: the designation of the schema item
3033
 * @item: the schema item
3034
 * @itemElem: the node of the schema item
3035
 * @message: the error message
3036
 * @str1: the optional param for the error message
3037
 *
3038
 * Reports an error during parsing.
3039
 */
3040
static void LIBXML_ATTR_FORMAT(5,0)
3041
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3042
        xmlParserErrors error,
3043
        xmlSchemaBasicItemPtr item,
3044
        xmlNodePtr itemElem,
3045
        const char *message,
3046
        const xmlChar *str1)
3047
20.7k
{
3048
20.7k
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3049
20.7k
  str1, NULL, NULL);
3050
20.7k
}
3051
3052
/**
3053
 * xmlSchemaPAttrUseErr:
3054
 * @ctxt: the schema parser context
3055
 * @error: the error code
3056
 * @itemDes: the designation of the schema type
3057
 * @item: the schema type
3058
 * @itemElem: the node of the schema type
3059
 * @attr: the invalid schema attribute
3060
 * @message: the error message
3061
 * @str1: the optional param for the error message
3062
 *
3063
 * Reports an attribute use error during parsing.
3064
 */
3065
static void LIBXML_ATTR_FORMAT(6,0)
3066
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3067
        xmlParserErrors error,
3068
        xmlNodePtr node,
3069
        xmlSchemaBasicItemPtr ownerItem,
3070
        const xmlSchemaAttributeUsePtr attruse,
3071
        const char *message,
3072
        const xmlChar *str1, const xmlChar *str2,
3073
        const xmlChar *str3,const xmlChar *str4)
3074
107
{
3075
107
    xmlChar *str = NULL, *msg = NULL;
3076
3077
107
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3078
107
    msg = xmlStrcat(msg, BAD_CAST ", ");
3079
107
    msg = xmlStrcat(msg,
3080
107
  BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3081
107
  WXS_BASIC_CAST attruse, NULL));
3082
107
    FREE_AND_NULL(str);
3083
107
    msg = xmlStrcat(msg, BAD_CAST ": ");
3084
107
    msg = xmlStrcat(msg, (const xmlChar *) message);
3085
107
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3086
107
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3087
107
  (const char *) msg, str1, str2, str3, str4);
3088
107
    xmlFree(msg);
3089
107
}
3090
3091
/**
3092
 * xmlSchemaPIllegalFacetAtomicErr:
3093
 * @ctxt: the schema parser context
3094
 * @error: the error code
3095
 * @type: the schema type
3096
 * @baseType: the base type of type
3097
 * @facet: the illegal facet
3098
 *
3099
 * Reports an illegal facet for atomic simple types.
3100
 */
3101
static void
3102
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3103
        xmlParserErrors error,
3104
        xmlSchemaTypePtr type,
3105
        xmlSchemaTypePtr baseType,
3106
        xmlSchemaFacetPtr facet)
3107
305
{
3108
305
    xmlChar *des = NULL, *strT = NULL;
3109
3110
305
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3111
305
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3112
305
  "%s: The facet '%s' is not allowed on types derived from the "
3113
305
  "type %s.\n",
3114
305
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3115
305
  xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3116
305
  NULL, NULL);
3117
305
    FREE_AND_NULL(des);
3118
305
    FREE_AND_NULL(strT);
3119
305
}
3120
3121
/**
3122
 * xmlSchemaPIllegalFacetListUnionErr:
3123
 * @ctxt: the schema parser context
3124
 * @error: the error code
3125
 * @itemDes: the designation of the schema item involved
3126
 * @item: the schema item involved
3127
 * @facet: the illegal facet
3128
 *
3129
 * Reports an illegal facet for <list> and <union>.
3130
 */
3131
static void
3132
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3133
        xmlParserErrors error,
3134
        xmlSchemaTypePtr type,
3135
        xmlSchemaFacetPtr facet)
3136
200
{
3137
200
    xmlChar *des = NULL;
3138
3139
200
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3140
200
  type->node);
3141
200
    xmlSchemaPErr(ctxt, type->node, error,
3142
200
  "%s: The facet '%s' is not allowed.\n",
3143
200
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3144
200
    FREE_AND_NULL(des);
3145
200
}
3146
3147
/**
3148
 * xmlSchemaPMutualExclAttrErr:
3149
 * @ctxt: the schema validation context
3150
 * @error: the error code
3151
 * @elemDes: the designation of the parent element node
3152
 * @attr: the bad attribute node
3153
 * @type: the corresponding type of the attribute node
3154
 *
3155
 * Reports an illegal attribute.
3156
 */
3157
static void
3158
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3159
       xmlParserErrors error,
3160
       xmlSchemaBasicItemPtr ownerItem,
3161
       xmlAttrPtr attr,
3162
       const char *name1,
3163
       const char *name2)
3164
715
{
3165
715
    xmlChar *des = NULL;
3166
3167
715
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3168
715
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3169
715
  "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3170
715
  BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3171
715
    FREE_AND_NULL(des);
3172
715
}
3173
3174
/**
3175
 * xmlSchemaPSimpleTypeErr:
3176
 * @ctxt:  the schema validation context
3177
 * @error: the error code
3178
 * @type: the type specifier
3179
 * @ownerItem: the schema object if existent
3180
 * @node: the validated node
3181
 * @value: the validated value
3182
 *
3183
 * Reports a simple type validation error.
3184
 * TODO: Should this report the value of an element as well?
3185
 */
3186
static void LIBXML_ATTR_FORMAT(8,0)
3187
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3188
      xmlParserErrors error,
3189
      xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3190
      xmlNodePtr node,
3191
      xmlSchemaTypePtr type,
3192
      const char *expected,
3193
      const xmlChar *value,
3194
      const char *message,
3195
      const xmlChar *str1,
3196
      const xmlChar *str2)
3197
118k
{
3198
118k
    xmlChar *msg = NULL;
3199
3200
118k
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3201
118k
    if (message == NULL) {
3202
  /*
3203
  * Use default messages.
3204
  */
3205
101k
  if (type != NULL) {
3206
94.9k
      if (node->type == XML_ATTRIBUTE_NODE)
3207
94.9k
    msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3208
2
      else
3209
2
    msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3210
2
    "valid value of ");
3211
94.9k
      if (! xmlSchemaIsGlobalItem(type))
3212
0
    msg = xmlStrcat(msg, BAD_CAST "the local ");
3213
94.9k
      else
3214
94.9k
    msg = xmlStrcat(msg, BAD_CAST "the ");
3215
3216
94.9k
      if (WXS_IS_ATOMIC(type))
3217
94.9k
    msg = xmlStrcat(msg, BAD_CAST "atomic type");
3218
0
      else if (WXS_IS_LIST(type))
3219
0
    msg = xmlStrcat(msg, BAD_CAST "list type");
3220
0
      else if (WXS_IS_UNION(type))
3221
0
    msg = xmlStrcat(msg, BAD_CAST "union type");
3222
3223
94.9k
      if (xmlSchemaIsGlobalItem(type)) {
3224
94.9k
    xmlChar *str = NULL;
3225
94.9k
    msg = xmlStrcat(msg, BAD_CAST " '");
3226
94.9k
    if (type->builtInType != 0) {
3227
94.9k
        msg = xmlStrcat(msg, BAD_CAST "xs:");
3228
94.9k
        str = xmlStrdup(type->name);
3229
94.9k
    } else {
3230
0
        const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3231
0
        if (!str)
3232
0
      str = xmlStrdup(qName);
3233
0
    }
3234
94.9k
    msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3235
94.9k
    msg = xmlStrcat(msg, BAD_CAST "'.");
3236
94.9k
    FREE_AND_NULL(str);
3237
94.9k
      }
3238
94.9k
  } else {
3239
6.73k
      if (node->type == XML_ATTRIBUTE_NODE)
3240
6.70k
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3241
39
      else
3242
39
    msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3243
39
    "valid.");
3244
6.73k
  }
3245
101k
  if (expected) {
3246
6.73k
      xmlChar *expectedEscaped = xmlCharStrdup(expected);
3247
6.73k
      msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3248
6.73k
      msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3249
6.73k
      FREE_AND_NULL(expectedEscaped);
3250
6.73k
      msg = xmlStrcat(msg, BAD_CAST "'.\n");
3251
6.73k
  } else
3252
94.9k
      msg = xmlStrcat(msg, BAD_CAST "\n");
3253
101k
  if (node->type == XML_ATTRIBUTE_NODE)
3254
101k
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3255
41
  else
3256
41
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3257
101k
    } else {
3258
17.1k
  msg = xmlStrcat(msg, BAD_CAST message);
3259
17.1k
  msg = xmlStrcat(msg, BAD_CAST ".\n");
3260
17.1k
  xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3261
17.1k
       (const char*) msg, str1, str2, NULL, NULL, NULL);
3262
17.1k
    }
3263
    /* Cleanup. */
3264
118k
    FREE_AND_NULL(msg)
3265
118k
}
3266
3267
/**
3268
 * xmlSchemaPContentErr:
3269
 * @ctxt: the schema parser context
3270
 * @error: the error code
3271
 * @ownerItem: the owner item of the holder of the content
3272
 * @ownerElem: the node of the holder of the content
3273
 * @child: the invalid child node
3274
 * @message: the optional error message
3275
 * @content: the optional string describing the correct content
3276
 *
3277
 * Reports an error concerning the content of a schema element.
3278
 */
3279
static void
3280
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3281
         xmlParserErrors error,
3282
         xmlSchemaBasicItemPtr ownerItem,
3283
         xmlNodePtr ownerElem,
3284
         xmlNodePtr child,
3285
         const char *message,
3286
         const char *content)
3287
86.4k
{
3288
86.4k
    xmlChar *des = NULL;
3289
3290
86.4k
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3291
86.4k
    if (message != NULL)
3292
911
  xmlSchemaPErr2(ctxt, ownerElem, child, error,
3293
911
      "%s: %s.\n",
3294
911
      BAD_CAST des, BAD_CAST message);
3295
85.5k
    else {
3296
85.5k
  if (content != NULL) {
3297
85.5k
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3298
85.5k
    "%s: The content is not valid. Expected is %s.\n",
3299
85.5k
    BAD_CAST des, BAD_CAST content);
3300
85.5k
  } else {
3301
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3302
0
    "%s: The content is not valid.\n",
3303
0
    BAD_CAST des, NULL);
3304
0
  }
3305
85.5k
    }
3306
86.4k
    FREE_AND_NULL(des)
3307
86.4k
}
3308
3309
/************************************************************************
3310
 *                  *
3311
 *      Streamable error functions                      *
3312
 *                  *
3313
 ************************************************************************/
3314
3315
3316
3317
3318
/************************************************************************
3319
 *                  *
3320
 *      Validation helper functions     *
3321
 *                  *
3322
 ************************************************************************/
3323
3324
3325
/************************************************************************
3326
 *                  *
3327
 *      Allocation functions        *
3328
 *                  *
3329
 ************************************************************************/
3330
3331
/**
3332
 * xmlSchemaNewSchemaForParserCtxt:
3333
 * @ctxt:  a schema validation context
3334
 *
3335
 * Allocate a new Schema structure.
3336
 *
3337
 * Returns the newly allocated structure or NULL in case or error
3338
 */
3339
static xmlSchemaPtr
3340
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3341
29.2k
{
3342
29.2k
    xmlSchemaPtr ret;
3343
3344
29.2k
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3345
29.2k
    if (ret == NULL) {
3346
0
        xmlSchemaPErrMemory(ctxt);
3347
0
        return (NULL);
3348
0
    }
3349
29.2k
    memset(ret, 0, sizeof(xmlSchema));
3350
29.2k
    ret->dict = ctxt->dict;
3351
29.2k
    xmlDictReference(ret->dict);
3352
3353
29.2k
    return (ret);
3354
29.2k
}
3355
3356
/**
3357
 * xmlSchemaNewFacet:
3358
 *
3359
 * Allocate a new Facet structure.
3360
 *
3361
 * Returns the newly allocated structure or NULL in case or error
3362
 */
3363
xmlSchemaFacetPtr
3364
xmlSchemaNewFacet(void)
3365
128k
{
3366
128k
    xmlSchemaFacetPtr ret;
3367
3368
128k
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3369
128k
    if (ret == NULL) {
3370
0
        return (NULL);
3371
0
    }
3372
128k
    memset(ret, 0, sizeof(xmlSchemaFacet));
3373
3374
128k
    return (ret);
3375
128k
}
3376
3377
/**
3378
 * xmlSchemaNewAnnot:
3379
 * @ctxt:  a schema validation context
3380
 * @node:  a node
3381
 *
3382
 * Allocate a new annotation structure.
3383
 *
3384
 * Returns the newly allocated structure or NULL in case or error
3385
 */
3386
static xmlSchemaAnnotPtr
3387
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3388
4.31k
{
3389
4.31k
    xmlSchemaAnnotPtr ret;
3390
3391
4.31k
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3392
4.31k
    if (ret == NULL) {
3393
0
        xmlSchemaPErrMemory(ctxt);
3394
0
        return (NULL);
3395
0
    }
3396
4.31k
    memset(ret, 0, sizeof(xmlSchemaAnnot));
3397
4.31k
    ret->content = node;
3398
4.31k
    return (ret);
3399
4.31k
}
3400
3401
static xmlSchemaItemListPtr
3402
xmlSchemaItemListCreate(void)
3403
122k
{
3404
122k
    xmlSchemaItemListPtr ret;
3405
3406
122k
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3407
122k
    if (ret == NULL) {
3408
0
  xmlSchemaPErrMemory(NULL);
3409
0
  return (NULL);
3410
0
    }
3411
122k
    memset(ret, 0, sizeof(xmlSchemaItemList));
3412
122k
    return (ret);
3413
122k
}
3414
3415
static void
3416
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3417
0
{
3418
0
    if (list->items != NULL) {
3419
0
  xmlFree(list->items);
3420
0
  list->items = NULL;
3421
0
    }
3422
0
    list->nbItems = 0;
3423
0
    list->sizeItems = 0;
3424
0
}
3425
3426
static int
3427
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3428
12.8k
{
3429
12.8k
    if (list->sizeItems <= list->nbItems) {
3430
12.5k
        void **tmp;
3431
12.5k
        size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3432
3433
12.5k
  tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3434
12.5k
  if (tmp == NULL) {
3435
0
      xmlSchemaPErrMemory(NULL);
3436
0
      return(-1);
3437
0
  }
3438
12.5k
        list->items = tmp;
3439
12.5k
  list->sizeItems = newSize;
3440
12.5k
    }
3441
12.8k
    list->items[list->nbItems++] = item;
3442
12.8k
    return(0);
3443
12.8k
}
3444
3445
static int
3446
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3447
       int initialSize,
3448
       void *item)
3449
253k
{
3450
253k
    if (list->items == NULL) {
3451
30.6k
  if (initialSize <= 0)
3452
0
      initialSize = 1;
3453
30.6k
  list->items = (void **) xmlMalloc(
3454
30.6k
      initialSize * sizeof(void *));
3455
30.6k
  if (list->items == NULL) {
3456
0
      xmlSchemaPErrMemory(NULL);
3457
0
      return(-1);
3458
0
  }
3459
30.6k
  list->sizeItems = initialSize;
3460
223k
    } else if (list->sizeItems <= list->nbItems) {
3461
9.04k
        void **tmp;
3462
3463
9.04k
  list->sizeItems *= 2;
3464
9.04k
  tmp = (void **) xmlRealloc(list->items,
3465
9.04k
      list->sizeItems * sizeof(void *));
3466
9.04k
  if (tmp == NULL) {
3467
0
      xmlSchemaPErrMemory(NULL);
3468
0
      list->sizeItems /= 2;
3469
0
      return(-1);
3470
0
  }
3471
9.04k
        list->items = tmp;
3472
9.04k
    }
3473
253k
    list->items[list->nbItems++] = item;
3474
253k
    return(0);
3475
253k
}
3476
3477
static int
3478
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3479
37
{
3480
37
    if (list->sizeItems <= list->nbItems) {
3481
6
        void **tmp;
3482
6
        size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
3483
3484
6
  tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
3485
6
  if (tmp == NULL) {
3486
0
      xmlSchemaPErrMemory(NULL);
3487
0
      return(-1);
3488
0
  }
3489
6
        list->items = tmp;
3490
6
  list->sizeItems = newSize;
3491
6
    }
3492
    /*
3493
    * Just append if the index is greater/equal than the item count.
3494
    */
3495
37
    if (idx >= list->nbItems) {
3496
32
  list->items[list->nbItems++] = item;
3497
32
    } else {
3498
5
  int i;
3499
10
  for (i = list->nbItems; i > idx; i--)
3500
5
      list->items[i] = list->items[i-1];
3501
5
  list->items[idx] = item;
3502
5
  list->nbItems++;
3503
5
    }
3504
37
    return(0);
3505
37
}
3506
3507
#if 0 /* enable if ever needed */
3508
static int
3509
xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3510
          int initialSize,
3511
          void *item,
3512
          int idx)
3513
{
3514
    if (list->items == NULL) {
3515
  if (initialSize <= 0)
3516
      initialSize = 1;
3517
  list->items = (void **) xmlMalloc(
3518
      initialSize * sizeof(void *));
3519
  if (list->items == NULL) {
3520
      xmlSchemaPErrMemory(NULL);
3521
      return(-1);
3522
  }
3523
  list->sizeItems = initialSize;
3524
    } else if (list->sizeItems <= list->nbItems) {
3525
  list->sizeItems *= 2;
3526
  list->items = (void **) xmlRealloc(list->items,
3527
      list->sizeItems * sizeof(void *));
3528
  if (list->items == NULL) {
3529
      xmlSchemaPErrMemory(NULL);
3530
      list->sizeItems = 0;
3531
      return(-1);
3532
  }
3533
    }
3534
    /*
3535
    * Just append if the index is greater/equal than the item count.
3536
    */
3537
    if (idx >= list->nbItems) {
3538
  list->items[list->nbItems++] = item;
3539
    } else {
3540
  int i;
3541
  for (i = list->nbItems; i > idx; i--)
3542
      list->items[i] = list->items[i-1];
3543
  list->items[idx] = item;
3544
  list->nbItems++;
3545
    }
3546
    return(0);
3547
}
3548
#endif
3549
3550
static int
3551
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3552
1.73k
{
3553
1.73k
    int i;
3554
1.73k
    if ((list->items == NULL) || (idx >= list->nbItems))
3555
0
  return(-1);
3556
3557
1.73k
    if (list->nbItems == 1) {
3558
  /* TODO: Really free the list? */
3559
172
  xmlFree(list->items);
3560
172
  list->items = NULL;
3561
172
  list->nbItems = 0;
3562
172
  list->sizeItems = 0;
3563
1.56k
    } else if (list->nbItems -1 == idx) {
3564
163
  list->nbItems--;
3565
1.40k
    } else {
3566
11.2k
  for (i = idx; i < list->nbItems -1; i++)
3567
9.89k
      list->items[i] = list->items[i+1];
3568
1.40k
  list->nbItems--;
3569
1.40k
    }
3570
1.73k
    return(0);
3571
1.73k
}
3572
3573
/**
3574
 * xmlSchemaItemListFree:
3575
 * @annot:  a schema type structure
3576
 *
3577
 * Deallocate a annotation structure
3578
 */
3579
static void
3580
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3581
122k
{
3582
122k
    if (list == NULL)
3583
0
  return;
3584
122k
    if (list->items != NULL)
3585
42.9k
  xmlFree(list->items);
3586
122k
    xmlFree(list);
3587
122k
}
3588
3589
static void
3590
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3591
12.6k
{
3592
12.6k
    if (bucket == NULL)
3593
0
  return;
3594
12.6k
    if (bucket->globals != NULL) {
3595
12.6k
  xmlSchemaComponentListFree(bucket->globals);
3596
12.6k
  xmlSchemaItemListFree(bucket->globals);
3597
12.6k
    }
3598
12.6k
    if (bucket->locals != NULL) {
3599
12.6k
  xmlSchemaComponentListFree(bucket->locals);
3600
12.6k
  xmlSchemaItemListFree(bucket->locals);
3601
12.6k
    }
3602
12.6k
    if (bucket->relations != NULL) {
3603
457
  xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3604
4.70k
  do {
3605
4.70k
      prev = cur;
3606
4.70k
      cur = cur->next;
3607
4.70k
      xmlFree(prev);
3608
4.70k
  } while (cur != NULL);
3609
457
    }
3610
12.6k
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3611
12.6k
  xmlFreeDoc(bucket->doc);
3612
12.6k
    }
3613
12.6k
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3614
159
  if (WXS_IMPBUCKET(bucket)->schema != NULL)
3615
159
      xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3616
159
    }
3617
12.6k
    xmlFree(bucket);
3618
12.6k
}
3619
3620
static void
3621
xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3622
12.5k
{
3623
12.5k
    xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3624
12.5k
}
3625
3626
static xmlSchemaBucketPtr
3627
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3628
       int type, const xmlChar *targetNamespace)
3629
12.6k
{
3630
12.6k
    xmlSchemaBucketPtr ret;
3631
12.6k
    int size;
3632
12.6k
    xmlSchemaPtr mainSchema;
3633
3634
12.6k
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3635
0
  PERROR_INT("xmlSchemaBucketCreate",
3636
0
      "no main schema on constructor");
3637
0
  return(NULL);
3638
0
    }
3639
12.6k
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3640
    /* Create the schema bucket. */
3641
12.6k
    if (WXS_IS_BUCKET_INCREDEF(type))
3642
107
  size = sizeof(xmlSchemaInclude);
3643
12.5k
    else
3644
12.5k
  size = sizeof(xmlSchemaImport);
3645
12.6k
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3646
12.6k
    if (ret == NULL) {
3647
0
  xmlSchemaPErrMemory(NULL);
3648
0
  return(NULL);
3649
0
    }
3650
12.6k
    memset(ret, 0, size);
3651
12.6k
    ret->targetNamespace = targetNamespace;
3652
12.6k
    ret->type = type;
3653
12.6k
    ret->globals = xmlSchemaItemListCreate();
3654
12.6k
    if (ret->globals == NULL) {
3655
0
  xmlSchemaBucketFree(ret);
3656
0
  return(NULL);
3657
0
    }
3658
12.6k
    ret->locals = xmlSchemaItemListCreate();
3659
12.6k
    if (ret->locals == NULL) {
3660
0
  xmlSchemaBucketFree(ret);
3661
0
  return(NULL);
3662
0
    }
3663
    /*
3664
    * The following will assure that only the first bucket is marked as
3665
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3666
    * For each following import buckets an xmlSchema will be created.
3667
    * An xmlSchema will be created for every distinct targetNamespace.
3668
    * We assign the targetNamespace to the schemata here.
3669
    */
3670
12.6k
    if (! WXS_HAS_BUCKETS(pctxt)) {
3671
12.4k
  if (WXS_IS_BUCKET_INCREDEF(type)) {
3672
0
      PERROR_INT("xmlSchemaBucketCreate",
3673
0
    "first bucket but it's an include or redefine");
3674
0
      xmlSchemaBucketFree(ret);
3675
0
      return(NULL);
3676
0
  }
3677
  /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3678
12.4k
  ret->type = XML_SCHEMA_SCHEMA_MAIN;
3679
  /* Point to the *main* schema. */
3680
12.4k
  WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3681
12.4k
  WXS_IMPBUCKET(ret)->schema = mainSchema;
3682
  /*
3683
  * Ensure that the main schema gets a targetNamespace.
3684
  */
3685
12.4k
  mainSchema->targetNamespace = targetNamespace;
3686
12.4k
    } else {
3687
266
  if (type == XML_SCHEMA_SCHEMA_MAIN) {
3688
0
      PERROR_INT("xmlSchemaBucketCreate",
3689
0
    "main bucket but it's not the first one");
3690
0
      xmlSchemaBucketFree(ret);
3691
0
      return(NULL);
3692
266
  } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3693
      /*
3694
      * Create a schema for imports and assign the
3695
      * targetNamespace.
3696
      */
3697
159
      WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3698
159
      if (WXS_IMPBUCKET(ret)->schema == NULL) {
3699
0
    xmlSchemaBucketFree(ret);
3700
0
    return(NULL);
3701
0
      }
3702
159
      WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3703
159
  }
3704
266
    }
3705
12.6k
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3706
12.5k
  int res;
3707
  /*
3708
  * Imports go into the "schemasImports" slot of the main *schema*.
3709
  * Note that we create an import entry for the main schema as well; i.e.,
3710
  * even if there's only one schema, we'll get an import.
3711
  */
3712
12.5k
  if (mainSchema->schemasImports == NULL) {
3713
12.4k
      mainSchema->schemasImports = xmlHashCreateDict(5,
3714
12.4k
    WXS_CONSTRUCTOR(pctxt)->dict);
3715
12.4k
      if (mainSchema->schemasImports == NULL) {
3716
0
    xmlSchemaBucketFree(ret);
3717
0
    return(NULL);
3718
0
      }
3719
12.4k
  }
3720
12.5k
  if (targetNamespace == NULL)
3721
11.4k
      res = xmlHashAddEntry(mainSchema->schemasImports,
3722
11.4k
    XML_SCHEMAS_NO_NAMESPACE, ret);
3723
1.10k
  else
3724
1.10k
      res = xmlHashAddEntry(mainSchema->schemasImports,
3725
1.10k
    targetNamespace, ret);
3726
12.5k
  if (res != 0) {
3727
2
      PERROR_INT("xmlSchemaBucketCreate",
3728
2
    "failed to add the schema bucket to the hash");
3729
2
      xmlSchemaBucketFree(ret);
3730
2
      return(NULL);
3731
2
  }
3732
12.5k
    } else {
3733
  /* Set the @ownerImport of an include bucket. */
3734
107
  if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3735
106
      WXS_INCBUCKET(ret)->ownerImport =
3736
106
    WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3737
1
  else
3738
1
      WXS_INCBUCKET(ret)->ownerImport =
3739
1
    WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3740
3741
  /* Includes got into the "includes" slot of the *main* schema. */
3742
107
  if (mainSchema->includes == NULL) {
3743
69
      mainSchema->includes = xmlSchemaItemListCreate();
3744
69
      if (mainSchema->includes == NULL) {
3745
0
    xmlSchemaBucketFree(ret);
3746
0
    return(NULL);
3747
0
      }
3748
69
  }
3749
107
  if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
3750
0
      xmlSchemaBucketFree(ret);
3751
0
      return(NULL);
3752
0
        }
3753
107
    }
3754
    /*
3755
    * Add to list of all buckets; this is used for lookup
3756
    * during schema construction time only.
3757
    */
3758
12.6k
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3759
0
  return(NULL);
3760
12.6k
    return(ret);
3761
12.6k
}
3762
3763
static int
3764
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3765
245k
{
3766
245k
    if (*list == NULL) {
3767
0
  *list = xmlSchemaItemListCreate();
3768
0
  if (*list == NULL)
3769
0
      return(-1);
3770
0
    }
3771
245k
    return(xmlSchemaItemListAddSize(*list, initialSize, item));
3772
245k
}
3773
3774
/**
3775
 * xmlSchemaFreeAnnot:
3776
 * @annot:  a schema type structure
3777
 *
3778
 * Deallocate a annotation structure
3779
 */
3780
static void
3781
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3782
4.25k
{
3783
4.25k
    if (annot == NULL)
3784
0
        return;
3785
4.25k
    if (annot->next == NULL) {
3786
4.19k
  xmlFree(annot);
3787
4.19k
    } else {
3788
60
  xmlSchemaAnnotPtr prev;
3789
3790
120
  do {
3791
120
      prev = annot;
3792
120
      annot = annot->next;
3793
120
      xmlFree(prev);
3794
120
  } while (annot != NULL);
3795
60
    }
3796
4.25k
}
3797
3798
/**
3799
 * xmlSchemaFreeNotation:
3800
 * @schema:  a schema notation structure
3801
 *
3802
 * Deallocate a Schema Notation structure.
3803
 */
3804
static void
3805
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3806
1.43k
{
3807
1.43k
    if (nota == NULL)
3808
0
        return;
3809
1.43k
    if (nota->annot != NULL)
3810
312
  xmlSchemaFreeAnnot(nota->annot);
3811
1.43k
    xmlFree(nota);
3812
1.43k
}
3813
3814
/**
3815
 * xmlSchemaFreeAttribute:
3816
 * @attr:  an attribute declaration
3817
 *
3818
 * Deallocates an attribute declaration structure.
3819
 */
3820
static void
3821
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3822
5.57k
{
3823
5.57k
    if (attr == NULL)
3824
0
        return;
3825
5.57k
    if (attr->annot != NULL)
3826
99
  xmlSchemaFreeAnnot(attr->annot);
3827
5.57k
    if (attr->defVal != NULL)
3828
44
  xmlSchemaFreeValue(attr->defVal);
3829
5.57k
    xmlFree(attr);
3830
5.57k
}
3831
3832
/**
3833
 * xmlSchemaFreeAttributeUse:
3834
 * @use:  an attribute use
3835
 *
3836
 * Deallocates an attribute use structure.
3837
 */
3838
static void
3839
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3840
4.46k
{
3841
4.46k
    if (use == NULL)
3842
0
        return;
3843
4.46k
    if (use->annot != NULL)
3844
85
  xmlSchemaFreeAnnot(use->annot);
3845
4.46k
    if (use->defVal != NULL)
3846
0
  xmlSchemaFreeValue(use->defVal);
3847
4.46k
    xmlFree(use);
3848
4.46k
}
3849
3850
/**
3851
 * xmlSchemaFreeAttributeUseProhib:
3852
 * @prohib:  an attribute use prohibition
3853
 *
3854
 * Deallocates an attribute use structure.
3855
 */
3856
static void
3857
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3858
431
{
3859
431
    if (prohib == NULL)
3860
0
        return;
3861
431
    xmlFree(prohib);
3862
431
}
3863
3864
/**
3865
 * xmlSchemaFreeWildcardNsSet:
3866
 * set:  a schema wildcard namespace
3867
 *
3868
 * Deallocates a list of wildcard constraint structures.
3869
 */
3870
static void
3871
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3872
3.86k
{
3873
3.86k
    xmlSchemaWildcardNsPtr next;
3874
3875
44.3k
    while (set != NULL) {
3876
40.4k
  next = set->next;
3877
40.4k
  xmlFree(set);
3878
40.4k
  set = next;
3879
40.4k
    }
3880
3.86k
}
3881
3882
/**
3883
 * xmlSchemaFreeWildcard:
3884
 * @wildcard:  a wildcard structure
3885
 *
3886
 * Deallocates a wildcard structure.
3887
 */
3888
void
3889
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3890
8.72k
{
3891
8.72k
    if (wildcard == NULL)
3892
0
        return;
3893
8.72k
    if (wildcard->annot != NULL)
3894
0
        xmlSchemaFreeAnnot(wildcard->annot);
3895
8.72k
    if (wildcard->nsSet != NULL)
3896
3.77k
  xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3897
8.72k
    if (wildcard->negNsSet != NULL)
3898
1.11k
  xmlFree(wildcard->negNsSet);
3899
8.72k
    xmlFree(wildcard);
3900
8.72k
}
3901
3902
/**
3903
 * xmlSchemaFreeAttributeGroup:
3904
 * @schema:  a schema attribute group structure
3905
 *
3906
 * Deallocate a Schema Attribute Group structure.
3907
 */
3908
static void
3909
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3910
2.35k
{
3911
2.35k
    if (attrGr == NULL)
3912
0
        return;
3913
2.35k
    if (attrGr->annot != NULL)
3914
1
        xmlSchemaFreeAnnot(attrGr->annot);
3915
2.35k
    if (attrGr->attrUses != NULL)
3916
285
  xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3917
2.35k
    xmlFree(attrGr);
3918
2.35k
}
3919
3920
/**
3921
 * xmlSchemaFreeQNameRef:
3922
 * @item: a QName reference structure
3923
 *
3924
 * Deallocatea a QName reference structure.
3925
 */
3926
static void
3927
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3928
59.6k
{
3929
59.6k
    xmlFree(item);
3930
59.6k
}
3931
3932
/**
3933
 * xmlSchemaFreeTypeLinkList:
3934
 * @alink: a type link
3935
 *
3936
 * Deallocate a list of types.
3937
 */
3938
static void
3939
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3940
2.28k
{
3941
2.28k
    xmlSchemaTypeLinkPtr next;
3942
3943
48.0k
    while (link != NULL) {
3944
45.7k
  next = link->next;
3945
45.7k
  xmlFree(link);
3946
45.7k
  link = next;
3947
45.7k
    }
3948
2.28k
}
3949
3950
static void
3951
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3952
0
{
3953
0
    xmlSchemaIDCStateObjPtr next;
3954
0
    while (sto != NULL) {
3955
0
  next = sto->next;
3956
0
  if (sto->history != NULL)
3957
0
      xmlFree(sto->history);
3958
0
  if (sto->xpathCtxt != NULL)
3959
0
      xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3960
0
  xmlFree(sto);
3961
0
  sto = next;
3962
0
    }
3963
0
}
3964
3965
/**
3966
 * xmlSchemaFreeIDC:
3967
 * @idc: a identity-constraint definition
3968
 *
3969
 * Deallocates an identity-constraint definition.
3970
 */
3971
static void
3972
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3973
3.62k
{
3974
3.62k
    xmlSchemaIDCSelectPtr cur, prev;
3975
3976
3.62k
    if (idcDef == NULL)
3977
0
  return;
3978
3.62k
    if (idcDef->annot != NULL)
3979
54
        xmlSchemaFreeAnnot(idcDef->annot);
3980
    /* Selector */
3981
3.62k
    if (idcDef->selector != NULL) {
3982
2.11k
  if (idcDef->selector->xpathComp != NULL)
3983
339
      xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3984
2.11k
  xmlFree(idcDef->selector);
3985
2.11k
    }
3986
    /* Fields */
3987
3.62k
    if (idcDef->fields != NULL) {
3988
1.30k
  cur = idcDef->fields;
3989
21.9k
  do {
3990
21.9k
      prev = cur;
3991
21.9k
      cur = cur->next;
3992
21.9k
      if (prev->xpathComp != NULL)
3993
2.44k
    xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3994
21.9k
      xmlFree(prev);
3995
21.9k
  } while (cur != NULL);
3996
1.30k
    }
3997
3.62k
    xmlFree(idcDef);
3998
3.62k
}
3999
4000
/**
4001
 * xmlSchemaFreeElement:
4002
 * @schema:  a schema element structure
4003
 *
4004
 * Deallocate a Schema Element structure.
4005
 */
4006
static void
4007
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
4008
23.6k
{
4009
23.6k
    if (elem == NULL)
4010
0
        return;
4011
23.6k
    if (elem->annot != NULL)
4012
131
        xmlSchemaFreeAnnot(elem->annot);
4013
23.6k
    if (elem->contModel != NULL)
4014
0
        xmlRegFreeRegexp(elem->contModel);
4015
23.6k
    if (elem->defVal != NULL)
4016
383
  xmlSchemaFreeValue(elem->defVal);
4017
23.6k
    xmlFree(elem);
4018
23.6k
}
4019
4020
/**
4021
 * xmlSchemaFreeFacet:
4022
 * @facet:  a schema facet structure
4023
 *
4024
 * Deallocate a Schema Facet structure.
4025
 */
4026
void
4027
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4028
128k
{
4029
128k
    if (facet == NULL)
4030
0
        return;
4031
128k
    if (facet->val != NULL)
4032
25.9k
        xmlSchemaFreeValue(facet->val);
4033
128k
    if (facet->regexp != NULL)
4034
7.28k
        xmlRegFreeRegexp(facet->regexp);
4035
128k
    if (facet->annot != NULL)
4036
86
        xmlSchemaFreeAnnot(facet->annot);
4037
128k
    xmlFree(facet);
4038
128k
}
4039
4040
/**
4041
 * xmlSchemaFreeType:
4042
 * @type:  a schema type structure
4043
 *
4044
 * Deallocate a Schema Type structure.
4045
 */
4046
void
4047
xmlSchemaFreeType(xmlSchemaTypePtr type)
4048
27.1k
{
4049
27.1k
    if (type == NULL)
4050
0
        return;
4051
27.1k
    if (type->annot != NULL)
4052
531
        xmlSchemaFreeAnnot(type->annot);
4053
27.1k
    if (type->facets != NULL) {
4054
9.11k
        xmlSchemaFacetPtr facet, next;
4055
4056
9.11k
        facet = type->facets;
4057
137k
        while (facet != NULL) {
4058
128k
            next = facet->next;
4059
128k
            xmlSchemaFreeFacet(facet);
4060
128k
            facet = next;
4061
128k
        }
4062
9.11k
    }
4063
27.1k
    if (type->attrUses != NULL)
4064
2.06k
  xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4065
27.1k
    if (type->memberTypes != NULL)
4066
2.28k
  xmlSchemaFreeTypeLinkList(type->memberTypes);
4067
27.1k
    if (type->facetSet != NULL) {
4068
9.14k
  xmlSchemaFacetLinkPtr next, link;
4069
4070
9.14k
  link = type->facetSet;
4071
129k
  do {
4072
129k
      next = link->next;
4073
129k
      xmlFree(link);
4074
129k
      link = next;
4075
129k
  } while (link != NULL);
4076
9.14k
    }
4077
27.1k
    if (type->contModel != NULL)
4078
616
        xmlRegFreeRegexp(type->contModel);
4079
27.1k
    xmlFree(type);
4080
27.1k
}
4081
4082
/**
4083
 * xmlSchemaFreeModelGroupDef:
4084
 * @item:  a schema model group definition
4085
 *
4086
 * Deallocates a schema model group definition.
4087
 */
4088
static void
4089
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4090
2.52k
{
4091
2.52k
    if (item->annot != NULL)
4092
33
  xmlSchemaFreeAnnot(item->annot);
4093
2.52k
    xmlFree(item);
4094
2.52k
}
4095
4096
/**
4097
 * xmlSchemaFreeModelGroup:
4098
 * @item:  a schema model group
4099
 *
4100
 * Deallocates a schema model group structure.
4101
 */
4102
static void
4103
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4104
5.54k
{
4105
5.54k
    if (item->annot != NULL)
4106
78
  xmlSchemaFreeAnnot(item->annot);
4107
5.54k
    xmlFree(item);
4108
5.54k
}
4109
4110
static void
4111
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4112
25.3k
{
4113
25.3k
    if ((list == NULL) || (list->nbItems == 0))
4114
8.94k
  return;
4115
16.4k
    {
4116
16.4k
  xmlSchemaTreeItemPtr item;
4117
16.4k
  xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4118
16.4k
  int i;
4119
4120
182k
  for (i = 0; i < list->nbItems; i++) {
4121
166k
      item = items[i];
4122
166k
      if (item == NULL)
4123
0
    continue;
4124
166k
      switch (item->type) {
4125
14.4k
    case XML_SCHEMA_TYPE_SIMPLE:
4126
27.1k
    case XML_SCHEMA_TYPE_COMPLEX:
4127
27.1k
        xmlSchemaFreeType((xmlSchemaTypePtr) item);
4128
27.1k
        break;
4129
5.57k
    case XML_SCHEMA_TYPE_ATTRIBUTE:
4130
5.57k
        xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4131
5.57k
        break;
4132
4.46k
    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4133
4.46k
        xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4134
4.46k
        break;
4135
431
    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4136
431
        xmlSchemaFreeAttributeUseProhib(
4137
431
      (xmlSchemaAttributeUseProhibPtr) item);
4138
431
        break;
4139
23.6k
    case XML_SCHEMA_TYPE_ELEMENT:
4140
23.6k
        xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4141
23.6k
        break;
4142
21.1k
    case XML_SCHEMA_TYPE_PARTICLE:
4143
21.1k
        if (item->annot != NULL)
4144
11
      xmlSchemaFreeAnnot(item->annot);
4145
21.1k
        xmlFree(item);
4146
21.1k
        break;
4147
2.86k
    case XML_SCHEMA_TYPE_SEQUENCE:
4148
5.40k
    case XML_SCHEMA_TYPE_CHOICE:
4149
5.54k
    case XML_SCHEMA_TYPE_ALL:
4150
5.54k
        xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4151
5.54k
        break;
4152
2.35k
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4153
2.35k
        xmlSchemaFreeAttributeGroup(
4154
2.35k
      (xmlSchemaAttributeGroupPtr) item);
4155
2.35k
        break;
4156
2.52k
    case XML_SCHEMA_TYPE_GROUP:
4157
2.52k
        xmlSchemaFreeModelGroupDef(
4158
2.52k
      (xmlSchemaModelGroupDefPtr) item);
4159
2.52k
        break;
4160
6.27k
    case XML_SCHEMA_TYPE_ANY:
4161
8.72k
    case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4162
8.72k
        xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4163
8.72k
        break;
4164
24
    case XML_SCHEMA_TYPE_IDC_KEY:
4165
49
    case XML_SCHEMA_TYPE_IDC_UNIQUE:
4166
3.62k
    case XML_SCHEMA_TYPE_IDC_KEYREF:
4167
3.62k
        xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4168
3.62k
        break;
4169
1.43k
    case XML_SCHEMA_TYPE_NOTATION:
4170
1.43k
        xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4171
1.43k
        break;
4172
59.6k
    case XML_SCHEMA_EXTRA_QNAMEREF:
4173
59.6k
        xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4174
59.6k
        break;
4175
0
    default:
4176
        /* TODO: This should never be hit. */
4177
0
        break;
4178
166k
      }
4179
166k
  }
4180
16.4k
  list->nbItems = 0;
4181
16.4k
    }
4182
16.4k
}
4183
4184
/**
4185
 * xmlSchemaFree:
4186
 * @schema:  a schema structure
4187
 *
4188
 * Deallocate a Schema structure.
4189
 */
4190
void
4191
xmlSchemaFree(xmlSchemaPtr schema)
4192
55.2k
{
4193
55.2k
    if (schema == NULL)
4194
26.0k
        return;
4195
    /*
4196
    * Note that those slots are not responsible for freeing
4197
    * schema components anymore; this will now be done by
4198
    * the schema buckets.
4199
    */
4200
29.2k
    if (schema->notaDecl != NULL)
4201
0
        xmlHashFree(schema->notaDecl, NULL);
4202
29.2k
    if (schema->attrDecl != NULL)
4203
369
        xmlHashFree(schema->attrDecl, NULL);
4204
29.2k
    if (schema->attrgrpDecl != NULL)
4205
235
        xmlHashFree(schema->attrgrpDecl, NULL);
4206
29.2k
    if (schema->elemDecl != NULL)
4207
2.30k
        xmlHashFree(schema->elemDecl, NULL);
4208
29.2k
    if (schema->typeDecl != NULL)
4209
5.72k
        xmlHashFree(schema->typeDecl, NULL);
4210
29.2k
    if (schema->groupDecl != NULL)
4211
158
        xmlHashFree(schema->groupDecl, NULL);
4212
29.2k
    if (schema->idcDef != NULL)
4213
12
        xmlHashFree(schema->idcDef, NULL);
4214
4215
29.2k
    if (schema->schemasImports != NULL)
4216
12.4k
  xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4217
29.2k
    if (schema->includes != NULL) {
4218
69
  xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4219
69
  int i;
4220
176
  for (i = 0; i < list->nbItems; i++) {
4221
107
      xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4222
107
  }
4223
69
  xmlSchemaItemListFree(list);
4224
69
    }
4225
29.2k
    if (schema->annot != NULL)
4226
830
        xmlSchemaFreeAnnot(schema->annot);
4227
    /* Never free the doc here, since this will be done by the buckets. */
4228
4229
29.2k
    xmlDictFree(schema->dict);
4230
29.2k
    xmlFree(schema);
4231
29.2k
}
4232
4233
/************************************************************************
4234
 *                  *
4235
 *      Debug functions         *
4236
 *                  *
4237
 ************************************************************************/
4238
4239
#ifdef LIBXML_OUTPUT_ENABLED
4240
4241
static void
4242
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4243
4244
/**
4245
 * xmlSchemaElementDump:
4246
 * @elem:  an element
4247
 * @output:  the file output
4248
 *
4249
 * Dump the element
4250
 */
4251
static void
4252
xmlSchemaElementDump(void *payload, void *data,
4253
                     const xmlChar * name ATTRIBUTE_UNUSED,
4254
         const xmlChar * namespace ATTRIBUTE_UNUSED,
4255
                     const xmlChar * context ATTRIBUTE_UNUSED)
4256
0
{
4257
0
    xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4258
0
    FILE *output = (FILE *) data;
4259
0
    if (elem == NULL)
4260
0
        return;
4261
4262
4263
0
    fprintf(output, "Element");
4264
0
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4265
0
  fprintf(output, " (global)");
4266
0
    fprintf(output, ": '%s' ", elem->name);
4267
0
    if (namespace != NULL)
4268
0
  fprintf(output, "ns '%s'", namespace);
4269
0
    fprintf(output, "\n");
4270
#if 0
4271
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4272
  fprintf(output, "  min %d ", elem->minOccurs);
4273
        if (elem->maxOccurs >= UNBOUNDED)
4274
            fprintf(output, "max: unbounded\n");
4275
        else if (elem->maxOccurs != 1)
4276
            fprintf(output, "max: %d\n", elem->maxOccurs);
4277
        else
4278
            fprintf(output, "\n");
4279
    }
4280
#endif
4281
    /*
4282
    * Misc other properties.
4283
    */
4284
0
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4285
0
  (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4286
0
  (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4287
0
  (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4288
0
  fprintf(output, "  props: ");
4289
0
  if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4290
0
      fprintf(output, "[fixed] ");
4291
0
  if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4292
0
      fprintf(output, "[default] ");
4293
0
  if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4294
0
      fprintf(output, "[abstract] ");
4295
0
  if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4296
0
      fprintf(output, "[nillable] ");
4297
0
  fprintf(output, "\n");
4298
0
    }
4299
    /*
4300
    * Default/fixed value.
4301
    */
4302
0
    if (elem->value != NULL)
4303
0
  fprintf(output, "  value: '%s'\n", elem->value);
4304
    /*
4305
    * Type.
4306
    */
4307
0
    if (elem->namedType != NULL) {
4308
0
  fprintf(output, "  type: '%s' ", elem->namedType);
4309
0
  if (elem->namedTypeNs != NULL)
4310
0
      fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4311
0
  else
4312
0
      fprintf(output, "\n");
4313
0
    } else if (elem->subtypes != NULL) {
4314
  /*
4315
  * Dump local types.
4316
  */
4317
0
  xmlSchemaTypeDump(elem->subtypes, output);
4318
0
    }
4319
    /*
4320
    * Substitution group.
4321
    */
4322
0
    if (elem->substGroup != NULL) {
4323
0
  fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4324
0
  if (elem->substGroupNs != NULL)
4325
0
      fprintf(output, "ns '%s'\n", elem->substGroupNs);
4326
0
  else
4327
0
      fprintf(output, "\n");
4328
0
    }
4329
0
}
4330
4331
/**
4332
 * xmlSchemaAnnotDump:
4333
 * @output:  the file output
4334
 * @annot:  a annotation
4335
 *
4336
 * Dump the annotation
4337
 */
4338
static void
4339
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4340
0
{
4341
0
    xmlChar *content;
4342
4343
0
    if (annot == NULL)
4344
0
        return;
4345
4346
0
    content = xmlNodeGetContent(annot->content);
4347
0
    if (content != NULL) {
4348
0
        fprintf(output, "  Annot: %s\n", content);
4349
0
        xmlFree(content);
4350
0
    } else
4351
0
        fprintf(output, "  Annot: empty\n");
4352
0
}
4353
4354
/**
4355
 * xmlSchemaContentModelDump:
4356
 * @particle: the schema particle
4357
 * @output: the file output
4358
 * @depth: the depth used for indentation
4359
 *
4360
 * Dump a SchemaType structure
4361
 */
4362
static void
4363
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4364
0
{
4365
0
    xmlChar *str = NULL;
4366
0
    xmlSchemaTreeItemPtr term;
4367
0
    char shift[100];
4368
0
    int i;
4369
4370
0
    if (particle == NULL)
4371
0
  return;
4372
0
    for (i = 0;((i < depth) && (i < 25));i++)
4373
0
        shift[2 * i] = shift[2 * i + 1] = ' ';
4374
0
    shift[2 * i] = shift[2 * i + 1] = 0;
4375
0
    fprintf(output, "%s", shift);
4376
0
    if (particle->children == NULL) {
4377
0
  fprintf(output, "MISSING particle term\n");
4378
0
  return;
4379
0
    }
4380
0
    term = particle->children;
4381
0
    if (term == NULL) {
4382
0
  fprintf(output, "(NULL)");
4383
0
    } else {
4384
0
  switch (term->type) {
4385
0
      case XML_SCHEMA_TYPE_ELEMENT:
4386
0
    fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4387
0
        ((xmlSchemaElementPtr)term)->targetNamespace,
4388
0
        ((xmlSchemaElementPtr)term)->name));
4389
0
    FREE_AND_NULL(str);
4390
0
    break;
4391
0
      case XML_SCHEMA_TYPE_SEQUENCE:
4392
0
    fprintf(output, "SEQUENCE");
4393
0
    break;
4394
0
      case XML_SCHEMA_TYPE_CHOICE:
4395
0
    fprintf(output, "CHOICE");
4396
0
    break;
4397
0
      case XML_SCHEMA_TYPE_ALL:
4398
0
    fprintf(output, "ALL");
4399
0
    break;
4400
0
      case XML_SCHEMA_TYPE_ANY:
4401
0
    fprintf(output, "ANY");
4402
0
    break;
4403
0
      default:
4404
0
    fprintf(output, "UNKNOWN\n");
4405
0
    return;
4406
0
  }
4407
0
    }
4408
0
    if (particle->minOccurs != 1)
4409
0
  fprintf(output, " min: %d", particle->minOccurs);
4410
0
    if (particle->maxOccurs >= UNBOUNDED)
4411
0
  fprintf(output, " max: unbounded");
4412
0
    else if (particle->maxOccurs != 1)
4413
0
  fprintf(output, " max: %d", particle->maxOccurs);
4414
0
    fprintf(output, "\n");
4415
0
    if (term &&
4416
0
  ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4417
0
   (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4418
0
   (term->type == XML_SCHEMA_TYPE_ALL)) &&
4419
0
   (term->children != NULL)) {
4420
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4421
0
      output, depth +1);
4422
0
    }
4423
0
    if (particle->next != NULL)
4424
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4425
0
    output, depth);
4426
0
}
4427
4428
/**
4429
 * xmlSchemaAttrUsesDump:
4430
 * @uses:  attribute uses list
4431
 * @output:  the file output
4432
 *
4433
 * Dumps a list of attribute use components.
4434
 */
4435
static void
4436
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4437
0
{
4438
0
    xmlSchemaAttributeUsePtr use;
4439
0
    xmlSchemaAttributeUseProhibPtr prohib;
4440
0
    xmlSchemaQNameRefPtr ref;
4441
0
    const xmlChar *name, *tns;
4442
0
    xmlChar *str = NULL;
4443
0
    int i;
4444
4445
0
    if ((uses == NULL) || (uses->nbItems == 0))
4446
0
        return;
4447
4448
0
    fprintf(output, "  attributes:\n");
4449
0
    for (i = 0; i < uses->nbItems; i++) {
4450
0
  use = uses->items[i];
4451
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4452
0
      fprintf(output, "  [prohibition] ");
4453
0
      prohib = (xmlSchemaAttributeUseProhibPtr) use;
4454
0
      name = prohib->name;
4455
0
      tns = prohib->targetNamespace;
4456
0
  } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4457
0
      fprintf(output, "  [reference] ");
4458
0
      ref = (xmlSchemaQNameRefPtr) use;
4459
0
      name = ref->name;
4460
0
      tns = ref->targetNamespace;
4461
0
  } else {
4462
0
      fprintf(output, "  [use] ");
4463
0
      name = WXS_ATTRUSE_DECL_NAME(use);
4464
0
      tns = WXS_ATTRUSE_DECL_TNS(use);
4465
0
  }
4466
0
  fprintf(output, "'%s'\n",
4467
0
      (const char *) xmlSchemaFormatQName(&str, tns, name));
4468
0
  FREE_AND_NULL(str);
4469
0
    }
4470
0
}
4471
4472
/**
4473
 * xmlSchemaTypeDump:
4474
 * @output:  the file output
4475
 * @type:  a type structure
4476
 *
4477
 * Dump a SchemaType structure
4478
 */
4479
static void
4480
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4481
0
{
4482
0
    if (type == NULL) {
4483
0
        fprintf(output, "Type: NULL\n");
4484
0
        return;
4485
0
    }
4486
0
    fprintf(output, "Type: ");
4487
0
    if (type->name != NULL)
4488
0
        fprintf(output, "'%s' ", type->name);
4489
0
    else
4490
0
        fprintf(output, "(no name) ");
4491
0
    if (type->targetNamespace != NULL)
4492
0
  fprintf(output, "ns '%s' ", type->targetNamespace);
4493
0
    switch (type->type) {
4494
0
        case XML_SCHEMA_TYPE_BASIC:
4495
0
            fprintf(output, "[basic] ");
4496
0
            break;
4497
0
        case XML_SCHEMA_TYPE_SIMPLE:
4498
0
            fprintf(output, "[simple] ");
4499
0
            break;
4500
0
        case XML_SCHEMA_TYPE_COMPLEX:
4501
0
            fprintf(output, "[complex] ");
4502
0
            break;
4503
0
        case XML_SCHEMA_TYPE_SEQUENCE:
4504
0
            fprintf(output, "[sequence] ");
4505
0
            break;
4506
0
        case XML_SCHEMA_TYPE_CHOICE:
4507
0
            fprintf(output, "[choice] ");
4508
0
            break;
4509
0
        case XML_SCHEMA_TYPE_ALL:
4510
0
            fprintf(output, "[all] ");
4511
0
            break;
4512
0
        case XML_SCHEMA_TYPE_UR:
4513
0
            fprintf(output, "[ur] ");
4514
0
            break;
4515
0
        case XML_SCHEMA_TYPE_RESTRICTION:
4516
0
            fprintf(output, "[restriction] ");
4517
0
            break;
4518
0
        case XML_SCHEMA_TYPE_EXTENSION:
4519
0
            fprintf(output, "[extension] ");
4520
0
            break;
4521
0
        default:
4522
0
            fprintf(output, "[unknown type %d] ", type->type);
4523
0
            break;
4524
0
    }
4525
0
    fprintf(output, "content: ");
4526
0
    switch (type->contentType) {
4527
0
        case XML_SCHEMA_CONTENT_UNKNOWN:
4528
0
            fprintf(output, "[unknown] ");
4529
0
            break;
4530
0
        case XML_SCHEMA_CONTENT_EMPTY:
4531
0
            fprintf(output, "[empty] ");
4532
0
            break;
4533
0
        case XML_SCHEMA_CONTENT_ELEMENTS:
4534
0
            fprintf(output, "[element] ");
4535
0
            break;
4536
0
        case XML_SCHEMA_CONTENT_MIXED:
4537
0
            fprintf(output, "[mixed] ");
4538
0
            break;
4539
0
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4540
  /* not used. */
4541
0
            break;
4542
0
        case XML_SCHEMA_CONTENT_BASIC:
4543
0
            fprintf(output, "[basic] ");
4544
0
            break;
4545
0
        case XML_SCHEMA_CONTENT_SIMPLE:
4546
0
            fprintf(output, "[simple] ");
4547
0
            break;
4548
0
        case XML_SCHEMA_CONTENT_ANY:
4549
0
            fprintf(output, "[any] ");
4550
0
            break;
4551
0
    }
4552
0
    fprintf(output, "\n");
4553
0
    if (type->base != NULL) {
4554
0
        fprintf(output, "  base type: '%s'", type->base);
4555
0
  if (type->baseNs != NULL)
4556
0
      fprintf(output, " ns '%s'\n", type->baseNs);
4557
0
  else
4558
0
      fprintf(output, "\n");
4559
0
    }
4560
0
    if (type->attrUses != NULL)
4561
0
  xmlSchemaAttrUsesDump(type->attrUses, output);
4562
0
    if (type->annot != NULL)
4563
0
        xmlSchemaAnnotDump(output, type->annot);
4564
0
#ifdef DUMP_CONTENT_MODEL
4565
0
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4566
0
  (type->subtypes != NULL)) {
4567
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4568
0
      output, 1);
4569
0
    }
4570
0
#endif
4571
0
}
4572
4573
static void
4574
xmlSchemaTypeDumpEntry(void *type, void *output,
4575
                       const xmlChar *name ATTRIBUTE_UNUSED)
4576
0
{
4577
0
    xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4578
0
}
4579
4580
/**
4581
 * xmlSchemaDump:
4582
 * @output:  the file output
4583
 * @schema:  a schema structure
4584
 *
4585
 * Dump a Schema structure.
4586
 */
4587
void
4588
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4589
0
{
4590
0
    if (output == NULL)
4591
0
        return;
4592
0
    if (schema == NULL) {
4593
0
        fprintf(output, "Schemas: NULL\n");
4594
0
        return;
4595
0
    }
4596
0
    fprintf(output, "Schemas: ");
4597
0
    if (schema->name != NULL)
4598
0
        fprintf(output, "%s, ", schema->name);
4599
0
    else
4600
0
        fprintf(output, "no name, ");
4601
0
    if (schema->targetNamespace != NULL)
4602
0
        fprintf(output, "%s", (const char *) schema->targetNamespace);
4603
0
    else
4604
0
        fprintf(output, "no target namespace");
4605
0
    fprintf(output, "\n");
4606
0
    if (schema->annot != NULL)
4607
0
        xmlSchemaAnnotDump(output, schema->annot);
4608
0
    xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4609
0
    xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4610
0
}
4611
4612
#endif /* LIBXML_OUTPUT_ENABLED */
4613
4614
/************************************************************************
4615
 *                  *
4616
 *      Utilities         *
4617
 *                  *
4618
 ************************************************************************/
4619
4620
/**
4621
 * xmlSchemaGetPropNode:
4622
 * @node: the element node
4623
 * @name: the name of the attribute
4624
 *
4625
 * Seeks an attribute with a name of @name in
4626
 * no namespace.
4627
 *
4628
 * Returns the attribute or NULL if not present.
4629
 */
4630
static xmlAttrPtr
4631
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4632
676k
{
4633
676k
    xmlAttrPtr prop;
4634
4635
676k
    if ((node == NULL) || (name == NULL))
4636
0
  return(NULL);
4637
676k
    prop = node->properties;
4638
1.38M
    while (prop != NULL) {
4639
857k
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4640
145k
      return(prop);
4641
711k
  prop = prop->next;
4642
711k
    }
4643
531k
    return (NULL);
4644
676k
}
4645
4646
/**
4647
 * xmlSchemaGetPropNodeNs:
4648
 * @node: the element node
4649
 * @uri: the uri
4650
 * @name: the name of the attribute
4651
 *
4652
 * Seeks an attribute with a local name of @name and
4653
 * a namespace URI of @uri.
4654
 *
4655
 * Returns the attribute or NULL if not present.
4656
 */
4657
static xmlAttrPtr
4658
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4659
1.03k
{
4660
1.03k
    xmlAttrPtr prop;
4661
4662
1.03k
    if ((node == NULL) || (name == NULL))
4663
0
  return(NULL);
4664
1.03k
    prop = node->properties;
4665
1.84k
    while (prop != NULL) {
4666
1.00k
  if ((prop->ns != NULL) &&
4667
1.00k
      xmlStrEqual(prop->name, BAD_CAST name) &&
4668
1.00k
      xmlStrEqual(prop->ns->href, BAD_CAST uri))
4669
204
      return(prop);
4670
802
  prop = prop->next;
4671
802
    }
4672
834
    return (NULL);
4673
1.03k
}
4674
4675
static const xmlChar *
4676
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4677
149k
{
4678
149k
    xmlChar *val;
4679
149k
    const xmlChar *ret;
4680
4681
149k
    val = xmlNodeGetContent(node);
4682
149k
    if (val == NULL)
4683
3.39k
  val = xmlStrdup((xmlChar *)"");
4684
149k
    ret = xmlDictLookup(ctxt->dict, val, -1);
4685
149k
    xmlFree(val);
4686
149k
    if (ret == NULL)
4687
0
        xmlSchemaPErrMemory(ctxt);
4688
149k
    return(ret);
4689
149k
}
4690
4691
static const xmlChar *
4692
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4693
5.07k
{
4694
5.07k
    return((const xmlChar*) xmlNodeGetContent(node));
4695
5.07k
}
4696
4697
/**
4698
 * xmlSchemaGetProp:
4699
 * @ctxt: the parser context
4700
 * @node: the node
4701
 * @name: the property name
4702
 *
4703
 * Read a attribute value and internalize the string
4704
 *
4705
 * Returns the string or NULL if not present.
4706
 */
4707
static const xmlChar *
4708
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4709
                 const char *name)
4710
286k
{
4711
286k
    xmlChar *val;
4712
286k
    const xmlChar *ret;
4713
4714
286k
    val = xmlGetNoNsProp(node, BAD_CAST name);
4715
286k
    if (val == NULL)
4716
148k
        return(NULL);
4717
138k
    ret = xmlDictLookup(ctxt->dict, val, -1);
4718
138k
    xmlFree(val);
4719
138k
    return(ret);
4720
286k
}
4721
4722
/************************************************************************
4723
 *                  *
4724
 *      Parsing functions       *
4725
 *                  *
4726
 ************************************************************************/
4727
4728
#define WXS_FIND_GLOBAL_ITEM(slot)      \
4729
11.0k
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4730
4.78k
  ret = xmlHashLookup(schema->slot, name); \
4731
4.78k
  if (ret != NULL) goto exit; \
4732
4.78k
    } \
4733
11.0k
    if (xmlHashSize(schema->schemasImports) > 1) { \
4734
456
  xmlSchemaImportPtr import; \
4735
456
  if (nsName == NULL) \
4736
456
      import = xmlHashLookup(schema->schemasImports, \
4737
108
    XML_SCHEMAS_NO_NAMESPACE); \
4738
456
  else \
4739
456
      import = xmlHashLookup(schema->schemasImports, nsName); \
4740
456
  if (import == NULL) \
4741
456
      goto exit; \
4742
456
  ret = xmlHashLookup(import->schema->slot, name); \
4743
414
    }
4744
4745
/**
4746
 * xmlSchemaGetElem:
4747
 * @schema:  the schema context
4748
 * @name:  the element name
4749
 * @ns:  the element namespace
4750
 *
4751
 * Lookup a global element declaration in the schema.
4752
 *
4753
 * Returns the element declaration or NULL if not found.
4754
 */
4755
static xmlSchemaElementPtr
4756
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4757
                 const xmlChar * nsName)
4758
1.13k
{
4759
1.13k
    xmlSchemaElementPtr ret = NULL;
4760
4761
1.13k
    if ((name == NULL) || (schema == NULL))
4762
0
        return(NULL);
4763
1.13k
    if (schema != NULL) {
4764
1.13k
  WXS_FIND_GLOBAL_ITEM(elemDecl)
4765
257
    }
4766
1.13k
exit:
4767
1.13k
    return (ret);
4768
1.13k
}
4769
4770
/**
4771
 * xmlSchemaGetType:
4772
 * @schema:  the main schema
4773
 * @name:  the type's name
4774
 * nsName:  the type's namespace
4775
 *
4776
 * Lookup a type in the schemas or the predefined types
4777
 *
4778
 * Returns the group definition or NULL if not found.
4779
 */
4780
static xmlSchemaTypePtr
4781
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4782
                 const xmlChar * nsName)
4783
20.8k
{
4784
20.8k
    xmlSchemaTypePtr ret = NULL;
4785
4786
20.8k
    if (name == NULL)
4787
0
        return (NULL);
4788
    /* First try the built-in types. */
4789
20.8k
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4790
18.8k
  ret = xmlSchemaGetPredefinedType(name, nsName);
4791
18.8k
  if (ret != NULL)
4792
12.9k
      goto exit;
4793
  /*
4794
  * Note that we try the parsed schemas as well here
4795
  * since one might have parsed the S4S, which contain more
4796
  * than the built-in types.
4797
  * TODO: Can we optimize this?
4798
  */
4799
18.8k
    }
4800
7.87k
    if (schema != NULL) {
4801
7.87k
  WXS_FIND_GLOBAL_ITEM(typeDecl)
4802
6.18k
    }
4803
20.8k
exit:
4804
4805
20.8k
    return (ret);
4806
7.87k
}
4807
4808
/**
4809
 * xmlSchemaGetAttributeDecl:
4810
 * @schema:  the context of the schema
4811
 * @name:  the name of the attribute
4812
 * @ns:  the target namespace of the attribute
4813
 *
4814
 * Lookup a an attribute in the schema or imported schemas
4815
 *
4816
 * Returns the attribute declaration or NULL if not found.
4817
 */
4818
static xmlSchemaAttributePtr
4819
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4820
                 const xmlChar * nsName)
4821
173
{
4822
173
    xmlSchemaAttributePtr ret = NULL;
4823
4824
173
    if ((name == NULL) || (schema == NULL))
4825
0
        return (NULL);
4826
173
    if (schema != NULL) {
4827
173
  WXS_FIND_GLOBAL_ITEM(attrDecl)
4828
97
    }
4829
173
exit:
4830
173
    return (ret);
4831
173
}
4832
4833
/**
4834
 * xmlSchemaGetAttributeGroup:
4835
 * @schema:  the context of the schema
4836
 * @name:  the name of the attribute group
4837
 * @ns:  the target namespace of the attribute group
4838
 *
4839
 * Lookup a an attribute group in the schema or imported schemas
4840
 *
4841
 * Returns the attribute group definition or NULL if not found.
4842
 */
4843
static xmlSchemaAttributeGroupPtr
4844
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4845
                 const xmlChar * nsName)
4846
1.73k
{
4847
1.73k
    xmlSchemaAttributeGroupPtr ret = NULL;
4848
4849
1.73k
    if ((name == NULL) || (schema == NULL))
4850
0
        return (NULL);
4851
1.73k
    if (schema != NULL) {
4852
1.73k
  WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4853
497
    }
4854
1.73k
exit:
4855
    /* TODO:
4856
    if ((ret != NULL) && (ret->redef != NULL)) {
4857
  * Return the last redefinition. *
4858
  ret = ret->redef;
4859
    }
4860
    */
4861
1.73k
    return (ret);
4862
1.73k
}
4863
4864
/**
4865
 * xmlSchemaGetGroup:
4866
 * @schema:  the context of the schema
4867
 * @name:  the name of the group
4868
 * @ns:  the target namespace of the group
4869
 *
4870
 * Lookup a group in the schema or imported schemas
4871
 *
4872
 * Returns the group definition or NULL if not found.
4873
 */
4874
static xmlSchemaModelGroupDefPtr
4875
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4876
                 const xmlChar * nsName)
4877
88
{
4878
88
    xmlSchemaModelGroupDefPtr ret = NULL;
4879
4880
88
    if ((name == NULL) || (schema == NULL))
4881
0
        return (NULL);
4882
88
    if (schema != NULL) {
4883
88
  WXS_FIND_GLOBAL_ITEM(groupDecl)
4884
43
    }
4885
88
exit:
4886
4887
88
    return (ret);
4888
88
}
4889
4890
static xmlSchemaNotationPtr
4891
xmlSchemaGetNotation(xmlSchemaPtr schema,
4892
         const xmlChar *name,
4893
         const xmlChar *nsName)
4894
17
{
4895
17
    xmlSchemaNotationPtr ret = NULL;
4896
4897
17
    if ((name == NULL) || (schema == NULL))
4898
0
        return (NULL);
4899
17
    if (schema != NULL) {
4900
17
  WXS_FIND_GLOBAL_ITEM(notaDecl)
4901
17
    }
4902
17
exit:
4903
17
    return (ret);
4904
17
}
4905
4906
static xmlSchemaIDCPtr
4907
xmlSchemaGetIDC(xmlSchemaPtr schema,
4908
    const xmlChar *name,
4909
    const xmlChar *nsName)
4910
4
{
4911
4
    xmlSchemaIDCPtr ret = NULL;
4912
4913
4
    if ((name == NULL) || (schema == NULL))
4914
0
        return (NULL);
4915
4
    if (schema != NULL) {
4916
4
  WXS_FIND_GLOBAL_ITEM(idcDef)
4917
1
    }
4918
4
exit:
4919
4
    return (ret);
4920
4
}
4921
4922
/**
4923
 * xmlSchemaGetNamedComponent:
4924
 * @schema:  the schema
4925
 * @name:  the name of the group
4926
 * @ns:  the target namespace of the group
4927
 *
4928
 * Lookup a group in the schema or imported schemas
4929
 *
4930
 * Returns the group definition or NULL if not found.
4931
 */
4932
static xmlSchemaBasicItemPtr
4933
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4934
         xmlSchemaTypeType itemType,
4935
         const xmlChar *name,
4936
         const xmlChar *targetNs)
4937
1.12k
{
4938
1.12k
    switch (itemType) {
4939
88
  case XML_SCHEMA_TYPE_GROUP:
4940
88
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4941
88
    name, targetNs));
4942
1.03k
  case XML_SCHEMA_TYPE_ELEMENT:
4943
1.03k
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4944
1.03k
    name, targetNs));
4945
0
  default:
4946
      /* TODO */
4947
0
      return (NULL);
4948
1.12k
    }
4949
1.12k
}
4950
4951
/************************************************************************
4952
 *                  *
4953
 *      Parsing functions       *
4954
 *                  *
4955
 ************************************************************************/
4956
4957
#define IS_BLANK_NODE(n)            \
4958
384k
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4959
4960
/**
4961
 * xmlSchemaIsBlank:
4962
 * @str:  a string
4963
 * @len: the length of the string or -1
4964
 *
4965
 * Check if a string is ignorable
4966
 *
4967
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4968
 */
4969
static int
4970
xmlSchemaIsBlank(xmlChar * str, int len)
4971
384k
{
4972
384k
    if (str == NULL)
4973
0
        return (1);
4974
384k
    if (len < 0) {
4975
1.82M
  while (*str != 0) {
4976
1.52M
      if (!(IS_BLANK_CH(*str)))
4977
93.6k
    return (0);
4978
1.43M
      str++;
4979
1.43M
  }
4980
384k
    } else while ((*str != 0) && (len != 0)) {
4981
0
  if (!(IS_BLANK_CH(*str)))
4982
0
      return (0);
4983
0
  str++;
4984
0
  len--;
4985
0
    }
4986
4987
290k
    return (1);
4988
384k
}
4989
4990
0
#define WXS_COMP_NAME(c, t) ((t) (c))->name
4991
0
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
4992
/*
4993
* xmlSchemaFindRedefCompInGraph:
4994
* ATTENTION TODO: This uses pointer comp. for strings.
4995
*/
4996
static xmlSchemaBasicItemPtr
4997
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
4998
            xmlSchemaTypeType type,
4999
            const xmlChar *name,
5000
            const xmlChar *nsName)
5001
0
{
5002
0
    xmlSchemaBasicItemPtr ret;
5003
0
    int i;
5004
5005
0
    if ((bucket == NULL) || (name == NULL))
5006
0
  return(NULL);
5007
0
    if ((bucket->globals == NULL) ||
5008
0
  (bucket->globals->nbItems == 0))
5009
0
  goto subschemas;
5010
    /*
5011
    * Search in global components.
5012
    */
5013
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
5014
0
  ret = bucket->globals->items[i];
5015
0
  if (ret->type == type) {
5016
0
      switch (type) {
5017
0
    case XML_SCHEMA_TYPE_COMPLEX:
5018
0
    case XML_SCHEMA_TYPE_SIMPLE:
5019
0
        if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5020
0
      (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5021
0
      nsName))
5022
0
        {
5023
0
      return(ret);
5024
0
        }
5025
0
        break;
5026
0
    case XML_SCHEMA_TYPE_GROUP:
5027
0
        if ((WXS_COMP_NAME(ret,
5028
0
          xmlSchemaModelGroupDefPtr) == name) &&
5029
0
      (WXS_COMP_TNS(ret,
5030
0
          xmlSchemaModelGroupDefPtr) == nsName))
5031
0
        {
5032
0
      return(ret);
5033
0
        }
5034
0
        break;
5035
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5036
0
        if ((WXS_COMP_NAME(ret,
5037
0
          xmlSchemaAttributeGroupPtr) == name) &&
5038
0
      (WXS_COMP_TNS(ret,
5039
0
          xmlSchemaAttributeGroupPtr) == nsName))
5040
0
        {
5041
0
      return(ret);
5042
0
        }
5043
0
        break;
5044
0
    default:
5045
        /* Should not be hit. */
5046
0
        return(NULL);
5047
0
      }
5048
0
  }
5049
0
    }
5050
0
subschemas:
5051
    /*
5052
    * Process imported/included schemas.
5053
    */
5054
0
    if (bucket->relations != NULL) {
5055
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
5056
5057
  /*
5058
  * TODO: Marking the bucket will not avoid multiple searches
5059
  * in the same schema, but avoids at least circularity.
5060
  */
5061
0
  bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5062
0
  do {
5063
0
      if ((rel->bucket != NULL) &&
5064
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5065
0
    ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5066
0
        type, name, nsName);
5067
0
    if (ret != NULL)
5068
0
        return(ret);
5069
0
      }
5070
0
      rel = rel->next;
5071
0
  } while (rel != NULL);
5072
0
   bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5073
0
    }
5074
0
    return(NULL);
5075
0
}
5076
5077
/**
5078
 * xmlSchemaAddNotation:
5079
 * @ctxt:  a schema parser context
5080
 * @schema:  the schema being built
5081
 * @name:  the item name
5082
 *
5083
 * Add an XML schema annotation declaration
5084
 * *WARNING* this interface is highly subject to change
5085
 *
5086
 * Returns the new structure or NULL in case of error
5087
 */
5088
static xmlSchemaNotationPtr
5089
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5090
                     const xmlChar *name, const xmlChar *nsName,
5091
         xmlNodePtr node ATTRIBUTE_UNUSED)
5092
1.43k
{
5093
1.43k
    xmlSchemaNotationPtr ret = NULL;
5094
5095
1.43k
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5096
0
        return (NULL);
5097
5098
1.43k
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5099
1.43k
    if (ret == NULL) {
5100
0
        xmlSchemaPErrMemory(ctxt);
5101
0
        return (NULL);
5102
0
    }
5103
1.43k
    memset(ret, 0, sizeof(xmlSchemaNotation));
5104
1.43k
    ret->type = XML_SCHEMA_TYPE_NOTATION;
5105
1.43k
    ret->name = name;
5106
1.43k
    ret->targetNamespace = nsName;
5107
    /* TODO: do we need the node to be set?
5108
    * ret->node = node;*/
5109
1.43k
    WXS_ADD_GLOBAL(ctxt, ret);
5110
1.43k
    return (ret);
5111
1.43k
}
5112
5113
/**
5114
 * xmlSchemaAddAttribute:
5115
 * @ctxt:  a schema parser context
5116
 * @schema:  the schema being built
5117
 * @name:  the item name
5118
 * @namespace:  the namespace
5119
 *
5120
 * Add an XML schema Attribute declaration
5121
 * *WARNING* this interface is highly subject to change
5122
 *
5123
 * Returns the new structure or NULL in case of error
5124
 */
5125
static xmlSchemaAttributePtr
5126
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5127
                      const xmlChar * name, const xmlChar * nsName,
5128
          xmlNodePtr node, int topLevel)
5129
5.57k
{
5130
5.57k
    xmlSchemaAttributePtr ret = NULL;
5131
5132
5.57k
    if ((ctxt == NULL) || (schema == NULL))
5133
0
        return (NULL);
5134
5135
5.57k
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5136
5.57k
    if (ret == NULL) {
5137
0
        xmlSchemaPErrMemory(ctxt);
5138
0
        return (NULL);
5139
0
    }
5140
5.57k
    memset(ret, 0, sizeof(xmlSchemaAttribute));
5141
5.57k
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5142
5.57k
    ret->node = node;
5143
5.57k
    ret->name = name;
5144
5.57k
    ret->targetNamespace = nsName;
5145
5146
5.57k
    if (topLevel)
5147
2.68k
  WXS_ADD_GLOBAL(ctxt, ret);
5148
2.89k
    else
5149
2.89k
  WXS_ADD_LOCAL(ctxt, ret);
5150
5.57k
    WXS_ADD_PENDING(ctxt, ret);
5151
5.57k
    return (ret);
5152
5.57k
}
5153
5154
/**
5155
 * xmlSchemaAddAttributeUse:
5156
 * @ctxt:  a schema parser context
5157
 * @schema:  the schema being built
5158
 * @name:  the item name
5159
 * @namespace:  the namespace
5160
 *
5161
 * Add an XML schema Attribute declaration
5162
 * *WARNING* this interface is highly subject to change
5163
 *
5164
 * Returns the new structure or NULL in case of error
5165
 */
5166
static xmlSchemaAttributeUsePtr
5167
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5168
       xmlNodePtr node)
5169
4.46k
{
5170
4.46k
    xmlSchemaAttributeUsePtr ret = NULL;
5171
5172
4.46k
    if (pctxt == NULL)
5173
0
        return (NULL);
5174
5175
4.46k
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5176
4.46k
    if (ret == NULL) {
5177
0
        xmlSchemaPErrMemory(pctxt);
5178
0
        return (NULL);
5179
0
    }
5180
4.46k
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5181
4.46k
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5182
4.46k
    ret->node = node;
5183
5184
4.46k
    WXS_ADD_LOCAL(pctxt, ret);
5185
4.46k
    return (ret);
5186
4.46k
}
5187
5188
/*
5189
* xmlSchemaAddRedef:
5190
*
5191
* Adds a redefinition information. This is used at a later stage to:
5192
* resolve references to the redefined components and to check constraints.
5193
*/
5194
static xmlSchemaRedefPtr
5195
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5196
      xmlSchemaBucketPtr targetBucket,
5197
      void *item,
5198
      const xmlChar *refName,
5199
      const xmlChar *refTargetNs)
5200
0
{
5201
0
    xmlSchemaRedefPtr ret;
5202
5203
0
    ret = (xmlSchemaRedefPtr)
5204
0
  xmlMalloc(sizeof(xmlSchemaRedef));
5205
0
    if (ret == NULL) {
5206
0
  xmlSchemaPErrMemory(pctxt);
5207
0
  return (NULL);
5208
0
    }
5209
0
    memset(ret, 0, sizeof(xmlSchemaRedef));
5210
0
    ret->item = item;
5211
0
    ret->targetBucket = targetBucket;
5212
0
    ret->refName = refName;
5213
0
    ret->refTargetNs = refTargetNs;
5214
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5215
0
  WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5216
0
    else
5217
0
  WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5218
0
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5219
5220
0
    return (ret);
5221
0
}
5222
5223
/**
5224
 * xmlSchemaAddAttributeGroupDefinition:
5225
 * @ctxt:  a schema parser context
5226
 * @schema:  the schema being built
5227
 * @name:  the item name
5228
 * @nsName:  the target namespace
5229
 * @node: the corresponding node
5230
 *
5231
 * Add an XML schema Attribute Group definition.
5232
 *
5233
 * Returns the new structure or NULL in case of error
5234
 */
5235
static xmlSchemaAttributeGroupPtr
5236
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5237
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5238
         const xmlChar *name,
5239
         const xmlChar *nsName,
5240
         xmlNodePtr node)
5241
2.35k
{
5242
2.35k
    xmlSchemaAttributeGroupPtr ret = NULL;
5243
5244
2.35k
    if ((pctxt == NULL) || (name == NULL))
5245
0
        return (NULL);
5246
5247
2.35k
    ret = (xmlSchemaAttributeGroupPtr)
5248
2.35k
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5249
2.35k
    if (ret == NULL) {
5250
0
  xmlSchemaPErrMemory(pctxt);
5251
0
  return (NULL);
5252
0
    }
5253
2.35k
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5254
2.35k
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5255
2.35k
    ret->name = name;
5256
2.35k
    ret->targetNamespace = nsName;
5257
2.35k
    ret->node = node;
5258
5259
    /* TODO: Remove the flag. */
5260
2.35k
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5261
2.35k
    if (pctxt->isRedefine) {
5262
0
  pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5263
0
      ret, name, nsName);
5264
0
  if (pctxt->redef == NULL) {
5265
0
      xmlFree(ret);
5266
0
      return(NULL);
5267
0
  }
5268
0
  pctxt->redefCounter = 0;
5269
0
    }
5270
2.35k
    WXS_ADD_GLOBAL(pctxt, ret);
5271
2.35k
    WXS_ADD_PENDING(pctxt, ret);
5272
2.35k
    return (ret);
5273
2.35k
}
5274
5275
/**
5276
 * xmlSchemaAddElement:
5277
 * @ctxt:  a schema parser context
5278
 * @schema:  the schema being built
5279
 * @name:  the type name
5280
 * @namespace:  the type namespace
5281
 *
5282
 * Add an XML schema Element declaration
5283
 * *WARNING* this interface is highly subject to change
5284
 *
5285
 * Returns the new structure or NULL in case of error
5286
 */
5287
static xmlSchemaElementPtr
5288
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5289
                    const xmlChar * name, const xmlChar * nsName,
5290
        xmlNodePtr node, int topLevel)
5291
23.6k
{
5292
23.6k
    xmlSchemaElementPtr ret = NULL;
5293
5294
23.6k
    if ((ctxt == NULL) || (name == NULL))
5295
0
        return (NULL);
5296
5297
23.6k
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5298
23.6k
    if (ret == NULL) {
5299
0
        xmlSchemaPErrMemory(ctxt);
5300
0
        return (NULL);
5301
0
    }
5302
23.6k
    memset(ret, 0, sizeof(xmlSchemaElement));
5303
23.6k
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5304
23.6k
    ret->name = name;
5305
23.6k
    ret->targetNamespace = nsName;
5306
23.6k
    ret->node = node;
5307
5308
23.6k
    if (topLevel)
5309
17.7k
  WXS_ADD_GLOBAL(ctxt, ret);
5310
5.91k
    else
5311
5.91k
  WXS_ADD_LOCAL(ctxt, ret);
5312
23.6k
    WXS_ADD_PENDING(ctxt, ret);
5313
23.6k
    return (ret);
5314
23.6k
}
5315
5316
/**
5317
 * xmlSchemaAddType:
5318
 * @ctxt:  a schema parser context
5319
 * @schema:  the schema being built
5320
 * @name:  the item name
5321
 * @namespace:  the namespace
5322
 *
5323
 * Add an XML schema item
5324
 * *WARNING* this interface is highly subject to change
5325
 *
5326
 * Returns the new structure or NULL in case of error
5327
 */
5328
static xmlSchemaTypePtr
5329
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5330
     xmlSchemaTypeType type,
5331
                 const xmlChar * name, const xmlChar * nsName,
5332
     xmlNodePtr node, int topLevel)
5333
27.1k
{
5334
27.1k
    xmlSchemaTypePtr ret = NULL;
5335
5336
27.1k
    if ((ctxt == NULL) || (schema == NULL))
5337
0
        return (NULL);
5338
5339
27.1k
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5340
27.1k
    if (ret == NULL) {
5341
0
        xmlSchemaPErrMemory(ctxt);
5342
0
        return (NULL);
5343
0
    }
5344
27.1k
    memset(ret, 0, sizeof(xmlSchemaType));
5345
27.1k
    ret->type = type;
5346
27.1k
    ret->name = name;
5347
27.1k
    ret->targetNamespace = nsName;
5348
27.1k
    ret->node = node;
5349
27.1k
    if (topLevel) {
5350
16.2k
  if (ctxt->isRedefine) {
5351
0
      ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5352
0
    ret, name, nsName);
5353
0
      if (ctxt->redef == NULL) {
5354
0
    xmlFree(ret);
5355
0
    return(NULL);
5356
0
      }
5357
0
      ctxt->redefCounter = 0;
5358
0
  }
5359
16.2k
  WXS_ADD_GLOBAL(ctxt, ret);
5360
16.2k
    } else
5361
10.8k
  WXS_ADD_LOCAL(ctxt, ret);
5362
27.1k
    WXS_ADD_PENDING(ctxt, ret);
5363
27.1k
    return (ret);
5364
27.1k
}
5365
5366
static xmlSchemaQNameRefPtr
5367
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5368
         xmlSchemaTypeType refType,
5369
         const xmlChar *refName,
5370
         const xmlChar *refNs)
5371
59.6k
{
5372
59.6k
    xmlSchemaQNameRefPtr ret;
5373
5374
59.6k
    ret = (xmlSchemaQNameRefPtr)
5375
59.6k
  xmlMalloc(sizeof(xmlSchemaQNameRef));
5376
59.6k
    if (ret == NULL) {
5377
0
  xmlSchemaPErrMemory(pctxt);
5378
0
  return (NULL);
5379
0
    }
5380
59.6k
    ret->node = NULL;
5381
59.6k
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5382
59.6k
    ret->name = refName;
5383
59.6k
    ret->targetNamespace = refNs;
5384
59.6k
    ret->item = NULL;
5385
59.6k
    ret->itemType = refType;
5386
    /*
5387
    * Store the reference item in the schema.
5388
    */
5389
59.6k
    WXS_ADD_LOCAL(pctxt, ret);
5390
59.6k
    return (ret);
5391
59.6k
}
5392
5393
static xmlSchemaAttributeUseProhibPtr
5394
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5395
431
{
5396
431
    xmlSchemaAttributeUseProhibPtr ret;
5397
5398
431
    ret = (xmlSchemaAttributeUseProhibPtr)
5399
431
  xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5400
431
    if (ret == NULL) {
5401
0
  xmlSchemaPErrMemory(pctxt);
5402
0
  return (NULL);
5403
0
    }
5404
431
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5405
431
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5406
431
    WXS_ADD_LOCAL(pctxt, ret);
5407
431
    return (ret);
5408
431
}
5409
5410
5411
/**
5412
 * xmlSchemaAddModelGroup:
5413
 * @ctxt:  a schema parser context
5414
 * @schema:  the schema being built
5415
 * @type: the "compositor" type of the model group
5416
 * @node: the node in the schema doc
5417
 *
5418
 * Adds a schema model group
5419
 * *WARNING* this interface is highly subject to change
5420
 *
5421
 * Returns the new structure or NULL in case of error
5422
 */
5423
static xmlSchemaModelGroupPtr
5424
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5425
           xmlSchemaPtr schema,
5426
           xmlSchemaTypeType type,
5427
           xmlNodePtr node)
5428
5.54k
{
5429
5.54k
    xmlSchemaModelGroupPtr ret = NULL;
5430
5431
5.54k
    if ((ctxt == NULL) || (schema == NULL))
5432
0
        return (NULL);
5433
5434
5.54k
    ret = (xmlSchemaModelGroupPtr)
5435
5.54k
  xmlMalloc(sizeof(xmlSchemaModelGroup));
5436
5.54k
    if (ret == NULL) {
5437
0
  xmlSchemaPErrMemory(ctxt);
5438
0
  return (NULL);
5439
0
    }
5440
5.54k
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5441
5.54k
    ret->type = type;
5442
5.54k
    ret->node = node;
5443
5.54k
    WXS_ADD_LOCAL(ctxt, ret);
5444
5.54k
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5445
5.54k
  (type == XML_SCHEMA_TYPE_CHOICE))
5446
5.40k
  WXS_ADD_PENDING(ctxt, ret);
5447
5.54k
    return (ret);
5448
5.54k
}
5449
5450
5451
/**
5452
 * xmlSchemaAddParticle:
5453
 * @ctxt:  a schema parser context
5454
 * @schema:  the schema being built
5455
 * @node: the corresponding node in the schema doc
5456
 * @min: the minOccurs
5457
 * @max: the maxOccurs
5458
 *
5459
 * Adds an XML schema particle component.
5460
 * *WARNING* this interface is highly subject to change
5461
 *
5462
 * Returns the new structure or NULL in case of error
5463
 */
5464
static xmlSchemaParticlePtr
5465
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5466
         xmlNodePtr node, int min, int max)
5467
21.1k
{
5468
21.1k
    xmlSchemaParticlePtr ret = NULL;
5469
21.1k
    if (ctxt == NULL)
5470
0
        return (NULL);
5471
5472
21.1k
    ret = (xmlSchemaParticlePtr)
5473
21.1k
  xmlMalloc(sizeof(xmlSchemaParticle));
5474
21.1k
    if (ret == NULL) {
5475
0
  xmlSchemaPErrMemory(ctxt);
5476
0
  return (NULL);
5477
0
    }
5478
21.1k
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5479
21.1k
    ret->annot = NULL;
5480
21.1k
    ret->node = node;
5481
21.1k
    ret->minOccurs = min;
5482
21.1k
    ret->maxOccurs = max;
5483
21.1k
    ret->next = NULL;
5484
21.1k
    ret->children = NULL;
5485
5486
21.1k
    WXS_ADD_LOCAL(ctxt, ret);
5487
    /*
5488
    * Note that addition to pending components will be done locally
5489
    * to the specific parsing function, since the most particles
5490
    * need not to be fixed up (i.e. the reference to be resolved).
5491
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5492
    */
5493
21.1k
    return (ret);
5494
21.1k
}
5495
5496
/**
5497
 * xmlSchemaAddModelGroupDefinition:
5498
 * @ctxt:  a schema validation context
5499
 * @schema:  the schema being built
5500
 * @name:  the group name
5501
 *
5502
 * Add an XML schema Group definition
5503
 *
5504
 * Returns the new structure or NULL in case of error
5505
 */
5506
static xmlSchemaModelGroupDefPtr
5507
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5508
         xmlSchemaPtr schema,
5509
         const xmlChar *name,
5510
         const xmlChar *nsName,
5511
         xmlNodePtr node)
5512
2.52k
{
5513
2.52k
    xmlSchemaModelGroupDefPtr ret = NULL;
5514
5515
2.52k
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5516
0
        return (NULL);
5517
5518
2.52k
    ret = (xmlSchemaModelGroupDefPtr)
5519
2.52k
  xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5520
2.52k
    if (ret == NULL) {
5521
0
        xmlSchemaPErrMemory(ctxt);
5522
0
        return (NULL);
5523
0
    }
5524
2.52k
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5525
2.52k
    ret->name = name;
5526
2.52k
    ret->type = XML_SCHEMA_TYPE_GROUP;
5527
2.52k
    ret->node = node;
5528
2.52k
    ret->targetNamespace = nsName;
5529
5530
2.52k
    if (ctxt->isRedefine) {
5531
0
  ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5532
0
      ret, name, nsName);
5533
0
  if (ctxt->redef == NULL) {
5534
0
      xmlFree(ret);
5535
0
      return(NULL);
5536
0
  }
5537
0
  ctxt->redefCounter = 0;
5538
0
    }
5539
2.52k
    WXS_ADD_GLOBAL(ctxt, ret);
5540
2.52k
    WXS_ADD_PENDING(ctxt, ret);
5541
2.52k
    return (ret);
5542
2.52k
}
5543
5544
/**
5545
 * xmlSchemaNewWildcardNs:
5546
 * @ctxt:  a schema validation context
5547
 *
5548
 * Creates a new wildcard namespace constraint.
5549
 *
5550
 * Returns the new structure or NULL in case of error
5551
 */
5552
static xmlSchemaWildcardNsPtr
5553
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5554
41.7k
{
5555
41.7k
    xmlSchemaWildcardNsPtr ret;
5556
5557
41.7k
    ret = (xmlSchemaWildcardNsPtr)
5558
41.7k
  xmlMalloc(sizeof(xmlSchemaWildcardNs));
5559
41.7k
    if (ret == NULL) {
5560
0
  xmlSchemaPErrMemory(ctxt);
5561
0
  return (NULL);
5562
0
    }
5563
41.7k
    ret->value = NULL;
5564
41.7k
    ret->next = NULL;
5565
41.7k
    return (ret);
5566
41.7k
}
5567
5568
static xmlSchemaIDCPtr
5569
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5570
                  const xmlChar *name, const xmlChar *nsName,
5571
      int category, xmlNodePtr node)
5572
3.62k
{
5573
3.62k
    xmlSchemaIDCPtr ret = NULL;
5574
5575
3.62k
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5576
0
        return (NULL);
5577
5578
3.62k
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5579
3.62k
    if (ret == NULL) {
5580
0
        xmlSchemaPErrMemory(ctxt);
5581
0
        return (NULL);
5582
0
    }
5583
3.62k
    memset(ret, 0, sizeof(xmlSchemaIDC));
5584
    /* The target namespace of the parent element declaration. */
5585
3.62k
    ret->targetNamespace = nsName;
5586
3.62k
    ret->name = name;
5587
3.62k
    ret->type = category;
5588
3.62k
    ret->node = node;
5589
5590
3.62k
    WXS_ADD_GLOBAL(ctxt, ret);
5591
    /*
5592
    * Only keyrefs need to be fixup up.
5593
    */
5594
3.62k
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5595
3.57k
  WXS_ADD_PENDING(ctxt, ret);
5596
3.62k
    return (ret);
5597
3.62k
}
5598
5599
/**
5600
 * xmlSchemaAddWildcard:
5601
 * @ctxt:  a schema validation context
5602
 * @schema: a schema
5603
 *
5604
 * Adds a wildcard.
5605
 * It corresponds to a xsd:anyAttribute and xsd:any.
5606
 *
5607
 * Returns the new structure or NULL in case of error
5608
 */
5609
static xmlSchemaWildcardPtr
5610
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5611
         xmlSchemaTypeType type, xmlNodePtr node)
5612
8.72k
{
5613
8.72k
    xmlSchemaWildcardPtr ret = NULL;
5614
5615
8.72k
    if ((ctxt == NULL) || (schema == NULL))
5616
0
        return (NULL);
5617
5618
8.72k
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5619
8.72k
    if (ret == NULL) {
5620
0
        xmlSchemaPErrMemory(ctxt);
5621
0
        return (NULL);
5622
0
    }
5623
8.72k
    memset(ret, 0, sizeof(xmlSchemaWildcard));
5624
8.72k
    ret->type = type;
5625
8.72k
    ret->node = node;
5626
8.72k
    WXS_ADD_LOCAL(ctxt, ret);
5627
8.72k
    return (ret);
5628
8.72k
}
5629
5630
static void
5631
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5632
9
{
5633
9
    if (group == NULL)
5634
0
  return;
5635
9
    if (group->members != NULL)
5636
9
  xmlSchemaItemListFree(group->members);
5637
9
    xmlFree(group);
5638
9
}
5639
5640
static void
5641
xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5642
9
{
5643
9
    xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5644
9
}
5645
5646
static xmlSchemaSubstGroupPtr
5647
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5648
           xmlSchemaElementPtr head)
5649
9
{
5650
9
    xmlSchemaSubstGroupPtr ret;
5651
5652
    /* Init subst group hash. */
5653
9
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5654
7
  WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5655
7
  if (WXS_SUBST_GROUPS(pctxt) == NULL)
5656
0
      return(NULL);
5657
7
    }
5658
    /* Create a new substitution group. */
5659
9
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5660
9
    if (ret == NULL) {
5661
0
  xmlSchemaPErrMemory(NULL);
5662
0
  return(NULL);
5663
0
    }
5664
9
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5665
9
    ret->head = head;
5666
    /* Create list of members. */
5667
9
    ret->members = xmlSchemaItemListCreate();
5668
9
    if (ret->members == NULL) {
5669
0
  xmlSchemaSubstGroupFree(ret);
5670
0
  return(NULL);
5671
0
    }
5672
    /* Add subst group to hash. */
5673
9
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5674
9
  head->name, head->targetNamespace, ret) != 0) {
5675
0
  PERROR_INT("xmlSchemaSubstGroupAdd",
5676
0
      "failed to add a new substitution container");
5677
0
  xmlSchemaSubstGroupFree(ret);
5678
0
  return(NULL);
5679
0
    }
5680
9
    return(ret);
5681
9
}
5682
5683
static xmlSchemaSubstGroupPtr
5684
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5685
           xmlSchemaElementPtr head)
5686
34
{
5687
34
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5688
7
  return(NULL);
5689
27
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5690
27
  head->name, head->targetNamespace));
5691
5692
34
}
5693
5694
/**
5695
 * xmlSchemaAddElementSubstitutionMember:
5696
 * @pctxt:  a schema parser context
5697
 * @head:  the head of the substitution group
5698
 * @member: the new member of the substitution group
5699
 *
5700
 * Allocate a new annotation structure.
5701
 *
5702
 * Returns the newly allocated structure or NULL in case or error
5703
 */
5704
static int
5705
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5706
              xmlSchemaElementPtr head,
5707
              xmlSchemaElementPtr member)
5708
27
{
5709
27
    xmlSchemaSubstGroupPtr substGroup = NULL;
5710
5711
27
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5712
0
  return (-1);
5713
5714
27
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5715
27
    if (substGroup == NULL)
5716
9
  substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5717
27
    if (substGroup == NULL)
5718
0
  return(-1);
5719
27
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5720
0
  return(-1);
5721
27
    return(0);
5722
27
}
5723
5724
/************************************************************************
5725
 *                  *
5726
 *    Utilities for parsing         *
5727
 *                  *
5728
 ************************************************************************/
5729
5730
/**
5731
 * xmlSchemaPValAttrNodeQNameValue:
5732
 * @ctxt:  a schema parser context
5733
 * @schema: the schema context
5734
 * @ownerItem: the parent as a schema object
5735
 * @value:  the QName value
5736
 * @uri:  the resulting namespace URI if found
5737
 * @local: the resulting local part if found, the attribute value otherwise
5738
 *
5739
 * Extracts the local name and the URI of a QName value and validates it.
5740
 * This one is intended to be used on attribute values that
5741
 * should resolve to schema components.
5742
 *
5743
 * Returns 0, in case the QName is valid, a positive error code
5744
 * if not valid and -1 if an internal error occurs.
5745
 */
5746
static int
5747
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5748
               xmlSchemaPtr schema,
5749
               xmlSchemaBasicItemPtr ownerItem,
5750
               xmlAttrPtr attr,
5751
               const xmlChar *value,
5752
               const xmlChar **uri,
5753
               const xmlChar **local)
5754
175k
{
5755
175k
    const xmlChar *pref;
5756
175k
    xmlNsPtr ns;
5757
175k
    int len, ret;
5758
5759
175k
    *uri = NULL;
5760
175k
    *local = NULL;
5761
175k
    ret = xmlValidateQName(value, 1);
5762
175k
    if (ret > 0) {
5763
83.5k
  xmlSchemaPSimpleTypeErr(ctxt,
5764
83.5k
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5765
83.5k
      ownerItem, (xmlNodePtr) attr,
5766
83.5k
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5767
83.5k
      NULL, value, NULL, NULL, NULL);
5768
83.5k
  *local = value;
5769
83.5k
  return (ctxt->err);
5770
92.0k
    } else if (ret < 0)
5771
0
  return (-1);
5772
5773
92.0k
    if (!strchr((char *) value, ':')) {
5774
61.5k
  ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5775
61.5k
  if (ns && ns->href && ns->href[0])
5776
53.8k
      *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5777
7.65k
  else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5778
      /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5779
      * parser context. */
5780
      /*
5781
      * This one takes care of included schemas with no
5782
      * target namespace.
5783
      */
5784
18
      *uri = ctxt->targetNamespace;
5785
18
  }
5786
61.5k
  *local = xmlDictLookup(ctxt->dict, value, -1);
5787
61.5k
  return (0);
5788
61.5k
    }
5789
    /*
5790
    * At this point xmlSplitQName3 has to return a local name.
5791
    */
5792
30.5k
    *local = xmlSplitQName3(value, &len);
5793
30.5k
    *local = xmlDictLookup(ctxt->dict, *local, -1);
5794
30.5k
    pref = xmlDictLookup(ctxt->dict, value, len);
5795
30.5k
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5796
30.5k
    if (ns == NULL) {
5797
12.5k
  xmlSchemaPSimpleTypeErr(ctxt,
5798
12.5k
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5799
12.5k
      ownerItem, (xmlNodePtr) attr,
5800
12.5k
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5801
12.5k
      "The value '%s' of simple type 'xs:QName' has no "
5802
12.5k
      "corresponding namespace declaration in scope", value, NULL);
5803
12.5k
  return (ctxt->err);
5804
17.9k
    } else {
5805
17.9k
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5806
17.9k
    }
5807
17.9k
    return (0);
5808
30.5k
}
5809
5810
/**
5811
 * xmlSchemaPValAttrNodeQName:
5812
 * @ctxt:  a schema parser context
5813
 * @schema: the schema context
5814
 * @ownerItem: the owner as a schema object
5815
 * @attr:  the attribute node
5816
 * @uri:  the resulting namespace URI if found
5817
 * @local: the resulting local part if found, the attribute value otherwise
5818
 *
5819
 * Extracts and validates the QName of an attribute value.
5820
 * This one is intended to be used on attribute values that
5821
 * should resolve to schema components.
5822
 *
5823
 * Returns 0, in case the QName is valid, a positive error code
5824
 * if not valid and -1 if an internal error occurs.
5825
 */
5826
static int
5827
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5828
               xmlSchemaPtr schema,
5829
               xmlSchemaBasicItemPtr ownerItem,
5830
               xmlAttrPtr attr,
5831
               const xmlChar **uri,
5832
               const xmlChar **local)
5833
32.4k
{
5834
32.4k
    const xmlChar *value;
5835
5836
32.4k
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5837
32.4k
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5838
32.4k
  ownerItem, attr, value, uri, local));
5839
32.4k
}
5840
5841
/**
5842
 * xmlSchemaPValAttrQName:
5843
 * @ctxt:  a schema parser context
5844
 * @schema: the schema context
5845
 * @ownerItem: the owner as a schema object
5846
 * @ownerElem:  the parent node of the attribute
5847
 * @name:  the name of the attribute
5848
 * @uri:  the resulting namespace URI if found
5849
 * @local: the resulting local part if found, the attribute value otherwise
5850
 *
5851
 * Extracts and validates the QName of an attribute value.
5852
 *
5853
 * Returns 0, in case the QName is valid, a positive error code
5854
 * if not valid and -1 if an internal error occurs.
5855
 */
5856
static int
5857
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5858
           xmlSchemaPtr schema,
5859
           xmlSchemaBasicItemPtr ownerItem,
5860
           xmlNodePtr ownerElem,
5861
           const char *name,
5862
           const xmlChar **uri,
5863
           const xmlChar **local)
5864
32.9k
{
5865
32.9k
    xmlAttrPtr attr;
5866
5867
32.9k
    attr = xmlSchemaGetPropNode(ownerElem, name);
5868
32.9k
    if (attr == NULL) {
5869
20.7k
  *local = NULL;
5870
20.7k
  *uri = NULL;
5871
20.7k
  return (0);
5872
20.7k
    }
5873
12.1k
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5874
12.1k
  ownerItem, attr, uri, local));
5875
32.9k
}
5876
5877
/**
5878
 * xmlSchemaPValAttrID:
5879
 * @ctxt:  a schema parser context
5880
 *
5881
 * Extracts and validates the ID of an attribute value.
5882
 *
5883
 * Returns 0, in case the ID is valid, a positive error code
5884
 * if not valid and -1 if an internal error occurs.
5885
 */
5886
static int
5887
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5888
5.07k
{
5889
5.07k
    int ret;
5890
5.07k
    const xmlChar *value;
5891
5892
5.07k
    if (attr == NULL)
5893
0
  return(0);
5894
5.07k
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5895
5.07k
    ret = xmlValidateNCName(value, 1);
5896
5.07k
    if (ret == 0) {
5897
  /*
5898
  * NOTE: the IDness might have already be declared in the DTD
5899
  */
5900
3.31k
  if (attr->atype != XML_ATTRIBUTE_ID) {
5901
2.81k
      xmlIDPtr res;
5902
2.81k
      xmlChar *strip;
5903
5904
      /*
5905
      * TODO: Use xmlSchemaStrip here; it's not exported at this
5906
      * moment.
5907
      */
5908
2.81k
      strip = xmlSchemaCollapseString(value);
5909
2.81k
      if (strip != NULL) {
5910
393
    xmlFree((xmlChar *) value);
5911
393
    value = strip;
5912
393
      }
5913
2.81k
      res = xmlAddID(NULL, attr->doc, value, attr);
5914
2.81k
      if (res == NULL) {
5915
2.47k
    ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5916
2.47k
    xmlSchemaPSimpleTypeErr(ctxt,
5917
2.47k
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5918
2.47k
        NULL, (xmlNodePtr) attr,
5919
2.47k
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5920
2.47k
        NULL, NULL, "Duplicate value '%s' of simple "
5921
2.47k
        "type 'xs:ID'", value, NULL);
5922
2.47k
      } else
5923
339
    attr->atype = XML_ATTRIBUTE_ID;
5924
2.81k
  }
5925
3.31k
    } else if (ret > 0) {
5926
1.75k
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5927
1.75k
  xmlSchemaPSimpleTypeErr(ctxt,
5928
1.75k
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5929
1.75k
      NULL, (xmlNodePtr) attr,
5930
1.75k
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5931
1.75k
      NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
5932
1.75k
      "not a valid 'xs:NCName'",
5933
1.75k
      value, NULL);
5934
1.75k
    }
5935
5.07k
    if (value != NULL)
5936
5.07k
  xmlFree((xmlChar *)value);
5937
5938
5.07k
    return (ret);
5939
5.07k
}
5940
5941
static int
5942
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5943
        xmlNodePtr ownerElem,
5944
        const xmlChar *name)
5945
263k
{
5946
263k
    xmlAttrPtr attr;
5947
5948
263k
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5949
263k
    if (attr == NULL)
5950
258k
  return(0);
5951
4.99k
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
5952
5953
263k
}
5954
5955
/**
5956
 * xmlGetMaxOccurs:
5957
 * @ctxt:  a schema validation context
5958
 * @node:  a subtree containing XML Schema information
5959
 *
5960
 * Get the maxOccurs property
5961
 *
5962
 * Returns the default if not found, or the value
5963
 */
5964
static int
5965
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5966
    int min, int max, int def, const char *expected)
5967
21.5k
{
5968
21.5k
    const xmlChar *val, *cur;
5969
21.5k
    int ret = 0;
5970
21.5k
    xmlAttrPtr attr;
5971
5972
21.5k
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
5973
21.5k
    if (attr == NULL)
5974
17.8k
  return (def);
5975
3.65k
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5976
3.65k
    if (val == NULL)
5977
0
        return (def);
5978
5979
3.65k
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
5980
1.42k
  if (max != UNBOUNDED) {
5981
1
      xmlSchemaPSimpleTypeErr(ctxt,
5982
1
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5983
    /* XML_SCHEMAP_INVALID_MINOCCURS, */
5984
1
    NULL, (xmlNodePtr) attr, NULL, expected,
5985
1
    val, NULL, NULL, NULL);
5986
1
      return (def);
5987
1
  } else
5988
1.41k
      return (UNBOUNDED);  /* encoding it with -1 might be another option */
5989
1.42k
    }
5990
5991
2.23k
    cur = val;
5992
2.23k
    while (IS_BLANK_CH(*cur))
5993
467
        cur++;
5994
2.23k
    if (*cur == 0) {
5995
311
        xmlSchemaPSimpleTypeErr(ctxt,
5996
311
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5997
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5998
311
      NULL, (xmlNodePtr) attr, NULL, expected,
5999
311
      val, NULL, NULL, NULL);
6000
311
  return (def);
6001
311
    }
6002
10.4k
    while ((*cur >= '0') && (*cur <= '9')) {
6003
8.54k
        if (ret > INT_MAX / 10) {
6004
2.01k
            ret = INT_MAX;
6005
6.52k
        } else {
6006
6.52k
            int digit = *cur - '0';
6007
6.52k
            ret *= 10;
6008
6.52k
            if (ret > INT_MAX - digit)
6009
194
                ret = INT_MAX;
6010
6.33k
            else
6011
6.33k
                ret += digit;
6012
6.52k
        }
6013
8.54k
        cur++;
6014
8.54k
    }
6015
1.92k
    while (IS_BLANK_CH(*cur))
6016
494
        cur++;
6017
    /*
6018
    * TODO: Restrict the maximal value to Integer.
6019
    */
6020
1.92k
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6021
914
  xmlSchemaPSimpleTypeErr(ctxt,
6022
914
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6023
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6024
914
      NULL, (xmlNodePtr) attr, NULL, expected,
6025
914
      val, NULL, NULL, NULL);
6026
914
        return (def);
6027
914
    }
6028
1.01k
    return (ret);
6029
1.92k
}
6030
6031
/**
6032
 * xmlGetMinOccurs:
6033
 * @ctxt:  a schema validation context
6034
 * @node:  a subtree containing XML Schema information
6035
 *
6036
 * Get the minOccurs property
6037
 *
6038
 * Returns the default if not found, or the value
6039
 */
6040
static int
6041
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6042
    int min, int max, int def, const char *expected)
6043
21.5k
{
6044
21.5k
    const xmlChar *val, *cur;
6045
21.5k
    int ret = 0;
6046
21.5k
    xmlAttrPtr attr;
6047
6048
21.5k
    attr = xmlSchemaGetPropNode(node, "minOccurs");
6049
21.5k
    if (attr == NULL)
6050
16.0k
  return (def);
6051
5.50k
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6052
5.50k
    if (val == NULL)
6053
0
  return (def);
6054
5.50k
    cur = val;
6055
5.50k
    while (IS_BLANK_CH(*cur))
6056
314
        cur++;
6057
5.50k
    if (*cur == 0) {
6058
6
        xmlSchemaPSimpleTypeErr(ctxt,
6059
6
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6060
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6061
6
      NULL, (xmlNodePtr) attr, NULL, expected,
6062
6
      val, NULL, NULL, NULL);
6063
6
        return (def);
6064
6
    }
6065
24.2k
    while ((*cur >= '0') && (*cur <= '9')) {
6066
18.7k
        if (ret > INT_MAX / 10) {
6067
6.07k
            ret = INT_MAX;
6068
12.6k
        } else {
6069
12.6k
            int digit = *cur - '0';
6070
12.6k
            ret *= 10;
6071
12.6k
            if (ret > INT_MAX - digit)
6072
414
                ret = INT_MAX;
6073
12.2k
            else
6074
12.2k
                ret += digit;
6075
12.6k
        }
6076
18.7k
        cur++;
6077
18.7k
    }
6078
5.49k
    while (IS_BLANK_CH(*cur))
6079
441
        cur++;
6080
    /*
6081
    * TODO: Restrict the maximal value to Integer.
6082
    */
6083
5.49k
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6084
555
  xmlSchemaPSimpleTypeErr(ctxt,
6085
555
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6086
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6087
555
      NULL, (xmlNodePtr) attr, NULL, expected,
6088
555
      val, NULL, NULL, NULL);
6089
555
        return (def);
6090
555
    }
6091
4.94k
    return (ret);
6092
5.49k
}
6093
6094
/**
6095
 * xmlSchemaPGetBoolNodeValue:
6096
 * @ctxt:  a schema validation context
6097
 * @ownerItem:  the owner as a schema item
6098
 * @node: the node holding the value
6099
 *
6100
 * Converts a boolean string value into 1 or 0.
6101
 *
6102
 * Returns 0 or 1.
6103
 */
6104
static int
6105
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6106
         xmlSchemaBasicItemPtr ownerItem,
6107
         xmlNodePtr node)
6108
1.04k
{
6109
1.04k
    xmlChar *value = NULL;
6110
1.04k
    int res = 0;
6111
6112
1.04k
    value = xmlNodeGetContent(node);
6113
    /*
6114
    * 3.2.2.1 Lexical representation
6115
    * An instance of a datatype that is defined as `boolean`
6116
    * can have the following legal literals {true, false, 1, 0}.
6117
    */
6118
1.04k
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6119
56
        res = 1;
6120
987
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6121
0
        res = 0;
6122
987
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6123
181
  res = 1;
6124
806
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6125
196
        res = 0;
6126
610
    else {
6127
610
        xmlSchemaPSimpleTypeErr(ctxt,
6128
610
      XML_SCHEMAP_INVALID_BOOLEAN,
6129
610
      ownerItem, node,
6130
610
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6131
610
      NULL, BAD_CAST value,
6132
610
      NULL, NULL, NULL);
6133
610
    }
6134
1.04k
    if (value != NULL)
6135
1.04k
  xmlFree(value);
6136
1.04k
    return (res);
6137
1.04k
}
6138
6139
/**
6140
 * xmlGetBooleanProp:
6141
 * @ctxt:  a schema validation context
6142
 * @node:  a subtree containing XML Schema information
6143
 * @name:  the attribute name
6144
 * @def:  the default value
6145
 *
6146
 * Evaluate if a boolean property is set
6147
 *
6148
 * Returns the default if not found, 0 if found to be false,
6149
 * 1 if found to be true
6150
 */
6151
static int
6152
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6153
      xmlNodePtr node,
6154
                  const char *name, int def)
6155
42.9k
{
6156
42.9k
    const xmlChar *val;
6157
6158
42.9k
    val = xmlSchemaGetProp(ctxt, node, name);
6159
42.9k
    if (val == NULL)
6160
42.3k
        return (def);
6161
    /*
6162
    * 3.2.2.1 Lexical representation
6163
    * An instance of a datatype that is defined as `boolean`
6164
    * can have the following legal literals {true, false, 1, 0}.
6165
    */
6166
584
    if (xmlStrEqual(val, BAD_CAST "true"))
6167
117
        def = 1;
6168
467
    else if (xmlStrEqual(val, BAD_CAST "false"))
6169
29
        def = 0;
6170
438
    else if (xmlStrEqual(val, BAD_CAST "1"))
6171
42
  def = 1;
6172
396
    else if (xmlStrEqual(val, BAD_CAST "0"))
6173
95
        def = 0;
6174
301
    else {
6175
301
        xmlSchemaPSimpleTypeErr(ctxt,
6176
301
      XML_SCHEMAP_INVALID_BOOLEAN,
6177
301
      NULL,
6178
301
      (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6179
301
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6180
301
      NULL, val, NULL, NULL, NULL);
6181
301
    }
6182
584
    return (def);
6183
42.9k
}
6184
6185
/************************************************************************
6186
 *                  *
6187
 *    Schema extraction from an Infoset     *
6188
 *                  *
6189
 ************************************************************************/
6190
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6191
                                                 ctxt, xmlSchemaPtr schema,
6192
                                                 xmlNodePtr node,
6193
             int topLevel);
6194
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6195
                                                  ctxt,
6196
                                                  xmlSchemaPtr schema,
6197
                                                  xmlNodePtr node,
6198
              int topLevel);
6199
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6200
                                                  ctxt,
6201
                                                  xmlSchemaPtr schema,
6202
                                                  xmlNodePtr node,
6203
              xmlSchemaTypeType parentType);
6204
static xmlSchemaBasicItemPtr
6205
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6206
           xmlSchemaPtr schema,
6207
           xmlNodePtr node,
6208
           xmlSchemaItemListPtr uses,
6209
           int parentType);
6210
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6211
                                           xmlSchemaPtr schema,
6212
                                           xmlNodePtr node);
6213
static xmlSchemaWildcardPtr
6214
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6215
                           xmlSchemaPtr schema, xmlNodePtr node);
6216
6217
/**
6218
 * xmlSchemaPValAttrNodeValue:
6219
 *
6220
 * @pctxt:  a schema parser context
6221
 * @ownerItem: the schema object owner if existent
6222
 * @attr:  the schema attribute node being validated
6223
 * @value: the value
6224
 * @type: the built-in type to be validated against
6225
 *
6226
 * Validates a value against the given built-in type.
6227
 * This one is intended to be used internally for validation
6228
 * of schema attribute values during parsing of the schema.
6229
 *
6230
 * Returns 0 if the value is valid, a positive error code
6231
 * number otherwise and -1 in case of an internal or API error.
6232
 */
6233
static int
6234
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6235
         xmlSchemaBasicItemPtr ownerItem,
6236
         xmlAttrPtr attr,
6237
         const xmlChar *value,
6238
         xmlSchemaTypePtr type)
6239
143k
{
6240
6241
143k
    int ret = 0;
6242
6243
    /*
6244
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6245
    * one is really meant to be used internally, so better not.
6246
    */
6247
143k
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6248
0
  return (-1);
6249
143k
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6250
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6251
0
      "the given type is not a built-in type");
6252
0
  return (-1);
6253
0
    }
6254
143k
    switch (type->builtInType) {
6255
59.9k
  case XML_SCHEMAS_NCNAME:
6256
59.9k
  case XML_SCHEMAS_QNAME:
6257
143k
  case XML_SCHEMAS_ANYURI:
6258
143k
  case XML_SCHEMAS_TOKEN:
6259
143k
  case XML_SCHEMAS_LANGUAGE:
6260
143k
      ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6261
143k
    (xmlNodePtr) attr);
6262
143k
      break;
6263
0
  default: {
6264
0
      PERROR_INT("xmlSchemaPValAttrNodeValue",
6265
0
    "validation using the given type is not supported while "
6266
0
    "parsing a schema");
6267
0
      return (-1);
6268
143k
  }
6269
143k
    }
6270
    /*
6271
    * TODO: Should we use the S4S error codes instead?
6272
    */
6273
143k
    if (ret < 0) {
6274
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6275
0
      "failed to validate a schema attribute value");
6276
0
  return (-1);
6277
143k
    } else if (ret > 0) {
6278
10.4k
  if (WXS_IS_LIST(type))
6279
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6280
10.4k
  else
6281
10.4k
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6282
10.4k
  xmlSchemaPSimpleTypeErr(pctxt,
6283
10.4k
      ret, ownerItem, (xmlNodePtr) attr,
6284
10.4k
      type, NULL, value, NULL, NULL, NULL);
6285
10.4k
    }
6286
143k
    return (ret);
6287
143k
}
6288
6289
/**
6290
 * xmlSchemaPValAttrNode:
6291
 *
6292
 * @ctxt:  a schema parser context
6293
 * @ownerItem: the schema object owner if existent
6294
 * @attr:  the schema attribute node being validated
6295
 * @type: the built-in type to be validated against
6296
 * @value: the resulting value if any
6297
 *
6298
 * Extracts and validates a value against the given built-in type.
6299
 * This one is intended to be used internally for validation
6300
 * of schema attribute values during parsing of the schema.
6301
 *
6302
 * Returns 0 if the value is valid, a positive error code
6303
 * number otherwise and -1 in case of an internal or API error.
6304
 */
6305
static int
6306
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6307
         xmlSchemaBasicItemPtr ownerItem,
6308
         xmlAttrPtr attr,
6309
         xmlSchemaTypePtr type,
6310
         const xmlChar **value)
6311
66.0k
{
6312
66.0k
    const xmlChar *val;
6313
6314
66.0k
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6315
0
  return (-1);
6316
6317
66.0k
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6318
66.0k
    if (value != NULL)
6319
64.7k
  *value = val;
6320
6321
66.0k
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6322
66.0k
  val, type));
6323
66.0k
}
6324
6325
/**
6326
 * xmlSchemaPValAttr:
6327
 *
6328
 * @ctxt:  a schema parser context
6329
 * @node: the element node of the attribute
6330
 * @ownerItem: the schema object owner if existent
6331
 * @ownerElem: the owner element node
6332
 * @name:  the name of the schema attribute node
6333
 * @type: the built-in type to be validated against
6334
 * @value: the resulting value if any
6335
 *
6336
 * Extracts and validates a value against the given built-in type.
6337
 * This one is intended to be used internally for validation
6338
 * of schema attribute values during parsing of the schema.
6339
 *
6340
 * Returns 0 if the value is valid, a positive error code
6341
 * number otherwise and -1 in case of an internal or API error.
6342
 */
6343
static int
6344
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6345
           xmlSchemaBasicItemPtr ownerItem,
6346
           xmlNodePtr ownerElem,
6347
           const char *name,
6348
           xmlSchemaTypePtr type,
6349
           const xmlChar **value)
6350
9.78k
{
6351
9.78k
    xmlAttrPtr attr;
6352
6353
9.78k
    if ((ctxt == NULL) || (type == NULL)) {
6354
0
  if (value != NULL)
6355
0
      *value = NULL;
6356
0
  return (-1);
6357
0
    }
6358
9.78k
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6359
0
  if (value != NULL)
6360
0
      *value = NULL;
6361
0
  xmlSchemaPErr(ctxt, ownerElem,
6362
0
      XML_SCHEMAP_INTERNAL,
6363
0
      "Internal error: xmlSchemaPValAttr, the given "
6364
0
      "type '%s' is not a built-in type.\n",
6365
0
      type->name, NULL);
6366
0
  return (-1);
6367
0
    }
6368
9.78k
    attr = xmlSchemaGetPropNode(ownerElem, name);
6369
9.78k
    if (attr == NULL) {
6370
5.20k
  if (value != NULL)
6371
4.56k
      *value = NULL;
6372
5.20k
  return (0);
6373
5.20k
    }
6374
4.58k
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6375
4.58k
  type, value));
6376
9.78k
}
6377
6378
static int
6379
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6380
      xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6381
      xmlNodePtr node,
6382
      xmlAttrPtr attr,
6383
      const xmlChar *namespaceName)
6384
18.2k
{
6385
    /* TODO: Pointer comparison instead? */
6386
18.2k
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6387
9.53k
  return (0);
6388
8.75k
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
6389
6.84k
  return (0);
6390
    /*
6391
    * Check if the referenced namespace was <import>ed.
6392
    */
6393
1.90k
    if (WXS_BUCKET(pctxt)->relations != NULL) {
6394
325
  xmlSchemaSchemaRelationPtr rel;
6395
6396
325
  rel = WXS_BUCKET(pctxt)->relations;
6397
532
  do {
6398
532
      if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6399
532
    xmlStrEqual(namespaceName, rel->importNamespace))
6400
233
    return (0);
6401
299
      rel = rel->next;
6402
299
  } while (rel != NULL);
6403
325
    }
6404
    /*
6405
    * No matching <import>ed namespace found.
6406
    */
6407
1.67k
    {
6408
1.67k
  xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6409
6410
1.67k
  if (namespaceName == NULL)
6411
940
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6412
940
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6413
940
    "References from this schema to components in no "
6414
940
    "namespace are not allowed, since not indicated by an "
6415
940
    "import statement", NULL, NULL);
6416
736
  else
6417
736
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6418
736
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6419
736
    "References from this schema to components in the "
6420
736
    "namespace '%s' are not allowed, since not indicated by an "
6421
736
    "import statement", namespaceName, NULL);
6422
1.67k
    }
6423
1.67k
    return (XML_SCHEMAP_SRC_RESOLVE);
6424
1.90k
}
6425
6426
/**
6427
 * xmlSchemaParseLocalAttributes:
6428
 * @ctxt:  a schema validation context
6429
 * @schema:  the schema being built
6430
 * @node:  a subtree containing XML Schema information
6431
 * @type:  the hosting type where the attributes will be anchored
6432
 *
6433
 * Parses attribute uses and attribute declarations and
6434
 * attribute group references.
6435
 */
6436
static int
6437
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6438
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
6439
      int parentType, int *hasRefs)
6440
13.5k
{
6441
13.5k
    void *item;
6442
6443
24.3k
    while ((IS_SCHEMA((*child), "attribute")) ||
6444
24.3k
           (IS_SCHEMA((*child), "attributeGroup"))) {
6445
10.8k
        if (IS_SCHEMA((*child), "attribute")) {
6446
7.12k
      item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6447
7.12k
    *list, parentType);
6448
7.12k
        } else {
6449
3.69k
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6450
3.69k
      if ((item != NULL) && (hasRefs != NULL))
6451
345
    *hasRefs = 1;
6452
3.69k
        }
6453
10.8k
  if (item != NULL) {
6454
7.90k
      if (*list == NULL) {
6455
    /* TODO: Customize grow factor. */
6456
2.49k
    *list = xmlSchemaItemListCreate();
6457
2.49k
    if (*list == NULL)
6458
0
        return(-1);
6459
2.49k
      }
6460
7.90k
      if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6461
0
    return(-1);
6462
7.90k
  }
6463
10.8k
        *child = (*child)->next;
6464
10.8k
    }
6465
13.5k
    return (0);
6466
13.5k
}
6467
6468
/**
6469
 * xmlSchemaParseAnnotation:
6470
 * @ctxt:  a schema validation context
6471
 * @schema:  the schema being built
6472
 * @node:  a subtree containing XML Schema information
6473
 *
6474
 * parse a XML schema Attribute declaration
6475
 * *WARNING* this interface is highly subject to change
6476
 *
6477
 * Returns -1 in case of error, 0 if the declaration is improper and
6478
 *         1 in case of success.
6479
 */
6480
static xmlSchemaAnnotPtr
6481
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6482
4.34k
{
6483
4.34k
    xmlSchemaAnnotPtr ret;
6484
4.34k
    xmlNodePtr child = NULL;
6485
4.34k
    xmlAttrPtr attr;
6486
4.34k
    int barked = 0;
6487
6488
    /*
6489
    * INFO: S4S completed.
6490
    */
6491
    /*
6492
    * id = ID
6493
    * {any attributes with non-schema namespace . . .}>
6494
    * Content: (appinfo | documentation)*
6495
    */
6496
4.34k
    if ((ctxt == NULL) || (node == NULL))
6497
0
        return (NULL);
6498
4.34k
    if (needed)
6499
4.31k
  ret = xmlSchemaNewAnnot(ctxt, node);
6500
29
    else
6501
29
  ret = NULL;
6502
4.34k
    attr = node->properties;
6503
7.63k
    while (attr != NULL) {
6504
3.28k
  if (((attr->ns == NULL) &&
6505
3.28k
      (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6506
3.28k
      ((attr->ns != NULL) &&
6507
2.38k
      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6508
6509
2.38k
      xmlSchemaPIllegalAttrErr(ctxt,
6510
2.38k
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6511
2.38k
  }
6512
3.28k
  attr = attr->next;
6513
3.28k
    }
6514
4.34k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6515
    /*
6516
    * And now for the children...
6517
    */
6518
4.34k
    child = node->children;
6519
11.1k
    while (child != NULL) {
6520
6.79k
  if (IS_SCHEMA(child, "appinfo")) {
6521
      /* TODO: make available the content of "appinfo". */
6522
      /*
6523
      * source = anyURI
6524
      * {any attributes with non-schema namespace . . .}>
6525
      * Content: ({any})*
6526
      */
6527
647
      attr = child->properties;
6528
3.62k
      while (attr != NULL) {
6529
2.98k
    if (((attr->ns == NULL) &&
6530
2.98k
         (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6531
2.98k
         ((attr->ns != NULL) &&
6532
2.61k
          xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6533
6534
2.61k
        xmlSchemaPIllegalAttrErr(ctxt,
6535
2.61k
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6536
2.61k
    }
6537
2.98k
    attr = attr->next;
6538
2.98k
      }
6539
647
      xmlSchemaPValAttr(ctxt, NULL, child, "source",
6540
647
    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6541
647
      child = child->next;
6542
6.14k
  } else if (IS_SCHEMA(child, "documentation")) {
6543
      /* TODO: make available the content of "documentation". */
6544
      /*
6545
      * source = anyURI
6546
      * {any attributes with non-schema namespace . . .}>
6547
      * Content: ({any})*
6548
      */
6549
1.03k
      attr = child->properties;
6550
2.05k
      while (attr != NULL) {
6551
1.01k
    if (attr->ns == NULL) {
6552
292
        if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6553
288
      xmlSchemaPIllegalAttrErr(ctxt,
6554
288
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6555
288
        }
6556
722
    } else {
6557
722
        if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6558
722
      (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6559
716
      (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6560
6561
129
      xmlSchemaPIllegalAttrErr(ctxt,
6562
129
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6563
129
        }
6564
722
    }
6565
1.01k
    attr = attr->next;
6566
1.01k
      }
6567
      /*
6568
      * Attribute "xml:lang".
6569
      */
6570
1.03k
      attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6571
1.03k
      if (attr != NULL)
6572
204
    xmlSchemaPValAttrNode(ctxt, NULL, attr,
6573
204
    xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6574
1.03k
      child = child->next;
6575
5.10k
  } else {
6576
5.10k
      if (!barked)
6577
824
    xmlSchemaPContentErr(ctxt,
6578
824
        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6579
824
        NULL, node, child, NULL, "(appinfo | documentation)*");
6580
5.10k
      barked = 1;
6581
5.10k
      child = child->next;
6582
5.10k
  }
6583
6.79k
    }
6584
6585
4.34k
    return (ret);
6586
4.34k
}
6587
6588
/**
6589
 * xmlSchemaParseFacet:
6590
 * @ctxt:  a schema validation context
6591
 * @schema:  the schema being built
6592
 * @node:  a subtree containing XML Schema information
6593
 *
6594
 * parse a XML schema Facet declaration
6595
 * *WARNING* this interface is highly subject to change
6596
 *
6597
 * Returns the new type structure or NULL in case of error
6598
 */
6599
static xmlSchemaFacetPtr
6600
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6601
                    xmlNodePtr node)
6602
128k
{
6603
128k
    xmlSchemaFacetPtr facet;
6604
128k
    xmlNodePtr child = NULL;
6605
128k
    const xmlChar *value;
6606
6607
128k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6608
0
        return (NULL);
6609
6610
128k
    facet = xmlSchemaNewFacet();
6611
128k
    if (facet == NULL) {
6612
0
        xmlSchemaPErrMemory(ctxt);
6613
0
        return (NULL);
6614
0
    }
6615
128k
    facet->node = node;
6616
128k
    value = xmlSchemaGetProp(ctxt, node, "value");
6617
128k
    if (value == NULL) {
6618
51
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6619
51
                       "Facet %s has no value\n", node->name, NULL);
6620
51
        xmlSchemaFreeFacet(facet);
6621
51
        return (NULL);
6622
51
    }
6623
128k
    if (IS_SCHEMA(node, "minInclusive")) {
6624
14.3k
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6625
114k
    } else if (IS_SCHEMA(node, "minExclusive")) {
6626
26.0k
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6627
88.3k
    } else if (IS_SCHEMA(node, "maxInclusive")) {
6628
5.63k
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6629
82.7k
    } else if (IS_SCHEMA(node, "maxExclusive")) {
6630
13.7k
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6631
68.9k
    } else if (IS_SCHEMA(node, "totalDigits")) {
6632
861
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6633
68.1k
    } else if (IS_SCHEMA(node, "fractionDigits")) {
6634
54
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6635
68.0k
    } else if (IS_SCHEMA(node, "pattern")) {
6636
18.0k
        facet->type = XML_SCHEMA_FACET_PATTERN;
6637
49.9k
    } else if (IS_SCHEMA(node, "enumeration")) {
6638
46.0k
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
6639
46.0k
    } else if (IS_SCHEMA(node, "whiteSpace")) {
6640
2.01k
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
6641
2.01k
    } else if (IS_SCHEMA(node, "length")) {
6642
764
        facet->type = XML_SCHEMA_FACET_LENGTH;
6643
1.17k
    } else if (IS_SCHEMA(node, "maxLength")) {
6644
566
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6645
612
    } else if (IS_SCHEMA(node, "minLength")) {
6646
612
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
6647
612
    } else {
6648
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6649
0
                       "Unknown facet type %s\n", node->name, NULL);
6650
0
        xmlSchemaFreeFacet(facet);
6651
0
        return (NULL);
6652
0
    }
6653
128k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6654
128k
    facet->value = value;
6655
128k
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6656
128k
  (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6657
64.6k
  const xmlChar *fixed;
6658
6659
64.6k
  fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6660
64.6k
  if (fixed != NULL) {
6661
13
      if (xmlStrEqual(fixed, BAD_CAST "true"))
6662
12
    facet->fixed = 1;
6663
13
  }
6664
64.6k
    }
6665
128k
    child = node->children;
6666
6667
128k
    if (IS_SCHEMA(child, "annotation")) {
6668
86
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6669
86
        child = child->next;
6670
86
    }
6671
128k
    if (child != NULL) {
6672
37
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6673
37
                       "Facet %s has unexpected child content\n",
6674
37
                       node->name, NULL);
6675
37
    }
6676
128k
    return (facet);
6677
128k
}
6678
6679
/**
6680
 * xmlSchemaParseWildcardNs:
6681
 * @ctxt:  a schema parser context
6682
 * @wildc:  the wildcard, already created
6683
 * @node:  a subtree containing XML Schema information
6684
 *
6685
 * Parses the attribute "processContents" and "namespace"
6686
 * of a xsd:anyAttribute and xsd:any.
6687
 * *WARNING* this interface is highly subject to change
6688
 *
6689
 * Returns 0 if everything goes fine, a positive error code
6690
 * if something is not valid and -1 if an internal error occurs.
6691
 */
6692
static int
6693
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6694
       xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6695
       xmlSchemaWildcardPtr wildc,
6696
       xmlNodePtr node)
6697
8.68k
{
6698
8.68k
    const xmlChar *pc, *ns, *dictnsItem;
6699
8.68k
    int ret = 0;
6700
8.68k
    xmlChar *nsItem;
6701
8.68k
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6702
8.68k
    xmlAttrPtr attr;
6703
6704
8.68k
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
6705
8.68k
    if ((pc == NULL)
6706
8.68k
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6707
6.78k
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6708
6.78k
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6709
194
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6710
1.70k
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6711
1.66k
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
6712
1.66k
    } else {
6713
39
        xmlSchemaPSimpleTypeErr(ctxt,
6714
39
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6715
39
      NULL, node,
6716
39
      NULL, "(strict | skip | lax)", pc,
6717
39
      NULL, NULL, NULL);
6718
39
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6719
39
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6720
39
    }
6721
    /*
6722
     * Build the namespace constraints.
6723
     */
6724
8.68k
    attr = xmlSchemaGetPropNode(node, "namespace");
6725
8.68k
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6726
8.68k
    if (ns == NULL)
6727
0
        return (-1);
6728
8.68k
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6729
3.59k
  wildc->any = 1;
6730
5.08k
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6731
1.07k
  wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6732
1.07k
  if (wildc->negNsSet == NULL) {
6733
0
      return (-1);
6734
0
  }
6735
1.07k
  wildc->negNsSet->value = ctxt->targetNamespace;
6736
4.01k
    } else {
6737
4.01k
  const xmlChar *end, *cur;
6738
6739
4.01k
  cur = ns;
6740
80.3k
  do {
6741
80.3k
      while (IS_BLANK_CH(*cur))
6742
86.0k
    cur++;
6743
80.3k
      end = cur;
6744
609k
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6745
529k
    end++;
6746
80.3k
      if (end == cur)
6747
1.03k
    break;
6748
79.3k
      nsItem = xmlStrndup(cur, end - cur);
6749
79.3k
      if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6750
79.3k
        (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6751
1.11k
    xmlSchemaPSimpleTypeErr(ctxt,
6752
1.11k
        XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6753
1.11k
        NULL, (xmlNodePtr) attr,
6754
1.11k
        NULL,
6755
1.11k
        "((##any | ##other) | List of (xs:anyURI | "
6756
1.11k
        "(##targetNamespace | ##local)))",
6757
1.11k
        nsItem, NULL, NULL, NULL);
6758
1.11k
    ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6759
78.2k
      } else {
6760
78.2k
    if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6761
510
        dictnsItem = ctxt->targetNamespace;
6762
77.7k
    } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6763
288
        dictnsItem = NULL;
6764
77.4k
    } else {
6765
        /*
6766
        * Validate the item (anyURI).
6767
        */
6768
77.4k
        xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6769
77.4k
      nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6770
77.4k
        dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6771
77.4k
    }
6772
    /*
6773
    * Avoid duplicate namespaces.
6774
    */
6775
78.2k
    tmp = wildc->nsSet;
6776
1.30M
    while (tmp != NULL) {
6777
1.26M
        if (dictnsItem == tmp->value)
6778
37.8k
      break;
6779
1.22M
        tmp = tmp->next;
6780
1.22M
    }
6781
78.2k
    if (tmp == NULL) {
6782
40.3k
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6783
40.3k
        if (tmp == NULL) {
6784
0
      xmlFree(nsItem);
6785
0
      return (-1);
6786
0
        }
6787
40.3k
        tmp->value = dictnsItem;
6788
40.3k
        tmp->next = NULL;
6789
40.3k
        if (wildc->nsSet == NULL)
6790
3.83k
      wildc->nsSet = tmp;
6791
36.5k
        else if (lastNs != NULL)
6792
36.5k
      lastNs->next = tmp;
6793
40.3k
        lastNs = tmp;
6794
40.3k
    }
6795
6796
78.2k
      }
6797
79.3k
      xmlFree(nsItem);
6798
79.3k
      cur = end;
6799
79.3k
  } while (*cur != 0);
6800
4.01k
    }
6801
8.68k
    return (ret);
6802
8.68k
}
6803
6804
static int
6805
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6806
         xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6807
         xmlNodePtr node,
6808
         int minOccurs,
6809
21.5k
         int maxOccurs) {
6810
6811
21.5k
    if ((maxOccurs == 0) && ( minOccurs == 0))
6812
547
  return (0);
6813
20.9k
    if (maxOccurs != UNBOUNDED) {
6814
  /*
6815
  * TODO: Maybe we should better not create the particle,
6816
  * if min/max is invalid, since it could confuse the build of the
6817
  * content model.
6818
  */
6819
  /*
6820
  * 3.9.6 Schema Component Constraint: Particle Correct
6821
  *
6822
  */
6823
19.5k
  if (maxOccurs < 1) {
6824
      /*
6825
      * 2.2 {max occurs} must be greater than or equal to 1.
6826
      */
6827
114
      xmlSchemaPCustomAttrErr(ctxt,
6828
114
    XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6829
114
    NULL, NULL,
6830
114
    xmlSchemaGetPropNode(node, "maxOccurs"),
6831
114
    "The value must be greater than or equal to 1");
6832
114
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6833
19.4k
  } else if (minOccurs > maxOccurs) {
6834
      /*
6835
      * 2.1 {min occurs} must not be greater than {max occurs}.
6836
      */
6837
1.19k
      xmlSchemaPCustomAttrErr(ctxt,
6838
1.19k
    XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6839
1.19k
    NULL, NULL,
6840
1.19k
    xmlSchemaGetPropNode(node, "minOccurs"),
6841
1.19k
    "The value must not be greater than the value of 'maxOccurs'");
6842
1.19k
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6843
1.19k
  }
6844
19.5k
    }
6845
19.6k
    return (0);
6846
20.9k
}
6847
6848
/**
6849
 * xmlSchemaParseAny:
6850
 * @ctxt:  a schema validation context
6851
 * @schema:  the schema being built
6852
 * @node:  a subtree containing XML Schema information
6853
 *
6854
 * Parsea a XML schema <any> element. A particle and wildcard
6855
 * will be created (except if minOccurs==maxOccurs==0, in this case
6856
 * nothing will be created).
6857
 * *WARNING* this interface is highly subject to change
6858
 *
6859
 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6860
 */
6861
static xmlSchemaParticlePtr
6862
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6863
                  xmlNodePtr node)
6864
6.27k
{
6865
6.27k
    xmlSchemaParticlePtr particle;
6866
6.27k
    xmlNodePtr child = NULL;
6867
6.27k
    xmlSchemaWildcardPtr wild;
6868
6.27k
    int min, max;
6869
6.27k
    xmlAttrPtr attr;
6870
6.27k
    xmlSchemaAnnotPtr annot = NULL;
6871
6872
6.27k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6873
0
        return (NULL);
6874
    /*
6875
    * Check for illegal attributes.
6876
    */
6877
6.27k
    attr = node->properties;
6878
15.9k
    while (attr != NULL) {
6879
9.68k
  if (attr->ns == NULL) {
6880
9.02k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6881
9.02k
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
6882
9.02k
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
6883
9.02k
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6884
9.02k
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6885
2.67k
    xmlSchemaPIllegalAttrErr(ctxt,
6886
2.67k
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6887
2.67k
      }
6888
9.02k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6889
68
      xmlSchemaPIllegalAttrErr(ctxt,
6890
68
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6891
68
  }
6892
9.68k
  attr = attr->next;
6893
9.68k
    }
6894
6.27k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6895
    /*
6896
    * minOccurs/maxOccurs.
6897
    */
6898
6.27k
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
6899
6.27k
  "(xs:nonNegativeInteger | unbounded)");
6900
6.27k
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
6901
6.27k
  "xs:nonNegativeInteger");
6902
6.27k
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
6903
    /*
6904
    * Create & parse the wildcard.
6905
    */
6906
6.27k
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6907
6.27k
    if (wild == NULL)
6908
0
  return (NULL);
6909
6.27k
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6910
    /*
6911
    * And now for the children...
6912
    */
6913
6.27k
    child = node->children;
6914
6.27k
    if (IS_SCHEMA(child, "annotation")) {
6915
3
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6916
3
        child = child->next;
6917
3
    }
6918
6.27k
    if (child != NULL) {
6919
25
  xmlSchemaPContentErr(ctxt,
6920
25
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6921
25
      NULL, node, child,
6922
25
      NULL, "(annotation?)");
6923
25
    }
6924
    /*
6925
    * No component if minOccurs==maxOccurs==0.
6926
    */
6927
6.27k
    if ((min == 0) && (max == 0)) {
6928
  /* Don't free the wildcard, since it's already on the list. */
6929
381
  return (NULL);
6930
381
    }
6931
    /*
6932
    * Create the particle.
6933
    */
6934
5.88k
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
6935
5.88k
    if (particle == NULL)
6936
0
        return (NULL);
6937
5.88k
    particle->annot = annot;
6938
5.88k
    particle->children = (xmlSchemaTreeItemPtr) wild;
6939
6940
5.88k
    return (particle);
6941
5.88k
}
6942
6943
/**
6944
 * xmlSchemaParseNotation:
6945
 * @ctxt:  a schema validation context
6946
 * @schema:  the schema being built
6947
 * @node:  a subtree containing XML Schema information
6948
 *
6949
 * parse a XML schema Notation declaration
6950
 *
6951
 * Returns the new structure or NULL in case of error
6952
 */
6953
static xmlSchemaNotationPtr
6954
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6955
                       xmlNodePtr node)
6956
1.73k
{
6957
1.73k
    const xmlChar *name;
6958
1.73k
    xmlSchemaNotationPtr ret;
6959
1.73k
    xmlNodePtr child = NULL;
6960
6961
1.73k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6962
0
        return (NULL);
6963
1.73k
    name = xmlSchemaGetProp(ctxt, node, "name");
6964
1.73k
    if (name == NULL) {
6965
295
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6966
295
                       "Notation has no name\n", NULL, NULL);
6967
295
        return (NULL);
6968
295
    }
6969
1.43k
    ret = xmlSchemaAddNotation(ctxt, schema, name,
6970
1.43k
  ctxt->targetNamespace, node);
6971
1.43k
    if (ret == NULL)
6972
0
        return (NULL);
6973
1.43k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6974
6975
1.43k
    child = node->children;
6976
1.43k
    if (IS_SCHEMA(child, "annotation")) {
6977
312
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6978
312
        child = child->next;
6979
312
    }
6980
1.43k
    if (child != NULL) {
6981
676
  xmlSchemaPContentErr(ctxt,
6982
676
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6983
676
      NULL, node, child,
6984
676
      NULL, "(annotation?)");
6985
676
    }
6986
6987
1.43k
    return (ret);
6988
1.43k
}
6989
6990
/**
6991
 * xmlSchemaParseAnyAttribute:
6992
 * @ctxt:  a schema validation context
6993
 * @schema:  the schema being built
6994
 * @node:  a subtree containing XML Schema information
6995
 *
6996
 * parse a XML schema AnyAttribute declaration
6997
 * *WARNING* this interface is highly subject to change
6998
 *
6999
 * Returns a wildcard or NULL.
7000
 */
7001
static xmlSchemaWildcardPtr
7002
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7003
                           xmlSchemaPtr schema, xmlNodePtr node)
7004
2.41k
{
7005
2.41k
    xmlSchemaWildcardPtr ret;
7006
2.41k
    xmlNodePtr child = NULL;
7007
2.41k
    xmlAttrPtr attr;
7008
7009
2.41k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7010
0
        return (NULL);
7011
7012
2.41k
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7013
2.41k
  node);
7014
2.41k
    if (ret == NULL) {
7015
0
        return (NULL);
7016
0
    }
7017
    /*
7018
    * Check for illegal attributes.
7019
    */
7020
2.41k
    attr = node->properties;
7021
6.70k
    while (attr != NULL) {
7022
4.29k
  if (attr->ns == NULL) {
7023
4.21k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7024
4.21k
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7025
4.21k
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7026
162
    xmlSchemaPIllegalAttrErr(ctxt,
7027
162
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7028
162
      }
7029
4.21k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7030
0
      xmlSchemaPIllegalAttrErr(ctxt,
7031
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7032
0
  }
7033
4.29k
  attr = attr->next;
7034
4.29k
    }
7035
2.41k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7036
    /*
7037
    * Parse the namespace list.
7038
    */
7039
2.41k
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7040
93
  return (NULL);
7041
    /*
7042
    * And now for the children...
7043
    */
7044
2.32k
    child = node->children;
7045
2.32k
    if (IS_SCHEMA(child, "annotation")) {
7046
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7047
0
        child = child->next;
7048
0
    }
7049
2.32k
    if (child != NULL) {
7050
34
  xmlSchemaPContentErr(ctxt,
7051
34
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7052
34
      NULL, node, child,
7053
34
      NULL, "(annotation?)");
7054
34
    }
7055
7056
2.32k
    return (ret);
7057
2.41k
}
7058
7059
7060
/**
7061
 * xmlSchemaParseAttribute:
7062
 * @ctxt:  a schema validation context
7063
 * @schema:  the schema being built
7064
 * @node:  a subtree containing XML Schema information
7065
 *
7066
 * parse a XML schema Attribute declaration
7067
 * *WARNING* this interface is highly subject to change
7068
 *
7069
 * Returns the attribute declaration.
7070
 */
7071
static xmlSchemaBasicItemPtr
7072
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7073
           xmlSchemaPtr schema,
7074
           xmlNodePtr node,
7075
           xmlSchemaItemListPtr uses,
7076
           int parentType)
7077
7.12k
{
7078
7.12k
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
7079
7.12k
    xmlSchemaAttributeUsePtr use = NULL;
7080
7.12k
    xmlNodePtr child = NULL;
7081
7.12k
    xmlAttrPtr attr;
7082
7.12k
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7083
7.12k
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7084
7.12k
    int nberrors, hasForm = 0, defValueType = 0;
7085
7086
7.28k
#define WXS_ATTR_DEF_VAL_DEFAULT 1
7087
7.12k
#define WXS_ATTR_DEF_VAL_FIXED 2
7088
7089
    /*
7090
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7091
     */
7092
7093
7.12k
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7094
0
        return (NULL);
7095
7.12k
    attr = xmlSchemaGetPropNode(node, "ref");
7096
7.12k
    if (attr != NULL) {
7097
2.62k
  if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7098
2.62k
      NULL, attr, &tmpNs, &tmpName) != 0) {
7099
81
      return (NULL);
7100
81
  }
7101
2.54k
  if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7102
50
      return(NULL);
7103
2.49k
  isRef = 1;
7104
2.49k
    }
7105
6.99k
    nberrors = pctxt->nberrors;
7106
    /*
7107
    * Check for illegal attributes.
7108
    */
7109
6.99k
    attr = node->properties;
7110
24.0k
    while (attr != NULL) {
7111
17.0k
  if (attr->ns == NULL) {
7112
13.2k
      if (isRef) {
7113
5.30k
    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7114
10
        xmlSchemaPValAttrNodeID(pctxt, attr);
7115
10
        goto attr_next;
7116
5.29k
    } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7117
2.49k
        goto attr_next;
7118
2.49k
    }
7119
7.96k
      } else {
7120
7.96k
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7121
3.95k
        goto attr_next;
7122
4.01k
    } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7123
61
        xmlSchemaPValAttrNodeID(pctxt, attr);
7124
61
        goto attr_next;
7125
3.95k
    } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7126
1.79k
        xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7127
1.79k
      attr, &tmpNs, &tmpName);
7128
1.79k
        goto attr_next;
7129
2.15k
    } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7130
        /*
7131
        * Evaluate the target namespace
7132
        */
7133
128
        hasForm = 1;
7134
128
        attrValue = xmlSchemaGetNodeContent(pctxt,
7135
128
      (xmlNodePtr) attr);
7136
128
        if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7137
107
      ns = pctxt->targetNamespace;
7138
107
        } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7139
21
        {
7140
21
      xmlSchemaPSimpleTypeErr(pctxt,
7141
21
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7142
21
          NULL, (xmlNodePtr) attr,
7143
21
          NULL, "(qualified | unqualified)",
7144
21
          attrValue, NULL, NULL, NULL);
7145
21
        }
7146
128
        goto attr_next;
7147
128
    }
7148
7.96k
      }
7149
4.83k
      if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7150
7151
1.60k
    attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7152
    /* TODO: Maybe we need to normalize the value beforehand. */
7153
1.60k
    if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7154
186
        occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7155
1.41k
    else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7156
455
        occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7157
960
    else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7158
798
        occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7159
162
    else {
7160
162
        xmlSchemaPSimpleTypeErr(pctxt,
7161
162
      XML_SCHEMAP_INVALID_ATTR_USE,
7162
162
      NULL, (xmlNodePtr) attr,
7163
162
      NULL, "(optional | prohibited | required)",
7164
162
      attrValue, NULL, NULL, NULL);
7165
162
    }
7166
1.60k
    goto attr_next;
7167
3.23k
      } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7168
    /*
7169
    * 3.2.3 : 1
7170
    * default and fixed must not both be present.
7171
    */
7172
804
    if (defValue) {
7173
508
        xmlSchemaPMutualExclAttrErr(pctxt,
7174
508
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7175
508
      NULL, attr, "default", "fixed");
7176
508
    } else {
7177
296
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7178
296
        defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7179
296
    }
7180
804
    goto attr_next;
7181
2.42k
      } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7182
    /*
7183
    * 3.2.3 : 1
7184
    * default and fixed must not both be present.
7185
    */
7186
1.88k
    if (defValue) {
7187
4
        xmlSchemaPMutualExclAttrErr(pctxt,
7188
4
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7189
4
      NULL, attr, "default", "fixed");
7190
1.88k
    } else {
7191
1.88k
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7192
1.88k
        defValueType = WXS_ATTR_DEF_VAL_FIXED;
7193
1.88k
    }
7194
1.88k
    goto attr_next;
7195
1.88k
      }
7196
4.83k
  } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7197
3.73k
      goto attr_next;
7198
7199
544
  xmlSchemaPIllegalAttrErr(pctxt,
7200
544
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7201
7202
17.0k
attr_next:
7203
17.0k
  attr = attr->next;
7204
17.0k
    }
7205
    /*
7206
    * 3.2.3 : 2
7207
    * If default and use are both present, use must have
7208
    * the actual value optional.
7209
    */
7210
6.99k
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7211
6.99k
  (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7212
180
  xmlSchemaPSimpleTypeErr(pctxt,
7213
180
      XML_SCHEMAP_SRC_ATTRIBUTE_2,
7214
180
      NULL, node, NULL,
7215
180
      "(optional | prohibited | required)", NULL,
7216
180
      "The value of the attribute 'use' must be 'optional' "
7217
180
      "if the attribute 'default' is present",
7218
180
      NULL, NULL);
7219
180
    }
7220
    /*
7221
    * We want correct attributes.
7222
    */
7223
6.99k
    if (nberrors != pctxt->nberrors)
7224
1.43k
  return(NULL);
7225
5.56k
    if (! isRef) {
7226
3.99k
  xmlSchemaAttributePtr attrDecl;
7227
7228
  /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7229
3.99k
  if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7230
13
      ns = pctxt->targetNamespace;
7231
  /*
7232
  * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7233
  * TODO: Move this to the component layer.
7234
  */
7235
3.99k
  if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7236
14
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7237
14
    XML_SCHEMAP_NO_XSI,
7238
14
    node, NULL,
7239
14
    "The target namespace must not match '%s'",
7240
14
    xmlSchemaInstanceNs, NULL);
7241
14
  }
7242
3.99k
  attr = xmlSchemaGetPropNode(node, "name");
7243
3.99k
  if (attr == NULL) {
7244
417
      xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7245
417
    NULL, node, "name", NULL);
7246
417
      return (NULL);
7247
417
  }
7248
3.57k
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7249
3.57k
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7250
234
      return (NULL);
7251
234
  }
7252
  /*
7253
  * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7254
  * TODO: Move this to the component layer.
7255
  */
7256
3.33k
  if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7257
1
      xmlSchemaPSimpleTypeErr(pctxt,
7258
1
    XML_SCHEMAP_NO_XMLNS,
7259
1
    NULL, (xmlNodePtr) attr,
7260
1
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7261
1
    "The value of the attribute must not match 'xmlns'",
7262
1
    NULL, NULL);
7263
1
      return (NULL);
7264
1
  }
7265
3.33k
  if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7266
448
      goto check_children;
7267
  /*
7268
  * Create the attribute use component.
7269
  */
7270
2.89k
  use = xmlSchemaAddAttributeUse(pctxt, node);
7271
2.89k
  if (use == NULL)
7272
0
      return(NULL);
7273
2.89k
  use->occurs = occurs;
7274
  /*
7275
  * Create the attribute declaration.
7276
  */
7277
2.89k
  attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7278
2.89k
  if (attrDecl == NULL)
7279
0
      return (NULL);
7280
2.89k
  if (tmpName != NULL) {
7281
1.15k
      attrDecl->typeName = tmpName;
7282
1.15k
      attrDecl->typeNs = tmpNs;
7283
1.15k
  }
7284
2.89k
  use->attrDecl = attrDecl;
7285
  /*
7286
  * Value constraint.
7287
  */
7288
2.89k
  if (defValue != NULL) {
7289
64
      attrDecl->defValue = defValue;
7290
64
      if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7291
1
    attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7292
64
  }
7293
2.89k
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7294
1.57k
  xmlSchemaQNameRefPtr ref;
7295
7296
  /*
7297
  * Create the attribute use component.
7298
  */
7299
1.57k
  use = xmlSchemaAddAttributeUse(pctxt, node);
7300
1.57k
  if (use == NULL)
7301
0
      return(NULL);
7302
  /*
7303
  * We need to resolve the reference at later stage.
7304
  */
7305
1.57k
  WXS_ADD_PENDING(pctxt, use);
7306
1.57k
  use->occurs = occurs;
7307
  /*
7308
  * Create a QName reference to the attribute declaration.
7309
  */
7310
1.57k
  ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7311
1.57k
      tmpName, tmpNs);
7312
1.57k
  if (ref == NULL)
7313
0
      return(NULL);
7314
  /*
7315
  * Assign the reference. This will be substituted for the
7316
  * referenced attribute declaration when the QName is resolved.
7317
  */
7318
1.57k
  use->attrDecl = WXS_ATTR_CAST ref;
7319
  /*
7320
  * Value constraint.
7321
  */
7322
1.57k
  if (defValue != NULL)
7323
998
      use->defValue = defValue;
7324
1.57k
  if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7325
998
      use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7326
1.57k
    }
7327
7328
4.91k
check_children:
7329
    /*
7330
    * And now for the children...
7331
    */
7332
4.91k
    child = node->children;
7333
4.91k
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7334
448
  xmlSchemaAttributeUseProhibPtr prohib;
7335
7336
448
  if (IS_SCHEMA(child, "annotation")) {
7337
10
      xmlSchemaParseAnnotation(pctxt, child, 0);
7338
10
      child = child->next;
7339
10
  }
7340
448
  if (child != NULL) {
7341
134
      xmlSchemaPContentErr(pctxt,
7342
134
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7343
134
    NULL, node, child, NULL,
7344
134
    "(annotation?)");
7345
134
  }
7346
  /*
7347
  * Check for pointlessness of attribute prohibitions.
7348
  */
7349
448
  if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7350
1
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7351
1
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7352
1
    node, NULL,
7353
1
    "Skipping attribute use prohibition, since it is "
7354
1
    "pointless inside an <attributeGroup>",
7355
1
    NULL, NULL, NULL);
7356
1
      return(NULL);
7357
447
  } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7358
2
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7359
2
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7360
2
    node, NULL,
7361
2
    "Skipping attribute use prohibition, since it is "
7362
2
    "pointless when extending a type",
7363
2
    NULL, NULL, NULL);
7364
2
      return(NULL);
7365
2
  }
7366
445
  if (! isRef) {
7367
445
      tmpName = name;
7368
445
      tmpNs = ns;
7369
445
  }
7370
  /*
7371
  * Check for duplicate attribute prohibitions.
7372
  */
7373
445
  if (uses) {
7374
190
      int i;
7375
7376
4.80k
      for (i = 0; i < uses->nbItems; i++) {
7377
4.63k
    use = uses->items[i];
7378
4.63k
    if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7379
4.63k
        (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7380
4.63k
        (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7381
14
    {
7382
14
        xmlChar *str = NULL;
7383
7384
14
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7385
14
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7386
14
      node, NULL,
7387
14
      "Skipping duplicate attribute use prohibition '%s'",
7388
14
      xmlSchemaFormatQName(&str, tmpNs, tmpName),
7389
14
      NULL, NULL);
7390
14
        FREE_AND_NULL(str)
7391
14
        return(NULL);
7392
14
    }
7393
4.63k
      }
7394
190
  }
7395
  /*
7396
  * Create the attribute prohibition helper component.
7397
  */
7398
431
  prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7399
431
  if (prohib == NULL)
7400
0
      return(NULL);
7401
431
  prohib->node = node;
7402
431
  prohib->name = tmpName;
7403
431
  prohib->targetNamespace = tmpNs;
7404
431
  if (isRef) {
7405
      /*
7406
      * We need at least to resolve to the attribute declaration.
7407
      */
7408
0
      WXS_ADD_PENDING(pctxt, prohib);
7409
0
  }
7410
431
  return(WXS_BASIC_CAST prohib);
7411
4.46k
    } else {
7412
4.46k
  if (IS_SCHEMA(child, "annotation")) {
7413
      /*
7414
      * TODO: Should this go into the attr decl?
7415
      */
7416
85
      use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7417
85
      child = child->next;
7418
85
  }
7419
4.46k
  if (isRef) {
7420
1.57k
      if (child != NULL) {
7421
879
    if (IS_SCHEMA(child, "simpleType"))
7422
        /*
7423
        * 3.2.3 : 3.2
7424
        * If ref is present, then all of <simpleType>,
7425
        * form and type must be absent.
7426
        */
7427
1
        xmlSchemaPContentErr(pctxt,
7428
1
      XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7429
1
      NULL, node, child, NULL,
7430
1
      "(annotation?)");
7431
878
    else
7432
878
        xmlSchemaPContentErr(pctxt,
7433
878
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7434
878
      NULL, node, child, NULL,
7435
878
      "(annotation?)");
7436
879
      }
7437
2.89k
  } else {
7438
2.89k
      if (IS_SCHEMA(child, "simpleType")) {
7439
113
    if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7440
        /*
7441
        * 3.2.3 : 4
7442
        * type and <simpleType> must not both be present.
7443
        */
7444
10
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7445
10
      NULL, node, child,
7446
10
      "The attribute 'type' and the <simpleType> child "
7447
10
      "are mutually exclusive", NULL);
7448
10
    } else
7449
103
        WXS_ATTRUSE_TYPEDEF(use) =
7450
103
      xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7451
113
    child = child->next;
7452
113
      }
7453
2.89k
      if (child != NULL)
7454
68
    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7455
68
    NULL, node, child, NULL,
7456
68
    "(annotation?, simpleType?)");
7457
2.89k
  }
7458
4.46k
    }
7459
4.46k
    return (WXS_BASIC_CAST use);
7460
4.91k
}
7461
7462
7463
static xmlSchemaAttributePtr
7464
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7465
            xmlSchemaPtr schema,
7466
            xmlNodePtr node)
7467
4.01k
{
7468
4.01k
    const xmlChar *attrValue;
7469
4.01k
    xmlSchemaAttributePtr ret;
7470
4.01k
    xmlNodePtr child = NULL;
7471
4.01k
    xmlAttrPtr attr;
7472
7473
    /*
7474
     * Note that the w3c spec assumes the schema to be validated with schema
7475
     * for schemas beforehand.
7476
     *
7477
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7478
     */
7479
4.01k
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7480
0
        return (NULL);
7481
    /*
7482
    * 3.2.3 : 3.1
7483
    * One of ref or name must be present, but not both
7484
    */
7485
4.01k
    attr = xmlSchemaGetPropNode(node, "name");
7486
4.01k
    if (attr == NULL) {
7487
770
  xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7488
770
      NULL, node, "name", NULL);
7489
770
  return (NULL);
7490
770
    }
7491
3.24k
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7492
3.24k
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7493
395
  return (NULL);
7494
395
    }
7495
    /*
7496
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7497
    * TODO: Move this to the component layer.
7498
    */
7499
2.85k
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7500
167
  xmlSchemaPSimpleTypeErr(pctxt,
7501
167
      XML_SCHEMAP_NO_XMLNS,
7502
167
      NULL, (xmlNodePtr) attr,
7503
167
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7504
167
      "The value of the attribute must not match 'xmlns'",
7505
167
      NULL, NULL);
7506
167
  return (NULL);
7507
167
    }
7508
    /*
7509
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7510
    * TODO: Move this to the component layer.
7511
    *       Or better leave it here and add it to the component layer
7512
    *       if we have a schema construction API.
7513
    */
7514
2.68k
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7515
6
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
7516
6
      XML_SCHEMAP_NO_XSI, node, NULL,
7517
6
      "The target namespace must not match '%s'",
7518
6
      xmlSchemaInstanceNs, NULL);
7519
6
    }
7520
7521
2.68k
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7522
2.68k
  pctxt->targetNamespace, node, 1);
7523
2.68k
    if (ret == NULL)
7524
0
  return (NULL);
7525
2.68k
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7526
7527
    /*
7528
    * Check for illegal attributes.
7529
    */
7530
2.68k
    attr = node->properties;
7531
9.77k
    while (attr != NULL) {
7532
7.09k
  if (attr->ns == NULL) {
7533
6.64k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7534
6.64k
    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7535
6.64k
    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7536
6.64k
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7537
6.64k
    (!xmlStrEqual(attr->name, BAD_CAST "type")))
7538
1.62k
      {
7539
1.62k
    xmlSchemaPIllegalAttrErr(pctxt,
7540
1.62k
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7541
1.62k
      }
7542
6.64k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7543
139
      xmlSchemaPIllegalAttrErr(pctxt,
7544
139
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7545
139
  }
7546
7.09k
  attr = attr->next;
7547
7.09k
    }
7548
2.68k
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
7549
2.68k
  node, "type", &ret->typeNs, &ret->typeName);
7550
7551
2.68k
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7552
    /*
7553
    * Attribute "fixed".
7554
    */
7555
2.68k
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7556
2.68k
    if (ret->defValue != NULL)
7557
124
  ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7558
    /*
7559
    * Attribute "default".
7560
    */
7561
2.68k
    attr = xmlSchemaGetPropNode(node, "default");
7562
2.68k
    if (attr != NULL) {
7563
  /*
7564
  * 3.2.3 : 1
7565
  * default and fixed must not both be present.
7566
  */
7567
671
  if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7568
119
      xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7569
119
    WXS_BASIC_CAST ret, attr, "default", "fixed");
7570
119
  } else
7571
552
      ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7572
671
    }
7573
    /*
7574
    * And now for the children...
7575
    */
7576
2.68k
    child = node->children;
7577
2.68k
    if (IS_SCHEMA(child, "annotation")) {
7578
99
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7579
99
        child = child->next;
7580
99
    }
7581
2.68k
    if (IS_SCHEMA(child, "simpleType")) {
7582
534
  if (ret->typeName != NULL) {
7583
      /*
7584
      * 3.2.3 : 4
7585
      * type and <simpleType> must not both be present.
7586
      */
7587
12
      xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7588
12
    NULL, node, child,
7589
12
    "The attribute 'type' and the <simpleType> child "
7590
12
    "are mutually exclusive", NULL);
7591
12
  } else
7592
522
      ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7593
534
  child = child->next;
7594
534
    }
7595
2.68k
    if (child != NULL)
7596
274
  xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7597
274
      NULL, node, child, NULL,
7598
274
      "(annotation?, simpleType?)");
7599
7600
2.68k
    return (ret);
7601
2.68k
}
7602
7603
/**
7604
 * xmlSchemaParseAttributeGroupRef:
7605
 * @ctxt:  a schema validation context
7606
 * @schema:  the schema being built
7607
 * @node:  a subtree containing XML Schema information
7608
 *
7609
 * Parse an attribute group definition reference.
7610
 * Note that a reference to an attribute group does not
7611
 * correspond to any component at all.
7612
 * *WARNING* this interface is highly subject to change
7613
 *
7614
 * Returns the attribute group or NULL in case of error.
7615
 */
7616
static xmlSchemaQNameRefPtr
7617
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7618
        xmlSchemaPtr schema,
7619
        xmlNodePtr node)
7620
3.69k
{
7621
3.69k
    xmlSchemaQNameRefPtr ret;
7622
3.69k
    xmlNodePtr child = NULL;
7623
3.69k
    xmlAttrPtr attr;
7624
3.69k
    const xmlChar *refNs = NULL, *ref = NULL;
7625
7626
3.69k
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7627
0
        return (NULL);
7628
7629
3.69k
    attr = xmlSchemaGetPropNode(node, "ref");
7630
3.69k
    if (attr == NULL) {
7631
399
  xmlSchemaPMissingAttrErr(pctxt,
7632
399
      XML_SCHEMAP_S4S_ATTR_MISSING,
7633
399
      NULL, node, "ref", NULL);
7634
399
  return (NULL);
7635
399
    }
7636
3.29k
    xmlSchemaPValAttrNodeQName(pctxt, schema,
7637
3.29k
  NULL, attr, &refNs, &ref);
7638
3.29k
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7639
284
  return(NULL);
7640
7641
    /*
7642
    * Check for illegal attributes.
7643
    */
7644
3.00k
    attr = node->properties;
7645
6.52k
    while (attr != NULL) {
7646
3.51k
  if (attr->ns == NULL) {
7647
3.19k
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7648
3.19k
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7649
166
      {
7650
166
    xmlSchemaPIllegalAttrErr(pctxt,
7651
166
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7652
166
      }
7653
3.19k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7654
42
      xmlSchemaPIllegalAttrErr(pctxt,
7655
42
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7656
42
  }
7657
3.51k
  attr = attr->next;
7658
3.51k
    }
7659
    /* Attribute ID */
7660
3.00k
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7661
7662
    /*
7663
    * And now for the children...
7664
    */
7665
3.00k
    child = node->children;
7666
3.00k
    if (IS_SCHEMA(child, "annotation")) {
7667
  /*
7668
  * TODO: We do not have a place to store the annotation, do we?
7669
  */
7670
19
        xmlSchemaParseAnnotation(pctxt, child, 0);
7671
19
        child = child->next;
7672
19
    }
7673
3.00k
    if (child != NULL) {
7674
116
  xmlSchemaPContentErr(pctxt,
7675
116
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7676
116
      NULL, node, child, NULL,
7677
116
      "(annotation?)");
7678
116
    }
7679
7680
    /*
7681
    * Handle attribute group redefinitions.
7682
    */
7683
3.00k
    if (pctxt->isRedefine && pctxt->redef &&
7684
3.00k
  (pctxt->redef->item->type ==
7685
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7686
3.00k
  (ref == pctxt->redef->refName) &&
7687
3.00k
  (refNs == pctxt->redef->refTargetNs))
7688
0
    {
7689
  /*
7690
  * SPEC src-redefine:
7691
  * (7.1) "If it has an <attributeGroup> among its contents
7692
  * the `actual value` of whose ref [attribute] is the same
7693
  * as the `actual value` of its own name attribute plus
7694
  * target namespace, then it must have exactly one such group."
7695
  */
7696
0
  if (pctxt->redefCounter != 0) {
7697
0
      xmlChar *str = NULL;
7698
7699
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7700
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7701
0
    "The redefining attribute group definition "
7702
0
    "'%s' must not contain more than one "
7703
0
    "reference to the redefined definition",
7704
0
    xmlSchemaFormatQName(&str, refNs, ref), NULL);
7705
0
      FREE_AND_NULL(str);
7706
0
      return(NULL);
7707
0
  }
7708
0
  pctxt->redefCounter++;
7709
  /*
7710
  * URGENT TODO: How to ensure that the reference will not be
7711
  * handled by the normal component resolution mechanism?
7712
  */
7713
0
  ret = xmlSchemaNewQNameRef(pctxt,
7714
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7715
0
  if (ret == NULL)
7716
0
      return(NULL);
7717
0
  ret->node = node;
7718
0
  pctxt->redef->reference = WXS_BASIC_CAST ret;
7719
3.00k
    } else {
7720
  /*
7721
  * Create a QName-reference helper component. We will substitute this
7722
  * component for the attribute uses of the referenced attribute group
7723
  * definition.
7724
  */
7725
3.00k
  ret = xmlSchemaNewQNameRef(pctxt,
7726
3.00k
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7727
3.00k
  if (ret == NULL)
7728
0
      return(NULL);
7729
3.00k
  ret->node = node;
7730
  /* Add to pending items, to be able to resolve the reference. */
7731
3.00k
  WXS_ADD_PENDING(pctxt, ret);
7732
3.00k
    }
7733
3.00k
    return (ret);
7734
3.00k
}
7735
7736
/**
7737
 * xmlSchemaParseAttributeGroupDefinition:
7738
 * @pctxt:  a schema validation context
7739
 * @schema:  the schema being built
7740
 * @node:  a subtree containing XML Schema information
7741
 *
7742
 * parse a XML schema Attribute Group declaration
7743
 * *WARNING* this interface is highly subject to change
7744
 *
7745
 * Returns the attribute group definition or NULL in case of error.
7746
 */
7747
static xmlSchemaAttributeGroupPtr
7748
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7749
               xmlSchemaPtr schema,
7750
               xmlNodePtr node)
7751
3.98k
{
7752
3.98k
    const xmlChar *name;
7753
3.98k
    xmlSchemaAttributeGroupPtr ret;
7754
3.98k
    xmlNodePtr child = NULL;
7755
3.98k
    xmlAttrPtr attr;
7756
3.98k
    int hasRefs = 0;
7757
7758
3.98k
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7759
0
        return (NULL);
7760
7761
3.98k
    attr = xmlSchemaGetPropNode(node, "name");
7762
3.98k
    if (attr == NULL) {
7763
932
  xmlSchemaPMissingAttrErr(pctxt,
7764
932
      XML_SCHEMAP_S4S_ATTR_MISSING,
7765
932
      NULL, node, "name", NULL);
7766
932
  return (NULL);
7767
932
    }
7768
    /*
7769
    * The name is crucial, exit if invalid.
7770
    */
7771
3.05k
    if (xmlSchemaPValAttrNode(pctxt,
7772
3.05k
  NULL, attr,
7773
3.05k
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7774
701
  return (NULL);
7775
701
    }
7776
2.35k
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7777
2.35k
  name, pctxt->targetNamespace, node);
7778
2.35k
    if (ret == NULL)
7779
0
  return (NULL);
7780
    /*
7781
    * Check for illegal attributes.
7782
    */
7783
2.35k
    attr = node->properties;
7784
6.65k
    while (attr != NULL) {
7785
4.30k
  if (attr->ns == NULL) {
7786
3.46k
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7787
3.46k
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7788
540
      {
7789
540
    xmlSchemaPIllegalAttrErr(pctxt,
7790
540
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7791
540
      }
7792
3.46k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7793
424
      xmlSchemaPIllegalAttrErr(pctxt,
7794
424
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7795
424
  }
7796
4.30k
  attr = attr->next;
7797
4.30k
    }
7798
    /* Attribute ID */
7799
2.35k
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7800
    /*
7801
    * And now for the children...
7802
    */
7803
2.35k
    child = node->children;
7804
2.35k
    if (IS_SCHEMA(child, "annotation")) {
7805
1
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7806
1
        child = child->next;
7807
1
    }
7808
    /*
7809
    * Parse contained attribute decls/refs.
7810
    */
7811
2.35k
    if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7812
2.35k
  (xmlSchemaItemListPtr *) &(ret->attrUses),
7813
2.35k
  XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7814
0
  return(NULL);
7815
2.35k
    if (hasRefs)
7816
165
  ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7817
    /*
7818
    * Parse the attribute wildcard.
7819
    */
7820
2.35k
    if (IS_SCHEMA(child, "anyAttribute")) {
7821
596
  ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7822
596
      schema, child);
7823
596
  child = child->next;
7824
596
    }
7825
2.35k
    if (child != NULL) {
7826
363
  xmlSchemaPContentErr(pctxt,
7827
363
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7828
363
      NULL, node, child, NULL,
7829
363
      "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7830
363
    }
7831
2.35k
    return (ret);
7832
2.35k
}
7833
7834
/**
7835
 * xmlSchemaPValAttrFormDefault:
7836
 * @value:  the value
7837
 * @flags: the flags to be modified
7838
 * @flagQualified: the specific flag for "qualified"
7839
 *
7840
 * Returns 0 if the value is valid, 1 otherwise.
7841
 */
7842
static int
7843
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7844
           int *flags,
7845
           int flagQualified)
7846
451
{
7847
451
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
7848
294
  if  ((*flags & flagQualified) == 0)
7849
294
      *flags |= flagQualified;
7850
294
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7851
3
  return (1);
7852
7853
448
    return (0);
7854
451
}
7855
7856
/**
7857
 * xmlSchemaPValAttrBlockFinal:
7858
 * @value:  the value
7859
 * @flags: the flags to be modified
7860
 * @flagAll: the specific flag for "#all"
7861
 * @flagExtension: the specific flag for "extension"
7862
 * @flagRestriction: the specific flag for "restriction"
7863
 * @flagSubstitution: the specific flag for "substitution"
7864
 * @flagList: the specific flag for "list"
7865
 * @flagUnion: the specific flag for "union"
7866
 *
7867
 * Validates the value of the attribute "final" and "block". The value
7868
 * is converted into the specified flag values and returned in @flags.
7869
 *
7870
 * Returns 0 if the value is valid, 1 otherwise.
7871
 */
7872
7873
static int
7874
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7875
          int *flags,
7876
          int flagAll,
7877
          int flagExtension,
7878
          int flagRestriction,
7879
          int flagSubstitution,
7880
          int flagList,
7881
          int flagUnion)
7882
4.71k
{
7883
4.71k
    int ret = 0;
7884
7885
    /*
7886
    * TODO: This does not check for duplicate entries.
7887
    */
7888
4.71k
    if ((flags == NULL) || (value == NULL))
7889
0
  return (-1);
7890
4.71k
    if (value[0] == 0)
7891
374
  return (0);
7892
4.34k
    if (xmlStrEqual(value, BAD_CAST "#all")) {
7893
345
  if (flagAll != -1)
7894
0
      *flags |= flagAll;
7895
345
  else {
7896
345
      if (flagExtension != -1)
7897
75
    *flags |= flagExtension;
7898
345
      if (flagRestriction != -1)
7899
345
    *flags |= flagRestriction;
7900
345
      if (flagSubstitution != -1)
7901
5
    *flags |= flagSubstitution;
7902
345
      if (flagList != -1)
7903
270
    *flags |= flagList;
7904
345
      if (flagUnion != -1)
7905
270
    *flags |= flagUnion;
7906
345
  }
7907
3.99k
    } else {
7908
3.99k
  const xmlChar *end, *cur = value;
7909
3.99k
  xmlChar *item;
7910
7911
8.74k
  do {
7912
8.74k
      while (IS_BLANK_CH(*cur))
7913
12.3k
    cur++;
7914
8.74k
      end = cur;
7915
125k
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
7916
116k
    end++;
7917
8.74k
      if (end == cur)
7918
386
    break;
7919
8.36k
      item = xmlStrndup(cur, end - cur);
7920
8.36k
      if (xmlStrEqual(item, BAD_CAST "extension")) {
7921
2.40k
    if (flagExtension != -1) {
7922
2.21k
        if ((*flags & flagExtension) == 0)
7923
1.37k
      *flags |= flagExtension;
7924
2.21k
    } else
7925
191
        ret = 1;
7926
5.95k
      } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
7927
1.86k
    if (flagRestriction != -1) {
7928
1.86k
        if ((*flags & flagRestriction) == 0)
7929
1.84k
      *flags |= flagRestriction;
7930
1.86k
    } else
7931
0
        ret = 1;
7932
4.08k
      } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
7933
35
    if (flagSubstitution != -1) {
7934
0
        if ((*flags & flagSubstitution) == 0)
7935
0
      *flags |= flagSubstitution;
7936
0
    } else
7937
35
        ret = 1;
7938
4.04k
      } else if (xmlStrEqual(item, BAD_CAST "list")) {
7939
595
    if (flagList != -1) {
7940
0
        if ((*flags & flagList) == 0)
7941
0
      *flags |= flagList;
7942
0
    } else
7943
595
        ret = 1;
7944
3.45k
      } else if (xmlStrEqual(item, BAD_CAST "union")) {
7945
849
    if (flagUnion != -1) {
7946
683
        if ((*flags & flagUnion) == 0)
7947
248
      *flags |= flagUnion;
7948
683
    } else
7949
166
        ret = 1;
7950
849
      } else
7951
2.60k
    ret = 1;
7952
8.36k
      if (item != NULL)
7953
8.36k
    xmlFree(item);
7954
8.36k
      cur = end;
7955
8.36k
  } while ((ret == 0) && (*cur != 0));
7956
3.99k
    }
7957
7958
0
    return (ret);
7959
4.71k
}
7960
7961
static int
7962
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7963
           xmlSchemaIDCPtr idc,
7964
           xmlSchemaIDCSelectPtr selector,
7965
           xmlAttrPtr attr,
7966
           int isField)
7967
22.2k
{
7968
22.2k
    xmlNodePtr node;
7969
7970
    /*
7971
    * c-selector-xpath:
7972
    * Schema Component Constraint: Selector Value OK
7973
    *
7974
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
7975
    * in [XPath].
7976
    */
7977
22.2k
    if (selector == NULL) {
7978
0
  xmlSchemaPErr(ctxt, idc->node,
7979
0
      XML_SCHEMAP_INTERNAL,
7980
0
      "Internal error: xmlSchemaCheckCSelectorXPath, "
7981
0
      "the selector is not specified.\n", NULL, NULL);
7982
0
  return (-1);
7983
0
    }
7984
22.2k
    if (attr == NULL)
7985
0
  node = idc->node;
7986
22.2k
    else
7987
22.2k
  node = (xmlNodePtr) attr;
7988
22.2k
    if (selector->xpath == NULL) {
7989
0
  xmlSchemaPCustomErr(ctxt,
7990
      /* TODO: Adjust error code. */
7991
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7992
0
      NULL, node,
7993
0
      "The XPath expression of the selector is not valid", NULL);
7994
0
  return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
7995
22.2k
    } else {
7996
22.2k
  const xmlChar **nsArray = NULL;
7997
22.2k
  xmlNsPtr *nsList = NULL;
7998
  /*
7999
  * Compile the XPath expression.
8000
  */
8001
  /*
8002
  * TODO: We need the array of in-scope namespaces for compilation.
8003
  * TODO: Call xmlPatterncompile with different options for selector/
8004
  * field.
8005
  */
8006
22.2k
  if (attr == NULL)
8007
0
      nsList = NULL;
8008
22.2k
  else
8009
22.2k
      nsList = xmlGetNsList(attr->doc, attr->parent);
8010
  /*
8011
  * Build an array of prefixes and namespaces.
8012
  */
8013
22.2k
  if (nsList != NULL) {
8014
22.2k
      int i, count = 0;
8015
8016
44.9k
      for (i = 0; nsList[i] != NULL; i++)
8017
22.6k
    count++;
8018
8019
22.2k
      nsArray = (const xmlChar **) xmlMalloc(
8020
22.2k
    (count * 2 + 1) * sizeof(const xmlChar *));
8021
22.2k
      if (nsArray == NULL) {
8022
0
    xmlSchemaPErrMemory(ctxt);
8023
0
    xmlFree(nsList);
8024
0
    return (-1);
8025
0
      }
8026
44.9k
      for (i = 0; i < count; i++) {
8027
22.6k
    nsArray[2 * i] = nsList[i]->href;
8028
22.6k
    nsArray[2 * i + 1] = nsList[i]->prefix;
8029
22.6k
      }
8030
22.2k
      nsArray[count * 2] = NULL;
8031
22.2k
      xmlFree(nsList);
8032
22.2k
  }
8033
  /*
8034
  * TODO: Differentiate between "selector" and "field".
8035
  */
8036
22.2k
  if (isField)
8037
21.2k
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8038
21.2k
    NULL, XML_PATTERN_XSFIELD, nsArray);
8039
1.08k
  else
8040
1.08k
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8041
1.08k
    NULL, XML_PATTERN_XSSEL, nsArray);
8042
22.2k
  if (nsArray != NULL)
8043
22.2k
      xmlFree((xmlChar **) nsArray);
8044
8045
22.2k
  if (selector->xpathComp == NULL) {
8046
19.5k
      xmlSchemaPCustomErr(ctxt,
8047
    /* TODO: Adjust error code? */
8048
19.5k
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8049
19.5k
    NULL, node,
8050
19.5k
    "The XPath expression '%s' could not be "
8051
19.5k
    "compiled", selector->xpath);
8052
19.5k
      return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8053
19.5k
  }
8054
22.2k
    }
8055
2.78k
    return (0);
8056
22.2k
}
8057
8058
#define ADD_ANNOTATION(annot)   \
8059
305
    xmlSchemaAnnotPtr cur = item->annot; \
8060
305
    if (item->annot == NULL) {  \
8061
245
  item->annot = annot;    \
8062
245
  return (annot);         \
8063
245
    }                           \
8064
305
    cur = item->annot;          \
8065
60
    if (cur->next != NULL) {    \
8066
0
  cur = cur->next;  \
8067
0
    }                           \
8068
60
    cur->next = annot;
8069
8070
/**
8071
 * xmlSchemaAssignAnnotation:
8072
 * @item: the schema component
8073
 * @annot: the annotation
8074
 *
8075
 * Adds the annotation to the given schema component.
8076
 *
8077
 * Returns the given annotation.
8078
 */
8079
static xmlSchemaAnnotPtr
8080
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8081
           xmlSchemaAnnotPtr annot)
8082
305
{
8083
305
    if ((annItem == NULL) || (annot == NULL))
8084
0
  return (NULL);
8085
305
    switch (annItem->type) {
8086
0
  case XML_SCHEMA_TYPE_ELEMENT: {
8087
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8088
0
    ADD_ANNOTATION(annot)
8089
0
      }
8090
0
      break;
8091
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
8092
0
    xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8093
0
    ADD_ANNOTATION(annot)
8094
0
      }
8095
0
      break;
8096
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8097
0
  case XML_SCHEMA_TYPE_ANY: {
8098
0
    xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8099
0
    ADD_ANNOTATION(annot)
8100
0
      }
8101
0
      break;
8102
0
  case XML_SCHEMA_TYPE_PARTICLE:
8103
0
  case XML_SCHEMA_TYPE_IDC_KEY:
8104
10
  case XML_SCHEMA_TYPE_IDC_KEYREF:
8105
10
  case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8106
10
    xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8107
10
    ADD_ANNOTATION(annot)
8108
0
      }
8109
0
      break;
8110
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8111
0
    xmlSchemaAttributeGroupPtr item =
8112
0
        (xmlSchemaAttributeGroupPtr) annItem;
8113
0
    ADD_ANNOTATION(annot)
8114
0
      }
8115
0
      break;
8116
0
  case XML_SCHEMA_TYPE_NOTATION: {
8117
0
    xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8118
0
    ADD_ANNOTATION(annot)
8119
0
      }
8120
0
      break;
8121
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
8122
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
8123
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
8124
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8125
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
8126
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
8127
0
  case XML_SCHEMA_FACET_PATTERN:
8128
0
  case XML_SCHEMA_FACET_ENUMERATION:
8129
0
  case XML_SCHEMA_FACET_WHITESPACE:
8130
0
  case XML_SCHEMA_FACET_LENGTH:
8131
0
  case XML_SCHEMA_FACET_MAXLENGTH:
8132
0
  case XML_SCHEMA_FACET_MINLENGTH: {
8133
0
    xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8134
0
    ADD_ANNOTATION(annot)
8135
0
      }
8136
0
      break;
8137
191
  case XML_SCHEMA_TYPE_SIMPLE:
8138
295
  case XML_SCHEMA_TYPE_COMPLEX: {
8139
295
    xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8140
295
    ADD_ANNOTATION(annot)
8141
60
      }
8142
0
      break;
8143
0
  case XML_SCHEMA_TYPE_GROUP: {
8144
0
    xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8145
0
    ADD_ANNOTATION(annot)
8146
0
      }
8147
0
      break;
8148
0
  case XML_SCHEMA_TYPE_SEQUENCE:
8149
0
  case XML_SCHEMA_TYPE_CHOICE:
8150
0
  case XML_SCHEMA_TYPE_ALL: {
8151
0
    xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8152
0
    ADD_ANNOTATION(annot)
8153
0
      }
8154
0
      break;
8155
0
  default:
8156
0
       xmlSchemaPCustomErr(NULL,
8157
0
    XML_SCHEMAP_INTERNAL,
8158
0
    NULL, NULL,
8159
0
    "Internal error: xmlSchemaAddAnnotation, "
8160
0
    "The item is not a annotated schema component", NULL);
8161
0
       break;
8162
305
    }
8163
60
    return (annot);
8164
305
}
8165
8166
/**
8167
 * xmlSchemaParseIDCSelectorAndField:
8168
 * @ctxt:  a schema validation context
8169
 * @schema:  the schema being built
8170
 * @node:  a subtree containing XML Schema information
8171
 *
8172
 * Parses a XML Schema identity-constraint definition's
8173
 * <selector> and <field> elements.
8174
 *
8175
 * Returns the parsed identity-constraint definition.
8176
 */
8177
static xmlSchemaIDCSelectPtr
8178
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8179
        xmlSchemaIDCPtr idc,
8180
        xmlNodePtr node,
8181
        int isField)
8182
24.0k
{
8183
24.0k
    xmlSchemaIDCSelectPtr item;
8184
24.0k
    xmlNodePtr child = NULL;
8185
24.0k
    xmlAttrPtr attr;
8186
8187
    /*
8188
    * Check for illegal attributes.
8189
    */
8190
24.0k
    attr = node->properties;
8191
49.2k
    while (attr != NULL) {
8192
25.2k
  if (attr->ns == NULL) {
8193
24.5k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8194
24.5k
    (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8195
1.97k
    xmlSchemaPIllegalAttrErr(ctxt,
8196
1.97k
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8197
1.97k
      }
8198
24.5k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8199
76
      xmlSchemaPIllegalAttrErr(ctxt,
8200
76
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8201
76
  }
8202
25.2k
  attr = attr->next;
8203
25.2k
    }
8204
    /*
8205
    * Create the item.
8206
    */
8207
24.0k
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8208
24.0k
    if (item == NULL) {
8209
0
        xmlSchemaPErrMemory(ctxt);
8210
0
        return (NULL);
8211
0
    }
8212
24.0k
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
8213
    /*
8214
    * Attribute "xpath" (mandatory).
8215
    */
8216
24.0k
    attr = xmlSchemaGetPropNode(node, "xpath");
8217
24.0k
    if (attr == NULL) {
8218
1.78k
  xmlSchemaPMissingAttrErr(ctxt,
8219
1.78k
      XML_SCHEMAP_S4S_ATTR_MISSING,
8220
1.78k
      NULL, node,
8221
1.78k
      "name", NULL);
8222
22.2k
    } else {
8223
22.2k
  item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8224
  /*
8225
  * URGENT TODO: "field"s have an other syntax than "selector"s.
8226
  */
8227
8228
22.2k
  if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8229
22.2k
      isField) == -1) {
8230
0
      xmlSchemaPErr(ctxt,
8231
0
    (xmlNodePtr) attr,
8232
0
    XML_SCHEMAP_INTERNAL,
8233
0
    "Internal error: xmlSchemaParseIDCSelectorAndField, "
8234
0
    "validating the XPath expression of a IDC selector.\n",
8235
0
    NULL, NULL);
8236
0
  }
8237
8238
22.2k
    }
8239
24.0k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8240
    /*
8241
    * And now for the children...
8242
    */
8243
24.0k
    child = node->children;
8244
24.0k
    if (IS_SCHEMA(child, "annotation")) {
8245
  /*
8246
  * Add the annotation to the parent IDC.
8247
  */
8248
10
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8249
10
      xmlSchemaParseAnnotation(ctxt, child, 1));
8250
10
  child = child->next;
8251
10
    }
8252
24.0k
    if (child != NULL) {
8253
62
  xmlSchemaPContentErr(ctxt,
8254
62
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8255
62
      NULL, node, child,
8256
62
      NULL, "(annotation?)");
8257
62
    }
8258
8259
24.0k
    return (item);
8260
24.0k
}
8261
8262
/**
8263
 * xmlSchemaParseIDC:
8264
 * @ctxt:  a schema validation context
8265
 * @schema:  the schema being built
8266
 * @node:  a subtree containing XML Schema information
8267
 *
8268
 * Parses a XML Schema identity-constraint definition.
8269
 *
8270
 * Returns the parsed identity-constraint definition.
8271
 */
8272
static xmlSchemaIDCPtr
8273
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8274
      xmlSchemaPtr schema,
8275
      xmlNodePtr node,
8276
      xmlSchemaTypeType idcCategory,
8277
      const xmlChar *targetNamespace)
8278
4.14k
{
8279
4.14k
    xmlSchemaIDCPtr item = NULL;
8280
4.14k
    xmlNodePtr child = NULL;
8281
4.14k
    xmlAttrPtr attr;
8282
4.14k
    const xmlChar *name = NULL;
8283
4.14k
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8284
8285
    /*
8286
    * Check for illegal attributes.
8287
    */
8288
4.14k
    attr = node->properties;
8289
11.8k
    while (attr != NULL) {
8290
7.71k
  if (attr->ns == NULL) {
8291
5.37k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8292
5.37k
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8293
5.37k
    ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8294
1.61k
     (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8295
1.61k
    xmlSchemaPIllegalAttrErr(ctxt,
8296
1.61k
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8297
1.61k
      }
8298
5.37k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8299
22
      xmlSchemaPIllegalAttrErr(ctxt,
8300
22
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8301
22
  }
8302
7.71k
  attr = attr->next;
8303
7.71k
    }
8304
    /*
8305
    * Attribute "name" (mandatory).
8306
    */
8307
4.14k
    attr = xmlSchemaGetPropNode(node, "name");
8308
4.14k
    if (attr == NULL) {
8309
411
  xmlSchemaPMissingAttrErr(ctxt,
8310
411
      XML_SCHEMAP_S4S_ATTR_MISSING,
8311
411
      NULL, node,
8312
411
      "name", NULL);
8313
411
  return (NULL);
8314
3.73k
    } else if (xmlSchemaPValAttrNode(ctxt,
8315
3.73k
  NULL, attr,
8316
3.73k
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8317
112
  return (NULL);
8318
112
    }
8319
    /* Create the component. */
8320
3.62k
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8321
3.62k
  idcCategory, node);
8322
3.62k
    if (item == NULL)
8323
0
  return(NULL);
8324
8325
3.62k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8326
3.62k
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8327
  /*
8328
  * Attribute "refer" (mandatory).
8329
  */
8330
3.57k
  attr = xmlSchemaGetPropNode(node, "refer");
8331
3.57k
  if (attr == NULL) {
8332
3.56k
      xmlSchemaPMissingAttrErr(ctxt,
8333
3.56k
    XML_SCHEMAP_S4S_ATTR_MISSING,
8334
3.56k
    NULL, node,
8335
3.56k
    "refer", NULL);
8336
3.56k
  } else {
8337
      /*
8338
      * Create a reference item.
8339
      */
8340
5
      item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8341
5
    NULL, NULL);
8342
5
      if (item->ref == NULL)
8343
0
    return (NULL);
8344
5
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8345
5
    NULL, attr,
8346
5
    &(item->ref->targetNamespace),
8347
5
    &(item->ref->name));
8348
5
      xmlSchemaCheckReference(ctxt, schema, node, attr,
8349
5
    item->ref->targetNamespace);
8350
5
  }
8351
3.57k
    }
8352
    /*
8353
    * And now for the children...
8354
    */
8355
3.62k
    child = node->children;
8356
3.62k
    if (IS_SCHEMA(child, "annotation")) {
8357
44
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8358
44
  child = child->next;
8359
44
    }
8360
3.62k
    if (child == NULL) {
8361
306
  xmlSchemaPContentErr(ctxt,
8362
306
    XML_SCHEMAP_S4S_ELEM_MISSING,
8363
306
    NULL, node, child,
8364
306
    "A child element is missing",
8365
306
    "(annotation?, (selector, field+))");
8366
306
    }
8367
    /*
8368
    * Child element <selector>.
8369
    */
8370
3.62k
    if (IS_SCHEMA(child, "selector")) {
8371
2.11k
  item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8372
2.11k
      item, child, 0);
8373
2.11k
  child = child->next;
8374
  /*
8375
  * Child elements <field>.
8376
  */
8377
2.11k
  if (IS_SCHEMA(child, "field")) {
8378
21.9k
      do {
8379
21.9k
    field = xmlSchemaParseIDCSelectorAndField(ctxt,
8380
21.9k
        item, child, 1);
8381
21.9k
    if (field != NULL) {
8382
21.9k
        field->index = item->nbFields;
8383
21.9k
        item->nbFields++;
8384
21.9k
        if (lastField != NULL)
8385
20.6k
      lastField->next = field;
8386
1.30k
        else
8387
1.30k
      item->fields = field;
8388
21.9k
        lastField = field;
8389
21.9k
    }
8390
21.9k
    child = child->next;
8391
21.9k
      } while (IS_SCHEMA(child, "field"));
8392
1.30k
  } else {
8393
808
      xmlSchemaPContentErr(ctxt,
8394
808
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8395
808
    NULL, node, child,
8396
808
    NULL, "(annotation?, (selector, field+))");
8397
808
  }
8398
2.11k
    }
8399
3.62k
    if (child != NULL) {
8400
2.65k
  xmlSchemaPContentErr(ctxt,
8401
2.65k
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8402
2.65k
      NULL, node, child,
8403
2.65k
      NULL, "(annotation?, (selector, field+))");
8404
2.65k
    }
8405
8406
3.62k
    return (item);
8407
3.62k
}
8408
8409
/**
8410
 * xmlSchemaParseElement:
8411
 * @ctxt:  a schema validation context
8412
 * @schema:  the schema being built
8413
 * @node:  a subtree containing XML Schema information
8414
 * @topLevel: indicates if this is global declaration
8415
 *
8416
 * Parses a XML schema element declaration.
8417
 * *WARNING* this interface is highly subject to change
8418
 *
8419
 * Returns the element declaration or a particle; NULL in case
8420
 * of an error or if the particle has minOccurs==maxOccurs==0.
8421
 */
8422
static xmlSchemaBasicItemPtr
8423
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8424
                      xmlNodePtr node, int *isElemRef, int topLevel)
8425
31.8k
{
8426
31.8k
    xmlSchemaElementPtr decl = NULL;
8427
31.8k
    xmlSchemaParticlePtr particle = NULL;
8428
31.8k
    xmlSchemaAnnotPtr annot = NULL;
8429
31.8k
    xmlNodePtr child = NULL;
8430
31.8k
    xmlAttrPtr attr, nameAttr;
8431
31.8k
    int min, max, isRef = 0;
8432
31.8k
    xmlChar *des = NULL;
8433
8434
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
8435
    /* TODO: Complete implementation of 3.3.6 */
8436
8437
31.8k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8438
0
        return (NULL);
8439
8440
31.8k
    if (isElemRef != NULL)
8441
9.79k
  *isElemRef = 0;
8442
    /*
8443
    * If we get a "ref" attribute on a local <element> we will assume it's
8444
    * a reference - even if there's a "name" attribute; this seems to be more
8445
    * robust.
8446
    */
8447
31.8k
    nameAttr = xmlSchemaGetPropNode(node, "name");
8448
31.8k
    attr = xmlSchemaGetPropNode(node, "ref");
8449
31.8k
    if ((topLevel) || (attr == NULL)) {
8450
28.4k
  if (nameAttr == NULL) {
8451
3.35k
      xmlSchemaPMissingAttrErr(ctxt,
8452
3.35k
    XML_SCHEMAP_S4S_ATTR_MISSING,
8453
3.35k
    NULL, node, "name", NULL);
8454
3.35k
      return (NULL);
8455
3.35k
  }
8456
28.4k
    } else
8457
3.45k
  isRef = 1;
8458
8459
28.5k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8460
28.5k
    child = node->children;
8461
28.5k
    if (IS_SCHEMA(child, "annotation")) {
8462
228
  annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8463
228
  child = child->next;
8464
228
    }
8465
    /*
8466
    * Skip particle part if a global declaration.
8467
    */
8468
28.5k
    if (topLevel)
8469
18.9k
  goto declaration_part;
8470
    /*
8471
    * The particle part ==================================================
8472
    */
8473
9.60k
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8474
9.60k
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8475
9.60k
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8476
9.60k
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
8477
9.60k
    if (particle == NULL)
8478
0
  goto return_null;
8479
8480
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8481
8482
9.60k
    if (isRef) {
8483
3.45k
  const xmlChar *refNs = NULL, *ref = NULL;
8484
3.45k
  xmlSchemaQNameRefPtr refer = NULL;
8485
  /*
8486
  * The reference part =============================================
8487
  */
8488
3.45k
  if (isElemRef != NULL)
8489
3.45k
      *isElemRef = 1;
8490
8491
3.45k
  xmlSchemaPValAttrNodeQName(ctxt, schema,
8492
3.45k
      NULL, attr, &refNs, &ref);
8493
3.45k
  xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8494
  /*
8495
  * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8496
  */
8497
3.45k
  if (nameAttr != NULL) {
8498
38
      xmlSchemaPMutualExclAttrErr(ctxt,
8499
38
    XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8500
38
  }
8501
  /*
8502
  * Check for illegal attributes.
8503
  */
8504
3.45k
  attr = node->properties;
8505
9.63k
  while (attr != NULL) {
8506
7.04k
      if (attr->ns == NULL) {
8507
6.27k
    if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8508
6.27k
        xmlStrEqual(attr->name, BAD_CAST "name") ||
8509
6.27k
        xmlStrEqual(attr->name, BAD_CAST "id") ||
8510
6.27k
        xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8511
6.27k
        xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8512
5.40k
    {
8513
5.40k
        attr = attr->next;
8514
5.40k
        continue;
8515
5.40k
    } else {
8516
        /* SPEC (3.3.3 : 2.2) */
8517
868
        xmlSchemaPCustomAttrErr(ctxt,
8518
868
      XML_SCHEMAP_SRC_ELEMENT_2_2,
8519
868
      NULL, NULL, attr,
8520
868
      "Only the attributes 'minOccurs', 'maxOccurs' and "
8521
868
      "'id' are allowed in addition to 'ref'");
8522
868
        break;
8523
868
    }
8524
6.27k
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8525
43
    xmlSchemaPIllegalAttrErr(ctxt,
8526
43
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8527
43
      }
8528
773
      attr = attr->next;
8529
773
  }
8530
  /*
8531
  * No children except <annotation> expected.
8532
  */
8533
3.45k
  if (child != NULL) {
8534
17
      xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8535
17
    NULL, node, child, NULL, "(annotation?)");
8536
17
  }
8537
3.45k
  if ((min == 0) && (max == 0))
8538
36
      goto return_null;
8539
  /*
8540
  * Create the reference item and attach it to the particle.
8541
  */
8542
3.41k
  refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8543
3.41k
      ref, refNs);
8544
3.41k
  if (refer == NULL)
8545
0
      goto return_null;
8546
3.41k
  particle->children = (xmlSchemaTreeItemPtr) refer;
8547
3.41k
  particle->annot = annot;
8548
  /*
8549
  * Add the particle to pending components, since the reference
8550
  * need to be resolved.
8551
  */
8552
3.41k
  WXS_ADD_PENDING(ctxt, particle);
8553
3.41k
  return ((xmlSchemaBasicItemPtr) particle);
8554
3.41k
    }
8555
    /*
8556
    * The declaration part ===============================================
8557
    */
8558
25.0k
declaration_part:
8559
25.0k
    {
8560
25.0k
  const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8561
25.0k
  xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8562
8563
25.0k
  if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8564
25.0k
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8565
1.45k
      goto return_null;
8566
  /*
8567
  * Evaluate the target namespace.
8568
  */
8569
23.6k
  if (topLevel) {
8570
17.7k
      ns = ctxt->targetNamespace;
8571
17.7k
  } else {
8572
5.91k
      attr = xmlSchemaGetPropNode(node, "form");
8573
5.91k
      if (attr != NULL) {
8574
37
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8575
37
    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8576
18
        ns = ctxt->targetNamespace;
8577
19
    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8578
19
        xmlSchemaPSimpleTypeErr(ctxt,
8579
19
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8580
19
      NULL, (xmlNodePtr) attr,
8581
19
      NULL, "(qualified | unqualified)",
8582
19
      attrValue, NULL, NULL, NULL);
8583
19
    }
8584
5.87k
      } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8585
684
    ns = ctxt->targetNamespace;
8586
5.91k
  }
8587
23.6k
  decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8588
23.6k
  if (decl == NULL) {
8589
0
      goto return_null;
8590
0
  }
8591
  /*
8592
  * Check for illegal attributes.
8593
  */
8594
23.6k
  attr = node->properties;
8595
65.5k
  while (attr != NULL) {
8596
41.9k
      if (attr->ns == NULL) {
8597
41.2k
    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8598
41.2k
        (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8599
41.2k
        (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8600
41.2k
        (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8601
41.2k
        (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8602
41.2k
        (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8603
41.2k
        (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8604
5.79k
    {
8605
5.79k
        if (topLevel == 0) {
8606
1.29k
      if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8607
1.29k
          (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8608
1.29k
          (!xmlStrEqual(attr->name, BAD_CAST "form")))
8609
619
      {
8610
619
          xmlSchemaPIllegalAttrErr(ctxt,
8611
619
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8612
619
      }
8613
4.50k
        } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8614
4.50k
      (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8615
4.50k
      (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8616
8617
1.74k
      xmlSchemaPIllegalAttrErr(ctxt,
8618
1.74k
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8619
1.74k
        }
8620
5.79k
    }
8621
41.2k
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8622
8623
312
    xmlSchemaPIllegalAttrErr(ctxt,
8624
312
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8625
312
      }
8626
41.9k
      attr = attr->next;
8627
41.9k
  }
8628
  /*
8629
  * Extract/validate attributes.
8630
  */
8631
23.6k
  if (topLevel) {
8632
      /*
8633
      * Process top attributes of global element declarations here.
8634
      */
8635
17.7k
      decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8636
17.7k
      decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8637
17.7k
      xmlSchemaPValAttrQName(ctxt, schema,
8638
17.7k
    NULL, node, "substitutionGroup",
8639
17.7k
    &(decl->substGroupNs), &(decl->substGroup));
8640
17.7k
      if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8641
57
    decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8642
      /*
8643
      * Attribute "final".
8644
      */
8645
17.7k
      attr = xmlSchemaGetPropNode(node, "final");
8646
17.7k
      if (attr == NULL) {
8647
15.7k
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8648
4
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8649
15.7k
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8650
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8651
15.7k
      } else {
8652
1.97k
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8653
1.97k
    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8654
1.97k
        -1,
8655
1.97k
        XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8656
1.97k
        XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8657
1.65k
        xmlSchemaPSimpleTypeErr(ctxt,
8658
1.65k
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8659
1.65k
      NULL, (xmlNodePtr) attr,
8660
1.65k
      NULL, "(#all | List of (extension | restriction))",
8661
1.65k
      attrValue, NULL, NULL, NULL);
8662
1.65k
    }
8663
1.97k
      }
8664
17.7k
  }
8665
  /*
8666
  * Attribute "block".
8667
  */
8668
23.6k
  attr = xmlSchemaGetPropNode(node, "block");
8669
23.6k
  if (attr == NULL) {
8670
      /*
8671
      * Apply default "block" values.
8672
      */
8673
23.3k
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8674
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8675
23.3k
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8676
5
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8677
23.3k
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8678
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8679
23.3k
  } else {
8680
330
      attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8681
330
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8682
330
    -1,
8683
330
    XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8684
330
    XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8685
330
    XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8686
253
    xmlSchemaPSimpleTypeErr(ctxt,
8687
253
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8688
253
        NULL, (xmlNodePtr) attr,
8689
253
        NULL, "(#all | List of (extension | "
8690
253
        "restriction | substitution))", attrValue,
8691
253
        NULL, NULL, NULL);
8692
253
      }
8693
330
  }
8694
23.6k
  if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8695
70
      decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8696
8697
23.6k
  attr = xmlSchemaGetPropNode(node, "type");
8698
23.6k
  if (attr != NULL) {
8699
7.82k
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8700
7.82k
    NULL, attr,
8701
7.82k
    &(decl->namedTypeNs), &(decl->namedType));
8702
7.82k
      xmlSchemaCheckReference(ctxt, schema, node,
8703
7.82k
    attr, decl->namedTypeNs);
8704
7.82k
  }
8705
23.6k
  decl->value = xmlSchemaGetProp(ctxt, node, "default");
8706
23.6k
  attr = xmlSchemaGetPropNode(node, "fixed");
8707
23.6k
  if (attr != NULL) {
8708
210
      fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8709
210
      if (decl->value != NULL) {
8710
    /*
8711
    * 3.3.3 : 1
8712
    * default and fixed must not both be present.
8713
    */
8714
46
    xmlSchemaPMutualExclAttrErr(ctxt,
8715
46
        XML_SCHEMAP_SRC_ELEMENT_1,
8716
46
        NULL, attr, "default", "fixed");
8717
164
      } else {
8718
164
    decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8719
164
    decl->value = fixed;
8720
164
      }
8721
210
  }
8722
  /*
8723
  * And now for the children...
8724
  */
8725
23.6k
  if (IS_SCHEMA(child, "complexType")) {
8726
      /*
8727
      * 3.3.3 : 3
8728
      * "type" and either <simpleType> or <complexType> are mutually
8729
      * exclusive
8730
      */
8731
4.62k
      if (decl->namedType != NULL) {
8732
51
    xmlSchemaPContentErr(ctxt,
8733
51
        XML_SCHEMAP_SRC_ELEMENT_3,
8734
51
        NULL, node, child,
8735
51
        "The attribute 'type' and the <complexType> child are "
8736
51
        "mutually exclusive", NULL);
8737
51
      } else
8738
4.57k
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8739
4.62k
      child = child->next;
8740
19.0k
  } else if (IS_SCHEMA(child, "simpleType")) {
8741
      /*
8742
      * 3.3.3 : 3
8743
      * "type" and either <simpleType> or <complexType> are
8744
      * mutually exclusive
8745
      */
8746
3.68k
      if (decl->namedType != NULL) {
8747
68
    xmlSchemaPContentErr(ctxt,
8748
68
        XML_SCHEMAP_SRC_ELEMENT_3,
8749
68
        NULL, node, child,
8750
68
        "The attribute 'type' and the <simpleType> child are "
8751
68
        "mutually exclusive", NULL);
8752
68
      } else
8753
3.62k
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8754
3.68k
      child = child->next;
8755
3.68k
  }
8756
27.7k
  while ((IS_SCHEMA(child, "unique")) ||
8757
27.7k
      (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8758
4.14k
      if (IS_SCHEMA(child, "unique")) {
8759
25
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8760
25
        XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8761
4.11k
      } else if (IS_SCHEMA(child, "key")) {
8762
97
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8763
97
        XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8764
4.02k
      } else if (IS_SCHEMA(child, "keyref")) {
8765
4.02k
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8766
4.02k
        XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8767
4.02k
      }
8768
4.14k
      if (lastIDC != NULL)
8769
1.77k
    lastIDC->next = curIDC;
8770
2.36k
      else
8771
2.36k
    decl->idcs = (void *) curIDC;
8772
4.14k
      lastIDC = curIDC;
8773
4.14k
      child = child->next;
8774
4.14k
  }
8775
23.6k
  if (child != NULL) {
8776
2.74k
      xmlSchemaPContentErr(ctxt,
8777
2.74k
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8778
2.74k
    NULL, node, child,
8779
2.74k
    NULL, "(annotation?, ((simpleType | complexType)?, "
8780
2.74k
    "(unique | key | keyref)*))");
8781
2.74k
  }
8782
23.6k
  decl->annot = annot;
8783
23.6k
    }
8784
    /*
8785
    * NOTE: Element Declaration Representation OK 4. will be checked at a
8786
    * different layer.
8787
    */
8788
23.6k
    FREE_AND_NULL(des)
8789
23.6k
    if (topLevel)
8790
17.7k
  return ((xmlSchemaBasicItemPtr) decl);
8791
5.91k
    else {
8792
5.91k
  particle->children = (xmlSchemaTreeItemPtr) decl;
8793
5.91k
  return ((xmlSchemaBasicItemPtr) particle);
8794
5.91k
    }
8795
8796
1.48k
return_null:
8797
1.48k
    FREE_AND_NULL(des);
8798
1.48k
    if (annot != NULL) {
8799
90
  if (particle != NULL)
8800
21
      particle->annot = NULL;
8801
90
  if (decl != NULL)
8802
0
      decl->annot = NULL;
8803
90
  xmlSchemaFreeAnnot(annot);
8804
90
    }
8805
1.48k
    return (NULL);
8806
23.6k
}
8807
8808
/**
8809
 * xmlSchemaParseUnion:
8810
 * @ctxt:  a schema validation context
8811
 * @schema:  the schema being built
8812
 * @node:  a subtree containing XML Schema information
8813
 *
8814
 * parse a XML schema Union definition
8815
 * *WARNING* this interface is highly subject to change
8816
 *
8817
 * Returns -1 in case of internal error, 0 in case of success and a positive
8818
 * error code otherwise.
8819
 */
8820
static int
8821
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8822
                    xmlNodePtr node)
8823
2.70k
{
8824
2.70k
    xmlSchemaTypePtr type;
8825
2.70k
    xmlNodePtr child = NULL;
8826
2.70k
    xmlAttrPtr attr;
8827
2.70k
    const xmlChar *cur = NULL;
8828
8829
2.70k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8830
0
        return (-1);
8831
    /* Not a component, don't create it. */
8832
2.70k
    type = ctxt->ctxtType;
8833
    /*
8834
    * Mark the simple type as being of variety "union".
8835
    */
8836
2.70k
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8837
    /*
8838
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8839
    * then the `simple ur-type definition`."
8840
    */
8841
2.70k
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8842
    /*
8843
    * Check for illegal attributes.
8844
    */
8845
2.70k
    attr = node->properties;
8846
5.77k
    while (attr != NULL) {
8847
3.06k
  if (attr->ns == NULL) {
8848
2.25k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8849
2.25k
    (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8850
455
    xmlSchemaPIllegalAttrErr(ctxt,
8851
455
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8852
455
      }
8853
2.25k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8854
0
      xmlSchemaPIllegalAttrErr(ctxt,
8855
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8856
0
  }
8857
3.06k
  attr = attr->next;
8858
3.06k
    }
8859
2.70k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8860
    /*
8861
    * Attribute "memberTypes". This is a list of QNames.
8862
    * TODO: Check the value to contain anything.
8863
    */
8864
2.70k
    attr = xmlSchemaGetPropNode(node, "memberTypes");
8865
2.70k
    if (attr != NULL) {
8866
1.76k
  const xmlChar *end;
8867
1.76k
  xmlChar *tmp;
8868
1.76k
  const xmlChar *localName, *nsName;
8869
1.76k
  xmlSchemaTypeLinkPtr link, lastLink = NULL;
8870
1.76k
  xmlSchemaQNameRefPtr ref;
8871
8872
1.76k
  cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8873
1.76k
        if (cur == NULL)
8874
0
            return (-1);
8875
1.76k
  type->base = cur;
8876
143k
  do {
8877
143k
      while (IS_BLANK_CH(*cur))
8878
168k
    cur++;
8879
143k
      end = cur;
8880
869k
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8881
726k
    end++;
8882
143k
      if (end == cur)
8883
205
    break;
8884
143k
      tmp = xmlStrndup(cur, end - cur);
8885
143k
            if (tmp == NULL) {
8886
0
                xmlSchemaPErrMemory(ctxt);
8887
0
                return (-1);
8888
0
            }
8889
143k
      if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8890
143k
    NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
8891
    /*
8892
    * Create the member type link.
8893
    */
8894
50.4k
    link = (xmlSchemaTypeLinkPtr)
8895
50.4k
        xmlMalloc(sizeof(xmlSchemaTypeLink));
8896
50.4k
    if (link == NULL) {
8897
0
        xmlSchemaPErrMemory(ctxt);
8898
0
              FREE_AND_NULL(tmp)
8899
0
        return (-1);
8900
0
    }
8901
50.4k
    link->type = NULL;
8902
50.4k
    link->next = NULL;
8903
50.4k
    if (lastLink == NULL)
8904
1.73k
        type->memberTypes = link;
8905
48.7k
    else
8906
48.7k
        lastLink->next = link;
8907
50.4k
    lastLink = link;
8908
    /*
8909
    * Create a reference item.
8910
    */
8911
50.4k
    ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8912
50.4k
        localName, nsName);
8913
50.4k
    if (ref == NULL) {
8914
0
        FREE_AND_NULL(tmp)
8915
0
        return (-1);
8916
0
    }
8917
    /*
8918
    * Assign the reference to the link, it will be resolved
8919
    * later during fixup of the union simple type.
8920
    */
8921
50.4k
    link->type = (xmlSchemaTypePtr) ref;
8922
50.4k
      }
8923
143k
      FREE_AND_NULL(tmp)
8924
143k
      cur = end;
8925
143k
  } while (*cur != 0);
8926
8927
1.76k
    }
8928
    /*
8929
    * And now for the children...
8930
    */
8931
2.70k
    child = node->children;
8932
2.70k
    if (IS_SCHEMA(child, "annotation")) {
8933
  /*
8934
  * Add the annotation to the simple type ancestor.
8935
  */
8936
20
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8937
20
      xmlSchemaParseAnnotation(ctxt, child, 1));
8938
20
        child = child->next;
8939
20
    }
8940
2.70k
    if (IS_SCHEMA(child, "simpleType")) {
8941
749
  xmlSchemaTypePtr subtype, last = NULL;
8942
8943
  /*
8944
  * Anchor the member types in the "subtypes" field of the
8945
  * simple type.
8946
  */
8947
1.65k
  while (IS_SCHEMA(child, "simpleType")) {
8948
909
      subtype = (xmlSchemaTypePtr)
8949
909
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8950
909
      if (subtype != NULL) {
8951
909
    if (last == NULL) {
8952
749
        type->subtypes = subtype;
8953
749
        last = subtype;
8954
749
    } else {
8955
160
        last->next = subtype;
8956
160
        last = subtype;
8957
160
    }
8958
909
    last->next = NULL;
8959
909
      }
8960
909
      child = child->next;
8961
909
  }
8962
749
    }
8963
2.70k
    if (child != NULL) {
8964
162
  xmlSchemaPContentErr(ctxt,
8965
162
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8966
162
      NULL, node, child, NULL, "(annotation?, simpleType*)");
8967
162
    }
8968
2.70k
    if ((attr == NULL) && (type->subtypes == NULL)) {
8969
   /*
8970
  * src-union-memberTypes-or-simpleTypes
8971
  * Either the memberTypes [attribute] of the <union> element must
8972
  * be non-empty or there must be at least one simpleType [child].
8973
  */
8974
281
  xmlSchemaPCustomErr(ctxt,
8975
281
      XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8976
281
      NULL, node,
8977
281
      "Either the attribute 'memberTypes' or "
8978
281
      "at least one <simpleType> child must be present", NULL);
8979
281
    }
8980
2.70k
    return (0);
8981
2.70k
}
8982
8983
/**
8984
 * xmlSchemaParseList:
8985
 * @ctxt:  a schema validation context
8986
 * @schema:  the schema being built
8987
 * @node:  a subtree containing XML Schema information
8988
 *
8989
 * parse a XML schema List definition
8990
 * *WARNING* this interface is highly subject to change
8991
 *
8992
 * Returns -1 in case of error, 0 if the declaration is improper and
8993
 *         1 in case of success.
8994
 */
8995
static xmlSchemaTypePtr
8996
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8997
                   xmlNodePtr node)
8998
311
{
8999
311
    xmlSchemaTypePtr type;
9000
311
    xmlNodePtr child = NULL;
9001
311
    xmlAttrPtr attr;
9002
9003
311
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9004
0
        return (NULL);
9005
    /* Not a component, don't create it. */
9006
311
    type = ctxt->ctxtType;
9007
    /*
9008
    * Mark the type as being of variety "list".
9009
    */
9010
311
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9011
    /*
9012
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9013
    * then the `simple ur-type definition`."
9014
    */
9015
311
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9016
    /*
9017
    * Check for illegal attributes.
9018
    */
9019
311
    attr = node->properties;
9020
352
    while (attr != NULL) {
9021
41
  if (attr->ns == NULL) {
9022
41
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9023
41
    (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
9024
26
    xmlSchemaPIllegalAttrErr(ctxt,
9025
26
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9026
26
      }
9027
41
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9028
0
      xmlSchemaPIllegalAttrErr(ctxt,
9029
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9030
0
  }
9031
41
  attr = attr->next;
9032
41
    }
9033
9034
311
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9035
9036
    /*
9037
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9038
    * fields for holding the reference to the itemType.
9039
    *
9040
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9041
    * the "ref" fields.
9042
    */
9043
311
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
9044
311
  node, "itemType", &(type->baseNs), &(type->base));
9045
    /*
9046
    * And now for the children...
9047
    */
9048
311
    child = node->children;
9049
311
    if (IS_SCHEMA(child, "annotation")) {
9050
1
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9051
1
      xmlSchemaParseAnnotation(ctxt, child, 1));
9052
1
        child = child->next;
9053
1
    }
9054
311
    if (IS_SCHEMA(child, "simpleType")) {
9055
  /*
9056
  * src-list-itemType-or-simpleType
9057
  * Either the itemType [attribute] or the <simpleType> [child] of
9058
  * the <list> element must be present, but not both.
9059
  */
9060
168
  if (type->base != NULL) {
9061
0
      xmlSchemaPCustomErr(ctxt,
9062
0
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9063
0
    NULL, node,
9064
0
    "The attribute 'itemType' and the <simpleType> child "
9065
0
    "are mutually exclusive", NULL);
9066
168
  } else {
9067
168
      type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9068
168
  }
9069
168
        child = child->next;
9070
168
    } else if (type->base == NULL) {
9071
128
  xmlSchemaPCustomErr(ctxt,
9072
128
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9073
128
      NULL, node,
9074
128
      "Either the attribute 'itemType' or the <simpleType> child "
9075
128
      "must be present", NULL);
9076
128
    }
9077
311
    if (child != NULL) {
9078
122
  xmlSchemaPContentErr(ctxt,
9079
122
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9080
122
      NULL, node, child, NULL, "(annotation?, simpleType?)");
9081
122
    }
9082
311
    if ((type->base == NULL) &&
9083
311
  (type->subtypes == NULL) &&
9084
311
  (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9085
128
  xmlSchemaPCustomErr(ctxt,
9086
128
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9087
128
      NULL, node,
9088
128
      "Either the attribute 'itemType' or the <simpleType> child "
9089
128
      "must be present", NULL);
9090
128
    }
9091
311
    return (NULL);
9092
311
}
9093
9094
/**
9095
 * xmlSchemaParseSimpleType:
9096
 * @ctxt:  a schema validation context
9097
 * @schema:  the schema being built
9098
 * @node:  a subtree containing XML Schema information
9099
 *
9100
 * parse a XML schema Simple Type definition
9101
 * *WARNING* this interface is highly subject to change
9102
 *
9103
 * Returns -1 in case of error, 0 if the declaration is improper and
9104
 * 1 in case of success.
9105
 */
9106
static xmlSchemaTypePtr
9107
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9108
                         xmlNodePtr node, int topLevel)
9109
17.0k
{
9110
17.0k
    xmlSchemaTypePtr type, oldCtxtType;
9111
17.0k
    xmlNodePtr child = NULL;
9112
17.0k
    const xmlChar *attrValue = NULL;
9113
17.0k
    xmlAttrPtr attr;
9114
17.0k
    int hasRestriction = 0;
9115
9116
17.0k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9117
0
        return (NULL);
9118
9119
17.0k
    if (topLevel) {
9120
10.7k
  attr = xmlSchemaGetPropNode(node, "name");
9121
10.7k
  if (attr == NULL) {
9122
1.54k
      xmlSchemaPMissingAttrErr(ctxt,
9123
1.54k
    XML_SCHEMAP_S4S_ATTR_MISSING,
9124
1.54k
    NULL, node,
9125
1.54k
    "name", NULL);
9126
1.54k
      return (NULL);
9127
9.20k
  } else {
9128
9.20k
      if (xmlSchemaPValAttrNode(ctxt,
9129
9.20k
    NULL, attr,
9130
9.20k
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9131
1.07k
    return (NULL);
9132
      /*
9133
      * Skip built-in types.
9134
      */
9135
8.13k
      if (ctxt->isS4S) {
9136
0
    xmlSchemaTypePtr biType;
9137
9138
0
    if (ctxt->isRedefine) {
9139
        /*
9140
        * REDEFINE: Disallow redefinition of built-in-types.
9141
        * TODO: It seems that the spec does not say anything
9142
        * about this case.
9143
        */
9144
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9145
0
      NULL, node,
9146
0
      "Redefinition of built-in simple types is not "
9147
0
      "supported", NULL);
9148
0
        return(NULL);
9149
0
    }
9150
0
    biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9151
0
    if (biType != NULL)
9152
0
        return (biType);
9153
0
      }
9154
8.13k
  }
9155
10.7k
    }
9156
    /*
9157
    * TargetNamespace:
9158
    * SPEC "The `actual value` of the targetNamespace [attribute]
9159
    * of the <schema> ancestor element information item if present,
9160
    * otherwise `absent`.
9161
    */
9162
14.4k
    if (topLevel == 0) {
9163
#ifdef ENABLE_NAMED_LOCALS
9164
        char buf[40];
9165
#endif
9166
  /*
9167
  * Parse as local simple type definition.
9168
  */
9169
#ifdef ENABLE_NAMED_LOCALS
9170
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9171
  type = xmlSchemaAddType(ctxt, schema,
9172
      XML_SCHEMA_TYPE_SIMPLE,
9173
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9174
      ctxt->targetNamespace, node, 0);
9175
#else
9176
6.26k
  type = xmlSchemaAddType(ctxt, schema,
9177
6.26k
      XML_SCHEMA_TYPE_SIMPLE,
9178
6.26k
      NULL, ctxt->targetNamespace, node, 0);
9179
6.26k
#endif
9180
6.26k
  if (type == NULL)
9181
0
      return (NULL);
9182
6.26k
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9183
6.26k
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9184
  /*
9185
  * Check for illegal attributes.
9186
  */
9187
6.26k
  attr = node->properties;
9188
7.03k
  while (attr != NULL) {
9189
774
      if (attr->ns == NULL) {
9190
455
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9191
368
        xmlSchemaPIllegalAttrErr(ctxt,
9192
368
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9193
368
    }
9194
455
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9195
34
        xmlSchemaPIllegalAttrErr(ctxt,
9196
34
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9197
34
      }
9198
774
      attr = attr->next;
9199
774
  }
9200
8.13k
    } else {
9201
  /*
9202
  * Parse as global simple type definition.
9203
  *
9204
  * Note that attrValue is the value of the attribute "name" here.
9205
  */
9206
8.13k
  type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9207
8.13k
      attrValue, ctxt->targetNamespace, node, 1);
9208
8.13k
  if (type == NULL)
9209
0
      return (NULL);
9210
8.13k
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9211
8.13k
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9212
8.13k
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9213
  /*
9214
  * Check for illegal attributes.
9215
  */
9216
8.13k
  attr = node->properties;
9217
18.4k
  while (attr != NULL) {
9218
10.3k
      if (attr->ns == NULL) {
9219
10.1k
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9220
10.1k
        (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9221
10.1k
        (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9222
1.33k
        xmlSchemaPIllegalAttrErr(ctxt,
9223
1.33k
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9224
1.33k
    }
9225
10.1k
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9226
127
    xmlSchemaPIllegalAttrErr(ctxt,
9227
127
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9228
127
      }
9229
10.3k
      attr = attr->next;
9230
10.3k
  }
9231
  /*
9232
  * Attribute "final".
9233
  */
9234
8.13k
  attr = xmlSchemaGetPropNode(node, "final");
9235
8.13k
  if (attr == NULL) {
9236
7.57k
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9237
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9238
7.57k
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9239
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9240
7.57k
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9241
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9242
7.57k
  } else {
9243
560
      attrValue = xmlSchemaGetProp(ctxt, node, "final");
9244
560
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9245
560
    -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9246
560
    XML_SCHEMAS_TYPE_FINAL_LIST,
9247
560
    XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9248
9249
290
    xmlSchemaPSimpleTypeErr(ctxt,
9250
290
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9251
290
        WXS_BASIC_CAST type, (xmlNodePtr) attr,
9252
290
        NULL, "(#all | List of (list | union | restriction)",
9253
290
        attrValue, NULL, NULL, NULL);
9254
290
      }
9255
560
  }
9256
8.13k
    }
9257
14.4k
    type->targetNamespace = ctxt->targetNamespace;
9258
14.4k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9259
    /*
9260
    * And now for the children...
9261
    */
9262
14.4k
    oldCtxtType = ctxt->ctxtType;
9263
9264
14.4k
    ctxt->ctxtType = type;
9265
9266
14.4k
    child = node->children;
9267
14.4k
    if (IS_SCHEMA(child, "annotation")) {
9268
186
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9269
186
        child = child->next;
9270
186
    }
9271
14.4k
    if (child == NULL) {
9272
1.16k
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9273
1.16k
      NULL, node, child, NULL,
9274
1.16k
      "(annotation?, (restriction | list | union))");
9275
13.2k
    } else if (IS_SCHEMA(child, "restriction")) {
9276
9.91k
        xmlSchemaParseRestriction(ctxt, schema, child,
9277
9.91k
      XML_SCHEMA_TYPE_SIMPLE);
9278
9.91k
  hasRestriction = 1;
9279
9.91k
        child = child->next;
9280
9.91k
    } else if (IS_SCHEMA(child, "list")) {
9281
311
        xmlSchemaParseList(ctxt, schema, child);
9282
311
        child = child->next;
9283
3.01k
    } else if (IS_SCHEMA(child, "union")) {
9284
2.70k
        xmlSchemaParseUnion(ctxt, schema, child);
9285
2.70k
        child = child->next;
9286
2.70k
    }
9287
14.4k
    if (child != NULL) {
9288
1.84k
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9289
1.84k
      NULL, node, child, NULL,
9290
1.84k
      "(annotation?, (restriction | list | union))");
9291
1.84k
    }
9292
    /*
9293
    * REDEFINE: SPEC src-redefine (5)
9294
    * "Within the [children], each <simpleType> must have a
9295
    * <restriction> among its [children] ... the `actual value` of whose
9296
    * base [attribute] must be the same as the `actual value` of its own
9297
    * name attribute plus target namespace;"
9298
    */
9299
14.4k
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9300
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9301
0
      NULL, node, "This is a redefinition, thus the "
9302
0
      "<simpleType> must have a <restriction> child", NULL);
9303
0
    }
9304
9305
14.4k
    ctxt->ctxtType = oldCtxtType;
9306
14.4k
    return (type);
9307
14.4k
}
9308
9309
/**
9310
 * xmlSchemaParseModelGroupDefRef:
9311
 * @ctxt:  the parser context
9312
 * @schema: the schema being built
9313
 * @node:  the node
9314
 *
9315
 * Parses a reference to a model group definition.
9316
 *
9317
 * We will return a particle component with a qname-component or
9318
 * NULL in case of an error.
9319
 */
9320
static xmlSchemaTreeItemPtr
9321
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9322
             xmlSchemaPtr schema,
9323
             xmlNodePtr node)
9324
1.71k
{
9325
1.71k
    xmlSchemaParticlePtr item;
9326
1.71k
    xmlNodePtr child = NULL;
9327
1.71k
    xmlAttrPtr attr;
9328
1.71k
    const xmlChar *ref = NULL, *refNs = NULL;
9329
1.71k
    int min, max;
9330
9331
1.71k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9332
0
        return (NULL);
9333
9334
1.71k
    attr = xmlSchemaGetPropNode(node, "ref");
9335
1.71k
    if (attr == NULL) {
9336
400
  xmlSchemaPMissingAttrErr(ctxt,
9337
400
      XML_SCHEMAP_S4S_ATTR_MISSING,
9338
400
      NULL, node, "ref", NULL);
9339
400
  return (NULL);
9340
1.31k
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9341
1.31k
  attr, &refNs, &ref) != 0) {
9342
137
  return (NULL);
9343
137
    }
9344
1.17k
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9345
1.17k
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9346
1.17k
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9347
1.17k
  "(xs:nonNegativeInteger | unbounded)");
9348
    /*
9349
    * Check for illegal attributes.
9350
    */
9351
1.17k
    attr = node->properties;
9352
5.59k
    while (attr != NULL) {
9353
4.42k
  if (attr->ns == NULL) {
9354
3.57k
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9355
3.57k
    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9356
3.57k
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9357
3.57k
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9358
728
    xmlSchemaPIllegalAttrErr(ctxt,
9359
728
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9360
728
      }
9361
3.57k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9362
232
      xmlSchemaPIllegalAttrErr(ctxt,
9363
232
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9364
232
  }
9365
4.42k
  attr = attr->next;
9366
4.42k
    }
9367
1.17k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9368
1.17k
    item = xmlSchemaAddParticle(ctxt, node, min, max);
9369
1.17k
    if (item == NULL)
9370
0
  return (NULL);
9371
    /*
9372
    * Create a qname-reference and set as the term; it will be substituted
9373
    * for the model group after the reference has been resolved.
9374
    */
9375
1.17k
    item->children = (xmlSchemaTreeItemPtr)
9376
1.17k
  xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9377
1.17k
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9378
    /*
9379
    * And now for the children...
9380
    */
9381
1.17k
    child = node->children;
9382
    /* TODO: Is annotation even allowed for a model group reference? */
9383
1.17k
    if (IS_SCHEMA(child, "annotation")) {
9384
  /*
9385
  * TODO: What to do exactly with the annotation?
9386
  */
9387
1
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9388
1
  child = child->next;
9389
1
    }
9390
1.17k
    if (child != NULL) {
9391
22
  xmlSchemaPContentErr(ctxt,
9392
22
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9393
22
      NULL, node, child, NULL,
9394
22
      "(annotation?)");
9395
22
    }
9396
    /*
9397
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
9398
    */
9399
1.17k
    if ((min == 0) && (max == 0))
9400
33
  return (NULL);
9401
9402
1.14k
    return ((xmlSchemaTreeItemPtr) item);
9403
1.17k
}
9404
9405
/**
9406
 * xmlSchemaParseModelGroupDefinition:
9407
 * @ctxt:  a schema validation context
9408
 * @schema:  the schema being built
9409
 * @node:  a subtree containing XML Schema information
9410
 *
9411
 * Parses a XML schema model group definition.
9412
 *
9413
 * Note that the constraint src-redefine (6.2) can't be applied until
9414
 * references have been resolved. So we will do this at the
9415
 * component fixup level.
9416
 *
9417
 * *WARNING* this interface is highly subject to change
9418
 *
9419
 * Returns -1 in case of error, 0 if the declaration is improper and
9420
 *         1 in case of success.
9421
 */
9422
static xmlSchemaModelGroupDefPtr
9423
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9424
           xmlSchemaPtr schema,
9425
           xmlNodePtr node)
9426
4.80k
{
9427
4.80k
    xmlSchemaModelGroupDefPtr item;
9428
4.80k
    xmlNodePtr child = NULL;
9429
4.80k
    xmlAttrPtr attr;
9430
4.80k
    const xmlChar *name;
9431
9432
4.80k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9433
0
        return (NULL);
9434
9435
4.80k
    attr = xmlSchemaGetPropNode(node, "name");
9436
4.80k
    if (attr == NULL) {
9437
1.58k
  xmlSchemaPMissingAttrErr(ctxt,
9438
1.58k
      XML_SCHEMAP_S4S_ATTR_MISSING,
9439
1.58k
      NULL, node,
9440
1.58k
      "name", NULL);
9441
1.58k
  return (NULL);
9442
3.21k
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9443
3.21k
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9444
698
  return (NULL);
9445
698
    }
9446
2.52k
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9447
2.52k
  ctxt->targetNamespace, node);
9448
2.52k
    if (item == NULL)
9449
0
  return (NULL);
9450
    /*
9451
    * Check for illegal attributes.
9452
    */
9453
2.52k
    attr = node->properties;
9454
7.29k
    while (attr != NULL) {
9455
4.77k
  if (attr->ns == NULL) {
9456
3.76k
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9457
3.76k
    (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9458
917
    xmlSchemaPIllegalAttrErr(ctxt,
9459
917
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9460
917
      }
9461
3.76k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9462
42
      xmlSchemaPIllegalAttrErr(ctxt,
9463
42
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9464
42
  }
9465
4.77k
  attr = attr->next;
9466
4.77k
    }
9467
2.52k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9468
    /*
9469
    * And now for the children...
9470
    */
9471
2.52k
    child = node->children;
9472
2.52k
    if (IS_SCHEMA(child, "annotation")) {
9473
33
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9474
33
  child = child->next;
9475
33
    }
9476
2.52k
    if (IS_SCHEMA(child, "all")) {
9477
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9478
0
      XML_SCHEMA_TYPE_ALL, 0);
9479
0
  child = child->next;
9480
2.52k
    } else if (IS_SCHEMA(child, "choice")) {
9481
639
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9482
639
      XML_SCHEMA_TYPE_CHOICE, 0);
9483
639
  child = child->next;
9484
1.88k
    } else if (IS_SCHEMA(child, "sequence")) {
9485
435
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9486
435
      XML_SCHEMA_TYPE_SEQUENCE, 0);
9487
435
  child = child->next;
9488
435
    }
9489
9490
9491
9492
2.52k
    if (child != NULL) {
9493
1.11k
  xmlSchemaPContentErr(ctxt,
9494
1.11k
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9495
1.11k
      NULL, node, child, NULL,
9496
1.11k
      "(annotation?, (all | choice | sequence)?)");
9497
1.11k
    }
9498
2.52k
    return (item);
9499
2.52k
}
9500
9501
/**
9502
 * xmlSchemaCleanupDoc:
9503
 * @ctxt:  a schema validation context
9504
 * @node:  the root of the document.
9505
 *
9506
 * removes unwanted nodes in a schemas document tree
9507
 */
9508
static void
9509
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9510
13.1k
{
9511
13.1k
    xmlNodePtr delete, cur;
9512
9513
13.1k
    if ((ctxt == NULL) || (root == NULL)) return;
9514
9515
    /*
9516
     * Remove all the blank text nodes
9517
     */
9518
13.1k
    delete = NULL;
9519
13.1k
    cur = root;
9520
809k
    while (cur != NULL) {
9521
796k
        if (delete != NULL) {
9522
288k
            xmlUnlinkNode(delete);
9523
288k
            xmlFreeNode(delete);
9524
288k
            delete = NULL;
9525
288k
        }
9526
796k
        if (cur->type == XML_TEXT_NODE) {
9527
384k
            if (IS_BLANK_NODE(cur)) {
9528
290k
                if (xmlNodeGetSpacePreserve(cur) != 1) {
9529
290k
                    delete = cur;
9530
290k
                }
9531
290k
            }
9532
412k
        } else if ((cur->type != XML_ELEMENT_NODE) &&
9533
412k
                   (cur->type != XML_CDATA_SECTION_NODE)) {
9534
7.62k
            delete = cur;
9535
7.62k
            goto skip_children;
9536
7.62k
        }
9537
9538
        /*
9539
         * Skip to next node
9540
         */
9541
788k
        if (cur->children != NULL) {
9542
115k
            if ((cur->children->type != XML_ENTITY_DECL) &&
9543
115k
                (cur->children->type != XML_ENTITY_REF_NODE) &&
9544
115k
                (cur->children->type != XML_ENTITY_NODE)) {
9545
114k
                cur = cur->children;
9546
114k
                continue;
9547
114k
            }
9548
115k
        }
9549
682k
      skip_children:
9550
682k
        if (cur->next != NULL) {
9551
595k
            cur = cur->next;
9552
595k
            continue;
9553
595k
        }
9554
9555
114k
        do {
9556
114k
            cur = cur->parent;
9557
114k
            if (cur == NULL)
9558
99
                break;
9559
114k
            if (cur == root) {
9560
13.0k
                cur = NULL;
9561
13.0k
                break;
9562
13.0k
            }
9563
101k
            if (cur->next != NULL) {
9564
73.6k
                cur = cur->next;
9565
73.6k
                break;
9566
73.6k
            }
9567
101k
        } while (cur != NULL);
9568
86.7k
    }
9569
13.1k
    if (delete != NULL) {
9570
9.51k
        xmlUnlinkNode(delete);
9571
9.51k
        xmlFreeNode(delete);
9572
9.51k
        delete = NULL;
9573
9.51k
    }
9574
13.1k
}
9575
9576
9577
static void
9578
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9579
214
{
9580
214
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9581
168
  schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9582
9583
214
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9584
3
  schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9585
9586
214
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9587
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9588
214
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9589
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9590
214
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9591
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9592
214
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9593
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9594
9595
214
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9596
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9597
214
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9598
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9599
214
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9600
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9601
214
}
9602
9603
static int
9604
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9605
           xmlSchemaPtr schema,
9606
           xmlNodePtr node)
9607
12.6k
{
9608
12.6k
    xmlAttrPtr attr;
9609
12.6k
    const xmlChar *val;
9610
12.6k
    int res = 0, oldErrs = ctxt->nberrors;
9611
9612
    /*
9613
    * Those flags should be moved to the parser context flags,
9614
    * since they are not visible at the component level. I.e.
9615
    * they are used if processing schema *documents* only.
9616
    */
9617
12.6k
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9618
12.6k
    HFAILURE;
9619
9620
    /*
9621
    * Since the version is of type xs:token, we won't bother to
9622
    * check it.
9623
    */
9624
    /* REMOVED:
9625
    attr = xmlSchemaGetPropNode(node, "version");
9626
    if (attr != NULL) {
9627
  res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9628
      xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9629
  HFAILURE;
9630
    }
9631
    */
9632
12.6k
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
9633
12.6k
    if (attr != NULL) {
9634
1.11k
  res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9635
1.11k
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9636
1.11k
  HFAILURE;
9637
1.11k
  if (res != 0) {
9638
35
      ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9639
35
      goto exit;
9640
35
  }
9641
1.11k
    }
9642
12.6k
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9643
12.6k
    if (attr != NULL) {
9644
290
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9645
290
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9646
290
      XML_SCHEMAS_QUALIF_ELEM);
9647
290
  HFAILURE;
9648
290
  if (res != 0) {
9649
2
      xmlSchemaPSimpleTypeErr(ctxt,
9650
2
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9651
2
    NULL, (xmlNodePtr) attr, NULL,
9652
2
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9653
2
  }
9654
290
    }
9655
12.6k
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9656
12.6k
    if (attr != NULL) {
9657
161
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9658
161
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9659
161
      XML_SCHEMAS_QUALIF_ATTR);
9660
161
  HFAILURE;
9661
161
  if (res != 0) {
9662
1
      xmlSchemaPSimpleTypeErr(ctxt,
9663
1
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9664
1
    NULL, (xmlNodePtr) attr, NULL,
9665
1
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9666
1
  }
9667
161
    }
9668
12.6k
    attr = xmlSchemaGetPropNode(node, "finalDefault");
9669
12.6k
    if (attr != NULL) {
9670
6
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9671
6
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9672
6
      XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9673
6
      XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9674
6
      -1,
9675
6
      XML_SCHEMAS_FINAL_DEFAULT_LIST,
9676
6
      XML_SCHEMAS_FINAL_DEFAULT_UNION);
9677
6
  HFAILURE;
9678
6
  if (res != 0) {
9679
2
      xmlSchemaPSimpleTypeErr(ctxt,
9680
2
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9681
2
    NULL, (xmlNodePtr) attr, NULL,
9682
2
    "(#all | List of (extension | restriction | list | union))",
9683
2
    val, NULL, NULL, NULL);
9684
2
  }
9685
6
    }
9686
12.6k
    attr = xmlSchemaGetPropNode(node, "blockDefault");
9687
12.6k
    if (attr != NULL) {
9688
7
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9689
7
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9690
7
      XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9691
7
      XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9692
7
      XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9693
7
  HFAILURE;
9694
7
  if (res != 0) {
9695
3
      xmlSchemaPSimpleTypeErr(ctxt,
9696
3
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9697
3
    NULL, (xmlNodePtr) attr, NULL,
9698
3
    "(#all | List of (extension | restriction | substitution))",
9699
3
    val, NULL, NULL, NULL);
9700
3
  }
9701
7
    }
9702
9703
12.6k
exit:
9704
12.6k
    if (oldErrs != ctxt->nberrors)
9705
44
  res = ctxt->err;
9706
12.6k
    return(res);
9707
0
exit_failure:
9708
0
    return(-1);
9709
12.6k
}
9710
9711
/**
9712
 * xmlSchemaParseSchemaTopLevel:
9713
 * @ctxt:  a schema validation context
9714
 * @schema:  the schemas
9715
 * @nodes:  the list of top level nodes
9716
 *
9717
 * Returns the internal XML Schema structure built from the resource or
9718
 *         NULL in case of error
9719
 */
9720
static int
9721
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9722
                             xmlSchemaPtr schema, xmlNodePtr nodes)
9723
12.5k
{
9724
12.5k
    xmlNodePtr child;
9725
12.5k
    xmlSchemaAnnotPtr annot;
9726
12.5k
    int res = 0, oldErrs, tmpOldErrs;
9727
9728
12.5k
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9729
0
        return(-1);
9730
9731
12.5k
    oldErrs = ctxt->nberrors;
9732
12.5k
    child = nodes;
9733
17.4k
    while ((IS_SCHEMA(child, "include")) ||
9734
17.4k
     (IS_SCHEMA(child, "import")) ||
9735
17.4k
     (IS_SCHEMA(child, "redefine")) ||
9736
17.4k
     (IS_SCHEMA(child, "annotation"))) {
9737
5.07k
  if (IS_SCHEMA(child, "annotation")) {
9738
337
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9739
337
      if (schema->annot == NULL)
9740
230
    schema->annot = annot;
9741
107
      else
9742
107
    xmlSchemaFreeAnnot(annot);
9743
4.73k
  } else if (IS_SCHEMA(child, "import")) {
9744
4.57k
      tmpOldErrs = ctxt->nberrors;
9745
4.57k
      res = xmlSchemaParseImport(ctxt, schema, child);
9746
4.57k
      HFAILURE;
9747
4.56k
      HSTOP(ctxt);
9748
4.56k
      if (tmpOldErrs != ctxt->nberrors)
9749
102
    goto exit;
9750
4.56k
  } else if (IS_SCHEMA(child, "include")) {
9751
163
      tmpOldErrs = ctxt->nberrors;
9752
163
      res = xmlSchemaParseInclude(ctxt, schema, child);
9753
163
      HFAILURE;
9754
161
      HSTOP(ctxt);
9755
161
      if (tmpOldErrs != ctxt->nberrors)
9756
77
    goto exit;
9757
161
  } else if (IS_SCHEMA(child, "redefine")) {
9758
0
      tmpOldErrs = ctxt->nberrors;
9759
0
      res = xmlSchemaParseRedefine(ctxt, schema, child);
9760
0
      HFAILURE;
9761
0
      HSTOP(ctxt);
9762
0
      if (tmpOldErrs != ctxt->nberrors)
9763
0
    goto exit;
9764
0
  }
9765
4.88k
  child = child->next;
9766
4.88k
    }
9767
    /*
9768
    * URGENT TODO: Change the functions to return int results.
9769
    * We need especially to catch internal errors.
9770
    */
9771
132k
    while (child != NULL) {
9772
120k
  if (IS_SCHEMA(child, "complexType")) {
9773
9.95k
      xmlSchemaParseComplexType(ctxt, schema, child, 1);
9774
9.95k
      child = child->next;
9775
110k
  } else if (IS_SCHEMA(child, "simpleType")) {
9776
10.7k
      xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9777
10.7k
      child = child->next;
9778
99.8k
  } else if (IS_SCHEMA(child, "element")) {
9779
22.1k
      xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9780
22.1k
      child = child->next;
9781
77.7k
  } else if (IS_SCHEMA(child, "attribute")) {
9782
4.01k
      xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9783
4.01k
      child = child->next;
9784
73.7k
  } else if (IS_SCHEMA(child, "attributeGroup")) {
9785
3.98k
      xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9786
3.98k
      child = child->next;
9787
69.7k
  } else if (IS_SCHEMA(child, "group")) {
9788
4.80k
      xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9789
4.80k
      child = child->next;
9790
64.9k
  } else if (IS_SCHEMA(child, "notation")) {
9791
1.73k
      xmlSchemaParseNotation(ctxt, schema, child);
9792
1.73k
      child = child->next;
9793
63.2k
  } else {
9794
63.2k
      xmlSchemaPContentErr(ctxt,
9795
63.2k
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9796
63.2k
    NULL, child->parent, child,
9797
63.2k
    NULL, "((include | import | redefine | annotation)*, "
9798
63.2k
    "(((simpleType | complexType | group | attributeGroup) "
9799
63.2k
    "| element | attribute | notation), annotation*)*)");
9800
63.2k
      child = child->next;
9801
63.2k
  }
9802
122k
  while (IS_SCHEMA(child, "annotation")) {
9803
      /*
9804
      * TODO: We should add all annotations.
9805
      */
9806
2.41k
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9807
2.41k
      if (schema->annot == NULL)
9808
600
    schema->annot = annot;
9809
1.81k
      else
9810
1.81k
    xmlSchemaFreeAnnot(annot);
9811
2.41k
      child = child->next;
9812
2.41k
  }
9813
120k
    }
9814
12.5k
exit:
9815
12.5k
    ctxt->ctxtType = NULL;
9816
12.5k
    if (oldErrs != ctxt->nberrors)
9817
4.59k
  res = ctxt->err;
9818
12.5k
    return(res);
9819
6
exit_failure:
9820
6
    return(-1);
9821
12.3k
}
9822
9823
static xmlSchemaSchemaRelationPtr
9824
xmlSchemaSchemaRelationCreate(void)
9825
4.70k
{
9826
4.70k
    xmlSchemaSchemaRelationPtr ret;
9827
9828
4.70k
    ret = (xmlSchemaSchemaRelationPtr)
9829
4.70k
  xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9830
4.70k
    if (ret == NULL) {
9831
0
  xmlSchemaPErrMemory(NULL);
9832
0
  return(NULL);
9833
0
    }
9834
4.70k
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9835
4.70k
    return(ret);
9836
4.70k
}
9837
9838
#if 0
9839
static void
9840
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9841
{
9842
    xmlFree(rel);
9843
}
9844
#endif
9845
9846
static void
9847
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9848
0
{
9849
0
    xmlSchemaRedefPtr prev;
9850
9851
0
    while (redef != NULL) {
9852
0
  prev = redef;
9853
0
  redef = redef->next;
9854
0
  xmlFree(prev);
9855
0
    }
9856
0
}
9857
9858
static void
9859
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9860
29.0k
{
9861
    /*
9862
    * After the construction context has been freed, there will be
9863
    * no schema graph available any more. Only the schema buckets
9864
    * will stay alive, which are put into the "schemasImports" and
9865
    * "includes" slots of the xmlSchema.
9866
    */
9867
29.0k
    if (con->buckets != NULL)
9868
29.0k
  xmlSchemaItemListFree(con->buckets);
9869
29.0k
    if (con->pending != NULL)
9870
29.0k
  xmlSchemaItemListFree(con->pending);
9871
29.0k
    if (con->substGroups != NULL)
9872
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9873
29.0k
    if (con->redefs != NULL)
9874
0
  xmlSchemaRedefListFree(con->redefs);
9875
29.0k
    if (con->dict != NULL)
9876
29.0k
  xmlDictFree(con->dict);
9877
29.0k
    xmlFree(con);
9878
29.0k
}
9879
9880
static xmlSchemaConstructionCtxtPtr
9881
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9882
29.0k
{
9883
29.0k
    xmlSchemaConstructionCtxtPtr ret;
9884
9885
29.0k
    ret = (xmlSchemaConstructionCtxtPtr)
9886
29.0k
  xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9887
29.0k
    if (ret == NULL) {
9888
0
        xmlSchemaPErrMemory(NULL);
9889
0
        return (NULL);
9890
0
    }
9891
29.0k
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9892
9893
29.0k
    ret->buckets = xmlSchemaItemListCreate();
9894
29.0k
    if (ret->buckets == NULL) {
9895
0
  xmlSchemaPErrMemory(NULL);
9896
0
  xmlFree(ret);
9897
0
        return (NULL);
9898
0
    }
9899
29.0k
    ret->pending = xmlSchemaItemListCreate();
9900
29.0k
    if (ret->pending == NULL) {
9901
0
  xmlSchemaPErrMemory(NULL);
9902
0
  xmlSchemaConstructionCtxtFree(ret);
9903
0
        return (NULL);
9904
0
    }
9905
29.0k
    ret->dict = dict;
9906
29.0k
    xmlDictReference(dict);
9907
29.0k
    return(ret);
9908
29.0k
}
9909
9910
static xmlSchemaParserCtxtPtr
9911
xmlSchemaParserCtxtCreate(void)
9912
29.3k
{
9913
29.3k
    xmlSchemaParserCtxtPtr ret;
9914
9915
29.3k
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9916
29.3k
    if (ret == NULL) {
9917
0
        xmlSchemaPErrMemory(NULL);
9918
0
        return (NULL);
9919
0
    }
9920
29.3k
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9921
29.3k
    ret->type = XML_SCHEMA_CTXT_PARSER;
9922
29.3k
    ret->attrProhibs = xmlSchemaItemListCreate();
9923
29.3k
    if (ret->attrProhibs == NULL) {
9924
0
  xmlFree(ret);
9925
0
  return(NULL);
9926
0
    }
9927
29.3k
    return(ret);
9928
29.3k
}
9929
9930
/**
9931
 * xmlSchemaNewParserCtxtUseDict:
9932
 * @URL:  the location of the schema
9933
 * @dict: the dictionary to be used
9934
 *
9935
 * Create an XML Schemas parse context for that file/resource expected
9936
 * to contain an XML Schemas file.
9937
 *
9938
 * Returns the parser context or NULL in case of error
9939
 */
9940
static xmlSchemaParserCtxtPtr
9941
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9942
261
{
9943
261
    xmlSchemaParserCtxtPtr ret;
9944
9945
261
    ret = xmlSchemaParserCtxtCreate();
9946
261
    if (ret == NULL)
9947
0
        return (NULL);
9948
261
    ret->dict = dict;
9949
261
    xmlDictReference(dict);
9950
261
    if (URL != NULL)
9951
261
  ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9952
261
    return (ret);
9953
261
}
9954
9955
static int
9956
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9957
0
{
9958
0
    if (vctxt->pctxt == NULL) {
9959
0
        if (vctxt->schema != NULL)
9960
0
      vctxt->pctxt =
9961
0
    xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9962
0
  else
9963
0
      vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9964
0
  if (vctxt->pctxt == NULL) {
9965
0
      VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
9966
0
    "failed to create a temp. parser context");
9967
0
      return (-1);
9968
0
  }
9969
  /* TODO: Pass user data. */
9970
0
  xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9971
0
      vctxt->warning, vctxt->errCtxt);
9972
0
  xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9973
0
      vctxt->errCtxt);
9974
0
    }
9975
0
    return (0);
9976
0
}
9977
9978
/**
9979
 * xmlSchemaGetSchemaBucket:
9980
 * @pctxt: the schema parser context
9981
 * @schemaLocation: the URI of the schema document
9982
 *
9983
 * Returns a schema bucket if it was already parsed.
9984
 *
9985
 * Returns a schema bucket if it was already parsed from
9986
 *         @schemaLocation, NULL otherwise.
9987
 */
9988
static xmlSchemaBucketPtr
9989
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9990
          const xmlChar *schemaLocation)
9991
437
{
9992
437
    xmlSchemaBucketPtr cur;
9993
437
    xmlSchemaItemListPtr list;
9994
9995
437
    list = pctxt->constructor->buckets;
9996
437
    if (list->nbItems == 0)
9997
0
  return(NULL);
9998
437
    else {
9999
437
  int i;
10000
1.21k
  for (i = 0; i < list->nbItems; i++) {
10001
835
      cur = (xmlSchemaBucketPtr) list->items[i];
10002
      /* Pointer comparison! */
10003
835
      if (cur->schemaLocation == schemaLocation)
10004
57
    return(cur);
10005
835
  }
10006
437
    }
10007
380
    return(NULL);
10008
437
}
10009
10010
static xmlSchemaBucketPtr
10011
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10012
             const xmlChar *schemaLocation,
10013
             const xmlChar *targetNamespace)
10014
25
{
10015
25
    xmlSchemaBucketPtr cur;
10016
25
    xmlSchemaItemListPtr list;
10017
10018
25
    list = pctxt->constructor->buckets;
10019
25
    if (list->nbItems == 0)
10020
0
  return(NULL);
10021
25
    else {
10022
25
  int i;
10023
117
  for (i = 0; i < list->nbItems; i++) {
10024
93
      cur = (xmlSchemaBucketPtr) list->items[i];
10025
      /* Pointer comparison! */
10026
93
      if ((cur->origTargetNamespace == NULL) &&
10027
93
    (cur->schemaLocation == schemaLocation) &&
10028
93
    (cur->targetNamespace == targetNamespace))
10029
1
    return(cur);
10030
93
  }
10031
25
    }
10032
24
    return(NULL);
10033
25
}
10034
10035
10036
#define IS_BAD_SCHEMA_DOC(b) \
10037
393
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10038
10039
static xmlSchemaBucketPtr
10040
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10041
         const xmlChar *targetNamespace,
10042
         int imported)
10043
268
{
10044
268
    xmlSchemaBucketPtr cur;
10045
268
    xmlSchemaItemListPtr list;
10046
10047
268
    list = pctxt->constructor->buckets;
10048
268
    if (list->nbItems == 0)
10049
0
  return(NULL);
10050
268
    else {
10051
268
  int i;
10052
624
  for (i = 0; i < list->nbItems; i++) {
10053
393
      cur = (xmlSchemaBucketPtr) list->items[i];
10054
393
      if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10055
393
    (cur->origTargetNamespace == targetNamespace) &&
10056
393
    ((imported && cur->imported) ||
10057
44
     ((!imported) && (!cur->imported))))
10058
37
    return(cur);
10059
393
  }
10060
268
    }
10061
231
    return(NULL);
10062
268
}
10063
10064
static int
10065
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10066
         xmlSchemaPtr schema,
10067
         xmlSchemaBucketPtr bucket)
10068
12.6k
{
10069
12.6k
    int oldFlags;
10070
12.6k
    xmlDocPtr oldDoc;
10071
12.6k
    xmlNodePtr node;
10072
12.6k
    int ret, oldErrs;
10073
12.6k
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10074
10075
    /*
10076
    * Save old values; reset the *main* schema.
10077
    * URGENT TODO: This is not good; move the per-document information
10078
    * to the parser. Get rid of passing the main schema to the
10079
    * parsing functions.
10080
    */
10081
12.6k
    oldFlags = schema->flags;
10082
12.6k
    oldDoc = schema->doc;
10083
12.6k
    if (schema->flags != 0)
10084
214
  xmlSchemaClearSchemaDefaults(schema);
10085
12.6k
    schema->doc = bucket->doc;
10086
12.6k
    pctxt->schema = schema;
10087
    /*
10088
    * Keep the current target namespace on the parser *not* on the
10089
    * main schema.
10090
    */
10091
12.6k
    pctxt->targetNamespace = bucket->targetNamespace;
10092
12.6k
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10093
10094
12.6k
    if ((bucket->targetNamespace != NULL) &&
10095
12.6k
  xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10096
  /*
10097
  * We are parsing the schema for schemas!
10098
  */
10099
1
  pctxt->isS4S = 1;
10100
1
    }
10101
    /* Mark it as parsed, even if parsing fails. */
10102
12.6k
    bucket->parsed++;
10103
    /* Compile the schema doc. */
10104
12.6k
    node = xmlDocGetRootElement(bucket->doc);
10105
12.6k
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10106
12.6k
    if (ret != 0)
10107
44
  goto exit;
10108
    /* An empty schema; just get out. */
10109
12.6k
    if (node->children == NULL)
10110
61
  goto exit;
10111
12.5k
    oldErrs = pctxt->nberrors;
10112
12.5k
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10113
12.5k
    if (ret != 0)
10114
4.60k
  goto exit;
10115
    /*
10116
    * TODO: Not nice, but I'm not 100% sure we will get always an error
10117
    * as a result of the above functions; so better rely on pctxt->err
10118
    * as well.
10119
    */
10120
7.98k
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10121
0
  ret = pctxt->err;
10122
0
  goto exit;
10123
0
    }
10124
10125
12.6k
exit:
10126
12.6k
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10127
    /* Restore schema values. */
10128
12.6k
    schema->doc = oldDoc;
10129
12.6k
    schema->flags = oldFlags;
10130
12.6k
    return(ret);
10131
7.98k
}
10132
10133
static int
10134
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10135
         xmlSchemaPtr schema,
10136
         xmlSchemaBucketPtr bucket)
10137
261
{
10138
261
    xmlSchemaParserCtxtPtr newpctxt;
10139
261
    int res = 0;
10140
10141
261
    if (bucket == NULL)
10142
0
  return(0);
10143
261
    if (bucket->parsed) {
10144
0
  PERROR_INT("xmlSchemaParseNewDoc",
10145
0
      "reparsing a schema doc");
10146
0
  return(-1);
10147
0
    }
10148
261
    if (bucket->doc == NULL) {
10149
0
  PERROR_INT("xmlSchemaParseNewDoc",
10150
0
      "parsing a schema doc, but there's no doc");
10151
0
  return(-1);
10152
0
    }
10153
261
    if (pctxt->constructor == NULL) {
10154
0
  PERROR_INT("xmlSchemaParseNewDoc",
10155
0
      "no constructor");
10156
0
  return(-1);
10157
0
    }
10158
    /* Create and init the temporary parser context. */
10159
261
    newpctxt = xmlSchemaNewParserCtxtUseDict(
10160
261
  (const char *) bucket->schemaLocation, pctxt->dict);
10161
261
    if (newpctxt == NULL)
10162
0
  return(-1);
10163
261
    newpctxt->constructor = pctxt->constructor;
10164
    /*
10165
    * TODO: Can we avoid that the parser knows about the main schema?
10166
    * It would be better if he knows about the current schema bucket
10167
    * only.
10168
    */
10169
261
    newpctxt->schema = schema;
10170
261
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10171
261
  pctxt->errCtxt);
10172
261
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10173
261
  pctxt->errCtxt);
10174
261
    newpctxt->counter = pctxt->counter;
10175
10176
10177
261
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10178
10179
    /* Channel back errors and cleanup the temporary parser context. */
10180
261
    if (res != 0)
10181
57
  pctxt->err = res;
10182
261
    pctxt->nberrors += newpctxt->nberrors;
10183
261
    pctxt->counter = newpctxt->counter;
10184
261
    newpctxt->constructor = NULL;
10185
    /* Free the parser context. */
10186
261
    xmlSchemaFreeParserCtxt(newpctxt);
10187
261
    return(res);
10188
261
}
10189
10190
static void
10191
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10192
        xmlSchemaSchemaRelationPtr rel)
10193
4.70k
{
10194
4.70k
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
10195
10196
4.70k
    if (cur == NULL) {
10197
457
  bucket->relations = rel;
10198
457
  return;
10199
457
    }
10200
315k
    while (cur->next != NULL)
10201
310k
  cur = cur->next;
10202
4.24k
    cur->next = rel;
10203
4.24k
}
10204
10205
10206
static const xmlChar *
10207
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10208
        xmlNodePtr ctxtNode)
10209
4.32k
{
10210
    /*
10211
    * Build an absolute location URI.
10212
    */
10213
4.32k
    if (location != NULL) {
10214
4.32k
  if (ctxtNode == NULL)
10215
0
      return(location);
10216
4.32k
  else {
10217
4.32k
      xmlChar *base, *URI;
10218
4.32k
      const xmlChar *ret = NULL;
10219
10220
4.32k
      base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10221
4.32k
      if (base == NULL) {
10222
440
    URI = xmlBuildURI(location, ctxtNode->doc->URL);
10223
3.88k
      } else {
10224
3.88k
    URI = xmlBuildURI(location, base);
10225
3.88k
    xmlFree(base);
10226
3.88k
      }
10227
4.32k
      if (URI != NULL) {
10228
293
    ret = xmlDictLookup(dict, URI, -1);
10229
293
    xmlFree(URI);
10230
293
    return(ret);
10231
293
      }
10232
4.32k
  }
10233
4.32k
    }
10234
4.02k
    return(NULL);
10235
4.32k
}
10236
10237
10238
10239
/**
10240
 * xmlSchemaAddSchemaDoc:
10241
 * @pctxt:  a schema validation context
10242
 * @schema:  the schema being built
10243
 * @node:  a subtree containing XML Schema information
10244
 *
10245
 * Parse an included (and to-be-redefined) XML schema document.
10246
 *
10247
 * Returns 0 on success, a positive error code on errors and
10248
 *         -1 in case of an internal or API error.
10249
 */
10250
10251
static int
10252
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10253
    int type, /* import or include or redefine */
10254
    const xmlChar *schemaLocation,
10255
    xmlDocPtr schemaDoc,
10256
    const char *schemaBuffer,
10257
    int schemaBufferLen,
10258
    xmlNodePtr invokingNode,
10259
    const xmlChar *sourceTargetNamespace,
10260
    const xmlChar *importNamespace,
10261
    xmlSchemaBucketPtr *bucket)
10262
33.7k
{
10263
33.7k
    const xmlChar *targetNamespace = NULL;
10264
33.7k
    xmlSchemaSchemaRelationPtr relation = NULL;
10265
33.7k
    xmlDocPtr doc = NULL;
10266
33.7k
    int res = 0, err = 0, located = 0, preserveDoc = 0;
10267
33.7k
    xmlSchemaBucketPtr bkt = NULL;
10268
10269
33.7k
    if (bucket != NULL)
10270
33.7k
  *bucket = NULL;
10271
10272
33.7k
    switch (type) {
10273
4.56k
  case XML_SCHEMA_SCHEMA_IMPORT:
10274
33.6k
  case XML_SCHEMA_SCHEMA_MAIN:
10275
33.6k
      err = XML_SCHEMAP_SRC_IMPORT;
10276
33.6k
      break;
10277
144
  case XML_SCHEMA_SCHEMA_INCLUDE:
10278
144
      err = XML_SCHEMAP_SRC_INCLUDE;
10279
144
      break;
10280
0
  case XML_SCHEMA_SCHEMA_REDEFINE:
10281
0
      err = XML_SCHEMAP_SRC_REDEFINE;
10282
0
      break;
10283
33.7k
    }
10284
10285
10286
    /* Special handling for the main schema:
10287
    * skip the location and relation logic and just parse the doc.
10288
    * We need just a bucket to be returned in this case.
10289
    */
10290
33.7k
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10291
29.0k
  goto doc_load;
10292
10293
    /* Note that we expect the location to be an absolute URI. */
10294
4.70k
    if (schemaLocation != NULL) {
10295
437
  bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10296
437
  if ((bkt != NULL) &&
10297
437
      (pctxt->constructor->bucket == bkt)) {
10298
      /* Report self-imports/inclusions/redefinitions. */
10299
10300
2
      xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10301
2
    invokingNode, NULL,
10302
2
    "The schema must not import/include/redefine itself",
10303
2
    NULL, NULL);
10304
2
      goto exit;
10305
2
  }
10306
437
    }
10307
    /*
10308
    * Create a relation for the graph of schemas.
10309
    */
10310
4.70k
    relation = xmlSchemaSchemaRelationCreate();
10311
4.70k
    if (relation == NULL)
10312
0
  return(-1);
10313
4.70k
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10314
4.70k
  relation);
10315
4.70k
    relation->type = type;
10316
10317
    /*
10318
    * Save the namespace import information.
10319
    */
10320
4.70k
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10321
4.56k
  relation->importNamespace = importNamespace;
10322
4.56k
  if (schemaLocation == NULL) {
10323
      /*
10324
      * No location; this is just an import of the namespace.
10325
      * Note that we don't assign a bucket to the relation
10326
      * in this case.
10327
      */
10328
4.26k
      goto exit;
10329
4.26k
  }
10330
291
  targetNamespace = importNamespace;
10331
291
    }
10332
10333
    /* Did we already fetch the doc? */
10334
435
    if (bkt != NULL) {
10335
55
  if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10336
      /*
10337
      * We included/redefined and then try to import a schema,
10338
      * but the new location provided for import was different.
10339
      */
10340
0
      if (schemaLocation == NULL)
10341
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10342
0
      if (!xmlStrEqual(schemaLocation,
10343
0
    bkt->schemaLocation)) {
10344
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10345
0
        invokingNode, NULL,
10346
0
        "The schema document '%s' cannot be imported, since "
10347
0
        "it was already included or redefined",
10348
0
        schemaLocation, NULL);
10349
0
    goto exit;
10350
0
      }
10351
55
  } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10352
      /*
10353
      * We imported and then try to include/redefine a schema,
10354
      * but the new location provided for the include/redefine
10355
      * was different.
10356
      */
10357
3
      if (schemaLocation == NULL)
10358
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10359
3
      if (!xmlStrEqual(schemaLocation,
10360
3
    bkt->schemaLocation)) {
10361
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10362
0
        invokingNode, NULL,
10363
0
        "The schema document '%s' cannot be included or "
10364
0
        "redefined, since it was already imported",
10365
0
        schemaLocation, NULL);
10366
0
    goto exit;
10367
0
      }
10368
3
  }
10369
55
    }
10370
10371
435
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10372
  /*
10373
  * Given that the schemaLocation [attribute] is only a hint, it is open
10374
  * to applications to ignore all but the first <import> for a given
10375
  * namespace, regardless of the `actual value` of schemaLocation, but
10376
  * such a strategy risks missing useful information when new
10377
  * schemaLocations are offered.
10378
  *
10379
  * We will use the first <import> that comes with a location.
10380
  * Further <import>s *with* a location, will result in an error.
10381
  * TODO: Better would be to just report a warning here, but
10382
  * we'll try it this way until someone complains.
10383
  *
10384
  * Schema Document Location Strategy:
10385
  * 3 Based on the namespace name, identify an existing schema document,
10386
  * either as a resource which is an XML document or a <schema> element
10387
  * information item, in some local schema repository;
10388
  * 5 Attempt to resolve the namespace name to locate such a resource.
10389
  *
10390
  * NOTE: (3) and (5) are not supported.
10391
  */
10392
291
  if (bkt != NULL) {
10393
23
      relation->bucket = bkt;
10394
23
      goto exit;
10395
23
  }
10396
268
  bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10397
268
      importNamespace, 1);
10398
10399
268
  if (bkt != NULL) {
10400
37
      relation->bucket = bkt;
10401
37
      if (bkt->schemaLocation == NULL) {
10402
    /* First given location of the schema; load the doc. */
10403
0
    bkt->schemaLocation = schemaLocation;
10404
37
      } else {
10405
37
    if (!xmlStrEqual(schemaLocation,
10406
37
        bkt->schemaLocation)) {
10407
        /*
10408
        * Additional location given; just skip it.
10409
        * URGENT TODO: We should report a warning here.
10410
        * res = XML_SCHEMAP_SRC_IMPORT;
10411
        */
10412
37
        if (schemaLocation == NULL)
10413
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10414
10415
37
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10416
37
      XML_SCHEMAP_WARN_SKIP_SCHEMA,
10417
37
      invokingNode, NULL,
10418
37
      "Skipping import of schema located at '%s' for the "
10419
37
      "namespace '%s', since this namespace was already "
10420
37
      "imported with the schema located at '%s'",
10421
37
      schemaLocation, importNamespace, bkt->schemaLocation);
10422
37
    }
10423
37
    goto exit;
10424
37
      }
10425
37
  }
10426
  /*
10427
  * No bucket + first location: load the doc and create a
10428
  * bucket.
10429
  */
10430
268
    } else {
10431
  /* <include> and <redefine> */
10432
144
  if (bkt != NULL) {
10433
10434
32
      if ((bkt->origTargetNamespace == NULL) &&
10435
32
    (bkt->targetNamespace != sourceTargetNamespace)) {
10436
25
    xmlSchemaBucketPtr chamel;
10437
10438
    /*
10439
    * Chameleon include/redefine: skip loading only if it was
10440
    * already build for the targetNamespace of the including
10441
    * schema.
10442
    */
10443
    /*
10444
    * URGENT TODO: If the schema is a chameleon-include then copy
10445
    * the components into the including schema and modify the
10446
    * targetNamespace of those components, do nothing otherwise.
10447
    * NOTE: This is currently worked-around by compiling the
10448
    * chameleon for every distinct including targetNamespace; thus
10449
    * not performant at the moment.
10450
    * TODO: Check when the namespace in wildcards for chameleons
10451
    * needs to be converted: before we built wildcard intersections
10452
    * or after.
10453
    *   Answer: after!
10454
    */
10455
25
    chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10456
25
        schemaLocation, sourceTargetNamespace);
10457
25
    if (chamel != NULL) {
10458
        /* A fitting chameleon was already parsed; NOP. */
10459
1
        relation->bucket = chamel;
10460
1
        goto exit;
10461
1
    }
10462
    /*
10463
    * We need to parse the chameleon again for a different
10464
    * targetNamespace.
10465
    * CHAMELEON TODO: Optimize this by only parsing the
10466
    * chameleon once, and then copying the components to
10467
    * the new targetNamespace.
10468
    */
10469
24
    bkt = NULL;
10470
24
      } else {
10471
7
    relation->bucket = bkt;
10472
7
    goto exit;
10473
7
      }
10474
32
  }
10475
144
    }
10476
367
    if ((bkt != NULL) && (bkt->doc != NULL)) {
10477
0
  PERROR_INT("xmlSchemaAddSchemaDoc",
10478
0
      "trying to load a schema doc, but a doc is already "
10479
0
      "assigned to the schema bucket");
10480
0
  goto exit_failure;
10481
0
    }
10482
10483
29.4k
doc_load:
10484
    /*
10485
    * Load the document.
10486
    */
10487
29.4k
    if (schemaDoc != NULL) {
10488
0
  doc = schemaDoc;
10489
  /* Don' free this one, since it was provided by the caller. */
10490
0
  preserveDoc = 1;
10491
  /* TODO: Does the context or the doc hold the location? */
10492
0
  if (schemaDoc->URL != NULL)
10493
0
      schemaLocation = xmlDictLookup(pctxt->dict,
10494
0
    schemaDoc->URL, -1);
10495
0
        else
10496
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10497
29.4k
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10498
29.4k
  xmlParserCtxtPtr parserCtxt;
10499
10500
29.4k
  parserCtxt = xmlNewParserCtxt();
10501
29.4k
  if (parserCtxt == NULL) {
10502
0
      xmlSchemaPErrMemory(NULL);
10503
0
      goto exit_failure;
10504
0
  }
10505
10506
29.4k
        if (pctxt->serror != NULL)
10507
0
            xmlCtxtSetErrorHandler(parserCtxt, pctxt->serror, pctxt->errCtxt);
10508
10509
29.4k
  if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10510
      /*
10511
      * TODO: Do we have to burden the schema parser dict with all
10512
      * the content of the schema doc?
10513
      */
10514
29.4k
      xmlDictFree(parserCtxt->dict);
10515
29.4k
      parserCtxt->dict = pctxt->dict;
10516
29.4k
      xmlDictReference(parserCtxt->dict);
10517
29.4k
  }
10518
29.4k
  if (schemaLocation != NULL) {
10519
      /* Parse from file. */
10520
29.4k
      doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10521
29.4k
    NULL, SCHEMAS_PARSE_OPTIONS);
10522
29.4k
  } else if (schemaBuffer != NULL) {
10523
      /* Parse from memory buffer. */
10524
0
      doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10525
0
    NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10526
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10527
0
      if (doc != NULL)
10528
0
    doc->URL = xmlStrdup(schemaLocation);
10529
0
  }
10530
  /*
10531
  * For <import>:
10532
  * 2.1 The referent is (a fragment of) a resource which is an
10533
  * XML document (see clause 1.1), which in turn corresponds to
10534
  * a <schema> element information item in a well-formed information
10535
  * set, which in turn corresponds to a valid schema.
10536
  * TODO: (2.1) fragments of XML documents are not supported.
10537
  *
10538
  * 2.2 The referent is a <schema> element information item in
10539
  * a well-formed information set, which in turn corresponds
10540
  * to a valid schema.
10541
  * TODO: (2.2) is not supported.
10542
  */
10543
29.4k
  if (doc == NULL) {
10544
16.1k
      const xmlError *lerr;
10545
16.1k
      lerr = xmlGetLastError();
10546
      /*
10547
      * Check if this a parser error, or if the document could
10548
      * just not be located.
10549
      * TODO: Try to find specific error codes to react only on
10550
      * localisation failures.
10551
      */
10552
16.1k
      if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10553
    /*
10554
    * We assume a parser error here.
10555
    */
10556
15.5k
    located = 1;
10557
    /* TODO: Error code ?? */
10558
15.5k
    res = XML_SCHEMAP_SRC_IMPORT_2_1;
10559
15.5k
    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10560
15.5k
        invokingNode, NULL,
10561
15.5k
        "Failed to parse the XML resource '%s'",
10562
15.5k
        schemaLocation, NULL);
10563
15.5k
      }
10564
16.1k
  }
10565
29.4k
  xmlFreeParserCtxt(parserCtxt);
10566
29.4k
  if ((doc == NULL) && located)
10567
15.5k
      goto exit_error;
10568
29.4k
    } else {
10569
0
  xmlSchemaPErr(pctxt, NULL,
10570
0
      XML_SCHEMAP_NOTHING_TO_PARSE,
10571
0
      "No information for parsing was provided with the "
10572
0
      "given schema parser context.\n",
10573
0
      NULL, NULL);
10574
0
  goto exit_failure;
10575
0
    }
10576
    /*
10577
    * Preprocess the document.
10578
    */
10579
13.8k
    if (doc != NULL) {
10580
13.2k
  xmlNodePtr docElem = NULL;
10581
10582
13.2k
  located = 1;
10583
13.2k
  docElem = xmlDocGetRootElement(doc);
10584
13.2k
  if (docElem == NULL) {
10585
119
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10586
119
    invokingNode, NULL,
10587
119
    "The document '%s' has no document element",
10588
119
    schemaLocation, NULL);
10589
119
      goto exit_error;
10590
119
  }
10591
  /*
10592
  * Remove all the blank text nodes.
10593
  */
10594
13.1k
  xmlSchemaCleanupDoc(pctxt, docElem);
10595
  /*
10596
  * Check the schema's top level element.
10597
  */
10598
13.1k
  if (!IS_SCHEMA(docElem, "schema")) {
10599
428
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10600
428
    invokingNode, NULL,
10601
428
    "The XML document '%s' is not a schema document",
10602
428
    schemaLocation, NULL);
10603
428
      goto exit_error;
10604
428
  }
10605
  /*
10606
  * Note that we don't apply a type check for the
10607
  * targetNamespace value here.
10608
  */
10609
12.6k
  targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10610
12.6k
      "targetNamespace");
10611
12.6k
    }
10612
10613
/* after_doc_loading: */
10614
13.3k
    if ((bkt == NULL) && located) {
10615
  /* Only create a bucket if the schema was located. */
10616
12.6k
        bkt = xmlSchemaBucketCreate(pctxt, type,
10617
12.6k
      targetNamespace);
10618
12.6k
  if (bkt == NULL)
10619
2
      goto exit_failure;
10620
12.6k
    }
10621
13.3k
    if (bkt != NULL) {
10622
12.6k
  bkt->schemaLocation = schemaLocation;
10623
12.6k
  bkt->located = located;
10624
12.6k
  if (doc != NULL) {
10625
12.6k
      bkt->doc = doc;
10626
12.6k
      bkt->targetNamespace = targetNamespace;
10627
12.6k
      bkt->origTargetNamespace = targetNamespace;
10628
12.6k
      if (preserveDoc)
10629
0
    bkt->preserveDoc = 1;
10630
12.6k
  }
10631
12.6k
  if (WXS_IS_BUCKET_IMPMAIN(type))
10632
12.5k
      bkt->imported++;
10633
      /*
10634
      * Add it to the graph of schemas.
10635
      */
10636
12.6k
  if (relation != NULL)
10637
264
      relation->bucket = bkt;
10638
12.6k
    }
10639
10640
17.6k
exit:
10641
    /*
10642
    * Return the bucket explicitly; this is needed for the
10643
    * main schema.
10644
    */
10645
17.6k
    if (bucket != NULL)
10646
17.6k
  *bucket = bkt;
10647
17.6k
    return (0);
10648
10649
16.0k
exit_error:
10650
16.0k
    if ((doc != NULL) && (! preserveDoc)) {
10651
547
  xmlFreeDoc(doc);
10652
547
  if (bkt != NULL)
10653
0
      bkt->doc = NULL;
10654
547
    }
10655
16.0k
    return(pctxt->err);
10656
10657
2
exit_failure:
10658
2
    if ((doc != NULL) && (! preserveDoc)) {
10659
2
  xmlFreeDoc(doc);
10660
2
  if (bkt != NULL)
10661
0
      bkt->doc = NULL;
10662
2
    }
10663
2
    return (-1);
10664
13.3k
}
10665
10666
/**
10667
 * xmlSchemaParseImport:
10668
 * @ctxt:  a schema validation context
10669
 * @schema:  the schema being built
10670
 * @node:  a subtree containing XML Schema information
10671
 *
10672
 * parse a XML schema Import definition
10673
 * *WARNING* this interface is highly subject to change
10674
 *
10675
 * Returns 0 in case of success, a positive error code if
10676
 * not valid and -1 in case of an internal error.
10677
 */
10678
static int
10679
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10680
                     xmlNodePtr node)
10681
4.57k
{
10682
4.57k
    xmlNodePtr child;
10683
4.57k
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10684
4.57k
    const xmlChar *thisTargetNamespace;
10685
4.57k
    xmlAttrPtr attr;
10686
4.57k
    int ret = 0;
10687
4.57k
    xmlSchemaBucketPtr bucket = NULL;
10688
10689
4.57k
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10690
0
        return (-1);
10691
10692
    /*
10693
    * Check for illegal attributes.
10694
    */
10695
4.57k
    attr = node->properties;
10696
13.1k
    while (attr != NULL) {
10697
8.61k
  if (attr->ns == NULL) {
10698
4.63k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10699
4.63k
    (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10700
4.63k
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10701
54
    xmlSchemaPIllegalAttrErr(pctxt,
10702
54
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10703
54
      }
10704
4.63k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10705
1
      xmlSchemaPIllegalAttrErr(pctxt,
10706
1
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10707
1
  }
10708
8.61k
  attr = attr->next;
10709
8.61k
    }
10710
    /*
10711
    * Extract and validate attributes.
10712
    */
10713
4.57k
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10714
4.57k
  "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10715
4.57k
  &namespaceName) != 0) {
10716
1
  xmlSchemaPSimpleTypeErr(pctxt,
10717
1
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10718
1
      NULL, node,
10719
1
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10720
1
      NULL, namespaceName, NULL, NULL, NULL);
10721
1
  return (pctxt->err);
10722
1
    }
10723
10724
4.56k
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10725
4.56k
  "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10726
4.56k
  &schemaLocation) != 0) {
10727
1
  xmlSchemaPSimpleTypeErr(pctxt,
10728
1
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10729
1
      NULL, node,
10730
1
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10731
1
      NULL, schemaLocation, NULL, NULL, NULL);
10732
1
  return (pctxt->err);
10733
1
    }
10734
    /*
10735
    * And now for the children...
10736
    */
10737
4.56k
    child = node->children;
10738
4.56k
    if (IS_SCHEMA(child, "annotation")) {
10739
        /*
10740
         * the annotation here is simply discarded ...
10741
   * TODO: really?
10742
         */
10743
0
        child = child->next;
10744
0
    }
10745
4.56k
    if (child != NULL) {
10746
2
  xmlSchemaPContentErr(pctxt,
10747
2
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10748
2
      NULL, node, child, NULL,
10749
2
      "(annotation?)");
10750
2
    }
10751
    /*
10752
    * Apply additional constraints.
10753
    *
10754
    * Note that it is important to use the original @targetNamespace
10755
    * (or none at all), to rule out imports of schemas _with_ a
10756
    * @targetNamespace if the importing schema is a chameleon schema
10757
    * (with no @targetNamespace).
10758
    */
10759
4.56k
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10760
4.56k
    if (namespaceName != NULL) {
10761
  /*
10762
  * 1.1 If the namespace [attribute] is present, then its `actual value`
10763
  * must not match the `actual value` of the enclosing <schema>'s
10764
  * targetNamespace [attribute].
10765
  */
10766
253
  if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10767
1
      xmlSchemaPCustomErr(pctxt,
10768
1
    XML_SCHEMAP_SRC_IMPORT_1_1,
10769
1
    NULL, node,
10770
1
    "The value of the attribute 'namespace' must not match "
10771
1
    "the target namespace '%s' of the importing schema",
10772
1
    thisTargetNamespace);
10773
1
      return (pctxt->err);
10774
1
  }
10775
4.31k
    } else {
10776
  /*
10777
  * 1.2 If the namespace [attribute] is not present, then the enclosing
10778
  * <schema> must have a targetNamespace [attribute].
10779
  */
10780
4.31k
  if (thisTargetNamespace == NULL) {
10781
5
      xmlSchemaPCustomErr(pctxt,
10782
5
    XML_SCHEMAP_SRC_IMPORT_1_2,
10783
5
    NULL, node,
10784
5
    "The attribute 'namespace' must be existent if "
10785
5
    "the importing schema has no target namespace",
10786
5
    NULL);
10787
5
      return (pctxt->err);
10788
5
  }
10789
4.31k
    }
10790
    /*
10791
    * Locate and acquire the schema document.
10792
    */
10793
4.56k
    if (schemaLocation != NULL)
10794
4.32k
  schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10795
4.32k
      schemaLocation, node);
10796
4.56k
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10797
4.56k
  schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10798
4.56k
  namespaceName, &bucket);
10799
10800
4.56k
    if (ret != 0)
10801
31
  return(ret);
10802
10803
    /*
10804
    * For <import>: "It is *not* an error for the application
10805
    * schema reference strategy to fail."
10806
    * So just don't parse if no schema document was found.
10807
    * Note that we will get no bucket if the schema could not be
10808
    * located or if there was no schemaLocation.
10809
    */
10810
4.53k
    if ((bucket == NULL) && (schemaLocation != NULL)) {
10811
43
  xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10812
43
      XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10813
43
      node, NULL,
10814
43
      "Failed to locate a schema at location '%s'. "
10815
43
      "Skipping the import", schemaLocation, NULL, NULL);
10816
43
    }
10817
10818
4.53k
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10819
157
  ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10820
157
    }
10821
10822
4.53k
    return (ret);
10823
4.56k
}
10824
10825
static int
10826
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10827
             xmlSchemaPtr schema,
10828
             xmlNodePtr node,
10829
             xmlChar **schemaLocation,
10830
             int type)
10831
163
{
10832
163
    xmlAttrPtr attr;
10833
10834
163
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10835
163
  (schemaLocation == NULL))
10836
0
        return (-1);
10837
10838
163
    *schemaLocation = NULL;
10839
    /*
10840
    * Check for illegal attributes.
10841
    * Applies for both <include> and <redefine>.
10842
    */
10843
163
    attr = node->properties;
10844
398
    while (attr != NULL) {
10845
235
  if (attr->ns == NULL) {
10846
230
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10847
230
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10848
78
    xmlSchemaPIllegalAttrErr(pctxt,
10849
78
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10850
78
      }
10851
230
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10852
4
      xmlSchemaPIllegalAttrErr(pctxt,
10853
4
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10854
4
  }
10855
235
  attr = attr->next;
10856
235
    }
10857
163
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10858
    /*
10859
    * Preliminary step, extract the URI-Reference and make an URI
10860
    * from the base.
10861
    */
10862
    /*
10863
    * Attribute "schemaLocation" is mandatory.
10864
    */
10865
163
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
10866
163
    if (attr != NULL) {
10867
149
        xmlChar *base = NULL;
10868
149
        xmlChar *uri = NULL;
10869
10870
149
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10871
149
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10872
149
      (const xmlChar **) schemaLocation) != 0)
10873
1
      goto exit_error;
10874
148
  base = xmlNodeGetBase(node->doc, node);
10875
148
  if (base == NULL) {
10876
0
      uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10877
148
  } else {
10878
148
      uri = xmlBuildURI(*schemaLocation, base);
10879
148
      xmlFree(base);
10880
148
  }
10881
148
  if (uri == NULL) {
10882
2
      PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10883
2
    "could not build an URI from the schemaLocation")
10884
2
      goto exit_failure;
10885
2
  }
10886
146
  (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10887
146
  xmlFree(uri);
10888
146
    } else {
10889
14
  xmlSchemaPMissingAttrErr(pctxt,
10890
14
      XML_SCHEMAP_S4S_ATTR_MISSING,
10891
14
      NULL, node, "schemaLocation", NULL);
10892
14
  goto exit_error;
10893
14
    }
10894
    /*
10895
    * Report self-inclusion and self-redefinition.
10896
    */
10897
146
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10898
2
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10899
0
      xmlSchemaPCustomErr(pctxt,
10900
0
    XML_SCHEMAP_SRC_REDEFINE,
10901
0
    NULL, node,
10902
0
    "The schema document '%s' cannot redefine itself.",
10903
0
    *schemaLocation);
10904
2
  } else {
10905
2
      xmlSchemaPCustomErr(pctxt,
10906
2
    XML_SCHEMAP_SRC_INCLUDE,
10907
2
    NULL, node,
10908
2
    "The schema document '%s' cannot include itself.",
10909
2
    *schemaLocation);
10910
2
  }
10911
2
  goto exit_error;
10912
2
    }
10913
10914
144
    return(0);
10915
17
exit_error:
10916
17
    return(pctxt->err);
10917
2
exit_failure:
10918
2
    return(-1);
10919
146
}
10920
10921
static int
10922
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10923
        xmlSchemaPtr schema,
10924
        xmlNodePtr node,
10925
        int type)
10926
163
{
10927
163
    xmlNodePtr child = NULL;
10928
163
    const xmlChar *schemaLocation = NULL;
10929
163
    int res = 0; /* hasRedefinitions = 0 */
10930
163
    int isChameleon = 0, wasChameleon = 0;
10931
163
    xmlSchemaBucketPtr bucket = NULL;
10932
10933
163
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10934
0
        return (-1);
10935
10936
    /*
10937
    * Parse attributes. Note that the returned schemaLocation will
10938
    * be already converted to an absolute URI.
10939
    */
10940
163
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10941
163
  node, (xmlChar **) (&schemaLocation), type);
10942
163
    if (res != 0)
10943
19
  return(res);
10944
    /*
10945
    * Load and add the schema document.
10946
    */
10947
144
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10948
144
  NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10949
144
    if (res != 0)
10950
27
  return(res);
10951
    /*
10952
    * If we get no schema bucket back, then this means that the schema
10953
    * document could not be located or was broken XML or was not
10954
    * a schema document.
10955
    */
10956
117
    if ((bucket == NULL) || (bucket->doc == NULL)) {
10957
2
  if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10958
      /*
10959
      * WARNING for <include>:
10960
      * We will raise an error if the schema cannot be located
10961
      * for inclusions, since the that was the feedback from the
10962
      * schema people. I.e. the following spec piece will *not* be
10963
      * satisfied:
10964
      * SPEC src-include: "It is not an error for the `actual value` of the
10965
      * schemaLocation [attribute] to fail to resolve it all, in which
10966
      * case no corresponding inclusion is performed.
10967
      * So do we need a warning report here?"
10968
      */
10969
2
      res = XML_SCHEMAP_SRC_INCLUDE;
10970
2
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10971
2
    node, NULL,
10972
2
    "Failed to load the document '%s' for inclusion",
10973
2
    schemaLocation, NULL);
10974
2
  } else {
10975
      /*
10976
      * NOTE: This was changed to raise an error even if no redefinitions
10977
      * are specified.
10978
      *
10979
      * SPEC src-redefine (1)
10980
      * "If there are any element information items among the [children]
10981
      * other than <annotation> then the `actual value` of the
10982
      * schemaLocation [attribute] must successfully resolve."
10983
      * TODO: Ask the WG if a the location has always to resolve
10984
      * here as well!
10985
      */
10986
0
      res = XML_SCHEMAP_SRC_REDEFINE;
10987
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10988
0
    node, NULL,
10989
0
    "Failed to load the document '%s' for redefinition",
10990
0
    schemaLocation, NULL);
10991
0
  }
10992
115
    } else {
10993
  /*
10994
  * Check targetNamespace sanity before parsing the new schema.
10995
  * TODO: Note that we won't check further content if the
10996
  * targetNamespace was bad.
10997
  */
10998
115
  if (bucket->origTargetNamespace != NULL) {
10999
      /*
11000
      * SPEC src-include (2.1)
11001
      * "SII has a targetNamespace [attribute], and its `actual
11002
      * value` is identical to the `actual value` of the targetNamespace
11003
      * [attribute] of SII' (which must have such an [attribute])."
11004
      */
11005
15
      if (pctxt->targetNamespace == NULL) {
11006
1
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
11007
1
        XML_SCHEMAP_SRC_INCLUDE,
11008
1
        node, NULL,
11009
1
        "The target namespace of the included/redefined schema "
11010
1
        "'%s' has to be absent, since the including/redefining "
11011
1
        "schema has no target namespace",
11012
1
        schemaLocation, NULL);
11013
1
    goto exit_error;
11014
14
      } else if (!xmlStrEqual(bucket->origTargetNamespace,
11015
14
    pctxt->targetNamespace)) {
11016
    /* TODO: Change error function. */
11017
2
    xmlSchemaPCustomErrExt(pctxt,
11018
2
        XML_SCHEMAP_SRC_INCLUDE,
11019
2
        NULL, node,
11020
2
        "The target namespace '%s' of the included/redefined "
11021
2
        "schema '%s' differs from '%s' of the "
11022
2
        "including/redefining schema",
11023
2
        bucket->origTargetNamespace, schemaLocation,
11024
2
        pctxt->targetNamespace);
11025
2
    goto exit_error;
11026
2
      }
11027
100
  } else if (pctxt->targetNamespace != NULL) {
11028
      /*
11029
      * Chameleons: the original target namespace will
11030
      * differ from the resulting namespace.
11031
      */
11032
76
      isChameleon = 1;
11033
76
      bucket->targetNamespace = pctxt->targetNamespace;
11034
76
  }
11035
115
    }
11036
    /*
11037
    * Parse the schema.
11038
    */
11039
114
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11040
104
  if (isChameleon) {
11041
      /* TODO: Get rid of this flag on the schema itself. */
11042
73
      if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11043
71
    schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11044
71
      } else
11045
2
    wasChameleon = 1;
11046
73
  }
11047
104
  xmlSchemaParseNewDoc(pctxt, schema, bucket);
11048
  /* Restore chameleon flag. */
11049
104
  if (isChameleon && (!wasChameleon))
11050
71
      schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11051
104
    }
11052
    /*
11053
    * And now for the children...
11054
    */
11055
114
    child = node->children;
11056
114
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11057
  /*
11058
  * Parse (simpleType | complexType | group | attributeGroup))*
11059
  */
11060
0
  pctxt->redefined = bucket;
11061
  /*
11062
  * How to proceed if the redefined schema was not located?
11063
  */
11064
0
  pctxt->isRedefine = 1;
11065
0
  while (IS_SCHEMA(child, "annotation") ||
11066
0
      IS_SCHEMA(child, "simpleType") ||
11067
0
      IS_SCHEMA(child, "complexType") ||
11068
0
      IS_SCHEMA(child, "group") ||
11069
0
      IS_SCHEMA(child, "attributeGroup")) {
11070
0
      if (IS_SCHEMA(child, "annotation")) {
11071
    /*
11072
    * TODO: discard or not?
11073
    */
11074
0
      } else if (IS_SCHEMA(child, "simpleType")) {
11075
0
    xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11076
0
      } else if (IS_SCHEMA(child, "complexType")) {
11077
0
    xmlSchemaParseComplexType(pctxt, schema, child, 1);
11078
    /* hasRedefinitions = 1; */
11079
0
      } else if (IS_SCHEMA(child, "group")) {
11080
    /* hasRedefinitions = 1; */
11081
0
    xmlSchemaParseModelGroupDefinition(pctxt,
11082
0
        schema, child);
11083
0
      } else if (IS_SCHEMA(child, "attributeGroup")) {
11084
    /* hasRedefinitions = 1; */
11085
0
    xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11086
0
        child);
11087
0
      }
11088
0
      child = child->next;
11089
0
  }
11090
0
  pctxt->redefined = NULL;
11091
0
  pctxt->isRedefine = 0;
11092
114
    } else {
11093
114
  if (IS_SCHEMA(child, "annotation")) {
11094
      /*
11095
      * TODO: discard or not?
11096
      */
11097
0
      child = child->next;
11098
0
  }
11099
114
    }
11100
114
    if (child != NULL) {
11101
0
  res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11102
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11103
0
      xmlSchemaPContentErr(pctxt, res,
11104
0
    NULL, node, child, NULL,
11105
0
    "(annotation | (simpleType | complexType | group | attributeGroup))*");
11106
0
  } else {
11107
0
       xmlSchemaPContentErr(pctxt, res,
11108
0
    NULL, node, child, NULL,
11109
0
    "(annotation?)");
11110
0
  }
11111
0
    }
11112
114
    return(res);
11113
11114
3
exit_error:
11115
3
    return(pctxt->err);
11116
117
}
11117
11118
static int
11119
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11120
                       xmlNodePtr node)
11121
0
{
11122
0
    int res;
11123
#ifndef ENABLE_REDEFINE
11124
    TODO
11125
    return(0);
11126
#endif
11127
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11128
0
  XML_SCHEMA_SCHEMA_REDEFINE);
11129
0
    if (res != 0)
11130
0
  return(res);
11131
0
    return(0);
11132
0
}
11133
11134
static int
11135
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11136
                       xmlNodePtr node)
11137
163
{
11138
163
    int res;
11139
11140
163
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11141
163
  XML_SCHEMA_SCHEMA_INCLUDE);
11142
163
    if (res != 0)
11143
51
  return(res);
11144
112
    return(0);
11145
163
}
11146
11147
/**
11148
 * xmlSchemaParseModelGroup:
11149
 * @ctxt:  a schema validation context
11150
 * @schema:  the schema being built
11151
 * @node:  a subtree containing XML Schema information
11152
 * @type: the "compositor" type
11153
 * @particleNeeded: if a a model group with a particle
11154
 *
11155
 * parse a XML schema Sequence definition.
11156
 * Applies parts of:
11157
 *   Schema Representation Constraint:
11158
 *     Redefinition Constraints and Semantics (src-redefine)
11159
 *     (6.1), (6.1.1), (6.1.2)
11160
 *
11161
 *   Schema Component Constraint:
11162
 *     All Group Limited (cos-all-limited) (2)
11163
 *     TODO: Actually this should go to component-level checks,
11164
 *     but is done here due to performance. Move it to an other layer
11165
 *     is schema construction via an API is implemented.
11166
 *
11167
 * *WARNING* this interface is highly subject to change
11168
 *
11169
 * Returns -1 in case of error, 0 if the declaration is improper and
11170
 *         1 in case of success.
11171
 */
11172
static xmlSchemaTreeItemPtr
11173
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11174
       xmlNodePtr node, xmlSchemaTypeType type,
11175
       int withParticle)
11176
5.53k
{
11177
5.53k
    xmlSchemaModelGroupPtr item;
11178
5.53k
    xmlSchemaParticlePtr particle = NULL;
11179
5.53k
    xmlNodePtr child = NULL;
11180
5.53k
    xmlAttrPtr attr;
11181
5.53k
    int min = 1, max = 1, isElemRef, hasRefs = 0;
11182
11183
5.53k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11184
0
        return (NULL);
11185
    /*
11186
    * Create a model group with the given compositor.
11187
    */
11188
5.53k
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11189
5.53k
    if (item == NULL)
11190
0
  return (NULL);
11191
11192
5.53k
    if (withParticle) {
11193
4.46k
  if (type == XML_SCHEMA_TYPE_ALL) {
11194
146
      min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11195
146
      max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11196
4.31k
  } else {
11197
      /* choice + sequence */
11198
4.31k
      min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11199
4.31k
      max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11200
4.31k
    "(xs:nonNegativeInteger | unbounded)");
11201
4.31k
  }
11202
4.46k
  xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11203
  /*
11204
  * Create a particle
11205
  */
11206
4.46k
  particle = xmlSchemaAddParticle(ctxt, node, min, max);
11207
4.46k
  if (particle == NULL)
11208
0
      return (NULL);
11209
4.46k
  particle->children = (xmlSchemaTreeItemPtr) item;
11210
  /*
11211
  * Check for illegal attributes.
11212
  */
11213
4.46k
  attr = node->properties;
11214
7.75k
  while (attr != NULL) {
11215
3.28k
      if (attr->ns == NULL) {
11216
2.49k
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11217
2.49k
        (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11218
2.49k
        (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11219
368
        xmlSchemaPIllegalAttrErr(ctxt,
11220
368
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11221
368
    }
11222
2.49k
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11223
19
    xmlSchemaPIllegalAttrErr(ctxt,
11224
19
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11225
19
      }
11226
3.28k
      attr = attr->next;
11227
3.28k
  }
11228
4.46k
    } else {
11229
  /*
11230
  * Check for illegal attributes.
11231
  */
11232
1.07k
  attr = node->properties;
11233
2.02k
  while (attr != NULL) {
11234
950
      if (attr->ns == NULL) {
11235
880
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11236
608
        xmlSchemaPIllegalAttrErr(ctxt,
11237
608
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11238
608
    }
11239
880
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11240
61
    xmlSchemaPIllegalAttrErr(ctxt,
11241
61
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11242
61
      }
11243
950
      attr = attr->next;
11244
950
  }
11245
1.07k
    }
11246
11247
    /*
11248
    * Extract and validate attributes.
11249
    */
11250
5.53k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11251
    /*
11252
    * And now for the children...
11253
    */
11254
5.53k
    child = node->children;
11255
5.53k
    if (IS_SCHEMA(child, "annotation")) {
11256
78
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11257
78
        child = child->next;
11258
78
    }
11259
5.53k
    if (type == XML_SCHEMA_TYPE_ALL) {
11260
146
  xmlSchemaParticlePtr part, last = NULL;
11261
11262
267
  while (IS_SCHEMA(child, "element")) {
11263
121
      part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11264
121
    schema, child, &isElemRef, 0);
11265
      /*
11266
      * SPEC cos-all-limited (2)
11267
      * "The {max occurs} of all the particles in the {particles}
11268
      * of the ('all') group must be 0 or 1.
11269
      */
11270
121
      if (part != NULL) {
11271
103
    if (isElemRef)
11272
82
        hasRefs++;
11273
103
    if (part->minOccurs > 1) {
11274
9
        xmlSchemaPCustomErr(ctxt,
11275
9
      XML_SCHEMAP_COS_ALL_LIMITED,
11276
9
      NULL, child,
11277
9
      "Invalid value for minOccurs (must be 0 or 1)",
11278
9
      NULL);
11279
        /* Reset to 1. */
11280
9
        part->minOccurs = 1;
11281
9
    }
11282
103
    if (part->maxOccurs > 1) {
11283
1
        xmlSchemaPCustomErr(ctxt,
11284
1
      XML_SCHEMAP_COS_ALL_LIMITED,
11285
1
      NULL, child,
11286
1
      "Invalid value for maxOccurs (must be 0 or 1)",
11287
1
      NULL);
11288
        /* Reset to 1. */
11289
1
        part->maxOccurs = 1;
11290
1
    }
11291
103
    if (last == NULL)
11292
51
        item->children = (xmlSchemaTreeItemPtr) part;
11293
52
    else
11294
52
        last->next = (xmlSchemaTreeItemPtr) part;
11295
103
    last = part;
11296
103
      }
11297
121
      child = child->next;
11298
121
  }
11299
146
  if (child != NULL) {
11300
24
      xmlSchemaPContentErr(ctxt,
11301
24
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11302
24
    NULL, node, child, NULL,
11303
24
    "(annotation?, (annotation?, element*)");
11304
24
  }
11305
5.39k
    } else {
11306
  /* choice + sequence */
11307
5.39k
  xmlSchemaTreeItemPtr part = NULL, last = NULL;
11308
11309
23.7k
  while ((IS_SCHEMA(child, "element")) ||
11310
23.7k
      (IS_SCHEMA(child, "group")) ||
11311
23.7k
      (IS_SCHEMA(child, "any")) ||
11312
23.7k
      (IS_SCHEMA(child, "choice")) ||
11313
23.7k
      (IS_SCHEMA(child, "sequence"))) {
11314
11315
18.3k
      if (IS_SCHEMA(child, "element")) {
11316
9.66k
    part = (xmlSchemaTreeItemPtr)
11317
9.66k
        xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11318
9.66k
    if (part && isElemRef)
11319
3.33k
        hasRefs++;
11320
9.66k
      } else if (IS_SCHEMA(child, "group")) {
11321
226
    part =
11322
226
        xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11323
226
    if (part != NULL)
11324
118
        hasRefs++;
11325
    /*
11326
    * Handle redefinitions.
11327
    */
11328
226
    if (ctxt->isRedefine && ctxt->redef &&
11329
226
        (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11330
226
        part && part->children)
11331
0
    {
11332
0
        if ((xmlSchemaGetQNameRefName(part->children) ==
11333
0
          ctxt->redef->refName) &&
11334
0
      (xmlSchemaGetQNameRefTargetNs(part->children) ==
11335
0
          ctxt->redef->refTargetNs))
11336
0
        {
11337
      /*
11338
      * SPEC src-redefine:
11339
      * (6.1) "If it has a <group> among its contents at
11340
      * some level the `actual value` of whose ref
11341
      * [attribute] is the same as the `actual value` of
11342
      * its own name attribute plus target namespace, then
11343
      * all of the following must be true:"
11344
      * (6.1.1) "It must have exactly one such group."
11345
      */
11346
0
      if (ctxt->redefCounter != 0) {
11347
0
          xmlChar *str = NULL;
11348
11349
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11350
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11351
0
        "The redefining model group definition "
11352
0
        "'%s' must not contain more than one "
11353
0
        "reference to the redefined definition",
11354
0
        xmlSchemaFormatQName(&str,
11355
0
            ctxt->redef->refTargetNs,
11356
0
            ctxt->redef->refName),
11357
0
        NULL);
11358
0
          FREE_AND_NULL(str)
11359
0
          part = NULL;
11360
0
      } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11361
0
          ((WXS_PARTICLE(part))->maxOccurs != 1))
11362
0
      {
11363
0
          xmlChar *str = NULL;
11364
          /*
11365
          * SPEC src-redefine:
11366
          * (6.1.2) "The `actual value` of both that
11367
          * group's minOccurs and maxOccurs [attribute]
11368
          * must be 1 (or `absent`).
11369
          */
11370
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11371
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11372
0
        "The redefining model group definition "
11373
0
        "'%s' must not contain a reference to the "
11374
0
        "redefined definition with a "
11375
0
        "maxOccurs/minOccurs other than 1",
11376
0
        xmlSchemaFormatQName(&str,
11377
0
            ctxt->redef->refTargetNs,
11378
0
            ctxt->redef->refName),
11379
0
        NULL);
11380
0
          FREE_AND_NULL(str)
11381
0
          part = NULL;
11382
0
      }
11383
0
      ctxt->redef->reference = WXS_BASIC_CAST part;
11384
0
      ctxt->redefCounter++;
11385
0
        }
11386
0
    }
11387
8.41k
      } else if (IS_SCHEMA(child, "any")) {
11388
6.27k
    part = (xmlSchemaTreeItemPtr)
11389
6.27k
        xmlSchemaParseAny(ctxt, schema, child);
11390
6.27k
      } else if (IS_SCHEMA(child, "choice")) {
11391
1.33k
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11392
1.33k
        XML_SCHEMA_TYPE_CHOICE, 1);
11393
1.33k
      } else if (IS_SCHEMA(child, "sequence")) {
11394
808
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11395
808
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11396
808
      }
11397
18.3k
      if (part != NULL) {
11398
17.3k
    if (last == NULL)
11399
3.62k
        item->children = part;
11400
13.7k
    else
11401
13.7k
        last->next = part;
11402
17.3k
    last = part;
11403
17.3k
      }
11404
18.3k
      child = child->next;
11405
18.3k
  }
11406
5.39k
  if (child != NULL) {
11407
1.24k
      xmlSchemaPContentErr(ctxt,
11408
1.24k
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11409
1.24k
    NULL, node, child, NULL,
11410
1.24k
    "(annotation?, (element | group | choice | sequence | any)*)");
11411
1.24k
  }
11412
5.39k
    }
11413
5.53k
    if ((max == 0) && (min == 0))
11414
90
  return (NULL);
11415
5.44k
    if (hasRefs) {
11416
  /*
11417
  * We need to resolve references.
11418
  */
11419
1.35k
  WXS_ADD_PENDING(ctxt, item);
11420
1.35k
    }
11421
5.44k
    if (withParticle)
11422
4.37k
  return ((xmlSchemaTreeItemPtr) particle);
11423
1.07k
    else
11424
1.07k
  return ((xmlSchemaTreeItemPtr) item);
11425
5.44k
}
11426
11427
/**
11428
 * xmlSchemaParseRestriction:
11429
 * @ctxt:  a schema validation context
11430
 * @schema:  the schema being built
11431
 * @node:  a subtree containing XML Schema information
11432
 *
11433
 * parse a XML schema Restriction definition
11434
 * *WARNING* this interface is highly subject to change
11435
 *
11436
 * Returns the type definition or NULL in case of error
11437
 */
11438
static xmlSchemaTypePtr
11439
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11440
                          xmlNodePtr node, xmlSchemaTypeType parentType)
11441
10.6k
{
11442
10.6k
    xmlSchemaTypePtr type;
11443
10.6k
    xmlNodePtr child = NULL;
11444
10.6k
    xmlAttrPtr attr;
11445
11446
10.6k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11447
0
        return (NULL);
11448
    /* Not a component, don't create it. */
11449
10.6k
    type = ctxt->ctxtType;
11450
10.6k
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11451
11452
    /*
11453
    * Check for illegal attributes.
11454
    */
11455
10.6k
    attr = node->properties;
11456
21.7k
    while (attr != NULL) {
11457
11.0k
  if (attr->ns == NULL) {
11458
10.6k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11459
10.6k
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11460
1.05k
    xmlSchemaPIllegalAttrErr(ctxt,
11461
1.05k
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11462
1.05k
      }
11463
10.6k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11464
24
      xmlSchemaPIllegalAttrErr(ctxt,
11465
24
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11466
24
  }
11467
11.0k
  attr = attr->next;
11468
11.0k
    }
11469
    /*
11470
    * Extract and validate attributes.
11471
    */
11472
10.6k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11473
    /*
11474
    * Attribute
11475
    */
11476
    /*
11477
    * Extract the base type. The "base" attribute is mandatory if inside
11478
    * a complex type or if redefining.
11479
    *
11480
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11481
    * among its [children]), the simple type definition which is
11482
    * the {content type} of the type definition `resolved` to by
11483
    * the `actual value` of the base [attribute]"
11484
    */
11485
10.6k
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11486
10.6k
  &(type->baseNs), &(type->base)) == 0)
11487
10.4k
    {
11488
10.4k
  if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11489
94
      xmlSchemaPMissingAttrErr(ctxt,
11490
94
    XML_SCHEMAP_S4S_ATTR_MISSING,
11491
94
    NULL, node, "base", NULL);
11492
10.3k
  } else if ((ctxt->isRedefine) &&
11493
10.3k
      (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11494
0
  {
11495
0
      if (type->base == NULL) {
11496
0
    xmlSchemaPMissingAttrErr(ctxt,
11497
0
        XML_SCHEMAP_S4S_ATTR_MISSING,
11498
0
        NULL, node, "base", NULL);
11499
0
      } else if ((! xmlStrEqual(type->base, type->name)) ||
11500
0
    (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11501
0
      {
11502
0
    xmlChar *str1 = NULL, *str2 = NULL;
11503
    /*
11504
    * REDEFINE: SPEC src-redefine (5)
11505
    * "Within the [children], each <simpleType> must have a
11506
    * <restriction> among its [children] ... the `actual value` of
11507
    * whose base [attribute] must be the same as the `actual value`
11508
    * of its own name attribute plus target namespace;"
11509
    */
11510
0
    xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11511
0
        NULL, node, "This is a redefinition, but the QName "
11512
0
        "value '%s' of the 'base' attribute does not match the "
11513
0
        "type's designation '%s'",
11514
0
        xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11515
0
        xmlSchemaFormatQName(&str2, type->targetNamespace,
11516
0
      type->name), NULL);
11517
0
    FREE_AND_NULL(str1);
11518
0
    FREE_AND_NULL(str2);
11519
    /* Avoid confusion and erase the values. */
11520
0
    type->base = NULL;
11521
0
    type->baseNs = NULL;
11522
0
      }
11523
0
  }
11524
10.4k
    }
11525
    /*
11526
    * And now for the children...
11527
    */
11528
10.6k
    child = node->children;
11529
10.6k
    if (IS_SCHEMA(child, "annotation")) {
11530
  /*
11531
  * Add the annotation to the simple type ancestor.
11532
  */
11533
170
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11534
170
      xmlSchemaParseAnnotation(ctxt, child, 1));
11535
170
        child = child->next;
11536
170
    }
11537
10.6k
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11538
  /*
11539
  * Corresponds to <simpleType><restriction><simpleType>.
11540
  */
11541
9.91k
  if (IS_SCHEMA(child, "simpleType")) {
11542
729
      if (type->base != NULL) {
11543
    /*
11544
    * src-restriction-base-or-simpleType
11545
    * Either the base [attribute] or the simpleType [child] of the
11546
    * <restriction> element must be present, but not both.
11547
    */
11548
35
    xmlSchemaPContentErr(ctxt,
11549
35
        XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11550
35
        NULL, node, child,
11551
35
        "The attribute 'base' and the <simpleType> child are "
11552
35
        "mutually exclusive", NULL);
11553
694
      } else {
11554
694
    type->baseType = (xmlSchemaTypePtr)
11555
694
        xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11556
694
      }
11557
729
      child = child->next;
11558
9.18k
  } else if (type->base == NULL) {
11559
429
      xmlSchemaPContentErr(ctxt,
11560
429
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11561
429
    NULL, node, child,
11562
429
    "Either the attribute 'base' or a <simpleType> child "
11563
429
    "must be present", NULL);
11564
429
  }
11565
9.91k
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11566
  /*
11567
  * Corresponds to <complexType><complexContent><restriction>...
11568
  * followed by:
11569
  *
11570
  * Model groups <all>, <choice> and <sequence>.
11571
  */
11572
340
  if (IS_SCHEMA(child, "all")) {
11573
0
      type->subtypes = (xmlSchemaTypePtr)
11574
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11575
0
        XML_SCHEMA_TYPE_ALL, 1);
11576
0
      child = child->next;
11577
340
  } else if (IS_SCHEMA(child, "choice")) {
11578
1
      type->subtypes = (xmlSchemaTypePtr)
11579
1
    xmlSchemaParseModelGroup(ctxt,
11580
1
        schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11581
1
      child = child->next;
11582
339
  } else if (IS_SCHEMA(child, "sequence")) {
11583
125
      type->subtypes = (xmlSchemaTypePtr)
11584
125
    xmlSchemaParseModelGroup(ctxt, schema, child,
11585
125
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11586
125
      child = child->next;
11587
  /*
11588
  * Model group reference <group>.
11589
  */
11590
214
  } else if (IS_SCHEMA(child, "group")) {
11591
1
      type->subtypes = (xmlSchemaTypePtr)
11592
1
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11593
      /*
11594
      * Note that the reference will be resolved in
11595
      * xmlSchemaResolveTypeReferences();
11596
      */
11597
1
      child = child->next;
11598
1
  }
11599
411
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11600
  /*
11601
  * Corresponds to <complexType><simpleContent><restriction>...
11602
  *
11603
  * "1.1 the simple type definition corresponding to the <simpleType>
11604
  * among the [children] of <restriction> if there is one;"
11605
  */
11606
411
  if (IS_SCHEMA(child, "simpleType")) {
11607
      /*
11608
      * We will store the to-be-restricted simple type in
11609
      * type->contentTypeDef *temporarily*.
11610
      */
11611
248
      type->contentTypeDef = (xmlSchemaTypePtr)
11612
248
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11613
248
      if ( type->contentTypeDef == NULL)
11614
0
    return (NULL);
11615
248
      child = child->next;
11616
248
  }
11617
411
    }
11618
11619
10.6k
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11620
10.6k
  (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11621
10.3k
  xmlSchemaFacetPtr facet, lastfacet = NULL;
11622
  /*
11623
  * Corresponds to <complexType><simpleContent><restriction>...
11624
  * <simpleType><restriction>...
11625
  */
11626
11627
  /*
11628
  * Add the facets to the simple type ancestor.
11629
  */
11630
  /*
11631
  * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11632
  * Simple Type Definition Schema Representation Constraint:
11633
  * *Single Facet Value*
11634
  */
11635
139k
  while ((IS_SCHEMA(child, "minInclusive")) ||
11636
139k
      (IS_SCHEMA(child, "minExclusive")) ||
11637
139k
      (IS_SCHEMA(child, "maxInclusive")) ||
11638
139k
      (IS_SCHEMA(child, "maxExclusive")) ||
11639
139k
      (IS_SCHEMA(child, "totalDigits")) ||
11640
139k
      (IS_SCHEMA(child, "fractionDigits")) ||
11641
139k
      (IS_SCHEMA(child, "pattern")) ||
11642
139k
      (IS_SCHEMA(child, "enumeration")) ||
11643
139k
      (IS_SCHEMA(child, "whiteSpace")) ||
11644
139k
      (IS_SCHEMA(child, "length")) ||
11645
139k
      (IS_SCHEMA(child, "maxLength")) ||
11646
139k
      (IS_SCHEMA(child, "minLength"))) {
11647
128k
      facet = xmlSchemaParseFacet(ctxt, schema, child);
11648
128k
      if (facet != NULL) {
11649
128k
    if (lastfacet == NULL)
11650
9.11k
        type->facets = facet;
11651
119k
    else
11652
119k
        lastfacet->next = facet;
11653
128k
    lastfacet = facet;
11654
128k
    lastfacet->next = NULL;
11655
128k
      }
11656
128k
      child = child->next;
11657
128k
  }
11658
  /*
11659
  * Create links for derivation and validation.
11660
  */
11661
10.3k
  if (type->facets != NULL) {
11662
9.11k
      xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11663
11664
9.11k
      facet = type->facets;
11665
128k
      do {
11666
128k
    facetLink = (xmlSchemaFacetLinkPtr)
11667
128k
        xmlMalloc(sizeof(xmlSchemaFacetLink));
11668
128k
    if (facetLink == NULL) {
11669
0
        xmlSchemaPErrMemory(ctxt);
11670
0
        xmlFree(facetLink);
11671
0
        return (NULL);
11672
0
    }
11673
128k
    facetLink->facet = facet;
11674
128k
    facetLink->next = NULL;
11675
128k
    if (lastFacetLink == NULL)
11676
9.11k
        type->facetSet = facetLink;
11677
119k
    else
11678
119k
        lastFacetLink->next = facetLink;
11679
128k
    lastFacetLink = facetLink;
11680
128k
    facet = facet->next;
11681
128k
      } while (facet != NULL);
11682
9.11k
  }
11683
10.3k
    }
11684
10.6k
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11685
  /*
11686
  * Attribute uses/declarations.
11687
  */
11688
751
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11689
751
      (xmlSchemaItemListPtr *) &(type->attrUses),
11690
751
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11691
0
      return(NULL);
11692
  /*
11693
  * Attribute wildcard.
11694
  */
11695
751
  if (IS_SCHEMA(child, "anyAttribute")) {
11696
37
      type->attributeWildcard =
11697
37
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11698
37
      child = child->next;
11699
37
  }
11700
751
    }
11701
10.6k
    if (child != NULL) {
11702
708
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11703
98
      xmlSchemaPContentErr(ctxt,
11704
98
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11705
98
    NULL, node, child, NULL,
11706
98
    "annotation?, (group | all | choice | sequence)?, "
11707
98
    "((attribute | attributeGroup)*, anyAttribute?))");
11708
610
  } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11709
209
       xmlSchemaPContentErr(ctxt,
11710
209
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11711
209
    NULL, node, child, NULL,
11712
209
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11713
209
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11714
209
    "length | minLength | maxLength | enumeration | whiteSpace | "
11715
209
    "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11716
401
  } else {
11717
      /* Simple type */
11718
401
      xmlSchemaPContentErr(ctxt,
11719
401
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11720
401
    NULL, node, child, NULL,
11721
401
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11722
401
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11723
401
    "length | minLength | maxLength | enumeration | whiteSpace | "
11724
401
    "pattern)*))");
11725
401
  }
11726
708
    }
11727
10.6k
    return (NULL);
11728
10.6k
}
11729
11730
/**
11731
 * xmlSchemaParseExtension:
11732
 * @ctxt:  a schema validation context
11733
 * @schema:  the schema being built
11734
 * @node:  a subtree containing XML Schema information
11735
 *
11736
 * Parses an <extension>, which is found inside a
11737
 * <simpleContent> or <complexContent>.
11738
 * *WARNING* this interface is highly subject to change.
11739
 *
11740
 * TODO: Returns the type definition or NULL in case of error
11741
 */
11742
static xmlSchemaTypePtr
11743
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11744
                        xmlNodePtr node, xmlSchemaTypeType parentType)
11745
1.53k
{
11746
1.53k
    xmlSchemaTypePtr type;
11747
1.53k
    xmlNodePtr child = NULL;
11748
1.53k
    xmlAttrPtr attr;
11749
11750
1.53k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11751
0
        return (NULL);
11752
    /* Not a component, don't create it. */
11753
1.53k
    type = ctxt->ctxtType;
11754
1.53k
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11755
11756
    /*
11757
    * Check for illegal attributes.
11758
    */
11759
1.53k
    attr = node->properties;
11760
3.72k
    while (attr != NULL) {
11761
2.19k
  if (attr->ns == NULL) {
11762
1.53k
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11763
1.53k
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11764
291
    xmlSchemaPIllegalAttrErr(ctxt,
11765
291
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11766
291
      }
11767
1.53k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11768
37
      xmlSchemaPIllegalAttrErr(ctxt,
11769
37
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11770
37
  }
11771
2.19k
  attr = attr->next;
11772
2.19k
    }
11773
11774
1.53k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11775
11776
    /*
11777
    * Attribute "base" - mandatory.
11778
    */
11779
1.53k
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11780
1.53k
  "base", &(type->baseNs), &(type->base)) == 0) &&
11781
1.53k
  (type->base == NULL)) {
11782
327
  xmlSchemaPMissingAttrErr(ctxt,
11783
327
      XML_SCHEMAP_S4S_ATTR_MISSING,
11784
327
      NULL, node, "base", NULL);
11785
327
    }
11786
    /*
11787
    * And now for the children...
11788
    */
11789
1.53k
    child = node->children;
11790
1.53k
    if (IS_SCHEMA(child, "annotation")) {
11791
  /*
11792
  * Add the annotation to the type ancestor.
11793
  */
11794
12
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11795
12
      xmlSchemaParseAnnotation(ctxt, child, 1));
11796
12
        child = child->next;
11797
12
    }
11798
1.53k
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11799
  /*
11800
  * Corresponds to <complexType><complexContent><extension>... and:
11801
  *
11802
  * Model groups <all>, <choice>, <sequence> and <group>.
11803
  */
11804
762
  if (IS_SCHEMA(child, "all")) {
11805
0
      type->subtypes = (xmlSchemaTypePtr)
11806
0
    xmlSchemaParseModelGroup(ctxt, schema,
11807
0
        child, XML_SCHEMA_TYPE_ALL, 1);
11808
0
      child = child->next;
11809
762
  } else if (IS_SCHEMA(child, "choice")) {
11810
0
      type->subtypes = (xmlSchemaTypePtr)
11811
0
    xmlSchemaParseModelGroup(ctxt, schema,
11812
0
        child, XML_SCHEMA_TYPE_CHOICE, 1);
11813
0
      child = child->next;
11814
762
  } else if (IS_SCHEMA(child, "sequence")) {
11815
53
      type->subtypes = (xmlSchemaTypePtr)
11816
53
    xmlSchemaParseModelGroup(ctxt, schema,
11817
53
    child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11818
53
      child = child->next;
11819
709
  } else if (IS_SCHEMA(child, "group")) {
11820
0
      type->subtypes = (xmlSchemaTypePtr)
11821
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11822
      /*
11823
      * Note that the reference will be resolved in
11824
      * xmlSchemaResolveTypeReferences();
11825
      */
11826
0
      child = child->next;
11827
0
  }
11828
762
    }
11829
1.53k
    if (child != NULL) {
11830
  /*
11831
  * Attribute uses/declarations.
11832
  */
11833
954
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11834
954
      (xmlSchemaItemListPtr *) &(type->attrUses),
11835
954
      XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11836
0
      return(NULL);
11837
  /*
11838
  * Attribute wildcard.
11839
  */
11840
954
  if (IS_SCHEMA(child, "anyAttribute")) {
11841
436
      ctxt->ctxtType->attributeWildcard =
11842
436
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11843
436
      child = child->next;
11844
436
  }
11845
954
    }
11846
1.53k
    if (child != NULL) {
11847
330
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11848
      /* Complex content extension. */
11849
63
      xmlSchemaPContentErr(ctxt,
11850
63
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11851
63
    NULL, node, child, NULL,
11852
63
    "(annotation?, ((group | all | choice | sequence)?, "
11853
63
    "((attribute | attributeGroup)*, anyAttribute?)))");
11854
267
  } else {
11855
      /* Simple content extension. */
11856
267
      xmlSchemaPContentErr(ctxt,
11857
267
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11858
267
    NULL, node, child, NULL,
11859
267
    "(annotation?, ((attribute | attributeGroup)*, "
11860
267
    "anyAttribute?))");
11861
267
  }
11862
330
    }
11863
1.53k
    return (NULL);
11864
1.53k
}
11865
11866
/**
11867
 * xmlSchemaParseSimpleContent:
11868
 * @ctxt:  a schema validation context
11869
 * @schema:  the schema being built
11870
 * @node:  a subtree containing XML Schema information
11871
 *
11872
 * parse a XML schema SimpleContent definition
11873
 * *WARNING* this interface is highly subject to change
11874
 *
11875
 * Returns the type definition or NULL in case of error
11876
 */
11877
static int
11878
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11879
                            xmlSchemaPtr schema, xmlNodePtr node,
11880
          int *hasRestrictionOrExtension)
11881
1.64k
{
11882
1.64k
    xmlSchemaTypePtr type;
11883
1.64k
    xmlNodePtr child = NULL;
11884
1.64k
    xmlAttrPtr attr;
11885
11886
1.64k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11887
1.64k
  (hasRestrictionOrExtension == NULL))
11888
0
        return (-1);
11889
1.64k
    *hasRestrictionOrExtension = 0;
11890
    /* Not a component, don't create it. */
11891
1.64k
    type = ctxt->ctxtType;
11892
1.64k
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11893
    /*
11894
    * Check for illegal attributes.
11895
    */
11896
1.64k
    attr = node->properties;
11897
3.56k
    while (attr != NULL) {
11898
1.92k
  if (attr->ns == NULL) {
11899
957
      if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11900
945
    xmlSchemaPIllegalAttrErr(ctxt,
11901
945
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11902
945
      }
11903
968
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11904
113
      xmlSchemaPIllegalAttrErr(ctxt,
11905
113
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11906
113
  }
11907
1.92k
  attr = attr->next;
11908
1.92k
    }
11909
11910
1.64k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11911
11912
    /*
11913
    * And now for the children...
11914
    */
11915
1.64k
    child = node->children;
11916
1.64k
    if (IS_SCHEMA(child, "annotation")) {
11917
  /*
11918
  * Add the annotation to the complex type ancestor.
11919
  */
11920
10
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11921
10
      xmlSchemaParseAnnotation(ctxt, child, 1));
11922
10
        child = child->next;
11923
10
    }
11924
1.64k
    if (child == NULL) {
11925
303
  xmlSchemaPContentErr(ctxt,
11926
303
      XML_SCHEMAP_S4S_ELEM_MISSING,
11927
303
      NULL, node, NULL, NULL,
11928
303
      "(annotation?, (restriction | extension))");
11929
303
    }
11930
1.64k
    if (child == NULL) {
11931
303
  xmlSchemaPContentErr(ctxt,
11932
303
      XML_SCHEMAP_S4S_ELEM_MISSING,
11933
303
      NULL, node, NULL, NULL,
11934
303
      "(annotation?, (restriction | extension))");
11935
303
    }
11936
1.64k
    if (IS_SCHEMA(child, "restriction")) {
11937
411
        xmlSchemaParseRestriction(ctxt, schema, child,
11938
411
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11939
411
  (*hasRestrictionOrExtension) = 1;
11940
411
        child = child->next;
11941
1.23k
    } else if (IS_SCHEMA(child, "extension")) {
11942
771
        xmlSchemaParseExtension(ctxt, schema, child,
11943
771
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11944
771
  (*hasRestrictionOrExtension) = 1;
11945
771
        child = child->next;
11946
771
    }
11947
1.64k
    if (child != NULL) {
11948
580
  xmlSchemaPContentErr(ctxt,
11949
580
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11950
580
      NULL, node, child, NULL,
11951
580
      "(annotation?, (restriction | extension))");
11952
580
    }
11953
1.64k
    return (0);
11954
1.64k
}
11955
11956
/**
11957
 * xmlSchemaParseComplexContent:
11958
 * @ctxt:  a schema validation context
11959
 * @schema:  the schema being built
11960
 * @node:  a subtree containing XML Schema information
11961
 *
11962
 * parse a XML schema ComplexContent definition
11963
 * *WARNING* this interface is highly subject to change
11964
 *
11965
 * Returns the type definition or NULL in case of error
11966
 */
11967
static int
11968
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11969
                             xmlSchemaPtr schema, xmlNodePtr node,
11970
           int *hasRestrictionOrExtension)
11971
1.57k
{
11972
1.57k
    xmlSchemaTypePtr type;
11973
1.57k
    xmlNodePtr child = NULL;
11974
1.57k
    xmlAttrPtr attr;
11975
11976
1.57k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11977
1.57k
  (hasRestrictionOrExtension == NULL))
11978
0
        return (-1);
11979
1.57k
    *hasRestrictionOrExtension = 0;
11980
    /* Not a component, don't create it. */
11981
1.57k
    type = ctxt->ctxtType;
11982
    /*
11983
    * Check for illegal attributes.
11984
    */
11985
1.57k
    attr = node->properties;
11986
3.10k
    while (attr != NULL) {
11987
1.53k
  if (attr->ns == NULL) {
11988
771
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11989
771
    (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
11990
455
      {
11991
455
    xmlSchemaPIllegalAttrErr(ctxt,
11992
455
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11993
455
      }
11994
771
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11995
0
      xmlSchemaPIllegalAttrErr(ctxt,
11996
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11997
0
  }
11998
1.53k
  attr = attr->next;
11999
1.53k
    }
12000
12001
1.57k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12002
12003
    /*
12004
    * Set the 'mixed' on the complex type ancestor.
12005
    */
12006
1.57k
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12007
32
  if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12008
32
      type->flags |= XML_SCHEMAS_TYPE_MIXED;
12009
32
    }
12010
1.57k
    child = node->children;
12011
1.57k
    if (IS_SCHEMA(child, "annotation")) {
12012
  /*
12013
  * Add the annotation to the complex type ancestor.
12014
  */
12015
82
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12016
82
      xmlSchemaParseAnnotation(ctxt, child, 1));
12017
82
        child = child->next;
12018
82
    }
12019
1.57k
    if (child == NULL) {
12020
214
  xmlSchemaPContentErr(ctxt,
12021
214
      XML_SCHEMAP_S4S_ELEM_MISSING,
12022
214
      NULL, node, NULL,
12023
214
      NULL, "(annotation?, (restriction | extension))");
12024
214
    }
12025
1.57k
    if (child == NULL) {
12026
214
  xmlSchemaPContentErr(ctxt,
12027
214
      XML_SCHEMAP_S4S_ELEM_MISSING,
12028
214
      NULL, node, NULL,
12029
214
      NULL, "(annotation?, (restriction | extension))");
12030
214
    }
12031
1.57k
    if (IS_SCHEMA(child, "restriction")) {
12032
340
        xmlSchemaParseRestriction(ctxt, schema, child,
12033
340
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12034
340
  (*hasRestrictionOrExtension) = 1;
12035
340
        child = child->next;
12036
1.23k
    } else if (IS_SCHEMA(child, "extension")) {
12037
762
        xmlSchemaParseExtension(ctxt, schema, child,
12038
762
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12039
762
  (*hasRestrictionOrExtension) = 1;
12040
762
        child = child->next;
12041
762
    }
12042
1.57k
    if (child != NULL) {
12043
369
  xmlSchemaPContentErr(ctxt,
12044
369
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12045
369
      NULL, node, child,
12046
369
      NULL, "(annotation?, (restriction | extension))");
12047
369
    }
12048
1.57k
    return (0);
12049
1.57k
}
12050
12051
/**
12052
 * xmlSchemaParseComplexType:
12053
 * @ctxt:  a schema validation context
12054
 * @schema:  the schema being built
12055
 * @node:  a subtree containing XML Schema information
12056
 *
12057
 * parse a XML schema Complex Type definition
12058
 * *WARNING* this interface is highly subject to change
12059
 *
12060
 * Returns the type definition or NULL in case of error
12061
 */
12062
static xmlSchemaTypePtr
12063
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12064
                          xmlNodePtr node, int topLevel)
12065
14.5k
{
12066
14.5k
    xmlSchemaTypePtr type, ctxtType;
12067
14.5k
    xmlNodePtr child = NULL;
12068
14.5k
    const xmlChar *name = NULL;
12069
14.5k
    xmlAttrPtr attr;
12070
14.5k
    const xmlChar *attrValue;
12071
#ifdef ENABLE_NAMED_LOCALS
12072
    char buf[40];
12073
#endif
12074
14.5k
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
12075
12076
12077
14.5k
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12078
0
        return (NULL);
12079
12080
14.5k
    ctxtType = ctxt->ctxtType;
12081
12082
14.5k
    if (topLevel) {
12083
9.95k
  attr = xmlSchemaGetPropNode(node, "name");
12084
9.95k
  if (attr == NULL) {
12085
1.09k
      xmlSchemaPMissingAttrErr(ctxt,
12086
1.09k
    XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12087
1.09k
      return (NULL);
12088
8.86k
  } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12089
8.86k
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12090
710
      return (NULL);
12091
710
  }
12092
9.95k
    }
12093
12094
12.7k
    if (topLevel == 0) {
12095
  /*
12096
  * Parse as local complex type definition.
12097
  */
12098
#ifdef ENABLE_NAMED_LOCALS
12099
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12100
  type = xmlSchemaAddType(ctxt, schema,
12101
      XML_SCHEMA_TYPE_COMPLEX,
12102
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12103
      ctxt->targetNamespace, node, 0);
12104
#else
12105
4.57k
  type = xmlSchemaAddType(ctxt, schema,
12106
4.57k
      XML_SCHEMA_TYPE_COMPLEX,
12107
4.57k
      NULL, ctxt->targetNamespace, node, 0);
12108
4.57k
#endif
12109
4.57k
  if (type == NULL)
12110
0
      return (NULL);
12111
4.57k
  name = type->name;
12112
4.57k
  type->node = node;
12113
4.57k
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12114
  /*
12115
  * TODO: We need the target namespace.
12116
  */
12117
8.15k
    } else {
12118
  /*
12119
  * Parse as global complex type definition.
12120
  */
12121
8.15k
  type = xmlSchemaAddType(ctxt, schema,
12122
8.15k
      XML_SCHEMA_TYPE_COMPLEX,
12123
8.15k
      name, ctxt->targetNamespace, node, 1);
12124
8.15k
  if (type == NULL)
12125
0
      return (NULL);
12126
8.15k
  type->node = node;
12127
8.15k
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12128
8.15k
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12129
8.15k
    }
12130
12.7k
    type->targetNamespace = ctxt->targetNamespace;
12131
    /*
12132
    * Handle attributes.
12133
    */
12134
12.7k
    attr = node->properties;
12135
27.1k
    while (attr != NULL) {
12136
14.4k
  if (attr->ns == NULL) {
12137
13.8k
      if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12138
    /*
12139
    * Attribute "id".
12140
    */
12141
1.30k
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12142
12.5k
      } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12143
    /*
12144
    * Attribute "mixed".
12145
    */
12146
616
    if (xmlSchemaPGetBoolNodeValue(ctxt,
12147
616
      NULL, (xmlNodePtr) attr))
12148
54
        type->flags |= XML_SCHEMAS_TYPE_MIXED;
12149
11.9k
      } else if (topLevel) {
12150
    /*
12151
    * Attributes of global complex type definitions.
12152
    */
12153
11.8k
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12154
        /* Pass. */
12155
8.15k
    } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12156
        /*
12157
        * Attribute "abstract".
12158
        */
12159
427
        if (xmlSchemaPGetBoolNodeValue(ctxt,
12160
427
          NULL, (xmlNodePtr) attr))
12161
183
      type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12162
3.22k
    } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12163
        /*
12164
        * Attribute "final".
12165
        */
12166
270
        attrValue = xmlSchemaGetNodeContent(ctxt,
12167
270
      (xmlNodePtr) attr);
12168
270
        if (xmlSchemaPValAttrBlockFinal(attrValue,
12169
270
      &(type->flags),
12170
270
      -1,
12171
270
      XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12172
270
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12173
270
      -1, -1, -1) != 0)
12174
101
        {
12175
101
      xmlSchemaPSimpleTypeErr(ctxt,
12176
101
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12177
101
          NULL, (xmlNodePtr) attr, NULL,
12178
101
          "(#all | List of (extension | restriction))",
12179
101
          attrValue, NULL, NULL, NULL);
12180
101
        } else
12181
169
      final = 1;
12182
2.95k
    } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12183
        /*
12184
        * Attribute "block".
12185
        */
12186
1.56k
        attrValue = xmlSchemaGetNodeContent(ctxt,
12187
1.56k
      (xmlNodePtr) attr);
12188
1.56k
        if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12189
1.56k
      -1,
12190
1.56k
      XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12191
1.56k
      XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12192
1.56k
      -1, -1, -1) != 0) {
12193
1.28k
      xmlSchemaPSimpleTypeErr(ctxt,
12194
1.28k
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12195
1.28k
          NULL, (xmlNodePtr) attr, NULL,
12196
1.28k
          "(#all | List of (extension | restriction)) ",
12197
1.28k
          attrValue, NULL, NULL, NULL);
12198
1.28k
        } else
12199
275
      block = 1;
12200
1.56k
    } else {
12201
1.39k
      xmlSchemaPIllegalAttrErr(ctxt,
12202
1.39k
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12203
1.39k
    }
12204
11.8k
      } else {
12205
151
    xmlSchemaPIllegalAttrErr(ctxt,
12206
151
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12207
151
      }
12208
13.8k
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12209
280
      xmlSchemaPIllegalAttrErr(ctxt,
12210
280
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12211
280
  }
12212
14.4k
  attr = attr->next;
12213
14.4k
    }
12214
12.7k
    if (! block) {
12215
  /*
12216
  * Apply default "block" values.
12217
  */
12218
12.4k
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12219
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12220
12.4k
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12221
3
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12222
12.4k
    }
12223
12.7k
    if (! final) {
12224
  /*
12225
  * Apply default "block" values.
12226
  */
12227
12.5k
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12228
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12229
12.5k
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12230
4
      type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12231
12.5k
    }
12232
    /*
12233
    * And now for the children...
12234
    */
12235
12.7k
    child = node->children;
12236
12.7k
    if (IS_SCHEMA(child, "annotation")) {
12237
110
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12238
110
        child = child->next;
12239
110
    }
12240
12.7k
    ctxt->ctxtType = type;
12241
12.7k
    if (IS_SCHEMA(child, "simpleContent")) {
12242
  /*
12243
  * <complexType><simpleContent>...
12244
  * 3.4.3 : 2.2
12245
  * Specifying mixed='true' when the <simpleContent>
12246
  * alternative is chosen has no effect
12247
  */
12248
1.64k
  if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12249
12
      type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12250
1.64k
        xmlSchemaParseSimpleContent(ctxt, schema, child,
12251
1.64k
      &hasRestrictionOrExtension);
12252
1.64k
        child = child->next;
12253
11.0k
    } else if (IS_SCHEMA(child, "complexContent")) {
12254
  /*
12255
  * <complexType><complexContent>...
12256
  */
12257
1.57k
  type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12258
1.57k
        xmlSchemaParseComplexContent(ctxt, schema, child,
12259
1.57k
      &hasRestrictionOrExtension);
12260
1.57k
        child = child->next;
12261
9.50k
    } else {
12262
  /*
12263
  * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12264
  *
12265
  * SPEC
12266
  * "...the third alternative (neither <simpleContent> nor
12267
  * <complexContent>) is chosen. This case is understood as shorthand
12268
  * for complex content restricting the `ur-type definition`, and the
12269
  * details of the mappings should be modified as necessary.
12270
  */
12271
9.50k
  type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12272
9.50k
  type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12273
  /*
12274
  * Parse model groups.
12275
  */
12276
9.50k
        if (IS_SCHEMA(child, "all")) {
12277
146
            type->subtypes = (xmlSchemaTypePtr)
12278
146
    xmlSchemaParseModelGroup(ctxt, schema, child,
12279
146
        XML_SCHEMA_TYPE_ALL, 1);
12280
146
            child = child->next;
12281
9.36k
        } else if (IS_SCHEMA(child, "choice")) {
12282
559
            type->subtypes = (xmlSchemaTypePtr)
12283
559
    xmlSchemaParseModelGroup(ctxt, schema, child,
12284
559
        XML_SCHEMA_TYPE_CHOICE, 1);
12285
559
            child = child->next;
12286
8.80k
        } else if (IS_SCHEMA(child, "sequence")) {
12287
1.43k
            type->subtypes = (xmlSchemaTypePtr)
12288
1.43k
    xmlSchemaParseModelGroup(ctxt, schema, child,
12289
1.43k
        XML_SCHEMA_TYPE_SEQUENCE, 1);
12290
1.43k
            child = child->next;
12291
7.37k
        } else if (IS_SCHEMA(child, "group")) {
12292
1.48k
            type->subtypes = (xmlSchemaTypePtr)
12293
1.48k
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12294
      /*
12295
      * Note that the reference will be resolved in
12296
      * xmlSchemaResolveTypeReferences();
12297
      */
12298
1.48k
            child = child->next;
12299
1.48k
        }
12300
  /*
12301
  * Parse attribute decls/refs.
12302
  */
12303
9.50k
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12304
9.50k
      (xmlSchemaItemListPtr *) &(type->attrUses),
12305
9.50k
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12306
0
      return(NULL);
12307
  /*
12308
  * Parse attribute wildcard.
12309
  */
12310
9.50k
  if (IS_SCHEMA(child, "anyAttribute")) {
12311
1.34k
      type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12312
1.34k
      child = child->next;
12313
1.34k
  }
12314
9.50k
    }
12315
12.7k
    if (child != NULL) {
12316
3.93k
  xmlSchemaPContentErr(ctxt,
12317
3.93k
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12318
3.93k
      NULL, node, child,
12319
3.93k
      NULL, "(annotation?, (simpleContent | complexContent | "
12320
3.93k
      "((group | all | choice | sequence)?, ((attribute | "
12321
3.93k
      "attributeGroup)*, anyAttribute?))))");
12322
3.93k
    }
12323
    /*
12324
    * REDEFINE: SPEC src-redefine (5)
12325
    */
12326
12.7k
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12327
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12328
0
      NULL, node, "This is a redefinition, thus the "
12329
0
      "<complexType> must have a <restriction> or <extension> "
12330
0
      "grand-child", NULL);
12331
0
    }
12332
12.7k
    ctxt->ctxtType = ctxtType;
12333
12.7k
    return (type);
12334
12.7k
}
12335
12336
/************************************************************************
12337
 *                  *
12338
 *      Validating using Schemas      *
12339
 *                  *
12340
 ************************************************************************/
12341
12342
/************************************************************************
12343
 *                  *
12344
 *      Reading/Writing Schemas       *
12345
 *                  *
12346
 ************************************************************************/
12347
12348
#if 0 /* Will be enabled if it is clear what options are needed. */
12349
/**
12350
 * xmlSchemaParserCtxtSetOptions:
12351
 * @ctxt: a schema parser context
12352
 * @options: a combination of xmlSchemaParserOption
12353
 *
12354
 * Sets the options to be used during the parse.
12355
 *
12356
 * Returns 0 in case of success, -1 in case of an
12357
 * API error.
12358
 */
12359
static int
12360
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12361
            int options)
12362
12363
{
12364
    int i;
12365
12366
    if (ctxt == NULL)
12367
  return (-1);
12368
    /*
12369
    * WARNING: Change the start value if adding to the
12370
    * xmlSchemaParseOption.
12371
    */
12372
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
12373
        if (options & 1<<i) {
12374
      return (-1);
12375
        }
12376
    }
12377
    ctxt->options = options;
12378
    return (0);
12379
}
12380
12381
/**
12382
 * xmlSchemaValidCtxtGetOptions:
12383
 * @ctxt: a schema parser context
12384
 *
12385
 * Returns the option combination of the parser context.
12386
 */
12387
static int
12388
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12389
12390
{
12391
    if (ctxt == NULL)
12392
  return (-1);
12393
    else
12394
  return (ctxt->options);
12395
}
12396
#endif
12397
12398
/**
12399
 * xmlSchemaNewParserCtxt:
12400
 * @URL:  the location of the schema
12401
 *
12402
 * Create an XML Schemas parse context for that file/resource expected
12403
 * to contain an XML Schemas file.
12404
 *
12405
 * Returns the parser context or NULL in case of error
12406
 */
12407
xmlSchemaParserCtxtPtr
12408
xmlSchemaNewParserCtxt(const char *URL)
12409
29.0k
{
12410
29.0k
    xmlSchemaParserCtxtPtr ret;
12411
12412
29.0k
    if (URL == NULL)
12413
53
        return (NULL);
12414
12415
29.0k
    ret = xmlSchemaParserCtxtCreate();
12416
29.0k
    if (ret == NULL)
12417
0
  return(NULL);
12418
29.0k
    ret->dict = xmlDictCreate();
12419
29.0k
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12420
29.0k
    return (ret);
12421
29.0k
}
12422
12423
/**
12424
 * xmlSchemaNewMemParserCtxt:
12425
 * @buffer:  a pointer to a char array containing the schemas
12426
 * @size:  the size of the array
12427
 *
12428
 * Create an XML Schemas parse context for that memory buffer expected
12429
 * to contain an XML Schemas file.
12430
 *
12431
 * Returns the parser context or NULL in case of error
12432
 */
12433
xmlSchemaParserCtxtPtr
12434
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12435
0
{
12436
0
    xmlSchemaParserCtxtPtr ret;
12437
12438
0
    if ((buffer == NULL) || (size <= 0))
12439
0
        return (NULL);
12440
0
    ret = xmlSchemaParserCtxtCreate();
12441
0
    if (ret == NULL)
12442
0
  return(NULL);
12443
0
    ret->buffer = buffer;
12444
0
    ret->size = size;
12445
0
    ret->dict = xmlDictCreate();
12446
0
    return (ret);
12447
0
}
12448
12449
/**
12450
 * xmlSchemaNewDocParserCtxt:
12451
 * @doc:  a preparsed document tree
12452
 *
12453
 * Create an XML Schemas parse context for that document.
12454
 * NB. The document may be modified during the parsing process.
12455
 *
12456
 * Returns the parser context or NULL in case of error
12457
 */
12458
xmlSchemaParserCtxtPtr
12459
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12460
0
{
12461
0
    xmlSchemaParserCtxtPtr ret;
12462
12463
0
    if (doc == NULL)
12464
0
      return (NULL);
12465
0
    ret = xmlSchemaParserCtxtCreate();
12466
0
    if (ret == NULL)
12467
0
  return(NULL);
12468
0
    ret->doc = doc;
12469
0
    ret->dict = xmlDictCreate();
12470
    /* The application has responsibility for the document */
12471
0
    ret->preserve = 1;
12472
12473
0
    return (ret);
12474
0
}
12475
12476
/**
12477
 * xmlSchemaFreeParserCtxt:
12478
 * @ctxt:  the schema parser context
12479
 *
12480
 * Free the resources associated to the schema parser context
12481
 */
12482
void
12483
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12484
29.3k
{
12485
29.3k
    if (ctxt == NULL)
12486
53
        return;
12487
29.3k
    if (ctxt->doc != NULL && !ctxt->preserve)
12488
0
        xmlFreeDoc(ctxt->doc);
12489
29.3k
    if (ctxt->vctxt != NULL) {
12490
6.83k
  xmlSchemaFreeValidCtxt(ctxt->vctxt);
12491
6.83k
    }
12492
29.3k
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12493
3.07k
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
12494
3.07k
  ctxt->constructor = NULL;
12495
3.07k
  ctxt->ownsConstructor = 0;
12496
3.07k
    }
12497
29.3k
    if (ctxt->attrProhibs != NULL)
12498
29.3k
  xmlSchemaItemListFree(ctxt->attrProhibs);
12499
29.3k
    xmlDictFree(ctxt->dict);
12500
29.3k
    xmlFree(ctxt);
12501
29.3k
}
12502
12503
/************************************************************************
12504
 *                  *
12505
 *      Building the content models     *
12506
 *                  *
12507
 ************************************************************************/
12508
12509
/**
12510
 * xmlSchemaBuildContentModelForSubstGroup:
12511
 *
12512
 * Returns 1 if nillable, 0 otherwise
12513
 */
12514
static int
12515
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12516
  xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12517
7
{
12518
7
    xmlAutomataStatePtr start, tmp;
12519
7
    xmlSchemaElementPtr elemDecl, member;
12520
7
    xmlSchemaSubstGroupPtr substGroup;
12521
7
    int i;
12522
7
    int ret = 0;
12523
12524
7
    elemDecl = (xmlSchemaElementPtr) particle->children;
12525
    /*
12526
    * Wrap the substitution group with a CHOICE.
12527
    */
12528
7
    start = pctxt->state;
12529
7
    if (end == NULL)
12530
2
  end = xmlAutomataNewState(pctxt->am);
12531
7
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12532
7
    if (substGroup == NULL) {
12533
0
  xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12534
0
      XML_SCHEMAP_INTERNAL,
12535
0
      "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12536
0
      "declaration is marked having a subst. group but none "
12537
0
      "available.\n", elemDecl->name, NULL);
12538
0
  return(0);
12539
0
    }
12540
7
    if (counter >= 0) {
12541
  /*
12542
  * NOTE that we put the declaration in, even if it's abstract.
12543
  * However, an error will be raised during *validation* if an element
12544
  * information item shall be validated against an abstract element
12545
  * declaration.
12546
  */
12547
5
  tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12548
5
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
12549
5
              elemDecl->name, elemDecl->targetNamespace, elemDecl);
12550
  /*
12551
  * Add subst. group members.
12552
  */
12553
13
  for (i = 0; i < substGroup->members->nbItems; i++) {
12554
8
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12555
8
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
12556
8
                   member->name, member->targetNamespace, member);
12557
8
  }
12558
5
    } else if (particle->maxOccurs == 1) {
12559
  /*
12560
  * NOTE that we put the declaration in, even if it's abstract,
12561
  */
12562
2
  xmlAutomataNewEpsilon(pctxt->am,
12563
2
      xmlAutomataNewTransition2(pctxt->am,
12564
2
      start, NULL,
12565
2
      elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12566
  /*
12567
  * Add subst. group members.
12568
  */
12569
18
  for (i = 0; i < substGroup->members->nbItems; i++) {
12570
16
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12571
      /*
12572
      * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12573
      *  was incorrectly used instead of xmlAutomataNewTransition2()
12574
      *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12575
      *  section in xmlSchemaBuildAContentModel() ).
12576
      * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12577
      *  intended for the above "counter" section originally. I.e.,
12578
      *  check xs:all with subst-groups.
12579
      *
12580
      * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12581
      *                member->name, member->targetNamespace,
12582
      *          1, 1, member);
12583
      */
12584
16
      tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12585
16
    member->name, member->targetNamespace, member);
12586
16
      xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12587
16
  }
12588
2
    } else {
12589
0
  xmlAutomataStatePtr hop;
12590
0
  int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12591
0
      UNBOUNDED : particle->maxOccurs - 1;
12592
0
  int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12593
12594
0
  counter =
12595
0
      xmlAutomataNewCounter(pctxt->am, minOccurs,
12596
0
      maxOccurs);
12597
0
  hop = xmlAutomataNewState(pctxt->am);
12598
12599
0
  xmlAutomataNewEpsilon(pctxt->am,
12600
0
      xmlAutomataNewTransition2(pctxt->am,
12601
0
      start, NULL,
12602
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl),
12603
0
      hop);
12604
  /*
12605
   * Add subst. group members.
12606
   */
12607
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12608
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12609
0
      xmlAutomataNewEpsilon(pctxt->am,
12610
0
    xmlAutomataNewTransition2(pctxt->am,
12611
0
    start, NULL,
12612
0
    member->name, member->targetNamespace, member),
12613
0
    hop);
12614
0
  }
12615
0
  xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12616
0
  xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12617
0
    }
12618
7
    if (particle->minOccurs == 0) {
12619
0
  xmlAutomataNewEpsilon(pctxt->am, start, end);
12620
0
        ret = 1;
12621
0
    }
12622
7
    pctxt->state = end;
12623
7
    return(ret);
12624
7
}
12625
12626
/**
12627
 * xmlSchemaBuildContentModelForElement:
12628
 *
12629
 * Returns 1 if nillable, 0 otherwise
12630
 */
12631
static int
12632
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12633
             xmlSchemaParticlePtr particle)
12634
1.22k
{
12635
1.22k
    int ret = 0;
12636
12637
1.22k
    if (((xmlSchemaElementPtr) particle->children)->flags &
12638
1.22k
  XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12639
  /*
12640
  * Substitution groups.
12641
  */
12642
2
  ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12643
1.22k
    } else {
12644
1.22k
  xmlSchemaElementPtr elemDecl;
12645
1.22k
  xmlAutomataStatePtr start;
12646
12647
1.22k
  elemDecl = (xmlSchemaElementPtr) particle->children;
12648
12649
1.22k
  if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12650
0
      return(0);
12651
1.22k
  if (particle->maxOccurs == 1) {
12652
1.07k
      start = ctxt->state;
12653
1.07k
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12654
1.07k
        elemDecl->name, elemDecl->targetNamespace, elemDecl);
12655
1.07k
  } else if ((particle->maxOccurs >= UNBOUNDED) &&
12656
150
             (particle->minOccurs < 2)) {
12657
      /* Special case. */
12658
94
      start = ctxt->state;
12659
94
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12660
94
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12661
94
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12662
94
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12663
94
  } else {
12664
56
      int counter;
12665
56
      int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12666
37
          UNBOUNDED : particle->maxOccurs - 1;
12667
56
      int minOccurs = particle->minOccurs < 1 ?
12668
44
          0 : particle->minOccurs - 1;
12669
12670
56
      start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12671
56
      counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12672
56
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12673
56
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12674
56
      xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12675
56
      ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12676
56
    NULL, counter);
12677
56
  }
12678
1.22k
  if (particle->minOccurs == 0) {
12679
213
      xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12680
213
            ret = 1;
12681
213
        }
12682
1.22k
    }
12683
1.22k
    return(ret);
12684
1.22k
}
12685
12686
/**
12687
 * xmlSchemaBuildAContentModel:
12688
 * @ctxt:  the schema parser context
12689
 * @particle:  the particle component
12690
 * @name:  the complex type's name whose content is being built
12691
 *
12692
 * Create the automaton for the {content type} of a complex type.
12693
 *
12694
 * Returns 1 if the content is nillable, 0 otherwise
12695
 */
12696
static int
12697
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12698
          xmlSchemaParticlePtr particle)
12699
5.87k
{
12700
5.87k
    int ret = 0, tmp2;
12701
12702
5.87k
    if (particle == NULL) {
12703
0
  PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12704
0
  return(1);
12705
0
    }
12706
5.87k
    if (particle->children == NULL) {
12707
  /*
12708
  * Just return in this case. A missing "term" of the particle
12709
  * might arise due to an invalid "term" component.
12710
  */
12711
0
  return(1);
12712
0
    }
12713
12714
5.87k
    switch (particle->children->type) {
12715
3.39k
  case XML_SCHEMA_TYPE_ANY: {
12716
3.39k
      xmlAutomataStatePtr start, end;
12717
3.39k
      xmlSchemaWildcardPtr wild;
12718
3.39k
      xmlSchemaWildcardNsPtr ns;
12719
12720
3.39k
      wild = (xmlSchemaWildcardPtr) particle->children;
12721
12722
3.39k
      start = pctxt->state;
12723
3.39k
      end = xmlAutomataNewState(pctxt->am);
12724
12725
3.39k
      if (particle->maxOccurs == 1) {
12726
3.34k
    if (wild->any == 1) {
12727
        /*
12728
        * We need to add both transitions:
12729
        *
12730
        * 1. the {"*", "*"} for elements in a namespace.
12731
        */
12732
1.65k
        pctxt->state =
12733
1.65k
      xmlAutomataNewTransition2(pctxt->am,
12734
1.65k
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12735
1.65k
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12736
        /*
12737
        * 2. the {"*"} for elements in no namespace.
12738
        */
12739
1.65k
        pctxt->state =
12740
1.65k
      xmlAutomataNewTransition2(pctxt->am,
12741
1.65k
      start, NULL, BAD_CAST "*", NULL, wild);
12742
1.65k
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12743
12744
1.69k
    } else if (wild->nsSet != NULL) {
12745
1.55k
        ns = wild->nsSet;
12746
29.3k
        do {
12747
29.3k
      pctxt->state = start;
12748
29.3k
      pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12749
29.3k
          pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12750
29.3k
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12751
29.3k
      ns = ns->next;
12752
29.3k
        } while (ns != NULL);
12753
12754
1.55k
    } else if (wild->negNsSet != NULL) {
12755
17
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12756
17
      start, end, BAD_CAST "*", wild->negNsSet->value,
12757
17
      wild);
12758
17
    }
12759
3.34k
      } else {
12760
49
    int counter;
12761
49
    xmlAutomataStatePtr hop;
12762
49
    int maxOccurs =
12763
49
        particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12764
49
                                           particle->maxOccurs - 1;
12765
49
    int minOccurs =
12766
49
        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12767
12768
49
    counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12769
49
    hop = xmlAutomataNewState(pctxt->am);
12770
49
    if (wild->any == 1) {
12771
15
        pctxt->state =
12772
15
      xmlAutomataNewTransition2(pctxt->am,
12773
15
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12774
15
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12775
15
        pctxt->state =
12776
15
      xmlAutomataNewTransition2(pctxt->am,
12777
15
      start, NULL, BAD_CAST "*", NULL, wild);
12778
15
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12779
34
    } else if (wild->nsSet != NULL) {
12780
19
        ns = wild->nsSet;
12781
136
        do {
12782
136
      pctxt->state =
12783
136
          xmlAutomataNewTransition2(pctxt->am,
12784
136
        start, NULL, BAD_CAST "*", ns->value, wild);
12785
136
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12786
136
      ns = ns->next;
12787
136
        } while (ns != NULL);
12788
12789
19
    } else if (wild->negNsSet != NULL) {
12790
9
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12791
9
      start, hop, BAD_CAST "*", wild->negNsSet->value,
12792
9
      wild);
12793
9
    }
12794
49
    xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12795
49
    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12796
49
      }
12797
3.39k
      if (particle->minOccurs == 0) {
12798
268
    xmlAutomataNewEpsilon(pctxt->am, start, end);
12799
268
                ret = 1;
12800
268
      }
12801
3.39k
      pctxt->state = end;
12802
3.39k
            break;
12803
0
  }
12804
1.22k
        case XML_SCHEMA_TYPE_ELEMENT:
12805
1.22k
      ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12806
1.22k
      break;
12807
826
        case XML_SCHEMA_TYPE_SEQUENCE:{
12808
826
            xmlSchemaTreeItemPtr sub;
12809
12810
826
            ret = 1;
12811
            /*
12812
             * If max and min occurrences are default (1) then
12813
             * simply iterate over the particles of the <sequence>.
12814
             */
12815
826
            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12816
569
                sub = particle->children->children;
12817
12818
2.43k
                while (sub != NULL) {
12819
1.86k
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12820
1.86k
                                        (xmlSchemaParticlePtr) sub);
12821
1.86k
                    if (tmp2 != 1) ret = 0;
12822
1.86k
                    sub = sub->next;
12823
1.86k
                }
12824
569
            } else {
12825
257
                xmlAutomataStatePtr oldstate = pctxt->state;
12826
12827
257
                if (particle->maxOccurs >= UNBOUNDED) {
12828
88
                    if (particle->minOccurs > 1) {
12829
24
                        xmlAutomataStatePtr tmp;
12830
24
                        int counter;
12831
12832
24
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12833
24
                            oldstate, NULL);
12834
24
                        oldstate = pctxt->state;
12835
12836
24
                        counter = xmlAutomataNewCounter(pctxt->am,
12837
24
                            particle->minOccurs - 1, UNBOUNDED);
12838
12839
24
                        sub = particle->children->children;
12840
352
                        while (sub != NULL) {
12841
328
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12842
328
                                            (xmlSchemaParticlePtr) sub);
12843
328
                            if (tmp2 != 1) ret = 0;
12844
328
                            sub = sub->next;
12845
328
                        }
12846
24
                        tmp = pctxt->state;
12847
24
                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
12848
24
                                                   oldstate, counter);
12849
24
                        pctxt->state =
12850
24
                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
12851
24
                                                       NULL, counter);
12852
24
                        if (ret == 1)
12853
1
                            xmlAutomataNewEpsilon(pctxt->am,
12854
1
                                                oldstate, pctxt->state);
12855
12856
64
                    } else {
12857
64
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12858
64
                            oldstate, NULL);
12859
64
                        oldstate = pctxt->state;
12860
12861
64
                        sub = particle->children->children;
12862
334
                        while (sub != NULL) {
12863
270
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12864
270
                                        (xmlSchemaParticlePtr) sub);
12865
270
                            if (tmp2 != 1) ret = 0;
12866
270
                            sub = sub->next;
12867
270
                        }
12868
64
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12869
64
                                              oldstate);
12870
                        /*
12871
                         * epsilon needed to block previous trans from
12872
                         * being allowed to enter back from another
12873
                         * construct
12874
                         */
12875
64
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12876
64
                                            pctxt->state, NULL);
12877
64
                        if (particle->minOccurs == 0) {
12878
31
                            xmlAutomataNewEpsilon(pctxt->am,
12879
31
                                oldstate, pctxt->state);
12880
31
                            ret = 1;
12881
31
                        }
12882
64
                    }
12883
169
                } else if ((particle->maxOccurs > 1)
12884
169
                           || (particle->minOccurs > 1)) {
12885
45
                    xmlAutomataStatePtr tmp;
12886
45
                    int counter;
12887
12888
45
                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12889
45
                        oldstate, NULL);
12890
45
                    oldstate = pctxt->state;
12891
12892
45
                    counter = xmlAutomataNewCounter(pctxt->am,
12893
45
                        particle->minOccurs - 1,
12894
45
                        particle->maxOccurs - 1);
12895
12896
45
                    sub = particle->children->children;
12897
287
                    while (sub != NULL) {
12898
242
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12899
242
                                        (xmlSchemaParticlePtr) sub);
12900
242
                        if (tmp2 != 1) ret = 0;
12901
242
                        sub = sub->next;
12902
242
                    }
12903
45
                    tmp = pctxt->state;
12904
45
                    xmlAutomataNewCountedTrans(pctxt->am,
12905
45
                        tmp, oldstate, counter);
12906
45
                    pctxt->state =
12907
45
                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12908
45
                                                   counter);
12909
45
                    if ((particle->minOccurs == 0) || (ret == 1)) {
12910
32
                        xmlAutomataNewEpsilon(pctxt->am,
12911
32
                                            oldstate, pctxt->state);
12912
32
                        ret = 1;
12913
32
                    }
12914
124
                } else {
12915
124
                    sub = particle->children->children;
12916
1.97k
                    while (sub != NULL) {
12917
1.85k
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12918
1.85k
                                        (xmlSchemaParticlePtr) sub);
12919
1.85k
                        if (tmp2 != 1) ret = 0;
12920
1.85k
                        sub = sub->next;
12921
1.85k
                    }
12922
12923
        /*
12924
         * epsilon needed to block previous trans from
12925
         * being allowed to enter back from another
12926
         * construct
12927
         */
12928
124
        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12929
124
          pctxt->state, NULL);
12930
12931
124
                    if (particle->minOccurs == 0) {
12932
124
                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
12933
124
                                              pctxt->state);
12934
124
                        ret = 1;
12935
124
                    }
12936
124
                }
12937
257
            }
12938
826
            break;
12939
0
        }
12940
402
        case XML_SCHEMA_TYPE_CHOICE:{
12941
402
            xmlSchemaTreeItemPtr sub;
12942
402
            xmlAutomataStatePtr start, end;
12943
12944
402
            ret = 0;
12945
402
            start = pctxt->state;
12946
402
            end = xmlAutomataNewState(pctxt->am);
12947
12948
            /*
12949
             * iterate over the subtypes and remerge the end with an
12950
             * epsilon transition
12951
             */
12952
402
            if (particle->maxOccurs == 1) {
12953
268
                sub = particle->children->children;
12954
560
                while (sub != NULL) {
12955
292
                    pctxt->state = start;
12956
292
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12957
292
                                        (xmlSchemaParticlePtr) sub);
12958
292
                    if (tmp2 == 1) ret = 1;
12959
292
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12960
292
                    sub = sub->next;
12961
292
                }
12962
268
            } else {
12963
134
                int counter;
12964
134
                xmlAutomataStatePtr hop, base;
12965
134
                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12966
131
                    UNBOUNDED : particle->maxOccurs - 1;
12967
134
                int minOccurs =
12968
134
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12969
12970
                /*
12971
                 * use a counter to keep track of the number of transitions
12972
                 * which went through the choice.
12973
                 */
12974
134
                counter =
12975
134
                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12976
134
                hop = xmlAutomataNewState(pctxt->am);
12977
134
                base = xmlAutomataNewState(pctxt->am);
12978
12979
134
                sub = particle->children->children;
12980
540
                while (sub != NULL) {
12981
406
                    pctxt->state = base;
12982
406
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12983
406
                                        (xmlSchemaParticlePtr) sub);
12984
406
                    if (tmp2 == 1) ret = 1;
12985
406
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12986
406
                    sub = sub->next;
12987
406
                }
12988
134
                xmlAutomataNewEpsilon(pctxt->am, start, base);
12989
134
                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
12990
134
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12991
134
                if (ret == 1)
12992
12
                    xmlAutomataNewEpsilon(pctxt->am, base, end);
12993
134
            }
12994
402
            if (particle->minOccurs == 0) {
12995
64
                xmlAutomataNewEpsilon(pctxt->am, start, end);
12996
64
                ret = 1;
12997
64
            }
12998
402
            pctxt->state = end;
12999
402
            break;
13000
0
        }
13001
19
        case XML_SCHEMA_TYPE_ALL:{
13002
19
            xmlAutomataStatePtr start, tmp;
13003
19
            xmlSchemaParticlePtr sub;
13004
19
            xmlSchemaElementPtr elemDecl;
13005
13006
19
            ret = 1;
13007
13008
19
            sub = (xmlSchemaParticlePtr) particle->children->children;
13009
19
            if (sub == NULL)
13010
0
                break;
13011
13012
19
            ret = 0;
13013
13014
19
            start = pctxt->state;
13015
19
            tmp = xmlAutomataNewState(pctxt->am);
13016
19
            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13017
19
            pctxt->state = tmp;
13018
68
            while (sub != NULL) {
13019
49
                pctxt->state = tmp;
13020
13021
49
                elemDecl = (xmlSchemaElementPtr) sub->children;
13022
49
                if (elemDecl == NULL) {
13023
0
                    PERROR_INT("xmlSchemaBuildAContentModel",
13024
0
                        "<element> particle has no term");
13025
0
                    return(ret);
13026
49
                };
13027
                /*
13028
                * NOTE: The {max occurs} of all the particles in the
13029
                * {particles} of the group must be 0 or 1; this is
13030
                * already ensured during the parse of the content of
13031
                * <all>.
13032
                */
13033
49
                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13034
5
                    int counter;
13035
13036
                    /*
13037
                     * This is an abstract group, we need to share
13038
                     * the same counter for all the element transitions
13039
                     * derived from the group
13040
                     */
13041
5
                    counter = xmlAutomataNewCounter(pctxt->am,
13042
5
                                       sub->minOccurs, sub->maxOccurs);
13043
5
                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
13044
5
                                       sub, counter, pctxt->state);
13045
44
                } else {
13046
44
                    if ((sub->minOccurs == 1) &&
13047
44
                        (sub->maxOccurs == 1)) {
13048
25
                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13049
25
                                                pctxt->state,
13050
25
                                                elemDecl->name,
13051
25
                                                elemDecl->targetNamespace,
13052
25
                                                1, 1, elemDecl);
13053
25
                    } else if ((sub->minOccurs == 0) &&
13054
19
                        (sub->maxOccurs == 1)) {
13055
13056
18
                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13057
18
                                                 pctxt->state,
13058
18
                                                 elemDecl->name,
13059
18
                                                 elemDecl->targetNamespace,
13060
18
                                                 0,
13061
18
                                                 1,
13062
18
                                                 elemDecl);
13063
18
                    }
13064
44
                }
13065
49
                sub = (xmlSchemaParticlePtr) sub->next;
13066
49
            }
13067
19
            pctxt->state =
13068
19
                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13069
19
            if (particle->minOccurs == 0) {
13070
1
                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13071
1
                ret = 1;
13072
1
            }
13073
19
            break;
13074
19
        }
13075
0
  case XML_SCHEMA_TYPE_GROUP:
13076
      /*
13077
      * If we hit a model group definition, then this means that
13078
      * it was empty, thus was not substituted for the containing
13079
      * model group. Just do nothing in this case.
13080
      * TODO: But the group should be substituted and not occur at
13081
      * all in the content model at this point. Fix this.
13082
      */
13083
0
            ret = 1;
13084
0
      break;
13085
0
        default:
13086
0
      xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13087
0
    "xmlSchemaBuildAContentModel",
13088
0
    "found unexpected term of type '%s' in content model",
13089
0
    WXS_ITEM_TYPE_NAME(particle->children), NULL);
13090
0
            return(ret);
13091
5.87k
    }
13092
5.87k
    return(ret);
13093
5.87k
}
13094
13095
/**
13096
 * xmlSchemaBuildContentModel:
13097
 * @ctxt:  the schema parser context
13098
 * @type:  the complex type definition
13099
 * @name:  the element name
13100
 *
13101
 * Builds the content model of the complex type.
13102
 */
13103
static void
13104
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13105
         xmlSchemaParserCtxtPtr ctxt)
13106
1.41k
{
13107
1.41k
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13108
1.41k
  (type->contModel != NULL) ||
13109
1.41k
  ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13110
1.41k
  (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13111
795
  return;
13112
13113
616
    ctxt->am = NULL;
13114
616
    ctxt->am = xmlNewAutomata();
13115
616
    if (ctxt->am == NULL) {
13116
0
  xmlSchemaPErrMemory(ctxt);
13117
0
        return;
13118
0
    }
13119
616
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
13120
    /*
13121
    * Build the automaton.
13122
    */
13123
616
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13124
616
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13125
616
    type->contModel = xmlAutomataCompile(ctxt->am);
13126
616
    if (type->contModel == NULL) {
13127
0
        xmlSchemaPCustomErr(ctxt,
13128
0
      XML_SCHEMAP_INTERNAL,
13129
0
      WXS_BASIC_CAST type, type->node,
13130
0
      "Failed to compile the content model", NULL);
13131
616
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13132
51
        xmlSchemaPCustomErr(ctxt,
13133
51
      XML_SCHEMAP_NOT_DETERMINISTIC,
13134
      /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13135
51
      WXS_BASIC_CAST type, type->node,
13136
51
      "The content model is not determinist", NULL);
13137
565
    } else {
13138
565
    }
13139
616
    ctxt->state = NULL;
13140
616
    xmlFreeAutomata(ctxt->am);
13141
616
    ctxt->am = NULL;
13142
616
}
13143
13144
/**
13145
 * xmlSchemaResolveElementReferences:
13146
 * @elem:  the schema element context
13147
 * @ctxt:  the schema parser context
13148
 *
13149
 * Resolves the references of an element declaration
13150
 * or particle, which has an element declaration as it's
13151
 * term.
13152
 */
13153
static void
13154
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13155
          xmlSchemaParserCtxtPtr ctxt)
13156
8.01k
{
13157
8.01k
    if ((ctxt == NULL) || (elemDecl == NULL) ||
13158
8.01k
  ((elemDecl != NULL) &&
13159
8.01k
  (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13160
73
        return;
13161
7.94k
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13162
13163
7.94k
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13164
4.38k
  xmlSchemaTypePtr type;
13165
13166
  /* (type definition) ... otherwise the type definition `resolved`
13167
  * to by the `actual value` of the type [attribute] ...
13168
  */
13169
4.38k
  type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13170
4.38k
      elemDecl->namedTypeNs);
13171
4.38k
  if (type == NULL) {
13172
216
      xmlSchemaPResCompAttrErr(ctxt,
13173
216
    XML_SCHEMAP_SRC_RESOLVE,
13174
216
    WXS_BASIC_CAST elemDecl, elemDecl->node,
13175
216
    "type", elemDecl->namedType, elemDecl->namedTypeNs,
13176
216
    XML_SCHEMA_TYPE_BASIC, "type definition");
13177
216
  } else
13178
4.16k
      elemDecl->subtypes = type;
13179
4.38k
    }
13180
7.94k
    if (elemDecl->substGroup != NULL) {
13181
102
  xmlSchemaElementPtr substHead;
13182
13183
  /*
13184
  * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13185
  * substitutionGroup?
13186
  */
13187
102
  substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13188
102
      elemDecl->substGroupNs);
13189
102
  if (substHead == NULL) {
13190
29
      xmlSchemaPResCompAttrErr(ctxt,
13191
29
    XML_SCHEMAP_SRC_RESOLVE,
13192
29
    WXS_BASIC_CAST elemDecl, NULL,
13193
29
    "substitutionGroup", elemDecl->substGroup,
13194
29
    elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13195
73
  } else {
13196
73
      xmlSchemaResolveElementReferences(substHead, ctxt);
13197
      /*
13198
      * Set the "substitution group affiliation".
13199
      * NOTE that now we use the "refDecl" field for this.
13200
      */
13201
73
      WXS_SUBST_HEAD(elemDecl) = substHead;
13202
      /*
13203
      * The type definitions is set to:
13204
      * SPEC "...the {type definition} of the element
13205
      * declaration `resolved` to by the `actual value`
13206
      * of the substitutionGroup [attribute], if present"
13207
      */
13208
73
      if (elemDecl->subtypes == NULL) {
13209
62
                if (substHead->subtypes == NULL) {
13210
                    /*
13211
                     * This can happen with self-referencing substitution
13212
                     * groups. The cycle will be detected later, but we have
13213
                     * to set subtypes to avoid null-pointer dereferences.
13214
                     */
13215
21
              elemDecl->subtypes = xmlSchemaGetBuiltInType(
13216
21
                            XML_SCHEMAS_ANYTYPE);
13217
41
                } else {
13218
41
        elemDecl->subtypes = substHead->subtypes;
13219
41
                }
13220
62
            }
13221
73
  }
13222
102
    }
13223
    /*
13224
    * SPEC "The definition of anyType serves as the default type definition
13225
    * for element declarations whose XML representation does not specify one."
13226
    */
13227
7.94k
    if ((elemDecl->subtypes == NULL) &&
13228
7.94k
  (elemDecl->namedType == NULL) &&
13229
7.94k
  (elemDecl->substGroup == NULL))
13230
442
  elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13231
7.94k
}
13232
13233
/**
13234
 * xmlSchemaResolveUnionMemberTypes:
13235
 * @ctxt:  the schema parser context
13236
 * @type:  the schema simple type definition
13237
 *
13238
 * Checks and builds the "member type definitions" property of the union
13239
 * simple type. This handles part (1), part (2) is done in
13240
 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13241
 *
13242
 * Returns -1 in case of an internal error, 0 otherwise.
13243
 */
13244
static int
13245
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13246
         xmlSchemaTypePtr type)
13247
909
{
13248
13249
909
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
13250
909
    xmlSchemaTypePtr memberType;
13251
13252
    /*
13253
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13254
    * define the explicit members as the type definitions `resolved`
13255
    * to by the items in the `actual value` of the memberTypes [attribute],
13256
    * if any, followed by the type definitions corresponding to the
13257
    * <simpleType>s among the [children] of <union>, if any."
13258
    */
13259
    /*
13260
    * Resolve references.
13261
    */
13262
909
    link = type->memberTypes;
13263
909
    lastLink = NULL;
13264
7.70k
    while (link != NULL) {
13265
6.79k
  const xmlChar *name, *nsName;
13266
13267
6.79k
  name = ((xmlSchemaQNameRefPtr) link->type)->name;
13268
6.79k
  nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13269
13270
6.79k
  memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13271
6.79k
  if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13272
5.61k
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13273
5.61k
    WXS_BASIC_CAST type, type->node, "memberTypes",
13274
5.61k
    name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13275
      /*
13276
      * Remove the member type link.
13277
      */
13278
5.61k
      if (lastLink == NULL)
13279
997
    type->memberTypes = link->next;
13280
4.61k
      else
13281
4.61k
    lastLink->next = link->next;
13282
5.61k
      newLink = link;
13283
5.61k
      link = link->next;
13284
5.61k
      xmlFree(newLink);
13285
5.61k
  } else {
13286
1.18k
      link->type = memberType;
13287
1.18k
      lastLink = link;
13288
1.18k
      link = link->next;
13289
1.18k
  }
13290
6.79k
    }
13291
    /*
13292
    * Add local simple types,
13293
    */
13294
909
    memberType = type->subtypes;
13295
1.58k
    while (memberType != NULL) {
13296
674
  link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13297
674
  if (link == NULL) {
13298
0
      xmlSchemaPErrMemory(ctxt);
13299
0
      return (-1);
13300
0
  }
13301
674
  link->type = memberType;
13302
674
  link->next = NULL;
13303
674
  if (lastLink == NULL)
13304
563
      type->memberTypes = link;
13305
111
  else
13306
111
      lastLink->next = link;
13307
674
  lastLink = link;
13308
674
  memberType = memberType->next;
13309
674
    }
13310
909
    return (0);
13311
909
}
13312
13313
/**
13314
 * xmlSchemaIsDerivedFromBuiltInType:
13315
 * @ctxt:  the schema parser context
13316
 * @type:  the type definition
13317
 * @valType: the value type
13318
 *
13319
 *
13320
 * Returns 1 if the type has the given value type, or
13321
 * is derived from such a type.
13322
 */
13323
static int
13324
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13325
7.60k
{
13326
7.60k
    if (type == NULL)
13327
3.61k
  return (0);
13328
3.99k
    if (WXS_IS_COMPLEX(type))
13329
0
  return (0);
13330
3.99k
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13331
3.66k
  if (type->builtInType == valType)
13332
12
      return(1);
13333
3.65k
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13334
3.65k
      (type->builtInType == XML_SCHEMAS_ANYTYPE))
13335
365
      return (0);
13336
3.29k
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13337
3.65k
    }
13338
323
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13339
3.99k
}
13340
13341
#if 0
13342
/**
13343
 * xmlSchemaIsDerivedFromBuiltInType:
13344
 * @ctxt:  the schema parser context
13345
 * @type:  the type definition
13346
 * @valType: the value type
13347
 *
13348
 *
13349
 * Returns 1 if the type has the given value type, or
13350
 * is derived from such a type.
13351
 */
13352
static int
13353
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13354
{
13355
    if (type == NULL)
13356
  return (0);
13357
    if (WXS_IS_COMPLEX(type))
13358
  return (0);
13359
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13360
  if (type->builtInType == valType)
13361
      return(1);
13362
  return (0);
13363
    } else
13364
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13365
13366
    return (0);
13367
}
13368
13369
static xmlSchemaTypePtr
13370
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13371
{
13372
    if (type == NULL)
13373
  return (NULL);
13374
    if (WXS_IS_COMPLEX(type))
13375
  return (NULL);
13376
    if (type->type == XML_SCHEMA_TYPE_BASIC)
13377
  return(type);
13378
    return(xmlSchemaQueryBuiltInType(type->subtypes));
13379
}
13380
#endif
13381
13382
/**
13383
 * xmlSchemaGetPrimitiveType:
13384
 * @type:  the simpleType definition
13385
 *
13386
 * Returns the primitive type of the given type or
13387
 * NULL in case of error.
13388
 */
13389
static xmlSchemaTypePtr
13390
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13391
33.4k
{
13392
13393
84.5k
    while (type != NULL) {
13394
  /*
13395
  * Note that anySimpleType is actually not a primitive type
13396
  * but we need that here.
13397
  */
13398
84.5k
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13399
84.5k
     (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13400
33.4k
      return (type);
13401
51.1k
  type = type->baseType;
13402
51.1k
    }
13403
13404
7
    return (NULL);
13405
33.4k
}
13406
13407
#if 0
13408
/**
13409
 * xmlSchemaGetBuiltInTypeAncestor:
13410
 * @type:  the simpleType definition
13411
 *
13412
 * Returns the primitive type of the given type or
13413
 * NULL in case of error.
13414
 */
13415
static xmlSchemaTypePtr
13416
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13417
{
13418
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13419
  return (0);
13420
    while (type != NULL) {
13421
  if (type->type == XML_SCHEMA_TYPE_BASIC)
13422
      return (type);
13423
  type = type->baseType;
13424
    }
13425
13426
    return (NULL);
13427
}
13428
#endif
13429
13430
/**
13431
 * xmlSchemaCloneWildcardNsConstraints:
13432
 * @ctxt:  the schema parser context
13433
 * @dest:  the destination wildcard
13434
 * @source: the source wildcard
13435
 *
13436
 * Clones the namespace constraints of source
13437
 * and assigns them to dest.
13438
 * Returns -1 on internal error, 0 otherwise.
13439
 */
13440
static int
13441
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13442
            xmlSchemaWildcardPtr dest,
13443
            xmlSchemaWildcardPtr source)
13444
67
{
13445
67
    xmlSchemaWildcardNsPtr cur, tmp, last;
13446
13447
67
    if ((source == NULL) || (dest == NULL))
13448
0
  return(-1);
13449
67
    dest->any = source->any;
13450
67
    cur = source->nsSet;
13451
67
    last = NULL;
13452
204
    while (cur != NULL) {
13453
137
  tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13454
137
  if (tmp == NULL)
13455
0
      return(-1);
13456
137
  tmp->value = cur->value;
13457
137
  if (last == NULL)
13458
51
      dest->nsSet = tmp;
13459
86
  else
13460
86
      last->next = tmp;
13461
137
  last = tmp;
13462
137
  cur = cur->next;
13463
137
    }
13464
67
    if (dest->negNsSet != NULL)
13465
8
  xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13466
67
    if (source->negNsSet != NULL) {
13467
0
  dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13468
0
  if (dest->negNsSet == NULL)
13469
0
      return(-1);
13470
0
  dest->negNsSet->value = source->negNsSet->value;
13471
0
    } else
13472
67
  dest->negNsSet = NULL;
13473
67
    return(0);
13474
67
}
13475
13476
/**
13477
 * xmlSchemaUnionWildcards:
13478
 * @ctxt:  the schema parser context
13479
 * @completeWild:  the first wildcard
13480
 * @curWild: the second wildcard
13481
 *
13482
 * Unions the namespace constraints of the given wildcards.
13483
 * @completeWild will hold the resulting union.
13484
 * Returns a positive error code on failure, -1 in case of an
13485
 * internal error, 0 otherwise.
13486
 */
13487
static int
13488
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13489
          xmlSchemaWildcardPtr completeWild,
13490
          xmlSchemaWildcardPtr curWild)
13491
203
{
13492
203
    xmlSchemaWildcardNsPtr cur, curB, tmp;
13493
13494
    /*
13495
    * 1 If O1 and O2 are the same value, then that value must be the
13496
    * value.
13497
    */
13498
203
    if ((completeWild->any == curWild->any) &&
13499
203
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13500
203
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13501
13502
73
  if ((completeWild->negNsSet == NULL) ||
13503
73
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13504
13505
63
      if (completeWild->nsSet != NULL) {
13506
46
    int found = 0;
13507
13508
    /*
13509
    * Check equality of sets.
13510
    */
13511
46
    cur = completeWild->nsSet;
13512
73
    while (cur != NULL) {
13513
68
        found = 0;
13514
68
        curB = curWild->nsSet;
13515
193
        while (curB != NULL) {
13516
152
      if (cur->value == curB->value) {
13517
27
          found = 1;
13518
27
          break;
13519
27
      }
13520
125
      curB = curB->next;
13521
125
        }
13522
68
        if (!found)
13523
41
      break;
13524
27
        cur = cur->next;
13525
27
    }
13526
46
    if (found)
13527
5
        return(0);
13528
46
      } else
13529
17
    return(0);
13530
63
  }
13531
73
    }
13532
    /*
13533
    * 2 If either O1 or O2 is any, then any must be the value
13534
    */
13535
181
    if (completeWild->any != curWild->any) {
13536
12
  if (completeWild->any == 0) {
13537
5
      completeWild->any = 1;
13538
5
      if (completeWild->nsSet != NULL) {
13539
5
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13540
5
    completeWild->nsSet = NULL;
13541
5
      }
13542
5
      if (completeWild->negNsSet != NULL) {
13543
0
    xmlFree(completeWild->negNsSet);
13544
0
    completeWild->negNsSet = NULL;
13545
0
      }
13546
5
  }
13547
12
  return (0);
13548
12
    }
13549
    /*
13550
    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13551
    * then the union of those sets must be the value.
13552
    */
13553
169
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13554
41
  int found;
13555
41
  xmlSchemaWildcardNsPtr start;
13556
13557
41
  cur = curWild->nsSet;
13558
41
  start = completeWild->nsSet;
13559
138
  while (cur != NULL) {
13560
97
      found = 0;
13561
97
      curB = start;
13562
299
      while (curB != NULL) {
13563
230
    if (cur->value == curB->value) {
13564
28
        found = 1;
13565
28
        break;
13566
28
    }
13567
202
    curB = curB->next;
13568
202
      }
13569
97
      if (!found) {
13570
69
    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13571
69
    if (tmp == NULL)
13572
0
        return (-1);
13573
69
    tmp->value = cur->value;
13574
69
    tmp->next = completeWild->nsSet;
13575
69
    completeWild->nsSet = tmp;
13576
69
      }
13577
97
      cur = cur->next;
13578
97
  }
13579
13580
41
  return(0);
13581
41
    }
13582
    /*
13583
    * 4 If the two are negations of different values (namespace names
13584
    * or `absent`), then a pair of not and `absent` must be the value.
13585
    */
13586
128
    if ((completeWild->negNsSet != NULL) &&
13587
128
  (curWild->negNsSet != NULL) &&
13588
128
  (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13589
10
  completeWild->negNsSet->value = NULL;
13590
13591
10
  return(0);
13592
10
    }
13593
    /*
13594
     * 5.
13595
     */
13596
118
    if (((completeWild->negNsSet != NULL) &&
13597
118
  (completeWild->negNsSet->value != NULL) &&
13598
118
  (curWild->nsSet != NULL)) ||
13599
118
  ((curWild->negNsSet != NULL) &&
13600
77
  (curWild->negNsSet->value != NULL) &&
13601
80
  (completeWild->nsSet != NULL))) {
13602
13603
80
  int nsFound, absentFound = 0;
13604
13605
80
  if (completeWild->nsSet != NULL) {
13606
39
      cur = completeWild->nsSet;
13607
39
      curB = curWild->negNsSet;
13608
41
  } else {
13609
41
      cur = curWild->nsSet;
13610
41
      curB = completeWild->negNsSet;
13611
41
  }
13612
80
  nsFound = 0;
13613
234
  while (cur != NULL) {
13614
162
      if (cur->value == NULL)
13615
8
    absentFound = 1;
13616
154
      else if (cur->value == curB->value)
13617
23
    nsFound = 1;
13618
162
      if (nsFound && absentFound)
13619
8
    break;
13620
154
      cur = cur->next;
13621
154
  }
13622
13623
80
  if (nsFound && absentFound) {
13624
      /*
13625
      * 5.1 If the set S includes both the negated namespace
13626
      * name and `absent`, then any must be the value.
13627
      */
13628
8
      completeWild->any = 1;
13629
8
      if (completeWild->nsSet != NULL) {
13630
5
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13631
5
    completeWild->nsSet = NULL;
13632
5
      }
13633
8
      if (completeWild->negNsSet != NULL) {
13634
3
    xmlFree(completeWild->negNsSet);
13635
3
    completeWild->negNsSet = NULL;
13636
3
      }
13637
72
  } else if (nsFound && (!absentFound)) {
13638
      /*
13639
      * 5.2 If the set S includes the negated namespace name
13640
      * but not `absent`, then a pair of not and `absent` must
13641
      * be the value.
13642
      */
13643
15
      if (completeWild->nsSet != NULL) {
13644
4
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13645
4
    completeWild->nsSet = NULL;
13646
4
      }
13647
15
      if (completeWild->negNsSet == NULL) {
13648
4
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13649
4
    if (completeWild->negNsSet == NULL)
13650
0
        return (-1);
13651
4
      }
13652
15
      completeWild->negNsSet->value = NULL;
13653
57
  } else if ((!nsFound) && absentFound) {
13654
      /*
13655
      * 5.3 If the set S includes `absent` but not the negated
13656
      * namespace name, then the union is not expressible.
13657
      */
13658
0
      xmlSchemaPErr(ctxt, completeWild->node,
13659
0
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13660
0
    "The union of the wildcard is not expressible.\n",
13661
0
    NULL, NULL);
13662
0
      return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13663
57
  } else if ((!nsFound) && (!absentFound)) {
13664
      /*
13665
      * 5.4 If the set S does not include either the negated namespace
13666
      * name or `absent`, then whichever of O1 or O2 is a pair of not
13667
      * and a namespace name must be the value.
13668
      */
13669
57
      if (completeWild->negNsSet == NULL) {
13670
30
    if (completeWild->nsSet != NULL) {
13671
30
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13672
30
        completeWild->nsSet = NULL;
13673
30
    }
13674
30
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13675
30
    if (completeWild->negNsSet == NULL)
13676
0
        return (-1);
13677
30
    completeWild->negNsSet->value = curWild->negNsSet->value;
13678
30
      }
13679
57
  }
13680
80
  return (0);
13681
80
    }
13682
    /*
13683
     * 6.
13684
     */
13685
38
    if (((completeWild->negNsSet != NULL) &&
13686
38
  (completeWild->negNsSet->value == NULL) &&
13687
38
  (curWild->nsSet != NULL)) ||
13688
38
  ((curWild->negNsSet != NULL) &&
13689
38
  (curWild->negNsSet->value == NULL) &&
13690
38
  (completeWild->nsSet != NULL))) {
13691
13692
35
  if (completeWild->nsSet != NULL) {
13693
35
      cur = completeWild->nsSet;
13694
35
  } else {
13695
0
      cur = curWild->nsSet;
13696
0
  }
13697
90
  while (cur != NULL) {
13698
67
      if (cur->value == NULL) {
13699
    /*
13700
    * 6.1 If the set S includes `absent`, then any must be the
13701
    * value.
13702
    */
13703
12
    completeWild->any = 1;
13704
12
    if (completeWild->nsSet != NULL) {
13705
12
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13706
12
        completeWild->nsSet = NULL;
13707
12
    }
13708
12
    if (completeWild->negNsSet != NULL) {
13709
0
        xmlFree(completeWild->negNsSet);
13710
0
        completeWild->negNsSet = NULL;
13711
0
    }
13712
12
    return (0);
13713
12
      }
13714
55
      cur = cur->next;
13715
55
  }
13716
23
  if (completeWild->negNsSet == NULL) {
13717
      /*
13718
      * 6.2 If the set S does not include `absent`, then a pair of not
13719
      * and `absent` must be the value.
13720
      */
13721
23
      if (completeWild->nsSet != NULL) {
13722
23
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13723
23
    completeWild->nsSet = NULL;
13724
23
      }
13725
23
      completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13726
23
      if (completeWild->negNsSet == NULL)
13727
0
    return (-1);
13728
23
      completeWild->negNsSet->value = NULL;
13729
23
  }
13730
23
  return (0);
13731
23
    }
13732
3
    return (0);
13733
13734
38
}
13735
13736
/**
13737
 * xmlSchemaIntersectWildcards:
13738
 * @ctxt:  the schema parser context
13739
 * @completeWild:  the first wildcard
13740
 * @curWild: the second wildcard
13741
 *
13742
 * Intersects the namespace constraints of the given wildcards.
13743
 * @completeWild will hold the resulting intersection.
13744
 * Returns a positive error code on failure, -1 in case of an
13745
 * internal error, 0 otherwise.
13746
 */
13747
static int
13748
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13749
          xmlSchemaWildcardPtr completeWild,
13750
          xmlSchemaWildcardPtr curWild)
13751
351
{
13752
351
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13753
13754
    /*
13755
    * 1 If O1 and O2 are the same value, then that value must be the
13756
    * value.
13757
    */
13758
351
    if ((completeWild->any == curWild->any) &&
13759
351
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13760
351
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13761
13762
202
  if ((completeWild->negNsSet == NULL) ||
13763
202
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13764
13765
201
      if (completeWild->nsSet != NULL) {
13766
127
    int found = 0;
13767
13768
    /*
13769
    * Check equality of sets.
13770
    */
13771
127
    cur = completeWild->nsSet;
13772
337
    while (cur != NULL) {
13773
257
        found = 0;
13774
257
        curB = curWild->nsSet;
13775
1.05k
        while (curB != NULL) {
13776
1.00k
      if (cur->value == curB->value) {
13777
210
          found = 1;
13778
210
          break;
13779
210
      }
13780
794
      curB = curB->next;
13781
794
        }
13782
257
        if (!found)
13783
47
      break;
13784
210
        cur = cur->next;
13785
210
    }
13786
127
    if (found)
13787
80
        return(0);
13788
127
      } else
13789
74
    return(0);
13790
201
  }
13791
202
    }
13792
    /*
13793
    * 2 If either O1 or O2 is any, then the other must be the value.
13794
    */
13795
197
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
13796
19
  if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13797
0
      return(-1);
13798
19
  return(0);
13799
19
    }
13800
    /*
13801
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
13802
    * name or `absent`) and the other is a set of (namespace names or
13803
    * `absent`), then that set, minus the negated value if it was in
13804
    * the set, minus `absent` if it was in the set, must be the value.
13805
    */
13806
178
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13807
178
  ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13808
11
  const xmlChar *neg;
13809
13810
11
  if (completeWild->nsSet == NULL) {
13811
8
      neg = completeWild->negNsSet->value;
13812
8
      if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13813
0
    return(-1);
13814
8
  } else
13815
3
      neg = curWild->negNsSet->value;
13816
  /*
13817
  * Remove absent and negated.
13818
  */
13819
11
  prev = NULL;
13820
11
  cur = completeWild->nsSet;
13821
44
  while (cur != NULL) {
13822
35
      if (cur->value == NULL) {
13823
2
    if (prev == NULL)
13824
2
        completeWild->nsSet = cur->next;
13825
0
    else
13826
0
        prev->next = cur->next;
13827
2
    xmlFree(cur);
13828
2
    break;
13829
2
      }
13830
33
      prev = cur;
13831
33
      cur = cur->next;
13832
33
  }
13833
11
  if (neg != NULL) {
13834
8
      prev = NULL;
13835
8
      cur = completeWild->nsSet;
13836
39
      while (cur != NULL) {
13837
33
    if (cur->value == neg) {
13838
2
        if (prev == NULL)
13839
1
      completeWild->nsSet = cur->next;
13840
1
        else
13841
1
      prev->next = cur->next;
13842
2
        xmlFree(cur);
13843
2
        break;
13844
2
    }
13845
31
    prev = cur;
13846
31
    cur = cur->next;
13847
31
      }
13848
8
  }
13849
13850
11
  return(0);
13851
11
    }
13852
    /*
13853
    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13854
    * then the intersection of those sets must be the value.
13855
    */
13856
167
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13857
47
  int found;
13858
13859
47
  cur = completeWild->nsSet;
13860
47
  prev = NULL;
13861
160
  while (cur != NULL) {
13862
113
      found = 0;
13863
113
      curB = curWild->nsSet;
13864
462
      while (curB != NULL) {
13865
378
    if (cur->value == curB->value) {
13866
29
        found = 1;
13867
29
        break;
13868
29
    }
13869
349
    curB = curB->next;
13870
349
      }
13871
113
      if (!found) {
13872
84
    if (prev == NULL)
13873
53
        completeWild->nsSet = cur->next;
13874
31
    else
13875
31
        prev->next = cur->next;
13876
84
    tmp = cur->next;
13877
84
    xmlFree(cur);
13878
84
    cur = tmp;
13879
84
    continue;
13880
84
      }
13881
29
      prev = cur;
13882
29
      cur = cur->next;
13883
29
  }
13884
13885
47
  return(0);
13886
47
    }
13887
    /* 5 If the two are negations of different namespace names,
13888
    * then the intersection is not expressible
13889
    */
13890
120
    if ((completeWild->negNsSet != NULL) &&
13891
120
  (curWild->negNsSet != NULL) &&
13892
120
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13893
120
  (completeWild->negNsSet->value != NULL) &&
13894
120
  (curWild->negNsSet->value != NULL)) {
13895
13896
0
  xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13897
0
      "The intersection of the wildcard is not expressible.\n",
13898
0
      NULL, NULL);
13899
0
  return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13900
0
    }
13901
    /*
13902
    * 6 If the one is a negation of a namespace name and the other
13903
    * is a negation of `absent`, then the one which is the negation
13904
    * of a namespace name must be the value.
13905
    */
13906
120
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13907
120
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13908
120
  (completeWild->negNsSet->value == NULL)) {
13909
0
  completeWild->negNsSet->value =  curWild->negNsSet->value;
13910
0
    }
13911
120
    return(0);
13912
120
}
13913
13914
/**
13915
 * xmlSchemaIsWildcardNsConstraintSubset:
13916
 * @ctxt:  the schema parser context
13917
 * @sub:  the first wildcard
13918
 * @super: the second wildcard
13919
 *
13920
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13921
 *
13922
 * Returns 0 if the namespace constraint of @sub is an intensional
13923
 * subset of @super, 1 otherwise.
13924
 */
13925
static int
13926
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13927
        xmlSchemaWildcardPtr super)
13928
11
{
13929
    /*
13930
    * 1 super must be any.
13931
    */
13932
11
    if (super->any)
13933
0
  return (0);
13934
    /*
13935
    * 2.1 sub must be a pair of not and a namespace name or `absent`.
13936
    * 2.2 super must be a pair of not and the same value.
13937
    */
13938
11
    if ((sub->negNsSet != NULL) &&
13939
11
  (super->negNsSet != NULL) &&
13940
11
  (sub->negNsSet->value == super->negNsSet->value))
13941
0
  return (0);
13942
    /*
13943
    * 3.1 sub must be a set whose members are either namespace names or `absent`.
13944
    */
13945
11
    if (sub->nsSet != NULL) {
13946
  /*
13947
  * 3.2.1 super must be the same set or a superset thereof.
13948
  */
13949
8
  if (super->nsSet != NULL) {
13950
8
      xmlSchemaWildcardNsPtr cur, curB;
13951
8
      int found = 0;
13952
13953
8
      cur = sub->nsSet;
13954
18
      while (cur != NULL) {
13955
18
    found = 0;
13956
18
    curB = super->nsSet;
13957
115
    while (curB != NULL) {
13958
107
        if (cur->value == curB->value) {
13959
10
      found = 1;
13960
10
      break;
13961
10
        }
13962
97
        curB = curB->next;
13963
97
    }
13964
18
    if (!found)
13965
8
        return (1);
13966
10
    cur = cur->next;
13967
10
      }
13968
0
      if (found)
13969
0
    return (0);
13970
0
  } else if (super->negNsSet != NULL) {
13971
0
      xmlSchemaWildcardNsPtr cur;
13972
      /*
13973
      * 3.2.2 super must be a pair of not and a namespace name or
13974
      * `absent` and that value must not be in sub's set.
13975
      */
13976
0
      cur = sub->nsSet;
13977
0
      while (cur != NULL) {
13978
0
    if (cur->value == super->negNsSet->value)
13979
0
        return (1);
13980
0
    cur = cur->next;
13981
0
      }
13982
0
      return (0);
13983
0
  }
13984
8
    }
13985
3
    return (1);
13986
11
}
13987
13988
static int
13989
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13990
             int *fixed,
13991
             const xmlChar **value,
13992
             xmlSchemaValPtr *val)
13993
100
{
13994
100
    *fixed = 0;
13995
100
    *value = NULL;
13996
100
    if (val != 0)
13997
0
  *val = NULL;
13998
13999
100
    if (attruse->defValue != NULL) {
14000
0
  *value = attruse->defValue;
14001
0
  if (val != NULL)
14002
0
      *val = attruse->defVal;
14003
0
  if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14004
0
      *fixed = 1;
14005
0
  return(1);
14006
100
    } else if ((attruse->attrDecl != NULL) &&
14007
100
  (attruse->attrDecl->defValue != NULL)) {
14008
0
  *value = attruse->attrDecl->defValue;
14009
0
  if (val != NULL)
14010
0
      *val = attruse->attrDecl->defVal;
14011
0
  if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14012
0
      *fixed = 1;
14013
0
  return(1);
14014
0
    }
14015
100
    return(0);
14016
100
}
14017
/**
14018
 * xmlSchemaCheckCVCWildcardNamespace:
14019
 * @wild:  the wildcard
14020
 * @ns:  the namespace
14021
 *
14022
 * Validation Rule: Wildcard allows Namespace Name
14023
 * (cvc-wildcard-namespace)
14024
 *
14025
 * Returns 0 if the given namespace matches the wildcard,
14026
 * 1 otherwise and -1 on API errors.
14027
 */
14028
static int
14029
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14030
           const xmlChar* ns)
14031
754
{
14032
754
    if (wild == NULL)
14033
0
  return(-1);
14034
14035
754
    if (wild->any)
14036
754
  return(0);
14037
0
    else if (wild->nsSet != NULL) {
14038
0
  xmlSchemaWildcardNsPtr cur;
14039
14040
0
  cur = wild->nsSet;
14041
0
  while (cur != NULL) {
14042
0
      if (xmlStrEqual(cur->value, ns))
14043
0
    return(0);
14044
0
      cur = cur->next;
14045
0
  }
14046
0
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14047
0
  (!xmlStrEqual(wild->negNsSet->value, ns)))
14048
0
  return(0);
14049
14050
0
    return(1);
14051
754
}
14052
14053
1.45k
#define XML_SCHEMA_ACTION_DERIVE 0
14054
0
#define XML_SCHEMA_ACTION_REDEFINE 1
14055
14056
132
#define WXS_ACTION_STR(a) \
14057
132
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14058
14059
/*
14060
* Schema Component Constraint:
14061
*   Derivation Valid (Restriction, Complex)
14062
*   derivation-ok-restriction (2) - (4)
14063
*
14064
* ATTENTION:
14065
* In XML Schema 1.1 this will be:
14066
* Validation Rule:
14067
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14068
*
14069
*/
14070
static int
14071
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14072
               int action,
14073
               xmlSchemaBasicItemPtr item,
14074
               xmlSchemaBasicItemPtr baseItem,
14075
               xmlSchemaItemListPtr uses,
14076
               xmlSchemaItemListPtr baseUses,
14077
               xmlSchemaWildcardPtr wild,
14078
               xmlSchemaWildcardPtr baseWild)
14079
1.31k
{
14080
1.31k
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
14081
1.31k
    int i, j, found; /* err = 0; */
14082
1.31k
    const xmlChar *bEffValue;
14083
1.31k
    int effFixed;
14084
14085
1.31k
    if (uses != NULL) {
14086
1.29k
  for (i = 0; i < uses->nbItems; i++) {
14087
961
      cur = uses->items[i];
14088
961
      found = 0;
14089
961
      if (baseUses == NULL)
14090
781
    goto not_found;
14091
588
      for (j = 0; j < baseUses->nbItems; j++) {
14092
514
    bcur = baseUses->items[j];
14093
514
    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14094
514
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14095
514
        (WXS_ATTRUSE_DECL_TNS(cur) ==
14096
107
      WXS_ATTRUSE_DECL_TNS(bcur)))
14097
106
    {
14098
        /*
14099
        * (2.1) "If there is an attribute use in the {attribute
14100
        * uses} of the {base type definition} (call this B) whose
14101
        * {attribute declaration} has the same {name} and {target
14102
        * namespace}, then  all of the following must be true:"
14103
        */
14104
106
        found = 1;
14105
14106
106
        if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14107
106
      (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14108
5
        {
14109
5
      xmlChar *str = NULL;
14110
      /*
14111
      * (2.1.1) "one of the following must be true:"
14112
      * (2.1.1.1) "B's {required} is false."
14113
      * (2.1.1.2) "R's {required} is true."
14114
      */
14115
5
      xmlSchemaPAttrUseErr4(pctxt,
14116
5
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14117
5
          WXS_ITEM_NODE(item), item, cur,
14118
5
          "The 'optional' attribute use is inconsistent "
14119
5
          "with the corresponding 'required' attribute use of "
14120
5
          "the %s %s",
14121
5
          WXS_ACTION_STR(action),
14122
5
          xmlSchemaGetComponentDesignation(&str, baseItem),
14123
5
          NULL, NULL);
14124
5
      FREE_AND_NULL(str);
14125
      /* err = pctxt->err; */
14126
101
        } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14127
101
      WXS_ATTRUSE_TYPEDEF(cur),
14128
101
      WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14129
1
        {
14130
1
      xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14131
14132
      /*
14133
      * SPEC (2.1.2) "R's {attribute declaration}'s
14134
      * {type definition} must be validly derived from
14135
      * B's {type definition} given the empty set as
14136
      * defined in Type Derivation OK (Simple) ($3.14.6)."
14137
      */
14138
1
      xmlSchemaPAttrUseErr4(pctxt,
14139
1
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14140
1
          WXS_ITEM_NODE(item), item, cur,
14141
1
          "The attribute declaration's %s "
14142
1
          "is not validly derived from "
14143
1
          "the corresponding %s of the "
14144
1
          "attribute declaration in the %s %s",
14145
1
          xmlSchemaGetComponentDesignation(&strA,
14146
1
        WXS_ATTRUSE_TYPEDEF(cur)),
14147
1
          xmlSchemaGetComponentDesignation(&strB,
14148
1
        WXS_ATTRUSE_TYPEDEF(bcur)),
14149
1
          WXS_ACTION_STR(action),
14150
1
          xmlSchemaGetComponentDesignation(&strC, baseItem));
14151
          /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14152
1
      FREE_AND_NULL(strA);
14153
1
      FREE_AND_NULL(strB);
14154
1
      FREE_AND_NULL(strC);
14155
      /* err = pctxt->err; */
14156
100
        } else {
14157
      /*
14158
      * 2.1.3 [Definition:]  Let the effective value
14159
      * constraint of an attribute use be its {value
14160
      * constraint}, if present, otherwise its {attribute
14161
      * declaration}'s {value constraint} .
14162
      */
14163
100
      xmlSchemaGetEffectiveValueConstraint(bcur,
14164
100
          &effFixed, &bEffValue, NULL);
14165
      /*
14166
      * 2.1.3 ... one of the following must be true
14167
      *
14168
      * 2.1.3.1 B's `effective value constraint` is
14169
      * `absent` or default.
14170
      */
14171
100
      if ((bEffValue != NULL) &&
14172
100
          (effFixed == 1)) {
14173
0
          const xmlChar *rEffValue = NULL;
14174
14175
0
          xmlSchemaGetEffectiveValueConstraint(bcur,
14176
0
        &effFixed, &rEffValue, NULL);
14177
          /*
14178
          * 2.1.3.2 R's `effective value constraint` is
14179
          * fixed with the same string as B's.
14180
          * MAYBE TODO: Compare the computed values.
14181
          *       Hmm, it says "same string" so
14182
          *       string-equality might really be sufficient.
14183
          */
14184
0
          if ((effFixed == 0) ||
14185
0
        (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14186
0
          {
14187
0
        xmlChar *str = NULL;
14188
14189
0
        xmlSchemaPAttrUseErr4(pctxt,
14190
0
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14191
0
            WXS_ITEM_NODE(item), item, cur,
14192
0
            "The effective value constraint of the "
14193
0
            "attribute use is inconsistent with "
14194
0
            "its correspondent in the %s %s",
14195
0
            WXS_ACTION_STR(action),
14196
0
            xmlSchemaGetComponentDesignation(&str,
14197
0
          baseItem),
14198
0
            NULL, NULL);
14199
0
        FREE_AND_NULL(str);
14200
        /* err = pctxt->err; */
14201
0
          }
14202
0
      }
14203
100
        }
14204
106
        break;
14205
106
    }
14206
514
      }
14207
961
not_found:
14208
961
      if (!found) {
14209
    /*
14210
    * (2.2) "otherwise the {base type definition} must have an
14211
    * {attribute wildcard} and the {target namespace} of the
14212
    * R's {attribute declaration} must be `valid` with respect
14213
    * to that wildcard, as defined in Wildcard allows Namespace
14214
    * Name ($3.10.4)."
14215
    */
14216
855
    if ((baseWild == NULL) ||
14217
855
        (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14218
754
        (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14219
101
    {
14220
101
        xmlChar *str = NULL;
14221
14222
101
        xmlSchemaPAttrUseErr4(pctxt,
14223
101
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14224
101
      WXS_ITEM_NODE(item), item, cur,
14225
101
      "Neither a matching attribute use, "
14226
101
      "nor a matching wildcard exists in the %s %s",
14227
101
      WXS_ACTION_STR(action),
14228
101
      xmlSchemaGetComponentDesignation(&str, baseItem),
14229
101
      NULL, NULL);
14230
101
        FREE_AND_NULL(str);
14231
        /* err = pctxt->err; */
14232
101
    }
14233
855
      }
14234
961
  }
14235
335
    }
14236
    /*
14237
    * SPEC derivation-ok-restriction (3):
14238
    * (3) "For each attribute use in the {attribute uses} of the {base type
14239
    * definition} whose {required} is true, there must be an attribute
14240
    * use with an {attribute declaration} with the same {name} and
14241
    * {target namespace} as its {attribute declaration} in the {attribute
14242
    * uses} of the complex type definition itself whose {required} is true.
14243
    */
14244
1.31k
    if (baseUses != NULL) {
14245
160
  for (j = 0; j < baseUses->nbItems; j++) {
14246
117
      bcur = baseUses->items[j];
14247
117
      if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14248
74
    continue;
14249
43
      found = 0;
14250
43
      if (uses != NULL) {
14251
230
    for (i = 0; i < uses->nbItems; i++) {
14252
227
        cur = uses->items[i];
14253
227
        if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14254
227
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14255
227
      (WXS_ATTRUSE_DECL_TNS(cur) ==
14256
40
      WXS_ATTRUSE_DECL_TNS(bcur))) {
14257
40
      found = 1;
14258
40
      break;
14259
40
        }
14260
227
    }
14261
43
      }
14262
43
      if (!found) {
14263
3
    xmlChar *strA = NULL, *strB = NULL;
14264
14265
3
    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14266
3
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14267
3
        NULL, item,
14268
3
        "A matching attribute use for the "
14269
3
        "'required' %s of the %s %s is missing",
14270
3
        xmlSchemaGetComponentDesignation(&strA, bcur),
14271
3
        WXS_ACTION_STR(action),
14272
3
        xmlSchemaGetComponentDesignation(&strB, baseItem),
14273
3
        NULL);
14274
3
    FREE_AND_NULL(strA);
14275
3
    FREE_AND_NULL(strB);
14276
3
      }
14277
43
  }
14278
43
    }
14279
    /*
14280
    * derivation-ok-restriction (4)
14281
    */
14282
1.31k
    if (wild != NULL) {
14283
  /*
14284
  * (4) "If there is an {attribute wildcard}, all of the
14285
  * following must be true:"
14286
  */
14287
386
  if (baseWild == NULL) {
14288
10
      xmlChar *str = NULL;
14289
14290
      /*
14291
      * (4.1) "The {base type definition} must also have one."
14292
      */
14293
10
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14294
10
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14295
10
    NULL, item,
14296
10
    "The %s has an attribute wildcard, "
14297
10
    "but the %s %s '%s' does not have one",
14298
10
    WXS_ITEM_TYPE_NAME(item),
14299
10
    WXS_ACTION_STR(action),
14300
10
    WXS_ITEM_TYPE_NAME(baseItem),
14301
10
    xmlSchemaGetComponentQName(&str, baseItem));
14302
10
      FREE_AND_NULL(str);
14303
10
      return(pctxt->err);
14304
376
  } else if ((baseWild->any == 0) &&
14305
376
    xmlSchemaCheckCOSNSSubset(wild, baseWild))
14306
11
  {
14307
11
      xmlChar *str = NULL;
14308
      /*
14309
      * (4.2) "The complex type definition's {attribute wildcard}'s
14310
      * {namespace constraint} must be a subset of the {base type
14311
      * definition}'s {attribute wildcard}'s {namespace constraint},
14312
      * as defined by Wildcard Subset ($3.10.6)."
14313
      */
14314
11
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14315
11
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14316
11
    NULL, item,
14317
11
    "The attribute wildcard is not a valid "
14318
11
    "subset of the wildcard in the %s %s '%s'",
14319
11
    WXS_ACTION_STR(action),
14320
11
    WXS_ITEM_TYPE_NAME(baseItem),
14321
11
    xmlSchemaGetComponentQName(&str, baseItem),
14322
11
    NULL);
14323
11
      FREE_AND_NULL(str);
14324
11
      return(pctxt->err);
14325
11
  }
14326
  /* 4.3 Unless the {base type definition} is the `ur-type
14327
  * definition`, the complex type definition's {attribute
14328
  * wildcard}'s {process contents} must be identical to or
14329
  * stronger than the {base type definition}'s {attribute
14330
  * wildcard}'s {process contents}, where strict is stronger
14331
  * than lax is stronger than skip.
14332
  */
14333
365
  if ((! WXS_IS_ANYTYPE(baseItem)) &&
14334
365
      (wild->processContents < baseWild->processContents)) {
14335
1
      xmlChar *str = NULL;
14336
1
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14337
1
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14338
1
    NULL, baseItem,
14339
1
    "The {process contents} of the attribute wildcard is "
14340
1
    "weaker than the one in the %s %s '%s'",
14341
1
    WXS_ACTION_STR(action),
14342
1
    WXS_ITEM_TYPE_NAME(baseItem),
14343
1
    xmlSchemaGetComponentQName(&str, baseItem),
14344
1
    NULL);
14345
1
      FREE_AND_NULL(str)
14346
1
    return(pctxt->err);
14347
1
  }
14348
365
    }
14349
1.29k
    return(0);
14350
1.31k
}
14351
14352
14353
static int
14354
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14355
          xmlSchemaBasicItemPtr item,
14356
          xmlSchemaWildcardPtr *completeWild,
14357
          xmlSchemaItemListPtr list,
14358
          xmlSchemaItemListPtr prohibs);
14359
/**
14360
 * xmlSchemaFixupTypeAttributeUses:
14361
 * @ctxt:  the schema parser context
14362
 * @type:  the complex type definition
14363
 *
14364
 *
14365
 * Builds the wildcard and the attribute uses on the given complex type.
14366
 * Returns -1 if an internal error occurs, 0 otherwise.
14367
 *
14368
 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14369
 * strings, so recheck this if we start to hardcode some schemata, since
14370
 * they might not be in the same dict.
14371
 * NOTE: It is allowed to "extend" the xs:anyType type.
14372
 */
14373
static int
14374
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14375
          xmlSchemaTypePtr type)
14376
1.60k
{
14377
1.60k
    xmlSchemaTypePtr baseType = NULL;
14378
1.60k
    xmlSchemaAttributeUsePtr use;
14379
1.60k
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14380
14381
1.60k
    if (type->baseType == NULL) {
14382
0
  PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14383
0
      "no base type");
14384
0
        return (-1);
14385
0
    }
14386
1.60k
    baseType = type->baseType;
14387
1.60k
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14388
0
  if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14389
0
      return(-1);
14390
14391
1.60k
    uses = type->attrUses;
14392
1.60k
    baseUses = baseType->attrUses;
14393
    /*
14394
    * Expand attribute group references. And build the 'complete'
14395
    * wildcard, i.e. intersect multiple wildcards.
14396
    * Move attribute prohibitions into a separate list.
14397
    */
14398
1.60k
    if (uses != NULL) {
14399
555
  if (WXS_IS_RESTRICTION(type)) {
14400
      /*
14401
      * This one will transfer all attr. prohibitions
14402
      * into pctxt->attrProhibs.
14403
      */
14404
488
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14405
488
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14406
488
    pctxt->attrProhibs) == -1)
14407
0
      {
14408
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14409
0
    "failed to expand attributes");
14410
0
                return(-1);
14411
0
      }
14412
488
      if (pctxt->attrProhibs->nbItems != 0)
14413
76
    prohibs = pctxt->attrProhibs;
14414
488
  } else {
14415
67
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14416
67
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14417
67
    NULL) == -1)
14418
0
      {
14419
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14420
0
    "failed to expand attributes");
14421
0
                return(-1);
14422
0
      }
14423
67
  }
14424
555
    }
14425
    /*
14426
    * Inherit the attribute uses of the base type.
14427
    */
14428
1.60k
    if (baseUses != NULL) {
14429
53
  int i, j;
14430
53
  xmlSchemaAttributeUseProhibPtr pro;
14431
14432
53
  if (WXS_IS_RESTRICTION(type)) {
14433
43
      int usesCount;
14434
43
      xmlSchemaAttributeUsePtr tmp;
14435
14436
43
      if (uses != NULL)
14437
40
    usesCount = uses->nbItems;
14438
3
      else
14439
3
    usesCount = 0;
14440
14441
      /* Restriction. */
14442
160
      for (i = 0; i < baseUses->nbItems; i++) {
14443
117
    use = baseUses->items[i];
14444
117
    if (prohibs) {
14445
        /*
14446
        * Filter out prohibited uses.
14447
        */
14448
230
        for (j = 0; j < prohibs->nbItems; j++) {
14449
162
      pro = prohibs->items[j];
14450
162
      if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14451
162
          (WXS_ATTRUSE_DECL_TNS(use) ==
14452
11
        pro->targetNamespace))
14453
11
      {
14454
11
          goto inherit_next;
14455
11
      }
14456
162
        }
14457
79
    }
14458
106
    if (usesCount) {
14459
        /*
14460
        * Filter out existing uses.
14461
        */
14462
324
        for (j = 0; j < usesCount; j++) {
14463
260
      tmp = uses->items[j];
14464
260
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
14465
260
        WXS_ATTRUSE_DECL_NAME(tmp)) &&
14466
260
          (WXS_ATTRUSE_DECL_TNS(use) ==
14467
40
        WXS_ATTRUSE_DECL_TNS(tmp)))
14468
39
      {
14469
39
          goto inherit_next;
14470
39
      }
14471
260
        }
14472
103
    }
14473
67
    if (uses == NULL) {
14474
3
        type->attrUses = xmlSchemaItemListCreate();
14475
3
        if (type->attrUses == NULL)
14476
0
      goto exit_failure;
14477
3
        uses = type->attrUses;
14478
3
    }
14479
67
    xmlSchemaItemListAddSize(uses, 2, use);
14480
117
inherit_next: {}
14481
117
      }
14482
43
  } else {
14483
      /* Extension. */
14484
21
      for (i = 0; i < baseUses->nbItems; i++) {
14485
11
    use = baseUses->items[i];
14486
11
    if (uses == NULL) {
14487
3
        type->attrUses = xmlSchemaItemListCreate();
14488
3
        if (type->attrUses == NULL)
14489
0
      goto exit_failure;
14490
3
        uses = type->attrUses;
14491
3
    }
14492
11
    xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14493
11
      }
14494
10
  }
14495
53
    }
14496
    /*
14497
    * Shrink attr. uses.
14498
    */
14499
1.60k
    if (uses) {
14500
561
  if (uses->nbItems == 0) {
14501
156
      xmlSchemaItemListFree(uses);
14502
156
      type->attrUses = NULL;
14503
156
  }
14504
  /*
14505
  * TODO: We could shrink the size of the array
14506
  * to fit the actual number of items.
14507
  */
14508
561
    }
14509
    /*
14510
    * Compute the complete wildcard.
14511
    */
14512
1.60k
    if (WXS_IS_EXTENSION(type)) {
14513
290
  if (baseType->attributeWildcard != NULL) {
14514
      /*
14515
      * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14516
      * the appropriate case among the following:"
14517
      */
14518
210
      if (type->attributeWildcard != NULL) {
14519
    /*
14520
    * Union the complete wildcard with the base wildcard.
14521
    * SPEC {attribute wildcard}
14522
    * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14523
    * and {annotation} are those of the `complete wildcard`,
14524
    * and whose {namespace constraint} is the intensional union
14525
    * of the {namespace constraint} of the `complete wildcard`
14526
    * and of the `base wildcard`, as defined in Attribute
14527
    * Wildcard Union ($3.10.6)."
14528
    */
14529
203
    if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14530
203
        baseType->attributeWildcard) == -1)
14531
0
        goto exit_failure;
14532
203
      } else {
14533
    /*
14534
    * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14535
    * then the `base wildcard`."
14536
    */
14537
7
    type->attributeWildcard = baseType->attributeWildcard;
14538
7
      }
14539
210
  } else {
14540
      /*
14541
      * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14542
      * `complete wildcard`"
14543
      * NOOP
14544
      */
14545
80
  }
14546
1.31k
    } else {
14547
  /*
14548
  * SPEC {attribute wildcard}
14549
  * (3.1) "If the <restriction> alternative is chosen, then the
14550
  * `complete wildcard`;"
14551
  * NOOP
14552
  */
14553
1.31k
    }
14554
14555
1.60k
    return (0);
14556
14557
0
exit_failure:
14558
0
    return(-1);
14559
1.60k
}
14560
14561
/**
14562
 * xmlSchemaTypeFinalContains:
14563
 * @schema:  the schema
14564
 * @type:  the type definition
14565
 * @final: the final
14566
 *
14567
 * Evaluates if a type definition contains the given "final".
14568
 * This does take "finalDefault" into account as well.
14569
 *
14570
 * Returns 1 if the type does contain the given "final",
14571
 * 0 otherwise.
14572
 */
14573
static int
14574
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14575
17.9k
{
14576
17.9k
    if (type == NULL)
14577
0
  return (0);
14578
17.9k
    if (type->flags & final)
14579
0
  return (1);
14580
17.9k
    else
14581
17.9k
  return (0);
14582
17.9k
}
14583
14584
/**
14585
 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14586
 * @type:  the Union Simple Type
14587
 *
14588
 * Returns a list of member types of @type if existing,
14589
 * returns NULL otherwise.
14590
 */
14591
static xmlSchemaTypeLinkPtr
14592
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14593
330
{
14594
330
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14595
330
  if (type->memberTypes != NULL)
14596
330
      return (type->memberTypes);
14597
0
  else
14598
0
      type = type->baseType;
14599
330
    }
14600
0
    return (NULL);
14601
330
}
14602
14603
#if 0
14604
/**
14605
 * xmlSchemaGetParticleTotalRangeMin:
14606
 * @particle: the particle
14607
 *
14608
 * Schema Component Constraint: Effective Total Range
14609
 * (all and sequence) + (choice)
14610
 *
14611
 * Returns the minimum Effective Total Range.
14612
 */
14613
static int
14614
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14615
{
14616
    if ((particle->children == NULL) ||
14617
  (particle->minOccurs == 0))
14618
  return (0);
14619
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14620
  int min = -1, cur;
14621
  xmlSchemaParticlePtr part =
14622
      (xmlSchemaParticlePtr) particle->children->children;
14623
14624
  if (part == NULL)
14625
      return (0);
14626
  while (part != NULL) {
14627
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14628
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14629
    cur = part->minOccurs;
14630
      else
14631
    cur = xmlSchemaGetParticleTotalRangeMin(part);
14632
      if (cur == 0)
14633
    return (0);
14634
      if ((min > cur) || (min == -1))
14635
    min = cur;
14636
      part = (xmlSchemaParticlePtr) part->next;
14637
  }
14638
  return (particle->minOccurs * min);
14639
    } else {
14640
  /* <all> and <sequence> */
14641
  int sum = 0;
14642
  xmlSchemaParticlePtr part =
14643
      (xmlSchemaParticlePtr) particle->children->children;
14644
14645
  if (part == NULL)
14646
      return (0);
14647
  do {
14648
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14649
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14650
    sum += part->minOccurs;
14651
      else
14652
    sum += xmlSchemaGetParticleTotalRangeMin(part);
14653
      part = (xmlSchemaParticlePtr) part->next;
14654
  } while (part != NULL);
14655
  return (particle->minOccurs * sum);
14656
    }
14657
}
14658
14659
/**
14660
 * xmlSchemaGetParticleTotalRangeMax:
14661
 * @particle: the particle
14662
 *
14663
 * Schema Component Constraint: Effective Total Range
14664
 * (all and sequence) + (choice)
14665
 *
14666
 * Returns the maximum Effective Total Range.
14667
 */
14668
static int
14669
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14670
{
14671
    if ((particle->children == NULL) ||
14672
  (particle->children->children == NULL))
14673
  return (0);
14674
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14675
  int max = -1, cur;
14676
  xmlSchemaParticlePtr part =
14677
      (xmlSchemaParticlePtr) particle->children->children;
14678
14679
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14680
      if (part->children == NULL)
14681
    continue;
14682
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14683
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14684
    cur = part->maxOccurs;
14685
      else
14686
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14687
      if (cur == UNBOUNDED)
14688
    return (UNBOUNDED);
14689
      if ((max < cur) || (max == -1))
14690
    max = cur;
14691
  }
14692
  /* TODO: Handle overflows? */
14693
  return (particle->maxOccurs * max);
14694
    } else {
14695
  /* <all> and <sequence> */
14696
  int sum = 0, cur;
14697
  xmlSchemaParticlePtr part =
14698
      (xmlSchemaParticlePtr) particle->children->children;
14699
14700
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14701
      if (part->children == NULL)
14702
    continue;
14703
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14704
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14705
    cur = part->maxOccurs;
14706
      else
14707
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14708
      if (cur == UNBOUNDED)
14709
    return (UNBOUNDED);
14710
      if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14711
    return (UNBOUNDED);
14712
      sum += cur;
14713
  }
14714
  /* TODO: Handle overflows? */
14715
  return (particle->maxOccurs * sum);
14716
    }
14717
}
14718
#endif
14719
14720
/**
14721
 * xmlSchemaGetParticleEmptiable:
14722
 * @particle: the particle
14723
 *
14724
 * Returns 1 if emptiable, 0 otherwise.
14725
 */
14726
static int
14727
xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14728
49
{
14729
49
    xmlSchemaParticlePtr part;
14730
49
    int emptiable;
14731
14732
49
    if ((particle->children == NULL) || (particle->minOccurs == 0))
14733
0
  return (1);
14734
14735
49
    part = (xmlSchemaParticlePtr) particle->children->children;
14736
49
    if (part == NULL)
14737
0
        return (1);
14738
14739
90
    while (part != NULL) {
14740
49
        if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14741
49
            (part->children->type == XML_SCHEMA_TYPE_ANY))
14742
49
            emptiable = (part->minOccurs == 0);
14743
0
        else
14744
0
            emptiable = xmlSchemaGetParticleEmptiable(part);
14745
49
        if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14746
0
            if (emptiable)
14747
0
                return (1);
14748
49
        } else {
14749
      /* <all> and <sequence> */
14750
49
            if (!emptiable)
14751
8
                return (0);
14752
49
        }
14753
41
        part = (xmlSchemaParticlePtr) part->next;
14754
41
    }
14755
14756
41
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14757
0
        return (0);
14758
41
    else
14759
41
        return (1);
14760
41
}
14761
14762
/**
14763
 * xmlSchemaIsParticleEmptiable:
14764
 * @particle: the particle
14765
 *
14766
 * Schema Component Constraint: Particle Emptiable
14767
 * Checks whether the given particle is emptiable.
14768
 *
14769
 * Returns 1 if emptiable, 0 otherwise.
14770
 */
14771
static int
14772
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14773
49
{
14774
    /*
14775
    * SPEC (1) "Its {min occurs} is 0."
14776
    */
14777
49
    if ((particle == NULL) || (particle->minOccurs == 0) ||
14778
49
  (particle->children == NULL))
14779
0
  return (1);
14780
    /*
14781
    * SPEC (2) "Its {term} is a group and the minimum part of the
14782
    * effective total range of that group, [...] is 0."
14783
    */
14784
49
    if (WXS_IS_MODEL_GROUP(particle->children))
14785
49
  return (xmlSchemaGetParticleEmptiable(particle));
14786
0
    return (0);
14787
49
}
14788
14789
/**
14790
 * xmlSchemaCheckCOSSTDerivedOK:
14791
 * @actxt: a context
14792
 * @type:  the derived simple type definition
14793
 * @baseType:  the base type definition
14794
 * @subset: the subset of ('restriction', etc.)
14795
 *
14796
 * Schema Component Constraint:
14797
 * Type Derivation OK (Simple) (cos-st-derived-OK)
14798
 *
14799
 * Checks whether @type can be validly
14800
 * derived from @baseType.
14801
 *
14802
 * Returns 0 on success, an positive error code otherwise.
14803
 */
14804
static int
14805
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14806
           xmlSchemaTypePtr type,
14807
           xmlSchemaTypePtr baseType,
14808
           int subset)
14809
115
{
14810
    /*
14811
    * 1 They are the same type definition.
14812
    * TODO: The identity check might have to be more complex than this.
14813
    */
14814
115
    if (type == baseType)
14815
96
  return (0);
14816
    /*
14817
    * 2.1 restriction is not in the subset, or in the {final}
14818
    * of its own {base type definition};
14819
    *
14820
    * NOTE that this will be used also via "xsi:type".
14821
    *
14822
    * TODO: Revise this, it looks strange. How can the "type"
14823
    * not be fixed or *in* fixing?
14824
    */
14825
19
    if (WXS_IS_TYPE_NOT_FIXED(type))
14826
0
  if (xmlSchemaTypeFixup(type, actxt) == -1)
14827
0
      return(-1);
14828
19
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14829
0
  if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14830
0
      return(-1);
14831
19
    if ((subset & SUBSET_RESTRICTION) ||
14832
19
  (xmlSchemaTypeFinalContains(type->baseType,
14833
19
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14834
0
  return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14835
0
    }
14836
    /* 2.2 */
14837
19
    if (type->baseType == baseType) {
14838
  /*
14839
  * 2.2.1 D's `base type definition` is B.
14840
  */
14841
9
  return (0);
14842
9
    }
14843
    /*
14844
    * 2.2.2 D's `base type definition` is not the `ur-type definition`
14845
    * and is validly derived from B given the subset, as defined by this
14846
    * constraint.
14847
    */
14848
10
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14849
10
  (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14850
8
      baseType, subset) == 0)) {
14851
6
  return (0);
14852
6
    }
14853
    /*
14854
    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14855
    * definition`.
14856
    */
14857
4
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14858
4
  (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14859
0
  return (0);
14860
0
    }
14861
    /*
14862
    * 2.2.4 B's {variety} is union and D is validly derived from a type
14863
    * definition in B's {member type definitions} given the subset, as
14864
    * defined by this constraint.
14865
    *
14866
    * NOTE: This seems not to involve built-in types, since there is no
14867
    * built-in Union Simple Type.
14868
    */
14869
4
    if (WXS_IS_UNION(baseType)) {
14870
0
  xmlSchemaTypeLinkPtr cur;
14871
14872
0
  cur = baseType->memberTypes;
14873
0
  while (cur != NULL) {
14874
0
      if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14875
0
    if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14876
0
        return(-1);
14877
0
      if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14878
0
        type, cur->type, subset) == 0)
14879
0
      {
14880
    /*
14881
    * It just has to be validly derived from at least one
14882
    * member-type.
14883
    */
14884
0
    return (0);
14885
0
      }
14886
0
      cur = cur->next;
14887
0
  }
14888
0
    }
14889
4
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14890
4
}
14891
14892
/**
14893
 * xmlSchemaCheckTypeDefCircularInternal:
14894
 * @pctxt:  the schema parser context
14895
 * @ctxtType:  the type definition
14896
 * @ancestor: an ancestor of @ctxtType
14897
 *
14898
 * Checks st-props-correct (2) + ct-props-correct (3).
14899
 * Circular type definitions are not allowed.
14900
 *
14901
 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14902
 * circular, 0 otherwise.
14903
 */
14904
static int
14905
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14906
         xmlSchemaTypePtr ctxtType,
14907
         xmlSchemaTypePtr ancestor)
14908
12.0k
{
14909
12.0k
    int ret;
14910
14911
12.0k
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14912
10.4k
  return (0);
14913
14914
1.55k
    if (ctxtType == ancestor) {
14915
2
  xmlSchemaPCustomErr(pctxt,
14916
2
      XML_SCHEMAP_ST_PROPS_CORRECT_2,
14917
2
      WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14918
2
      "The definition is circular", NULL);
14919
2
  return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14920
2
    }
14921
1.55k
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14922
  /*
14923
  * Avoid infinite recursion on circular types not yet checked.
14924
  */
14925
0
  return (0);
14926
0
    }
14927
1.55k
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14928
1.55k
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14929
1.55k
  ancestor->baseType);
14930
1.55k
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14931
1.55k
    return (ret);
14932
1.55k
}
14933
14934
/**
14935
 * xmlSchemaCheckTypeDefCircular:
14936
 * @item:  the complex/simple type definition
14937
 * @ctxt:  the parser context
14938
 * @name:  the name
14939
 *
14940
 * Checks for circular type definitions.
14941
 */
14942
static void
14943
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14944
            xmlSchemaParserCtxtPtr ctxt)
14945
10.4k
{
14946
10.4k
    if ((item == NULL) ||
14947
10.4k
  (item->type == XML_SCHEMA_TYPE_BASIC) ||
14948
10.4k
  (item->baseType == NULL))
14949
0
  return;
14950
10.4k
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14951
10.4k
  item->baseType);
14952
10.4k
}
14953
14954
/*
14955
* Simple Type Definition Representation OK (src-simple-type) 4
14956
*
14957
* "4 Circular union type definition is disallowed. That is, if the
14958
* <union> alternative is chosen, there must not be any entries in the
14959
* memberTypes [attribute] at any depth which resolve to the component
14960
* corresponding to the <simpleType>."
14961
*
14962
* Note that this should work on the *representation* of a component,
14963
* thus assumes any union types in the member types not being yet
14964
* substituted. At this stage we need the variety of the types
14965
* to be already computed.
14966
*/
14967
static int
14968
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14969
          xmlSchemaTypePtr ctxType,
14970
          xmlSchemaTypeLinkPtr members)
14971
405
{
14972
405
    xmlSchemaTypeLinkPtr member;
14973
405
    xmlSchemaTypePtr memberType;
14974
14975
405
    member = members;
14976
1.29k
    while (member != NULL) {
14977
888
  memberType = member->type;
14978
1.18k
  while ((memberType != NULL) &&
14979
1.18k
      (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14980
292
      if (memberType == ctxType) {
14981
0
    xmlSchemaPCustomErr(pctxt,
14982
0
        XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14983
0
        WXS_BASIC_CAST ctxType, NULL,
14984
0
        "The union type definition is circular", NULL);
14985
0
    return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14986
0
      }
14987
292
      if ((WXS_IS_UNION(memberType)) &&
14988
292
    ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14989
91
      {
14990
91
    int res;
14991
91
    memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14992
91
    res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14993
91
        ctxType,
14994
91
        xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14995
91
    memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14996
91
    if (res != 0)
14997
0
        return(res);
14998
91
      }
14999
292
      memberType = memberType->baseType;
15000
292
  }
15001
888
  member = member->next;
15002
888
    }
15003
405
    return(0);
15004
405
}
15005
15006
static int
15007
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15008
           xmlSchemaTypePtr type)
15009
314
{
15010
314
    if (! WXS_IS_UNION(type))
15011
0
  return(0);
15012
314
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15013
314
  type->memberTypes));
15014
314
}
15015
15016
/**
15017
 * xmlSchemaResolveTypeReferences:
15018
 * @item:  the complex/simple type definition
15019
 * @ctxt:  the parser context
15020
 * @name:  the name
15021
 *
15022
 * Resolves type definition references
15023
 */
15024
static void
15025
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15026
       xmlSchemaParserCtxtPtr ctxt)
15027
12.8k
{
15028
12.8k
    if (typeDef == NULL)
15029
0
  return;
15030
15031
    /*
15032
    * Resolve the base type.
15033
    */
15034
12.8k
    if (typeDef->baseType == NULL) {
15035
8.92k
  typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15036
8.92k
      typeDef->base, typeDef->baseNs);
15037
8.92k
  if (typeDef->baseType == NULL) {
15038
263
      xmlSchemaPResCompAttrErr(ctxt,
15039
263
    XML_SCHEMAP_SRC_RESOLVE,
15040
263
    WXS_BASIC_CAST typeDef, typeDef->node,
15041
263
    "base", typeDef->base, typeDef->baseNs,
15042
263
    XML_SCHEMA_TYPE_SIMPLE, NULL);
15043
263
      return;
15044
263
  }
15045
8.92k
    }
15046
12.5k
    if (WXS_IS_SIMPLE(typeDef)) {
15047
9.64k
  if (WXS_IS_UNION(typeDef)) {
15048
      /*
15049
      * Resolve the memberTypes.
15050
      */
15051
909
      xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15052
909
      return;
15053
8.73k
  } else if (WXS_IS_LIST(typeDef)) {
15054
      /*
15055
      * Resolve the itemType.
15056
      */
15057
82
      if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15058
15059
12
    typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15060
12
        typeDef->base, typeDef->baseNs);
15061
15062
12
    if ((typeDef->subtypes == NULL) ||
15063
12
        (! WXS_IS_SIMPLE(typeDef->subtypes)))
15064
1
    {
15065
1
        typeDef->subtypes = NULL;
15066
1
        xmlSchemaPResCompAttrErr(ctxt,
15067
1
      XML_SCHEMAP_SRC_RESOLVE,
15068
1
      WXS_BASIC_CAST typeDef, typeDef->node,
15069
1
      "itemType", typeDef->base, typeDef->baseNs,
15070
1
      XML_SCHEMA_TYPE_SIMPLE, NULL);
15071
1
    }
15072
12
      }
15073
82
      return;
15074
82
  }
15075
9.64k
    }
15076
    /*
15077
    * The ball of letters below means, that if we have a particle
15078
    * which has a QName-helper component as its {term}, we want
15079
    * to resolve it...
15080
    */
15081
2.92k
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15082
2.92k
  ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15083
932
      XML_SCHEMA_TYPE_PARTICLE) &&
15084
2.92k
  (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15085
2.92k
  ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15086
932
      XML_SCHEMA_EXTRA_QNAMEREF))
15087
50
    {
15088
50
  xmlSchemaQNameRefPtr ref =
15089
50
      WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15090
50
  xmlSchemaModelGroupDefPtr groupDef;
15091
15092
  /*
15093
  * URGENT TODO: Test this.
15094
  */
15095
50
  WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15096
  /*
15097
  * Resolve the MG definition reference.
15098
  */
15099
50
  groupDef =
15100
50
      WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15101
50
    ref->itemType, ref->name, ref->targetNamespace);
15102
50
  if (groupDef == NULL) {
15103
29
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15104
29
    NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15105
29
    "ref", ref->name, ref->targetNamespace, ref->itemType,
15106
29
    NULL);
15107
      /* Remove the particle. */
15108
29
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15109
29
  } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15110
      /* Remove the particle. */
15111
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15112
21
  else {
15113
      /*
15114
      * Assign the MG definition's {model group} to the
15115
      * particle's {term}.
15116
      */
15117
21
      WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15118
15119
21
      if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15120
    /*
15121
    * SPEC cos-all-limited (1.2)
15122
    * "1.2 the {term} property of a particle with
15123
    * {max occurs}=1 which is part of a pair which constitutes
15124
    * the {content type} of a complex type definition."
15125
    */
15126
0
    if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15127
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
15128
      /* TODO: error code */
15129
0
      XML_SCHEMAP_COS_ALL_LIMITED,
15130
0
      WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15131
0
      "The particle's {max occurs} must be 1, since the "
15132
0
      "reference resolves to an 'all' model group",
15133
0
      NULL, NULL);
15134
0
    }
15135
0
      }
15136
21
  }
15137
50
    }
15138
12.5k
}
15139
15140
15141
15142
/**
15143
 * xmlSchemaCheckSTPropsCorrect:
15144
 * @ctxt:  the schema parser context
15145
 * @type:  the simple type definition
15146
 *
15147
 * Checks st-props-correct.
15148
 *
15149
 * Returns 0 if the properties are correct,
15150
 * if not, a positive error code and -1 on internal
15151
 * errors.
15152
 */
15153
static int
15154
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15155
           xmlSchemaTypePtr type)
15156
8.73k
{
15157
8.73k
    xmlSchemaTypePtr baseType = type->baseType;
15158
8.73k
    xmlChar *str = NULL;
15159
15160
    /* STATE: error funcs converted. */
15161
    /*
15162
    * Schema Component Constraint: Simple Type Definition Properties Correct
15163
    *
15164
    * NOTE: This is somehow redundant, since we actually built a simple type
15165
    * to have all the needed information; this acts as an self test.
15166
    */
15167
    /* Base type: If the datatype has been `derived` by `restriction`
15168
    * then the Simple Type Definition component from which it is `derived`,
15169
    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15170
    */
15171
8.73k
    if (baseType == NULL) {
15172
  /*
15173
  * TODO: Think about: "modulo the impact of Missing
15174
  * Sub-components ($5.3)."
15175
  */
15176
0
  xmlSchemaPCustomErr(ctxt,
15177
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15178
0
      WXS_BASIC_CAST type, NULL,
15179
0
      "No base type existent", NULL);
15180
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15181
15182
0
    }
15183
8.73k
    if (! WXS_IS_SIMPLE(baseType)) {
15184
0
  xmlSchemaPCustomErr(ctxt,
15185
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15186
0
      WXS_BASIC_CAST type, NULL,
15187
0
      "The base type '%s' is not a simple type",
15188
0
      xmlSchemaGetComponentQName(&str, baseType));
15189
0
  FREE_AND_NULL(str)
15190
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15191
0
    }
15192
8.73k
    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15193
8.73k
  (WXS_IS_RESTRICTION(type) == 0) &&
15194
8.73k
  ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15195
368
         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15196
0
  xmlSchemaPCustomErr(ctxt,
15197
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15198
0
      WXS_BASIC_CAST type, NULL,
15199
0
      "A type, derived by list or union, must have "
15200
0
      "the simple ur-type definition as base type, not '%s'",
15201
0
      xmlSchemaGetComponentQName(&str, baseType));
15202
0
  FREE_AND_NULL(str)
15203
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15204
0
    }
15205
    /*
15206
    * Variety: One of {atomic, list, union}.
15207
    */
15208
8.73k
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15209
8.73k
  (! WXS_IS_LIST(type))) {
15210
0
  xmlSchemaPCustomErr(ctxt,
15211
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15212
0
      WXS_BASIC_CAST type, NULL,
15213
0
      "The variety is absent", NULL);
15214
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15215
0
    }
15216
    /* TODO: Finish this. Hmm, is this finished? */
15217
15218
    /*
15219
    * 3 The {final} of the {base type definition} must not contain restriction.
15220
    */
15221
8.73k
    if (xmlSchemaTypeFinalContains(baseType,
15222
8.73k
  XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15223
0
  xmlSchemaPCustomErr(ctxt,
15224
0
      XML_SCHEMAP_ST_PROPS_CORRECT_3,
15225
0
      WXS_BASIC_CAST type, NULL,
15226
0
      "The 'final' of its base type '%s' must not contain "
15227
0
      "'restriction'",
15228
0
      xmlSchemaGetComponentQName(&str, baseType));
15229
0
  FREE_AND_NULL(str)
15230
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15231
0
    }
15232
15233
    /*
15234
    * 2 All simple type definitions must be derived ultimately from the `simple
15235
    * ur-type definition` (so circular definitions are disallowed). That is, it
15236
    * must be possible to reach a built-in primitive datatype or the `simple
15237
    * ur-type definition` by repeatedly following the {base type definition}.
15238
    *
15239
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15240
    */
15241
8.73k
    return (0);
15242
8.73k
}
15243
15244
/**
15245
 * xmlSchemaCheckCOSSTRestricts:
15246
 * @ctxt:  the schema parser context
15247
 * @type:  the simple type definition
15248
 *
15249
 * Schema Component Constraint:
15250
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15251
15252
 * Checks if the given @type (simpleType) is derived validly by restriction.
15253
 * STATUS:
15254
 *
15255
 * Returns -1 on internal errors, 0 if the type is validly derived,
15256
 * a positive error code otherwise.
15257
 */
15258
static int
15259
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15260
           xmlSchemaTypePtr type)
15261
8.73k
{
15262
8.73k
    xmlChar *str = NULL;
15263
15264
8.73k
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15265
0
  PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15266
0
      "given type is not a user-derived simpleType");
15267
0
  return (-1);
15268
0
    }
15269
15270
8.73k
    if (WXS_IS_ATOMIC(type)) {
15271
7.91k
  xmlSchemaTypePtr primitive;
15272
  /*
15273
  * 1.1 The {base type definition} must be an atomic simple
15274
  * type definition or a built-in primitive datatype.
15275
  */
15276
7.91k
  if (! WXS_IS_ATOMIC(type->baseType)) {
15277
0
      xmlSchemaPCustomErr(pctxt,
15278
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15279
0
    WXS_BASIC_CAST type, NULL,
15280
0
    "The base type '%s' is not an atomic simple type",
15281
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15282
0
      FREE_AND_NULL(str)
15283
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15284
0
  }
15285
  /* 1.2 The {final} of the {base type definition} must not contain
15286
  * restriction.
15287
  */
15288
  /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15289
7.91k
  if (xmlSchemaTypeFinalContains(type->baseType,
15290
7.91k
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15291
0
      xmlSchemaPCustomErr(pctxt,
15292
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15293
0
    WXS_BASIC_CAST type, NULL,
15294
0
    "The final of its base type '%s' must not contain 'restriction'",
15295
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15296
0
      FREE_AND_NULL(str)
15297
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15298
0
  }
15299
15300
  /*
15301
  * 1.3.1 DF must be an allowed constraining facet for the {primitive
15302
  * type definition}, as specified in the appropriate subsection of 3.2
15303
  * Primitive datatypes.
15304
  */
15305
7.91k
  if (type->facets != NULL) {
15306
7.82k
      xmlSchemaFacetPtr facet;
15307
7.82k
      int ok = 1;
15308
15309
7.82k
      primitive = xmlSchemaGetPrimitiveType(type);
15310
7.82k
      if (primitive == NULL) {
15311
0
    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15312
0
        "failed to get primitive type");
15313
0
    return (-1);
15314
0
      }
15315
7.82k
      facet = type->facets;
15316
120k
      do {
15317
120k
    if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15318
305
        ok = 0;
15319
305
        xmlSchemaPIllegalFacetAtomicErr(pctxt,
15320
305
      XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15321
305
      type, primitive, facet);
15322
305
    }
15323
120k
    facet = facet->next;
15324
120k
      } while (facet != NULL);
15325
7.82k
      if (ok == 0)
15326
30
    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15327
7.82k
  }
15328
  /*
15329
  * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15330
  * of the {base type definition} (call this BF),then the DF's {value}
15331
  * must be a valid restriction of BF's {value} as defined in
15332
  * [XML Schemas: Datatypes]."
15333
  *
15334
  * NOTE (1.3.2) Facet derivation constraints are currently handled in
15335
  * xmlSchemaDeriveAndValidateFacets()
15336
  */
15337
7.91k
    } else if (WXS_IS_LIST(type)) {
15338
457
  xmlSchemaTypePtr itemType = NULL;
15339
15340
457
  itemType = type->subtypes;
15341
457
  if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15342
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15343
0
    "failed to evaluate the item type");
15344
0
      return (-1);
15345
0
  }
15346
457
  if (WXS_IS_TYPE_NOT_FIXED(itemType))
15347
49
      xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15348
  /*
15349
  * 2.1 The {item type definition} must have a {variety} of atomic or
15350
  * union (in which case all the {member type definitions}
15351
  * must be atomic).
15352
  */
15353
457
  if ((! WXS_IS_ATOMIC(itemType)) &&
15354
457
      (! WXS_IS_UNION(itemType))) {
15355
0
      xmlSchemaPCustomErr(pctxt,
15356
0
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15357
0
    WXS_BASIC_CAST type, NULL,
15358
0
    "The item type '%s' does not have a variety of atomic or union",
15359
0
    xmlSchemaGetComponentQName(&str, itemType));
15360
0
      FREE_AND_NULL(str)
15361
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15362
457
  } else if (WXS_IS_UNION(itemType)) {
15363
105
      xmlSchemaTypeLinkPtr member;
15364
15365
105
      member = itemType->memberTypes;
15366
763
      while (member != NULL) {
15367
658
    if (! WXS_IS_ATOMIC(member->type)) {
15368
0
        xmlSchemaPCustomErr(pctxt,
15369
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15370
0
      WXS_BASIC_CAST type, NULL,
15371
0
      "The item type is a union type, but the "
15372
0
      "member type '%s' of this item type is not atomic",
15373
0
      xmlSchemaGetComponentQName(&str, member->type));
15374
0
        FREE_AND_NULL(str)
15375
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15376
0
    }
15377
658
    member = member->next;
15378
658
      }
15379
105
  }
15380
15381
457
  if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15382
54
      xmlSchemaFacetPtr facet;
15383
      /*
15384
      * This is the case if we have: <simpleType><list ..
15385
      */
15386
      /*
15387
      * 2.3.1
15388
      * 2.3.1.1 The {final} of the {item type definition} must not
15389
      * contain list.
15390
      */
15391
54
      if (xmlSchemaTypeFinalContains(itemType,
15392
54
    XML_SCHEMAS_TYPE_FINAL_LIST)) {
15393
0
    xmlSchemaPCustomErr(pctxt,
15394
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15395
0
        WXS_BASIC_CAST type, NULL,
15396
0
        "The final of its item type '%s' must not contain 'list'",
15397
0
        xmlSchemaGetComponentQName(&str, itemType));
15398
0
    FREE_AND_NULL(str)
15399
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15400
0
      }
15401
      /*
15402
      * 2.3.1.2 The {facets} must only contain the whiteSpace
15403
      * facet component.
15404
      * OPTIMIZE TODO: the S4S already disallows any facet
15405
      * to be specified.
15406
      */
15407
54
      if (type->facets != NULL) {
15408
0
    facet = type->facets;
15409
0
    do {
15410
0
        if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15411
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15412
0
          XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15413
0
          type, facet);
15414
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15415
0
        }
15416
0
        facet = facet->next;
15417
0
    } while (facet != NULL);
15418
0
      }
15419
      /*
15420
      * MAYBE TODO: (Hmm, not really) Datatypes states:
15421
      * A `list` datatype can be `derived` from an `atomic` datatype
15422
      * whose `lexical space` allows space (such as string or anyURI)or
15423
      * a `union` datatype any of whose {member type definitions}'s
15424
      * `lexical space` allows space.
15425
      */
15426
403
  } else {
15427
      /*
15428
      * This is the case if we have: <simpleType><restriction ...
15429
      * I.e. the variety of "list" is inherited.
15430
      */
15431
      /*
15432
      * 2.3.2
15433
      * 2.3.2.1 The {base type definition} must have a {variety} of list.
15434
      */
15435
403
      if (! WXS_IS_LIST(type->baseType)) {
15436
0
    xmlSchemaPCustomErr(pctxt,
15437
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15438
0
        WXS_BASIC_CAST type, NULL,
15439
0
        "The base type '%s' must be a list type",
15440
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15441
0
    FREE_AND_NULL(str)
15442
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15443
0
      }
15444
      /*
15445
      * 2.3.2.2 The {final} of the {base type definition} must not
15446
      * contain restriction.
15447
      */
15448
403
      if (xmlSchemaTypeFinalContains(type->baseType,
15449
403
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15450
0
    xmlSchemaPCustomErr(pctxt,
15451
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15452
0
        WXS_BASIC_CAST type, NULL,
15453
0
        "The 'final' of the base type '%s' must not contain 'restriction'",
15454
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15455
0
    FREE_AND_NULL(str)
15456
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15457
0
      }
15458
      /*
15459
      * 2.3.2.3 The {item type definition} must be validly derived
15460
      * from the {base type definition}'s {item type definition} given
15461
      * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15462
      */
15463
403
      {
15464
403
    xmlSchemaTypePtr baseItemType;
15465
15466
403
    baseItemType = type->baseType->subtypes;
15467
403
    if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15468
0
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15469
0
      "failed to eval the item type of a base type");
15470
0
        return (-1);
15471
0
    }
15472
403
    if ((itemType != baseItemType) &&
15473
403
        (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15474
0
      baseItemType, 0) != 0)) {
15475
0
        xmlChar *strBIT = NULL, *strBT = NULL;
15476
0
        xmlSchemaPCustomErrExt(pctxt,
15477
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15478
0
      WXS_BASIC_CAST type, NULL,
15479
0
      "The item type '%s' is not validly derived from "
15480
0
      "the item type '%s' of the base type '%s'",
15481
0
      xmlSchemaGetComponentQName(&str, itemType),
15482
0
      xmlSchemaGetComponentQName(&strBIT, baseItemType),
15483
0
      xmlSchemaGetComponentQName(&strBT, type->baseType));
15484
15485
0
        FREE_AND_NULL(str)
15486
0
        FREE_AND_NULL(strBIT)
15487
0
        FREE_AND_NULL(strBT)
15488
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15489
0
    }
15490
403
      }
15491
15492
403
      if (type->facets != NULL) {
15493
370
    xmlSchemaFacetPtr facet;
15494
370
    int ok = 1;
15495
    /*
15496
    * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15497
    * and enumeration facet components are allowed among the {facets}.
15498
    */
15499
370
    facet = type->facets;
15500
6.41k
    do {
15501
6.41k
        switch (facet->type) {
15502
8
      case XML_SCHEMA_FACET_LENGTH:
15503
50
      case XML_SCHEMA_FACET_MINLENGTH:
15504
50
      case XML_SCHEMA_FACET_MAXLENGTH:
15505
50
      case XML_SCHEMA_FACET_WHITESPACE:
15506
          /*
15507
          * TODO: 2.5.1.2 List datatypes
15508
          * The value of `whiteSpace` is fixed to the value collapse.
15509
          */
15510
50
      case XML_SCHEMA_FACET_PATTERN:
15511
6.21k
      case XML_SCHEMA_FACET_ENUMERATION:
15512
6.21k
          break;
15513
200
      default: {
15514
200
          xmlSchemaPIllegalFacetListUnionErr(pctxt,
15515
200
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15516
200
        type, facet);
15517
          /*
15518
          * We could return, but it's nicer to report all
15519
          * invalid facets.
15520
          */
15521
200
          ok = 0;
15522
200
      }
15523
6.41k
        }
15524
6.41k
        facet = facet->next;
15525
6.41k
    } while (facet != NULL);
15526
370
    if (ok == 0)
15527
9
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15528
    /*
15529
    * SPEC (2.3.2.5) (same as 1.3.2)
15530
    *
15531
    * NOTE (2.3.2.5) This is currently done in
15532
    * xmlSchemaDeriveAndValidateFacets()
15533
    */
15534
370
      }
15535
403
  }
15536
457
    } else if (WXS_IS_UNION(type)) {
15537
  /*
15538
  * 3.1 The {member type definitions} must all have {variety} of
15539
  * atomic or list.
15540
  */
15541
357
  xmlSchemaTypeLinkPtr member;
15542
15543
357
  member = type->memberTypes;
15544
1.15k
  while (member != NULL) {
15545
797
      if (WXS_IS_TYPE_NOT_FIXED(member->type))
15546
0
    xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15547
15548
797
      if ((! WXS_IS_ATOMIC(member->type)) &&
15549
797
    (! WXS_IS_LIST(member->type))) {
15550
0
    xmlSchemaPCustomErr(pctxt,
15551
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15552
0
        WXS_BASIC_CAST type, NULL,
15553
0
        "The member type '%s' is neither an atomic, nor a list type",
15554
0
        xmlSchemaGetComponentQName(&str, member->type));
15555
0
    FREE_AND_NULL(str)
15556
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15557
0
      }
15558
797
      member = member->next;
15559
797
  }
15560
  /*
15561
  * 3.3.1 If the {base type definition} is the `simple ur-type
15562
  * definition`
15563
  */
15564
357
  if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15565
      /*
15566
      * 3.3.1.1 All of the {member type definitions} must have a
15567
      * {final} which does not contain union.
15568
      */
15569
314
      member = type->memberTypes;
15570
1.11k
      while (member != NULL) {
15571
797
    if (xmlSchemaTypeFinalContains(member->type,
15572
797
        XML_SCHEMAS_TYPE_FINAL_UNION)) {
15573
0
        xmlSchemaPCustomErr(pctxt,
15574
0
      XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15575
0
      WXS_BASIC_CAST type, NULL,
15576
0
      "The 'final' of member type '%s' contains 'union'",
15577
0
      xmlSchemaGetComponentQName(&str, member->type));
15578
0
        FREE_AND_NULL(str)
15579
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15580
0
    }
15581
797
    member = member->next;
15582
797
      }
15583
      /*
15584
      * 3.3.1.2 The {facets} must be empty.
15585
      */
15586
314
      if (type->facetSet != NULL) {
15587
0
    xmlSchemaPCustomErr(pctxt,
15588
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15589
0
        WXS_BASIC_CAST type, NULL,
15590
0
        "No facets allowed", NULL);
15591
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15592
0
      }
15593
314
  } else {
15594
      /*
15595
      * 3.3.2.1 The {base type definition} must have a {variety} of union.
15596
      * I.e. the variety of "list" is inherited.
15597
      */
15598
43
      if (! WXS_IS_UNION(type->baseType)) {
15599
0
    xmlSchemaPCustomErr(pctxt,
15600
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15601
0
        WXS_BASIC_CAST type, NULL,
15602
0
        "The base type '%s' is not a union type",
15603
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15604
0
    FREE_AND_NULL(str)
15605
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15606
0
      }
15607
      /*
15608
      * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15609
      */
15610
43
      if (xmlSchemaTypeFinalContains(type->baseType,
15611
43
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15612
0
    xmlSchemaPCustomErr(pctxt,
15613
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15614
0
        WXS_BASIC_CAST type, NULL,
15615
0
        "The 'final' of its base type '%s' must not contain 'restriction'",
15616
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15617
0
    FREE_AND_NULL(str)
15618
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15619
0
      }
15620
      /*
15621
      * 3.3.2.3 The {member type definitions}, in order, must be validly
15622
      * derived from the corresponding type definitions in the {base
15623
      * type definition}'s {member type definitions} given the empty set,
15624
      * as defined in Type Derivation OK (Simple) ($3.14.6).
15625
      */
15626
43
      {
15627
43
    xmlSchemaTypeLinkPtr baseMember;
15628
15629
    /*
15630
    * OPTIMIZE: if the type is restricting, it has no local defined
15631
    * member types and inherits the member types of the base type;
15632
    * thus a check for equality can be skipped.
15633
    */
15634
    /*
15635
    * Even worse: I cannot see a scenario where a restricting
15636
    * union simple type can have other member types as the member
15637
    * types of it's base type. This check seems not necessary with
15638
    * respect to the derivation process in libxml2.
15639
    * But necessary if constructing types with an API.
15640
    */
15641
43
    if (type->memberTypes != NULL) {
15642
0
        member = type->memberTypes;
15643
0
        baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15644
0
        if ((member == NULL) && (baseMember != NULL)) {
15645
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15646
0
          "different number of member types in base");
15647
0
        }
15648
0
        while (member != NULL) {
15649
0
      if (baseMember == NULL) {
15650
0
          PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15651
0
          "different number of member types in base");
15652
0
      } else if ((member->type != baseMember->type) &&
15653
0
          (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15654
0
        member->type, baseMember->type, 0) != 0)) {
15655
0
          xmlChar *strBMT = NULL, *strBT = NULL;
15656
15657
0
          xmlSchemaPCustomErrExt(pctxt,
15658
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15659
0
        WXS_BASIC_CAST type, NULL,
15660
0
        "The member type %s is not validly "
15661
0
        "derived from its corresponding member "
15662
0
        "type %s of the base type %s",
15663
0
        xmlSchemaGetComponentQName(&str, member->type),
15664
0
        xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15665
0
        xmlSchemaGetComponentQName(&strBT, type->baseType));
15666
0
          FREE_AND_NULL(str)
15667
0
          FREE_AND_NULL(strBMT)
15668
0
          FREE_AND_NULL(strBT)
15669
0
          return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15670
0
      }
15671
0
      member = member->next;
15672
0
                        if (baseMember != NULL)
15673
0
                            baseMember = baseMember->next;
15674
0
        }
15675
0
    }
15676
43
      }
15677
      /*
15678
      * 3.3.2.4 Only pattern and enumeration facet components are
15679
      * allowed among the {facets}.
15680
      */
15681
43
      if (type->facets != NULL) {
15682
36
    xmlSchemaFacetPtr facet;
15683
36
    int ok = 1;
15684
15685
36
    facet = type->facets;
15686
149
    do {
15687
149
        if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15688
149
      (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15689
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15690
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15691
0
        type, facet);
15692
0
      ok = 0;
15693
0
        }
15694
149
        facet = facet->next;
15695
149
    } while (facet != NULL);
15696
36
    if (ok == 0)
15697
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15698
15699
36
      }
15700
      /*
15701
      * SPEC (3.3.2.5) (same as 1.3.2)
15702
      *
15703
      * NOTE (3.3.2.5) This is currently done in
15704
      * xmlSchemaDeriveAndValidateFacets()
15705
      */
15706
43
  }
15707
357
    }
15708
15709
8.69k
    return (0);
15710
8.73k
}
15711
15712
/**
15713
 * xmlSchemaCheckSRCSimpleType:
15714
 * @ctxt:  the schema parser context
15715
 * @type:  the simple type definition
15716
 *
15717
 * Checks crc-simple-type constraints.
15718
 *
15719
 * Returns 0 if the constraints are satisfied,
15720
 * if not a positive error code and -1 on internal
15721
 * errors.
15722
 */
15723
#if 0
15724
static int
15725
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15726
          xmlSchemaTypePtr type)
15727
{
15728
    /*
15729
    * src-simple-type.1 The corresponding simple type definition, if any,
15730
    * must satisfy the conditions set out in Constraints on Simple Type
15731
    * Definition Schema Components ($3.14.6).
15732
    */
15733
    if (WXS_IS_RESTRICTION(type)) {
15734
  /*
15735
  * src-simple-type.2 "If the <restriction> alternative is chosen,
15736
  * either it must have a base [attribute] or a <simpleType> among its
15737
  * [children], but not both."
15738
  * NOTE: This is checked in the parse function of <restriction>.
15739
  */
15740
  /*
15741
  *
15742
  */
15743
    } else if (WXS_IS_LIST(type)) {
15744
  /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15745
  * an itemType [attribute] or a <simpleType> among its [children],
15746
  * but not both."
15747
  *
15748
  * NOTE: This is checked in the parse function of <list>.
15749
  */
15750
    } else if (WXS_IS_UNION(type)) {
15751
  /*
15752
  * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15753
  */
15754
    }
15755
    return (0);
15756
}
15757
#endif
15758
15759
static int
15760
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15761
6.83k
{
15762
6.83k
   if (ctxt->vctxt == NULL) {
15763
6.83k
  ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15764
6.83k
  if (ctxt->vctxt == NULL) {
15765
0
      xmlSchemaPErr(ctxt, NULL,
15766
0
    XML_SCHEMAP_INTERNAL,
15767
0
    "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15768
0
    "failed to create a temp. validation context.\n",
15769
0
    NULL, NULL);
15770
0
      return (-1);
15771
0
  }
15772
  /* TODO: Pass user data. */
15773
6.83k
  xmlSchemaSetValidErrors(ctxt->vctxt,
15774
6.83k
      ctxt->error, ctxt->warning, ctxt->errCtxt);
15775
6.83k
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15776
6.83k
      ctxt->serror, ctxt->errCtxt);
15777
6.83k
    }
15778
6.83k
    return (0);
15779
6.83k
}
15780
15781
static int
15782
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15783
           xmlNodePtr node,
15784
           xmlSchemaTypePtr type,
15785
           const xmlChar *value,
15786
           xmlSchemaValPtr *retVal,
15787
           int fireErrors,
15788
           int normalize,
15789
           int isNormalized);
15790
15791
/**
15792
 * xmlSchemaParseCheckCOSValidDefault:
15793
 * @pctxt:  the schema parser context
15794
 * @type:  the simple type definition
15795
 * @value: the default value
15796
 * @node: an optional node (the holder of the value)
15797
 *
15798
 * Schema Component Constraint: Element Default Valid (Immediate)
15799
 * (cos-valid-default)
15800
 * This will be used by the parser only. For the validator there's
15801
 * an other version.
15802
 *
15803
 * Returns 0 if the constraints are satisfied,
15804
 * if not, a positive error code and -1 on internal
15805
 * errors.
15806
 */
15807
static int
15808
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15809
           xmlNodePtr node,
15810
           xmlSchemaTypePtr type,
15811
           const xmlChar *value,
15812
           xmlSchemaValPtr *val)
15813
2.94k
{
15814
2.94k
    int ret = 0;
15815
15816
    /*
15817
    * cos-valid-default:
15818
    * Schema Component Constraint: Element Default Valid (Immediate)
15819
    * For a string to be a valid default with respect to a type
15820
    * definition the appropriate case among the following must be true:
15821
    */
15822
2.94k
    if WXS_IS_COMPLEX(type) {
15823
  /*
15824
  * Complex type.
15825
  *
15826
  * SPEC (2.1) "its {content type} must be a simple type definition
15827
  * or mixed."
15828
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15829
  * type}'s particle must be `emptiable` as defined by
15830
  * Particle Emptiable ($3.9.6)."
15831
  */
15832
11
  if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15833
11
      ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15834
      /* NOTE that this covers (2.2.2) as well. */
15835
0
      xmlSchemaPCustomErr(pctxt,
15836
0
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15837
0
    WXS_BASIC_CAST type, type->node,
15838
0
    "For a string to be a valid default, the type definition "
15839
0
    "must be a simple type or a complex type with mixed content "
15840
0
    "and a particle emptiable", NULL);
15841
0
      return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15842
0
  }
15843
11
    }
15844
    /*
15845
    * 1 If the type definition is a simple type definition, then the string
15846
    * must be `valid` with respect to that definition as defined by String
15847
    * Valid ($3.14.4).
15848
    *
15849
    * AND
15850
    *
15851
    * 2.2.1 If the {content type} is a simple type definition, then the
15852
    * string must be `valid` with respect to that simple type definition
15853
    * as defined by String Valid ($3.14.4).
15854
    */
15855
2.94k
    if (WXS_IS_SIMPLE(type))
15856
2.93k
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15857
2.93k
      type, value, val, 1, 1, 0);
15858
11
    else if (WXS_HAS_SIMPLE_CONTENT(type))
15859
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15860
0
      type->contentTypeDef, value, val, 1, 1, 0);
15861
11
    else
15862
11
  return (ret);
15863
15864
2.93k
    if (ret < 0) {
15865
0
  PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15866
0
      "calling xmlSchemaVCheckCVCSimpleType()");
15867
0
    }
15868
15869
2.93k
    return (ret);
15870
2.94k
}
15871
15872
/**
15873
 * xmlSchemaCheckCTPropsCorrect:
15874
 * @ctxt:  the schema parser context
15875
 * @type:  the complex type definition
15876
 *
15877
 *.(4.6) Constraints on Complex Type Definition Schema Components
15878
 * Schema Component Constraint:
15879
 * Complex Type Definition Properties Correct (ct-props-correct)
15880
 * STATUS: (seems) complete
15881
 *
15882
 * Returns 0 if the constraints are satisfied, a positive
15883
 * error code if not and -1 if an internal error occurred.
15884
 */
15885
static int
15886
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15887
           xmlSchemaTypePtr type)
15888
1.60k
{
15889
    /*
15890
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15891
    *
15892
    * SPEC (1) "The values of the properties of a complex type definition must
15893
    * be as described in the property tableau in The Complex Type Definition
15894
    * Schema Component ($3.4.1), modulo the impact of Missing
15895
    * Sub-components ($5.3)."
15896
    */
15897
1.60k
    if ((type->baseType != NULL) &&
15898
1.60k
  (WXS_IS_SIMPLE(type->baseType)) &&
15899
1.60k
  (WXS_IS_EXTENSION(type) == 0)) {
15900
  /*
15901
  * SPEC (2) "If the {base type definition} is a simple type definition,
15902
  * the {derivation method} must be extension."
15903
  */
15904
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
15905
0
      XML_SCHEMAP_SRC_CT_1,
15906
0
      NULL, WXS_BASIC_CAST type,
15907
0
      "If the base type is a simple type, the derivation method must be "
15908
0
      "'extension'", NULL, NULL);
15909
0
  return (XML_SCHEMAP_SRC_CT_1);
15910
0
    }
15911
    /*
15912
    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
15913
    * definition`. That is, it must be possible to reach the `ur-type
15914
    * definition` by repeatedly following the {base type definition}."
15915
    *
15916
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15917
    */
15918
    /*
15919
    * NOTE that (4) and (5) need the following:
15920
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
15921
    *   - attribute group references need to be expanded already
15922
    *   - simple types need to be typefixed already
15923
    */
15924
1.60k
    if (type->attrUses &&
15925
1.60k
  (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15926
214
    {
15927
214
  xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15928
214
  xmlSchemaAttributeUsePtr use, tmp;
15929
214
  int i, j, hasId = 0;
15930
15931
2.20k
  for (i = uses->nbItems -1; i >= 0; i--) {
15932
1.98k
      use = uses->items[i];
15933
15934
      /*
15935
      * SPEC ct-props-correct
15936
      * (4) "Two distinct attribute declarations in the
15937
      * {attribute uses} must not have identical {name}s and
15938
      * {target namespace}s."
15939
      */
15940
1.98k
      if (i > 0) {
15941
13.8k
    for (j = i -1; j >= 0; j--) {
15942
13.2k
        tmp = uses->items[j];
15943
13.2k
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
15944
13.2k
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
15945
13.2k
      (WXS_ATTRUSE_DECL_TNS(use) ==
15946
1.11k
      WXS_ATTRUSE_DECL_TNS(tmp)))
15947
1.09k
        {
15948
1.09k
      xmlChar *str = NULL;
15949
15950
1.09k
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15951
1.09k
          XML_SCHEMAP_AG_PROPS_CORRECT,
15952
1.09k
          NULL, WXS_BASIC_CAST type,
15953
1.09k
          "Duplicate %s",
15954
1.09k
          xmlSchemaGetComponentDesignation(&str, use),
15955
1.09k
          NULL);
15956
1.09k
      FREE_AND_NULL(str);
15957
      /*
15958
      * Remove the duplicate.
15959
      */
15960
1.09k
      if (xmlSchemaItemListRemove(uses, i) == -1)
15961
0
          goto exit_failure;
15962
1.09k
      goto next_use;
15963
1.09k
        }
15964
13.2k
    }
15965
1.77k
      }
15966
      /*
15967
      * SPEC ct-props-correct
15968
      * (5) "Two distinct attribute declarations in the
15969
      * {attribute uses} must not have {type definition}s which
15970
      * are or are derived from ID."
15971
      */
15972
892
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15973
892
    if (xmlSchemaIsDerivedFromBuiltInType(
15974
892
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15975
12
    {
15976
12
        if (hasId) {
15977
0
      xmlChar *str = NULL;
15978
15979
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15980
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15981
0
          NULL, WXS_BASIC_CAST type,
15982
0
          "There must not exist more than one attribute "
15983
0
          "declaration of type 'xs:ID' "
15984
0
          "(or derived from 'xs:ID'). The %s violates this "
15985
0
          "constraint",
15986
0
          xmlSchemaGetComponentDesignation(&str, use),
15987
0
          NULL);
15988
0
      FREE_AND_NULL(str);
15989
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15990
0
          goto exit_failure;
15991
0
        }
15992
15993
12
        hasId = 1;
15994
12
    }
15995
892
      }
15996
1.98k
next_use: {}
15997
1.98k
  }
15998
214
    }
15999
1.60k
    return (0);
16000
0
exit_failure:
16001
0
    return(-1);
16002
1.60k
}
16003
16004
static int
16005
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16006
           xmlSchemaTypePtr typeB)
16007
3
{
16008
    /*
16009
    * TODO: This should implement component-identity
16010
    * in the future.
16011
    */
16012
3
    if ((typeA == NULL) || (typeB == NULL))
16013
0
  return (0);
16014
3
    return (typeA == typeB);
16015
3
}
16016
16017
/**
16018
 * xmlSchemaCheckCOSCTDerivedOK:
16019
 * @ctxt:  the schema parser context
16020
 * @type:  the to-be derived complex type definition
16021
 * @baseType:  the base complex type definition
16022
 * @set: the given set
16023
 *
16024
 * Schema Component Constraint:
16025
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16026
 *
16027
 * STATUS: completed
16028
 *
16029
 * Returns 0 if the constraints are satisfied, or 1
16030
 * if not.
16031
 */
16032
static int
16033
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16034
           xmlSchemaTypePtr type,
16035
           xmlSchemaTypePtr baseType,
16036
           int set)
16037
3
{
16038
3
    int equal = xmlSchemaAreEqualTypes(type, baseType);
16039
    /* TODO: Error codes. */
16040
    /*
16041
    * SPEC "For a complex type definition (call it D, for derived)
16042
    * to be validly derived from a type definition (call this
16043
    * B, for base) given a subset of {extension, restriction}
16044
    * all of the following must be true:"
16045
    */
16046
3
    if (! equal) {
16047
  /*
16048
  * SPEC (1) "If B and D are not the same type definition, then the
16049
  * {derivation method} of D must not be in the subset."
16050
  */
16051
3
  if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16052
3
      ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16053
0
      return (1);
16054
3
    } else {
16055
  /*
16056
  * SPEC (2.1) "B and D must be the same type definition."
16057
  */
16058
0
  return (0);
16059
0
    }
16060
    /*
16061
    * SPEC (2.2) "B must be D's {base type definition}."
16062
    */
16063
3
    if (type->baseType == baseType)
16064
3
  return (0);
16065
    /*
16066
    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16067
    * definition`."
16068
    */
16069
0
    if (WXS_IS_ANYTYPE(type->baseType))
16070
0
  return (1);
16071
16072
0
    if (WXS_IS_COMPLEX(type->baseType)) {
16073
  /*
16074
  * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16075
  * must be validly derived from B given the subset as defined by this
16076
  * constraint."
16077
  */
16078
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16079
0
      baseType, set));
16080
0
    } else {
16081
  /*
16082
  * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16083
  * must be validly derived from B given the subset as defined in Type
16084
  * Derivation OK (Simple) ($3.14.6).
16085
  */
16086
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16087
0
      baseType, set));
16088
0
    }
16089
0
}
16090
16091
/**
16092
 * xmlSchemaCheckCOSDerivedOK:
16093
 * @type:  the derived simple type definition
16094
 * @baseType:  the base type definition
16095
 *
16096
 * Calls:
16097
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16098
 *
16099
 * Checks whether @type can be validly derived from @baseType.
16100
 *
16101
 * Returns 0 on success, an positive error code otherwise.
16102
 */
16103
static int
16104
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16105
         xmlSchemaTypePtr type,
16106
         xmlSchemaTypePtr baseType,
16107
         int set)
16108
7
{
16109
7
    if (WXS_IS_SIMPLE(type))
16110
4
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16111
3
    else
16112
3
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16113
7
}
16114
16115
/**
16116
 * xmlSchemaCheckCOSCTExtends:
16117
 * @ctxt:  the schema parser context
16118
 * @type:  the complex type definition
16119
 *
16120
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16121
 * Schema Component Constraint:
16122
 * Derivation Valid (Extension) (cos-ct-extends)
16123
 *
16124
 * STATUS:
16125
 *   missing:
16126
 *     (1.5)
16127
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16128
 *
16129
 * Returns 0 if the constraints are satisfied, a positive
16130
 * error code if not and -1 if an internal error occurred.
16131
 */
16132
static int
16133
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16134
         xmlSchemaTypePtr type)
16135
290
{
16136
290
    xmlSchemaTypePtr base = type->baseType;
16137
    /*
16138
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16139
    * temporarily only.
16140
    */
16141
    /*
16142
    * SPEC (1) "If the {base type definition} is a complex type definition,
16143
    * then all of the following must be true:"
16144
    */
16145
290
    if (WXS_IS_COMPLEX(base)) {
16146
  /*
16147
  * SPEC (1.1) "The {final} of the {base type definition} must not
16148
  * contain extension."
16149
  */
16150
227
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16151
0
      xmlSchemaPCustomErr(ctxt,
16152
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16153
0
    WXS_BASIC_CAST type, NULL,
16154
0
    "The 'final' of the base type definition "
16155
0
    "contains 'extension'", NULL);
16156
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16157
0
  }
16158
16159
  /*
16160
  * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16161
  * since they are automatically satisfied through the
16162
  * inheriting mechanism.
16163
  * Note that even if redefining components, the inheriting mechanism
16164
  * is used.
16165
  */
16166
#if 0
16167
  /*
16168
  * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16169
  * uses}
16170
  * of the complex type definition itself, that is, for every attribute
16171
  * use in the {attribute uses} of the {base type definition}, there
16172
  * must be an attribute use in the {attribute uses} of the complex
16173
  * type definition itself whose {attribute declaration} has the same
16174
  * {name}, {target namespace} and {type definition} as its attribute
16175
  * declaration"
16176
  */
16177
  if (base->attrUses != NULL) {
16178
      int i, j, found;
16179
      xmlSchemaAttributeUsePtr use, buse;
16180
16181
      for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16182
    buse = (WXS_LIST_CAST base->attrUses)->items[i];
16183
    found = 0;
16184
    if (type->attrUses != NULL) {
16185
        use = (WXS_LIST_CAST type->attrUses)->items[j];
16186
        for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16187
        {
16188
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
16189
        WXS_ATTRUSE_DECL_NAME(buse)) &&
16190
          (WXS_ATTRUSE_DECL_TNS(use) ==
16191
        WXS_ATTRUSE_DECL_TNS(buse)) &&
16192
          (WXS_ATTRUSE_TYPEDEF(use) ==
16193
        WXS_ATTRUSE_TYPEDEF(buse))
16194
      {
16195
          found = 1;
16196
          break;
16197
      }
16198
        }
16199
    }
16200
    if (! found) {
16201
        xmlChar *str = NULL;
16202
16203
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
16204
      XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16205
      NULL, WXS_BASIC_CAST type,
16206
      /*
16207
      * TODO: The report does not indicate that also the
16208
      * type needs to be the same.
16209
      */
16210
      "This type is missing a matching correspondent "
16211
      "for its {base type}'s %s in its {attribute uses}",
16212
      xmlSchemaGetComponentDesignation(&str,
16213
          buse->children),
16214
      NULL);
16215
        FREE_AND_NULL(str)
16216
    }
16217
      }
16218
  }
16219
  /*
16220
  * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16221
  * definition must also have one, and the base type definition's
16222
  * {attribute  wildcard}'s {namespace constraint} must be a subset
16223
  * of the complex  type definition's {attribute wildcard}'s {namespace
16224
  * constraint}, as defined by Wildcard Subset ($3.10.6)."
16225
  */
16226
16227
  /*
16228
  * MAYBE TODO: Enable if ever needed. But this will be needed only
16229
  * if created the type via a schema construction API.
16230
  */
16231
  if (base->attributeWildcard != NULL) {
16232
      if (type->attributeWildcard == NULL) {
16233
    xmlChar *str = NULL;
16234
16235
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16236
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16237
        NULL, type,
16238
        "The base %s has an attribute wildcard, "
16239
        "but this type is missing an attribute wildcard",
16240
        xmlSchemaGetComponentDesignation(&str, base));
16241
    FREE_AND_NULL(str)
16242
16243
      } else if (xmlSchemaCheckCOSNSSubset(
16244
    base->attributeWildcard, type->attributeWildcard))
16245
      {
16246
    xmlChar *str = NULL;
16247
16248
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16249
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16250
        NULL, type,
16251
        "The attribute wildcard is not a valid "
16252
        "superset of the one in the base %s",
16253
        xmlSchemaGetComponentDesignation(&str, base));
16254
    FREE_AND_NULL(str)
16255
      }
16256
  }
16257
#endif
16258
  /*
16259
  * SPEC (1.4) "One of the following must be true:"
16260
  */
16261
227
  if ((type->contentTypeDef != NULL) &&
16262
227
      (type->contentTypeDef == base->contentTypeDef)) {
16263
      /*
16264
      * SPEC (1.4.1) "The {content type} of the {base type definition}
16265
      * and the {content type} of the complex type definition itself
16266
      * must be the same simple type definition"
16267
      * PASS
16268
      */
16269
227
  } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16270
227
      (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16271
      /*
16272
      * SPEC (1.4.2) "The {content type} of both the {base type
16273
      * definition} and the complex type definition itself must
16274
      * be empty."
16275
      * PASS
16276
      */
16277
212
  } else {
16278
      /*
16279
      * SPEC (1.4.3) "All of the following must be true:"
16280
      */
16281
15
      if (type->subtypes == NULL) {
16282
    /*
16283
    * SPEC 1.4.3.1 The {content type} of the complex type
16284
    * definition itself must specify a particle.
16285
    */
16286
0
    xmlSchemaPCustomErr(ctxt,
16287
0
        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16288
0
        WXS_BASIC_CAST type, NULL,
16289
0
        "The content type must specify a particle", NULL);
16290
0
    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16291
0
      }
16292
      /*
16293
      * SPEC (1.4.3.2) "One of the following must be true:"
16294
      */
16295
15
      if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16296
    /*
16297
    * SPEC (1.4.3.2.1) "The {content type} of the {base type
16298
    * definition} must be empty.
16299
    * PASS
16300
    */
16301
10
      } else {
16302
    /*
16303
    * SPEC (1.4.3.2.2) "All of the following must be true:"
16304
    */
16305
5
    if ((type->contentType != base->contentType) ||
16306
5
        ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16307
4
        (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16308
        /*
16309
        * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16310
        * or both must be element-only."
16311
        */
16312
1
        xmlSchemaPCustomErr(ctxt,
16313
1
      XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16314
1
      WXS_BASIC_CAST type, NULL,
16315
1
      "The content type of both, the type and its base "
16316
1
      "type, must either 'mixed' or 'element-only'", NULL);
16317
1
        return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16318
1
    }
16319
    /*
16320
    * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16321
    * complex type definition must be a `valid extension`
16322
    * of the {base type definition}'s particle, as defined
16323
    * in Particle Valid (Extension) ($3.9.6)."
16324
    *
16325
    * NOTE that we won't check "Particle Valid (Extension)",
16326
    * since it is ensured by the derivation process in
16327
    * xmlSchemaTypeFixup(). We need to implement this when heading
16328
    * for a construction API
16329
    * TODO: !! This is needed to be checked if redefining a type !!
16330
    */
16331
5
      }
16332
      /*
16333
      * URGENT TODO (1.5)
16334
      */
16335
15
  }
16336
227
    } else {
16337
  /*
16338
  * SPEC (2) "If the {base type definition} is a simple type definition,
16339
  * then all of the following must be true:"
16340
  */
16341
63
  if (type->contentTypeDef != base) {
16342
      /*
16343
      * SPEC (2.1) "The {content type} must be the same simple type
16344
      * definition."
16345
      */
16346
0
      xmlSchemaPCustomErr(ctxt,
16347
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16348
0
    WXS_BASIC_CAST type, NULL,
16349
0
    "The content type must be the simple base type", NULL);
16350
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16351
0
  }
16352
63
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16353
      /*
16354
      * SPEC (2.2) "The {final} of the {base type definition} must not
16355
      * contain extension"
16356
      * NOTE that this is the same as (1.1).
16357
      */
16358
0
      xmlSchemaPCustomErr(ctxt,
16359
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16360
0
    WXS_BASIC_CAST type, NULL,
16361
0
    "The 'final' of the base type definition "
16362
0
    "contains 'extension'", NULL);
16363
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16364
0
  }
16365
63
    }
16366
289
    return (0);
16367
290
}
16368
16369
/**
16370
 * xmlSchemaCheckDerivationOKRestriction:
16371
 * @ctxt:  the schema parser context
16372
 * @type:  the complex type definition
16373
 *
16374
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16375
 * Schema Component Constraint:
16376
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16377
 *
16378
 * STATUS:
16379
 *   missing:
16380
 *     (5.4.2) ???
16381
 *
16382
 * ATTENTION:
16383
 * In XML Schema 1.1 this will be:
16384
 * Validation Rule: Checking complex type subsumption
16385
 *
16386
 * Returns 0 if the constraints are satisfied, a positive
16387
 * error code if not and -1 if an internal error occurred.
16388
 */
16389
static int
16390
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16391
              xmlSchemaTypePtr type)
16392
1.31k
{
16393
1.31k
    xmlSchemaTypePtr base;
16394
16395
    /*
16396
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16397
    * temporarily only.
16398
    */
16399
1.31k
    base = type->baseType;
16400
1.31k
    if (! WXS_IS_COMPLEX(base)) {
16401
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16402
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16403
0
      type->node, WXS_BASIC_CAST type,
16404
0
      "The base type must be a complex type", NULL, NULL);
16405
0
  return(ctxt->err);
16406
0
    }
16407
1.31k
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16408
  /*
16409
  * SPEC (1) "The {base type definition} must be a complex type
16410
  * definition whose {final} does not contain restriction."
16411
  */
16412
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16413
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16414
0
      type->node, WXS_BASIC_CAST type,
16415
0
      "The 'final' of the base type definition "
16416
0
      "contains 'restriction'", NULL, NULL);
16417
0
  return (ctxt->err);
16418
0
    }
16419
    /*
16420
    * SPEC (2), (3) and (4)
16421
    * Those are handled in a separate function, since the
16422
    * same constraints are needed for redefinition of
16423
    * attribute groups as well.
16424
    */
16425
1.31k
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16426
1.31k
  XML_SCHEMA_ACTION_DERIVE,
16427
1.31k
  WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16428
1.31k
  type->attrUses, base->attrUses,
16429
1.31k
  type->attributeWildcard,
16430
1.31k
  base->attributeWildcard) == -1)
16431
0
    {
16432
0
  return(-1);
16433
0
    }
16434
    /*
16435
    * SPEC (5) "One of the following must be true:"
16436
    */
16437
1.31k
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16438
  /*
16439
  * SPEC (5.1) "The {base type definition} must be the
16440
  * `ur-type definition`."
16441
  * PASS
16442
  */
16443
1.24k
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16444
73
      (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16445
  /*
16446
  * SPEC (5.2.1) "The {content type} of the complex type definition
16447
  * must be a simple type definition"
16448
  *
16449
  * SPEC (5.2.2) "One of the following must be true:"
16450
  */
16451
2
  if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16452
2
      (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16453
2
  {
16454
2
      int err;
16455
      /*
16456
      * SPEC (5.2.2.1) "The {content type} of the {base type
16457
      * definition} must be a simple type definition from which
16458
      * the {content type} is validly derived given the empty
16459
      * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16460
      *
16461
      * ATTENTION TODO: This seems not needed if the type implicitly
16462
      * derived from the base type.
16463
      *
16464
      */
16465
2
      err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16466
2
    type->contentTypeDef, base->contentTypeDef, 0);
16467
2
      if (err != 0) {
16468
0
    xmlChar *strA = NULL, *strB = NULL;
16469
16470
0
    if (err == -1)
16471
0
        return(-1);
16472
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16473
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16474
0
        NULL, WXS_BASIC_CAST type,
16475
0
        "The {content type} %s is not validly derived from the "
16476
0
        "base type's {content type} %s",
16477
0
        xmlSchemaGetComponentDesignation(&strA,
16478
0
      type->contentTypeDef),
16479
0
        xmlSchemaGetComponentDesignation(&strB,
16480
0
      base->contentTypeDef));
16481
0
    FREE_AND_NULL(strA);
16482
0
    FREE_AND_NULL(strB);
16483
0
    return(ctxt->err);
16484
0
      }
16485
2
  } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16486
0
      (xmlSchemaIsParticleEmptiable(
16487
0
    (xmlSchemaParticlePtr) base->subtypes))) {
16488
      /*
16489
      * SPEC (5.2.2.2) "The {base type definition} must be mixed
16490
      * and have a particle which is `emptiable` as defined in
16491
      * Particle Emptiable ($3.9.6)."
16492
      * PASS
16493
      */
16494
0
  } else {
16495
0
      xmlSchemaPCustomErr(ctxt,
16496
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16497
0
    WXS_BASIC_CAST type, NULL,
16498
0
    "The content type of the base type must be either "
16499
0
    "a simple type or 'mixed' and an emptiable particle", NULL);
16500
0
      return (ctxt->err);
16501
0
  }
16502
71
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16503
  /*
16504
  * SPEC (5.3.1) "The {content type} of the complex type itself must
16505
  * be empty"
16506
  */
16507
61
  if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16508
      /*
16509
      * SPEC (5.3.2.1) "The {content type} of the {base type
16510
      * definition} must also be empty."
16511
      * PASS
16512
      */
16513
53
  } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16514
8
      (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16515
8
      xmlSchemaIsParticleEmptiable(
16516
8
    (xmlSchemaParticlePtr) base->subtypes)) {
16517
      /*
16518
      * SPEC (5.3.2.2) "The {content type} of the {base type
16519
      * definition} must be elementOnly or mixed and have a particle
16520
      * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16521
      * PASS
16522
      */
16523
8
  } else {
16524
8
      xmlSchemaPCustomErr(ctxt,
16525
8
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16526
8
    WXS_BASIC_CAST type, NULL,
16527
8
    "The content type of the base type must be either "
16528
8
    "empty or 'mixed' (or 'elements-only') and an emptiable "
16529
8
    "particle", NULL);
16530
8
      return (ctxt->err);
16531
8
  }
16532
61
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16533
10
  WXS_HAS_MIXED_CONTENT(type)) {
16534
  /*
16535
  * SPEC (5.4.1.1) "The {content type} of the complex type definition
16536
  * itself must be element-only"
16537
  */
16538
10
  if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16539
      /*
16540
      * SPEC (5.4.1.2) "The {content type} of the complex type
16541
      * definition itself and of the {base type definition} must be
16542
      * mixed"
16543
      */
16544
0
      xmlSchemaPCustomErr(ctxt,
16545
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16546
0
    WXS_BASIC_CAST type, NULL,
16547
0
    "If the content type is 'mixed', then the content type of the "
16548
0
    "base type must also be 'mixed'", NULL);
16549
0
      return (ctxt->err);
16550
0
  }
16551
  /*
16552
  * SPEC (5.4.2) "The particle of the complex type definition itself
16553
  * must be a `valid restriction` of the particle of the {content
16554
  * type} of the {base type definition} as defined in Particle Valid
16555
  * (Restriction) ($3.9.6).
16556
  *
16557
  * URGENT TODO: (5.4.2)
16558
  */
16559
10
    } else {
16560
0
  xmlSchemaPCustomErr(ctxt,
16561
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16562
0
      WXS_BASIC_CAST type, NULL,
16563
0
      "The type is not a valid restriction of its base type", NULL);
16564
0
  return (ctxt->err);
16565
0
    }
16566
1.31k
    return (0);
16567
1.31k
}
16568
16569
/**
16570
 * xmlSchemaCheckCTComponent:
16571
 * @ctxt:  the schema parser context
16572
 * @type:  the complex type definition
16573
 *
16574
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16575
 *
16576
 * Returns 0 if the constraints are satisfied, a positive
16577
 * error code if not and -1 if an internal error occurred.
16578
 */
16579
static int
16580
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16581
        xmlSchemaTypePtr type)
16582
1.60k
{
16583
1.60k
    int ret;
16584
    /*
16585
    * Complex Type Definition Properties Correct
16586
    */
16587
1.60k
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16588
1.60k
    if (ret != 0)
16589
0
  return (ret);
16590
1.60k
    if (WXS_IS_EXTENSION(type))
16591
290
  ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16592
1.31k
    else
16593
1.31k
  ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16594
1.60k
    return (ret);
16595
1.60k
}
16596
16597
/**
16598
 * xmlSchemaCheckSRCCT:
16599
 * @ctxt:  the schema parser context
16600
 * @type:  the complex type definition
16601
 *
16602
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16603
 * Schema Representation Constraint:
16604
 * Complex Type Definition Representation OK (src-ct)
16605
 *
16606
 * Returns 0 if the constraints are satisfied, a positive
16607
 * error code if not and -1 if an internal error occurred.
16608
 */
16609
static int
16610
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16611
        xmlSchemaTypePtr type)
16612
1.60k
{
16613
1.60k
    xmlSchemaTypePtr base;
16614
1.60k
    int ret = 0;
16615
16616
    /*
16617
    * TODO: Adjust the error codes here, as I used
16618
    * XML_SCHEMAP_SRC_CT_1 only yet.
16619
    */
16620
1.60k
    base = type->baseType;
16621
1.60k
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16622
  /*
16623
  * 1 If the <complexContent> alternative is chosen, the type definition
16624
  * `resolved` to by the `actual value` of the base [attribute]
16625
  * must be a complex type definition;
16626
  */
16627
1.51k
  if (! WXS_IS_COMPLEX(base)) {
16628
0
      xmlChar *str = NULL;
16629
0
      xmlSchemaPCustomErr(ctxt,
16630
0
    XML_SCHEMAP_SRC_CT_1,
16631
0
    WXS_BASIC_CAST type, type->node,
16632
0
    "If using <complexContent>, the base type is expected to be "
16633
0
    "a complex type. The base type '%s' is a simple type",
16634
0
    xmlSchemaFormatQName(&str, base->targetNamespace,
16635
0
    base->name));
16636
0
      FREE_AND_NULL(str)
16637
0
      return (XML_SCHEMAP_SRC_CT_1);
16638
0
  }
16639
1.51k
    } else {
16640
  /*
16641
  * SPEC
16642
  * 2 If the <simpleContent> alternative is chosen, all of the
16643
  * following must be true:
16644
  * 2.1 The type definition `resolved` to by the `actual value` of the
16645
  * base [attribute] must be one of the following:
16646
  */
16647
95
  if (WXS_IS_SIMPLE(base)) {
16648
63
      if (WXS_IS_EXTENSION(type) == 0) {
16649
0
    xmlChar *str = NULL;
16650
    /*
16651
    * 2.1.3 only if the <extension> alternative is also
16652
    * chosen, a simple type definition.
16653
    */
16654
    /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16655
0
    xmlSchemaPCustomErr(ctxt,
16656
0
        XML_SCHEMAP_SRC_CT_1,
16657
0
        WXS_BASIC_CAST type, NULL,
16658
0
        "If using <simpleContent> and <restriction>, the base "
16659
0
        "type must be a complex type. The base type '%s' is "
16660
0
        "a simple type",
16661
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16662
0
      base->name));
16663
0
    FREE_AND_NULL(str)
16664
0
    return (XML_SCHEMAP_SRC_CT_1);
16665
0
      }
16666
63
  } else {
16667
      /* Base type is a complex type. */
16668
32
      if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16669
32
    (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16670
    /*
16671
    * 2.1.1 a complex type definition whose {content type} is a
16672
    * simple type definition;
16673
    * PASS
16674
    */
16675
2
    if (base->contentTypeDef == NULL) {
16676
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16677
0
      WXS_BASIC_CAST type, NULL,
16678
0
      "Internal error: xmlSchemaCheckSRCCT, "
16679
0
      "'%s', base type has no content type",
16680
0
      type->name);
16681
0
        return (-1);
16682
0
    }
16683
30
      } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16684
30
    (WXS_IS_RESTRICTION(type))) {
16685
16686
    /*
16687
    * 2.1.2 only if the <restriction> alternative is also
16688
    * chosen, a complex type definition whose {content type}
16689
    * is mixed and a particle emptiable.
16690
    */
16691
30
    if (! xmlSchemaIsParticleEmptiable(
16692
30
        (xmlSchemaParticlePtr) base->subtypes)) {
16693
0
        ret = XML_SCHEMAP_SRC_CT_1;
16694
0
    } else
16695
        /*
16696
        * Attention: at this point the <simpleType> child is in
16697
        * ->contentTypeDef (put there during parsing).
16698
        */
16699
30
        if (type->contentTypeDef == NULL) {
16700
0
        xmlChar *str = NULL;
16701
        /*
16702
        * 2.2 If clause 2.1.2 above is satisfied, then there
16703
        * must be a <simpleType> among the [children] of
16704
        * <restriction>.
16705
        */
16706
        /* TODO: Change error code to ..._SRC_CT_2_2. */
16707
0
        xmlSchemaPCustomErr(ctxt,
16708
0
      XML_SCHEMAP_SRC_CT_1,
16709
0
      WXS_BASIC_CAST type, NULL,
16710
0
      "A <simpleType> is expected among the children "
16711
0
      "of <restriction>, if <simpleContent> is used and "
16712
0
      "the base type '%s' is a complex type",
16713
0
      xmlSchemaFormatQName(&str, base->targetNamespace,
16714
0
      base->name));
16715
0
        FREE_AND_NULL(str)
16716
0
        return (XML_SCHEMAP_SRC_CT_1);
16717
0
    }
16718
30
      } else {
16719
0
    ret = XML_SCHEMAP_SRC_CT_1;
16720
0
      }
16721
32
  }
16722
95
  if (ret > 0) {
16723
0
      xmlChar *str = NULL;
16724
0
      if (WXS_IS_RESTRICTION(type)) {
16725
0
    xmlSchemaPCustomErr(ctxt,
16726
0
        XML_SCHEMAP_SRC_CT_1,
16727
0
        WXS_BASIC_CAST type, NULL,
16728
0
        "If <simpleContent> and <restriction> is used, the "
16729
0
        "base type must be a simple type or a complex type with "
16730
0
        "mixed content and particle emptiable. The base type "
16731
0
        "'%s' is none of those",
16732
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16733
0
        base->name));
16734
0
      } else {
16735
0
    xmlSchemaPCustomErr(ctxt,
16736
0
        XML_SCHEMAP_SRC_CT_1,
16737
0
        WXS_BASIC_CAST type, NULL,
16738
0
        "If <simpleContent> and <extension> is used, the "
16739
0
        "base type must be a simple type. The base type '%s' "
16740
0
        "is a complex type",
16741
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16742
0
        base->name));
16743
0
      }
16744
0
      FREE_AND_NULL(str)
16745
0
  }
16746
95
    }
16747
    /*
16748
    * SPEC (3) "The corresponding complex type definition component must
16749
    * satisfy the conditions set out in Constraints on Complex Type
16750
    * Definition Schema Components ($3.4.6);"
16751
    * NOTE (3) will be done in xmlSchemaTypeFixup().
16752
    */
16753
    /*
16754
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16755
    * above for {attribute wildcard} is satisfied, the intensional
16756
    * intersection must be expressible, as defined in Attribute Wildcard
16757
    * Intersection ($3.10.6).
16758
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16759
    */
16760
1.60k
    return (ret);
16761
1.60k
}
16762
16763
#ifdef ENABLE_PARTICLE_RESTRICTION
16764
/**
16765
 * xmlSchemaCheckParticleRangeOK:
16766
 * @ctxt:  the schema parser context
16767
 * @type:  the complex type definition
16768
 *
16769
 * (3.9.6) Constraints on Particle Schema Components
16770
 * Schema Component Constraint:
16771
 * Occurrence Range OK (range-ok)
16772
 *
16773
 * STATUS: complete
16774
 *
16775
 * Returns 0 if the constraints are satisfied, a positive
16776
 * error code if not and -1 if an internal error occurred.
16777
 */
16778
static int
16779
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16780
            int bmin, int bmax)
16781
{
16782
    if (rmin < bmin)
16783
  return (1);
16784
    if ((bmax != UNBOUNDED) &&
16785
  (rmax > bmax))
16786
  return (1);
16787
    return (0);
16788
}
16789
16790
/**
16791
 * xmlSchemaCheckRCaseNameAndTypeOK:
16792
 * @ctxt:  the schema parser context
16793
 * @r: the restricting element declaration particle
16794
 * @b: the base element declaration particle
16795
 *
16796
 * (3.9.6) Constraints on Particle Schema Components
16797
 * Schema Component Constraint:
16798
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16799
 * (rcase-NameAndTypeOK)
16800
 *
16801
 * STATUS:
16802
 *   MISSING (3.2.3)
16803
 *   CLARIFY: (3.2.2)
16804
 *
16805
 * Returns 0 if the constraints are satisfied, a positive
16806
 * error code if not and -1 if an internal error occurred.
16807
 */
16808
static int
16809
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16810
         xmlSchemaParticlePtr r,
16811
         xmlSchemaParticlePtr b)
16812
{
16813
    xmlSchemaElementPtr elemR, elemB;
16814
16815
    /* TODO: Error codes (rcase-NameAndTypeOK). */
16816
    elemR = (xmlSchemaElementPtr) r->children;
16817
    elemB = (xmlSchemaElementPtr) b->children;
16818
    /*
16819
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
16820
    * the same."
16821
    */
16822
    if ((elemR != elemB) &&
16823
  ((! xmlStrEqual(elemR->name, elemB->name)) ||
16824
  (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16825
  return (1);
16826
    /*
16827
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16828
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16829
    */
16830
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16831
      b->minOccurs, b->maxOccurs) != 0)
16832
  return (1);
16833
    /*
16834
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16835
    * {scope} are global."
16836
    */
16837
    if (elemR == elemB)
16838
  return (0);
16839
    /*
16840
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16841
    */
16842
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16843
  (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16844
   return (1);
16845
    /*
16846
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16847
    * or is not fixed, or R's declaration's {value constraint} is fixed
16848
    * with the same value."
16849
    */
16850
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16851
  ((elemR->value == NULL) ||
16852
   ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16853
   /* TODO: Equality of the initial value or normalized or canonical? */
16854
   (! xmlStrEqual(elemR->value, elemB->value))))
16855
   return (1);
16856
    /*
16857
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16858
    * definitions} is a subset of B's declaration's {identity-constraint
16859
    * definitions}, if any."
16860
    */
16861
    if (elemB->idcs != NULL) {
16862
  /* TODO */
16863
    }
16864
    /*
16865
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16866
    * superset of B's declaration's {disallowed substitutions}."
16867
    */
16868
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16869
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16870
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16871
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16872
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16873
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16874
   return (1);
16875
    /*
16876
    * SPEC (3.2.5) "R's {type definition} is validly derived given
16877
    * {extension, list, union} from B's {type definition}"
16878
    *
16879
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
16880
    * set, if the corresponding constraints handle "restriction" and
16881
    * "extension" only?
16882
    *
16883
    */
16884
    {
16885
  int set = 0;
16886
16887
  set |= SUBSET_EXTENSION;
16888
  set |= SUBSET_LIST;
16889
  set |= SUBSET_UNION;
16890
  if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16891
      elemB->subtypes, set) != 0)
16892
      return (1);
16893
    }
16894
    return (0);
16895
}
16896
16897
/**
16898
 * xmlSchemaCheckRCaseNSCompat:
16899
 * @ctxt:  the schema parser context
16900
 * @r: the restricting element declaration particle
16901
 * @b: the base wildcard particle
16902
 *
16903
 * (3.9.6) Constraints on Particle Schema Components
16904
 * Schema Component Constraint:
16905
 * Particle Derivation OK (Elt:Any -- NSCompat)
16906
 * (rcase-NSCompat)
16907
 *
16908
 * STATUS: complete
16909
 *
16910
 * Returns 0 if the constraints are satisfied, a positive
16911
 * error code if not and -1 if an internal error occurred.
16912
 */
16913
static int
16914
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16915
          xmlSchemaParticlePtr r,
16916
          xmlSchemaParticlePtr b)
16917
{
16918
    /* TODO:Error codes (rcase-NSCompat). */
16919
    /*
16920
    * SPEC "For an element declaration particle to be a `valid restriction`
16921
    * of a wildcard particle all of the following must be true:"
16922
    *
16923
    * SPEC (1) "The element declaration's {target namespace} is `valid`
16924
    * with respect to the wildcard's {namespace constraint} as defined by
16925
    * Wildcard allows Namespace Name ($3.10.4)."
16926
    */
16927
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16928
  ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16929
  return (1);
16930
    /*
16931
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16932
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16933
    */
16934
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16935
      b->minOccurs, b->maxOccurs) != 0)
16936
  return (1);
16937
16938
    return (0);
16939
}
16940
16941
/**
16942
 * xmlSchemaCheckRCaseRecurseAsIfGroup:
16943
 * @ctxt:  the schema parser context
16944
 * @r: the restricting element declaration particle
16945
 * @b: the base model group particle
16946
 *
16947
 * (3.9.6) Constraints on Particle Schema Components
16948
 * Schema Component Constraint:
16949
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16950
 * (rcase-RecurseAsIfGroup)
16951
 *
16952
 * STATUS: TODO
16953
 *
16954
 * Returns 0 if the constraints are satisfied, a positive
16955
 * error code if not and -1 if an internal error occurred.
16956
 */
16957
static int
16958
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16959
            xmlSchemaParticlePtr r,
16960
            xmlSchemaParticlePtr b)
16961
{
16962
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16963
    TODO
16964
    return (0);
16965
}
16966
16967
/**
16968
 * xmlSchemaCheckRCaseNSSubset:
16969
 * @ctxt:  the schema parser context
16970
 * @r: the restricting wildcard particle
16971
 * @b: the base wildcard particle
16972
 *
16973
 * (3.9.6) Constraints on Particle Schema Components
16974
 * Schema Component Constraint:
16975
 * Particle Derivation OK (Any:Any -- NSSubset)
16976
 * (rcase-NSSubset)
16977
 *
16978
 * STATUS: complete
16979
 *
16980
 * Returns 0 if the constraints are satisfied, a positive
16981
 * error code if not and -1 if an internal error occurred.
16982
 */
16983
static int
16984
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16985
            xmlSchemaParticlePtr r,
16986
            xmlSchemaParticlePtr b,
16987
            int isAnyTypeBase)
16988
{
16989
    /* TODO: Error codes (rcase-NSSubset). */
16990
    /*
16991
    * SPEC (1) "R's occurrence range is a valid restriction of B's
16992
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16993
    */
16994
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16995
      b->minOccurs, b->maxOccurs))
16996
  return (1);
16997
    /*
16998
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
16999
    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17000
    */
17001
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
17002
  (xmlSchemaWildcardPtr) b->children))
17003
  return (1);
17004
    /*
17005
    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17006
    * definition`, R's {process contents} must be identical to or stronger
17007
    * than B's {process contents}, where strict is stronger than lax is
17008
    * stronger than skip."
17009
    */
17010
    if (! isAnyTypeBase) {
17011
  if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17012
      ((xmlSchemaWildcardPtr) b->children)->processContents)
17013
      return (1);
17014
    }
17015
17016
    return (0);
17017
}
17018
17019
/**
17020
 * xmlSchemaCheckCOSParticleRestrict:
17021
 * @ctxt:  the schema parser context
17022
 * @type:  the complex type definition
17023
 *
17024
 * (3.9.6) Constraints on Particle Schema Components
17025
 * Schema Component Constraint:
17026
 * Particle Valid (Restriction) (cos-particle-restrict)
17027
 *
17028
 * STATUS: TODO
17029
 *
17030
 * Returns 0 if the constraints are satisfied, a positive
17031
 * error code if not and -1 if an internal error occurred.
17032
 */
17033
static int
17034
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17035
          xmlSchemaParticlePtr r,
17036
          xmlSchemaParticlePtr b)
17037
{
17038
    int ret = 0;
17039
17040
    /*part = WXS_TYPE_PARTICLE(type);
17041
    basePart = WXS_TYPE_PARTICLE(base);
17042
    */
17043
17044
    TODO
17045
17046
    /*
17047
    * SPEC (1) "They are the same particle."
17048
    */
17049
    if (r == b)
17050
  return (0);
17051
17052
17053
    return (0);
17054
}
17055
17056
#if 0
17057
/**
17058
 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17059
 * @ctxt:  the schema parser context
17060
 * @r: the model group particle
17061
 * @b: the base wildcard particle
17062
 *
17063
 * (3.9.6) Constraints on Particle Schema Components
17064
 * Schema Component Constraint:
17065
 * Particle Derivation OK (All/Choice/Sequence:Any --
17066
 *                         NSRecurseCheckCardinality)
17067
 * (rcase-NSRecurseCheckCardinality)
17068
 *
17069
 * STATUS: TODO: subst-groups
17070
 *
17071
 * Returns 0 if the constraints are satisfied, a positive
17072
 * error code if not and -1 if an internal error occurred.
17073
 */
17074
static int
17075
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17076
               xmlSchemaParticlePtr r,
17077
               xmlSchemaParticlePtr b)
17078
{
17079
    xmlSchemaParticlePtr part;
17080
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17081
    if ((r->children == NULL) || (r->children->children == NULL))
17082
  return (-1);
17083
    /*
17084
    * SPEC "For a group particle to be a `valid restriction` of a
17085
    * wildcard particle..."
17086
    *
17087
    * SPEC (1) "Every member of the {particles} of the group is a `valid
17088
    * restriction` of the wildcard as defined by
17089
    * Particle Valid (Restriction) ($3.9.6)."
17090
    */
17091
    part = (xmlSchemaParticlePtr) r->children->children;
17092
    do {
17093
  if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17094
      return (1);
17095
  part = (xmlSchemaParticlePtr) part->next;
17096
    } while (part != NULL);
17097
    /*
17098
    * SPEC (2) "The effective total range of the group [...] is a
17099
    * valid restriction of B's occurrence range as defined by
17100
    * Occurrence Range OK ($3.9.6)."
17101
    */
17102
    if (xmlSchemaCheckParticleRangeOK(
17103
      xmlSchemaGetParticleTotalRangeMin(r),
17104
      xmlSchemaGetParticleTotalRangeMax(r),
17105
      b->minOccurs, b->maxOccurs) != 0)
17106
  return (1);
17107
    return (0);
17108
}
17109
#endif
17110
17111
/**
17112
 * xmlSchemaCheckRCaseRecurse:
17113
 * @ctxt:  the schema parser context
17114
 * @r: the <all> or <sequence> model group particle
17115
 * @b: the base <all> or <sequence> model group particle
17116
 *
17117
 * (3.9.6) Constraints on Particle Schema Components
17118
 * Schema Component Constraint:
17119
 * Particle Derivation OK (All:All,Sequence:Sequence --
17120
                           Recurse)
17121
 * (rcase-Recurse)
17122
 *
17123
 * STATUS:  ?
17124
 * TODO: subst-groups
17125
 *
17126
 * Returns 0 if the constraints are satisfied, a positive
17127
 * error code if not and -1 if an internal error occurred.
17128
 */
17129
static int
17130
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17131
         xmlSchemaParticlePtr r,
17132
         xmlSchemaParticlePtr b)
17133
{
17134
    /* xmlSchemaParticlePtr part; */
17135
    /* TODO: Error codes (rcase-Recurse). */
17136
    if ((r->children == NULL) || (b->children == NULL) ||
17137
  (r->children->type != b->children->type))
17138
  return (-1);
17139
    /*
17140
    * SPEC "For an all or sequence group particle to be a `valid
17141
    * restriction` of another group particle with the same {compositor}..."
17142
    *
17143
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17144
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17145
    */
17146
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17147
      b->minOccurs, b->maxOccurs))
17148
  return (1);
17149
17150
17151
    return (0);
17152
}
17153
17154
#endif
17155
17156
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17157
175
    xmlSchemaPCustomErrExt(pctxt,      \
17158
175
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17159
175
  WXS_BASIC_CAST fac1, fac1->node, \
17160
175
  "It is an error for both '%s' and '%s' to be specified on the "\
17161
175
  "same type definition", \
17162
175
  BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17163
175
  BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17164
17165
#define FACET_RESTR_ERR(fac1, msg) \
17166
101
    xmlSchemaPCustomErr(pctxt,      \
17167
101
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17168
101
  WXS_BASIC_CAST fac1, fac1->node, \
17169
101
  msg, NULL);
17170
17171
#define FACET_RESTR_FIXED_ERR(fac) \
17172
0
    xmlSchemaPCustomErr(pctxt, \
17173
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17174
0
  WXS_BASIC_CAST fac, fac->node, \
17175
0
  "The base type's facet is 'fixed', thus the value must not " \
17176
0
  "differ", NULL);
17177
17178
static void
17179
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17180
      xmlSchemaFacetPtr facet1,
17181
      xmlSchemaFacetPtr facet2,
17182
      int lessGreater,
17183
      int orEqual,
17184
      int ofBase)
17185
534
{
17186
534
    xmlChar *msg = NULL;
17187
17188
534
    msg = xmlStrdup(BAD_CAST "'");
17189
534
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17190
534
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
17191
534
    if (lessGreater == 0)
17192
14
  msg = xmlStrcat(msg, BAD_CAST " equal to");
17193
534
    if (lessGreater == 1)
17194
256
  msg = xmlStrcat(msg, BAD_CAST " greater than");
17195
278
    else
17196
278
  msg = xmlStrcat(msg, BAD_CAST " less than");
17197
17198
534
    if (orEqual)
17199
298
  msg = xmlStrcat(msg, BAD_CAST " or equal to");
17200
534
    msg = xmlStrcat(msg, BAD_CAST " '");
17201
534
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17202
534
    if (ofBase)
17203
99
  msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17204
435
    else
17205
435
  msg = xmlStrcat(msg, BAD_CAST "'");
17206
17207
534
    xmlSchemaPCustomErr(pctxt,
17208
534
  XML_SCHEMAP_INVALID_FACET_VALUE,
17209
534
  WXS_BASIC_CAST facet1, NULL,
17210
534
  (const char *) msg, NULL);
17211
17212
534
    if (msg != NULL)
17213
534
  xmlFree(msg);
17214
534
}
17215
17216
/*
17217
* xmlSchemaDeriveAndValidateFacets:
17218
*
17219
* Schema Component Constraint: Simple Type Restriction (Facets)
17220
* (st-restrict-facets)
17221
*/
17222
static int
17223
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17224
         xmlSchemaTypePtr type)
17225
4.12k
{
17226
4.12k
    xmlSchemaTypePtr base = type->baseType;
17227
4.12k
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
17228
4.12k
    xmlSchemaFacetPtr facet, bfacet,
17229
4.12k
  flength = NULL, ftotdig = NULL, ffracdig = NULL,
17230
4.12k
  fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17231
4.12k
  fmininc = NULL, fmaxinc = NULL,
17232
4.12k
  fminexc = NULL, fmaxexc = NULL,
17233
4.12k
  bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17234
4.12k
  bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17235
4.12k
  bfmininc = NULL, bfmaxinc = NULL,
17236
4.12k
  bfminexc = NULL, bfmaxexc = NULL;
17237
4.12k
    int res; /* err = 0, fixedErr; */
17238
17239
    /*
17240
    * SPEC st-restrict-facets 1:
17241
    * "The {variety} of R is the same as that of B."
17242
    */
17243
    /*
17244
    * SPEC st-restrict-facets 2:
17245
    * "If {variety} is atomic, the {primitive type definition}
17246
    * of R is the same as that of B."
17247
    *
17248
    * NOTE: we leave 1 & 2 out for now, since this will be
17249
    * satisfied by the derivation process.
17250
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
17251
    */
17252
    /*
17253
    * SPEC st-restrict-facets 3:
17254
    * "The {facets} of R are the union of S and the {facets}
17255
    * of B, eliminating duplicates. To eliminate duplicates,
17256
    * when a facet of the same kind occurs in both S and the
17257
    * {facets} of B, the one in the {facets} of B is not
17258
    * included, with the exception of enumeration and pattern
17259
    * facets, for which multiple occurrences with distinct values
17260
    * are allowed."
17261
    */
17262
17263
4.12k
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
17264
0
  return (0);
17265
17266
4.12k
    last = type->facetSet;
17267
4.12k
    if (last != NULL)
17268
7.52k
  while (last->next != NULL)
17269
3.43k
      last = last->next;
17270
17271
11.6k
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17272
7.52k
  facet = cur->facet;
17273
7.52k
  switch (facet->type) {
17274
206
      case XML_SCHEMA_FACET_LENGTH:
17275
206
    flength = facet; break;
17276
258
      case XML_SCHEMA_FACET_MINLENGTH:
17277
258
    fminlen = facet; break;
17278
581
      case XML_SCHEMA_FACET_MININCLUSIVE:
17279
581
    fmininc = facet; break;
17280
540
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17281
540
    fminexc = facet; break;
17282
157
      case XML_SCHEMA_FACET_MAXLENGTH:
17283
157
    fmaxlen = facet; break;
17284
849
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17285
849
    fmaxinc = facet; break;
17286
407
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17287
407
    fmaxexc = facet; break;
17288
103
      case XML_SCHEMA_FACET_TOTALDIGITS:
17289
103
    ftotdig = facet; break;
17290
30
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17291
30
    ffracdig = facet; break;
17292
4.39k
      default:
17293
4.39k
    break;
17294
7.52k
  }
17295
7.52k
    }
17296
5.81k
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17297
1.68k
  facet = cur->facet;
17298
1.68k
  switch (facet->type) {
17299
480
      case XML_SCHEMA_FACET_LENGTH:
17300
480
    bflength = facet; break;
17301
196
      case XML_SCHEMA_FACET_MINLENGTH:
17302
196
    bfminlen = facet; break;
17303
240
      case XML_SCHEMA_FACET_MININCLUSIVE:
17304
240
    bfmininc = facet; break;
17305
64
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17306
64
    bfminexc = facet; break;
17307
140
      case XML_SCHEMA_FACET_MAXLENGTH:
17308
140
    bfmaxlen = facet; break;
17309
43
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17310
43
    bfmaxinc = facet; break;
17311
42
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17312
42
    bfmaxexc = facet; break;
17313
74
      case XML_SCHEMA_FACET_TOTALDIGITS:
17314
74
    bftotdig = facet; break;
17315
10
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17316
10
    bffracdig = facet; break;
17317
400
      default:
17318
400
    break;
17319
1.68k
  }
17320
1.68k
    }
17321
    /*
17322
    * length and minLength or maxLength (2.2) + (3.2)
17323
    */
17324
4.12k
    if (flength && (fminlen || fmaxlen)) {
17325
74
  FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17326
74
      "either of 'minLength' or 'maxLength' to be specified on "
17327
74
      "the same type definition")
17328
74
    }
17329
    /*
17330
    * Mutual exclusions in the same derivation step.
17331
    */
17332
4.12k
    if ((fmaxinc) && (fmaxexc)) {
17333
  /*
17334
  * SCC "maxInclusive and maxExclusive"
17335
  */
17336
126
  FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17337
126
    }
17338
4.12k
    if ((fmininc) && (fminexc)) {
17339
  /*
17340
  * SCC "minInclusive and minExclusive"
17341
  */
17342
49
  FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17343
49
    }
17344
17345
4.12k
    if (flength && bflength) {
17346
  /*
17347
  * SCC "length valid restriction"
17348
  * The values have to be equal.
17349
  */
17350
16
  res = xmlSchemaCompareValues(flength->val, bflength->val);
17351
16
  if (res == -2)
17352
1
      goto internal_error;
17353
15
  if (res != 0)
17354
14
      xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17355
15
  if ((res != 0) && (bflength->fixed)) {
17356
0
      FACET_RESTR_FIXED_ERR(flength)
17357
0
  }
17358
17359
15
    }
17360
4.12k
    if (fminlen && bfminlen) {
17361
  /*
17362
  * SCC "minLength valid restriction"
17363
  * minLength >= BASE minLength
17364
  */
17365
12
  res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17366
12
  if (res == -2)
17367
1
      goto internal_error;
17368
11
  if (res == -1)
17369
4
      xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17370
11
  if ((res != 0) && (bfminlen->fixed)) {
17371
0
      FACET_RESTR_FIXED_ERR(fminlen)
17372
0
  }
17373
11
    }
17374
4.12k
    if (fmaxlen && bfmaxlen) {
17375
  /*
17376
  * SCC "maxLength valid restriction"
17377
  * maxLength <= BASE minLength
17378
  */
17379
5
  res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17380
5
  if (res == -2)
17381
1
      goto internal_error;
17382
4
  if (res == 1)
17383
2
      xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17384
4
  if ((res != 0) && (bfmaxlen->fixed)) {
17385
0
      FACET_RESTR_FIXED_ERR(fmaxlen)
17386
0
  }
17387
4
    }
17388
    /*
17389
    * SCC "length and minLength or maxLength"
17390
    */
17391
4.12k
    if (! flength)
17392
3.99k
  flength = bflength;
17393
4.12k
    if (flength) {
17394
156
  if (! fminlen)
17395
84
      fminlen = bfminlen;
17396
156
  if (fminlen) {
17397
      /* (1.1) length >= minLength */
17398
106
      res = xmlSchemaCompareValues(flength->val, fminlen->val);
17399
106
      if (res == -2)
17400
14
    goto internal_error;
17401
92
      if (res == -1)
17402
56
    xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17403
92
  }
17404
142
  if (! fmaxlen)
17405
115
      fmaxlen = bfmaxlen;
17406
142
  if (fmaxlen) {
17407
      /* (2.1) length <= maxLength */
17408
48
      res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17409
48
      if (res == -2)
17410
3
    goto internal_error;
17411
45
      if (res == 1)
17412
27
    xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17413
45
  }
17414
142
    }
17415
4.10k
    if (fmaxinc) {
17416
  /*
17417
  * "maxInclusive"
17418
  */
17419
723
  if (fmininc) {
17420
      /* SCC "maxInclusive >= minInclusive" */
17421
302
      res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17422
302
      if (res == -2)
17423
3
    goto internal_error;
17424
299
      if (res == -1) {
17425
52
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17426
52
      }
17427
299
  }
17428
  /*
17429
  * SCC "maxInclusive valid restriction"
17430
  */
17431
720
  if (bfmaxinc) {
17432
      /* maxInclusive <= BASE maxInclusive */
17433
9
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17434
9
      if (res == -2)
17435
1
    goto internal_error;
17436
8
      if (res == 1)
17437
2
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17438
8
      if ((res != 0) && (bfmaxinc->fixed)) {
17439
0
    FACET_RESTR_FIXED_ERR(fmaxinc)
17440
0
      }
17441
8
  }
17442
719
  if (bfmaxexc) {
17443
      /* maxInclusive < BASE maxExclusive */
17444
5
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17445
5
      if (res == -2)
17446
1
    goto internal_error;
17447
4
      if (res != -1) {
17448
3
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17449
3
      }
17450
4
  }
17451
718
  if (bfmininc) {
17452
      /* maxInclusive >= BASE minInclusive */
17453
142
      res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17454
142
      if (res == -2)
17455
6
    goto internal_error;
17456
136
      if (res == -1) {
17457
3
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17458
3
      }
17459
136
  }
17460
712
  if (bfminexc) {
17461
      /* maxInclusive > BASE minExclusive */
17462
6
      res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17463
6
      if (res == -2)
17464
1
    goto internal_error;
17465
5
      if (res != 1) {
17466
2
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17467
2
      }
17468
5
  }
17469
712
    }
17470
4.09k
    if (fmaxexc) {
17471
  /*
17472
  * "maxExclusive >= minExclusive"
17473
  */
17474
377
  if (fminexc) {
17475
192
      res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17476
192
      if (res == -2)
17477
2
    goto internal_error;
17478
190
      if (res == -1) {
17479
103
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17480
103
      }
17481
190
  }
17482
  /*
17483
  * "maxExclusive valid restriction"
17484
  */
17485
375
  if (bfmaxexc) {
17486
      /* maxExclusive <= BASE maxExclusive */
17487
15
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17488
15
      if (res == -2)
17489
1
    goto internal_error;
17490
14
      if (res == 1) {
17491
9
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17492
9
      }
17493
14
      if ((res != 0) && (bfmaxexc->fixed)) {
17494
0
    FACET_RESTR_FIXED_ERR(fmaxexc)
17495
0
      }
17496
14
  }
17497
374
  if (bfmaxinc) {
17498
      /* maxExclusive <= BASE maxInclusive */
17499
17
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17500
17
      if (res == -2)
17501
6
    goto internal_error;
17502
11
      if (res == 1) {
17503
3
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17504
3
      }
17505
11
  }
17506
368
  if (bfmininc) {
17507
      /* maxExclusive > BASE minInclusive */
17508
111
      res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17509
111
      if (res == -2)
17510
3
    goto internal_error;
17511
108
      if (res != 1) {
17512
7
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17513
7
      }
17514
108
  }
17515
365
  if (bfminexc) {
17516
      /* maxExclusive > BASE minExclusive */
17517
11
      res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17518
11
      if (res == -2)
17519
1
    goto internal_error;
17520
10
      if (res != 1) {
17521
5
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17522
5
      }
17523
10
  }
17524
365
    }
17525
4.08k
    if (fminexc) {
17526
  /*
17527
  * "minExclusive < maxInclusive"
17528
  */
17529
512
  if (fmaxinc) {
17530
290
      res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17531
290
      if (res == -2)
17532
5
    goto internal_error;
17533
285
      if (res != -1) {
17534
142
    xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17535
142
      }
17536
285
  }
17537
  /*
17538
  * "minExclusive valid restriction"
17539
  */
17540
507
  if (bfminexc) {
17541
      /* minExclusive >= BASE minExclusive */
17542
5
      res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17543
5
      if (res == -2)
17544
1
    goto internal_error;
17545
4
      if (res == -1) {
17546
2
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17547
2
      }
17548
4
      if ((res != 0) && (bfminexc->fixed)) {
17549
0
    FACET_RESTR_FIXED_ERR(fminexc)
17550
0
      }
17551
4
  }
17552
506
  if (bfmaxinc) {
17553
      /* minExclusive <= BASE maxInclusive */
17554
8
      res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17555
8
      if (res == -2)
17556
1
    goto internal_error;
17557
7
      if (res == 1) {
17558
1
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17559
1
      }
17560
7
  }
17561
505
  if (bfmininc) {
17562
      /* minExclusive >= BASE minInclusive */
17563
31
      res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17564
31
      if (res == -2)
17565
3
    goto internal_error;
17566
28
      if (res == -1) {
17567
5
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17568
5
      }
17569
28
  }
17570
502
  if (bfmaxexc) {
17571
      /* minExclusive < BASE maxExclusive */
17572
12
      res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17573
12
      if (res == -2)
17574
5
    goto internal_error;
17575
7
      if (res != -1) {
17576
4
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17577
4
      }
17578
7
  }
17579
502
    }
17580
4.06k
    if (fmininc) {
17581
  /*
17582
  * "minInclusive < maxExclusive"
17583
  */
17584
532
  if (fmaxexc) {
17585
65
      res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17586
65
      if (res == -2)
17587
2
    goto internal_error;
17588
63
      if (res != -1) {
17589
43
    xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17590
43
      }
17591
63
  }
17592
  /*
17593
  * "minExclusive valid restriction"
17594
  */
17595
530
  if (bfmininc) {
17596
      /* minInclusive >= BASE minInclusive */
17597
46
      res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17598
46
      if (res == -2)
17599
1
    goto internal_error;
17600
45
      if (res == -1) {
17601
8
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17602
8
      }
17603
45
      if ((res != 0) && (bfmininc->fixed)) {
17604
0
    FACET_RESTR_FIXED_ERR(fmininc)
17605
0
      }
17606
45
  }
17607
529
  if (bfmaxinc) {
17608
      /* minInclusive <= BASE maxInclusive */
17609
7
      res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17610
7
      if (res == -2)
17611
1
    goto internal_error;
17612
6
      if (res == 1) {
17613
1
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17614
1
      }
17615
6
  }
17616
528
  if (bfminexc) {
17617
      /* minInclusive > BASE minExclusive */
17618
15
      res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17619
15
      if (res == -2)
17620
1
    goto internal_error;
17621
14
      if (res != 1)
17622
9
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17623
14
  }
17624
527
  if (bfmaxexc) {
17625
      /* minInclusive < BASE maxExclusive */
17626
8
      res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17627
8
      if (res == -2)
17628
0
    goto internal_error;
17629
8
      if (res != -1)
17630
7
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17631
8
  }
17632
527
    }
17633
4.06k
    if (ftotdig && bftotdig) {
17634
  /*
17635
  * SCC " totalDigits valid restriction"
17636
  * totalDigits <= BASE totalDigits
17637
  */
17638
11
  res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17639
11
  if (res == -2)
17640
1
      goto internal_error;
17641
10
  if (res == 1)
17642
2
      xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17643
2
      -1, 1, 1);
17644
10
  if ((res != 0) && (bftotdig->fixed)) {
17645
0
      FACET_RESTR_FIXED_ERR(ftotdig)
17646
0
  }
17647
10
    }
17648
4.06k
    if (ffracdig && bffracdig) {
17649
  /*
17650
  * SCC  "fractionDigits valid restriction"
17651
  * fractionDigits <= BASE fractionDigits
17652
  */
17653
9
  res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17654
9
  if (res == -2)
17655
1
      goto internal_error;
17656
8
  if (res == 1)
17657
6
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17658
6
      -1, 1, 1);
17659
8
  if ((res != 0) && (bffracdig->fixed)) {
17660
0
      FACET_RESTR_FIXED_ERR(ffracdig)
17661
0
  }
17662
8
    }
17663
    /*
17664
    * SCC "fractionDigits less than or equal to totalDigits"
17665
    */
17666
4.05k
    if (! ftotdig)
17667
3.97k
  ftotdig = bftotdig;
17668
4.05k
    if (! ffracdig)
17669
4.03k
  ffracdig = bffracdig;
17670
4.05k
    if (ftotdig && ffracdig) {
17671
22
  res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17672
22
  if (res == -2)
17673
1
      goto internal_error;
17674
21
  if (res == 1)
17675
12
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17676
12
    -1, 1, 0);
17677
21
    }
17678
    /*
17679
    * *Enumerations* won' be added here, since only the first set
17680
    * of enumerations in the ancestor-or-self axis is used
17681
    * for validation, plus we need to use the base type of those
17682
    * enumerations for whitespace.
17683
    *
17684
    * *Patterns*: won't be add here, since they are ORed at
17685
    * type level and ANDed at ancestor level. This will
17686
    * happen during validation by walking the base axis
17687
    * of the type.
17688
    */
17689
5.13k
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17690
1.07k
  bfacet = cur->facet;
17691
  /*
17692
  * Special handling of enumerations and patterns.
17693
  * TODO: hmm, they should not appear in the set, so remove this.
17694
  */
17695
1.07k
  if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17696
1.07k
      (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17697
221
      continue;
17698
  /*
17699
  * Search for a duplicate facet in the current type.
17700
  */
17701
858
  link = type->facetSet;
17702
  /* err = 0; */
17703
  /* fixedErr = 0; */
17704
4.22k
  while (link != NULL) {
17705
3.89k
      facet = link->facet;
17706
3.89k
      if (facet->type == bfacet->type) {
17707
536
    switch (facet->type) {
17708
103
        case XML_SCHEMA_FACET_WHITESPACE:
17709
      /*
17710
      * The whitespace must be stronger.
17711
      */
17712
103
      if (facet->whitespace < bfacet->whitespace) {
17713
27
          FACET_RESTR_ERR(facet,
17714
27
        "The 'whitespace' value has to be equal to "
17715
27
        "or stronger than the 'whitespace' value of "
17716
27
        "the base type")
17717
27
      }
17718
103
      if ((bfacet->fixed) &&
17719
103
          (facet->whitespace != bfacet->whitespace)) {
17720
0
          FACET_RESTR_FIXED_ERR(facet)
17721
0
      }
17722
103
      break;
17723
433
        default:
17724
433
      break;
17725
536
    }
17726
    /* Duplicate found. */
17727
536
    break;
17728
536
      }
17729
3.36k
      link = link->next;
17730
3.36k
  }
17731
  /*
17732
  * If no duplicate was found: add the base types's facet
17733
  * to the set.
17734
  */
17735
858
  if (link == NULL) {
17736
322
      link = (xmlSchemaFacetLinkPtr)
17737
322
    xmlMalloc(sizeof(xmlSchemaFacetLink));
17738
322
      if (link == NULL) {
17739
0
    xmlSchemaPErrMemory(pctxt);
17740
0
    return (-1);
17741
0
      }
17742
322
      link->facet = cur->facet;
17743
322
      link->next = NULL;
17744
322
      if (last == NULL)
17745
34
    type->facetSet = link;
17746
288
      else
17747
288
    last->next = link;
17748
322
      last = link;
17749
322
  }
17750
17751
858
    }
17752
17753
4.05k
    return (0);
17754
68
internal_error:
17755
68
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17756
68
  "an error occurred");
17757
68
    return (-1);
17758
4.05k
}
17759
17760
static int
17761
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17762
               xmlSchemaTypePtr type)
17763
314
{
17764
314
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17765
    /*
17766
    * The actual value is then formed by replacing any union type
17767
    * definition in the `explicit members` with the members of their
17768
    * {member type definitions}, in order.
17769
    *
17770
    * TODO: There's a bug entry at
17771
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17772
    * which indicates that we'll keep the union types the future.
17773
    */
17774
314
    link = type->memberTypes;
17775
1.11k
    while (link != NULL) {
17776
17777
797
  if (WXS_IS_TYPE_NOT_FIXED(link->type))
17778
276
      xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17779
17780
797
  if (WXS_IS_UNION(link->type)) {
17781
91
      subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17782
91
      if (subLink != NULL) {
17783
91
    link->type = subLink->type;
17784
91
    if (subLink->next != NULL) {
17785
91
        lastLink = link->next;
17786
91
        subLink = subLink->next;
17787
91
        prevLink = link;
17788
273
        while (subLink != NULL) {
17789
182
      newLink = (xmlSchemaTypeLinkPtr)
17790
182
          xmlMalloc(sizeof(xmlSchemaTypeLink));
17791
182
      if (newLink == NULL) {
17792
0
          xmlSchemaPErrMemory(pctxt);
17793
0
          return (-1);
17794
0
      }
17795
182
      newLink->type = subLink->type;
17796
182
      prevLink->next = newLink;
17797
182
      prevLink = newLink;
17798
182
      newLink->next = lastLink;
17799
17800
182
      subLink = subLink->next;
17801
182
        }
17802
91
    }
17803
91
      }
17804
91
  }
17805
797
  link = link->next;
17806
797
    }
17807
314
    return (0);
17808
314
}
17809
17810
static void
17811
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17812
4.51k
{
17813
4.51k
    int has = 0, needVal = 0, normVal = 0;
17814
17815
4.51k
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17816
4.51k
    if (has) {
17817
258
  needVal = (type->baseType->flags &
17818
258
      XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17819
258
  normVal = (type->baseType->flags &
17820
258
      XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17821
258
    }
17822
4.51k
    if (type->facets != NULL) {
17823
4.01k
  xmlSchemaFacetPtr fac;
17824
17825
11.3k
  for (fac = type->facets; fac != NULL; fac = fac->next) {
17826
7.35k
      switch (fac->type) {
17827
483
    case XML_SCHEMA_FACET_WHITESPACE:
17828
483
        break;
17829
2.83k
    case XML_SCHEMA_FACET_PATTERN:
17830
2.83k
        normVal = 1;
17831
2.83k
        has = 1;
17832
2.83k
        break;
17833
1.01k
    case XML_SCHEMA_FACET_ENUMERATION:
17834
1.01k
        needVal = 1;
17835
1.01k
        normVal = 1;
17836
1.01k
        has = 1;
17837
1.01k
        break;
17838
3.02k
    default:
17839
3.02k
        has = 1;
17840
3.02k
        break;
17841
7.35k
      }
17842
7.35k
  }
17843
4.01k
    }
17844
4.51k
    if (normVal)
17845
2.80k
  type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17846
4.51k
    if (needVal)
17847
509
  type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17848
4.51k
    if (has)
17849
4.01k
  type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17850
17851
4.51k
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17852
3.42k
  xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17853
  /*
17854
  * OPTIMIZE VAL TODO: Some facets need a computed value.
17855
  */
17856
3.42k
  if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17857
3.42k
      (prim->builtInType != XML_SCHEMAS_STRING)) {
17858
1.05k
      type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17859
1.05k
  }
17860
3.42k
    }
17861
4.51k
}
17862
17863
static int
17864
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17865
4.52k
{
17866
17867
17868
    /*
17869
    * Evaluate the whitespace-facet value.
17870
    */
17871
4.52k
    if (WXS_IS_LIST(type)) {
17872
186
  type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17873
186
  return (0);
17874
4.33k
    } else if (WXS_IS_UNION(type))
17875
325
  return (0);
17876
17877
4.01k
    if (type->facetSet != NULL) {
17878
3.94k
  xmlSchemaFacetLinkPtr lin;
17879
17880
10.1k
  for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17881
6.62k
      if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17882
414
    switch (lin->facet->whitespace) {
17883
84
    case XML_SCHEMAS_FACET_PRESERVE:
17884
84
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17885
84
        break;
17886
201
    case XML_SCHEMAS_FACET_REPLACE:
17887
201
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17888
201
        break;
17889
118
    case XML_SCHEMAS_FACET_COLLAPSE:
17890
118
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17891
118
        break;
17892
11
    default:
17893
11
        return (-1);
17894
414
    }
17895
403
    return (0);
17896
414
      }
17897
6.62k
  }
17898
3.94k
    }
17899
    /*
17900
    * For all `atomic` datatypes other than string (and types `derived`
17901
    * by `restriction` from it) the value of whiteSpace is fixed to
17902
    * collapse
17903
    */
17904
3.59k
    {
17905
3.59k
  xmlSchemaTypePtr anc;
17906
17907
3.70k
  for (anc = type->baseType; anc != NULL &&
17908
3.70k
    anc->builtInType != XML_SCHEMAS_ANYTYPE;
17909
3.70k
    anc = anc->baseType) {
17910
17911
3.70k
      if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17912
3.59k
    if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17913
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17914
17915
3.59k
    } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17916
3.59k
        (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17917
2.28k
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17918
17919
2.28k
    } else
17920
1.30k
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17921
3.59k
    break;
17922
3.59k
      }
17923
3.70k
  }
17924
3.59k
    }
17925
3.59k
    return (0);
17926
4.01k
}
17927
17928
static int
17929
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17930
        xmlSchemaTypePtr type)
17931
8.73k
{
17932
8.73k
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17933
0
  return(0);
17934
8.73k
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17935
0
  return(0);
17936
8.73k
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17937
17938
8.73k
    if (WXS_IS_LIST(type)) {
17939
  /*
17940
  * Corresponds to <simpleType><list>...
17941
  */
17942
54
  if (type->subtypes == NULL) {
17943
      /*
17944
      * This one is really needed, so get out.
17945
      */
17946
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17947
0
    "list type has no item-type assigned");
17948
0
      return(-1);
17949
0
  }
17950
8.68k
    } else if (WXS_IS_UNION(type)) {
17951
  /*
17952
  * Corresponds to <simpleType><union>...
17953
  */
17954
315
  if (type->memberTypes == NULL) {
17955
      /*
17956
      * This one is really needed, so get out.
17957
      */
17958
1
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17959
1
    "union type has no member-types assigned");
17960
1
      return(-1);
17961
1
  }
17962
8.36k
    } else {
17963
  /*
17964
  * Corresponds to <simpleType><restriction>...
17965
  */
17966
8.36k
  if (type->baseType == NULL) {
17967
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17968
0
    "type has no base-type assigned");
17969
0
      return(-1);
17970
0
  }
17971
8.36k
  if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17972
535
      if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17973
0
    return(-1);
17974
  /*
17975
  * Variety
17976
  * If the <restriction> alternative is chosen, then the
17977
  * {variety} of the {base type definition}.
17978
  */
17979
8.36k
  if (WXS_IS_ATOMIC(type->baseType))
17980
7.91k
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17981
446
  else if (WXS_IS_LIST(type->baseType)) {
17982
403
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17983
      /*
17984
      * Inherit the itemType.
17985
      */
17986
403
      type->subtypes = type->baseType->subtypes;
17987
403
  } else if (WXS_IS_UNION(type->baseType)) {
17988
43
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17989
      /*
17990
      * NOTE that we won't assign the memberTypes of the base,
17991
      * since this will make trouble when freeing them; we will
17992
      * use a lookup function to access them instead.
17993
      */
17994
43
  }
17995
8.36k
    }
17996
8.73k
    return(0);
17997
8.73k
}
17998
17999
/*
18000
* 3.14.6 Constraints on Simple Type Definition Schema Components
18001
*/
18002
static int
18003
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18004
         xmlSchemaTypePtr type)
18005
8.73k
{
18006
8.73k
    int res, olderrs = pctxt->nberrors;
18007
18008
8.73k
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18009
0
  return(-1);
18010
18011
8.73k
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18012
0
  return(0);
18013
18014
8.73k
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18015
8.73k
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18016
18017
8.73k
    if (type->baseType == NULL) {
18018
0
  PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18019
0
      "missing baseType");
18020
0
  goto exit_failure;
18021
0
    }
18022
8.73k
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18023
535
  xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18024
    /*
18025
    * If a member type of a union is a union itself, we need to substitute
18026
    * that member type for its member types.
18027
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18028
    * types in WXS 1.1.
18029
    */
18030
8.73k
    if ((type->memberTypes != NULL) &&
18031
8.73k
  (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18032
0
  return(-1);
18033
    /*
18034
    * SPEC src-simple-type 1
18035
    * "The corresponding simple type definition, if any, must satisfy
18036
    * the conditions set out in Constraints on Simple Type Definition
18037
    * Schema Components ($3.14.6)."
18038
    */
18039
    /*
18040
    * Schema Component Constraint: Simple Type Definition Properties Correct
18041
    * (st-props-correct)
18042
    */
18043
8.73k
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18044
8.73k
    HFAILURE HERROR
18045
    /*
18046
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18047
    * (cos-st-restricts)
18048
    */
18049
8.73k
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18050
8.73k
    HFAILURE HERROR
18051
    /*
18052
    * TODO: Removed the error report, since it got annoying to get an
18053
    * extra error report, if anything failed until now.
18054
    * Enable this if needed.
18055
    *
18056
    * xmlSchemaPErr(ctxt, type->node,
18057
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18058
    *    "Simple type '%s' does not satisfy the constraints "
18059
    *    "on simple type definitions.\n",
18060
    *    type->name, NULL);
18061
    */
18062
    /*
18063
    * Schema Component Constraint: Simple Type Restriction (Facets)
18064
    * (st-restrict-facets)
18065
    */
18066
8.69k
    res = xmlSchemaCheckFacetValues(type, pctxt);
18067
8.69k
    HFAILURE HERROR
18068
4.59k
    if ((type->facetSet != NULL) ||
18069
4.59k
  (type->baseType->facetSet != NULL)) {
18070
4.12k
  res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18071
4.12k
  HFAILURE HERROR
18072
4.05k
    }
18073
    /*
18074
    * Whitespace value.
18075
    */
18076
4.52k
    res = xmlSchemaTypeFixupWhitespace(type);
18077
4.52k
    HFAILURE HERROR
18078
4.51k
    xmlSchemaTypeFixupOptimFacets(type);
18079
18080
8.62k
exit_error:
18081
8.62k
    if (olderrs != pctxt->nberrors)
18082
4.81k
  return(pctxt->err);
18083
3.81k
    return(0);
18084
18085
103
exit_failure:
18086
103
    return(-1);
18087
8.62k
}
18088
18089
static int
18090
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18091
        xmlSchemaTypePtr type)
18092
1.60k
{
18093
1.60k
    int res = 0, olderrs = pctxt->nberrors;
18094
1.60k
    xmlSchemaTypePtr baseType = type->baseType;
18095
18096
1.60k
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18097
0
  return(0);
18098
1.60k
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18099
1.60k
    if (baseType == NULL) {
18100
0
  PERROR_INT("xmlSchemaFixupComplexType",
18101
0
      "missing baseType");
18102
0
  goto exit_failure;
18103
0
    }
18104
    /*
18105
    * Fixup the base type.
18106
    */
18107
1.60k
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
18108
202
  xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18109
1.60k
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18110
  /*
18111
  * Skip fixup if the base type is invalid.
18112
  * TODO: Generate a warning!
18113
  */
18114
0
  return(0);
18115
0
    }
18116
    /*
18117
    * This basically checks if the base type can be derived.
18118
    */
18119
1.60k
    res = xmlSchemaCheckSRCCT(pctxt, type);
18120
1.60k
    HFAILURE HERROR
18121
    /*
18122
    * Fixup the content type.
18123
    */
18124
1.60k
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18125
  /*
18126
  * Corresponds to <complexType><simpleContent>...
18127
  */
18128
95
  if ((WXS_IS_COMPLEX(baseType)) &&
18129
95
      (baseType->contentTypeDef != NULL) &&
18130
95
      (WXS_IS_RESTRICTION(type))) {
18131
2
      xmlSchemaTypePtr contentBase, content;
18132
#ifdef ENABLE_NAMED_LOCALS
18133
      char buf[30];
18134
      const xmlChar *tmpname;
18135
#endif
18136
      /*
18137
      * SPEC (1) If <restriction> + base type is <complexType>,
18138
      * "whose own {content type} is a simple type..."
18139
      */
18140
2
      if (type->contentTypeDef != NULL) {
18141
    /*
18142
    * SPEC (1.1) "the simple type definition corresponding to the
18143
    * <simpleType> among the [children] of <restriction> if there
18144
    * is one;"
18145
    * Note that this "<simpleType> among the [children]" was put
18146
    * into ->contentTypeDef during parsing.
18147
    */
18148
2
    contentBase = type->contentTypeDef;
18149
2
    type->contentTypeDef = NULL;
18150
2
      } else {
18151
    /*
18152
    * (1.2) "...otherwise (<restriction> has no <simpleType>
18153
    * among its [children]), the simple type definition which
18154
    * is the {content type} of the ... base type."
18155
    */
18156
0
    contentBase = baseType->contentTypeDef;
18157
0
      }
18158
      /*
18159
      * SPEC
18160
      * "... a simple type definition which restricts the simple
18161
      * type definition identified in clause 1.1 or clause 1.2
18162
      * with a set of facet components"
18163
      *
18164
      * Create the anonymous simple type, which will be the content
18165
      * type of the complex type.
18166
      */
18167
#ifdef ENABLE_NAMED_LOCALS
18168
      snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18169
      tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18170
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18171
    XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18172
    type->node, 0);
18173
#else
18174
2
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18175
2
    XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18176
2
    type->node, 0);
18177
2
#endif
18178
2
      if (content == NULL)
18179
0
    goto exit_failure;
18180
      /*
18181
      * We will use the same node as for the <complexType>
18182
      * to have it somehow anchored in the schema doc.
18183
      */
18184
2
      content->type = XML_SCHEMA_TYPE_SIMPLE;
18185
2
      content->baseType = contentBase;
18186
      /*
18187
      * Move the facets, previously anchored on the
18188
      * complexType during parsing.
18189
      */
18190
2
      content->facets = type->facets;
18191
2
      type->facets = NULL;
18192
2
      content->facetSet = type->facetSet;
18193
2
      type->facetSet = NULL;
18194
18195
2
      type->contentTypeDef = content;
18196
2
      if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18197
0
    xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18198
      /*
18199
      * Fixup the newly created type. We don't need to check
18200
      * for circularity here.
18201
      */
18202
2
      res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18203
2
      HFAILURE HERROR
18204
2
      res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18205
2
      HFAILURE HERROR
18206
18207
93
  } else if ((WXS_IS_COMPLEX(baseType)) &&
18208
93
      (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18209
93
      (WXS_IS_RESTRICTION(type))) {
18210
      /*
18211
      * SPEC (2) If <restriction> + base is a mixed <complexType> with
18212
      * an emptiable particle, then a simple type definition which
18213
      * restricts the <restriction>'s <simpleType> child.
18214
      */
18215
30
      if ((type->contentTypeDef == NULL) ||
18216
30
    (type->contentTypeDef->baseType == NULL)) {
18217
    /*
18218
    * TODO: Check if this ever happens.
18219
    */
18220
0
    xmlSchemaPCustomErr(pctxt,
18221
0
        XML_SCHEMAP_INTERNAL,
18222
0
        WXS_BASIC_CAST type, NULL,
18223
0
        "Internal error: xmlSchemaTypeFixup, "
18224
0
        "complex type '%s': the <simpleContent><restriction> "
18225
0
        "is missing a <simpleType> child, but was not caught "
18226
0
        "by xmlSchemaCheckSRCCT()", type->name);
18227
0
    goto exit_failure;
18228
0
      }
18229
63
  } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18230
      /*
18231
      * SPEC (3) If <extension> + base is <complexType> with
18232
      * <simpleType> content, "...then the {content type} of that
18233
      * complex type definition"
18234
      */
18235
0
      if (baseType->contentTypeDef == NULL) {
18236
    /*
18237
    * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18238
    * should have caught this already.
18239
    */
18240
0
    xmlSchemaPCustomErr(pctxt,
18241
0
        XML_SCHEMAP_INTERNAL,
18242
0
        WXS_BASIC_CAST type, NULL,
18243
0
        "Internal error: xmlSchemaTypeFixup, "
18244
0
        "complex type '%s': the <extension>ed base type is "
18245
0
        "a complex type with no simple content type",
18246
0
        type->name);
18247
0
    goto exit_failure;
18248
0
      }
18249
0
      type->contentTypeDef = baseType->contentTypeDef;
18250
63
  } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18251
      /*
18252
      * SPEC (4) <extension> + base is <simpleType>
18253
      * "... then that simple type definition"
18254
      */
18255
63
      type->contentTypeDef = baseType;
18256
63
  } else {
18257
      /*
18258
      * TODO: Check if this ever happens.
18259
      */
18260
0
      xmlSchemaPCustomErr(pctxt,
18261
0
    XML_SCHEMAP_INTERNAL,
18262
0
    WXS_BASIC_CAST type, NULL,
18263
0
    "Internal error: xmlSchemaTypeFixup, "
18264
0
    "complex type '%s' with <simpleContent>: unhandled "
18265
0
    "derivation case", type->name);
18266
0
      goto exit_failure;
18267
0
  }
18268
1.51k
    } else {
18269
1.51k
  int dummySequence = 0;
18270
1.51k
  xmlSchemaParticlePtr particle =
18271
1.51k
      (xmlSchemaParticlePtr) type->subtypes;
18272
  /*
18273
  * Corresponds to <complexType><complexContent>...
18274
  *
18275
  * NOTE that the effective mixed was already set during parsing of
18276
  * <complexType> and <complexContent>; its flag value is
18277
  * XML_SCHEMAS_TYPE_MIXED.
18278
  *
18279
  * Compute the "effective content":
18280
  * (2.1.1) + (2.1.2) + (2.1.3)
18281
  */
18282
1.51k
  if ((particle == NULL) ||
18283
1.51k
      ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18284
631
      ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18285
631
      (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18286
631
      ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18287
58
      (particle->minOccurs == 0))) &&
18288
890
      ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18289
890
      if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18290
    /*
18291
    * SPEC (2.1.4) "If the `effective mixed` is true, then
18292
    * a particle whose properties are as follows:..."
18293
    *
18294
    * Empty sequence model group with
18295
    * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18296
    * NOTE that we sill assign it the <complexType> node to
18297
    * somehow anchor it in the doc.
18298
    */
18299
8
    if ((particle == NULL) ||
18300
8
        (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18301
        /*
18302
        * Create the particle.
18303
        */
18304
8
        particle = xmlSchemaAddParticle(pctxt,
18305
8
      type->node, 1, 1);
18306
8
        if (particle == NULL)
18307
0
      goto exit_failure;
18308
        /*
18309
        * Create the model group.
18310
        */ /* URGENT TODO: avoid adding to pending items. */
18311
8
        particle->children = (xmlSchemaTreeItemPtr)
18312
8
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18313
8
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18314
8
        if (particle->children == NULL)
18315
0
      goto exit_failure;
18316
18317
8
        type->subtypes = (xmlSchemaTypePtr) particle;
18318
8
    }
18319
8
    dummySequence = 1;
18320
8
    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18321
882
      } else {
18322
    /*
18323
    * SPEC (2.1.5) "otherwise empty"
18324
    */
18325
882
    type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18326
882
      }
18327
890
  } else {
18328
      /*
18329
      * SPEC (2.2) "otherwise the particle corresponding to the
18330
      * <all>, <choice>, <group> or <sequence> among the
18331
      * [children]."
18332
      */
18333
623
      type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18334
623
  }
18335
  /*
18336
  * Compute the "content type".
18337
  */
18338
1.51k
  if (WXS_IS_RESTRICTION(type)) {
18339
      /*
18340
      * SPEC (3.1) "If <restriction>..."
18341
      * (3.1.1) + (3.1.2) */
18342
1.28k
      if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18343
618
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18344
13
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18345
618
      }
18346
1.28k
  } else {
18347
      /*
18348
      * SPEC (3.2) "If <extension>..."
18349
      */
18350
227
      if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18351
    /*
18352
    * SPEC (3.2.1)
18353
    * "If the `effective content` is empty, then the
18354
    *  {content type} of the [...] base ..."
18355
    */
18356
214
    type->contentType = baseType->contentType;
18357
214
    type->subtypes = baseType->subtypes;
18358
    /*
18359
    * Fixes bug #347316:
18360
    * This is the case when the base type has a simple
18361
    * type definition as content.
18362
    */
18363
214
    type->contentTypeDef = baseType->contentTypeDef;
18364
    /*
18365
    * NOTE that the effective mixed is ignored here.
18366
    */
18367
214
      } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18368
    /*
18369
    * SPEC (3.2.2)
18370
    */
18371
10
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18372
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18373
10
      } else {
18374
    /*
18375
    * SPEC (3.2.3)
18376
    */
18377
3
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18378
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18379
        /*
18380
        * "A model group whose {compositor} is sequence and whose
18381
        * {particles} are..."
18382
        */
18383
3
    if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18384
3
        (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18385
3
        ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18386
3
      XML_SCHEMA_TYPE_ALL))
18387
0
    {
18388
        /*
18389
        * SPEC cos-all-limited (1)
18390
        */
18391
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18392
      /* TODO: error code */
18393
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18394
0
      WXS_ITEM_NODE(type), NULL,
18395
0
      "The type has an 'all' model group in its "
18396
0
      "{content type} and thus cannot be derived from "
18397
0
      "a non-empty type, since this would produce a "
18398
0
      "'sequence' model group containing the 'all' "
18399
0
      "model group; 'all' model groups are not "
18400
0
      "allowed to appear inside other model groups",
18401
0
      NULL, NULL);
18402
18403
3
    } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18404
3
        (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18405
3
        ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18406
2
      XML_SCHEMA_TYPE_ALL))
18407
0
    {
18408
        /*
18409
        * SPEC cos-all-limited (1)
18410
        */
18411
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18412
      /* TODO: error code */
18413
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18414
0
      WXS_ITEM_NODE(type), NULL,
18415
0
      "A type cannot be derived by extension from a type "
18416
0
      "which has an 'all' model group in its "
18417
0
      "{content type}, since this would produce a "
18418
0
      "'sequence' model group containing the 'all' "
18419
0
      "model group; 'all' model groups are not "
18420
0
      "allowed to appear inside other model groups",
18421
0
      NULL, NULL);
18422
18423
3
    } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
18424
2
        xmlSchemaTreeItemPtr effectiveContent =
18425
2
      (xmlSchemaTreeItemPtr) type->subtypes;
18426
        /*
18427
        * Create the particle.
18428
        */
18429
2
        particle = xmlSchemaAddParticle(pctxt,
18430
2
      type->node, 1, 1);
18431
2
        if (particle == NULL)
18432
0
      goto exit_failure;
18433
        /*
18434
        * Create the "sequence" model group.
18435
        */
18436
2
        particle->children = (xmlSchemaTreeItemPtr)
18437
2
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18438
2
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18439
2
        if (particle->children == NULL)
18440
0
      goto exit_failure;
18441
2
        WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18442
        /*
18443
        * SPEC "the particle of the {content type} of
18444
        * the ... base ..."
18445
        * Create a duplicate of the base type's particle
18446
        * and assign its "term" to it.
18447
        */
18448
2
        particle->children->children =
18449
2
      (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18450
2
      type->node,
18451
2
      ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18452
2
      ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18453
2
        if (particle->children->children == NULL)
18454
0
      goto exit_failure;
18455
2
        particle = (xmlSchemaParticlePtr)
18456
2
      particle->children->children;
18457
2
        particle->children =
18458
2
      ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18459
        /*
18460
        * SPEC "followed by the `effective content`."
18461
        */
18462
2
        particle->next = effectiveContent;
18463
        /*
18464
        * This all will result in:
18465
        * new-particle
18466
        *   --> new-sequence(
18467
        *         new-particle
18468
        *           --> base-model,
18469
        *         this-particle
18470
        *         --> this-model
18471
        *     )
18472
        */
18473
2
    } else {
18474
        /*
18475
        * This is the case when there is already an empty
18476
        * <sequence> with minOccurs==maxOccurs==1.
18477
        * Just add the base types's content type.
18478
        * NOTE that, although we miss to add an intermediate
18479
        * <sequence>, this should produce no difference to
18480
        * neither the regex compilation of the content model,
18481
        * nor to the complex type constraints.
18482
        */
18483
1
        particle->children->children =
18484
1
      (xmlSchemaTreeItemPtr) baseType->subtypes;
18485
1
    }
18486
3
      }
18487
227
  }
18488
1.51k
    }
18489
    /*
18490
    * Now fixup attribute uses:
18491
    *   - expand attr. group references
18492
    *     - intersect attribute wildcards
18493
    *   - inherit attribute uses of the base type
18494
    *   - inherit or union attr. wildcards if extending
18495
    *   - apply attr. use prohibitions if restricting
18496
    */
18497
1.60k
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18498
1.60k
    HFAILURE HERROR
18499
    /*
18500
    * Apply the complex type component constraints; this will not
18501
    * check attributes, since this is done in
18502
    * xmlSchemaFixupTypeAttributeUses().
18503
    */
18504
1.60k
    res = xmlSchemaCheckCTComponent(pctxt, type);
18505
1.60k
    HFAILURE HERROR
18506
18507
1.59k
    if (olderrs != pctxt->nberrors)
18508
94
  return(pctxt->err);
18509
1.50k
    else
18510
1.50k
  return(0);
18511
18512
9
exit_error:
18513
9
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18514
9
    return(pctxt->err);
18515
18516
0
exit_failure:
18517
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18518
0
    return(-1);
18519
1.59k
}
18520
18521
18522
/**
18523
 * xmlSchemaTypeFixup:
18524
 * @typeDecl:  the schema type definition
18525
 * @ctxt:  the schema parser context
18526
 *
18527
 * Fixes the content model of the type.
18528
 * URGENT TODO: We need an int result!
18529
 */
18530
static int
18531
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18532
                   xmlSchemaAbstractCtxtPtr actxt)
18533
1.06k
{
18534
1.06k
    if (type == NULL)
18535
0
        return(0);
18536
1.06k
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18537
0
  AERROR_INT("xmlSchemaTypeFixup",
18538
0
      "this function needs a parser context");
18539
0
  return(-1);
18540
0
    }
18541
1.06k
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18542
0
  return(0);
18543
1.06k
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18544
202
  return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18545
860
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18546
860
  return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18547
0
    return(0);
18548
1.06k
}
18549
18550
/**
18551
 * xmlSchemaCheckFacet:
18552
 * @facet:  the facet
18553
 * @typeDecl:  the schema type definition
18554
 * @pctxt:  the schema parser context or NULL
18555
 * @name: the optional name of the type
18556
 *
18557
 * Checks and computes the values of facets.
18558
 *
18559
 * Returns 0 if valid, a positive error code if not valid and
18560
 *         -1 in case of an internal or API error.
18561
 */
18562
int
18563
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18564
                    xmlSchemaTypePtr typeDecl,
18565
                    xmlSchemaParserCtxtPtr pctxt,
18566
        const xmlChar * name ATTRIBUTE_UNUSED)
18567
125k
{
18568
125k
    int ret = 0, ctxtGiven;
18569
18570
125k
    if ((facet == NULL) || (typeDecl == NULL))
18571
0
        return(-1);
18572
    /*
18573
    * TODO: will the parser context be given if used from
18574
    * the relaxNG module?
18575
    */
18576
125k
    if (pctxt == NULL)
18577
0
  ctxtGiven = 0;
18578
125k
    else
18579
125k
  ctxtGiven = 1;
18580
18581
125k
    switch (facet->type) {
18582
14.2k
        case XML_SCHEMA_FACET_MININCLUSIVE:
18583
39.8k
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
18584
45.3k
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
18585
58.9k
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18586
104k
  case XML_SCHEMA_FACET_ENUMERATION: {
18587
                /*
18588
                 * Okay we need to validate the value
18589
                 * at that point.
18590
                 */
18591
104k
    xmlSchemaTypePtr base;
18592
18593
    /* 4.3.5.5 Constraints on enumeration Schema Components
18594
    * Schema Component Constraint: enumeration valid restriction
18595
    * It is an `error` if any member of {value} is not in the
18596
    * `value space` of {base type definition}.
18597
    *
18598
    * minInclusive, maxInclusive, minExclusive, maxExclusive:
18599
    * The value `must` be in the
18600
    * `value space` of the `base type`.
18601
    */
18602
    /*
18603
    * This function is intended to deliver a compiled value
18604
    * on the facet. In this implementation of XML Schemata the
18605
    * type holding a facet, won't be a built-in type.
18606
    * Thus to ensure that other API
18607
    * calls (relaxng) do work, if the given type is a built-in
18608
    * type, we will assume that the given built-in type *is
18609
    * already* the base type.
18610
    */
18611
104k
    if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18612
104k
        base = typeDecl->baseType;
18613
104k
        if (base == NULL) {
18614
0
      PERROR_INT("xmlSchemaCheckFacet",
18615
0
          "a type user derived type has no base type");
18616
0
      return (-1);
18617
0
        }
18618
104k
    } else
18619
0
        base = typeDecl;
18620
18621
104k
    if (! ctxtGiven) {
18622
        /*
18623
        * A context is needed if called from RelaxNG.
18624
        */
18625
0
        pctxt = xmlSchemaNewParserCtxt("*");
18626
0
        if (pctxt == NULL)
18627
0
      return (-1);
18628
0
    }
18629
    /*
18630
    * NOTE: This call does not check the content nodes,
18631
    * since they are not available:
18632
    * facet->node is just the node holding the facet
18633
    * definition, *not* the attribute holding the *value*
18634
    * of the facet.
18635
    */
18636
104k
    ret = xmlSchemaVCheckCVCSimpleType(
18637
104k
        ACTXT_CAST pctxt, facet->node, base,
18638
104k
        facet->value, &(facet->val), 1, 1, 0);
18639
104k
                if (ret != 0) {
18640
79.6k
        if (ret < 0) {
18641
      /* No error message for RelaxNG. */
18642
24
      if (ctxtGiven) {
18643
24
          xmlSchemaCustomErr(ACTXT_CAST pctxt,
18644
24
        XML_SCHEMAP_INTERNAL, facet->node, NULL,
18645
24
        "Internal error: xmlSchemaCheckFacet, "
18646
24
        "failed to validate the value '%s' of the "
18647
24
        "facet '%s' against the base type",
18648
24
        facet->value, xmlSchemaFacetTypeToString(facet->type));
18649
24
      }
18650
24
      goto internal_error;
18651
24
        }
18652
79.5k
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18653
        /* No error message for RelaxNG. */
18654
79.5k
        if (ctxtGiven) {
18655
79.5k
      xmlChar *str = NULL;
18656
18657
79.5k
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18658
79.5k
          ret, facet->node, WXS_BASIC_CAST facet,
18659
79.5k
          "The value '%s' of the facet does not validate "
18660
79.5k
          "against the base type '%s'",
18661
79.5k
          facet->value,
18662
79.5k
          xmlSchemaFormatQName(&str,
18663
79.5k
        base->targetNamespace, base->name));
18664
79.5k
      FREE_AND_NULL(str);
18665
79.5k
        }
18666
79.5k
        goto exit;
18667
79.6k
                } else if (facet->val == NULL) {
18668
19
        if (ctxtGiven) {
18669
19
      PERROR_INT("xmlSchemaCheckFacet",
18670
19
          "value was not computed");
18671
19
        }
18672
        /* TODO */
18673
19
    }
18674
24.4k
                break;
18675
104k
            }
18676
24.4k
        case XML_SCHEMA_FACET_PATTERN:
18677
17.3k
            facet->regexp = xmlRegexpCompile(facet->value);
18678
17.3k
            if (facet->regexp == NULL) {
18679
10.0k
    ret = XML_SCHEMAP_REGEXP_INVALID;
18680
    /* No error message for RelaxNG. */
18681
10.0k
    if (ctxtGiven) {
18682
10.0k
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18683
10.0k
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18684
10.0k
      "The value '%s' of the facet 'pattern' is not a "
18685
10.0k
      "valid regular expression",
18686
10.0k
      facet->value, NULL);
18687
10.0k
    }
18688
10.0k
            }
18689
17.3k
            break;
18690
757
        case XML_SCHEMA_FACET_TOTALDIGITS:
18691
797
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
18692
1.52k
        case XML_SCHEMA_FACET_LENGTH:
18693
2.03k
        case XML_SCHEMA_FACET_MAXLENGTH:
18694
2.49k
        case XML_SCHEMA_FACET_MINLENGTH:
18695
18696
2.49k
      if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18697
757
    ret = xmlSchemaValidatePredefinedType(
18698
757
        xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18699
757
        facet->value, &(facet->val));
18700
1.73k
      } else {
18701
1.73k
    ret = xmlSchemaValidatePredefinedType(
18702
1.73k
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18703
1.73k
        facet->value, &(facet->val));
18704
1.73k
      }
18705
2.49k
      if (ret != 0) {
18706
948
    if (ret < 0) {
18707
        /* No error message for RelaxNG. */
18708
0
        if (ctxtGiven) {
18709
0
      PERROR_INT("xmlSchemaCheckFacet",
18710
0
          "validating facet value");
18711
0
        }
18712
0
        goto internal_error;
18713
0
    }
18714
948
    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18715
    /* No error message for RelaxNG. */
18716
948
    if (ctxtGiven) {
18717
        /* error code */
18718
948
        xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18719
948
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18720
948
      "The value '%s' of the facet '%s' is not a valid '%s'",
18721
948
      facet->value,
18722
948
      xmlSchemaFacetTypeToString(facet->type),
18723
948
      (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18724
448
          BAD_CAST "nonNegativeInteger" :
18725
948
          BAD_CAST "positiveInteger",
18726
948
      NULL);
18727
948
    }
18728
948
      }
18729
2.49k
      break;
18730
18731
2.49k
        case XML_SCHEMA_FACET_WHITESPACE:{
18732
1.94k
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18733
295
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18734
1.65k
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18735
407
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18736
1.24k
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18737
286
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18738
960
                } else {
18739
960
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18740
                    /* No error message for RelaxNG. */
18741
960
        if (ctxtGiven) {
18742
      /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18743
960
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18744
960
          ret, facet->node, WXS_BASIC_CAST typeDecl,
18745
960
          "The value '%s' of the facet 'whitespace' is not "
18746
960
          "valid", facet->value, NULL);
18747
960
                    }
18748
960
                }
18749
1.94k
            }
18750
1.94k
        default:
18751
1.94k
            break;
18752
125k
    }
18753
125k
exit:
18754
125k
    if ((! ctxtGiven) && (pctxt != NULL))
18755
0
  xmlSchemaFreeParserCtxt(pctxt);
18756
125k
    return (ret);
18757
24
internal_error:
18758
24
    if ((! ctxtGiven) && (pctxt != NULL))
18759
0
  xmlSchemaFreeParserCtxt(pctxt);
18760
24
    return (-1);
18761
125k
}
18762
18763
/**
18764
 * xmlSchemaCheckFacetValues:
18765
 * @typeDecl:  the schema type definition
18766
 * @ctxt:  the schema parser context
18767
 *
18768
 * Checks the default values types, especially for facets
18769
 */
18770
static int
18771
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18772
        xmlSchemaParserCtxtPtr pctxt)
18773
8.69k
{
18774
8.69k
    int res, olderrs = pctxt->nberrors;
18775
8.69k
    const xmlChar *name = typeDecl->name;
18776
    /*
18777
    * NOTE: It is intended to use the facets list, instead
18778
    * of facetSet.
18779
    */
18780
8.69k
    if (typeDecl->facets != NULL) {
18781
8.19k
  xmlSchemaFacetPtr facet = typeDecl->facets;
18782
18783
  /*
18784
  * Temporarily assign the "schema" to the validation context
18785
  * of the parser context. This is needed for NOTATION validation.
18786
  */
18787
8.19k
  if (pctxt->vctxt == NULL) {
18788
6.83k
      if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18789
0
    return(-1);
18790
6.83k
  }
18791
8.19k
  pctxt->vctxt->schema = pctxt->schema;
18792
133k
  while (facet != NULL) {
18793
125k
      res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18794
125k
      HFAILURE
18795
125k
      facet = facet->next;
18796
125k
  }
18797
8.17k
  pctxt->vctxt->schema = NULL;
18798
8.17k
    }
18799
8.66k
    if (olderrs != pctxt->nberrors)
18800
4.07k
  return(pctxt->err);
18801
4.59k
    return(0);
18802
24
exit_failure:
18803
24
    return(-1);
18804
8.66k
}
18805
18806
/**
18807
 * xmlSchemaGetCircModelGrDefRef:
18808
 * @ctxtMGroup: the searched model group
18809
 * @selfMGroup: the second searched model group
18810
 * @particle: the first particle
18811
 *
18812
 * This one is intended to be used by
18813
 * xmlSchemaCheckGroupDefCircular only.
18814
 *
18815
 * Returns the particle with the circular model group definition reference,
18816
 * otherwise NULL.
18817
 */
18818
static xmlSchemaTreeItemPtr
18819
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18820
            xmlSchemaTreeItemPtr particle)
18821
159
{
18822
159
    xmlSchemaTreeItemPtr circ = NULL;
18823
159
    xmlSchemaTreeItemPtr term;
18824
159
    xmlSchemaModelGroupDefPtr gdef;
18825
18826
3.26k
    for (; particle != NULL; particle = particle->next) {
18827
3.10k
  term = particle->children;
18828
3.10k
  if (term == NULL)
18829
0
      continue;
18830
3.10k
  switch (term->type) {
18831
0
      case XML_SCHEMA_TYPE_GROUP:
18832
0
    gdef = (xmlSchemaModelGroupDefPtr) term;
18833
0
    if (gdef == groupDef)
18834
0
        return (particle);
18835
    /*
18836
    * Mark this model group definition to avoid infinite
18837
    * recursion on circular references not yet examined.
18838
    */
18839
0
    if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18840
0
        continue;
18841
0
    if (gdef->children != NULL) {
18842
0
        gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18843
0
        circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18844
0
      gdef->children->children);
18845
0
        gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18846
0
        if (circ != NULL)
18847
0
      return (circ);
18848
0
    }
18849
0
    break;
18850
2
      case XML_SCHEMA_TYPE_SEQUENCE:
18851
18
      case XML_SCHEMA_TYPE_CHOICE:
18852
18
      case XML_SCHEMA_TYPE_ALL:
18853
18
    circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18854
18
    if (circ != NULL)
18855
0
        return (circ);
18856
18
    break;
18857
3.08k
      default:
18858
3.08k
    break;
18859
3.10k
  }
18860
3.10k
    }
18861
159
    return (NULL);
18862
159
}
18863
18864
/**
18865
 * xmlSchemaCheckGroupDefCircular:
18866
 * @item:  the model group definition
18867
 * @ctxt:  the parser context
18868
 * @name:  the name
18869
 *
18870
 * Checks for circular references to model group definitions.
18871
 */
18872
static void
18873
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18874
             xmlSchemaParserCtxtPtr ctxt)
18875
145
{
18876
    /*
18877
    * Schema Component Constraint: Model Group Correct
18878
    * 2 Circular groups are disallowed. That is, within the {particles}
18879
    * of a group there must not be at any depth a particle whose {term}
18880
    * is the group itself.
18881
    */
18882
145
    if ((item == NULL) ||
18883
145
  (item->type != XML_SCHEMA_TYPE_GROUP) ||
18884
145
  (item->children == NULL))
18885
4
  return;
18886
141
    {
18887
141
  xmlSchemaTreeItemPtr circ;
18888
18889
141
  circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18890
141
  if (circ != NULL) {
18891
0
      xmlChar *str = NULL;
18892
      /*
18893
      * TODO: The error report is not adequate: this constraint
18894
      * is defined for model groups but not definitions, but since
18895
      * there cannot be any circular model groups without a model group
18896
      * definition (if not using a construction API), we check those
18897
      * definitions only.
18898
      */
18899
0
      xmlSchemaPCustomErr(ctxt,
18900
0
    XML_SCHEMAP_MG_PROPS_CORRECT_2,
18901
0
    NULL, WXS_ITEM_NODE(circ),
18902
0
    "Circular reference to the model group definition '%s' "
18903
0
    "defined", xmlSchemaFormatQName(&str,
18904
0
        item->targetNamespace, item->name));
18905
0
      FREE_AND_NULL(str)
18906
      /*
18907
      * NOTE: We will cut the reference to avoid further
18908
      * confusion of the processor. This is a fatal error.
18909
      */
18910
0
      circ->children = NULL;
18911
0
  }
18912
141
    }
18913
141
}
18914
18915
/**
18916
 * xmlSchemaModelGroupToModelGroupDefFixup:
18917
 * @ctxt:  the parser context
18918
 * @mg:  the model group
18919
 *
18920
 * Assigns the model group of model group definitions to the "term"
18921
 * of the referencing particle.
18922
 * In xmlSchemaResolveModelGroupParticleReferences the model group
18923
 * definitions were assigned to the "term", since needed for the
18924
 * circularity check.
18925
 *
18926
 * Schema Component Constraint:
18927
 *     All Group Limited (cos-all-limited) (1.2)
18928
 */
18929
static void
18930
xmlSchemaModelGroupToModelGroupDefFixup(
18931
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18932
    xmlSchemaModelGroupPtr mg)
18933
1.76k
{
18934
1.76k
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18935
18936
11.5k
    while (particle != NULL) {
18937
9.74k
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18938
9.74k
      ((WXS_PARTICLE_TERM(particle))->type !=
18939
9.74k
    XML_SCHEMA_TYPE_GROUP))
18940
9.71k
  {
18941
9.71k
      particle = WXS_PTC_CAST particle->next;
18942
9.71k
      continue;
18943
9.71k
  }
18944
24
  if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18945
      /*
18946
      * TODO: Remove the particle.
18947
      */
18948
0
      WXS_PARTICLE_TERM(particle) = NULL;
18949
0
      particle = WXS_PTC_CAST particle->next;
18950
0
      continue;
18951
0
  }
18952
  /*
18953
  * Assign the model group to the {term} of the particle.
18954
  */
18955
24
  WXS_PARTICLE_TERM(particle) =
18956
24
      WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18957
18958
24
  particle = WXS_PTC_CAST particle->next;
18959
24
    }
18960
1.76k
}
18961
18962
/**
18963
 * xmlSchemaCheckAttrGroupCircularRecur:
18964
 * @ctxtGr: the searched attribute group
18965
 * @attr: the current attribute list to be processed
18966
 *
18967
 * This one is intended to be used by
18968
 * xmlSchemaCheckAttrGroupCircular only.
18969
 *
18970
 * Returns the circular attribute group reference, otherwise NULL.
18971
 */
18972
static xmlSchemaQNameRefPtr
18973
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
18974
             xmlSchemaItemListPtr list)
18975
65
{
18976
65
    xmlSchemaAttributeGroupPtr gr;
18977
65
    xmlSchemaQNameRefPtr ref, circ;
18978
65
    int i;
18979
    /*
18980
    * We will search for an attribute group reference which
18981
    * references the context attribute group.
18982
    */
18983
231
    for (i = 0; i < list->nbItems; i++) {
18984
173
  ref = list->items[i];
18985
173
  if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18986
173
      (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
18987
173
      (ref->item != NULL))
18988
173
  {
18989
173
      gr = WXS_ATTR_GROUP_CAST ref->item;
18990
173
      if (gr == ctxtGr)
18991
7
    return(ref);
18992
166
      if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
18993
14
    continue;
18994
      /*
18995
      * Mark as visited to avoid infinite recursion on
18996
      * circular references not yet examined.
18997
      */
18998
152
      if ((gr->attrUses) &&
18999
152
    (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19000
34
      {
19001
34
    gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19002
34
    circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19003
34
        (xmlSchemaItemListPtr) gr->attrUses);
19004
34
    gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19005
34
    if (circ != NULL)
19006
0
        return (circ);
19007
34
      }
19008
19009
152
  }
19010
173
    }
19011
58
    return (NULL);
19012
65
}
19013
19014
/**
19015
 * xmlSchemaCheckAttrGroupCircular:
19016
 * attrGr:  the attribute group definition
19017
 * @ctxt:  the parser context
19018
 * @name:  the name
19019
 *
19020
 * Checks for circular references of attribute groups.
19021
 */
19022
static int
19023
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19024
        xmlSchemaParserCtxtPtr ctxt)
19025
349
{
19026
    /*
19027
    * Schema Representation Constraint:
19028
    * Attribute Group Definition Representation OK
19029
    * 3 Circular group reference is disallowed outside <redefine>.
19030
    * That is, unless this element information item's parent is
19031
    * <redefine>, then among the [children], if any, there must
19032
    * not be an <attributeGroup> with ref [attribute] which resolves
19033
    * to the component corresponding to this <attributeGroup>. Indirect
19034
    * circularity is also ruled out. That is, when QName resolution
19035
    * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19036
    * any <attributeGroup>s with a ref [attribute] among the [children],
19037
    * it must not be the case that a `QName` is encountered at any depth
19038
    * which resolves to the component corresponding to this <attributeGroup>.
19039
    */
19040
349
    if (attrGr->attrUses == NULL)
19041
239
  return(0);
19042
110
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19043
79
  return(0);
19044
31
    else {
19045
31
  xmlSchemaQNameRefPtr circ;
19046
19047
31
  circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19048
31
      (xmlSchemaItemListPtr) attrGr->attrUses);
19049
31
  if (circ != NULL) {
19050
7
      xmlChar *str = NULL;
19051
      /*
19052
      * TODO: Report the referenced attr group as QName.
19053
      */
19054
7
      xmlSchemaPCustomErr(ctxt,
19055
7
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19056
7
    NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19057
7
    "Circular reference to the attribute group '%s' "
19058
7
    "defined", xmlSchemaGetComponentQName(&str, attrGr));
19059
7
      FREE_AND_NULL(str);
19060
      /*
19061
      * NOTE: We will cut the reference to avoid further
19062
      * confusion of the processor.
19063
      * BADSPEC TODO: The spec should define how to process in this case.
19064
      */
19065
7
      circ->item = NULL;
19066
7
      return(ctxt->err);
19067
7
  }
19068
31
    }
19069
24
    return(0);
19070
349
}
19071
19072
static int
19073
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19074
          xmlSchemaAttributeGroupPtr attrGr);
19075
19076
/**
19077
 * xmlSchemaExpandAttributeGroupRefs:
19078
 * @pctxt: the parser context
19079
 * @node: the node of the component holding the attribute uses
19080
 * @completeWild: the intersected wildcard to be returned
19081
 * @list: the attribute uses
19082
 *
19083
 * Substitutes contained attribute group references
19084
 * for their attribute uses. Wildcards are intersected.
19085
 * Attribute use prohibitions are removed from the list
19086
 * and returned via the @prohibs list.
19087
 * Pointlessness of attr. prohibs, if a matching attr. decl
19088
 * is existent a well, are checked.
19089
 */
19090
static int
19091
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19092
          xmlSchemaBasicItemPtr item,
19093
          xmlSchemaWildcardPtr *completeWild,
19094
          xmlSchemaItemListPtr list,
19095
          xmlSchemaItemListPtr prohibs)
19096
599
{
19097
599
    xmlSchemaAttributeGroupPtr gr;
19098
599
    xmlSchemaAttributeUsePtr use;
19099
599
    xmlSchemaItemListPtr sublist;
19100
599
    int i, j;
19101
599
    int created = (*completeWild == NULL) ? 0 : 1;
19102
19103
599
    if (prohibs)
19104
488
  prohibs->nbItems = 0;
19105
19106
3.32k
    for (i = 0; i < list->nbItems; i++) {
19107
2.72k
  use = list->items[i];
19108
19109
2.72k
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19110
187
      if (prohibs == NULL) {
19111
0
    PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19112
0
        "unexpected attr prohibition found");
19113
0
    return(-1);
19114
0
      }
19115
      /*
19116
      * Remove from attribute uses.
19117
      */
19118
187
      if (xmlSchemaItemListRemove(list, i) == -1)
19119
0
    return(-1);
19120
187
      i--;
19121
      /*
19122
      * Note that duplicate prohibitions were already
19123
      * handled at parsing time.
19124
      */
19125
      /*
19126
      * Add to list of prohibitions.
19127
      */
19128
187
      xmlSchemaItemListAddSize(prohibs, 2, use);
19129
187
      continue;
19130
187
  }
19131
2.53k
  if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19132
2.53k
      ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19133
595
  {
19134
595
      if ((WXS_QNAME_CAST use)->item == NULL)
19135
0
    return(-1);
19136
595
      gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19137
      /*
19138
      * Expand the referenced attr. group.
19139
      * TODO: remove this, this is done in a previous step, so
19140
      * already done here.
19141
      */
19142
595
      if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19143
446
    if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19144
0
        return(-1);
19145
446
      }
19146
      /*
19147
      * Build the 'complete' wildcard; i.e. intersect multiple
19148
      * wildcards.
19149
      */
19150
595
      if (gr->attributeWildcard != NULL) {
19151
400
    if (*completeWild == NULL) {
19152
49
        *completeWild = gr->attributeWildcard;
19153
351
    } else {
19154
351
        if (! created) {
19155
40
      xmlSchemaWildcardPtr tmpWild;
19156
19157
       /*
19158
      * Copy the first encountered wildcard as context,
19159
      * except for the annotation.
19160
      *
19161
      * Although the complete wildcard might not correspond
19162
      * to any node in the schema, we will anchor it on
19163
      * the node of the owner component.
19164
      */
19165
40
      tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19166
40
          XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19167
40
          WXS_ITEM_NODE(item));
19168
40
      if (tmpWild == NULL)
19169
0
          return(-1);
19170
40
      if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19171
40
          tmpWild, *completeWild) == -1)
19172
0
          return (-1);
19173
40
      tmpWild->processContents = (*completeWild)->processContents;
19174
40
      *completeWild = tmpWild;
19175
40
      created = 1;
19176
40
        }
19177
19178
351
        if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19179
351
      gr->attributeWildcard) == -1)
19180
0
      return(-1);
19181
351
    }
19182
400
      }
19183
      /*
19184
      * Just remove the reference if the referenced group does not
19185
      * contain any attribute uses.
19186
      */
19187
595
      sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19188
595
      if ((sublist == NULL) || sublist->nbItems == 0) {
19189
435
    if (xmlSchemaItemListRemove(list, i) == -1)
19190
0
        return(-1);
19191
435
    i--;
19192
435
    continue;
19193
435
      }
19194
      /*
19195
      * Add the attribute uses.
19196
      */
19197
160
      list->items[i] = sublist->items[0];
19198
160
      if (sublist->nbItems != 1) {
19199
73
    for (j = 1; j < sublist->nbItems; j++) {
19200
37
        i++;
19201
37
        if (xmlSchemaItemListInsert(list,
19202
37
          sublist->items[j], i) == -1)
19203
0
      return(-1);
19204
37
    }
19205
36
      }
19206
160
  }
19207
19208
2.53k
    }
19209
    /*
19210
    * Handle pointless prohibitions of declared attributes.
19211
    */
19212
599
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19213
65
  xmlSchemaAttributeUseProhibPtr prohib;
19214
19215
234
  for (i = prohibs->nbItems -1; i >= 0; i--) {
19216
169
      prohib = prohibs->items[i];
19217
5.00k
      for (j = 0; j < list->nbItems; j++) {
19218
4.85k
    use = list->items[j];
19219
19220
4.85k
    if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19221
4.85k
        (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19222
14
    {
19223
14
        xmlChar *str = NULL;
19224
19225
14
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19226
14
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19227
14
      prohib->node, NULL,
19228
14
      "Skipping pointless attribute use prohibition "
19229
14
      "'%s', since a corresponding attribute use "
19230
14
      "exists already in the type definition",
19231
14
      xmlSchemaFormatQName(&str,
19232
14
          prohib->targetNamespace, prohib->name),
19233
14
      NULL, NULL);
19234
14
        FREE_AND_NULL(str);
19235
        /*
19236
        * Remove the prohibition.
19237
        */
19238
14
        if (xmlSchemaItemListRemove(prohibs, i) == -1)
19239
0
      return(-1);
19240
14
        break;
19241
14
    }
19242
4.85k
      }
19243
169
  }
19244
65
    }
19245
599
    return(0);
19246
599
}
19247
19248
/**
19249
 * xmlSchemaAttributeGroupExpandRefs:
19250
 * @pctxt:  the parser context
19251
 * @attrGr:  the attribute group definition
19252
 *
19253
 * Computation of:
19254
 * {attribute uses} property
19255
 * {attribute wildcard} property
19256
 *
19257
 * Substitutes contained attribute group references
19258
 * for their attribute uses. Wildcards are intersected.
19259
 */
19260
static int
19261
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19262
          xmlSchemaAttributeGroupPtr attrGr)
19263
459
{
19264
459
    if ((attrGr->attrUses == NULL) ||
19265
459
  (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19266
415
  return(0);
19267
19268
44
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19269
44
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19270
44
  &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19271
0
  return(-1);
19272
44
    return(0);
19273
44
}
19274
19275
/**
19276
 * xmlSchemaAttributeGroupExpandRefs:
19277
 * @pctxt:  the parser context
19278
 * @attrGr:  the attribute group definition
19279
 *
19280
 * Substitutes contained attribute group references
19281
 * for their attribute uses. Wildcards are intersected.
19282
 *
19283
 * Schema Component Constraint:
19284
 *    Attribute Group Definition Properties Correct (ag-props-correct)
19285
 */
19286
static int
19287
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19288
          xmlSchemaAttributeGroupPtr attrGr)
19289
14
{
19290
    /*
19291
    * SPEC ag-props-correct
19292
    * (1) "The values of the properties of an attribute group definition
19293
    * must be as described in the property tableau in The Attribute
19294
    * Group Definition Schema Component ($3.6.1), modulo the impact of
19295
    * Missing Sub-components ($5.3);"
19296
    */
19297
19298
14
    if ((attrGr->attrUses != NULL) &&
19299
14
  (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19300
14
    {
19301
14
  xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19302
14
  xmlSchemaAttributeUsePtr use, tmp;
19303
14
  int i, j, hasId = 0;
19304
19305
65
  for (i = uses->nbItems -1; i >= 0; i--) {
19306
51
      use = uses->items[i];
19307
      /*
19308
      * SPEC ag-props-correct
19309
      * (2) "Two distinct members of the {attribute uses} must not have
19310
      * {attribute declaration}s both of whose {name}s match and whose
19311
      * {target namespace}s are identical."
19312
      */
19313
51
      if (i > 0) {
19314
114
    for (j = i -1; j >= 0; j--) {
19315
85
        tmp = uses->items[j];
19316
85
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
19317
85
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
19318
85
      (WXS_ATTRUSE_DECL_TNS(use) ==
19319
8
      WXS_ATTRUSE_DECL_TNS(tmp)))
19320
8
        {
19321
8
      xmlChar *str = NULL;
19322
19323
8
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19324
8
          XML_SCHEMAP_AG_PROPS_CORRECT,
19325
8
          attrGr->node, WXS_BASIC_CAST attrGr,
19326
8
          "Duplicate %s",
19327
8
          xmlSchemaGetComponentDesignation(&str, use),
19328
8
          NULL);
19329
8
      FREE_AND_NULL(str);
19330
      /*
19331
      * Remove the duplicate.
19332
      */
19333
8
      if (xmlSchemaItemListRemove(uses, i) == -1)
19334
0
          return(-1);
19335
8
      goto next_use;
19336
8
        }
19337
85
    }
19338
37
      }
19339
      /*
19340
      * SPEC ag-props-correct
19341
      * (3) "Two distinct members of the {attribute uses} must not have
19342
      * {attribute declaration}s both of whose {type definition}s are or
19343
      * are derived from ID."
19344
      * TODO: Does 'derived' include member-types of unions?
19345
      */
19346
43
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19347
43
    if (xmlSchemaIsDerivedFromBuiltInType(
19348
43
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19349
0
    {
19350
0
        if (hasId) {
19351
0
      xmlChar *str = NULL;
19352
19353
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19354
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19355
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19356
0
          "There must not exist more than one attribute "
19357
0
          "declaration of type 'xs:ID' "
19358
0
          "(or derived from 'xs:ID'). The %s violates this "
19359
0
          "constraint",
19360
0
          xmlSchemaGetComponentDesignation(&str, use),
19361
0
          NULL);
19362
0
      FREE_AND_NULL(str);
19363
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19364
0
          return(-1);
19365
0
        }
19366
0
        hasId = 1;
19367
0
    }
19368
43
      }
19369
51
next_use: {}
19370
51
  }
19371
14
    }
19372
14
    return(0);
19373
14
}
19374
19375
/**
19376
 * xmlSchemaResolveAttrGroupReferences:
19377
 * @attrgrpDecl:  the schema attribute definition
19378
 * @ctxt:  the schema parser context
19379
 * @name:  the attribute name
19380
 *
19381
 * Resolves references to attribute group definitions.
19382
 */
19383
static int
19384
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19385
            xmlSchemaParserCtxtPtr ctxt)
19386
1.73k
{
19387
1.73k
    xmlSchemaAttributeGroupPtr group;
19388
19389
1.73k
    if (ref->item != NULL)
19390
0
        return(0);
19391
1.73k
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
19392
1.73k
  ref->name,
19393
1.73k
  ref->targetNamespace);
19394
1.73k
    if (group == NULL) {
19395
483
  xmlSchemaPResCompAttrErr(ctxt,
19396
483
      XML_SCHEMAP_SRC_RESOLVE,
19397
483
      NULL, ref->node,
19398
483
      "ref", ref->name, ref->targetNamespace,
19399
483
      ref->itemType, NULL);
19400
483
  return(ctxt->err);
19401
483
    }
19402
1.25k
    ref->item = WXS_BASIC_CAST group;
19403
1.25k
    return(0);
19404
1.73k
}
19405
19406
/**
19407
 * xmlSchemaCheckAttrPropsCorrect:
19408
 * @item:  an schema attribute declaration/use
19409
 * @ctxt:  a schema parser context
19410
 * @name:  the name of the attribute
19411
 *
19412
 *
19413
 * Schema Component Constraint:
19414
 *    Attribute Declaration Properties Correct (a-props-correct)
19415
 *
19416
 * Validates the value constraints of an attribute declaration/use.
19417
 * NOTE that this needs the simple type definitions to be already
19418
 *   built and checked.
19419
 */
19420
static int
19421
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19422
             xmlSchemaAttributePtr attr)
19423
2.13k
{
19424
19425
    /*
19426
    * SPEC a-props-correct (1)
19427
    * "The values of the properties of an attribute declaration must
19428
    * be as described in the property tableau in The Attribute
19429
    * Declaration Schema Component ($3.2.1), modulo the impact of
19430
    * Missing Sub-components ($5.3)."
19431
    */
19432
19433
2.13k
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
19434
0
  return(0);
19435
19436
2.13k
    if (attr->defValue != NULL) {
19437
126
  int ret;
19438
19439
  /*
19440
  * SPEC a-props-correct (3)
19441
  * "If the {type definition} is or is derived from ID then there
19442
  * must not be a {value constraint}."
19443
  */
19444
126
  if (xmlSchemaIsDerivedFromBuiltInType(
19445
126
      WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19446
0
  {
19447
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19448
0
    XML_SCHEMAP_A_PROPS_CORRECT_3,
19449
0
    NULL, WXS_BASIC_CAST attr,
19450
0
    "Value constraints are not allowed if the type definition "
19451
0
    "is or is derived from xs:ID",
19452
0
    NULL, NULL);
19453
0
      return(pctxt->err);
19454
0
  }
19455
  /*
19456
  * SPEC a-props-correct (2)
19457
  * "if there is a {value constraint}, the canonical lexical
19458
  * representation of its value must be `valid` with respect
19459
  * to the {type definition} as defined in String Valid ($3.14.4)."
19460
  * TODO: Don't care about the *canonical* stuff here, this requirement
19461
  * will be removed in WXS 1.1 anyway.
19462
  */
19463
126
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19464
126
      attr->node, WXS_ATTR_TYPEDEF(attr),
19465
126
      attr->defValue, &(attr->defVal),
19466
126
      1, 1, 0);
19467
126
  if (ret != 0) {
19468
82
      if (ret < 0) {
19469
0
    PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19470
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19471
0
    return(-1);
19472
0
      }
19473
82
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19474
82
    XML_SCHEMAP_A_PROPS_CORRECT_2,
19475
82
    NULL, WXS_BASIC_CAST attr,
19476
82
    "The value of the value constraint is not valid",
19477
82
    NULL, NULL);
19478
82
      return(pctxt->err);
19479
82
  }
19480
126
    }
19481
19482
2.05k
    return(0);
19483
2.13k
}
19484
19485
static xmlSchemaElementPtr
19486
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19487
         xmlSchemaElementPtr ancestor)
19488
5
{
19489
5
    xmlSchemaElementPtr ret;
19490
19491
5
    if (WXS_SUBST_HEAD(ancestor) == NULL)
19492
0
  return (NULL);
19493
5
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19494
5
  return (ancestor);
19495
19496
0
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19497
0
  return (NULL);
19498
0
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19499
0
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19500
0
  WXS_SUBST_HEAD(ancestor));
19501
0
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19502
19503
0
    return (ret);
19504
0
}
19505
19506
/**
19507
 * xmlSchemaCheckElemPropsCorrect:
19508
 * @ctxt:  a schema parser context
19509
 * @decl: the element declaration
19510
 * @name:  the name of the attribute
19511
 *
19512
 * Schema Component Constraint:
19513
 * Element Declaration Properties Correct (e-props-correct)
19514
 *
19515
 * STATUS:
19516
 *   missing: (6)
19517
 */
19518
static int
19519
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19520
             xmlSchemaElementPtr elemDecl)
19521
4.93k
{
19522
4.93k
    int ret = 0;
19523
4.93k
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19524
    /*
19525
    * SPEC (1) "The values of the properties of an element declaration
19526
    * must be as described in the property tableau in The Element
19527
    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19528
    * Sub-components ($5.3)."
19529
    */
19530
4.93k
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19531
40
  xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19532
19533
40
  xmlSchemaCheckElementDeclComponent(head, pctxt);
19534
  /*
19535
  * SPEC (3) "If there is a non-`absent` {substitution group
19536
  * affiliation}, then {scope} must be global."
19537
  */
19538
40
  if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19539
0
      xmlSchemaPCustomErr(pctxt,
19540
0
    XML_SCHEMAP_E_PROPS_CORRECT_3,
19541
0
    WXS_BASIC_CAST elemDecl, NULL,
19542
0
    "Only global element declarations can have a "
19543
0
    "substitution group affiliation", NULL);
19544
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19545
0
  }
19546
  /*
19547
  * TODO: SPEC (6) "Circular substitution groups are disallowed.
19548
  * That is, it must not be possible to return to an element declaration
19549
  * by repeatedly following the {substitution group affiliation}
19550
  * property."
19551
  */
19552
40
  if (head == elemDecl)
19553
8
      circ = head;
19554
32
  else if (WXS_SUBST_HEAD(head) != NULL)
19555
5
      circ = xmlSchemaCheckSubstGroupCircular(head, head);
19556
27
  else
19557
27
      circ = NULL;
19558
40
  if (circ != NULL) {
19559
13
      xmlChar *strA = NULL, *strB = NULL;
19560
19561
13
      xmlSchemaPCustomErrExt(pctxt,
19562
13
    XML_SCHEMAP_E_PROPS_CORRECT_6,
19563
13
    WXS_BASIC_CAST circ, NULL,
19564
13
    "The element declaration '%s' defines a circular "
19565
13
    "substitution group to element declaration '%s'",
19566
13
    xmlSchemaGetComponentQName(&strA, circ),
19567
13
    xmlSchemaGetComponentQName(&strB, head),
19568
13
    NULL);
19569
13
      FREE_AND_NULL(strA)
19570
13
      FREE_AND_NULL(strB)
19571
13
      ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19572
13
  }
19573
  /*
19574
  * SPEC (4) "If there is a {substitution group affiliation},
19575
  * the {type definition}
19576
  * of the element declaration must be validly derived from the {type
19577
  * definition} of the {substitution group affiliation}, given the value
19578
  * of the {substitution group exclusions} of the {substitution group
19579
  * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19580
  * (if the {type definition} is complex) or as defined in
19581
  * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19582
  * simple)."
19583
  *
19584
  * NOTE: {substitution group exclusions} means the values of the
19585
  * attribute "final".
19586
  */
19587
19588
40
  if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19589
7
      int set = 0;
19590
19591
7
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19592
0
    set |= SUBSET_EXTENSION;
19593
7
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19594
0
    set |= SUBSET_RESTRICTION;
19595
19596
7
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19597
7
    WXS_ELEM_TYPEDEF(head), set) != 0) {
19598
1
    xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19599
19600
1
    ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19601
1
    xmlSchemaPCustomErrExt(pctxt,
19602
1
        XML_SCHEMAP_E_PROPS_CORRECT_4,
19603
1
        WXS_BASIC_CAST elemDecl, NULL,
19604
1
        "The type definition '%s' was "
19605
1
        "either rejected by the substitution group "
19606
1
        "affiliation '%s', or not validly derived from its type "
19607
1
        "definition '%s'",
19608
1
        xmlSchemaGetComponentQName(&strA, typeDef),
19609
1
        xmlSchemaGetComponentQName(&strB, head),
19610
1
        xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19611
1
    FREE_AND_NULL(strA)
19612
1
    FREE_AND_NULL(strB)
19613
1
    FREE_AND_NULL(strC)
19614
1
      }
19615
7
  }
19616
40
    }
19617
    /*
19618
    * SPEC (5) "If the {type definition} or {type definition}'s
19619
    * {content type}
19620
    * is or is derived from ID then there must not be a {value constraint}.
19621
    * Note: The use of ID as a type definition for elements goes beyond
19622
    * XML 1.0, and should be avoided if backwards compatibility is desired"
19623
    */
19624
4.93k
    if ((elemDecl->value != NULL) &&
19625
4.93k
  ((WXS_IS_SIMPLE(typeDef) &&
19626
2.94k
    xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19627
2.94k
   (WXS_IS_COMPLEX(typeDef) &&
19628
2.94k
    WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19629
2.94k
    xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19630
0
      XML_SCHEMAS_ID)))) {
19631
19632
0
  ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19633
0
  xmlSchemaPCustomErr(pctxt,
19634
0
      XML_SCHEMAP_E_PROPS_CORRECT_5,
19635
0
      WXS_BASIC_CAST elemDecl, NULL,
19636
0
      "The type definition (or type definition's content type) is or "
19637
0
      "is derived from ID; value constraints are not allowed in "
19638
0
      "conjunction with such a type definition", NULL);
19639
4.93k
    } else if (elemDecl->value != NULL) {
19640
2.94k
  int vcret;
19641
2.94k
  xmlNodePtr node = NULL;
19642
19643
  /*
19644
  * SPEC (2) "If there is a {value constraint}, the canonical lexical
19645
  * representation of its value must be `valid` with respect to the
19646
  * {type definition} as defined in Element Default Valid (Immediate)
19647
  * ($3.3.6)."
19648
  */
19649
2.94k
  if (typeDef == NULL) {
19650
0
      xmlSchemaPErr(pctxt, elemDecl->node,
19651
0
    XML_SCHEMAP_INTERNAL,
19652
0
    "Internal error: xmlSchemaCheckElemPropsCorrect, "
19653
0
    "type is missing... skipping validation of "
19654
0
    "the value constraint", NULL, NULL);
19655
0
      return (-1);
19656
0
  }
19657
2.94k
  if (elemDecl->node != NULL) {
19658
2.94k
      if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19659
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19660
0
        BAD_CAST "fixed");
19661
2.94k
      else
19662
2.94k
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19663
2.94k
        BAD_CAST "default");
19664
2.94k
  }
19665
2.94k
  vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19666
2.94k
      typeDef, elemDecl->value, &(elemDecl->defVal));
19667
2.94k
  if (vcret != 0) {
19668
2.54k
      if (vcret < 0) {
19669
0
    PERROR_INT("xmlSchemaElemCheckValConstr",
19670
0
        "failed to validate the value constraint of an "
19671
0
        "element declaration");
19672
0
    return (-1);
19673
0
      }
19674
2.54k
      return (vcret);
19675
2.54k
  }
19676
2.94k
    }
19677
19678
2.39k
    return (ret);
19679
4.93k
}
19680
19681
/**
19682
 * xmlSchemaCheckElemSubstGroup:
19683
 * @ctxt:  a schema parser context
19684
 * @decl: the element declaration
19685
 * @name:  the name of the attribute
19686
 *
19687
 * Schema Component Constraint:
19688
 * Substitution Group (cos-equiv-class)
19689
 *
19690
 * In Libxml2 the subst. groups will be precomputed, in terms of that
19691
 * a list will be built for each subst. group head, holding all direct
19692
 * referents to this head.
19693
 * NOTE that this function needs:
19694
 *   1. circular subst. groups to be checked beforehand
19695
 *   2. the declaration's type to be derived from the head's type
19696
 *
19697
 * STATUS:
19698
 *
19699
 */
19700
static void
19701
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19702
           xmlSchemaElementPtr elemDecl)
19703
2.37k
{
19704
2.37k
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19705
  /* SPEC (1) "Its {abstract} is false." */
19706
2.37k
  (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19707
2.35k
  return;
19708
27
    {
19709
27
  xmlSchemaElementPtr head;
19710
27
  xmlSchemaTypePtr headType, type;
19711
27
  int set, methSet;
19712
  /*
19713
  * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19714
  * {disallowed substitutions} as the blocking constraint, as defined in
19715
  * Substitution Group OK (Transitive) ($3.3.6)."
19716
  */
19717
54
  for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19718
27
      head = WXS_SUBST_HEAD(head)) {
19719
27
      set = 0;
19720
27
      methSet = 0;
19721
      /*
19722
      * The blocking constraints.
19723
      */
19724
27
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19725
0
    continue;
19726
27
      headType = head->subtypes;
19727
27
      type = elemDecl->subtypes;
19728
27
      if (headType == type)
19729
25
    goto add_member;
19730
2
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19731
0
    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19732
2
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19733
0
    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19734
      /*
19735
      * SPEC: Substitution Group OK (Transitive) (2.3)
19736
      * "The set of all {derivation method}s involved in the
19737
      * derivation of D's {type definition} from C's {type definition}
19738
      * does not intersect with the union of the blocking constraint,
19739
      * C's {prohibited substitutions} (if C is complex, otherwise the
19740
      * empty set) and the {prohibited substitutions} (respectively the
19741
      * empty set) of any intermediate {type definition}s in the
19742
      * derivation of D's {type definition} from C's {type definition}."
19743
      */
19744
      /*
19745
      * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19746
      * subst.head axis, the methSet does not need to be computed for
19747
      * the full depth over and over.
19748
      */
19749
      /*
19750
      * The set of all {derivation method}s involved in the derivation
19751
      */
19752
5
      while ((type != NULL) && (type != headType) &&
19753
5
                   (type != type->baseType)) {
19754
3
    if ((WXS_IS_EXTENSION(type)) &&
19755
3
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19756
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19757
19758
3
    if (WXS_IS_RESTRICTION(type) &&
19759
3
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19760
1
        methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19761
19762
3
    type = type->baseType;
19763
3
      }
19764
      /*
19765
      * The {prohibited substitutions} of all intermediate types +
19766
      * the head's type.
19767
      */
19768
2
      type = elemDecl->subtypes->baseType;
19769
2
      while (type != NULL) {
19770
2
    if (WXS_IS_COMPLEX(type)) {
19771
1
        if ((type->flags &
19772
1
          XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19773
1
      ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19774
0
        set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19775
1
        if ((type->flags &
19776
1
          XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19777
1
      ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19778
0
        set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19779
1
    } else
19780
1
        break;
19781
1
    if (type == headType)
19782
1
        break;
19783
0
    type = type->baseType;
19784
0
      }
19785
2
      if ((set != 0) &&
19786
2
    (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19787
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19788
0
    ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19789
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19790
0
    continue;
19791
0
      }
19792
27
add_member:
19793
27
      xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19794
27
      if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19795
9
    head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19796
27
  }
19797
27
    }
19798
27
}
19799
19800
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19801
/**
19802
 * xmlSchemaCheckElementDeclComponent
19803
 * @pctxt: the schema parser context
19804
 * @ctxtComponent: the context component (an element declaration)
19805
 * @ctxtParticle: the first particle of the context component
19806
 * @searchParticle: the element declaration particle to be analysed
19807
 *
19808
 * Schema Component Constraint: Element Declarations Consistent
19809
 */
19810
static int
19811
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19812
            xmlSchemaBasicItemPtr ctxtComponent,
19813
            xmlSchemaParticlePtr ctxtParticle,
19814
            xmlSchemaParticlePtr searchParticle,
19815
            xmlSchemaParticlePtr curParticle,
19816
            int search)
19817
{
19818
    return(0);
19819
19820
    int ret = 0;
19821
    xmlSchemaParticlePtr cur = curParticle;
19822
    if (curParticle == NULL) {
19823
  return(0);
19824
    }
19825
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19826
  /*
19827
  * Just return in this case. A missing "term" of the particle
19828
  * might arise due to an invalid "term" component.
19829
  */
19830
  return(0);
19831
    }
19832
    while (cur != NULL) {
19833
  switch (WXS_PARTICLE_TERM(cur)->type) {
19834
      case XML_SCHEMA_TYPE_ANY:
19835
    break;
19836
      case XML_SCHEMA_TYPE_ELEMENT:
19837
    if (search == 0) {
19838
        ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19839
      ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19840
        if (ret != 0)
19841
      return(ret);
19842
    } else {
19843
        xmlSchemaElementPtr elem =
19844
      WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19845
        /*
19846
        * SPEC Element Declarations Consistent:
19847
        * "If the {particles} contains, either directly,
19848
        * indirectly (that is, within the {particles} of a
19849
        * contained model group, recursively) or `implicitly`
19850
        * two or more element declaration particles with
19851
        * the same {name} and {target namespace}, then
19852
        * all their type definitions must be the same
19853
        * top-level definition [...]"
19854
        */
19855
        if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19856
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19857
      xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19858
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19859
        {
19860
      xmlChar *strA = NULL, *strB = NULL;
19861
19862
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19863
          /* TODO: error code */
19864
          XML_SCHEMAP_COS_NONAMBIG,
19865
          WXS_ITEM_NODE(cur), NULL,
19866
          "In the content model of %s, there are multiple "
19867
          "element declarations for '%s' with different "
19868
          "type definitions",
19869
          xmlSchemaGetComponentDesignation(&strA,
19870
        ctxtComponent),
19871
          xmlSchemaFormatQName(&strB,
19872
        WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19873
        WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19874
      FREE_AND_NULL(strA);
19875
      FREE_AND_NULL(strB);
19876
      return(XML_SCHEMAP_COS_NONAMBIG);
19877
        }
19878
    }
19879
    break;
19880
      case XML_SCHEMA_TYPE_SEQUENCE: {
19881
    break;
19882
    }
19883
      case XML_SCHEMA_TYPE_CHOICE:{
19884
    /*
19885
    xmlSchemaTreeItemPtr sub;
19886
19887
    sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19888
    while (sub != NULL) {
19889
        ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19890
      ctxtParticle, ctxtElem);
19891
        if (ret != 0)
19892
      return(ret);
19893
        sub = sub->next;
19894
    }
19895
    */
19896
    break;
19897
    }
19898
      case XML_SCHEMA_TYPE_ALL:
19899
    break;
19900
      case XML_SCHEMA_TYPE_GROUP:
19901
    break;
19902
      default:
19903
    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19904
        "xmlSchemaCheckElementDeclConsistent",
19905
        "found unexpected term of type '%s' in content model",
19906
        WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19907
    return(-1);
19908
  }
19909
  cur = (xmlSchemaParticlePtr) cur->next;
19910
    }
19911
19912
exit:
19913
    return(ret);
19914
}
19915
#endif
19916
19917
/**
19918
 * xmlSchemaCheckElementDeclComponent
19919
 * @item:  an schema element declaration/particle
19920
 * @ctxt:  a schema parser context
19921
 * @name:  the name of the attribute
19922
 *
19923
 * Validates the value constraints of an element declaration.
19924
 * Adds substitution group members.
19925
 */
19926
static void
19927
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19928
           xmlSchemaParserCtxtPtr ctxt)
19929
4.97k
{
19930
4.97k
    if (elemDecl == NULL)
19931
0
  return;
19932
4.97k
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19933
39
  return;
19934
4.93k
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19935
4.93k
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19936
  /*
19937
  * Adds substitution group members.
19938
  */
19939
2.37k
  xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19940
2.37k
    }
19941
4.93k
}
19942
19943
/**
19944
 * xmlSchemaResolveModelGroupParticleReferences:
19945
 * @particle:  a particle component
19946
 * @ctxt:  a parser context
19947
 *
19948
 * Resolves references of a model group's {particles} to
19949
 * model group definitions and to element declarations.
19950
 */
19951
static void
19952
xmlSchemaResolveModelGroupParticleReferences(
19953
    xmlSchemaParserCtxtPtr ctxt,
19954
    xmlSchemaModelGroupPtr mg)
19955
2.16k
{
19956
2.16k
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19957
2.16k
    xmlSchemaQNameRefPtr ref;
19958
2.16k
    xmlSchemaBasicItemPtr refItem;
19959
19960
    /*
19961
    * URGENT TODO: Test this.
19962
    */
19963
13.4k
    while (particle != NULL) {
19964
11.2k
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19965
11.2k
      ((WXS_PARTICLE_TERM(particle))->type !=
19966
11.1k
    XML_SCHEMA_EXTRA_QNAMEREF))
19967
10.2k
  {
19968
10.2k
      goto next_particle;
19969
10.2k
  }
19970
1.07k
  ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
19971
  /*
19972
  * Resolve the reference.
19973
  * NULL the {term} by default.
19974
  */
19975
1.07k
  particle->children = NULL;
19976
19977
1.07k
  refItem = xmlSchemaGetNamedComponent(ctxt->schema,
19978
1.07k
      ref->itemType, ref->name, ref->targetNamespace);
19979
1.07k
  if (refItem == NULL) {
19980
142
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
19981
142
    NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
19982
142
    ref->targetNamespace, ref->itemType, NULL);
19983
      /* TODO: remove the particle. */
19984
142
      goto next_particle;
19985
142
  }
19986
932
  if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
19987
31
      if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
19988
    /* TODO: remove the particle. */
19989
0
    goto next_particle;
19990
      /*
19991
      * NOTE that we will assign the model group definition
19992
      * itself to the "term" of the particle. This will ease
19993
      * the check for circular model group definitions. After
19994
      * that the "term" will be assigned the model group of the
19995
      * model group definition.
19996
      */
19997
31
      if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
19998
31
        XML_SCHEMA_TYPE_ALL) {
19999
    /*
20000
    * SPEC cos-all-limited (1)
20001
    * SPEC cos-all-limited (1.2)
20002
    * "It appears only as the value of one or both of the
20003
    * following properties:"
20004
    * (1.1) "the {model group} property of a model group
20005
    *        definition."
20006
    * (1.2) "the {term} property of a particle [... of] the "
20007
    * {content type} of a complex type definition."
20008
    */
20009
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20010
        /* TODO: error code */
20011
0
        XML_SCHEMAP_COS_ALL_LIMITED,
20012
0
        WXS_ITEM_NODE(particle), NULL,
20013
0
        "A model group definition is referenced, but "
20014
0
        "it contains an 'all' model group, which "
20015
0
        "cannot be contained by model groups",
20016
0
        NULL, NULL);
20017
    /* TODO: remove the particle. */
20018
0
    goto next_particle;
20019
0
      }
20020
31
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20021
901
  } else {
20022
      /*
20023
      * TODO: Are referenced element declarations the only
20024
      * other components we expect here?
20025
      */
20026
901
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20027
901
  }
20028
11.2k
next_particle:
20029
11.2k
  particle = WXS_PTC_CAST particle->next;
20030
11.2k
    }
20031
2.16k
}
20032
20033
static int
20034
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20035
           xmlSchemaValPtr y)
20036
7.26k
{
20037
7.26k
    xmlSchemaTypePtr tx, ty, ptx, pty;
20038
7.26k
    int ret;
20039
20040
7.27k
    while (x != NULL) {
20041
  /* Same types. */
20042
7.26k
  tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20043
7.26k
  ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20044
7.26k
  ptx = xmlSchemaGetPrimitiveType(tx);
20045
7.26k
  pty = xmlSchemaGetPrimitiveType(ty);
20046
  /*
20047
  * (1) if a datatype T' is `derived` by `restriction` from an
20048
  * atomic datatype T then the `value space` of T' is a subset of
20049
  * the `value space` of T. */
20050
  /*
20051
  * (2) if datatypes T' and T'' are `derived` by `restriction`
20052
  * from a common atomic ancestor T then the `value space`s of T'
20053
  * and T'' may overlap.
20054
  */
20055
7.26k
  if (ptx != pty)
20056
7
      return(0);
20057
  /*
20058
  * We assume computed values to be normalized, so do a fast
20059
  * string comparison for string based types.
20060
  */
20061
7.25k
  if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20062
7.25k
      WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20063
431
      if (! xmlStrEqual(
20064
431
    xmlSchemaValueGetAsString(x),
20065
431
    xmlSchemaValueGetAsString(y)))
20066
381
    return (0);
20067
6.82k
  } else {
20068
6.82k
      ret = xmlSchemaCompareValuesWhtsp(
20069
6.82k
    x, XML_SCHEMA_WHITESPACE_PRESERVE,
20070
6.82k
    y, XML_SCHEMA_WHITESPACE_PRESERVE);
20071
6.82k
      if (ret == -2)
20072
0
    return(-1);
20073
6.82k
      if (ret != 0)
20074
6.71k
    return(0);
20075
6.82k
  }
20076
  /*
20077
  * Lists.
20078
  */
20079
162
  x = xmlSchemaValueGetNext(x);
20080
162
  if (x != NULL) {
20081
10
      y = xmlSchemaValueGetNext(y);
20082
10
      if (y == NULL)
20083
0
    return (0);
20084
152
  } else if (xmlSchemaValueGetNext(y) != NULL)
20085
0
      return (0);
20086
152
  else
20087
152
      return (1);
20088
162
    }
20089
7
    return (0);
20090
7.26k
}
20091
20092
/**
20093
 * xmlSchemaResolveAttrUseReferences:
20094
 * @item:  an attribute use
20095
 * @ctxt:  a parser context
20096
 *
20097
 * Resolves the referenced attribute declaration.
20098
 */
20099
static int
20100
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20101
          xmlSchemaParserCtxtPtr ctxt)
20102
173
{
20103
173
    if ((ctxt == NULL) || (ause == NULL))
20104
0
  return(-1);
20105
173
    if ((ause->attrDecl == NULL) ||
20106
173
  (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20107
0
  return(0);
20108
20109
173
    {
20110
173
  xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20111
20112
  /*
20113
  * TODO: Evaluate, what errors could occur if the declaration is not
20114
  * found.
20115
  */
20116
173
  ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20117
173
      ref->name, ref->targetNamespace);
20118
173
        if (ause->attrDecl == NULL) {
20119
39
      xmlSchemaPResCompAttrErr(ctxt,
20120
39
    XML_SCHEMAP_SRC_RESOLVE,
20121
39
    WXS_BASIC_CAST ause, ause->node,
20122
39
    "ref", ref->name, ref->targetNamespace,
20123
39
    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20124
39
            return(ctxt->err);;
20125
0
        }
20126
173
    }
20127
134
    return(0);
20128
173
}
20129
20130
/**
20131
 * xmlSchemaCheckAttrUsePropsCorrect:
20132
 * @ctxt:  a parser context
20133
 * @use:  an attribute use
20134
 *
20135
 * Schema Component Constraint:
20136
 * Attribute Use Correct (au-props-correct)
20137
 *
20138
 */
20139
static int
20140
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20141
           xmlSchemaAttributeUsePtr use)
20142
0
{
20143
0
    if ((ctxt == NULL) || (use == NULL))
20144
0
  return(-1);
20145
0
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20146
0
  ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20147
0
  return(0);
20148
20149
    /*
20150
    * SPEC au-props-correct (1)
20151
    * "The values of the properties of an attribute use must be as
20152
    * described in the property tableau in The Attribute Use Schema
20153
    * Component ($3.5.1), modulo the impact of Missing
20154
    * Sub-components ($5.3)."
20155
    */
20156
20157
0
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20158
0
  ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20159
0
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20160
0
    {
20161
0
  xmlSchemaPCustomErr(ctxt,
20162
0
      XML_SCHEMAP_AU_PROPS_CORRECT_2,
20163
0
      WXS_BASIC_CAST use, NULL,
20164
0
      "The attribute declaration has a 'fixed' value constraint "
20165
0
      ", thus the attribute use must also have a 'fixed' value "
20166
0
      "constraint",
20167
0
      NULL);
20168
0
  return(ctxt->err);
20169
0
    }
20170
    /*
20171
    * Compute and check the value constraint's value.
20172
    */
20173
0
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20174
0
  int ret;
20175
  /*
20176
  * TODO: The spec seems to be missing a check of the
20177
  * value constraint of the attribute use. We will do it here.
20178
  */
20179
  /*
20180
  * SPEC a-props-correct (3)
20181
  */
20182
0
  if (xmlSchemaIsDerivedFromBuiltInType(
20183
0
      WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20184
0
  {
20185
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20186
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20187
0
    NULL, WXS_BASIC_CAST use,
20188
0
    "Value constraints are not allowed if the type definition "
20189
0
    "is or is derived from xs:ID",
20190
0
    NULL, NULL);
20191
0
      return(ctxt->err);
20192
0
  }
20193
20194
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20195
0
      use->node, WXS_ATTRUSE_TYPEDEF(use),
20196
0
      use->defValue, &(use->defVal),
20197
0
      1, 1, 0);
20198
0
  if (ret != 0) {
20199
0
      if (ret < 0) {
20200
0
    PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20201
0
        "calling xmlSchemaVCheckCVCSimpleType()");
20202
0
    return(-1);
20203
0
      }
20204
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20205
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20206
0
    NULL, WXS_BASIC_CAST use,
20207
0
    "The value of the value constraint is not valid",
20208
0
    NULL, NULL);
20209
0
      return(ctxt->err);
20210
0
  }
20211
0
    }
20212
    /*
20213
    * SPEC au-props-correct (2)
20214
    * "If the {attribute declaration} has a fixed
20215
    * {value constraint}, then if the attribute use itself has a
20216
    * {value constraint}, it must also be fixed and its value must match
20217
    * that of the {attribute declaration}'s {value constraint}."
20218
    */
20219
0
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20220
0
  (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20221
0
    {
20222
0
  if (! xmlSchemaAreValuesEqual(use->defVal,
20223
0
    (WXS_ATTRUSE_DECL(use))->defVal))
20224
0
  {
20225
0
      xmlSchemaPCustomErr(ctxt,
20226
0
    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20227
0
    WXS_BASIC_CAST use, NULL,
20228
0
    "The 'fixed' value constraint of the attribute use "
20229
0
    "must match the attribute declaration's value "
20230
0
    "constraint '%s'",
20231
0
    (WXS_ATTRUSE_DECL(use))->defValue);
20232
0
  }
20233
0
  return(ctxt->err);
20234
0
    }
20235
0
    return(0);
20236
0
}
20237
20238
20239
20240
20241
/**
20242
 * xmlSchemaResolveAttrTypeReferences:
20243
 * @item:  an attribute declaration
20244
 * @ctxt:  a parser context
20245
 *
20246
 * Resolves the referenced type definition component.
20247
 */
20248
static int
20249
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20250
           xmlSchemaParserCtxtPtr ctxt)
20251
2.55k
{
20252
    /*
20253
    * The simple type definition corresponding to the <simpleType> element
20254
    * information item in the [children], if present, otherwise the simple
20255
    * type definition `resolved` to by the `actual value` of the type
20256
    * [attribute], if present, otherwise the `simple ur-type definition`.
20257
    */
20258
2.55k
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20259
0
  return(0);
20260
2.55k
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20261
2.55k
    if (item->subtypes != NULL)
20262
365
        return(0);
20263
2.18k
    if (item->typeName != NULL) {
20264
734
        xmlSchemaTypePtr type;
20265
20266
734
  type = xmlSchemaGetType(ctxt->schema, item->typeName,
20267
734
      item->typeNs);
20268
734
  if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20269
38
      xmlSchemaPResCompAttrErr(ctxt,
20270
38
    XML_SCHEMAP_SRC_RESOLVE,
20271
38
    WXS_BASIC_CAST item, item->node,
20272
38
    "type", item->typeName, item->typeNs,
20273
38
    XML_SCHEMA_TYPE_SIMPLE, NULL);
20274
38
      return(ctxt->err);
20275
38
  } else
20276
696
      item->subtypes = type;
20277
20278
1.45k
    } else {
20279
  /*
20280
  * The type defaults to the xs:anySimpleType.
20281
  */
20282
1.45k
  item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20283
1.45k
    }
20284
2.15k
    return(0);
20285
2.18k
}
20286
20287
/**
20288
 * xmlSchemaResolveIDCKeyReferences:
20289
 * @idc:  the identity-constraint definition
20290
 * @ctxt:  the schema parser context
20291
 * @name:  the attribute name
20292
 *
20293
 * Resolve keyRef references to key/unique IDCs.
20294
 * Schema Component Constraint:
20295
 *   Identity-constraint Definition Properties Correct (c-props-correct)
20296
 */
20297
static int
20298
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20299
        xmlSchemaParserCtxtPtr pctxt)
20300
4
{
20301
4
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20302
0
        return(0);
20303
4
    if (idc->ref->name != NULL) {
20304
4
  idc->ref->item = (xmlSchemaBasicItemPtr)
20305
4
      xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20306
4
    idc->ref->targetNamespace);
20307
4
        if (idc->ref->item == NULL) {
20308
      /*
20309
      * TODO: It is actually not an error to fail to resolve
20310
      * at this stage. BUT we need to be that strict!
20311
      */
20312
1
      xmlSchemaPResCompAttrErr(pctxt,
20313
1
    XML_SCHEMAP_SRC_RESOLVE,
20314
1
    WXS_BASIC_CAST idc, idc->node,
20315
1
    "refer", idc->ref->name,
20316
1
    idc->ref->targetNamespace,
20317
1
    XML_SCHEMA_TYPE_IDC_KEY, NULL);
20318
1
            return(pctxt->err);
20319
3
  } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20320
      /*
20321
      * SPEC c-props-correct (1)
20322
      */
20323
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20324
0
    XML_SCHEMAP_C_PROPS_CORRECT,
20325
0
    NULL, WXS_BASIC_CAST idc,
20326
0
    "The keyref references a keyref",
20327
0
    NULL, NULL);
20328
0
      idc->ref->item = NULL;
20329
0
      return(pctxt->err);
20330
3
  } else {
20331
3
      if (idc->nbFields !=
20332
3
    ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20333
0
    xmlChar *str = NULL;
20334
0
    xmlSchemaIDCPtr refer;
20335
20336
0
    refer = (xmlSchemaIDCPtr) idc->ref->item;
20337
    /*
20338
    * SPEC c-props-correct(2)
20339
    * "If the {identity-constraint category} is keyref,
20340
    * the cardinality of the {fields} must equal that of
20341
    * the {fields} of the {referenced key}.
20342
    */
20343
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20344
0
        XML_SCHEMAP_C_PROPS_CORRECT,
20345
0
        NULL, WXS_BASIC_CAST idc,
20346
0
        "The cardinality of the keyref differs from the "
20347
0
        "cardinality of the referenced key/unique '%s'",
20348
0
        xmlSchemaFormatQName(&str, refer->targetNamespace,
20349
0
      refer->name),
20350
0
        NULL);
20351
0
    FREE_AND_NULL(str)
20352
0
    return(pctxt->err);
20353
0
      }
20354
3
  }
20355
4
    }
20356
3
    return(0);
20357
4
}
20358
20359
static int
20360
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20361
               xmlSchemaParserCtxtPtr pctxt)
20362
0
{
20363
0
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20364
0
  prohib->targetNamespace) == NULL) {
20365
20366
0
  xmlSchemaPResCompAttrErr(pctxt,
20367
0
      XML_SCHEMAP_SRC_RESOLVE,
20368
0
      NULL, prohib->node,
20369
0
      "ref", prohib->name, prohib->targetNamespace,
20370
0
      XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20371
0
  return(XML_SCHEMAP_SRC_RESOLVE);
20372
0
    }
20373
0
    return(0);
20374
0
}
20375
20376
8.10k
#define WXS_REDEFINED_TYPE(c) \
20377
8.10k
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20378
20379
208
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20380
208
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20381
20382
538
#define WXS_REDEFINED_ATTR_GROUP(c) \
20383
538
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20384
20385
static int
20386
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20387
7.79k
{
20388
7.79k
    int err = 0;
20389
7.79k
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20390
7.79k
    xmlSchemaBasicItemPtr prev, item;
20391
7.79k
    int wasRedefined;
20392
20393
7.79k
    if (redef == NULL)
20394
7.79k
  return(0);
20395
20396
0
    do {
20397
0
  item = redef->item;
20398
  /*
20399
  * First try to locate the redefined component in the
20400
  * schema graph starting with the redefined schema.
20401
  * NOTE: According to this schema bug entry:
20402
  *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20403
  *   it's not clear if the referenced component needs to originate
20404
  *   from the <redefine>d schema _document_ or the schema; the latter
20405
  *   would include all imported and included sub-schemas of the
20406
  *   <redefine>d schema. Currently the latter approach is used.
20407
  *   SUPPLEMENT: It seems that the WG moves towards the latter
20408
  *   approach, so we are doing it right.
20409
  *
20410
  */
20411
0
  prev = xmlSchemaFindRedefCompInGraph(
20412
0
      redef->targetBucket, item->type,
20413
0
      redef->refName, redef->refTargetNs);
20414
0
  if (prev == NULL) {
20415
0
      xmlChar *str = NULL;
20416
0
      xmlNodePtr node;
20417
20418
      /*
20419
      * SPEC src-redefine:
20420
      * (6.2.1) "The `actual value` of its own name attribute plus
20421
      * target namespace must successfully `resolve` to a model
20422
      * group definition in I."
20423
      * (7.2.1) "The `actual value` of its own name attribute plus
20424
      * target namespace must successfully `resolve` to an attribute
20425
      * group definition in I."
20426
20427
      *
20428
      * Note that, if we are redefining with the use of references
20429
      * to components, the spec assumes the src-resolve to be used;
20430
      * but this won't assure that we search only *inside* the
20431
      * redefined schema.
20432
      */
20433
0
      if (redef->reference)
20434
0
    node = WXS_ITEM_NODE(redef->reference);
20435
0
      else
20436
0
    node = WXS_ITEM_NODE(item);
20437
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20438
    /*
20439
    * TODO: error code.
20440
    * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20441
    * reference kind.
20442
    */
20443
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20444
0
    "The %s '%s' to be redefined could not be found in "
20445
0
    "the redefined schema",
20446
0
    WXS_ITEM_TYPE_NAME(item),
20447
0
    xmlSchemaFormatQName(&str, redef->refTargetNs,
20448
0
        redef->refName));
20449
0
      FREE_AND_NULL(str);
20450
0
      err = pctxt->err;
20451
0
      redef = redef->next;
20452
0
      continue;
20453
0
  }
20454
  /*
20455
  * TODO: Obtaining and setting the redefinition state is really
20456
  * clumsy.
20457
  */
20458
0
  wasRedefined = 0;
20459
0
  switch (item->type) {
20460
0
      case XML_SCHEMA_TYPE_COMPLEX:
20461
0
      case XML_SCHEMA_TYPE_SIMPLE:
20462
0
    if ((WXS_TYPE_CAST prev)->flags &
20463
0
        XML_SCHEMAS_TYPE_REDEFINED)
20464
0
    {
20465
0
        wasRedefined = 1;
20466
0
        break;
20467
0
    }
20468
    /* Mark it as redefined. */
20469
0
    (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20470
    /*
20471
    * Assign the redefined type to the
20472
    * base type of the redefining type.
20473
    * TODO: How
20474
    */
20475
0
    ((xmlSchemaTypePtr) item)->baseType =
20476
0
        (xmlSchemaTypePtr) prev;
20477
0
    break;
20478
0
      case XML_SCHEMA_TYPE_GROUP:
20479
0
    if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20480
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20481
0
    {
20482
0
        wasRedefined = 1;
20483
0
        break;
20484
0
    }
20485
    /* Mark it as redefined. */
20486
0
    (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20487
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20488
0
    if (redef->reference != NULL) {
20489
        /*
20490
        * Overwrite the QName-reference with the
20491
        * referenced model group def.
20492
        */
20493
0
        (WXS_PTC_CAST redef->reference)->children =
20494
0
      WXS_TREE_CAST prev;
20495
0
    }
20496
0
    redef->target = prev;
20497
0
    break;
20498
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20499
0
    if ((WXS_ATTR_GROUP_CAST prev)->flags &
20500
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED)
20501
0
    {
20502
0
        wasRedefined = 1;
20503
0
        break;
20504
0
    }
20505
0
    (WXS_ATTR_GROUP_CAST prev)->flags |=
20506
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED;
20507
0
    if (redef->reference != NULL) {
20508
        /*
20509
        * Assign the redefined attribute group to the
20510
        * QName-reference component.
20511
        * This is the easy case, since we will just
20512
        * expand the redefined group.
20513
        */
20514
0
        (WXS_QNAME_CAST redef->reference)->item = prev;
20515
0
        redef->target = NULL;
20516
0
    } else {
20517
        /*
20518
        * This is the complicated case: we need
20519
        * to apply src-redefine (7.2.2) at a later
20520
        * stage, i.e. when attribute group references
20521
        * have been expanded and simple types have
20522
        * been fixed.
20523
        */
20524
0
        redef->target = prev;
20525
0
    }
20526
0
    break;
20527
0
      default:
20528
0
    PERROR_INT("xmlSchemaResolveRedefReferences",
20529
0
        "Unexpected redefined component type");
20530
0
    return(-1);
20531
0
  }
20532
0
  if (wasRedefined) {
20533
0
      xmlChar *str = NULL;
20534
0
      xmlNodePtr node;
20535
20536
0
      if (redef->reference)
20537
0
    node = WXS_ITEM_NODE(redef->reference);
20538
0
      else
20539
0
    node = WXS_ITEM_NODE(redef->item);
20540
20541
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20542
    /* TODO: error code. */
20543
0
    XML_SCHEMAP_SRC_REDEFINE,
20544
0
    node, NULL,
20545
0
    "The referenced %s was already redefined. Multiple "
20546
0
    "redefinition of the same component is not supported",
20547
0
    xmlSchemaGetComponentDesignation(&str, prev),
20548
0
    NULL);
20549
0
      FREE_AND_NULL(str)
20550
0
      err = pctxt->err;
20551
0
      redef = redef->next;
20552
0
      continue;
20553
0
  }
20554
0
  redef = redef->next;
20555
0
    } while (redef != NULL);
20556
20557
0
    return(err);
20558
0
}
20559
20560
static int
20561
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20562
0
{
20563
0
    int err = 0;
20564
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20565
0
    xmlSchemaBasicItemPtr item;
20566
20567
0
    if (redef == NULL)
20568
0
  return(0);
20569
20570
0
    do {
20571
0
  if (redef->target == NULL) {
20572
0
      redef = redef->next;
20573
0
      continue;
20574
0
  }
20575
0
  item = redef->item;
20576
20577
0
  switch (item->type) {
20578
0
      case XML_SCHEMA_TYPE_SIMPLE:
20579
0
      case XML_SCHEMA_TYPE_COMPLEX:
20580
    /*
20581
    * Since the spec wants the {name} of the redefined
20582
    * type to be 'absent', we'll NULL it.
20583
    */
20584
0
    (WXS_TYPE_CAST redef->target)->name = NULL;
20585
20586
    /*
20587
    * TODO: Seems like there's nothing more to do. The normal
20588
    * inheritance mechanism is used. But not 100% sure.
20589
    */
20590
0
    break;
20591
0
      case XML_SCHEMA_TYPE_GROUP:
20592
    /*
20593
    * URGENT TODO:
20594
    * SPEC src-redefine:
20595
    * (6.2.2) "The {model group} of the model group definition
20596
    * which corresponds to it per XML Representation of Model
20597
    * Group Definition Schema Components ($3.7.2) must be a
20598
    * `valid restriction` of the {model group} of that model
20599
    * group definition in I, as defined in Particle Valid
20600
    * (Restriction) ($3.9.6)."
20601
    */
20602
0
    break;
20603
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20604
    /*
20605
    * SPEC src-redefine:
20606
    * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20607
    * the attribute group definition which corresponds to it
20608
    * per XML Representation of Attribute Group Definition Schema
20609
    * Components ($3.6.2) must be `valid restrictions` of the
20610
    * {attribute uses} and {attribute wildcard} of that attribute
20611
    * group definition in I, as defined in clause 2, clause 3 and
20612
    * clause 4 of Derivation Valid (Restriction, Complex)
20613
    * ($3.4.6) (where references to the base type definition are
20614
    * understood as references to the attribute group definition
20615
    * in I)."
20616
    */
20617
0
    err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20618
0
        XML_SCHEMA_ACTION_REDEFINE,
20619
0
        item, redef->target,
20620
0
        (WXS_ATTR_GROUP_CAST item)->attrUses,
20621
0
        (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20622
0
        (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20623
0
        (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20624
0
    if (err == -1)
20625
0
        return(-1);
20626
0
    break;
20627
0
      default:
20628
0
    break;
20629
0
  }
20630
0
  redef = redef->next;
20631
0
    } while (redef != NULL);
20632
0
    return(0);
20633
0
}
20634
20635
20636
static int
20637
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20638
           xmlSchemaBucketPtr bucket)
20639
7.93k
{
20640
7.93k
    xmlSchemaBasicItemPtr item;
20641
7.93k
    int err;
20642
7.93k
    xmlHashTablePtr *table;
20643
7.93k
    const xmlChar *name;
20644
7.93k
    int i;
20645
20646
12.5k
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20647
12.5k
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20648
12.5k
  table = &(WXS_IMPBUCKET((c))->schema->slot); \
20649
12.5k
    else \
20650
12.5k
  table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20651
20652
    /*
20653
    * Add global components to the schema's hash tables.
20654
    * This is the place where duplicate components will be
20655
    * detected.
20656
    * TODO: I think normally we should support imports of the
20657
    *   same namespace from multiple locations. We don't do currently,
20658
    *   but if we do then according to:
20659
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20660
    *   we would need, if imported directly, to import redefined
20661
    *   components as well to be able to catch clashing components.
20662
    *   (I hope I'll still know what this means after some months :-()
20663
    */
20664
7.93k
    if (bucket == NULL)
20665
0
  return(-1);
20666
7.93k
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20667
0
  return(0);
20668
7.93k
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20669
20670
20.5k
    for (i = 0; i < bucket->globals->nbItems; i++) {
20671
12.5k
  item = bucket->globals->items[i];
20672
12.5k
  table = NULL;
20673
12.5k
  switch (item->type) {
20674
1.83k
      case XML_SCHEMA_TYPE_COMPLEX:
20675
8.10k
      case XML_SCHEMA_TYPE_SIMPLE:
20676
8.10k
    if (WXS_REDEFINED_TYPE(item))
20677
0
        continue;
20678
8.10k
    name = (WXS_TYPE_CAST item)->name;
20679
8.10k
    WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20680
8.10k
    break;
20681
3.21k
      case XML_SCHEMA_TYPE_ELEMENT:
20682
3.21k
    name = (WXS_ELEM_CAST item)->name;
20683
3.21k
    WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20684
3.21k
    break;
20685
473
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20686
473
    name = (WXS_ATTR_CAST item)->name;
20687
473
    WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20688
473
    break;
20689
208
      case XML_SCHEMA_TYPE_GROUP:
20690
208
    if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20691
0
        continue;
20692
208
    name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20693
208
    WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20694
208
    break;
20695
538
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20696
538
    if (WXS_REDEFINED_ATTR_GROUP(item))
20697
0
        continue;
20698
538
    name = (WXS_ATTR_GROUP_CAST item)->name;
20699
538
    WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20700
538
    break;
20701
5
      case XML_SCHEMA_TYPE_IDC_KEY:
20702
25
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20703
29
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20704
29
    name = (WXS_IDC_CAST item)->name;
20705
29
    WXS_GET_GLOBAL_HASH(bucket, idcDef)
20706
29
    break;
20707
0
      case XML_SCHEMA_TYPE_NOTATION:
20708
0
    name = ((xmlSchemaNotationPtr) item)->name;
20709
0
    WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20710
0
    break;
20711
0
      default:
20712
0
    PERROR_INT("xmlSchemaAddComponents",
20713
0
        "Unexpected global component type");
20714
0
    continue;
20715
12.5k
  }
20716
12.5k
  if (*table == NULL) {
20717
8.80k
      *table = xmlHashCreateDict(10, pctxt->dict);
20718
8.80k
      if (*table == NULL) {
20719
0
    PERROR_INT("xmlSchemaAddComponents",
20720
0
        "failed to create a component hash table");
20721
0
    return(-1);
20722
0
      }
20723
8.80k
  }
20724
12.5k
  err = xmlHashAddEntry(*table, name, item);
20725
12.5k
  if (err != 0) {
20726
1.27k
      xmlChar *str = NULL;
20727
20728
1.27k
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20729
1.27k
    XML_SCHEMAP_REDEFINED_TYPE,
20730
1.27k
    WXS_ITEM_NODE(item),
20731
1.27k
    WXS_BASIC_CAST item,
20732
1.27k
    "A global %s '%s' does already exist",
20733
1.27k
    WXS_ITEM_TYPE_NAME(item),
20734
1.27k
    xmlSchemaGetComponentQName(&str, item));
20735
1.27k
      FREE_AND_NULL(str);
20736
1.27k
  }
20737
12.5k
    }
20738
    /*
20739
    * Process imported/included schemas.
20740
    */
20741
7.93k
    if (bucket->relations != NULL) {
20742
132
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
20743
218
  do {
20744
218
      if ((rel->bucket != NULL) &&
20745
218
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20746
140
    if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20747
0
        return(-1);
20748
140
      }
20749
218
      rel = rel->next;
20750
218
  } while (rel != NULL);
20751
132
    }
20752
7.93k
    return(0);
20753
7.93k
}
20754
20755
static int
20756
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20757
       xmlSchemaBucketPtr rootBucket)
20758
7.83k
{
20759
7.83k
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20760
7.83k
    xmlSchemaTreeItemPtr item, *items;
20761
7.83k
    int nbItems, i, ret = 0;
20762
7.83k
    xmlSchemaBucketPtr oldbucket = con->bucket;
20763
7.83k
    xmlSchemaElementPtr elemDecl;
20764
20765
63.2k
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20766
20767
7.83k
    if ((con->pending == NULL) ||
20768
7.83k
  (con->pending->nbItems == 0))
20769
45
  return(0);
20770
20771
    /*
20772
    * Since xmlSchemaFixupComplexType() will create new particles
20773
    * (local components), and those particle components need a bucket
20774
    * on the constructor, we'll assure here that the constructor has
20775
    * a bucket.
20776
    * TODO: Think about storing locals _only_ on the main bucket.
20777
    */
20778
7.79k
    if (con->bucket == NULL)
20779
7.79k
  con->bucket = rootBucket;
20780
20781
    /* TODO:
20782
    * SPEC (src-redefine):
20783
    * (6.2) "If it has no such self-reference, then all of the
20784
    * following must be true:"
20785
20786
    * (6.2.2) The {model group} of the model group definition which
20787
    * corresponds to it per XML Representation of Model Group
20788
    * Definition Schema Components ($3.7.2) must be a `valid
20789
    * restriction` of the {model group} of that model group definition
20790
    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20791
    */
20792
7.79k
    xmlSchemaCheckSRCRedefineFirst(pctxt);
20793
20794
    /*
20795
    * Add global components to the schemata's hash tables.
20796
    */
20797
7.79k
    xmlSchemaAddComponents(pctxt, rootBucket);
20798
20799
7.79k
    pctxt->ctxtType = NULL;
20800
7.79k
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
20801
7.79k
    nbItems = con->pending->nbItems;
20802
    /*
20803
    * Now that we have parsed *all* the schema document(s) and converted
20804
    * them to schema components, we can resolve references, apply component
20805
    * constraints, create the FSA from the content model, etc.
20806
    */
20807
    /*
20808
    * Resolve references of..
20809
    *
20810
    * 1. element declarations:
20811
    *   - the type definition
20812
    *   - the substitution group affiliation
20813
    * 2. simple/complex types:
20814
    *   - the base type definition
20815
    *   - the memberTypes of union types
20816
    *   - the itemType of list types
20817
    * 3. attributes declarations and attribute uses:
20818
    *   - the type definition
20819
    *   - if an attribute use, then the attribute declaration
20820
    * 4. attribute group references:
20821
    *   - the attribute group definition
20822
    * 5. particles:
20823
    *   - the term of the particle (e.g. a model group)
20824
    * 6. IDC key-references:
20825
    *   - the referenced IDC 'key' or 'unique' definition
20826
    * 7. Attribute prohibitions which had a "ref" attribute.
20827
    */
20828
36.9k
    for (i = 0; i < nbItems; i++) {
20829
29.1k
  item = items[i];
20830
29.1k
  switch (item->type) {
20831
7.94k
      case XML_SCHEMA_TYPE_ELEMENT:
20832
7.94k
    xmlSchemaResolveElementReferences(
20833
7.94k
        (xmlSchemaElementPtr) item, pctxt);
20834
7.94k
    FIXHFAILURE;
20835
7.94k
    break;
20836
2.97k
      case XML_SCHEMA_TYPE_COMPLEX:
20837
12.8k
      case XML_SCHEMA_TYPE_SIMPLE:
20838
12.8k
    xmlSchemaResolveTypeReferences(
20839
12.8k
        (xmlSchemaTypePtr) item, pctxt);
20840
12.8k
    FIXHFAILURE;
20841
12.8k
    break;
20842
2.55k
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20843
2.55k
    xmlSchemaResolveAttrTypeReferences(
20844
2.55k
        (xmlSchemaAttributePtr) item, pctxt);
20845
2.55k
    FIXHFAILURE;
20846
2.55k
    break;
20847
173
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20848
173
    xmlSchemaResolveAttrUseReferences(
20849
173
        (xmlSchemaAttributeUsePtr) item, pctxt);
20850
173
    FIXHFAILURE;
20851
173
    break;
20852
1.73k
      case XML_SCHEMA_EXTRA_QNAMEREF:
20853
1.73k
    if ((WXS_QNAME_CAST item)->itemType ==
20854
1.73k
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20855
1.73k
    {
20856
1.73k
        xmlSchemaResolveAttrGroupReferences(
20857
1.73k
      WXS_QNAME_CAST item, pctxt);
20858
1.73k
    }
20859
1.73k
    FIXHFAILURE;
20860
1.73k
    break;
20861
1.44k
      case XML_SCHEMA_TYPE_SEQUENCE:
20862
2.15k
      case XML_SCHEMA_TYPE_CHOICE:
20863
2.16k
      case XML_SCHEMA_TYPE_ALL:
20864
2.16k
    xmlSchemaResolveModelGroupParticleReferences(pctxt,
20865
2.16k
        WXS_MODEL_GROUP_CAST item);
20866
2.16k
    FIXHFAILURE;
20867
2.16k
    break;
20868
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20869
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20870
4
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20871
4
    xmlSchemaResolveIDCKeyReferences(
20872
4
        (xmlSchemaIDCPtr) item, pctxt);
20873
4
    FIXHFAILURE;
20874
4
    break;
20875
0
      case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20876
    /*
20877
    * Handle attribute prohibition which had a
20878
    * "ref" attribute.
20879
    */
20880
0
    xmlSchemaResolveAttrUseProhibReferences(
20881
0
        WXS_ATTR_PROHIB_CAST item, pctxt);
20882
0
    FIXHFAILURE;
20883
0
    break;
20884
1.78k
      default:
20885
1.78k
    break;
20886
29.1k
  }
20887
29.1k
    }
20888
7.79k
    if (pctxt->nberrors != 0)
20889
215
  goto exit_error;
20890
20891
    /*
20892
    * Now that all references are resolved we
20893
    * can check for circularity of...
20894
    * 1. the base axis of type definitions
20895
    * 2. nested model group definitions
20896
    * 3. nested attribute group definitions
20897
    * TODO: check for circular substitution groups.
20898
    */
20899
30.9k
    for (i = 0; i < nbItems; i++) {
20900
23.4k
  item = items[i];
20901
  /*
20902
  * Let's better stop on the first error here.
20903
  */
20904
23.4k
  switch (item->type) {
20905
1.76k
      case XML_SCHEMA_TYPE_COMPLEX:
20906
10.4k
      case XML_SCHEMA_TYPE_SIMPLE:
20907
10.4k
    xmlSchemaCheckTypeDefCircular(
20908
10.4k
        (xmlSchemaTypePtr) item, pctxt);
20909
10.4k
    FIXHFAILURE;
20910
10.4k
    if (pctxt->nberrors != 0)
20911
2
        goto exit_error;
20912
10.4k
    break;
20913
10.4k
      case XML_SCHEMA_TYPE_GROUP:
20914
145
    xmlSchemaCheckGroupDefCircular(
20915
145
        (xmlSchemaModelGroupDefPtr) item, pctxt);
20916
145
    FIXHFAILURE;
20917
145
    if (pctxt->nberrors != 0)
20918
0
        goto exit_error;
20919
145
    break;
20920
349
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20921
349
    xmlSchemaCheckAttrGroupCircular(
20922
349
        (xmlSchemaAttributeGroupPtr) item, pctxt);
20923
349
    FIXHFAILURE;
20924
349
    if (pctxt->nberrors != 0)
20925
7
        goto exit_error;
20926
342
    break;
20927
12.4k
      default:
20928
12.4k
    break;
20929
23.4k
  }
20930
23.4k
    }
20931
7.56k
    if (pctxt->nberrors != 0)
20932
0
  goto exit_error;
20933
    /*
20934
    * Model group definition references:
20935
    * Such a reference is reflected by a particle at the component
20936
    * level. Until now the 'term' of such particles pointed
20937
    * to the model group definition; this was done, in order to
20938
    * ease circularity checks. Now we need to set the 'term' of
20939
    * such particles to the model group of the model group definition.
20940
    */
20941
30.9k
    for (i = 0; i < nbItems; i++) {
20942
23.3k
  item = items[i];
20943
23.3k
  switch (item->type) {
20944
1.17k
      case XML_SCHEMA_TYPE_SEQUENCE:
20945
1.76k
      case XML_SCHEMA_TYPE_CHOICE:
20946
1.76k
    xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20947
1.76k
        WXS_MODEL_GROUP_CAST item);
20948
1.76k
    break;
20949
21.5k
      default:
20950
21.5k
    break;
20951
23.3k
  }
20952
23.3k
    }
20953
7.56k
    if (pctxt->nberrors != 0)
20954
0
  goto exit_error;
20955
    /*
20956
    * Expand attribute group references of attribute group definitions.
20957
    */
20958
30.9k
    for (i = 0; i < nbItems; i++) {
20959
23.3k
  item = items[i];
20960
23.3k
  switch (item->type) {
20961
330
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20962
330
    if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20963
330
        WXS_ATTR_GROUP_HAS_REFS(item))
20964
13
    {
20965
13
        xmlSchemaAttributeGroupExpandRefs(pctxt,
20966
13
      WXS_ATTR_GROUP_CAST item);
20967
13
        FIXHFAILURE;
20968
13
    }
20969
330
    break;
20970
23.0k
      default:
20971
23.0k
    break;
20972
23.3k
  }
20973
23.3k
    }
20974
7.56k
    if (pctxt->nberrors != 0)
20975
0
  goto exit_error;
20976
    /*
20977
    * First compute the variety of simple types. This is needed as
20978
    * a separate step, since otherwise we won't be able to detect
20979
    * circular union types in all cases.
20980
    */
20981
30.9k
    for (i = 0; i < nbItems; i++) {
20982
23.3k
  item = items[i];
20983
23.3k
  switch (item->type) {
20984
8.73k
            case XML_SCHEMA_TYPE_SIMPLE:
20985
8.73k
    if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
20986
8.19k
        xmlSchemaFixupSimpleTypeStageOne(pctxt,
20987
8.19k
      (xmlSchemaTypePtr) item);
20988
8.19k
        FIXHFAILURE;
20989
8.19k
    }
20990
8.73k
    break;
20991
14.6k
      default:
20992
14.6k
    break;
20993
23.3k
  }
20994
23.3k
    }
20995
7.56k
    if (pctxt->nberrors != 0)
20996
0
  goto exit_error;
20997
    /*
20998
    * Detect circular union types. Note that this needs the variety to
20999
    * be already computed.
21000
    */
21001
30.9k
    for (i = 0; i < nbItems; i++) {
21002
23.3k
  item = items[i];
21003
23.3k
  switch (item->type) {
21004
8.73k
            case XML_SCHEMA_TYPE_SIMPLE:
21005
8.73k
    if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21006
314
        xmlSchemaCheckUnionTypeDefCircular(pctxt,
21007
314
      (xmlSchemaTypePtr) item);
21008
314
        FIXHFAILURE;
21009
314
    }
21010
8.73k
    break;
21011
14.6k
      default:
21012
14.6k
    break;
21013
23.3k
  }
21014
23.3k
    }
21015
7.56k
    if (pctxt->nberrors != 0)
21016
0
  goto exit_error;
21017
21018
    /*
21019
    * Do the complete type fixup for simple types.
21020
    */
21021
30.7k
    for (i = 0; i < nbItems; i++) {
21022
23.2k
  item = items[i];
21023
23.2k
  switch (item->type) {
21024
8.67k
            case XML_SCHEMA_TYPE_SIMPLE:
21025
8.67k
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21026
7.87k
        xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21027
7.87k
        FIXHFAILURE;
21028
7.77k
    }
21029
8.57k
    break;
21030
14.6k
      default:
21031
14.6k
    break;
21032
23.2k
  }
21033
23.2k
    }
21034
7.47k
    if (pctxt->nberrors != 0)
21035
4.12k
  goto exit_error;
21036
    /*
21037
    * At this point we need build and check all simple types.
21038
    */
21039
    /*
21040
    * Apply constraints for attribute declarations.
21041
    */
21042
18.4k
    for (i = 0; i < nbItems; i++) {
21043
15.0k
  item = items[i];
21044
15.0k
  switch (item->type) {
21045
2.13k
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21046
2.13k
    xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21047
2.13k
    FIXHFAILURE;
21048
2.13k
    break;
21049
12.9k
      default:
21050
12.9k
    break;
21051
15.0k
  }
21052
15.0k
    }
21053
3.34k
    if (pctxt->nberrors != 0)
21054
82
  goto exit_error;
21055
    /*
21056
    * Apply constraints for attribute uses.
21057
    */
21058
18.0k
    for (i = 0; i < nbItems; i++) {
21059
14.7k
  item = items[i];
21060
14.7k
  switch (item->type) {
21061
74
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21062
74
    if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21063
0
        xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21064
0
      WXS_ATTR_USE_CAST item);
21065
0
        FIXHFAILURE;
21066
0
    }
21067
74
    break;
21068
14.7k
      default:
21069
14.7k
    break;
21070
14.7k
  }
21071
14.7k
    }
21072
3.26k
    if (pctxt->nberrors != 0)
21073
0
  goto exit_error;
21074
21075
    /*
21076
    * Apply constraints for attribute group definitions.
21077
    */
21078
18.0k
    for (i = 0; i < nbItems; i++) {
21079
14.7k
  item = items[i];
21080
14.7k
  switch (item->type) {
21081
303
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21082
303
      if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21083
303
    ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21084
14
      {
21085
14
    xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21086
14
    FIXHFAILURE;
21087
14
      }
21088
303
      break;
21089
14.4k
  default:
21090
14.4k
      break;
21091
14.7k
  }
21092
14.7k
    }
21093
3.26k
    if (pctxt->nberrors != 0)
21094
5
  goto exit_error;
21095
21096
    /*
21097
    * Apply constraints for redefinitions.
21098
    */
21099
3.26k
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21100
0
  xmlSchemaCheckSRCRedefineSecond(pctxt);
21101
3.26k
    if (pctxt->nberrors != 0)
21102
0
  goto exit_error;
21103
21104
    /*
21105
    * Complex types are built and checked.
21106
    */
21107
17.9k
    for (i = 0; i < nbItems; i++) {
21108
14.7k
  item = con->pending->items[i];
21109
14.7k
  switch (item->type) {
21110
1.60k
      case XML_SCHEMA_TYPE_COMPLEX:
21111
1.60k
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21112
1.40k
        xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21113
1.40k
        FIXHFAILURE;
21114
1.40k
    }
21115
1.60k
    break;
21116
13.1k
      default:
21117
13.1k
    break;
21118
14.7k
  }
21119
14.7k
    }
21120
3.26k
    if (pctxt->nberrors != 0)
21121
86
  goto exit_error;
21122
21123
    /*
21124
    * The list could have changed, since xmlSchemaFixupComplexType()
21125
    * will create particles and model groups in some cases.
21126
    */
21127
3.17k
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
21128
3.17k
    nbItems = con->pending->nbItems;
21129
21130
    /*
21131
    * Apply some constraints for element declarations.
21132
    */
21133
15.9k
    for (i = 0; i < nbItems; i++) {
21134
12.7k
  item = items[i];
21135
12.7k
  switch (item->type) {
21136
4.93k
      case XML_SCHEMA_TYPE_ELEMENT:
21137
4.93k
    elemDecl = (xmlSchemaElementPtr) item;
21138
21139
4.93k
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21140
4.93k
    {
21141
4.93k
        xmlSchemaCheckElementDeclComponent(
21142
4.93k
      (xmlSchemaElementPtr) elemDecl, pctxt);
21143
4.93k
        FIXHFAILURE;
21144
4.93k
    }
21145
21146
#ifdef WXS_ELEM_DECL_CONS_ENABLED
21147
    /*
21148
    * Schema Component Constraint: Element Declarations Consistent
21149
    * Apply this constraint to local types of element declarations.
21150
    */
21151
    if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21152
        (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21153
        (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21154
    {
21155
        xmlSchemaCheckElementDeclConsistent(pctxt,
21156
      WXS_BASIC_CAST elemDecl,
21157
      WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21158
      NULL, NULL, 0);
21159
    }
21160
#endif
21161
4.93k
    break;
21162
7.79k
      default:
21163
7.79k
    break;
21164
12.7k
  }
21165
12.7k
    }
21166
3.17k
    if (pctxt->nberrors != 0)
21167
95
  goto exit_error;
21168
21169
    /*
21170
    * Finally we can build the automaton from the content model of
21171
    * complex types.
21172
    */
21173
21174
12.6k
    for (i = 0; i < nbItems; i++) {
21175
9.52k
  item = items[i];
21176
9.52k
  switch (item->type) {
21177
1.41k
      case XML_SCHEMA_TYPE_COMPLEX:
21178
1.41k
    xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21179
    /* FIXHFAILURE; */
21180
1.41k
    break;
21181
8.11k
      default:
21182
8.11k
    break;
21183
9.52k
  }
21184
9.52k
    }
21185
3.08k
    if (pctxt->nberrors != 0)
21186
51
  goto exit_error;
21187
    /*
21188
    * URGENT TODO: cos-element-consistent
21189
    */
21190
3.03k
    goto exit;
21191
21192
4.66k
exit_error:
21193
4.66k
    ret = pctxt->err;
21194
4.66k
    goto exit;
21195
21196
96
exit_failure:
21197
96
    ret = -1;
21198
21199
7.79k
exit:
21200
    /*
21201
    * Reset the constructor. This is needed for XSI acquisition, since
21202
    * those items will be processed over and over again for every XSI
21203
    * if not cleared here.
21204
    */
21205
7.79k
    con->bucket = oldbucket;
21206
7.79k
    con->pending->nbItems = 0;
21207
7.79k
    if (con->substGroups != NULL) {
21208
7
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21209
7
  con->substGroups = NULL;
21210
7
    }
21211
7.79k
    if (con->redefs != NULL) {
21212
0
  xmlSchemaRedefListFree(con->redefs);
21213
0
  con->redefs = NULL;
21214
0
    }
21215
7.79k
    return(ret);
21216
96
}
21217
/**
21218
 * xmlSchemaParse:
21219
 * @ctxt:  a schema validation context
21220
 *
21221
 * parse a schema definition resource and build an internal
21222
 * XML Schema structure which can be used to validate instances.
21223
 *
21224
 * Returns the internal XML Schema structure built from the resource or
21225
 *         NULL in case of error
21226
 */
21227
xmlSchemaPtr
21228
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21229
29.0k
{
21230
29.0k
    xmlSchemaPtr mainSchema = NULL;
21231
29.0k
    xmlSchemaBucketPtr bucket = NULL;
21232
29.0k
    int res;
21233
21234
    /*
21235
    * This one is used if the schema to be parsed was specified via
21236
    * the API; i.e. not automatically by the validated instance document.
21237
    */
21238
21239
29.0k
    if (xmlSchemaInitTypes() < 0)
21240
0
        return (NULL);
21241
21242
29.0k
    if (ctxt == NULL)
21243
53
        return (NULL);
21244
21245
    /* TODO: Init the context. Is this all we need?*/
21246
29.0k
    ctxt->nberrors = 0;
21247
29.0k
    ctxt->err = 0;
21248
29.0k
    ctxt->counter = 0;
21249
21250
    /* Create the *main* schema. */
21251
29.0k
    mainSchema = xmlSchemaNewSchema(ctxt);
21252
29.0k
    if (mainSchema == NULL)
21253
0
  goto exit_failure;
21254
    /*
21255
    * Create the schema constructor.
21256
    */
21257
29.0k
    if (ctxt->constructor == NULL) {
21258
29.0k
  ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21259
29.0k
  if (ctxt->constructor == NULL)
21260
0
      goto exit_failure;
21261
  /* Take ownership of the constructor to be able to free it. */
21262
29.0k
  ctxt->ownsConstructor = 1;
21263
29.0k
    }
21264
29.0k
    ctxt->constructor->mainSchema = mainSchema;
21265
    /*
21266
    * Locate and add the schema document.
21267
    */
21268
29.0k
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21269
29.0k
  ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21270
29.0k
  NULL, NULL, &bucket);
21271
29.0k
    if (res == -1)
21272
0
  goto exit_failure;
21273
29.0k
    if (res != 0)
21274
16.0k
  goto exit;
21275
21276
13.0k
    if (bucket == NULL) {
21277
  /* TODO: Error code, actually we failed to *locate* the schema. */
21278
599
  if (ctxt->URL)
21279
599
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21280
599
    NULL, NULL,
21281
599
    "Failed to locate the main schema resource at '%s'",
21282
599
    ctxt->URL, NULL);
21283
0
  else
21284
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21285
0
    NULL, NULL,
21286
0
    "Failed to locate the main schema resource",
21287
0
        NULL, NULL);
21288
599
  goto exit;
21289
599
    }
21290
    /* Then do the parsing for good. */
21291
12.4k
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21292
4
  goto exit_failure;
21293
12.4k
    if (ctxt->nberrors != 0)
21294
4.58k
  goto exit;
21295
21296
7.83k
    mainSchema->doc = bucket->doc;
21297
7.83k
    mainSchema->preserve = ctxt->preserve;
21298
21299
7.83k
    ctxt->schema = mainSchema;
21300
21301
7.83k
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21302
96
  goto exit_failure;
21303
21304
    /*
21305
    * TODO: This is not nice, since we cannot distinguish from the
21306
    * result if there was an internal error or not.
21307
    */
21308
28.9k
exit:
21309
28.9k
    if (ctxt->nberrors != 0) {
21310
25.8k
  if (mainSchema) {
21311
25.8k
      xmlSchemaFree(mainSchema);
21312
25.8k
      mainSchema = NULL;
21313
25.8k
  }
21314
25.8k
  if (ctxt->constructor) {
21315
25.8k
      xmlSchemaConstructionCtxtFree(ctxt->constructor);
21316
25.8k
      ctxt->constructor = NULL;
21317
25.8k
      ctxt->ownsConstructor = 0;
21318
25.8k
  }
21319
25.8k
    }
21320
28.9k
    ctxt->schema = NULL;
21321
28.9k
    return(mainSchema);
21322
100
exit_failure:
21323
    /*
21324
    * Quite verbose, but should catch internal errors, which were
21325
    * not communicated.
21326
    */
21327
100
    if (mainSchema) {
21328
100
        xmlSchemaFree(mainSchema);
21329
100
  mainSchema = NULL;
21330
100
    }
21331
100
    if (ctxt->constructor) {
21332
100
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
21333
100
  ctxt->constructor = NULL;
21334
100
  ctxt->ownsConstructor = 0;
21335
100
    }
21336
100
    PERROR_INT2("xmlSchemaParse",
21337
100
  "An internal error occurred");
21338
100
    ctxt->schema = NULL;
21339
100
    return(NULL);
21340
7.83k
}
21341
21342
/**
21343
 * xmlSchemaSetParserErrors:
21344
 * @ctxt:  a schema validation context
21345
 * @err:  the error callback
21346
 * @warn:  the warning callback
21347
 * @ctx:  contextual data for the callbacks
21348
 *
21349
 * DEPRECATED: Use xmlSchemaSetParserStructuredErrors.
21350
 *
21351
 * Set the callback functions used to handle errors for a validation context
21352
 */
21353
void
21354
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21355
                         xmlSchemaValidityErrorFunc err,
21356
                         xmlSchemaValidityWarningFunc warn, void *ctx)
21357
29.3k
{
21358
29.3k
    if (ctxt == NULL)
21359
53
        return;
21360
29.3k
    ctxt->error = err;
21361
29.3k
    ctxt->warning = warn;
21362
29.3k
    ctxt->errCtxt = ctx;
21363
29.3k
    if (ctxt->vctxt != NULL)
21364
0
  xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21365
29.3k
}
21366
21367
/**
21368
 * xmlSchemaSetParserStructuredErrors:
21369
 * @ctxt:  a schema parser context
21370
 * @serror:  the structured error function
21371
 * @ctx: the functions context
21372
 *
21373
 * Set the structured error callback
21374
 */
21375
void
21376
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21377
           xmlStructuredErrorFunc serror,
21378
           void *ctx)
21379
261
{
21380
261
    if (ctxt == NULL)
21381
0
  return;
21382
261
    ctxt->serror = serror;
21383
261
    ctxt->errCtxt = ctx;
21384
261
    if (ctxt->vctxt != NULL)
21385
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21386
261
}
21387
21388
/**
21389
 * xmlSchemaGetParserErrors:
21390
 * @ctxt:  a XMl-Schema parser context
21391
 * @err: the error callback result
21392
 * @warn: the warning callback result
21393
 * @ctx: contextual data for the callbacks result
21394
 *
21395
 * Get the callback information used to handle errors for a parser context
21396
 *
21397
 * Returns -1 in case of failure, 0 otherwise
21398
 */
21399
int
21400
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21401
       xmlSchemaValidityErrorFunc * err,
21402
       xmlSchemaValidityWarningFunc * warn, void **ctx)
21403
0
{
21404
0
  if (ctxt == NULL)
21405
0
    return(-1);
21406
0
  if (err != NULL)
21407
0
    *err = ctxt->error;
21408
0
  if (warn != NULL)
21409
0
    *warn = ctxt->warning;
21410
0
  if (ctx != NULL)
21411
0
    *ctx = ctxt->errCtxt;
21412
0
  return(0);
21413
0
}
21414
21415
/**
21416
 * xmlSchemaFacetTypeToString:
21417
 * @type:  the facet type
21418
 *
21419
 * Convert the xmlSchemaTypeType to a char string.
21420
 *
21421
 * Returns the char string representation of the facet type if the
21422
 *     type is a facet and an "Internal Error" string otherwise.
21423
 */
21424
static const xmlChar *
21425
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21426
30.1k
{
21427
30.1k
    switch (type) {
21428
6.77k
        case XML_SCHEMA_FACET_PATTERN:
21429
6.77k
            return (BAD_CAST "pattern");
21430
4.58k
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21431
4.58k
            return (BAD_CAST "maxExclusive");
21432
8.12k
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
21433
8.12k
            return (BAD_CAST "maxInclusive");
21434
733
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
21435
733
            return (BAD_CAST "minExclusive");
21436
564
        case XML_SCHEMA_FACET_MININCLUSIVE:
21437
564
            return (BAD_CAST "minInclusive");
21438
27
        case XML_SCHEMA_FACET_WHITESPACE:
21439
27
            return (BAD_CAST "whiteSpace");
21440
6.45k
        case XML_SCHEMA_FACET_ENUMERATION:
21441
6.45k
            return (BAD_CAST "enumeration");
21442
988
        case XML_SCHEMA_FACET_LENGTH:
21443
988
            return (BAD_CAST "length");
21444
565
        case XML_SCHEMA_FACET_MAXLENGTH:
21445
565
            return (BAD_CAST "maxLength");
21446
344
        case XML_SCHEMA_FACET_MINLENGTH:
21447
344
            return (BAD_CAST "minLength");
21448
903
        case XML_SCHEMA_FACET_TOTALDIGITS:
21449
903
            return (BAD_CAST "totalDigits");
21450
49
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
21451
49
            return (BAD_CAST "fractionDigits");
21452
0
        default:
21453
0
            break;
21454
30.1k
    }
21455
0
    return (BAD_CAST "Internal Error");
21456
30.1k
}
21457
21458
static xmlSchemaWhitespaceValueType
21459
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21460
113k
{
21461
    /*
21462
    * The normalization type can be changed only for types which are derived
21463
    * from xsd:string.
21464
    */
21465
113k
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
21466
  /*
21467
  * Note that we assume a whitespace of preserve for anySimpleType.
21468
  */
21469
92.1k
  if ((type->builtInType == XML_SCHEMAS_STRING) ||
21470
92.1k
      (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21471
635
      return(XML_SCHEMA_WHITESPACE_PRESERVE);
21472
91.4k
  else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21473
0
      return(XML_SCHEMA_WHITESPACE_REPLACE);
21474
91.4k
  else {
21475
      /*
21476
      * For all `atomic` datatypes other than string (and types `derived`
21477
      * by `restriction` from it) the value of whiteSpace is fixed to
21478
      * collapse
21479
      * Note that this includes built-in list datatypes.
21480
      */
21481
91.4k
      return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21482
91.4k
  }
21483
92.1k
    } else if (WXS_IS_LIST(type)) {
21484
  /*
21485
  * For list types the facet "whiteSpace" is fixed to "collapse".
21486
  */
21487
179
  return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21488
21.6k
    } else if (WXS_IS_UNION(type)) {
21489
0
  return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21490
21.6k
    } else if (WXS_IS_ATOMIC(type)) {
21491
21.6k
  if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21492
757
      return (XML_SCHEMA_WHITESPACE_PRESERVE);
21493
20.8k
  else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21494
11.5k
      return (XML_SCHEMA_WHITESPACE_REPLACE);
21495
9.31k
  else
21496
9.31k
      return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21497
21.6k
    }
21498
0
    return (-1);
21499
113k
}
21500
21501
/************************************************************************
21502
 *                  *
21503
 *      Simple type validation        *
21504
 *                  *
21505
 ************************************************************************/
21506
21507
21508
/************************************************************************
21509
 *                  *
21510
 *      DOM Validation code       *
21511
 *                  *
21512
 ************************************************************************/
21513
21514
/**
21515
 * xmlSchemaAssembleByLocation:
21516
 * @pctxt:  a schema parser context
21517
 * @vctxt:  a schema validation context
21518
 * @schema: the existing schema
21519
 * @node: the node that fired the assembling
21520
 * @nsName: the namespace name of the new schema
21521
 * @location: the location of the schema
21522
 *
21523
 * Expands an existing schema by an additional schema.
21524
 *
21525
 * Returns 0 if the new schema is correct, a positive error code
21526
 * number otherwise and -1 in case of an internal or API error.
21527
 */
21528
static int
21529
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21530
          xmlSchemaPtr schema,
21531
          xmlNodePtr node,
21532
          const xmlChar *nsName,
21533
          const xmlChar *location)
21534
0
{
21535
0
    int ret = 0;
21536
0
    xmlSchemaParserCtxtPtr pctxt;
21537
0
    xmlSchemaBucketPtr bucket = NULL;
21538
21539
0
    if ((vctxt == NULL) || (schema == NULL))
21540
0
  return (-1);
21541
21542
0
    if (vctxt->pctxt == NULL) {
21543
0
  VERROR_INT("xmlSchemaAssembleByLocation",
21544
0
      "no parser context available");
21545
0
  return(-1);
21546
0
    }
21547
0
    pctxt = vctxt->pctxt;
21548
0
    if (pctxt->constructor == NULL) {
21549
0
  PERROR_INT("xmlSchemaAssembleByLocation",
21550
0
      "no constructor");
21551
0
  return(-1);
21552
0
    }
21553
    /*
21554
    * Acquire the schema document.
21555
    */
21556
0
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21557
0
  location, node);
21558
    /*
21559
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21560
    * the process will automatically change this to
21561
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21562
    */
21563
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21564
0
  location, NULL, NULL, 0, node, NULL, nsName,
21565
0
  &bucket);
21566
0
    if (ret != 0)
21567
0
  return(ret);
21568
0
    if (bucket == NULL) {
21569
  /*
21570
  * Generate a warning that the document could not be located.
21571
  */
21572
0
  xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21573
0
      node, NULL,
21574
0
      "The document at location '%s' could not be acquired",
21575
0
      location, NULL, NULL);
21576
0
  return(ret);
21577
0
    }
21578
    /*
21579
    * The first located schema will be handled as if all other
21580
    * schemas imported by XSI were imported by this first schema.
21581
    */
21582
0
    if ((bucket != NULL) &&
21583
0
  (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21584
0
  WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21585
    /*
21586
    * TODO: Is this handled like an import? I.e. is it not an error
21587
    * if the schema cannot be located?
21588
    */
21589
0
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21590
0
  return(0);
21591
    /*
21592
    * We will reuse the parser context for every schema imported
21593
    * directly via XSI. So reset the context.
21594
    */
21595
0
    pctxt->nberrors = 0;
21596
0
    pctxt->err = 0;
21597
0
    pctxt->doc = bucket->doc;
21598
21599
0
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21600
0
    if (ret == -1) {
21601
0
  pctxt->doc = NULL;
21602
0
  goto exit_failure;
21603
0
    }
21604
    /* Paranoid error channelling. */
21605
0
    if ((ret == 0) && (pctxt->nberrors != 0))
21606
0
  ret = pctxt->err;
21607
0
    if (pctxt->nberrors == 0) {
21608
  /*
21609
  * Only bother to fixup pending components, if there was
21610
  * no error yet.
21611
  * For every XSI acquired schema (and its sub-schemata) we will
21612
  * fixup the components.
21613
  */
21614
0
  xmlSchemaFixupComponents(pctxt, bucket);
21615
0
  ret = pctxt->err;
21616
  /*
21617
  * Not nice, but we need somehow to channel the schema parser
21618
  * error to the validation context.
21619
  */
21620
0
  if ((ret != 0) && (vctxt->err == 0))
21621
0
      vctxt->err = ret;
21622
0
  vctxt->nberrors += pctxt->nberrors;
21623
0
    } else {
21624
  /* Add to validation error sum. */
21625
0
  vctxt->nberrors += pctxt->nberrors;
21626
0
    }
21627
0
    pctxt->doc = NULL;
21628
0
    return(ret);
21629
0
exit_failure:
21630
0
    pctxt->doc = NULL;
21631
0
    return (-1);
21632
0
}
21633
21634
static xmlSchemaAttrInfoPtr
21635
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21636
       int metaType)
21637
0
{
21638
0
    if (vctxt->nbAttrInfos == 0)
21639
0
  return (NULL);
21640
0
    {
21641
0
  int i;
21642
0
  xmlSchemaAttrInfoPtr iattr;
21643
21644
0
  for (i = 0; i < vctxt->nbAttrInfos; i++) {
21645
0
      iattr = vctxt->attrInfos[i];
21646
0
      if (iattr->metaType == metaType)
21647
0
    return (iattr);
21648
0
  }
21649
21650
0
    }
21651
0
    return (NULL);
21652
0
}
21653
21654
/**
21655
 * xmlSchemaAssembleByXSI:
21656
 * @vctxt:  a schema validation context
21657
 *
21658
 * Expands an existing schema by an additional schema using
21659
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21660
 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21661
 * must be set to 1.
21662
 *
21663
 * Returns 0 if the new schema is correct, a positive error code
21664
 * number otherwise and -1 in case of an internal or API error.
21665
 */
21666
static int
21667
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21668
0
{
21669
0
    const xmlChar *cur, *end;
21670
0
    const xmlChar *nsname = NULL, *location;
21671
0
    int ret = 0;
21672
0
    xmlSchemaAttrInfoPtr iattr;
21673
21674
    /*
21675
    * Parse the value; we will assume an even number of values
21676
    * to be given (this is how Xerces and XSV work).
21677
    *
21678
    * URGENT TODO: !! This needs to work for both
21679
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
21680
    * element !!
21681
    */
21682
0
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21683
0
  XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21684
0
    if (iattr == NULL)
21685
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21686
0
  XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21687
0
    if (iattr == NULL)
21688
0
  return (0);
21689
0
    cur = iattr->value;
21690
0
    do {
21691
  /*
21692
  * TODO: Move the string parsing mechanism away from here.
21693
  */
21694
0
  if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21695
      /*
21696
      * Get the namespace name.
21697
      */
21698
0
      while (IS_BLANK_CH(*cur))
21699
0
    cur++;
21700
0
      end = cur;
21701
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21702
0
    end++;
21703
0
      if (end == cur)
21704
0
    break;
21705
      /* TODO: Don't use the schema's dict. */
21706
0
      nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21707
0
      cur = end;
21708
0
  }
21709
  /*
21710
  * Get the URI.
21711
  */
21712
0
  while (IS_BLANK_CH(*cur))
21713
0
      cur++;
21714
0
  end = cur;
21715
0
  while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21716
0
      end++;
21717
0
  if (end == cur) {
21718
0
      if (iattr->metaType ==
21719
0
    XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21720
0
      {
21721
    /*
21722
    * If using @schemaLocation then tuples are expected.
21723
    * I.e. the namespace name *and* the document's URI.
21724
    */
21725
0
    xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21726
0
        iattr->node, NULL,
21727
0
        "The value must consist of tuples: the target namespace "
21728
0
        "name and the document's URI", NULL, NULL, NULL);
21729
0
      }
21730
0
      break;
21731
0
  }
21732
  /* TODO: Don't use the schema's dict. */
21733
0
  location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21734
0
  cur = end;
21735
0
  ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21736
0
      iattr->node, nsname, location);
21737
0
  if (ret == -1) {
21738
0
      VERROR_INT("xmlSchemaAssembleByXSI",
21739
0
    "assembling schemata");
21740
0
      return (-1);
21741
0
  }
21742
0
    } while (*cur != 0);
21743
0
    return (ret);
21744
0
}
21745
21746
static const xmlChar *
21747
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21748
       const xmlChar *prefix)
21749
0
{
21750
0
    if (vctxt->sax != NULL) {
21751
0
  int i, j;
21752
0
  xmlSchemaNodeInfoPtr inode;
21753
21754
0
  for (i = vctxt->depth; i >= 0; i--) {
21755
0
      if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21756
0
    inode = vctxt->elemInfos[i];
21757
0
    for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21758
0
        if (((prefix == NULL) &&
21759
0
          (inode->nsBindings[j] == NULL)) ||
21760
0
      ((prefix != NULL) && xmlStrEqual(prefix,
21761
0
          inode->nsBindings[j]))) {
21762
21763
      /*
21764
      * Note that the namespace bindings are already
21765
      * in a string dict.
21766
      */
21767
0
      return (inode->nsBindings[j+1]);
21768
0
        }
21769
0
    }
21770
0
      }
21771
0
  }
21772
0
  return (NULL);
21773
0
#ifdef LIBXML_READER_ENABLED
21774
0
    } else if (vctxt->reader != NULL) {
21775
0
  xmlChar *nsName;
21776
21777
0
  nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21778
0
  if (nsName != NULL) {
21779
0
      const xmlChar *ret;
21780
21781
0
      ret = xmlDictLookup(vctxt->dict, nsName, -1);
21782
0
      xmlFree(nsName);
21783
0
      return (ret);
21784
0
  } else
21785
0
      return (NULL);
21786
0
#endif
21787
0
    } else {
21788
0
  xmlNsPtr ns;
21789
21790
0
  if ((vctxt->inode->node == NULL) ||
21791
0
      (vctxt->inode->node->doc == NULL)) {
21792
0
      VERROR_INT("xmlSchemaLookupNamespace",
21793
0
    "no node or node's doc available");
21794
0
      return (NULL);
21795
0
  }
21796
0
  ns = xmlSearchNs(vctxt->inode->node->doc,
21797
0
      vctxt->inode->node, prefix);
21798
0
  if (ns != NULL)
21799
0
      return (ns->href);
21800
0
  return (NULL);
21801
0
    }
21802
0
}
21803
21804
/*
21805
* This one works on the schema of the validation context.
21806
*/
21807
static int
21808
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21809
        xmlSchemaPtr schema,
21810
        xmlNodePtr node,
21811
        const xmlChar *value,
21812
        xmlSchemaValPtr *val,
21813
        int valNeeded)
21814
962
{
21815
962
    int ret;
21816
21817
962
    if (vctxt && (vctxt->schema == NULL)) {
21818
0
  VERROR_INT("xmlSchemaValidateNotation",
21819
0
      "a schema is needed on the validation context");
21820
0
  return (-1);
21821
0
    }
21822
962
    ret = xmlValidateQName(value, 1);
21823
962
    if (ret != 0)
21824
348
  return (ret);
21825
614
    {
21826
614
  xmlChar *localName = NULL;
21827
614
  xmlChar *prefix = NULL;
21828
21829
614
  localName = xmlSplitQName2(value, &prefix);
21830
614
  if (prefix != NULL) {
21831
597
      const xmlChar *nsName = NULL;
21832
21833
597
      if (vctxt != NULL)
21834
0
    nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21835
597
      else if (node != NULL) {
21836
597
    xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21837
597
    if (ns != NULL)
21838
0
        nsName = ns->href;
21839
597
      } else {
21840
0
    xmlFree(prefix);
21841
0
    xmlFree(localName);
21842
0
    return (1);
21843
0
      }
21844
597
      if (nsName == NULL) {
21845
597
    xmlFree(prefix);
21846
597
    xmlFree(localName);
21847
597
    return (1);
21848
597
      }
21849
0
      if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21850
0
    if ((valNeeded) && (val != NULL)) {
21851
0
        (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21852
0
                   xmlStrdup(nsName));
21853
0
        if (*val == NULL)
21854
0
      ret = -1;
21855
0
    }
21856
0
      } else
21857
0
    ret = 1;
21858
0
      xmlFree(prefix);
21859
0
      xmlFree(localName);
21860
17
  } else {
21861
17
      if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21862
0
    if (valNeeded && (val != NULL)) {
21863
0
        (*val) = xmlSchemaNewNOTATIONValue(
21864
0
      BAD_CAST xmlStrdup(value), NULL);
21865
0
        if (*val == NULL)
21866
0
      ret = -1;
21867
0
    }
21868
0
      } else
21869
17
    return (1);
21870
17
  }
21871
614
    }
21872
0
    return (ret);
21873
614
}
21874
21875
static int
21876
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21877
           const xmlChar* lname,
21878
           const xmlChar* nsname)
21879
0
{
21880
0
    int i;
21881
21882
0
    lname = xmlDictLookup(vctxt->dict, lname, -1);
21883
0
    if (lname == NULL)
21884
0
  return(-1);
21885
0
    if (nsname != NULL) {
21886
0
  nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21887
0
  if (nsname == NULL)
21888
0
      return(-1);
21889
0
    }
21890
0
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21891
0
  if ((vctxt->nodeQNames->items [i] == lname) &&
21892
0
      (vctxt->nodeQNames->items[i +1] == nsname))
21893
      /* Already there */
21894
0
      return(i);
21895
0
    }
21896
    /* Add new entry. */
21897
0
    i = vctxt->nodeQNames->nbItems;
21898
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21899
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21900
0
    return(i);
21901
0
}
21902
21903
/************************************************************************
21904
 *                  *
21905
 *  Validation of identity-constraints (IDC)                            *
21906
 *                  *
21907
 ************************************************************************/
21908
21909
/**
21910
 * xmlSchemaAugmentIDC:
21911
 * @idcDef: the IDC definition
21912
 *
21913
 * Creates an augmented IDC definition item.
21914
 *
21915
 * Returns the item, or NULL on internal errors.
21916
 */
21917
static void
21918
xmlSchemaAugmentIDC(void *payload, void *data,
21919
                    const xmlChar *name ATTRIBUTE_UNUSED)
21920
0
{
21921
0
    xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
21922
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21923
0
    xmlSchemaIDCAugPtr aidc;
21924
21925
0
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21926
0
    if (aidc == NULL) {
21927
0
  xmlSchemaVErrMemory(vctxt);
21928
0
  return;
21929
0
    }
21930
0
    aidc->keyrefDepth = -1;
21931
0
    aidc->def = idcDef;
21932
0
    aidc->next = NULL;
21933
0
    if (vctxt->aidcs == NULL)
21934
0
  vctxt->aidcs = aidc;
21935
0
    else {
21936
0
  aidc->next = vctxt->aidcs;
21937
0
  vctxt->aidcs = aidc;
21938
0
    }
21939
    /*
21940
    * Save if we have keyrefs at all.
21941
    */
21942
0
    if ((vctxt->hasKeyrefs == 0) &&
21943
0
  (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21944
0
  vctxt->hasKeyrefs = 1;
21945
0
}
21946
21947
/**
21948
 * xmlSchemaAugmentImportedIDC:
21949
 * @imported: the imported schema
21950
 *
21951
 * Creates an augmented IDC definition for the imported schema.
21952
 */
21953
static void
21954
xmlSchemaAugmentImportedIDC(void *payload, void *data,
21955
0
                            const xmlChar *name ATTRIBUTE_UNUSED) {
21956
0
    xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
21957
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21958
0
    if (imported->schema->idcDef != NULL) {
21959
0
      xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
21960
0
    }
21961
0
}
21962
21963
/**
21964
 * xmlSchemaIDCNewBinding:
21965
 * @idcDef: the IDC definition of this binding
21966
 *
21967
 * Creates a new IDC binding.
21968
 *
21969
 * Returns the new IDC binding, NULL on internal errors.
21970
 */
21971
static xmlSchemaPSVIIDCBindingPtr
21972
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
21973
0
{
21974
0
    xmlSchemaPSVIIDCBindingPtr ret;
21975
21976
0
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
21977
0
      sizeof(xmlSchemaPSVIIDCBinding));
21978
0
    if (ret == NULL) {
21979
0
  xmlSchemaVErrMemory(NULL);
21980
0
  return (NULL);
21981
0
    }
21982
0
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
21983
0
    ret->definition = idcDef;
21984
0
    return (ret);
21985
0
}
21986
21987
/**
21988
 * xmlSchemaIDCStoreNodeTableItem:
21989
 * @vctxt: the WXS validation context
21990
 * @item: the IDC node table item
21991
 *
21992
 * The validation context is used to store IDC node table items.
21993
 * They are stored to avoid copying them if IDC node-tables are merged
21994
 * with corresponding parent IDC node-tables (bubbling).
21995
 *
21996
 * Returns 0 if succeeded, -1 on internal errors.
21997
 */
21998
static int
21999
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22000
             xmlSchemaPSVIIDCNodePtr item)
22001
0
{
22002
    /*
22003
    * Add to global list.
22004
    */
22005
0
    if (vctxt->idcNodes == NULL) {
22006
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22007
0
      xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22008
0
  if (vctxt->idcNodes == NULL) {
22009
0
      xmlSchemaVErrMemory(vctxt);
22010
0
      return (-1);
22011
0
  }
22012
0
  vctxt->sizeIdcNodes = 20;
22013
0
    } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22014
0
  vctxt->sizeIdcNodes *= 2;
22015
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22016
0
      xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22017
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
22018
0
  if (vctxt->idcNodes == NULL) {
22019
0
      xmlSchemaVErrMemory(vctxt);
22020
0
      return (-1);
22021
0
  }
22022
0
    }
22023
0
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22024
22025
0
    return (0);
22026
0
}
22027
22028
/**
22029
 * xmlSchemaIDCStoreKey:
22030
 * @vctxt: the WXS validation context
22031
 * @item: the IDC key
22032
 *
22033
 * The validation context is used to store an IDC key.
22034
 *
22035
 * Returns 0 if succeeded, -1 on internal errors.
22036
 */
22037
static int
22038
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22039
         xmlSchemaPSVIIDCKeyPtr key)
22040
0
{
22041
    /*
22042
    * Add to global list.
22043
    */
22044
0
    if (vctxt->idcKeys == NULL) {
22045
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22046
0
      xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22047
0
  if (vctxt->idcKeys == NULL) {
22048
0
      xmlSchemaVErrMemory(vctxt);
22049
0
      return (-1);
22050
0
  }
22051
0
  vctxt->sizeIdcKeys = 40;
22052
0
    } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22053
0
  vctxt->sizeIdcKeys *= 2;
22054
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22055
0
      xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22056
0
      sizeof(xmlSchemaPSVIIDCKeyPtr));
22057
0
  if (vctxt->idcKeys == NULL) {
22058
0
      xmlSchemaVErrMemory(vctxt);
22059
0
      return (-1);
22060
0
  }
22061
0
    }
22062
0
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22063
22064
0
    return (0);
22065
0
}
22066
22067
/**
22068
 * xmlSchemaIDCAppendNodeTableItem:
22069
 * @bind: the IDC binding
22070
 * @ntItem: the node-table item
22071
 *
22072
 * Appends the IDC node-table item to the binding.
22073
 *
22074
 * Returns 0 on success and -1 on internal errors.
22075
 */
22076
static int
22077
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22078
        xmlSchemaPSVIIDCNodePtr ntItem)
22079
0
{
22080
0
    if (bind->nodeTable == NULL) {
22081
0
  bind->sizeNodes = 10;
22082
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22083
0
      xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22084
0
  if (bind->nodeTable == NULL) {
22085
0
      xmlSchemaVErrMemory(NULL);
22086
0
      return(-1);
22087
0
  }
22088
0
    } else if (bind->sizeNodes <= bind->nbNodes) {
22089
0
  bind->sizeNodes *= 2;
22090
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22091
0
      xmlRealloc(bind->nodeTable, bind->sizeNodes *
22092
0
    sizeof(xmlSchemaPSVIIDCNodePtr));
22093
0
  if (bind->nodeTable == NULL) {
22094
0
      xmlSchemaVErrMemory(NULL);
22095
0
      return(-1);
22096
0
  }
22097
0
    }
22098
0
    bind->nodeTable[bind->nbNodes++] = ntItem;
22099
0
    return(0);
22100
0
}
22101
22102
/**
22103
 * xmlSchemaIDCAcquireBinding:
22104
 * @vctxt: the WXS validation context
22105
 * @matcher: the IDC matcher
22106
 *
22107
 * Looks up an PSVI IDC binding, for the IDC definition and
22108
 * of the given matcher. If none found, a new one is created
22109
 * and added to the IDC table.
22110
 *
22111
 * Returns an IDC binding or NULL on internal errors.
22112
 */
22113
static xmlSchemaPSVIIDCBindingPtr
22114
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22115
        xmlSchemaIDCMatcherPtr matcher)
22116
0
{
22117
0
    xmlSchemaNodeInfoPtr ielem;
22118
22119
0
    ielem = vctxt->elemInfos[matcher->depth];
22120
22121
0
    if (ielem->idcTable == NULL) {
22122
0
  ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22123
0
  if (ielem->idcTable == NULL)
22124
0
      return (NULL);
22125
0
  return(ielem->idcTable);
22126
0
    } else {
22127
0
  xmlSchemaPSVIIDCBindingPtr bind = NULL;
22128
22129
0
  bind = ielem->idcTable;
22130
0
  do {
22131
0
      if (bind->definition == matcher->aidc->def)
22132
0
    return(bind);
22133
0
      if (bind->next == NULL) {
22134
0
    bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22135
0
    if (bind->next == NULL)
22136
0
        return (NULL);
22137
0
    return(bind->next);
22138
0
      }
22139
0
      bind = bind->next;
22140
0
  } while (bind != NULL);
22141
0
    }
22142
0
    return (NULL);
22143
0
}
22144
22145
static xmlSchemaItemListPtr
22146
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22147
           xmlSchemaIDCMatcherPtr matcher)
22148
0
{
22149
0
    if (matcher->targets == NULL)
22150
0
  matcher->targets = xmlSchemaItemListCreate();
22151
0
    return(matcher->targets);
22152
0
}
22153
22154
/**
22155
 * xmlSchemaIDCFreeKey:
22156
 * @key: the IDC key
22157
 *
22158
 * Frees an IDC key together with its compiled value.
22159
 */
22160
static void
22161
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22162
0
{
22163
0
    if (key->val != NULL)
22164
0
  xmlSchemaFreeValue(key->val);
22165
0
    xmlFree(key);
22166
0
}
22167
22168
/**
22169
 * xmlSchemaIDCFreeBinding:
22170
 *
22171
 * Frees an IDC binding. Note that the node table-items
22172
 * are not freed.
22173
 */
22174
static void
22175
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22176
0
{
22177
0
    if (bind->nodeTable != NULL)
22178
0
  xmlFree(bind->nodeTable);
22179
0
    if (bind->dupls != NULL)
22180
0
  xmlSchemaItemListFree(bind->dupls);
22181
0
    xmlFree(bind);
22182
0
}
22183
22184
/**
22185
 * xmlSchemaIDCFreeIDCTable:
22186
 * @bind: the first IDC binding in the list
22187
 *
22188
 * Frees an IDC table, i.e. all the IDC bindings in the list.
22189
 */
22190
static void
22191
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22192
0
{
22193
0
    xmlSchemaPSVIIDCBindingPtr prev;
22194
22195
0
    while (bind != NULL) {
22196
0
  prev = bind;
22197
0
  bind = bind->next;
22198
0
  xmlSchemaIDCFreeBinding(prev);
22199
0
    }
22200
0
}
22201
22202
static void
22203
xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
22204
0
{
22205
0
    xmlIDCHashEntryPtr e = payload, n;
22206
0
    while (e) {
22207
0
  n = e->next;
22208
0
  xmlFree(e);
22209
0
  e = n;
22210
0
    }
22211
0
}
22212
22213
/**
22214
 * xmlSchemaIDCFreeMatcherList:
22215
 * @matcher: the first IDC matcher in the list
22216
 *
22217
 * Frees a list of IDC matchers.
22218
 */
22219
static void
22220
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22221
0
{
22222
0
    xmlSchemaIDCMatcherPtr next;
22223
22224
0
    while (matcher != NULL) {
22225
0
  next = matcher->next;
22226
0
  if (matcher->keySeqs != NULL) {
22227
0
      int i;
22228
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22229
0
    if (matcher->keySeqs[i] != NULL)
22230
0
        xmlFree(matcher->keySeqs[i]);
22231
0
      xmlFree(matcher->keySeqs);
22232
0
  }
22233
0
  if (matcher->targets != NULL) {
22234
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22235
0
    int i;
22236
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22237
    /*
22238
    * Node-table items for keyrefs are not stored globally
22239
    * to the validation context, since they are not bubbled.
22240
    * We need to free them here.
22241
    */
22242
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22243
0
        idcNode =
22244
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22245
0
        xmlFree(idcNode->keys);
22246
0
        xmlFree(idcNode);
22247
0
    }
22248
0
      }
22249
0
      xmlSchemaItemListFree(matcher->targets);
22250
0
  }
22251
0
  if (matcher->htab != NULL)
22252
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22253
0
  xmlFree(matcher);
22254
0
  matcher = next;
22255
0
    }
22256
0
}
22257
22258
/**
22259
 * xmlSchemaIDCReleaseMatcherList:
22260
 * @vctxt: the WXS validation context
22261
 * @matcher: the first IDC matcher in the list
22262
 *
22263
 * Caches a list of IDC matchers for reuse.
22264
 */
22265
static void
22266
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22267
             xmlSchemaIDCMatcherPtr matcher)
22268
0
{
22269
0
    xmlSchemaIDCMatcherPtr next;
22270
22271
0
    while (matcher != NULL) {
22272
0
  next = matcher->next;
22273
0
  if (matcher->keySeqs != NULL) {
22274
0
      int i;
22275
      /*
22276
      * Don't free the array, but only the content.
22277
      */
22278
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22279
0
    if (matcher->keySeqs[i] != NULL) {
22280
0
        xmlFree(matcher->keySeqs[i]);
22281
0
        matcher->keySeqs[i] = NULL;
22282
0
    }
22283
0
  }
22284
0
  if (matcher->targets) {
22285
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22286
0
    int i;
22287
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22288
    /*
22289
    * Node-table items for keyrefs are not stored globally
22290
    * to the validation context, since they are not bubbled.
22291
    * We need to free them here.
22292
    */
22293
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22294
0
        idcNode =
22295
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22296
0
        xmlFree(idcNode->keys);
22297
0
        xmlFree(idcNode);
22298
0
    }
22299
0
      }
22300
0
      xmlSchemaItemListFree(matcher->targets);
22301
0
      matcher->targets = NULL;
22302
0
  }
22303
0
  if (matcher->htab != NULL) {
22304
0
      xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22305
0
      matcher->htab = NULL;
22306
0
  }
22307
0
  matcher->next = NULL;
22308
  /*
22309
  * Cache the matcher.
22310
  */
22311
0
  if (vctxt->idcMatcherCache != NULL)
22312
0
      matcher->nextCached = vctxt->idcMatcherCache;
22313
0
  vctxt->idcMatcherCache = matcher;
22314
22315
0
  matcher = next;
22316
0
    }
22317
0
}
22318
22319
/**
22320
 * xmlSchemaIDCAddStateObject:
22321
 * @vctxt: the WXS validation context
22322
 * @matcher: the IDC matcher
22323
 * @sel: the XPath information
22324
 * @parent: the parent "selector" state object if any
22325
 * @type: "selector" or "field"
22326
 *
22327
 * Creates/reuses and activates state objects for the given
22328
 * XPath information; if the XPath expression consists of unions,
22329
 * multiple state objects are created for every unioned expression.
22330
 *
22331
 * Returns 0 on success and -1 on internal errors.
22332
 */
22333
static int
22334
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22335
      xmlSchemaIDCMatcherPtr matcher,
22336
      xmlSchemaIDCSelectPtr sel,
22337
      int type)
22338
0
{
22339
0
    xmlSchemaIDCStateObjPtr sto;
22340
22341
    /*
22342
    * Reuse the state objects from the pool.
22343
    */
22344
0
    if (vctxt->xpathStatePool != NULL) {
22345
0
  sto = vctxt->xpathStatePool;
22346
0
  vctxt->xpathStatePool = sto->next;
22347
0
  sto->next = NULL;
22348
0
    } else {
22349
  /*
22350
  * Create a new state object.
22351
  */
22352
0
  sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22353
0
  if (sto == NULL) {
22354
0
      xmlSchemaVErrMemory(NULL);
22355
0
      return (-1);
22356
0
  }
22357
0
  memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22358
0
    }
22359
    /*
22360
    * Add to global list.
22361
    */
22362
0
    if (vctxt->xpathStates != NULL)
22363
0
  sto->next = vctxt->xpathStates;
22364
0
    vctxt->xpathStates = sto;
22365
22366
    /*
22367
    * Free the old xpath validation context.
22368
    */
22369
0
    if (sto->xpathCtxt != NULL)
22370
0
  xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22371
22372
    /*
22373
    * Create a new XPath (pattern) validation context.
22374
    */
22375
0
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22376
0
  (xmlPatternPtr) sel->xpathComp);
22377
0
    if (sto->xpathCtxt == NULL) {
22378
0
  VERROR_INT("xmlSchemaIDCAddStateObject",
22379
0
      "failed to create an XPath validation context");
22380
0
  return (-1);
22381
0
    }
22382
0
    sto->type = type;
22383
0
    sto->depth = vctxt->depth;
22384
0
    sto->matcher = matcher;
22385
0
    sto->sel = sel;
22386
0
    sto->nbHistory = 0;
22387
22388
0
    return (0);
22389
0
}
22390
22391
/**
22392
 * xmlSchemaXPathEvaluate:
22393
 * @vctxt: the WXS validation context
22394
 * @nodeType: the nodeType of the current node
22395
 *
22396
 * Evaluates all active XPath state objects.
22397
 *
22398
 * Returns the number of IC "field" state objects which resolved to
22399
 * this node, 0 if none resolved and -1 on internal errors.
22400
 */
22401
static int
22402
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22403
           xmlElementType nodeType)
22404
0
{
22405
0
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22406
0
    int res, resolved = 0, depth = vctxt->depth;
22407
22408
0
    if (vctxt->xpathStates == NULL)
22409
0
  return (0);
22410
22411
0
    if (nodeType == XML_ATTRIBUTE_NODE)
22412
0
  depth++;
22413
    /*
22414
    * Process all active XPath state objects.
22415
    */
22416
0
    first = vctxt->xpathStates;
22417
0
    sto = first;
22418
0
    while (sto != head) {
22419
0
  if (nodeType == XML_ELEMENT_NODE)
22420
0
      res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22421
0
    vctxt->inode->localName, vctxt->inode->nsName);
22422
0
  else
22423
0
      res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22424
0
    vctxt->inode->localName, vctxt->inode->nsName);
22425
22426
0
  if (res == -1) {
22427
0
      VERROR_INT("xmlSchemaXPathEvaluate",
22428
0
    "calling xmlStreamPush()");
22429
0
      return (-1);
22430
0
  }
22431
0
  if (res == 0)
22432
0
      goto next_sto;
22433
  /*
22434
  * Full match.
22435
  */
22436
  /*
22437
  * Register a match in the state object history.
22438
  */
22439
0
  if (sto->history == NULL) {
22440
0
      sto->history = (int *) xmlMalloc(5 * sizeof(int));
22441
0
      if (sto->history == NULL) {
22442
0
    xmlSchemaVErrMemory(NULL);
22443
0
    return(-1);
22444
0
      }
22445
0
      sto->sizeHistory = 5;
22446
0
  } else if (sto->sizeHistory <= sto->nbHistory) {
22447
0
      sto->sizeHistory *= 2;
22448
0
      sto->history = (int *) xmlRealloc(sto->history,
22449
0
    sto->sizeHistory * sizeof(int));
22450
0
      if (sto->history == NULL) {
22451
0
    xmlSchemaVErrMemory(NULL);
22452
0
    return(-1);
22453
0
      }
22454
0
  }
22455
0
  sto->history[sto->nbHistory++] = depth;
22456
22457
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22458
0
      xmlSchemaIDCSelectPtr sel;
22459
      /*
22460
      * Activate state objects for the IDC fields of
22461
      * the IDC selector.
22462
      */
22463
0
      sel = sto->matcher->aidc->def->fields;
22464
0
      while (sel != NULL) {
22465
0
    if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22466
0
        sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22467
0
        return (-1);
22468
0
    sel = sel->next;
22469
0
      }
22470
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22471
      /*
22472
      * An IDC key node was found by the IDC field.
22473
      */
22474
      /*
22475
      * Notify that the character value of this node is
22476
      * needed.
22477
      */
22478
0
      if (resolved == 0) {
22479
0
    if ((vctxt->inode->flags &
22480
0
        XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22481
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22482
0
      }
22483
0
      resolved++;
22484
0
  }
22485
0
next_sto:
22486
0
  if (sto->next == NULL) {
22487
      /*
22488
      * Evaluate field state objects created on this node as well.
22489
      */
22490
0
      head = first;
22491
0
      sto = vctxt->xpathStates;
22492
0
  } else
22493
0
      sto = sto->next;
22494
0
    }
22495
0
    return (resolved);
22496
0
}
22497
22498
static const xmlChar *
22499
xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22500
        xmlChar **buf,
22501
        xmlSchemaPSVIIDCKeyPtr *seq,
22502
        int count, int for_hash)
22503
0
{
22504
0
    int i, res;
22505
0
    xmlChar *value = NULL;
22506
22507
0
    *buf = xmlStrdup(BAD_CAST "[");
22508
0
    for (i = 0; i < count; i++) {
22509
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
22510
0
  if (!for_hash)
22511
0
      res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22512
0
        xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22513
0
        &value);
22514
0
  else {
22515
0
      res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22516
0
  }
22517
0
  if (res == 0)
22518
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
22519
0
  else {
22520
0
      VERROR_INT("xmlSchemaFormatIDCKeySequence",
22521
0
    "failed to compute a canonical value");
22522
0
      *buf = xmlStrcat(*buf, BAD_CAST "???");
22523
0
  }
22524
0
  if (i < count -1)
22525
0
      *buf = xmlStrcat(*buf, BAD_CAST "', ");
22526
0
  else
22527
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
22528
0
  if (value != NULL) {
22529
0
      xmlFree(value);
22530
0
      value = NULL;
22531
0
  }
22532
0
    }
22533
0
    *buf = xmlStrcat(*buf, BAD_CAST "]");
22534
22535
0
    return (BAD_CAST *buf);
22536
0
}
22537
22538
static const xmlChar *
22539
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22540
            xmlChar **buf,
22541
            xmlSchemaPSVIIDCKeyPtr *seq,
22542
            int count)
22543
0
{
22544
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22545
0
}
22546
22547
static const xmlChar *
22548
xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22549
       xmlChar **buf,
22550
       xmlSchemaPSVIIDCKeyPtr *seq,
22551
       int count)
22552
0
{
22553
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22554
0
}
22555
22556
/**
22557
 * xmlSchemaXPathPop:
22558
 * @vctxt: the WXS validation context
22559
 *
22560
 * Pops all XPath states.
22561
 *
22562
 * Returns 0 on success and -1 on internal errors.
22563
 */
22564
static int
22565
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22566
0
{
22567
0
    xmlSchemaIDCStateObjPtr sto;
22568
0
    int res;
22569
22570
0
    if (vctxt->xpathStates == NULL)
22571
0
  return(0);
22572
0
    sto = vctxt->xpathStates;
22573
0
    do {
22574
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22575
0
  if (res == -1)
22576
0
      return (-1);
22577
0
  sto = sto->next;
22578
0
    } while (sto != NULL);
22579
0
    return(0);
22580
0
}
22581
22582
/**
22583
 * xmlSchemaXPathProcessHistory:
22584
 * @vctxt: the WXS validation context
22585
 * @type: the simple/complex type of the current node if any at all
22586
 * @val: the precompiled value
22587
 *
22588
 * Processes and pops the history items of the IDC state objects.
22589
 * IDC key-sequences are validated/created on IDC bindings.
22590
 *
22591
 * Returns 0 on success and -1 on internal errors.
22592
 */
22593
static int
22594
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22595
           int depth)
22596
0
{
22597
0
    xmlSchemaIDCStateObjPtr sto, nextsto;
22598
0
    int res, matchDepth;
22599
0
    xmlSchemaPSVIIDCKeyPtr key = NULL;
22600
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22601
22602
0
    if (vctxt->xpathStates == NULL)
22603
0
  return (0);
22604
0
    sto = vctxt->xpathStates;
22605
22606
    /*
22607
    * Evaluate the state objects.
22608
    */
22609
0
    while (sto != NULL) {
22610
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22611
0
  if (res == -1) {
22612
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22613
0
    "calling xmlStreamPop()");
22614
0
      return (-1);
22615
0
  }
22616
0
  if (sto->nbHistory == 0)
22617
0
      goto deregister_check;
22618
22619
0
  matchDepth = sto->history[sto->nbHistory -1];
22620
22621
  /*
22622
  * Only matches at the current depth are of interest.
22623
  */
22624
0
  if (matchDepth != depth) {
22625
0
      sto = sto->next;
22626
0
      continue;
22627
0
  }
22628
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22629
      /*
22630
      * NOTE: According to
22631
      *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22632
      *   ... the simple-content of complex types is also allowed.
22633
      */
22634
22635
0
      if (WXS_IS_COMPLEX(type)) {
22636
0
    if (WXS_HAS_SIMPLE_CONTENT(type)) {
22637
        /*
22638
        * Sanity check for complex types with simple content.
22639
        */
22640
0
        simpleType = type->contentTypeDef;
22641
0
        if (simpleType == NULL) {
22642
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22643
0
          "field resolves to a CT with simple content "
22644
0
          "but the CT is missing the ST definition");
22645
0
      return (-1);
22646
0
        }
22647
0
    } else
22648
0
        simpleType = NULL;
22649
0
      } else
22650
0
    simpleType = type;
22651
0
      if (simpleType == NULL) {
22652
0
    xmlChar *str = NULL;
22653
22654
    /*
22655
    * Not qualified if the field resolves to a node of non
22656
    * simple type.
22657
    */
22658
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22659
0
        XML_SCHEMAV_CVC_IDC, NULL,
22660
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22661
0
        "The XPath '%s' of a field of %s does evaluate to a node of "
22662
0
        "non-simple type",
22663
0
        sto->sel->xpath,
22664
0
        xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22665
0
    FREE_AND_NULL(str);
22666
0
    sto->nbHistory--;
22667
0
    goto deregister_check;
22668
0
      }
22669
22670
0
      if ((key == NULL) && (vctxt->inode->val == NULL)) {
22671
    /*
22672
    * Failed to provide the normalized value; maybe
22673
    * the value was invalid.
22674
    */
22675
0
    VERROR(XML_SCHEMAV_CVC_IDC,
22676
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22677
0
        "Warning: No precomputed value available, the value "
22678
0
        "was either invalid or something strange happened");
22679
0
    sto->nbHistory--;
22680
0
    goto deregister_check;
22681
0
      } else {
22682
0
    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22683
0
    xmlSchemaPSVIIDCKeyPtr *keySeq;
22684
0
    int pos, idx;
22685
22686
    /*
22687
    * The key will be anchored on the matcher's list of
22688
    * key-sequences. The position in this list is determined
22689
    * by the target node's depth relative to the matcher's
22690
    * depth of creation (i.e. the depth of the scope element).
22691
    *
22692
    * Element        Depth    Pos   List-entries
22693
    * <scope>          0              NULL
22694
    *   <bar>          1              NULL
22695
    *     <target/>    2       2      target
22696
    *   <bar>
22697
                * </scope>
22698
    *
22699
    * The size of the list is only dependent on the depth of
22700
    * the tree.
22701
    * An entry will be NULLed in selector_leave, i.e. when
22702
    * we hit the target's
22703
    */
22704
0
    pos = sto->depth - matcher->depth;
22705
0
    idx = sto->sel->index;
22706
22707
    /*
22708
    * Create/grow the array of key-sequences.
22709
    */
22710
0
    if (matcher->keySeqs == NULL) {
22711
0
        if (pos > 9)
22712
0
      matcher->sizeKeySeqs = pos * 2;
22713
0
        else
22714
0
      matcher->sizeKeySeqs = 10;
22715
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22716
0
      xmlMalloc(matcher->sizeKeySeqs *
22717
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22718
0
        if (matcher->keySeqs == NULL) {
22719
0
      xmlSchemaVErrMemory(NULL);
22720
0
      return(-1);
22721
0
        }
22722
0
        memset(matcher->keySeqs, 0,
22723
0
      matcher->sizeKeySeqs *
22724
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22725
0
    } else if (pos >= matcher->sizeKeySeqs) {
22726
0
        int i = matcher->sizeKeySeqs;
22727
22728
0
        matcher->sizeKeySeqs = pos * 2;
22729
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22730
0
      xmlRealloc(matcher->keySeqs,
22731
0
      matcher->sizeKeySeqs *
22732
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22733
0
        if (matcher->keySeqs == NULL) {
22734
0
      xmlSchemaVErrMemory(NULL);
22735
0
      return (-1);
22736
0
        }
22737
        /*
22738
        * The array needs to be NULLed.
22739
        * TODO: Use memset?
22740
        */
22741
0
        for (; i < matcher->sizeKeySeqs; i++)
22742
0
      matcher->keySeqs[i] = NULL;
22743
0
    }
22744
22745
    /*
22746
    * Get/create the key-sequence.
22747
    */
22748
0
    keySeq = matcher->keySeqs[pos];
22749
0
    if (keySeq == NULL) {
22750
0
        goto create_sequence;
22751
0
    } else if (keySeq[idx] != NULL) {
22752
0
        xmlChar *str = NULL;
22753
        /*
22754
        * cvc-identity-constraint:
22755
        * 3 For each node in the `target node set` all
22756
        * of the {fields}, with that node as the context
22757
        * node, evaluate to either an empty node-set or
22758
        * a node-set with exactly one member, which must
22759
        * have a simple type.
22760
        *
22761
        * The key was already set; report an error.
22762
        */
22763
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22764
0
      XML_SCHEMAV_CVC_IDC, NULL,
22765
0
      WXS_BASIC_CAST matcher->aidc->def,
22766
0
      "The XPath '%s' of a field of %s evaluates to a "
22767
0
      "node-set with more than one member",
22768
0
      sto->sel->xpath,
22769
0
      xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22770
0
        FREE_AND_NULL(str);
22771
0
        sto->nbHistory--;
22772
0
        goto deregister_check;
22773
0
    } else
22774
0
        goto create_key;
22775
22776
0
create_sequence:
22777
    /*
22778
    * Create a key-sequence.
22779
    */
22780
0
    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22781
0
        matcher->aidc->def->nbFields *
22782
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22783
0
    if (keySeq == NULL) {
22784
0
        xmlSchemaVErrMemory(NULL);
22785
0
        return(-1);
22786
0
    }
22787
0
    memset(keySeq, 0, matcher->aidc->def->nbFields *
22788
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22789
0
    matcher->keySeqs[pos] = keySeq;
22790
0
create_key:
22791
    /*
22792
    * Create a key once per node only.
22793
    */
22794
0
    if (key == NULL) {
22795
0
        key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22796
0
      sizeof(xmlSchemaPSVIIDCKey));
22797
0
        if (key == NULL) {
22798
0
      xmlSchemaVErrMemory(NULL);
22799
0
      xmlFree(keySeq);
22800
0
      matcher->keySeqs[pos] = NULL;
22801
0
      return(-1);
22802
0
        }
22803
        /*
22804
        * Consume the compiled value.
22805
        */
22806
0
        key->type = simpleType;
22807
0
        key->val = vctxt->inode->val;
22808
0
        vctxt->inode->val = NULL;
22809
        /*
22810
        * Store the key in a global list.
22811
        */
22812
0
        if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22813
0
      xmlSchemaIDCFreeKey(key);
22814
0
      return (-1);
22815
0
        }
22816
0
    }
22817
0
    keySeq[idx] = key;
22818
0
      }
22819
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22820
22821
0
      xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22822
      /* xmlSchemaPSVIIDCBindingPtr bind; */
22823
0
      xmlSchemaPSVIIDCNodePtr ntItem;
22824
0
      xmlSchemaIDCMatcherPtr matcher;
22825
0
      xmlSchemaIDCPtr idc;
22826
0
      xmlSchemaItemListPtr targets;
22827
0
      int pos, i, j, nbKeys;
22828
      /*
22829
      * Here we have the following scenario:
22830
      * An IDC 'selector' state object resolved to a target node,
22831
      * during the time this target node was in the
22832
      * ancestor-or-self axis, the 'field' state object(s) looked
22833
      * out for matching nodes to create a key-sequence for this
22834
      * target node. Now we are back to this target node and need
22835
      * to put the key-sequence, together with the target node
22836
      * itself, into the node-table of the corresponding IDC
22837
      * binding.
22838
      */
22839
0
      matcher = sto->matcher;
22840
0
      idc = matcher->aidc->def;
22841
0
      nbKeys = idc->nbFields;
22842
0
      pos = depth - matcher->depth;
22843
      /*
22844
      * Check if the matcher has any key-sequences at all, plus
22845
      * if it has a key-sequence for the current target node.
22846
      */
22847
0
      if ((matcher->keySeqs == NULL) ||
22848
0
    (matcher->sizeKeySeqs <= pos)) {
22849
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22850
0
        goto selector_key_error;
22851
0
    else
22852
0
        goto selector_leave;
22853
0
      }
22854
22855
0
      keySeq = &(matcher->keySeqs[pos]);
22856
0
      if (*keySeq == NULL) {
22857
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22858
0
        goto selector_key_error;
22859
0
    else
22860
0
        goto selector_leave;
22861
0
      }
22862
22863
0
      for (i = 0; i < nbKeys; i++) {
22864
0
    if ((*keySeq)[i] == NULL) {
22865
        /*
22866
        * Not qualified, if not all fields did resolve.
22867
        */
22868
0
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22869
      /*
22870
      * All fields of a "key" IDC must resolve.
22871
      */
22872
0
      goto selector_key_error;
22873
0
        }
22874
0
        goto selector_leave;
22875
0
    }
22876
0
      }
22877
      /*
22878
      * All fields did resolve.
22879
      */
22880
22881
      /*
22882
      * 4.1 If the {identity-constraint category} is unique(/key),
22883
      * then no two members of the `qualified node set` have
22884
      * `key-sequences` whose members are pairwise equal, as
22885
      * defined by Equal in [XML Schemas: Datatypes].
22886
      *
22887
      * Get the IDC binding from the matcher and check for
22888
      * duplicate key-sequences.
22889
      */
22890
#if 0
22891
      bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22892
#endif
22893
0
      targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22894
0
      if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22895
0
    (targets->nbItems != 0)) {
22896
0
    xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22897
0
    xmlIDCHashEntryPtr e;
22898
22899
0
    res = 0;
22900
22901
0
    if (!matcher->htab)
22902
0
        e = NULL;
22903
0
    else {
22904
0
        xmlChar *value = NULL;
22905
0
        xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
22906
0
        e = xmlHashLookup(matcher->htab, value);
22907
0
        FREE_AND_NULL(value);
22908
0
    }
22909
22910
    /*
22911
    * Compare the key-sequences, key by key.
22912
    */
22913
0
    for (;e; e = e->next) {
22914
0
        bkeySeq =
22915
0
      ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
22916
0
        for (j = 0; j < nbKeys; j++) {
22917
0
      ckey = (*keySeq)[j];
22918
0
      bkey = bkeySeq[j];
22919
0
      res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22920
0
      if (res == -1) {
22921
0
          return (-1);
22922
0
      } else if (res == 0) {
22923
          /*
22924
          * One of the keys differs, so the key-sequence
22925
          * won't be equal; get out.
22926
          */
22927
0
          break;
22928
0
      }
22929
0
        }
22930
0
        if (res == 1) {
22931
      /*
22932
      * Duplicate key-sequence found.
22933
      */
22934
0
      break;
22935
0
        }
22936
0
    }
22937
0
    if (e) {
22938
0
        xmlChar *str = NULL, *strB = NULL;
22939
        /*
22940
        * TODO: Try to report the key-sequence.
22941
        */
22942
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22943
0
      XML_SCHEMAV_CVC_IDC, NULL,
22944
0
      WXS_BASIC_CAST idc,
22945
0
      "Duplicate key-sequence %s in %s",
22946
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
22947
0
          (*keySeq), nbKeys),
22948
0
      xmlSchemaGetIDCDesignation(&strB, idc));
22949
0
        FREE_AND_NULL(str);
22950
0
        FREE_AND_NULL(strB);
22951
0
        goto selector_leave;
22952
0
    }
22953
0
      }
22954
      /*
22955
      * Add a node-table item to the IDC binding.
22956
      */
22957
0
      ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
22958
0
    sizeof(xmlSchemaPSVIIDCNode));
22959
0
      if (ntItem == NULL) {
22960
0
    xmlSchemaVErrMemory(NULL);
22961
0
    xmlFree(*keySeq);
22962
0
    *keySeq = NULL;
22963
0
    return(-1);
22964
0
      }
22965
0
      memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
22966
22967
      /*
22968
      * Store the node-table item in a global list.
22969
      */
22970
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22971
0
    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
22972
0
        xmlFree(ntItem);
22973
0
        xmlFree(*keySeq);
22974
0
        *keySeq = NULL;
22975
0
        return (-1);
22976
0
    }
22977
0
    ntItem->nodeQNameID = -1;
22978
0
      } else {
22979
    /*
22980
    * Save a cached QName for this node on the IDC node, to be
22981
    * able to report it, even if the node is not saved.
22982
    */
22983
0
    ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
22984
0
        vctxt->inode->localName, vctxt->inode->nsName);
22985
0
    if (ntItem->nodeQNameID == -1) {
22986
0
        xmlFree(ntItem);
22987
0
        xmlFree(*keySeq);
22988
0
        *keySeq = NULL;
22989
0
        return (-1);
22990
0
    }
22991
0
      }
22992
      /*
22993
      * Init the node-table item: Save the node, position and
22994
      * consume the key-sequence.
22995
      */
22996
0
      ntItem->node = vctxt->node;
22997
0
      ntItem->nodeLine = vctxt->inode->nodeLine;
22998
0
      ntItem->keys = *keySeq;
22999
0
      *keySeq = NULL;
23000
#if 0
23001
      if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23002
#endif
23003
0
      if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23004
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23005
        /*
23006
        * Free the item, since keyref items won't be
23007
        * put on a global list.
23008
        */
23009
0
        xmlFree(ntItem->keys);
23010
0
        xmlFree(ntItem);
23011
0
    }
23012
0
    return (-1);
23013
0
      }
23014
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23015
0
    xmlChar *value = NULL;
23016
0
    xmlIDCHashEntryPtr r, e;
23017
0
    if (!matcher->htab)
23018
0
      matcher->htab = xmlHashCreate(4);
23019
0
    xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23020
0
    e = xmlMalloc(sizeof *e);
23021
0
    e->index = targets->nbItems - 1;
23022
0
    r = xmlHashLookup(matcher->htab, value);
23023
0
    if (r) {
23024
0
        e->next = r->next;
23025
0
        r->next = e;
23026
0
    } else {
23027
0
        e->next = NULL;
23028
0
        xmlHashAddEntry(matcher->htab, value, e);
23029
0
    }
23030
0
    FREE_AND_NULL(value);
23031
0
      }
23032
23033
0
      goto selector_leave;
23034
0
selector_key_error:
23035
0
      {
23036
0
    xmlChar *str = NULL;
23037
    /*
23038
    * 4.2.1 (KEY) The `target node set` and the
23039
    * `qualified node set` are equal, that is, every
23040
    * member of the `target node set` is also a member
23041
    * of the `qualified node set` and vice versa.
23042
    */
23043
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
23044
0
        XML_SCHEMAV_CVC_IDC, NULL,
23045
0
        WXS_BASIC_CAST idc,
23046
0
        "Not all fields of %s evaluate to a node",
23047
0
        xmlSchemaGetIDCDesignation(&str, idc), NULL);
23048
0
    FREE_AND_NULL(str);
23049
0
      }
23050
0
selector_leave:
23051
      /*
23052
      * Free the key-sequence if not added to the IDC table.
23053
      */
23054
0
      if ((keySeq != NULL) && (*keySeq != NULL)) {
23055
0
    xmlFree(*keySeq);
23056
0
    *keySeq = NULL;
23057
0
      }
23058
0
  } /* if selector */
23059
23060
0
  sto->nbHistory--;
23061
23062
0
deregister_check:
23063
  /*
23064
  * Deregister state objects if they reach the depth of creation.
23065
  */
23066
0
  if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23067
0
      if (vctxt->xpathStates != sto) {
23068
0
    VERROR_INT("xmlSchemaXPathProcessHistory",
23069
0
        "The state object to be removed is not the first "
23070
0
        "in the list");
23071
0
      }
23072
0
      nextsto = sto->next;
23073
      /*
23074
      * Unlink from the list of active XPath state objects.
23075
      */
23076
0
      vctxt->xpathStates = sto->next;
23077
0
      sto->next = vctxt->xpathStatePool;
23078
      /*
23079
      * Link it to the pool of reusable state objects.
23080
      */
23081
0
      vctxt->xpathStatePool = sto;
23082
0
      sto = nextsto;
23083
0
  } else
23084
0
      sto = sto->next;
23085
0
    } /* while (sto != NULL) */
23086
0
    return (0);
23087
0
}
23088
23089
/**
23090
 * xmlSchemaIDCRegisterMatchers:
23091
 * @vctxt: the WXS validation context
23092
 * @elemDecl: the element declaration
23093
 *
23094
 * Creates helper objects to evaluate IDC selectors/fields
23095
 * successively.
23096
 *
23097
 * Returns 0 if OK and -1 on internal errors.
23098
 */
23099
static int
23100
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23101
           xmlSchemaElementPtr elemDecl)
23102
0
{
23103
0
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
23104
0
    xmlSchemaIDCPtr idc, refIdc;
23105
0
    xmlSchemaIDCAugPtr aidc;
23106
23107
0
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23108
0
    if (idc == NULL)
23109
0
  return (0);
23110
23111
0
    if (vctxt->inode->idcMatchers != NULL) {
23112
0
  VERROR_INT("xmlSchemaIDCRegisterMatchers",
23113
0
      "The chain of IDC matchers is expected to be empty");
23114
0
  return (-1);
23115
0
    }
23116
0
    do {
23117
0
  if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23118
      /*
23119
      * Since IDCs bubbles are expensive we need to know the
23120
      * depth at which the bubbles should stop; this will be
23121
      * the depth of the top-most keyref IDC. If no keyref
23122
      * references a key/unique IDC, the keyrefDepth will
23123
      * be -1, indicating that no bubbles are needed.
23124
      */
23125
0
      refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23126
0
      if (refIdc != NULL) {
23127
    /*
23128
    * Remember that we have keyrefs on this node.
23129
    */
23130
0
    vctxt->inode->hasKeyrefs = 1;
23131
    /*
23132
    * Lookup the referenced augmented IDC info.
23133
    */
23134
0
    aidc = vctxt->aidcs;
23135
0
    while (aidc != NULL) {
23136
0
        if (aidc->def == refIdc)
23137
0
      break;
23138
0
        aidc = aidc->next;
23139
0
    }
23140
0
    if (aidc == NULL) {
23141
0
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
23142
0
      "Could not find an augmented IDC item for an IDC "
23143
0
      "definition");
23144
0
        return (-1);
23145
0
    }
23146
0
    if ((aidc->keyrefDepth == -1) ||
23147
0
        (vctxt->depth < aidc->keyrefDepth))
23148
0
        aidc->keyrefDepth = vctxt->depth;
23149
0
      }
23150
0
  }
23151
  /*
23152
  * Lookup the augmented IDC item for the IDC definition.
23153
  */
23154
0
  aidc = vctxt->aidcs;
23155
0
  while (aidc != NULL) {
23156
0
      if (aidc->def == idc)
23157
0
    break;
23158
0
      aidc = aidc->next;
23159
0
  }
23160
0
  if (aidc == NULL) {
23161
0
      VERROR_INT("xmlSchemaIDCRegisterMatchers",
23162
0
    "Could not find an augmented IDC item for an IDC definition");
23163
0
      return (-1);
23164
0
  }
23165
  /*
23166
  * Create an IDC matcher for every IDC definition.
23167
  */
23168
0
  if (vctxt->idcMatcherCache != NULL) {
23169
      /*
23170
      * Reuse a cached matcher.
23171
      */
23172
0
      matcher = vctxt->idcMatcherCache;
23173
0
      vctxt->idcMatcherCache = matcher->nextCached;
23174
0
      matcher->nextCached = NULL;
23175
0
  } else {
23176
0
      matcher = (xmlSchemaIDCMatcherPtr)
23177
0
    xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23178
0
      if (matcher == NULL) {
23179
0
    xmlSchemaVErrMemory(vctxt);
23180
0
    return (-1);
23181
0
      }
23182
0
      memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23183
0
  }
23184
0
  if (last == NULL)
23185
0
      vctxt->inode->idcMatchers = matcher;
23186
0
  else
23187
0
      last->next = matcher;
23188
0
  last = matcher;
23189
23190
0
  matcher->type = IDC_MATCHER;
23191
0
  matcher->depth = vctxt->depth;
23192
0
  matcher->aidc = aidc;
23193
0
  matcher->idcType = aidc->def->type;
23194
  /*
23195
  * Init the automaton state object.
23196
  */
23197
0
  if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23198
0
      idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23199
0
      return (-1);
23200
23201
0
  idc = idc->next;
23202
0
    } while (idc != NULL);
23203
0
    return (0);
23204
0
}
23205
23206
static int
23207
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23208
         xmlSchemaNodeInfoPtr ielem)
23209
0
{
23210
0
    xmlSchemaPSVIIDCBindingPtr bind;
23211
0
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23212
0
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23213
0
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23214
23215
0
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23216
    /* vctxt->createIDCNodeTables */
23217
0
    while (matcher != NULL) {
23218
  /*
23219
  * Skip keyref IDCs and empty IDC target-lists.
23220
  */
23221
0
  if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23222
0
      WXS_ILIST_IS_EMPTY(matcher->targets))
23223
0
  {
23224
0
      matcher = matcher->next;
23225
0
      continue;
23226
0
  }
23227
  /*
23228
  * If we _want_ the IDC node-table to be created in any case
23229
  * then do so. Otherwise create them only if keyrefs need them.
23230
  */
23231
0
  if ((! vctxt->createIDCNodeTables) &&
23232
0
      ((matcher->aidc->keyrefDepth == -1) ||
23233
0
       (matcher->aidc->keyrefDepth > vctxt->depth)))
23234
0
  {
23235
0
      matcher = matcher->next;
23236
0
      continue;
23237
0
  }
23238
  /*
23239
  * Get/create the IDC binding on this element for the IDC definition.
23240
  */
23241
0
  bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23242
0
  if (bind == NULL)
23243
0
     goto internal_error;
23244
23245
0
  if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23246
0
      dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23247
0
      nbDupls = bind->dupls->nbItems;
23248
0
  } else {
23249
0
      dupls = NULL;
23250
0
      nbDupls = 0;
23251
0
  }
23252
0
  if (bind->nodeTable != NULL) {
23253
0
      nbNodeTable = bind->nbNodes;
23254
0
  } else {
23255
0
      nbNodeTable = 0;
23256
0
  }
23257
23258
0
  if ((nbNodeTable == 0) && (nbDupls == 0)) {
23259
      /*
23260
      * Transfer all IDC target-nodes to the IDC node-table.
23261
      */
23262
0
      bind->nodeTable =
23263
0
    (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23264
0
      bind->sizeNodes = matcher->targets->sizeItems;
23265
0
      bind->nbNodes = matcher->targets->nbItems;
23266
23267
0
      matcher->targets->items = NULL;
23268
0
      matcher->targets->sizeItems = 0;
23269
0
      matcher->targets->nbItems = 0;
23270
0
      if (matcher->htab) {
23271
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23272
0
    matcher->htab = NULL;
23273
0
      }
23274
0
  } else {
23275
      /*
23276
      * Compare the key-sequences and add to the IDC node-table.
23277
      */
23278
0
      nbTargets = matcher->targets->nbItems;
23279
0
      targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23280
0
      nbFields = matcher->aidc->def->nbFields;
23281
0
      i = 0;
23282
0
      do {
23283
0
    keys = targets[i]->keys;
23284
0
    if (nbDupls) {
23285
        /*
23286
        * Search in already found duplicates first.
23287
        */
23288
0
        j = 0;
23289
0
        do {
23290
0
      if (nbFields == 1) {
23291
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23292
0
        dupls[j]->keys[0]->val);
23293
0
          if (res == -1)
23294
0
        goto internal_error;
23295
0
          if (res == 1) {
23296
        /*
23297
        * Equal key-sequence.
23298
        */
23299
0
        goto next_target;
23300
0
          }
23301
0
      } else {
23302
0
          res = 0;
23303
0
          ntkeys = dupls[j]->keys;
23304
0
          for (k = 0; k < nbFields; k++) {
23305
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23306
0
            ntkeys[k]->val);
23307
0
        if (res == -1)
23308
0
            goto internal_error;
23309
0
        if (res == 0) {
23310
            /*
23311
            * One of the keys differs.
23312
            */
23313
0
            break;
23314
0
        }
23315
0
          }
23316
0
          if (res == 1) {
23317
        /*
23318
        * Equal key-sequence found.
23319
        */
23320
0
        goto next_target;
23321
0
          }
23322
0
      }
23323
0
      j++;
23324
0
        } while (j < nbDupls);
23325
0
    }
23326
0
    if (nbNodeTable) {
23327
0
        j = 0;
23328
0
        do {
23329
0
      if (nbFields == 1) {
23330
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23331
0
        bind->nodeTable[j]->keys[0]->val);
23332
0
          if (res == -1)
23333
0
        goto internal_error;
23334
0
          if (res == 0) {
23335
        /*
23336
        * The key-sequence differs.
23337
        */
23338
0
        goto next_node_table_entry;
23339
0
          }
23340
0
      } else {
23341
0
          res = 0;
23342
0
          ntkeys = bind->nodeTable[j]->keys;
23343
0
          for (k = 0; k < nbFields; k++) {
23344
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23345
0
            ntkeys[k]->val);
23346
0
        if (res == -1)
23347
0
            goto internal_error;
23348
0
        if (res == 0) {
23349
            /*
23350
            * One of the keys differs.
23351
            */
23352
0
            goto next_node_table_entry;
23353
0
        }
23354
0
          }
23355
0
      }
23356
      /*
23357
      * Add the duplicate to the list of duplicates.
23358
      */
23359
0
      if (bind->dupls == NULL) {
23360
0
          bind->dupls = xmlSchemaItemListCreate();
23361
0
          if (bind->dupls == NULL)
23362
0
        goto internal_error;
23363
0
      }
23364
0
      if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23365
0
          goto internal_error;
23366
      /*
23367
      * Remove the duplicate entry from the IDC node-table.
23368
      */
23369
0
      bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23370
0
      bind->nbNodes--;
23371
23372
0
      goto next_target;
23373
23374
0
next_node_table_entry:
23375
0
      j++;
23376
0
        } while (j < nbNodeTable);
23377
0
    }
23378
    /*
23379
    * If everything is fine, then add the IDC target-node to
23380
    * the IDC node-table.
23381
    */
23382
0
    if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23383
0
        goto internal_error;
23384
23385
0
next_target:
23386
0
    i++;
23387
0
      } while (i < nbTargets);
23388
0
  }
23389
0
  matcher = matcher->next;
23390
0
    }
23391
0
    return(0);
23392
23393
0
internal_error:
23394
0
    return(-1);
23395
0
}
23396
23397
/**
23398
 * xmlSchemaBubbleIDCNodeTables:
23399
 * @depth: the current tree depth
23400
 *
23401
 * Merges IDC bindings of an element at @depth into the corresponding IDC
23402
 * bindings of its parent element. If a duplicate note-table entry is found,
23403
 * both, the parent node-table entry and child entry are discarded from the
23404
 * node-table of the parent.
23405
 *
23406
 * Returns 0 if OK and -1 on internal errors.
23407
 */
23408
static int
23409
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23410
0
{
23411
0
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23412
0
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23413
0
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23414
0
    xmlSchemaIDCAugPtr aidc;
23415
0
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23416
23417
0
    bind = vctxt->inode->idcTable;
23418
0
    if (bind == NULL) {
23419
  /* Fine, no table, no bubbles. */
23420
0
  return (0);
23421
0
    }
23422
23423
0
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23424
    /*
23425
    * Walk all bindings; create new or add to existing bindings.
23426
    * Remove duplicate key-sequences.
23427
    */
23428
0
    while (bind != NULL) {
23429
23430
0
  if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23431
0
      goto next_binding;
23432
  /*
23433
  * Check if the key/unique IDC table needs to be bubbled.
23434
  */
23435
0
  if (! vctxt->createIDCNodeTables) {
23436
0
      aidc = vctxt->aidcs;
23437
0
      do {
23438
0
    if (aidc->def == bind->definition) {
23439
0
        if ((aidc->keyrefDepth == -1) ||
23440
0
      (aidc->keyrefDepth >= vctxt->depth)) {
23441
0
      goto next_binding;
23442
0
        }
23443
0
        break;
23444
0
    }
23445
0
    aidc = aidc->next;
23446
0
      } while (aidc != NULL);
23447
0
  }
23448
23449
0
  if (parTable != NULL)
23450
0
      parBind = *parTable;
23451
  /*
23452
  * Search a matching parent binding for the
23453
  * IDC definition.
23454
  */
23455
0
  while (parBind != NULL) {
23456
0
      if (parBind->definition == bind->definition)
23457
0
    break;
23458
0
      parBind = parBind->next;
23459
0
  }
23460
23461
0
  if (parBind != NULL) {
23462
      /*
23463
      * Compare every node-table entry of the child node,
23464
      * i.e. the key-sequence within, ...
23465
      */
23466
0
      oldNum = parBind->nbNodes; /* Skip newly added items. */
23467
23468
0
      if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23469
0
    oldDupls = parBind->dupls->nbItems;
23470
0
    dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23471
0
      } else {
23472
0
    dupls = NULL;
23473
0
    oldDupls = 0;
23474
0
      }
23475
23476
0
      parNodes = parBind->nodeTable;
23477
0
      nbFields = bind->definition->nbFields;
23478
23479
0
      for (i = 0; i < bind->nbNodes; i++) {
23480
0
    node = bind->nodeTable[i];
23481
0
    if (node == NULL)
23482
0
        continue;
23483
    /*
23484
    * ...with every key-sequence of the parent node, already
23485
    * evaluated to be a duplicate key-sequence.
23486
    */
23487
0
    if (oldDupls) {
23488
0
        j = 0;
23489
0
        while (j < oldDupls) {
23490
0
      if (nbFields == 1) {
23491
0
          ret = xmlSchemaAreValuesEqual(
23492
0
        node->keys[0]->val,
23493
0
        dupls[j]->keys[0]->val);
23494
0
          if (ret == -1)
23495
0
        goto internal_error;
23496
0
          if (ret == 0) {
23497
0
        j++;
23498
0
        continue;
23499
0
          }
23500
0
      } else {
23501
0
          parNode = dupls[j];
23502
0
          for (k = 0; k < nbFields; k++) {
23503
0
        ret = xmlSchemaAreValuesEqual(
23504
0
            node->keys[k]->val,
23505
0
            parNode->keys[k]->val);
23506
0
        if (ret == -1)
23507
0
            goto internal_error;
23508
0
        if (ret == 0)
23509
0
            break;
23510
0
          }
23511
0
      }
23512
0
      if (ret == 1)
23513
          /* Duplicate found. */
23514
0
          break;
23515
0
      j++;
23516
0
        }
23517
0
        if (j != oldDupls) {
23518
      /* Duplicate found. Skip this entry. */
23519
0
      continue;
23520
0
        }
23521
0
    }
23522
    /*
23523
    * ... and with every key-sequence of the parent node.
23524
    */
23525
0
    if (oldNum) {
23526
0
        j = 0;
23527
0
        while (j < oldNum) {
23528
0
      parNode = parNodes[j];
23529
0
      if (nbFields == 1) {
23530
0
          ret = xmlSchemaAreValuesEqual(
23531
0
        node->keys[0]->val,
23532
0
        parNode->keys[0]->val);
23533
0
          if (ret == -1)
23534
0
        goto internal_error;
23535
0
          if (ret == 0) {
23536
0
        j++;
23537
0
        continue;
23538
0
          }
23539
0
      } else {
23540
0
          for (k = 0; k < nbFields; k++) {
23541
0
        ret = xmlSchemaAreValuesEqual(
23542
0
            node->keys[k]->val,
23543
0
            parNode->keys[k]->val);
23544
0
        if (ret == -1)
23545
0
            goto internal_error;
23546
0
        if (ret == 0)
23547
0
            break;
23548
0
          }
23549
0
      }
23550
0
      if (ret == 1)
23551
          /* Duplicate found. */
23552
0
          break;
23553
0
      j++;
23554
0
        }
23555
0
        if (j != oldNum) {
23556
      /*
23557
      * Handle duplicates. Move the duplicate in
23558
      * the parent's node-table to the list of
23559
      * duplicates.
23560
      */
23561
0
      oldNum--;
23562
0
      parBind->nbNodes--;
23563
      /*
23564
      * Move last old item to pos of duplicate.
23565
      */
23566
0
      parNodes[j] = parNodes[oldNum];
23567
23568
0
      if (parBind->nbNodes != oldNum) {
23569
          /*
23570
          * If new items exist, move last new item to
23571
          * last of old items.
23572
          */
23573
0
          parNodes[oldNum] =
23574
0
        parNodes[parBind->nbNodes];
23575
0
      }
23576
0
      if (parBind->dupls == NULL) {
23577
0
          parBind->dupls = xmlSchemaItemListCreate();
23578
0
          if (parBind->dupls == NULL)
23579
0
        goto internal_error;
23580
0
      }
23581
0
      xmlSchemaItemListAdd(parBind->dupls, parNode);
23582
0
        } else {
23583
      /*
23584
      * Add the node-table entry (node and key-sequence) of
23585
      * the child node to the node table of the parent node.
23586
      */
23587
0
      if (parBind->nodeTable == NULL) {
23588
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23589
0
        xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23590
0
          if (parBind->nodeTable == NULL) {
23591
0
        xmlSchemaVErrMemory(NULL);
23592
0
        goto internal_error;
23593
0
          }
23594
0
          parBind->sizeNodes = 1;
23595
0
      } else if (parBind->nbNodes >= parBind->sizeNodes) {
23596
0
          parBind->sizeNodes *= 2;
23597
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23598
0
        xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23599
0
        sizeof(xmlSchemaPSVIIDCNodePtr));
23600
0
          if (parBind->nodeTable == NULL) {
23601
0
        xmlSchemaVErrMemory(NULL);
23602
0
        goto internal_error;
23603
0
          }
23604
0
      }
23605
0
      parNodes = parBind->nodeTable;
23606
      /*
23607
      * Append the new node-table entry to the 'new node-table
23608
      * entries' section.
23609
      */
23610
0
      parNodes[parBind->nbNodes++] = node;
23611
0
        }
23612
23613
0
    }
23614
23615
0
      }
23616
0
  } else {
23617
      /*
23618
      * No binding for the IDC was found: create a new one and
23619
      * copy all node-tables.
23620
      */
23621
0
      parBind = xmlSchemaIDCNewBinding(bind->definition);
23622
0
      if (parBind == NULL)
23623
0
    goto internal_error;
23624
23625
      /*
23626
      * TODO: Hmm, how to optimize the initial number of
23627
      * allocated entries?
23628
      */
23629
0
      if (bind->nbNodes != 0) {
23630
    /*
23631
    * Add all IDC node-table entries.
23632
    */
23633
0
    if (! vctxt->psviExposeIDCNodeTables) {
23634
        /*
23635
        * Just move the entries.
23636
        * NOTE: this is quite save here, since
23637
        * all the keyref lookups have already been
23638
        * performed.
23639
        */
23640
0
        parBind->nodeTable = bind->nodeTable;
23641
0
        bind->nodeTable = NULL;
23642
0
        parBind->sizeNodes = bind->sizeNodes;
23643
0
        bind->sizeNodes = 0;
23644
0
        parBind->nbNodes = bind->nbNodes;
23645
0
        bind->nbNodes = 0;
23646
0
    } else {
23647
        /*
23648
        * Copy the entries.
23649
        */
23650
0
        parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23651
0
      xmlMalloc(bind->nbNodes *
23652
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
23653
0
        if (parBind->nodeTable == NULL) {
23654
0
      xmlSchemaVErrMemory(NULL);
23655
0
      xmlSchemaIDCFreeBinding(parBind);
23656
0
      goto internal_error;
23657
0
        }
23658
0
        parBind->sizeNodes = bind->nbNodes;
23659
0
        parBind->nbNodes = bind->nbNodes;
23660
0
        memcpy(parBind->nodeTable, bind->nodeTable,
23661
0
      bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23662
0
    }
23663
0
      }
23664
0
      if (bind->dupls) {
23665
    /*
23666
    * Move the duplicates.
23667
    */
23668
0
    if (parBind->dupls != NULL)
23669
0
        xmlSchemaItemListFree(parBind->dupls);
23670
0
    parBind->dupls = bind->dupls;
23671
0
    bind->dupls = NULL;
23672
0
      }
23673
0
            if (parTable != NULL) {
23674
0
                if (*parTable == NULL)
23675
0
                    *parTable = parBind;
23676
0
                else {
23677
0
                    parBind->next = *parTable;
23678
0
                    *parTable = parBind;
23679
0
                }
23680
0
            }
23681
0
  }
23682
23683
0
next_binding:
23684
0
  bind = bind->next;
23685
0
    }
23686
0
    return (0);
23687
23688
0
internal_error:
23689
0
    return(-1);
23690
0
}
23691
23692
/**
23693
 * xmlSchemaCheckCVCIDCKeyRef:
23694
 * @vctxt: the WXS validation context
23695
 * @elemDecl: the element declaration
23696
 *
23697
 * Check the cvc-idc-keyref constraints.
23698
 */
23699
static int
23700
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23701
0
{
23702
0
    xmlSchemaIDCMatcherPtr matcher;
23703
0
    xmlSchemaPSVIIDCBindingPtr bind;
23704
23705
0
    matcher = vctxt->inode->idcMatchers;
23706
    /*
23707
    * Find a keyref.
23708
    */
23709
0
    while (matcher != NULL) {
23710
0
  if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23711
0
      matcher->targets &&
23712
0
      matcher->targets->nbItems)
23713
0
  {
23714
0
      int i, j, k, res, nbFields, hasDupls;
23715
0
      xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23716
0
      xmlSchemaPSVIIDCNodePtr refNode = NULL;
23717
0
      xmlHashTablePtr table = NULL;
23718
23719
0
      nbFields = matcher->aidc->def->nbFields;
23720
23721
      /*
23722
      * Find the IDC node-table for the referenced IDC key/unique.
23723
      */
23724
0
      bind = vctxt->inode->idcTable;
23725
0
      while (bind != NULL) {
23726
0
    if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23727
0
        bind->definition)
23728
0
        break;
23729
0
    bind = bind->next;
23730
0
      }
23731
0
      hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23732
      /*
23733
      * Search for a matching key-sequences.
23734
      */
23735
0
      if (bind) {
23736
0
    table = xmlHashCreate(bind->nbNodes * 2);
23737
0
    for (j = 0; j < bind->nbNodes; j++) {
23738
0
        xmlChar *value;
23739
0
        xmlIDCHashEntryPtr r, e;
23740
0
        keys = bind->nodeTable[j]->keys;
23741
0
        xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
23742
0
        e = xmlMalloc(sizeof *e);
23743
0
        e->index = j;
23744
0
        r = xmlHashLookup(table, value);
23745
0
        if (r) {
23746
0
      e->next = r->next;
23747
0
      r->next = e;
23748
0
        } else {
23749
0
      e->next = NULL;
23750
0
      xmlHashAddEntry(table, value, e);
23751
0
        }
23752
0
        FREE_AND_NULL(value);
23753
0
    }
23754
0
      }
23755
0
      for (i = 0; i < matcher->targets->nbItems; i++) {
23756
0
    res = 0;
23757
0
    refNode = matcher->targets->items[i];
23758
0
    if (bind != NULL) {
23759
0
        xmlChar *value;
23760
0
        xmlIDCHashEntryPtr e;
23761
0
        refKeys = refNode->keys;
23762
0
        xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
23763
0
        e = xmlHashLookup(table, value);
23764
0
        FREE_AND_NULL(value);
23765
0
        res = 0;
23766
0
        for (;e; e = e->next) {
23767
0
      keys = bind->nodeTable[e->index]->keys;
23768
0
      for (k = 0; k < nbFields; k++) {
23769
0
          res = xmlSchemaAreValuesEqual(keys[k]->val,
23770
0
                refKeys[k]->val);
23771
0
          if (res == 0)
23772
0
              break;
23773
0
          else if (res == -1) {
23774
0
        return (-1);
23775
0
          }
23776
0
      }
23777
0
      if (res == 1) {
23778
          /*
23779
           * Match found.
23780
           */
23781
0
          break;
23782
0
      }
23783
0
        }
23784
0
        if ((res == 0) && hasDupls) {
23785
      /*
23786
      * Search in duplicates
23787
      */
23788
0
      for (j = 0; j < bind->dupls->nbItems; j++) {
23789
0
          keys = ((xmlSchemaPSVIIDCNodePtr)
23790
0
        bind->dupls->items[j])->keys;
23791
0
          for (k = 0; k < nbFields; k++) {
23792
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23793
0
            refKeys[k]->val);
23794
0
        if (res == 0)
23795
0
            break;
23796
0
        else if (res == -1) {
23797
0
            return (-1);
23798
0
        }
23799
0
          }
23800
0
          if (res == 1) {
23801
        /*
23802
        * Match in duplicates found.
23803
        */
23804
0
        xmlChar *str = NULL, *strB = NULL;
23805
0
        xmlSchemaKeyrefErr(vctxt,
23806
0
            XML_SCHEMAV_CVC_IDC, refNode,
23807
0
            (xmlSchemaTypePtr) matcher->aidc->def,
23808
0
            "More than one match found for "
23809
0
            "key-sequence %s of keyref '%s'",
23810
0
            xmlSchemaFormatIDCKeySequence(vctxt, &str,
23811
0
          refNode->keys, nbFields),
23812
0
            xmlSchemaGetComponentQName(&strB,
23813
0
          matcher->aidc->def));
23814
0
        FREE_AND_NULL(str);
23815
0
        FREE_AND_NULL(strB);
23816
0
        break;
23817
0
          }
23818
0
      }
23819
0
        }
23820
0
    }
23821
23822
0
    if (res == 0) {
23823
0
        xmlChar *str = NULL, *strB = NULL;
23824
0
        xmlSchemaKeyrefErr(vctxt,
23825
0
      XML_SCHEMAV_CVC_IDC, refNode,
23826
0
      (xmlSchemaTypePtr) matcher->aidc->def,
23827
0
      "No match found for key-sequence %s of keyref '%s'",
23828
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
23829
0
          refNode->keys, nbFields),
23830
0
      xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23831
0
        FREE_AND_NULL(str);
23832
0
        FREE_AND_NULL(strB);
23833
0
    }
23834
0
      }
23835
0
      if (table) {
23836
0
    xmlHashFree(table, xmlFreeIDCHashEntry);
23837
0
      }
23838
0
  }
23839
0
  matcher = matcher->next;
23840
0
    }
23841
    /* TODO: Return an error if any error encountered. */
23842
0
    return (0);
23843
0
}
23844
23845
/************************************************************************
23846
 *                  *
23847
 *      XML Reader validation code                      *
23848
 *                  *
23849
 ************************************************************************/
23850
23851
static xmlSchemaAttrInfoPtr
23852
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23853
0
{
23854
0
    xmlSchemaAttrInfoPtr iattr;
23855
    /*
23856
    * Grow/create list of attribute infos.
23857
    */
23858
0
    if (vctxt->attrInfos == NULL) {
23859
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23860
0
      xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23861
0
  vctxt->sizeAttrInfos = 1;
23862
0
  if (vctxt->attrInfos == NULL) {
23863
0
      xmlSchemaVErrMemory(vctxt);
23864
0
      return (NULL);
23865
0
  }
23866
0
    } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23867
0
  vctxt->sizeAttrInfos++;
23868
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23869
0
      xmlRealloc(vctxt->attrInfos,
23870
0
    vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23871
0
  if (vctxt->attrInfos == NULL) {
23872
0
      xmlSchemaVErrMemory(vctxt);
23873
0
      return (NULL);
23874
0
  }
23875
0
    } else {
23876
0
  iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23877
0
  if (iattr->localName != NULL) {
23878
0
      VERROR_INT("xmlSchemaGetFreshAttrInfo",
23879
0
    "attr info not cleared");
23880
0
      return (NULL);
23881
0
  }
23882
0
  iattr->nodeType = XML_ATTRIBUTE_NODE;
23883
0
  return (iattr);
23884
0
    }
23885
    /*
23886
    * Create an attribute info.
23887
    */
23888
0
    iattr = (xmlSchemaAttrInfoPtr)
23889
0
  xmlMalloc(sizeof(xmlSchemaAttrInfo));
23890
0
    if (iattr == NULL) {
23891
0
  xmlSchemaVErrMemory(vctxt);
23892
0
  return (NULL);
23893
0
    }
23894
0
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23895
0
    iattr->nodeType = XML_ATTRIBUTE_NODE;
23896
0
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23897
23898
0
    return (iattr);
23899
0
}
23900
23901
static int
23902
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23903
      xmlNodePtr attrNode,
23904
      int nodeLine,
23905
      const xmlChar *localName,
23906
      const xmlChar *nsName,
23907
      int ownedNames,
23908
      xmlChar *value,
23909
      int ownedValue)
23910
0
{
23911
0
    xmlSchemaAttrInfoPtr attr;
23912
23913
0
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
23914
0
    if (attr == NULL) {
23915
0
  VERROR_INT("xmlSchemaPushAttribute",
23916
0
      "calling xmlSchemaGetFreshAttrInfo()");
23917
0
  return (-1);
23918
0
    }
23919
0
    attr->node = attrNode;
23920
0
    attr->nodeLine = nodeLine;
23921
0
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23922
0
    attr->localName = localName;
23923
0
    attr->nsName = nsName;
23924
0
    if (ownedNames)
23925
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23926
    /*
23927
    * Evaluate if it's an XSI attribute.
23928
    */
23929
0
    if (nsName != NULL) {
23930
0
  if (xmlStrEqual(localName, BAD_CAST "nil")) {
23931
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23932
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23933
0
      }
23934
0
  } else if (xmlStrEqual(localName, BAD_CAST "type")) {
23935
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23936
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23937
0
      }
23938
0
  } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23939
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23940
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23941
0
      }
23942
0
  } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23943
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23944
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23945
0
      }
23946
0
  } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23947
0
      attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23948
0
  }
23949
0
    }
23950
0
    attr->value = value;
23951
0
    if (ownedValue)
23952
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23953
0
    if (attr->metaType != 0)
23954
0
  attr->state = XML_SCHEMAS_ATTR_META;
23955
0
    return (0);
23956
0
}
23957
23958
/**
23959
 * xmlSchemaClearElemInfo:
23960
 * @vctxt: the WXS validation context
23961
 * @ielem: the element information item
23962
 */
23963
static void
23964
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23965
           xmlSchemaNodeInfoPtr ielem)
23966
0
{
23967
0
    ielem->hasKeyrefs = 0;
23968
0
    ielem->appliedXPath = 0;
23969
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23970
0
  FREE_AND_NULL(ielem->localName);
23971
0
  FREE_AND_NULL(ielem->nsName);
23972
0
    } else {
23973
0
  ielem->localName = NULL;
23974
0
  ielem->nsName = NULL;
23975
0
    }
23976
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
23977
0
  FREE_AND_NULL(ielem->value);
23978
0
    } else {
23979
0
  ielem->value = NULL;
23980
0
    }
23981
0
    if (ielem->val != NULL) {
23982
  /*
23983
  * PSVI TODO: Be careful not to free it when the value is
23984
  * exposed via PSVI.
23985
  */
23986
0
  xmlSchemaFreeValue(ielem->val);
23987
0
  ielem->val = NULL;
23988
0
    }
23989
0
    if (ielem->idcMatchers != NULL) {
23990
  /*
23991
  * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
23992
  *   Does it work?
23993
  */
23994
0
  xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
23995
#if 0
23996
  xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
23997
#endif
23998
0
  ielem->idcMatchers = NULL;
23999
0
    }
24000
0
    if (ielem->idcTable != NULL) {
24001
  /*
24002
  * OPTIMIZE TODO: Use a pool of IDC tables??.
24003
  */
24004
0
  xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24005
0
  ielem->idcTable = NULL;
24006
0
    }
24007
0
    if (ielem->regexCtxt != NULL) {
24008
0
  xmlRegFreeExecCtxt(ielem->regexCtxt);
24009
0
  ielem->regexCtxt = NULL;
24010
0
    }
24011
0
    if (ielem->nsBindings != NULL) {
24012
0
  xmlFree((xmlChar **)ielem->nsBindings);
24013
0
  ielem->nsBindings = NULL;
24014
0
  ielem->nbNsBindings = 0;
24015
0
  ielem->sizeNsBindings = 0;
24016
0
    }
24017
0
}
24018
24019
/**
24020
 * xmlSchemaGetFreshElemInfo:
24021
 * @vctxt: the schema validation context
24022
 *
24023
 * Creates/reuses and initializes the element info item for
24024
 * the current tree depth.
24025
 *
24026
 * Returns the element info item or NULL on API or internal errors.
24027
 */
24028
static xmlSchemaNodeInfoPtr
24029
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24030
0
{
24031
0
    xmlSchemaNodeInfoPtr info = NULL;
24032
24033
0
    if (vctxt->depth > vctxt->sizeElemInfos) {
24034
0
  VERROR_INT("xmlSchemaGetFreshElemInfo",
24035
0
      "inconsistent depth encountered");
24036
0
  return (NULL);
24037
0
    }
24038
0
    if (vctxt->elemInfos == NULL) {
24039
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24040
0
      xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24041
0
  if (vctxt->elemInfos == NULL) {
24042
0
      xmlSchemaVErrMemory(vctxt);
24043
0
      return (NULL);
24044
0
  }
24045
0
  memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24046
0
  vctxt->sizeElemInfos = 10;
24047
0
    } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24048
0
  int i = vctxt->sizeElemInfos;
24049
24050
0
  vctxt->sizeElemInfos *= 2;
24051
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24052
0
      xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24053
0
      sizeof(xmlSchemaNodeInfoPtr));
24054
0
  if (vctxt->elemInfos == NULL) {
24055
0
      xmlSchemaVErrMemory(vctxt);
24056
0
      return (NULL);
24057
0
  }
24058
  /*
24059
  * We need the new memory to be NULLed.
24060
  * TODO: Use memset instead?
24061
  */
24062
0
  for (; i < vctxt->sizeElemInfos; i++)
24063
0
      vctxt->elemInfos[i] = NULL;
24064
0
    } else
24065
0
  info = vctxt->elemInfos[vctxt->depth];
24066
24067
0
    if (info == NULL) {
24068
0
  info = (xmlSchemaNodeInfoPtr)
24069
0
      xmlMalloc(sizeof(xmlSchemaNodeInfo));
24070
0
  if (info == NULL) {
24071
0
      xmlSchemaVErrMemory(vctxt);
24072
0
      return (NULL);
24073
0
  }
24074
0
  vctxt->elemInfos[vctxt->depth] = info;
24075
0
    } else {
24076
0
  if (info->localName != NULL) {
24077
0
      VERROR_INT("xmlSchemaGetFreshElemInfo",
24078
0
    "elem info has not been cleared");
24079
0
      return (NULL);
24080
0
  }
24081
0
    }
24082
0
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
24083
0
    info->nodeType = XML_ELEMENT_NODE;
24084
0
    info->depth = vctxt->depth;
24085
24086
0
    return (info);
24087
0
}
24088
24089
0
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24090
0
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24091
0
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24092
24093
static int
24094
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24095
      xmlNodePtr node,
24096
      xmlSchemaTypePtr type,
24097
      xmlSchemaValType valType,
24098
      const xmlChar * value,
24099
      xmlSchemaValPtr val,
24100
      unsigned long length,
24101
      int fireErrors)
24102
10.6k
{
24103
10.6k
    int ret, error = 0, found;
24104
24105
10.6k
    xmlSchemaTypePtr tmpType;
24106
10.6k
    xmlSchemaFacetLinkPtr facetLink;
24107
10.6k
    xmlSchemaFacetPtr facet;
24108
10.6k
    unsigned long len = 0;
24109
10.6k
    xmlSchemaWhitespaceValueType ws;
24110
24111
    /*
24112
    * In Libxml2, derived built-in types have currently no explicit facets.
24113
    */
24114
10.6k
    if (type->type == XML_SCHEMA_TYPE_BASIC)
24115
2.95k
  return (0);
24116
24117
    /*
24118
    * NOTE: Do not jump away, if the facetSet of the given type is
24119
    * empty: until now, "pattern" and "enumeration" facets of the
24120
    * *base types* need to be checked as well.
24121
    */
24122
7.70k
    if (type->facetSet == NULL)
24123
7
  goto pattern_and_enum;
24124
24125
7.70k
    if (! WXS_IS_ATOMIC(type)) {
24126
40
  if (WXS_IS_LIST(type))
24127
40
      goto WXS_IS_LIST;
24128
0
  else
24129
0
      goto pattern_and_enum;
24130
40
    }
24131
24132
    /*
24133
    * Whitespace handling is only of importance for string-based
24134
    * types.
24135
    */
24136
7.66k
    tmpType = xmlSchemaGetPrimitiveType(type);
24137
7.66k
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24138
7.66k
  WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24139
331
  ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24140
331
    } else
24141
7.33k
  ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24142
24143
    /*
24144
    * If the value was not computed (for string or
24145
    * anySimpleType based types), then use the provided
24146
    * type.
24147
    */
24148
7.66k
    if (val != NULL)
24149
7.66k
  valType = xmlSchemaGetValType(val);
24150
24151
7.66k
    ret = 0;
24152
63.1k
    for (facetLink = type->facetSet; facetLink != NULL;
24153
55.4k
  facetLink = facetLink->next) {
24154
  /*
24155
  * Skip the pattern "whiteSpace": it is used to
24156
  * format the character content beforehand.
24157
  */
24158
55.4k
  switch (facetLink->facet->type) {
24159
10.5k
      case XML_SCHEMA_FACET_WHITESPACE:
24160
18.1k
      case XML_SCHEMA_FACET_PATTERN:
24161
25.5k
      case XML_SCHEMA_FACET_ENUMERATION:
24162
25.5k
    continue;
24163
506
      case XML_SCHEMA_FACET_LENGTH:
24164
1.17k
      case XML_SCHEMA_FACET_MINLENGTH:
24165
1.74k
      case XML_SCHEMA_FACET_MAXLENGTH:
24166
1.74k
    ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24167
1.74k
        valType, value, val, &len, ws);
24168
1.74k
    break;
24169
28.1k
      default:
24170
28.1k
    ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24171
28.1k
        valType, value, val, ws);
24172
28.1k
    break;
24173
55.4k
  }
24174
29.9k
  if (ret < 0) {
24175
1
      AERROR_INT("xmlSchemaValidateFacets",
24176
1
    "validating against a atomic type facet");
24177
1
      return (-1);
24178
29.9k
  } else if (ret > 0) {
24179
13.2k
      if (fireErrors)
24180
13.2k
    xmlSchemaFacetErr(actxt, ret, node,
24181
13.2k
    value, len, type, facetLink->facet, NULL, NULL, NULL);
24182
0
      else
24183
0
    return (ret);
24184
13.2k
      if (error == 0)
24185
4.67k
    error = ret;
24186
13.2k
  }
24187
29.9k
  ret = 0;
24188
29.9k
    }
24189
24190
7.70k
WXS_IS_LIST:
24191
7.70k
    if (! WXS_IS_LIST(type))
24192
7.66k
  goto pattern_and_enum;
24193
    /*
24194
    * "length", "minLength" and "maxLength" of list types.
24195
    */
24196
40
    ret = 0;
24197
90
    for (facetLink = type->facetSet; facetLink != NULL;
24198
50
  facetLink = facetLink->next) {
24199
24200
50
  switch (facetLink->facet->type) {
24201
0
      case XML_SCHEMA_FACET_LENGTH:
24202
0
      case XML_SCHEMA_FACET_MINLENGTH:
24203
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24204
0
    ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24205
0
        value, length, NULL);
24206
0
    break;
24207
50
      default:
24208
50
    continue;
24209
50
  }
24210
0
  if (ret < 0) {
24211
0
      AERROR_INT("xmlSchemaValidateFacets",
24212
0
    "validating against a list type facet");
24213
0
      return (-1);
24214
0
  } else if (ret > 0) {
24215
0
      if (fireErrors)
24216
0
    xmlSchemaFacetErr(actxt, ret, node,
24217
0
    value, length, type, facetLink->facet, NULL, NULL, NULL);
24218
0
      else
24219
0
    return (ret);
24220
0
      if (error == 0)
24221
0
    error = ret;
24222
0
  }
24223
0
  ret = 0;
24224
0
    }
24225
24226
7.70k
pattern_and_enum:
24227
7.70k
    found = 0;
24228
    /*
24229
    * Process enumerations. Facet values are in the value space
24230
    * of the defining type's base type. This seems to be a bug in the
24231
    * XML Schema 1.0 spec. Use the whitespace type of the base type.
24232
    * Only the first set of enumerations in the ancestor-or-self axis
24233
    * is used for validation.
24234
    */
24235
7.70k
    ret = 0;
24236
7.70k
    tmpType = type;
24237
7.99k
    do {
24238
56.4k
        for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24239
48.6k
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24240
41.3k
                continue;
24241
7.26k
            found = 1;
24242
7.26k
            ret = xmlSchemaAreValuesEqual(facet->val, val);
24243
7.26k
            if (ret == 1)
24244
152
                break;
24245
7.10k
            else if (ret < 0) {
24246
0
                AERROR_INT("xmlSchemaValidateFacets",
24247
0
                    "validating against an enumeration facet");
24248
0
                return (-1);
24249
0
            }
24250
7.26k
        }
24251
7.99k
        if (ret != 0)
24252
152
            break;
24253
        /*
24254
        * Break on the first set of enumerations. Any additional
24255
        *  enumerations which might be existent on the ancestors
24256
        *  of the current type are restricted by this set; thus
24257
        *  *must* *not* be taken into account.
24258
        */
24259
7.84k
        if (found)
24260
6.47k
            break;
24261
1.36k
        tmpType = tmpType->baseType;
24262
1.36k
    } while ((tmpType != NULL) &&
24263
1.36k
        (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24264
7.70k
    if (found && (ret == 0)) {
24265
6.47k
        ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24266
6.47k
        if (fireErrors) {
24267
6.43k
            xmlSchemaFacetErr(actxt, ret, node,
24268
6.43k
                value, 0, type, NULL, NULL, NULL, NULL);
24269
6.43k
        } else
24270
40
            return (ret);
24271
6.43k
        if (error == 0)
24272
2.22k
            error = ret;
24273
6.43k
    }
24274
24275
    /*
24276
    * Process patters. Pattern facets are ORed at type level
24277
    * and ANDed if derived. Walk the base type axis.
24278
    */
24279
7.66k
    tmpType = type;
24280
7.66k
    facet = NULL;
24281
7.76k
    do {
24282
7.76k
        found = 0;
24283
63.2k
        for (facetLink = tmpType->facetSet; facetLink != NULL;
24284
55.5k
            facetLink = facetLink->next) {
24285
55.5k
            if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24286
47.9k
                continue;
24287
7.57k
            found = 1;
24288
            /*
24289
            * NOTE that for patterns, @value needs to be the
24290
            * normalized value.
24291
            */
24292
7.57k
            ret = xmlRegexpExec(facetLink->facet->regexp, value);
24293
7.57k
            if (ret == 1)
24294
22
                break;
24295
7.55k
            else if (ret < 0) {
24296
23
                AERROR_INT("xmlSchemaValidateFacets",
24297
23
                    "validating against a pattern facet");
24298
23
                return (-1);
24299
7.53k
            } else {
24300
                /*
24301
                * Save the last non-validating facet.
24302
                */
24303
7.53k
                facet = facetLink->facet;
24304
7.53k
            }
24305
7.57k
        }
24306
7.74k
        if (found && (ret != 1)) {
24307
6.77k
            ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24308
6.77k
            if (fireErrors) {
24309
6.77k
                xmlSchemaFacetErr(actxt, ret, node,
24310
6.77k
                    value, 0, type, facet, NULL, NULL, NULL);
24311
6.77k
            } else
24312
0
                return (ret);
24313
6.77k
            if (error == 0)
24314
113
                error = ret;
24315
6.77k
            break;
24316
6.77k
        }
24317
968
        tmpType = tmpType->baseType;
24318
968
    } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24319
24320
7.64k
    return (error);
24321
7.66k
}
24322
24323
static xmlChar *
24324
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24325
      const xmlChar *value)
24326
107k
{
24327
107k
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24328
94.4k
  case XML_SCHEMA_WHITESPACE_COLLAPSE:
24329
94.4k
      return (xmlSchemaCollapseString(value));
24330
11.5k
  case XML_SCHEMA_WHITESPACE_REPLACE:
24331
11.5k
      return (xmlSchemaWhiteSpaceReplace(value));
24332
1.09k
  default:
24333
1.09k
      return (NULL);
24334
107k
    }
24335
107k
}
24336
24337
static int
24338
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24339
           const xmlChar *value,
24340
           xmlSchemaValPtr *val,
24341
           int valNeeded)
24342
0
{
24343
0
    int ret;
24344
0
    xmlChar *stripped;
24345
0
    const xmlChar *nsName;
24346
0
    xmlChar *local, *prefix = NULL;
24347
24348
0
    ret = xmlValidateQName(value, 1);
24349
0
    if (ret != 0) {
24350
0
  if (ret == -1) {
24351
0
      VERROR_INT("xmlSchemaValidateQName",
24352
0
    "calling xmlValidateQName()");
24353
0
      return (-1);
24354
0
  }
24355
0
  return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24356
0
    }
24357
    /*
24358
    * NOTE: xmlSplitQName2 will always return a duplicated
24359
    * strings.
24360
    */
24361
    /* TODO: Export and use xmlSchemaStrip instead */
24362
0
    stripped = xmlSchemaCollapseString(value);
24363
0
    local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24364
0
    xmlFree(stripped);
24365
0
    if (local == NULL)
24366
0
  local = xmlStrdup(value);
24367
    /*
24368
    * OPTIMIZE TODO: Use flags for:
24369
    *  - is there any namespace binding?
24370
    *  - is there a default namespace?
24371
    */
24372
0
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24373
24374
0
    if (prefix != NULL) {
24375
0
  xmlFree(prefix);
24376
  /*
24377
  * A namespace must be found if the prefix is
24378
  * NOT NULL.
24379
  */
24380
0
  if (nsName == NULL) {
24381
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24382
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24383
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24384
0
    "The QName value '%s' has no "
24385
0
    "corresponding namespace declaration in "
24386
0
    "scope", value, NULL);
24387
0
      if (local != NULL)
24388
0
    xmlFree(local);
24389
0
      return (ret);
24390
0
  }
24391
0
    }
24392
0
    if (valNeeded && val) {
24393
0
  if (nsName != NULL)
24394
0
      *val = xmlSchemaNewQNameValue(
24395
0
    BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24396
0
  else
24397
0
      *val = xmlSchemaNewQNameValue(NULL,
24398
0
    BAD_CAST local);
24399
0
    } else
24400
0
  xmlFree(local);
24401
0
    return (0);
24402
0
}
24403
24404
/*
24405
* cvc-simple-type
24406
*/
24407
static int
24408
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24409
           xmlNodePtr node,
24410
           xmlSchemaTypePtr type,
24411
           const xmlChar *value,
24412
           xmlSchemaValPtr *retVal,
24413
           int fireErrors,
24414
           int normalize,
24415
           int isNormalized)
24416
144k
{
24417
144k
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
24418
144k
    xmlSchemaValPtr val = NULL;
24419
    /* xmlSchemaWhitespaceValueType ws; */
24420
144k
    xmlChar *normValue = NULL;
24421
24422
144k
#define NORMALIZE(atype) \
24423
147k
    if ((! isNormalized) && \
24424
147k
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24425
107k
  normValue = xmlSchemaNormalizeValue(atype, value); \
24426
107k
  if (normValue != NULL) \
24427
107k
      value = normValue; \
24428
107k
  isNormalized = 1; \
24429
107k
    }
24430
24431
144k
    if ((retVal != NULL) && (*retVal != NULL)) {
24432
0
  xmlSchemaFreeValue(*retVal);
24433
0
  *retVal = NULL;
24434
0
    }
24435
    /*
24436
    * 3.14.4 Simple Type Definition Validation Rules
24437
    * Validation Rule: String Valid
24438
    */
24439
    /*
24440
    * 1 It is schema-valid with respect to that definition as defined
24441
    * by Datatype Valid in [XML Schemas: Datatypes].
24442
    */
24443
    /*
24444
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24445
    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24446
    * the string must be a `declared entity name`.
24447
    */
24448
    /*
24449
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24450
    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24451
    * then every whitespace-delimited substring of the string must be a `declared
24452
    * entity name`.
24453
    */
24454
    /*
24455
    * 2.3 otherwise no further condition applies.
24456
    */
24457
144k
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24458
0
  valNeeded = 1;
24459
144k
    if (value == NULL)
24460
0
  value = BAD_CAST "";
24461
144k
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24462
137k
  xmlSchemaTypePtr biType; /* The built-in type. */
24463
  /*
24464
  * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24465
  * a literal in the `lexical space` of {base type definition}"
24466
  */
24467
  /*
24468
  * Whitespace-normalize.
24469
  */
24470
137k
  NORMALIZE(type);
24471
137k
  if (type->type != XML_SCHEMA_TYPE_BASIC) {
24472
      /*
24473
      * Get the built-in type.
24474
      */
24475
15.1k
      biType = type->baseType;
24476
28.4k
      while ((biType != NULL) &&
24477
28.4k
    (biType->type != XML_SCHEMA_TYPE_BASIC))
24478
13.2k
    biType = biType->baseType;
24479
24480
15.1k
      if (biType == NULL) {
24481
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24482
0
        "could not get the built-in type");
24483
0
    goto internal_error;
24484
0
      }
24485
15.1k
  } else
24486
122k
      biType = type;
24487
  /*
24488
  * NOTATIONs need to be processed here, since they need
24489
  * to lookup in the hashtable of NOTATION declarations of the schema.
24490
  */
24491
137k
  if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24492
0
      switch (biType->builtInType) {
24493
0
    case XML_SCHEMAS_NOTATION:
24494
0
        ret = xmlSchemaValidateNotation(
24495
0
      (xmlSchemaValidCtxtPtr) actxt,
24496
0
      ((xmlSchemaValidCtxtPtr) actxt)->schema,
24497
0
      NULL, value, &val, valNeeded);
24498
0
        break;
24499
0
    case XML_SCHEMAS_QNAME:
24500
0
        ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24501
0
      value, &val, valNeeded);
24502
0
        break;
24503
0
    default:
24504
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24505
0
        if (valNeeded)
24506
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24507
0
          value, &val, node);
24508
0
        else
24509
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24510
0
          value, NULL, node);
24511
0
        break;
24512
0
      }
24513
137k
  } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24514
137k
      switch (biType->builtInType) {
24515
962
    case XML_SCHEMAS_NOTATION:
24516
962
        ret = xmlSchemaValidateNotation(NULL,
24517
962
      ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24518
962
      value, &val, valNeeded);
24519
962
        break;
24520
136k
    default:
24521
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24522
136k
        if (valNeeded)
24523
136k
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24524
136k
          value, &val, node);
24525
0
        else
24526
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24527
0
          value, NULL, node);
24528
136k
        break;
24529
137k
      }
24530
137k
  } else {
24531
      /*
24532
      * Validation via a public API is not implemented yet.
24533
      */
24534
0
      goto internal_error;
24535
0
  }
24536
137k
  if (ret != 0) {
24537
75.2k
      if (ret < 0) {
24538
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24539
0
        "validating against a built-in type");
24540
0
    goto internal_error;
24541
0
      }
24542
75.2k
      if (WXS_IS_LIST(type))
24543
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24544
75.2k
      else
24545
75.2k
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24546
75.2k
  }
24547
137k
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24548
      /*
24549
      * Check facets.
24550
      */
24551
7.66k
      ret = xmlSchemaValidateFacets(actxt, node, type,
24552
7.66k
    (xmlSchemaValType) biType->builtInType, value, val,
24553
7.66k
    0, fireErrors);
24554
7.66k
      if (ret != 0) {
24555
7.02k
    if (ret < 0) {
24556
24
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24557
24
      "validating facets of atomic simple type");
24558
24
        goto internal_error;
24559
24
    }
24560
6.99k
    if (WXS_IS_LIST(type))
24561
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24562
6.99k
    else
24563
6.99k
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24564
6.99k
      }
24565
7.66k
  }
24566
130k
  else if (fireErrors && (ret > 0))
24567
75.1k
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24568
137k
    } else if (WXS_IS_LIST(type)) {
24569
24570
6.33k
  xmlSchemaTypePtr itemType;
24571
6.33k
  const xmlChar *cur, *end;
24572
6.33k
  xmlChar *tmpValue = NULL;
24573
6.33k
  unsigned long len = 0;
24574
6.33k
  xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24575
  /* 1.2.2 if {variety} is `list` then the string must be a sequence
24576
  * of white space separated tokens, each of which `match`es a literal
24577
  * in the `lexical space` of {item type definition}
24578
  */
24579
  /*
24580
  * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24581
  * the list type has an enum or pattern facet.
24582
  */
24583
6.33k
  NORMALIZE(type);
24584
  /*
24585
  * VAL TODO: Optimize validation of empty values.
24586
  * VAL TODO: We do not have computed values for lists.
24587
  */
24588
6.33k
  itemType = WXS_LIST_ITEMTYPE(type);
24589
6.33k
  cur = value;
24590
37.1k
  do {
24591
37.1k
      while (IS_BLANK_CH(*cur))
24592
30.8k
    cur++;
24593
37.1k
      end = cur;
24594
581k
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24595
544k
    end++;
24596
37.1k
      if (end == cur)
24597
26
    break;
24598
37.1k
      tmpValue = xmlStrndup(cur, end - cur);
24599
37.1k
      len++;
24600
24601
37.1k
      if (valNeeded)
24602
37.1k
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24603
37.1k
        tmpValue, &curVal, fireErrors, 0, 1);
24604
0
      else
24605
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24606
0
        tmpValue, NULL, fireErrors, 0, 1);
24607
37.1k
      FREE_AND_NULL(tmpValue);
24608
37.1k
      if (curVal != NULL) {
24609
    /*
24610
    * Add to list of computed values.
24611
    */
24612
33.8k
    if (val == NULL)
24613
3.88k
        val = curVal;
24614
29.9k
    else
24615
29.9k
        xmlSchemaValueAppend(prevVal, curVal);
24616
33.8k
    prevVal = curVal;
24617
33.8k
    curVal = NULL;
24618
33.8k
      }
24619
37.1k
      if (ret != 0) {
24620
3.29k
    if (ret < 0) {
24621
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24622
0
      "validating an item of list simple type");
24623
0
        goto internal_error;
24624
0
    }
24625
3.29k
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24626
3.29k
    break;
24627
3.29k
      }
24628
33.8k
      cur = end;
24629
33.8k
  } while (*cur != 0);
24630
6.33k
  FREE_AND_NULL(tmpValue);
24631
6.33k
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24632
      /*
24633
      * Apply facets (pattern, enumeration).
24634
      */
24635
3.00k
      ret = xmlSchemaValidateFacets(actxt, node, type,
24636
3.00k
    XML_SCHEMAS_UNKNOWN, value, val,
24637
3.00k
    len, fireErrors);
24638
3.00k
      if (ret != 0) {
24639
40
    if (ret < 0) {
24640
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24641
0
      "validating facets of list simple type");
24642
0
        goto internal_error;
24643
0
    }
24644
40
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24645
40
      }
24646
3.00k
  }
24647
6.33k
  if (fireErrors && (ret > 0)) {
24648
      /*
24649
      * Report the normalized value.
24650
      */
24651
3.19k
      normalize = 1;
24652
3.19k
      NORMALIZE(type);
24653
3.19k
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24654
3.19k
  }
24655
6.33k
    } else if (WXS_IS_UNION(type)) {
24656
148
  xmlSchemaTypeLinkPtr memberLink;
24657
  /*
24658
  * TODO: For all datatypes `derived` by `union`  whiteSpace does
24659
  * not apply directly; however, the normalization behavior of `union`
24660
  * types is controlled by the value of whiteSpace on that one of the
24661
  * `memberTypes` against which the `union` is successfully validated.
24662
  *
24663
  * This means that the value is normalized by the first validating
24664
  * member type, then the facets of the union type are applied. This
24665
  * needs changing of the value!
24666
  */
24667
24668
  /*
24669
  * 1.2.3 if {variety} is `union` then the string must `match` a
24670
  * literal in the `lexical space` of at least one member of
24671
  * {member type definitions}
24672
  */
24673
148
  memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24674
148
  if (memberLink == NULL) {
24675
0
      AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24676
0
    "union simple type has no member types");
24677
0
      goto internal_error;
24678
0
  }
24679
  /*
24680
  * Always normalize union type values, since we currently
24681
  * cannot store the whitespace information with the value
24682
  * itself; otherwise a later value-comparison would be
24683
  * not possible.
24684
  */
24685
285
  while (memberLink != NULL) {
24686
181
      if (valNeeded)
24687
181
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24688
181
        memberLink->type, value, &val, 0, 1, 0);
24689
0
      else
24690
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24691
0
        memberLink->type, value, NULL, 0, 1, 0);
24692
181
      if (ret <= 0)
24693
44
    break;
24694
137
      memberLink = memberLink->next;
24695
137
  }
24696
148
  if (ret != 0) {
24697
104
      if (ret < 0) {
24698
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24699
0
        "validating members of union simple type");
24700
0
    goto internal_error;
24701
0
      }
24702
104
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24703
104
  }
24704
  /*
24705
  * Apply facets (pattern, enumeration).
24706
  */
24707
148
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24708
      /*
24709
      * The normalization behavior of `union` types is controlled by
24710
      * the value of whiteSpace on that one of the `memberTypes`
24711
      * against which the `union` is successfully validated.
24712
      */
24713
0
      NORMALIZE(memberLink->type);
24714
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24715
0
    XML_SCHEMAS_UNKNOWN, value, val,
24716
0
    0, fireErrors);
24717
0
      if (ret != 0) {
24718
0
    if (ret < 0) {
24719
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24720
0
      "validating facets of union simple type");
24721
0
        goto internal_error;
24722
0
    }
24723
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24724
0
      }
24725
0
  }
24726
148
  if (fireErrors && (ret > 0))
24727
104
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24728
148
    }
24729
24730
144k
    if (normValue != NULL)
24731
23.9k
  xmlFree(normValue);
24732
144k
    if (ret == 0) {
24733
58.7k
  if (retVal != NULL)
24734
58.7k
      *retVal = val;
24735
0
  else if (val != NULL)
24736
0
      xmlSchemaFreeValue(val);
24737
85.6k
    } else if (val != NULL)
24738
7.89k
  xmlSchemaFreeValue(val);
24739
144k
    return (ret);
24740
24
internal_error:
24741
24
    if (normValue != NULL)
24742
3
  xmlFree(normValue);
24743
24
    if (val != NULL)
24744
24
  xmlSchemaFreeValue(val);
24745
24
    return (-1);
24746
144k
}
24747
24748
static int
24749
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24750
         const xmlChar *value,
24751
         const xmlChar **nsName,
24752
         const xmlChar **localName)
24753
0
{
24754
0
    int ret = 0;
24755
24756
0
    if ((nsName == NULL) || (localName == NULL))
24757
0
  return (-1);
24758
0
    *nsName = NULL;
24759
0
    *localName = NULL;
24760
24761
0
    ret = xmlValidateQName(value, 1);
24762
0
    if (ret == -1)
24763
0
  return (-1);
24764
0
    if (ret > 0) {
24765
0
  xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24766
0
      XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24767
0
      value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24768
0
  return (1);
24769
0
    }
24770
0
    {
24771
0
  xmlChar *local = NULL;
24772
0
  xmlChar *prefix;
24773
24774
  /*
24775
  * NOTE: xmlSplitQName2 will return a duplicated
24776
  * string.
24777
  */
24778
0
  local = xmlSplitQName2(value, &prefix);
24779
0
  if (local == NULL)
24780
0
      *localName = xmlDictLookup(vctxt->dict, value, -1);
24781
0
  else {
24782
0
      *localName = xmlDictLookup(vctxt->dict, local, -1);
24783
0
      xmlFree(local);
24784
0
  }
24785
24786
0
  *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24787
24788
0
  if (prefix != NULL) {
24789
0
      xmlFree(prefix);
24790
      /*
24791
      * A namespace must be found if the prefix is NOT NULL.
24792
      */
24793
0
      if (*nsName == NULL) {
24794
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24795
0
        XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24796
0
        WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24797
0
        "The QName value '%s' has no "
24798
0
        "corresponding namespace declaration in scope",
24799
0
        value, NULL);
24800
0
    return (2);
24801
0
      }
24802
0
  }
24803
0
    }
24804
0
    return (0);
24805
0
}
24806
24807
static int
24808
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24809
      xmlSchemaAttrInfoPtr iattr,
24810
      xmlSchemaTypePtr *localType,
24811
      xmlSchemaElementPtr elemDecl)
24812
0
{
24813
0
    int ret = 0;
24814
    /*
24815
    * cvc-elt (3.3.4) : (4)
24816
    * AND
24817
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
24818
    *   (1.2.1.2.1) - (1.2.1.2.4)
24819
    * Handle 'xsi:type'.
24820
    */
24821
0
    if (localType == NULL)
24822
0
  return (-1);
24823
0
    *localType = NULL;
24824
0
    if (iattr == NULL)
24825
0
  return (0);
24826
0
    else {
24827
0
  const xmlChar *nsName = NULL, *local = NULL;
24828
  /*
24829
  * TODO: We should report a *warning* that the type was overridden
24830
  * by the instance.
24831
  */
24832
0
  ACTIVATE_ATTRIBUTE(iattr);
24833
  /*
24834
  * (cvc-elt) (3.3.4) : (4.1)
24835
  * (cvc-assess-elt) (1.2.1.2.2)
24836
  */
24837
0
  ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24838
0
      &nsName, &local);
24839
0
  if (ret != 0) {
24840
0
      if (ret < 0) {
24841
0
    VERROR_INT("xmlSchemaValidateElementByDeclaration",
24842
0
        "calling xmlSchemaQNameExpand() to validate the "
24843
0
        "attribute 'xsi:type'");
24844
0
    goto internal_error;
24845
0
      }
24846
0
      goto exit;
24847
0
  }
24848
  /*
24849
  * (cvc-elt) (3.3.4) : (4.2)
24850
  * (cvc-assess-elt) (1.2.1.2.3)
24851
  */
24852
0
  *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24853
0
  if (*localType == NULL) {
24854
0
      xmlChar *str = NULL;
24855
24856
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
24857
0
    XML_SCHEMAV_CVC_ELT_4_2, NULL,
24858
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24859
0
    "The QName value '%s' of the xsi:type attribute does not "
24860
0
    "resolve to a type definition",
24861
0
    xmlSchemaFormatQName(&str, nsName, local), NULL);
24862
0
      FREE_AND_NULL(str);
24863
0
      ret = vctxt->err;
24864
0
      goto exit;
24865
0
  }
24866
0
  if (elemDecl != NULL) {
24867
0
      int set = 0;
24868
24869
      /*
24870
      * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24871
      * "The `local type definition` must be validly
24872
      * derived from the {type definition} given the union of
24873
      * the {disallowed substitutions} and the {type definition}'s
24874
      * {prohibited substitutions}, as defined in
24875
      * Type Derivation OK (Complex) ($3.4.6)
24876
      * (if it is a complex type definition),
24877
      * or given {disallowed substitutions} as defined in Type
24878
      * Derivation OK (Simple) ($3.14.6) (if it is a simple type
24879
      * definition)."
24880
      *
24881
      * {disallowed substitutions}: the "block" on the element decl.
24882
      * {prohibited substitutions}: the "block" on the type def.
24883
      */
24884
      /*
24885
      * OPTIMIZE TODO: We could map types already evaluated
24886
      * to be validly derived from other types to avoid checking
24887
      * this over and over for the same types.
24888
      */
24889
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24890
0
    (elemDecl->subtypes->flags &
24891
0
        XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24892
0
    set |= SUBSET_EXTENSION;
24893
24894
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24895
0
    (elemDecl->subtypes->flags &
24896
0
        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24897
0
    set |= SUBSET_RESTRICTION;
24898
24899
      /*
24900
      * REMOVED and CHANGED since this produced a parser context
24901
      * which adds to the string dict of the schema. So this would
24902
      * change the schema and we don't want this. We don't need
24903
      * the parser context anymore.
24904
      *
24905
      * if ((vctxt->pctxt == NULL) &&
24906
      * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24907
      *     return (-1);
24908
      */
24909
24910
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24911
0
    elemDecl->subtypes, set) != 0) {
24912
0
    xmlChar *str = NULL;
24913
24914
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24915
0
        XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24916
0
        "The type definition '%s', specified by xsi:type, is "
24917
0
        "blocked or not validly derived from the type definition "
24918
0
        "of the element declaration",
24919
0
        xmlSchemaFormatQName(&str,
24920
0
      (*localType)->targetNamespace,
24921
0
      (*localType)->name),
24922
0
        NULL);
24923
0
    FREE_AND_NULL(str);
24924
0
    ret = vctxt->err;
24925
0
    *localType = NULL;
24926
0
      }
24927
0
  }
24928
0
    }
24929
0
exit:
24930
0
    ACTIVATE_ELEM;
24931
0
    return (ret);
24932
0
internal_error:
24933
0
    ACTIVATE_ELEM;
24934
0
    return (-1);
24935
0
}
24936
24937
static int
24938
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24939
0
{
24940
0
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24941
0
    xmlSchemaTypePtr actualType;
24942
24943
    /*
24944
    * cvc-elt (3.3.4) : 1
24945
    */
24946
0
    if (elemDecl == NULL) {
24947
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24948
0
      "No matching declaration available");
24949
0
        return (vctxt->err);
24950
0
    }
24951
0
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
24952
    /*
24953
    * cvc-elt (3.3.4) : 2
24954
    */
24955
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24956
0
  VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24957
0
      "The element declaration is abstract");
24958
0
        return (vctxt->err);
24959
0
    }
24960
0
    if (actualType == NULL) {
24961
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24962
0
      "The type definition is absent");
24963
0
  return (XML_SCHEMAV_CVC_TYPE_1);
24964
0
    }
24965
0
    if (vctxt->nbAttrInfos != 0) {
24966
0
  int ret;
24967
0
  xmlSchemaAttrInfoPtr iattr;
24968
  /*
24969
  * cvc-elt (3.3.4) : 3
24970
  * Handle 'xsi:nil'.
24971
  */
24972
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
24973
0
      XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
24974
0
  if (iattr) {
24975
0
      ACTIVATE_ATTRIBUTE(iattr);
24976
      /*
24977
      * Validate the value.
24978
      */
24979
0
      ret = xmlSchemaVCheckCVCSimpleType(
24980
0
    ACTXT_CAST vctxt, NULL,
24981
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
24982
0
    iattr->value, &(iattr->val), 1, 0, 0);
24983
0
      ACTIVATE_ELEM;
24984
0
      if (ret < 0) {
24985
0
    VERROR_INT("xmlSchemaValidateElemDecl",
24986
0
        "calling xmlSchemaVCheckCVCSimpleType() to "
24987
0
        "validate the attribute 'xsi:nil'");
24988
0
    return (-1);
24989
0
      }
24990
0
      if (ret == 0) {
24991
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
24992
        /*
24993
        * cvc-elt (3.3.4) : 3.1
24994
        */
24995
0
        VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
24996
0
      "The element is not 'nillable'");
24997
        /* Does not return an error on purpose. */
24998
0
    } else {
24999
0
        if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25000
      /*
25001
      * cvc-elt (3.3.4) : 3.2.2
25002
      */
25003
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25004
0
          (elemDecl->value != NULL)) {
25005
0
          VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25006
0
        "The element cannot be 'nilled' because "
25007
0
        "there is a fixed value constraint defined "
25008
0
        "for it");
25009
           /* Does not return an error on purpose. */
25010
0
      } else
25011
0
          vctxt->inode->flags |=
25012
0
        XML_SCHEMA_ELEM_INFO_NILLED;
25013
0
        }
25014
0
    }
25015
0
      }
25016
0
  }
25017
  /*
25018
  * cvc-elt (3.3.4) : 4
25019
  * Handle 'xsi:type'.
25020
  */
25021
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25022
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25023
0
  if (iattr) {
25024
0
      xmlSchemaTypePtr localType = NULL;
25025
25026
0
      ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25027
0
    elemDecl);
25028
0
      if (ret != 0) {
25029
0
    if (ret == -1) {
25030
0
        VERROR_INT("xmlSchemaValidateElemDecl",
25031
0
      "calling xmlSchemaProcessXSIType() to "
25032
0
      "process the attribute 'xsi:type'");
25033
0
        return (-1);
25034
0
    }
25035
    /* Does not return an error on purpose. */
25036
0
      }
25037
0
      if (localType != NULL) {
25038
0
    vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25039
0
    actualType = localType;
25040
0
      }
25041
0
  }
25042
0
    }
25043
    /*
25044
    * IDC: Register identity-constraint XPath matchers.
25045
    */
25046
0
    if ((elemDecl->idcs != NULL) &&
25047
0
  (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25048
0
      return (-1);
25049
    /*
25050
    * No actual type definition.
25051
    */
25052
0
    if (actualType == NULL) {
25053
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25054
0
      "The type definition is absent");
25055
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25056
0
    }
25057
    /*
25058
    * Remember the actual type definition.
25059
    */
25060
0
    vctxt->inode->typeDef = actualType;
25061
25062
0
    return (0);
25063
0
}
25064
25065
static int
25066
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25067
0
{
25068
0
    xmlSchemaAttrInfoPtr iattr;
25069
0
    int ret = 0, i;
25070
25071
    /*
25072
    * SPEC cvc-type (3.1.1)
25073
    * "The attributes of must be empty, excepting those whose namespace
25074
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25075
    * whose local name is one of type, nil, schemaLocation or
25076
    * noNamespaceSchemaLocation."
25077
    */
25078
0
    if (vctxt->nbAttrInfos == 0)
25079
0
  return (0);
25080
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25081
0
  iattr = vctxt->attrInfos[i];
25082
0
  if (! iattr->metaType) {
25083
0
      ACTIVATE_ATTRIBUTE(iattr)
25084
0
      xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25085
0
    XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25086
0
      ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25087
0
        }
25088
0
    }
25089
0
    ACTIVATE_ELEM
25090
0
    return (ret);
25091
0
}
25092
25093
/*
25094
* Cleanup currently used attribute infos.
25095
*/
25096
static void
25097
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25098
0
{
25099
0
    int i;
25100
0
    xmlSchemaAttrInfoPtr attr;
25101
25102
0
    if (vctxt->nbAttrInfos == 0)
25103
0
  return;
25104
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25105
0
  attr = vctxt->attrInfos[i];
25106
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25107
0
      if (attr->localName != NULL)
25108
0
    xmlFree((xmlChar *) attr->localName);
25109
0
      if (attr->nsName != NULL)
25110
0
    xmlFree((xmlChar *) attr->nsName);
25111
0
  }
25112
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25113
0
      if (attr->value != NULL)
25114
0
    xmlFree((xmlChar *) attr->value);
25115
0
  }
25116
0
  if (attr->val != NULL) {
25117
0
      xmlSchemaFreeValue(attr->val);
25118
0
      attr->val = NULL;
25119
0
  }
25120
0
  memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25121
0
    }
25122
0
    vctxt->nbAttrInfos = 0;
25123
0
}
25124
25125
/*
25126
* 3.4.4 Complex Type Definition Validation Rules
25127
*   Element Locally Valid (Complex Type) (cvc-complex-type)
25128
* 3.2.4 Attribute Declaration Validation Rules
25129
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
25130
*   Attribute Locally Valid (Use) (cvc-au)
25131
*
25132
* Only "assessed" attribute information items will be visible to
25133
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25134
*/
25135
static int
25136
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25137
0
{
25138
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef;
25139
0
    xmlSchemaItemListPtr attrUseList;
25140
0
    xmlSchemaAttributeUsePtr attrUse = NULL;
25141
0
    xmlSchemaAttributePtr attrDecl = NULL;
25142
0
    xmlSchemaAttrInfoPtr iattr, tmpiattr;
25143
0
    int i, j, found, nbAttrs, nbUses;
25144
0
    int xpathRes = 0, res, wildIDs = 0, fixed;
25145
0
    xmlNodePtr defAttrOwnerElem = NULL;
25146
25147
    /*
25148
    * SPEC (cvc-attribute)
25149
    * (1) "The declaration must not be `absent` (see Missing
25150
    * Sub-components ($5.3) for how this can fail to be
25151
    * the case)."
25152
    * (2) "Its {type definition} must not be absent."
25153
    *
25154
    * NOTE (1) + (2): This is not handled here, since we currently do not
25155
    * allow validation against schemas which have missing sub-components.
25156
    *
25157
    * SPEC (cvc-complex-type)
25158
    * (3) "For each attribute information item in the element information
25159
    * item's [attributes] excepting those whose [namespace name] is
25160
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25161
    * [local name] is one of type, nil, schemaLocation or
25162
    * noNamespaceSchemaLocation, the appropriate case among the following
25163
    * must be true:
25164
    *
25165
    */
25166
0
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25167
    /*
25168
    * @nbAttrs is the number of attributes present in the instance.
25169
    */
25170
0
    nbAttrs = vctxt->nbAttrInfos;
25171
0
    if (attrUseList != NULL)
25172
0
  nbUses = attrUseList->nbItems;
25173
0
    else
25174
0
  nbUses = 0;
25175
0
    for (i = 0; i < nbUses; i++) {
25176
0
        found = 0;
25177
0
  attrUse = attrUseList->items[i];
25178
0
  attrDecl = WXS_ATTRUSE_DECL(attrUse);
25179
0
        for (j = 0; j < nbAttrs; j++) {
25180
0
      iattr = vctxt->attrInfos[j];
25181
      /*
25182
      * SPEC (cvc-complex-type) (3)
25183
      * Skip meta attributes.
25184
      */
25185
0
      if (iattr->metaType)
25186
0
    continue;
25187
0
      if (iattr->localName[0] != attrDecl->name[0])
25188
0
    continue;
25189
0
      if (!xmlStrEqual(iattr->localName, attrDecl->name))
25190
0
    continue;
25191
0
      if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25192
0
    continue;
25193
0
      found = 1;
25194
      /*
25195
      * SPEC (cvc-complex-type)
25196
      * (3.1) "If there is among the {attribute uses} an attribute
25197
      * use with an {attribute declaration} whose {name} matches
25198
      * the attribute information item's [local name] and whose
25199
      * {target namespace} is identical to the attribute information
25200
      * item's [namespace name] (where an `absent` {target namespace}
25201
      * is taken to be identical to a [namespace name] with no value),
25202
      * then the attribute information must be `valid` with respect
25203
      * to that attribute use as per Attribute Locally Valid (Use)
25204
      * ($3.5.4). In this case the {attribute declaration} of that
25205
      * attribute use is the `context-determined declaration` for the
25206
      * attribute information item with respect to Schema-Validity
25207
      * Assessment (Attribute) ($3.2.4) and
25208
      * Assessment Outcome (Attribute) ($3.2.5).
25209
      */
25210
0
      iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25211
0
      iattr->use = attrUse;
25212
      /*
25213
      * Context-determined declaration.
25214
      */
25215
0
      iattr->decl = attrDecl;
25216
0
      iattr->typeDef = attrDecl->subtypes;
25217
0
      break;
25218
0
  }
25219
25220
0
  if (found)
25221
0
      continue;
25222
25223
0
  if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25224
      /*
25225
      * Handle non-existent, required attributes.
25226
      *
25227
      * SPEC (cvc-complex-type)
25228
      * (4) "The {attribute declaration} of each attribute use in
25229
      * the {attribute uses} whose {required} is true matches one
25230
      * of the attribute information items in the element information
25231
      * item's [attributes] as per clause 3.1 above."
25232
      */
25233
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25234
0
      if (tmpiattr == NULL) {
25235
0
    VERROR_INT(
25236
0
        "xmlSchemaVAttributesComplex",
25237
0
        "calling xmlSchemaGetFreshAttrInfo()");
25238
0
    return (-1);
25239
0
      }
25240
0
      tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25241
0
      tmpiattr->use = attrUse;
25242
0
      tmpiattr->decl = attrDecl;
25243
0
  } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25244
0
      ((attrUse->defValue != NULL) ||
25245
0
       (attrDecl->defValue != NULL))) {
25246
      /*
25247
      * Handle non-existent, optional, default/fixed attributes.
25248
      */
25249
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25250
0
      if (tmpiattr == NULL) {
25251
0
    VERROR_INT(
25252
0
        "xmlSchemaVAttributesComplex",
25253
0
        "calling xmlSchemaGetFreshAttrInfo()");
25254
0
    return (-1);
25255
0
      }
25256
0
      tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25257
0
      tmpiattr->use = attrUse;
25258
0
      tmpiattr->decl = attrDecl;
25259
0
      tmpiattr->typeDef = attrDecl->subtypes;
25260
0
      tmpiattr->localName = attrDecl->name;
25261
0
      tmpiattr->nsName = attrDecl->targetNamespace;
25262
0
  }
25263
0
    }
25264
25265
0
    if (vctxt->nbAttrInfos == 0)
25266
0
  return (0);
25267
    /*
25268
    * Validate against the wildcard.
25269
    */
25270
0
    if (type->attributeWildcard != NULL) {
25271
  /*
25272
  * SPEC (cvc-complex-type)
25273
  * (3.2.1) "There must be an {attribute wildcard}."
25274
  */
25275
0
  for (i = 0; i < nbAttrs; i++) {
25276
0
      iattr = vctxt->attrInfos[i];
25277
      /*
25278
      * SPEC (cvc-complex-type) (3)
25279
      * Skip meta attributes.
25280
      */
25281
0
      if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25282
0
    continue;
25283
      /*
25284
      * SPEC (cvc-complex-type)
25285
      * (3.2.2) "The attribute information item must be `valid` with
25286
      * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25287
      *
25288
      * SPEC Item Valid (Wildcard) (cvc-wildcard)
25289
      * "... its [namespace name] must be `valid` with respect to
25290
      * the wildcard constraint, as defined in Wildcard allows
25291
      * Namespace Name ($3.10.4)."
25292
      */
25293
0
      if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25294
0
        iattr->nsName) == 0) {
25295
    /*
25296
    * Handle processContents.
25297
    *
25298
    * SPEC (cvc-wildcard):
25299
    * processContents | context-determined declaration:
25300
    * "strict"          "mustFind"
25301
    * "lax"             "none"
25302
    * "skip"            "skip"
25303
    */
25304
0
    if (type->attributeWildcard->processContents ==
25305
0
        XML_SCHEMAS_ANY_SKIP) {
25306
         /*
25307
        * context-determined declaration = "skip"
25308
        *
25309
        * SPEC PSVI Assessment Outcome (Attribute)
25310
        * [validity] = "notKnown"
25311
        * [validation attempted] = "none"
25312
        */
25313
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25314
0
        continue;
25315
0
    }
25316
    /*
25317
    * Find an attribute declaration.
25318
    */
25319
0
    iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25320
0
        iattr->localName, iattr->nsName);
25321
0
    if (iattr->decl != NULL) {
25322
0
        iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25323
        /*
25324
        * SPEC (cvc-complex-type)
25325
        * (5) "Let [Definition:]  the wild IDs be the set of
25326
        * all attribute information item to which clause 3.2
25327
        * applied and whose `validation` resulted in a
25328
        * `context-determined declaration` of mustFind or no
25329
        * `context-determined declaration` at all, and whose
25330
        * [local name] and [namespace name] resolve (as
25331
        * defined by QName resolution (Instance) ($3.15.4)) to
25332
        * an attribute declaration whose {type definition} is
25333
        * or is derived from ID. Then all of the following
25334
        * must be true:"
25335
        */
25336
0
        iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25337
0
        if (xmlSchemaIsDerivedFromBuiltInType(
25338
0
      iattr->typeDef, XML_SCHEMAS_ID)) {
25339
      /*
25340
      * SPEC (5.1) "There must be no more than one
25341
      * item in `wild IDs`."
25342
      */
25343
0
      if (wildIDs != 0) {
25344
          /* VAL TODO */
25345
0
          iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25346
0
          continue;
25347
0
      }
25348
0
      wildIDs++;
25349
      /*
25350
      * SPEC (cvc-complex-type)
25351
      * (5.2) "If `wild IDs` is non-empty, there must not
25352
      * be any attribute uses among the {attribute uses}
25353
      * whose {attribute declaration}'s {type definition}
25354
      * is or is derived from ID."
25355
      */
25356
0
                        if (attrUseList != NULL) {
25357
0
                            for (j = 0; j < attrUseList->nbItems; j++) {
25358
0
                                if (xmlSchemaIsDerivedFromBuiltInType(
25359
0
                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25360
0
                                    XML_SCHEMAS_ID)) {
25361
                                    /* URGENT VAL TODO: implement */
25362
0
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25363
0
                                    break;
25364
0
                                }
25365
0
                            }
25366
0
                        }
25367
0
        }
25368
0
    } else if (type->attributeWildcard->processContents ==
25369
0
        XML_SCHEMAS_ANY_LAX) {
25370
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25371
        /*
25372
        * SPEC PSVI Assessment Outcome (Attribute)
25373
        * [validity] = "notKnown"
25374
        * [validation attempted] = "none"
25375
        */
25376
0
    } else {
25377
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25378
0
    }
25379
0
      }
25380
0
  }
25381
0
    }
25382
25383
0
    if (vctxt->nbAttrInfos == 0)
25384
0
  return (0);
25385
25386
    /*
25387
    * Get the owner element; needed for creation of default attributes.
25388
    * This fixes bug #341337, reported by David Grohmann.
25389
    */
25390
0
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25391
0
  xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25392
0
  if (ielem && ielem->node && ielem->node->doc)
25393
0
      defAttrOwnerElem = ielem->node;
25394
0
    }
25395
    /*
25396
    * Validate values, create default attributes, evaluate IDCs.
25397
    */
25398
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25399
0
  iattr = vctxt->attrInfos[i];
25400
  /*
25401
  * VAL TODO: Note that we won't try to resolve IDCs to
25402
  * "lax" and "skip" validated attributes. Check what to
25403
  * do in this case.
25404
  */
25405
0
  if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25406
0
      (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25407
0
      continue;
25408
  /*
25409
  * VAL TODO: What to do if the type definition is missing?
25410
  */
25411
0
  if (iattr->typeDef == NULL) {
25412
0
      iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25413
0
      continue;
25414
0
  }
25415
25416
0
  ACTIVATE_ATTRIBUTE(iattr);
25417
0
  fixed = 0;
25418
0
  xpathRes = 0;
25419
25420
0
  if (vctxt->xpathStates != NULL) {
25421
      /*
25422
      * Evaluate IDCs.
25423
      */
25424
0
      xpathRes = xmlSchemaXPathEvaluate(vctxt,
25425
0
    XML_ATTRIBUTE_NODE);
25426
0
      if (xpathRes == -1) {
25427
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25428
0
        "calling xmlSchemaXPathEvaluate()");
25429
0
    goto internal_error;
25430
0
      }
25431
0
  }
25432
25433
0
  if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25434
      /*
25435
      * Default/fixed attributes.
25436
      * We need the value only if we need to resolve IDCs or
25437
      * will create default attributes.
25438
      */
25439
0
      if ((xpathRes) || (defAttrOwnerElem)) {
25440
0
    if (iattr->use->defValue != NULL) {
25441
0
        iattr->value = (xmlChar *) iattr->use->defValue;
25442
0
        iattr->val = iattr->use->defVal;
25443
0
    } else {
25444
0
        iattr->value = (xmlChar *) iattr->decl->defValue;
25445
0
        iattr->val = iattr->decl->defVal;
25446
0
    }
25447
    /*
25448
    * IDCs will consume the precomputed default value,
25449
    * so we need to clone it.
25450
    */
25451
0
    if (iattr->val == NULL) {
25452
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25453
0
      "default/fixed value on an attribute use was "
25454
0
      "not precomputed");
25455
0
        goto internal_error;
25456
0
    }
25457
0
    iattr->val = xmlSchemaCopyValue(iattr->val);
25458
0
    if (iattr->val == NULL) {
25459
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25460
0
      "calling xmlSchemaCopyValue()");
25461
0
        goto internal_error;
25462
0
    }
25463
0
      }
25464
      /*
25465
      * PSVI: Add the default attribute to the current element.
25466
      * VAL TODO: Should we use the *normalized* value? This currently
25467
      *   uses the *initial* value.
25468
      */
25469
25470
0
      if (defAttrOwnerElem) {
25471
0
    xmlChar *normValue;
25472
0
    const xmlChar *value;
25473
25474
0
    value = iattr->value;
25475
    /*
25476
    * Normalize the value.
25477
    */
25478
0
    normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25479
0
        iattr->value);
25480
0
    if (normValue != NULL)
25481
0
        value = BAD_CAST normValue;
25482
25483
0
    if (iattr->nsName == NULL) {
25484
0
        if (xmlNewProp(defAttrOwnerElem,
25485
0
      iattr->localName, value) == NULL) {
25486
0
      VERROR_INT("xmlSchemaVAttributesComplex",
25487
0
          "calling xmlNewProp()");
25488
0
      if (normValue != NULL)
25489
0
          xmlFree(normValue);
25490
0
      goto internal_error;
25491
0
        }
25492
0
    } else {
25493
0
        xmlNsPtr ns;
25494
25495
0
        ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25496
0
      defAttrOwnerElem, iattr->nsName);
25497
0
        if (ns == NULL) {
25498
0
      xmlChar prefix[12];
25499
0
      int counter = 0;
25500
25501
      /*
25502
      * Create a namespace declaration on the validation
25503
      * root node if no namespace declaration is in scope.
25504
      */
25505
0
      do {
25506
0
          snprintf((char *) prefix, 12, "p%d", counter++);
25507
0
          ns = xmlSearchNs(defAttrOwnerElem->doc,
25508
0
        defAttrOwnerElem, BAD_CAST prefix);
25509
0
          if (counter > 1000) {
25510
0
        VERROR_INT(
25511
0
            "xmlSchemaVAttributesComplex",
25512
0
            "could not compute a ns prefix for a "
25513
0
            "default/fixed attribute");
25514
0
        if (normValue != NULL)
25515
0
            xmlFree(normValue);
25516
0
        goto internal_error;
25517
0
          }
25518
0
      } while (ns != NULL);
25519
0
      ns = xmlNewNs(vctxt->validationRoot,
25520
0
          iattr->nsName, BAD_CAST prefix);
25521
0
        }
25522
        /*
25523
        * TODO:
25524
        * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25525
        * If we have QNames: do we need to ensure there's a
25526
        * prefix defined for the QName?
25527
        */
25528
0
        xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25529
0
    }
25530
0
    if (normValue != NULL)
25531
0
        xmlFree(normValue);
25532
0
      }
25533
      /*
25534
      * Go directly to IDC evaluation.
25535
      */
25536
0
      goto eval_idcs;
25537
0
  }
25538
  /*
25539
  * Validate the value.
25540
  */
25541
0
  if (vctxt->value != NULL) {
25542
      /*
25543
      * Free last computed value; just for safety reasons.
25544
      */
25545
0
      xmlSchemaFreeValue(vctxt->value);
25546
0
      vctxt->value = NULL;
25547
0
  }
25548
  /*
25549
  * Note that the attribute *use* can be unavailable, if
25550
  * the attribute was a wild attribute.
25551
  */
25552
0
  if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25553
0
      ((iattr->use != NULL) &&
25554
0
       (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25555
0
      fixed = 1;
25556
0
  else
25557
0
      fixed = 0;
25558
  /*
25559
  * SPEC (cvc-attribute)
25560
  * (3) "The item's `normalized value` must be locally `valid`
25561
  * with respect to that {type definition} as per
25562
  * String Valid ($3.14.4)."
25563
  *
25564
  * VAL TODO: Do we already have the
25565
  * "normalized attribute value" here?
25566
  */
25567
0
  if (xpathRes || fixed) {
25568
0
      iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25569
      /*
25570
      * Request a computed value.
25571
      */
25572
0
      res = xmlSchemaVCheckCVCSimpleType(
25573
0
    ACTXT_CAST vctxt,
25574
0
    iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25575
0
    1, 1, 0);
25576
0
  } else {
25577
0
      res = xmlSchemaVCheckCVCSimpleType(
25578
0
    ACTXT_CAST vctxt,
25579
0
    iattr->node, iattr->typeDef, iattr->value, NULL,
25580
0
    1, 0, 0);
25581
0
  }
25582
25583
0
  if (res != 0) {
25584
0
      if (res == -1) {
25585
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25586
0
        "calling xmlSchemaStreamValidateSimpleTypeValue()");
25587
0
    goto internal_error;
25588
0
      }
25589
0
      iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25590
      /*
25591
      * SPEC PSVI Assessment Outcome (Attribute)
25592
      * [validity] = "invalid"
25593
      */
25594
0
      goto eval_idcs;
25595
0
  }
25596
25597
0
  if (fixed) {
25598
      /*
25599
      * SPEC Attribute Locally Valid (Use) (cvc-au)
25600
      * "For an attribute information item to be `valid`
25601
      * with respect to an attribute use its *normalized*
25602
      * value must match the *canonical* lexical
25603
      * representation of the attribute use's {value
25604
      * constraint}value, if it is present and fixed."
25605
      *
25606
      * VAL TODO: The requirement for the *canonical* value
25607
      * will be removed in XML Schema 1.1.
25608
      */
25609
      /*
25610
      * SPEC Attribute Locally Valid (cvc-attribute)
25611
      * (4) "The item's *actual* value must match the *value* of
25612
      * the {value constraint}, if it is present and fixed."
25613
      */
25614
0
      if (iattr->val == NULL) {
25615
    /* VAL TODO: A value was not precomputed. */
25616
0
    goto eval_idcs;
25617
0
      }
25618
0
      if ((iattr->use != NULL) &&
25619
0
    (iattr->use->defValue != NULL)) {
25620
0
    if (iattr->use->defVal == NULL) {
25621
        /* VAL TODO: A default value was not precomputed. */
25622
0
        goto eval_idcs;
25623
0
    }
25624
0
    iattr->vcValue = iattr->use->defValue;
25625
    /*
25626
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25627
        (xmlSchemaWhitespaceValueType) ws,
25628
        attr->use->defVal,
25629
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25630
    */
25631
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25632
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25633
0
      } else {
25634
0
    if (iattr->decl->defVal == NULL) {
25635
        /* VAL TODO: A default value was not precomputed. */
25636
0
        goto eval_idcs;
25637
0
    }
25638
0
    iattr->vcValue = iattr->decl->defValue;
25639
    /*
25640
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25641
        (xmlSchemaWhitespaceValueType) ws,
25642
        attrDecl->defVal,
25643
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25644
    */
25645
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25646
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25647
0
      }
25648
      /*
25649
      * [validity] = "valid"
25650
      */
25651
0
  }
25652
0
eval_idcs:
25653
  /*
25654
  * Evaluate IDCs.
25655
  */
25656
0
  if (xpathRes) {
25657
0
      if (xmlSchemaXPathProcessHistory(vctxt,
25658
0
    vctxt->depth +1) == -1) {
25659
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25660
0
        "calling xmlSchemaXPathEvaluate()");
25661
0
    goto internal_error;
25662
0
      }
25663
0
  } else if (vctxt->xpathStates != NULL)
25664
0
      xmlSchemaXPathPop(vctxt);
25665
0
    }
25666
25667
    /*
25668
    * Report errors.
25669
    */
25670
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25671
0
  iattr = vctxt->attrInfos[i];
25672
0
  if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25673
0
      (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25674
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25675
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25676
0
      continue;
25677
0
  ACTIVATE_ATTRIBUTE(iattr);
25678
0
  switch (iattr->state) {
25679
0
      case XML_SCHEMAS_ATTR_ERR_MISSING: {
25680
0
        xmlChar *str = NULL;
25681
0
        ACTIVATE_ELEM;
25682
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
25683
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25684
0
      "The attribute '%s' is required but missing",
25685
0
      xmlSchemaFormatQName(&str,
25686
0
          iattr->decl->targetNamespace,
25687
0
          iattr->decl->name),
25688
0
      NULL);
25689
0
        FREE_AND_NULL(str)
25690
0
        break;
25691
0
    }
25692
0
      case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25693
0
    VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25694
0
        "The type definition is absent");
25695
0
    break;
25696
0
      case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25697
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25698
0
        XML_SCHEMAV_CVC_AU, NULL, NULL,
25699
0
        "The value '%s' does not match the fixed "
25700
0
        "value constraint '%s'",
25701
0
        iattr->value, iattr->vcValue);
25702
0
    break;
25703
0
      case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25704
0
    VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25705
0
        "No matching global attribute declaration available, but "
25706
0
        "demanded by the strict wildcard");
25707
0
    break;
25708
0
      case XML_SCHEMAS_ATTR_UNKNOWN:
25709
0
    if (iattr->metaType)
25710
0
        break;
25711
    /*
25712
    * MAYBE VAL TODO: One might report different error messages
25713
    * for the following errors.
25714
    */
25715
0
    if (type->attributeWildcard == NULL) {
25716
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25717
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25718
0
    } else {
25719
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25720
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25721
0
    }
25722
0
    break;
25723
0
      default:
25724
0
    break;
25725
0
  }
25726
0
    }
25727
25728
0
    ACTIVATE_ELEM;
25729
0
    return (0);
25730
0
internal_error:
25731
0
    ACTIVATE_ELEM;
25732
0
    return (-1);
25733
0
}
25734
25735
static int
25736
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25737
            int *skip)
25738
0
{
25739
0
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25740
    /*
25741
    * The namespace of the element was already identified to be
25742
    * matching the wildcard.
25743
    */
25744
0
    if ((skip == NULL) || (wild == NULL) ||
25745
0
  (wild->type != XML_SCHEMA_TYPE_ANY)) {
25746
0
  VERROR_INT("xmlSchemaValidateElemWildcard",
25747
0
      "bad arguments");
25748
0
  return (-1);
25749
0
    }
25750
0
    *skip = 0;
25751
0
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25752
  /*
25753
  * URGENT VAL TODO: Either we need to position the stream to the
25754
  * next sibling, or walk the whole subtree.
25755
  */
25756
0
  *skip = 1;
25757
0
  return (0);
25758
0
    }
25759
0
    {
25760
0
  xmlSchemaElementPtr decl = NULL;
25761
25762
0
  decl = xmlSchemaGetElem(vctxt->schema,
25763
0
      vctxt->inode->localName, vctxt->inode->nsName);
25764
0
  if (decl != NULL) {
25765
0
      vctxt->inode->decl = decl;
25766
0
      return (0);
25767
0
  }
25768
0
    }
25769
0
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25770
  /* VAL TODO: Change to proper error code. */
25771
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25772
0
      "No matching global element declaration available, but "
25773
0
      "demanded by the strict wildcard");
25774
0
  return (vctxt->err);
25775
0
    }
25776
0
    if (vctxt->nbAttrInfos != 0) {
25777
0
  xmlSchemaAttrInfoPtr iattr;
25778
  /*
25779
  * SPEC Validation Rule: Schema-Validity Assessment (Element)
25780
  * (1.2.1.2.1) - (1.2.1.2.3 )
25781
  *
25782
  * Use the xsi:type attribute for the type definition.
25783
  */
25784
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25785
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25786
0
  if (iattr != NULL) {
25787
0
      if (xmlSchemaProcessXSIType(vctxt, iattr,
25788
0
    &(vctxt->inode->typeDef), NULL) == -1) {
25789
0
    VERROR_INT("xmlSchemaValidateElemWildcard",
25790
0
        "calling xmlSchemaProcessXSIType() to "
25791
0
        "process the attribute 'xsi:nil'");
25792
0
    return (-1);
25793
0
      }
25794
      /*
25795
      * Don't return an error on purpose.
25796
      */
25797
0
      return (0);
25798
0
  }
25799
0
    }
25800
    /*
25801
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
25802
    *
25803
    * Fallback to "anyType".
25804
    */
25805
0
    vctxt->inode->typeDef =
25806
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25807
0
    return (0);
25808
0
}
25809
25810
/*
25811
* xmlSchemaCheckCOSValidDefault:
25812
*
25813
* This will be called if: not nilled, no content and a default/fixed
25814
* value is provided.
25815
*/
25816
25817
static int
25818
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25819
            const xmlChar *value,
25820
            xmlSchemaValPtr *val)
25821
0
{
25822
0
    int ret = 0;
25823
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25824
25825
    /*
25826
    * cos-valid-default:
25827
    * Schema Component Constraint: Element Default Valid (Immediate)
25828
    * For a string to be a valid default with respect to a type
25829
    * definition the appropriate case among the following must be true:
25830
    */
25831
0
    if WXS_IS_COMPLEX(inode->typeDef) {
25832
  /*
25833
  * Complex type.
25834
  *
25835
  * SPEC (2.1) "its {content type} must be a simple type definition
25836
  * or mixed."
25837
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
25838
  * type}'s particle must be `emptiable` as defined by
25839
  * Particle Emptiable ($3.9.6)."
25840
  */
25841
0
  if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25842
0
      ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25843
0
       (! WXS_EMPTIABLE(inode->typeDef)))) {
25844
0
      ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25845
      /* NOTE that this covers (2.2.2) as well. */
25846
0
      VERROR(ret, NULL,
25847
0
    "For a string to be a valid default, the type definition "
25848
0
    "must be a simple type or a complex type with simple content "
25849
0
    "or mixed content and a particle emptiable");
25850
0
      return(ret);
25851
0
  }
25852
0
    }
25853
    /*
25854
    * 1 If the type definition is a simple type definition, then the string
25855
    * must be `valid` with respect to that definition as defined by String
25856
    * Valid ($3.14.4).
25857
    *
25858
    * AND
25859
    *
25860
    * 2.2.1 If the {content type} is a simple type definition, then the
25861
    * string must be `valid` with respect to that simple type definition
25862
    * as defined by String Valid ($3.14.4).
25863
    */
25864
0
    if (WXS_IS_SIMPLE(inode->typeDef)) {
25865
25866
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25867
0
      NULL, inode->typeDef, value, val, 1, 1, 0);
25868
25869
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25870
25871
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25872
0
      NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25873
0
    }
25874
0
    if (ret < 0) {
25875
0
  VERROR_INT("xmlSchemaCheckCOSValidDefault",
25876
0
      "calling xmlSchemaVCheckCVCSimpleType()");
25877
0
    }
25878
0
    return (ret);
25879
0
}
25880
25881
static void
25882
xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
25883
             const xmlChar * name ATTRIBUTE_UNUSED,
25884
             void *transdata, void *inputdata)
25885
0
{
25886
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
25887
0
    xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
25888
0
    inode->decl = item;
25889
0
}
25890
25891
static int
25892
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25893
0
{
25894
0
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25895
0
    if (vctxt->inode == NULL) {
25896
0
  VERROR_INT("xmlSchemaValidatorPushElem",
25897
0
      "calling xmlSchemaGetFreshElemInfo()");
25898
0
  return (-1);
25899
0
    }
25900
0
    vctxt->nbAttrInfos = 0;
25901
0
    return (0);
25902
0
}
25903
25904
static int
25905
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25906
           xmlSchemaNodeInfoPtr inode,
25907
           xmlSchemaTypePtr type,
25908
           const xmlChar *value)
25909
0
{
25910
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25911
0
  return (xmlSchemaVCheckCVCSimpleType(
25912
0
      ACTXT_CAST vctxt, NULL,
25913
0
      type, value, &(inode->val), 1, 1, 0));
25914
0
    else
25915
0
  return (xmlSchemaVCheckCVCSimpleType(
25916
0
      ACTXT_CAST vctxt, NULL,
25917
0
      type, value, NULL, 1, 0, 0));
25918
0
}
25919
25920
25921
25922
/*
25923
* Process END of element.
25924
*/
25925
static int
25926
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25927
0
{
25928
0
    int ret = 0;
25929
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25930
25931
0
    if (vctxt->nbAttrInfos != 0)
25932
0
  xmlSchemaClearAttrInfos(vctxt);
25933
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25934
  /*
25935
  * This element was not expected;
25936
  * we will not validate child elements of broken parents.
25937
  * Skip validation of all content of the parent.
25938
  */
25939
0
  vctxt->skipDepth = vctxt->depth -1;
25940
0
  goto end_elem;
25941
0
    }
25942
0
    if ((inode->typeDef == NULL) ||
25943
0
  (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25944
  /*
25945
  * 1. the type definition might be missing if the element was
25946
  *    error prone
25947
  * 2. it might be abstract.
25948
  */
25949
0
  goto end_elem;
25950
0
    }
25951
    /*
25952
    * Check the content model.
25953
    */
25954
0
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
25955
0
  (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
25956
25957
  /*
25958
  * Workaround for "anyType".
25959
  */
25960
0
  if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
25961
0
      goto character_content;
25962
25963
0
  if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
25964
0
      xmlChar *values[10];
25965
0
      int terminal, nbval = 10, nbneg;
25966
25967
0
      if (inode->regexCtxt == NULL) {
25968
    /*
25969
    * Create the regex context.
25970
    */
25971
0
    inode->regexCtxt =
25972
0
        xmlRegNewExecCtxt(inode->typeDef->contModel,
25973
0
        xmlSchemaVContentModelCallback, vctxt);
25974
0
    if (inode->regexCtxt == NULL) {
25975
0
        VERROR_INT("xmlSchemaValidatorPopElem",
25976
0
      "failed to create a regex context");
25977
0
        goto internal_error;
25978
0
    }
25979
0
      }
25980
25981
      /*
25982
       * Do not check further content if the node has been nilled
25983
       */
25984
0
      if (INODE_NILLED(inode)) {
25985
0
    ret = 0;
25986
0
                goto skip_nilled;
25987
0
      }
25988
25989
      /*
25990
      * Get hold of the still expected content, since a further
25991
      * call to xmlRegExecPushString() will lose this information.
25992
      */
25993
0
      xmlRegExecNextValues(inode->regexCtxt,
25994
0
    &nbval, &nbneg, &values[0], &terminal);
25995
0
      ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
25996
0
      if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
25997
    /*
25998
    * Still missing something.
25999
    */
26000
0
    ret = 1;
26001
0
    inode->flags |=
26002
0
        XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26003
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26004
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26005
0
        "Missing child element(s)",
26006
0
        nbval, nbneg, values);
26007
0
      } else {
26008
    /*
26009
    * Content model is satisfied.
26010
    */
26011
0
    ret = 0;
26012
0
      }
26013
26014
0
  }
26015
0
    }
26016
26017
0
skip_nilled:
26018
26019
0
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26020
0
  goto end_elem;
26021
26022
0
character_content:
26023
26024
0
    if (vctxt->value != NULL) {
26025
0
  xmlSchemaFreeValue(vctxt->value);
26026
0
  vctxt->value = NULL;
26027
0
    }
26028
    /*
26029
    * Check character content.
26030
    */
26031
0
    if (inode->decl == NULL) {
26032
  /*
26033
  * Speedup if no declaration exists.
26034
  */
26035
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26036
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26037
0
    inode, inode->typeDef, inode->value);
26038
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26039
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26040
0
    inode, inode->typeDef->contentTypeDef,
26041
0
    inode->value);
26042
0
  }
26043
0
  if (ret < 0) {
26044
0
      VERROR_INT("xmlSchemaValidatorPopElem",
26045
0
    "calling xmlSchemaVCheckCVCSimpleType()");
26046
0
      goto internal_error;
26047
0
  }
26048
0
  goto end_elem;
26049
0
    }
26050
    /*
26051
    * cvc-elt (3.3.4) : 5
26052
    * The appropriate case among the following must be true:
26053
    */
26054
    /*
26055
    * cvc-elt (3.3.4) : 5.1
26056
    * If the declaration has a {value constraint},
26057
    * the item has neither element nor character [children] and
26058
    * clause 3.2 has not applied, then all of the following must be true:
26059
    */
26060
0
    if ((inode->decl->value != NULL) &&
26061
0
  (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26062
0
  (! INODE_NILLED(inode))) {
26063
  /*
26064
  * cvc-elt (3.3.4) : 5.1.1
26065
  * If the `actual type definition` is a `local type definition`
26066
  * then the canonical lexical representation of the {value constraint}
26067
  * value must be a valid default for the `actual type definition` as
26068
  * defined in Element Default Valid (Immediate) ($3.3.6).
26069
  */
26070
  /*
26071
  * NOTE: 'local' above means types acquired by xsi:type.
26072
  * NOTE: Although the *canonical* value is stated, it is not
26073
  * relevant if canonical or not. Additionally XML Schema 1.1
26074
  * will removed this requirement as well.
26075
  */
26076
0
  if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26077
26078
0
      ret = xmlSchemaCheckCOSValidDefault(vctxt,
26079
0
    inode->decl->value, &(inode->val));
26080
0
      if (ret != 0) {
26081
0
    if (ret < 0) {
26082
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26083
0
      "calling xmlSchemaCheckCOSValidDefault()");
26084
0
        goto internal_error;
26085
0
    }
26086
0
    goto end_elem;
26087
0
      }
26088
      /*
26089
      * Stop here, to avoid redundant validation of the value
26090
      * (see following).
26091
      */
26092
0
      goto default_psvi;
26093
0
  }
26094
  /*
26095
  * cvc-elt (3.3.4) : 5.1.2
26096
  * The element information item with the canonical lexical
26097
  * representation of the {value constraint} value used as its
26098
  * `normalized value` must be `valid` with respect to the
26099
  * `actual type definition` as defined by Element Locally Valid (Type)
26100
  * ($3.3.4).
26101
  */
26102
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26103
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26104
0
    inode, inode->typeDef, inode->decl->value);
26105
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26106
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26107
0
    inode, inode->typeDef->contentTypeDef,
26108
0
    inode->decl->value);
26109
0
  }
26110
0
  if (ret != 0) {
26111
0
      if (ret < 0) {
26112
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26113
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26114
0
    goto internal_error;
26115
0
      }
26116
0
      goto end_elem;
26117
0
  }
26118
26119
0
default_psvi:
26120
  /*
26121
  * PSVI: Create a text node on the instance element.
26122
  */
26123
0
  if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26124
0
      (inode->node != NULL)) {
26125
0
      xmlNodePtr textChild;
26126
0
      xmlChar *normValue;
26127
      /*
26128
      * VAL TODO: Normalize the value.
26129
      */
26130
0
      normValue = xmlSchemaNormalizeValue(inode->typeDef,
26131
0
    inode->decl->value);
26132
0
      if (normValue != NULL) {
26133
0
    textChild = xmlNewDocText(inode->node->doc,
26134
0
                        BAD_CAST normValue);
26135
0
    xmlFree(normValue);
26136
0
      } else
26137
0
    textChild = xmlNewDocText(inode->node->doc,
26138
0
                        inode->decl->value);
26139
0
      if (textChild == NULL) {
26140
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26141
0
        "calling xmlNewDocText()");
26142
0
    goto internal_error;
26143
0
      } else
26144
0
    xmlAddChild(inode->node, textChild);
26145
0
  }
26146
26147
0
    } else if (! INODE_NILLED(inode)) {
26148
  /*
26149
  * 5.2.1 The element information item must be `valid` with respect
26150
  * to the `actual type definition` as defined by Element Locally
26151
  * Valid (Type) ($3.3.4).
26152
  */
26153
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26154
       /*
26155
      * SPEC (cvc-type) (3.1)
26156
      * "If the type definition is a simple type definition, ..."
26157
      * (3.1.3) "If clause 3.2 of Element Locally Valid
26158
      * (Element) ($3.3.4) did not apply, then the `normalized value`
26159
      * must be `valid` with respect to the type definition as defined
26160
      * by String Valid ($3.14.4).
26161
      */
26162
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26163
0
        inode, inode->typeDef, inode->value);
26164
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26165
      /*
26166
      * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26167
      * definition, then the element information item must be
26168
      * `valid` with respect to the type definition as per
26169
      * Element Locally Valid (Complex Type) ($3.4.4);"
26170
      *
26171
      * SPEC (cvc-complex-type) (2.2)
26172
      * "If the {content type} is a simple type definition, ...
26173
      * the `normalized value` of the element information item is
26174
      * `valid` with respect to that simple type definition as
26175
      * defined by String Valid ($3.14.4)."
26176
      */
26177
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26178
0
    inode, inode->typeDef->contentTypeDef, inode->value);
26179
0
  }
26180
0
  if (ret != 0) {
26181
0
      if (ret < 0) {
26182
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26183
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26184
0
    goto internal_error;
26185
0
      }
26186
0
      goto end_elem;
26187
0
  }
26188
  /*
26189
  * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26190
  * not applied, all of the following must be true:
26191
  */
26192
0
  if ((inode->decl->value != NULL) &&
26193
0
      (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26194
26195
      /*
26196
      * TODO: We will need a computed value, when comparison is
26197
      * done on computed values.
26198
      */
26199
      /*
26200
      * 5.2.2.1 The element information item must have no element
26201
      * information item [children].
26202
      */
26203
0
      if (inode->flags &
26204
0
        XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26205
0
    ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26206
0
    VERROR(ret, NULL,
26207
0
        "The content must not contain element nodes since "
26208
0
        "there is a fixed value constraint");
26209
0
    goto end_elem;
26210
0
      } else {
26211
    /*
26212
    * 5.2.2.2 The appropriate case among the following must
26213
    * be true:
26214
    */
26215
0
    if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26216
        /*
26217
        * 5.2.2.2.1 If the {content type} of the `actual type
26218
        * definition` is mixed, then the *initial value* of the
26219
        * item must match the canonical lexical representation
26220
        * of the {value constraint} value.
26221
        *
26222
        * ... the *initial value* of an element information
26223
        * item is the string composed of, in order, the
26224
        * [character code] of each character information item in
26225
        * the [children] of that element information item.
26226
        */
26227
0
        if (! xmlStrEqual(inode->value, inode->decl->value)){
26228
      /*
26229
      * VAL TODO: Report invalid & expected values as well.
26230
      * VAL TODO: Implement the canonical stuff.
26231
      */
26232
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26233
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26234
0
          ret, NULL, NULL,
26235
0
          "The initial value '%s' does not match the fixed "
26236
0
          "value constraint '%s'",
26237
0
          inode->value, inode->decl->value);
26238
0
      goto end_elem;
26239
0
        }
26240
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26241
        /*
26242
        * 5.2.2.2.2 If the {content type} of the `actual type
26243
        * definition` is a simple type definition, then the
26244
        * *actual value* of the item must match the canonical
26245
        * lexical representation of the {value constraint} value.
26246
        */
26247
        /*
26248
        * VAL TODO: *actual value* is the normalized value, impl.
26249
        *           this.
26250
        * VAL TODO: Report invalid & expected values as well.
26251
        * VAL TODO: Implement a comparison with the computed values.
26252
        */
26253
0
        if (! xmlStrEqual(inode->value,
26254
0
          inode->decl->value)) {
26255
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26256
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26257
0
          ret, NULL, NULL,
26258
0
          "The actual value '%s' does not match the fixed "
26259
0
          "value constraint '%s'",
26260
0
          inode->value,
26261
0
          inode->decl->value);
26262
0
      goto end_elem;
26263
0
        }
26264
0
    }
26265
0
      }
26266
0
  }
26267
0
    }
26268
26269
0
end_elem:
26270
0
    if (vctxt->depth < 0) {
26271
  /* TODO: raise error? */
26272
0
  return (0);
26273
0
    }
26274
0
    if (vctxt->depth == vctxt->skipDepth)
26275
0
  vctxt->skipDepth = -1;
26276
    /*
26277
    * Evaluate the history of XPath state objects.
26278
    */
26279
0
    if (inode->appliedXPath &&
26280
0
  (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26281
0
  goto internal_error;
26282
    /*
26283
    * MAYBE TODO:
26284
    * SPEC (6) "The element information item must be `valid` with
26285
    * respect to each of the {identity-constraint definitions} as per
26286
    * Identity-constraint Satisfied ($3.11.4)."
26287
    */
26288
    /*
26289
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26290
    *   need to be built in any case.
26291
    *   We will currently build IDC node-tables and bubble them only if
26292
    *   keyrefs do exist.
26293
    */
26294
26295
    /*
26296
    * Add the current IDC target-nodes to the IDC node-tables.
26297
    */
26298
0
    if ((inode->idcMatchers != NULL) &&
26299
0
  (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26300
0
    {
26301
0
  if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26302
0
      goto internal_error;
26303
0
    }
26304
    /*
26305
    * Validate IDC keyrefs.
26306
    */
26307
0
    if (vctxt->inode->hasKeyrefs)
26308
0
  if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26309
0
      goto internal_error;
26310
    /*
26311
    * Merge/free the IDC table.
26312
    */
26313
0
    if (inode->idcTable != NULL) {
26314
0
  if ((vctxt->depth > 0) &&
26315
0
      (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26316
0
  {
26317
      /*
26318
      * Merge the IDC node table with the table of the parent node.
26319
      */
26320
0
      if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26321
0
    goto internal_error;
26322
0
  }
26323
0
    }
26324
    /*
26325
    * Clear the current ielem.
26326
    * VAL TODO: Don't free the PSVI IDC tables if they are
26327
    * requested for the PSVI.
26328
    */
26329
0
    xmlSchemaClearElemInfo(vctxt, inode);
26330
    /*
26331
    * Skip further processing if we are on the validation root.
26332
    */
26333
0
    if (vctxt->depth == 0) {
26334
0
  vctxt->depth--;
26335
0
  vctxt->inode = NULL;
26336
0
  return (0);
26337
0
    }
26338
    /*
26339
    * Reset the keyrefDepth if needed.
26340
    */
26341
0
    if (vctxt->aidcs != NULL) {
26342
0
  xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26343
0
  do {
26344
0
      if (aidc->keyrefDepth == vctxt->depth) {
26345
    /*
26346
    * A 'keyrefDepth' of a key/unique IDC matches the current
26347
    * depth, this means that we are leaving the scope of the
26348
    * top-most keyref IDC which refers to this IDC.
26349
    */
26350
0
    aidc->keyrefDepth = -1;
26351
0
      }
26352
0
      aidc = aidc->next;
26353
0
  } while (aidc != NULL);
26354
0
    }
26355
0
    vctxt->depth--;
26356
0
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
26357
    /*
26358
    * VAL TODO: 7 If the element information item is the `validation root`, it must be
26359
    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26360
    */
26361
0
    return (ret);
26362
26363
0
internal_error:
26364
0
    vctxt->err = -1;
26365
0
    return (-1);
26366
0
}
26367
26368
/*
26369
* 3.4.4 Complex Type Definition Validation Rules
26370
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26371
*/
26372
static int
26373
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26374
0
{
26375
0
    xmlSchemaNodeInfoPtr pielem;
26376
0
    xmlSchemaTypePtr ptype;
26377
0
    int ret = 0;
26378
26379
0
    if (vctxt->depth <= 0) {
26380
0
  VERROR_INT("xmlSchemaValidateChildElem",
26381
0
      "not intended for the validation root");
26382
0
  return (-1);
26383
0
    }
26384
0
    pielem = vctxt->elemInfos[vctxt->depth -1];
26385
0
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26386
0
  pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26387
    /*
26388
    * Handle 'nilled' elements.
26389
    */
26390
0
    if (INODE_NILLED(pielem)) {
26391
  /*
26392
  * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26393
  */
26394
0
  ACTIVATE_PARENT_ELEM;
26395
0
  ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26396
0
  VERROR(ret, NULL,
26397
0
      "Neither character nor element content is allowed, "
26398
0
      "because the element was 'nilled'");
26399
0
  ACTIVATE_ELEM;
26400
0
  goto unexpected_elem;
26401
0
    }
26402
26403
0
    ptype = pielem->typeDef;
26404
26405
0
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26406
  /*
26407
  * Workaround for "anyType": we have currently no content model
26408
  * assigned for "anyType", so handle it explicitly.
26409
  * "anyType" has an unbounded, lax "any" wildcard.
26410
  */
26411
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26412
0
      vctxt->inode->localName,
26413
0
      vctxt->inode->nsName);
26414
26415
0
  if (vctxt->inode->decl == NULL) {
26416
0
      xmlSchemaAttrInfoPtr iattr;
26417
      /*
26418
      * Process "xsi:type".
26419
      * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26420
      */
26421
0
      iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26422
0
    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26423
0
      if (iattr != NULL) {
26424
0
    ret = xmlSchemaProcessXSIType(vctxt, iattr,
26425
0
        &(vctxt->inode->typeDef), NULL);
26426
0
    if (ret != 0) {
26427
0
        if (ret == -1) {
26428
0
      VERROR_INT("xmlSchemaValidateChildElem",
26429
0
          "calling xmlSchemaProcessXSIType() to "
26430
0
          "process the attribute 'xsi:nil'");
26431
0
      return (-1);
26432
0
        }
26433
0
        return (ret);
26434
0
    }
26435
0
      } else {
26436
     /*
26437
     * Fallback to "anyType".
26438
     *
26439
     * SPEC (cvc-assess-elt)
26440
     * "If the item cannot be `strictly assessed`, [...]
26441
     * an element information item's schema validity may be laxly
26442
     * assessed if its `context-determined declaration` is not
26443
     * skip by `validating` with respect to the `ur-type
26444
     * definition` as per Element Locally Valid (Type) ($3.3.4)."
26445
    */
26446
0
    vctxt->inode->typeDef =
26447
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26448
0
      }
26449
0
  }
26450
0
  return (0);
26451
0
    }
26452
26453
0
    switch (ptype->contentType) {
26454
0
  case XML_SCHEMA_CONTENT_EMPTY:
26455
      /*
26456
      * SPEC (2.1) "If the {content type} is empty, then the
26457
      * element information item has no character or element
26458
      * information item [children]."
26459
      */
26460
0
      ACTIVATE_PARENT_ELEM
26461
0
      ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26462
0
      VERROR(ret, NULL,
26463
0
    "Element content is not allowed, "
26464
0
    "because the content type is empty");
26465
0
      ACTIVATE_ELEM
26466
0
      goto unexpected_elem;
26467
0
      break;
26468
26469
0
  case XML_SCHEMA_CONTENT_MIXED:
26470
0
        case XML_SCHEMA_CONTENT_ELEMENTS: {
26471
0
      xmlRegExecCtxtPtr regexCtxt;
26472
0
      xmlChar *values[10];
26473
0
      int terminal, nbval = 10, nbneg;
26474
26475
      /* VAL TODO: Optimized "anyType" validation.*/
26476
26477
0
      if (ptype->contModel == NULL) {
26478
0
    VERROR_INT("xmlSchemaValidateChildElem",
26479
0
        "type has elem content but no content model");
26480
0
    return (-1);
26481
0
      }
26482
      /*
26483
      * Safety belt for evaluation if the cont. model was already
26484
      * examined to be invalid.
26485
      */
26486
0
      if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26487
0
    VERROR_INT("xmlSchemaValidateChildElem",
26488
0
        "validating elem, but elem content is already invalid");
26489
0
    return (-1);
26490
0
      }
26491
26492
0
      regexCtxt = pielem->regexCtxt;
26493
0
      if (regexCtxt == NULL) {
26494
    /*
26495
    * Create the regex context.
26496
    */
26497
0
    regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26498
0
        xmlSchemaVContentModelCallback, vctxt);
26499
0
    if (regexCtxt == NULL) {
26500
0
        VERROR_INT("xmlSchemaValidateChildElem",
26501
0
      "failed to create a regex context");
26502
0
        return (-1);
26503
0
    }
26504
0
    pielem->regexCtxt = regexCtxt;
26505
0
      }
26506
26507
      /*
26508
      * SPEC (2.4) "If the {content type} is element-only or mixed,
26509
      * then the sequence of the element information item's
26510
      * element information item [children], if any, taken in
26511
      * order, is `valid` with respect to the {content type}'s
26512
      * particle, as defined in Element Sequence Locally Valid
26513
      * (Particle) ($3.9.4)."
26514
      */
26515
0
      ret = xmlRegExecPushString2(regexCtxt,
26516
0
    vctxt->inode->localName,
26517
0
    vctxt->inode->nsName,
26518
0
    vctxt->inode);
26519
0
      if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26520
0
    VERROR_INT("xmlSchemaValidateChildElem",
26521
0
        "calling xmlRegExecPushString2()");
26522
0
    return (-1);
26523
0
      }
26524
0
      if (ret < 0) {
26525
0
    xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26526
0
        &values[0], &terminal);
26527
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26528
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26529
0
        "This element is not expected",
26530
0
        nbval, nbneg, values);
26531
0
    ret = vctxt->err;
26532
0
    goto unexpected_elem;
26533
0
      } else
26534
0
    ret = 0;
26535
0
  }
26536
0
      break;
26537
0
  case XML_SCHEMA_CONTENT_SIMPLE:
26538
0
  case XML_SCHEMA_CONTENT_BASIC:
26539
0
      ACTIVATE_PARENT_ELEM
26540
0
      if (WXS_IS_COMPLEX(ptype)) {
26541
    /*
26542
    * SPEC (cvc-complex-type) (2.2)
26543
    * "If the {content type} is a simple type definition, then
26544
    * the element information item has no element information
26545
    * item [children], ..."
26546
    */
26547
0
    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26548
0
    VERROR(ret, NULL, "Element content is not allowed, "
26549
0
        "because the content type is a simple type definition");
26550
0
      } else {
26551
    /*
26552
    * SPEC (cvc-type) (3.1.2) "The element information item must
26553
    * have no element information item [children]."
26554
    */
26555
0
    ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26556
0
    VERROR(ret, NULL, "Element content is not allowed, "
26557
0
        "because the type definition is simple");
26558
0
      }
26559
0
      ACTIVATE_ELEM
26560
0
      ret = vctxt->err;
26561
0
      goto unexpected_elem;
26562
0
      break;
26563
26564
0
  default:
26565
0
      break;
26566
0
    }
26567
0
    return (ret);
26568
0
unexpected_elem:
26569
    /*
26570
    * Pop this element and set the skipDepth to skip
26571
    * all further content of the parent element.
26572
    */
26573
0
    vctxt->skipDepth = vctxt->depth;
26574
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26575
0
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26576
0
    return (ret);
26577
0
}
26578
26579
0
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26580
0
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26581
0
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26582
26583
static int
26584
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26585
      int nodeType, const xmlChar *value, int len,
26586
      int mode, int *consumed)
26587
0
{
26588
    /*
26589
    * Unfortunately we have to duplicate the text sometimes.
26590
    * OPTIMIZE: Maybe we could skip it, if:
26591
    *   1. content type is simple
26592
    *   2. whitespace is "collapse"
26593
    *   3. it consists of whitespace only
26594
    *
26595
    * Process character content.
26596
    */
26597
0
    if (consumed != NULL)
26598
0
  *consumed = 0;
26599
0
    if (INODE_NILLED(vctxt->inode)) {
26600
  /*
26601
  * SPEC cvc-elt (3.3.4 - 3.2.1)
26602
  * "The element information item must have no character or
26603
  * element information item [children]."
26604
  */
26605
0
  VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26606
0
      "Neither character nor element content is allowed "
26607
0
      "because the element is 'nilled'");
26608
0
  return (vctxt->err);
26609
0
    }
26610
    /*
26611
    * SPEC (2.1) "If the {content type} is empty, then the
26612
    * element information item has no character or element
26613
    * information item [children]."
26614
    */
26615
0
    if (vctxt->inode->typeDef->contentType ==
26616
0
      XML_SCHEMA_CONTENT_EMPTY) {
26617
0
  VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26618
0
      "Character content is not allowed, "
26619
0
      "because the content type is empty");
26620
0
  return (vctxt->err);
26621
0
    }
26622
26623
0
    if (vctxt->inode->typeDef->contentType ==
26624
0
      XML_SCHEMA_CONTENT_ELEMENTS) {
26625
0
  if ((nodeType != XML_TEXT_NODE) ||
26626
0
      (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26627
      /*
26628
      * SPEC cvc-complex-type (2.3)
26629
      * "If the {content type} is element-only, then the
26630
      * element information item has no character information
26631
      * item [children] other than those whose [character
26632
      * code] is defined as a white space in [XML 1.0 (Second
26633
      * Edition)]."
26634
      */
26635
0
      VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26636
0
    "Character content other than whitespace is not allowed "
26637
0
    "because the content type is 'element-only'");
26638
0
      return (vctxt->err);
26639
0
  }
26640
0
  return (0);
26641
0
    }
26642
26643
0
    if ((value == NULL) || (value[0] == 0))
26644
0
  return (0);
26645
    /*
26646
    * Save the value.
26647
    * NOTE that even if the content type is *mixed*, we need the
26648
    * *initial value* for default/fixed value constraints.
26649
    */
26650
0
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26651
0
  ((vctxt->inode->decl == NULL) ||
26652
0
  (vctxt->inode->decl->value == NULL)))
26653
0
  return (0);
26654
26655
0
    if (vctxt->inode->value == NULL) {
26656
  /*
26657
  * Set the value.
26658
  */
26659
0
  switch (mode) {
26660
0
      case XML_SCHEMA_PUSH_TEXT_PERSIST:
26661
    /*
26662
    * When working on a tree.
26663
    */
26664
0
    vctxt->inode->value = value;
26665
0
    break;
26666
0
      case XML_SCHEMA_PUSH_TEXT_CREATED:
26667
    /*
26668
    * When working with the reader.
26669
    * The value will be freed by the element info.
26670
    */
26671
0
    vctxt->inode->value = value;
26672
0
    if (consumed != NULL)
26673
0
        *consumed = 1;
26674
0
    vctxt->inode->flags |=
26675
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26676
0
    break;
26677
0
      case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26678
    /*
26679
    * When working with SAX.
26680
    * The value will be freed by the element info.
26681
    */
26682
0
    if (len != -1)
26683
0
        vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26684
0
    else
26685
0
        vctxt->inode->value = BAD_CAST xmlStrdup(value);
26686
0
    vctxt->inode->flags |=
26687
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26688
0
    break;
26689
0
      default:
26690
0
    break;
26691
0
  }
26692
0
    } else {
26693
0
  if (len < 0)
26694
0
      len = xmlStrlen(value);
26695
  /*
26696
  * Concat the value.
26697
  */
26698
0
  if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26699
0
      vctxt->inode->value = BAD_CAST xmlStrncat(
26700
0
    (xmlChar *) vctxt->inode->value, value, len);
26701
0
  } else {
26702
0
      vctxt->inode->value =
26703
0
    BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26704
0
      vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26705
0
  }
26706
0
    }
26707
26708
0
    return (0);
26709
0
}
26710
26711
static int
26712
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26713
0
{
26714
0
    int ret = 0;
26715
26716
0
    if ((vctxt->skipDepth != -1) &&
26717
0
  (vctxt->depth >= vctxt->skipDepth)) {
26718
0
  VERROR_INT("xmlSchemaValidateElem",
26719
0
      "in skip-state");
26720
0
  goto internal_error;
26721
0
    }
26722
0
    if (vctxt->xsiAssemble) {
26723
  /*
26724
  * We will stop validation if there was an error during
26725
  * dynamic schema construction.
26726
  * Note that we simply set @skipDepth to 0, this could
26727
  * mean that a streaming document via SAX would be
26728
  * still read to the end but it won't be validated any more.
26729
  * TODO: If we are sure how to stop the validation at once
26730
  *   for all input scenarios, then this should be changed to
26731
  *   instantly stop the validation.
26732
  */
26733
0
  ret = xmlSchemaAssembleByXSI(vctxt);
26734
0
  if (ret != 0) {
26735
0
      if (ret == -1)
26736
0
    goto internal_error;
26737
0
      vctxt->skipDepth = 0;
26738
0
      return(ret);
26739
0
  }
26740
        /*
26741
         * Augment the IDC definitions for the main schema and all imported ones
26742
         * NOTE: main schema is the first in the imported list
26743
         */
26744
0
        xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
26745
0
                    vctxt);
26746
0
    }
26747
0
    if (vctxt->depth > 0) {
26748
  /*
26749
  * Validate this element against the content model
26750
  * of the parent.
26751
  */
26752
0
  ret = xmlSchemaValidateChildElem(vctxt);
26753
0
  if (ret != 0) {
26754
0
      if (ret < 0) {
26755
0
    VERROR_INT("xmlSchemaValidateElem",
26756
0
        "calling xmlSchemaStreamValidateChildElement()");
26757
0
    goto internal_error;
26758
0
      }
26759
0
      goto exit;
26760
0
  }
26761
0
  if (vctxt->depth == vctxt->skipDepth)
26762
0
      goto exit;
26763
0
  if ((vctxt->inode->decl == NULL) &&
26764
0
      (vctxt->inode->typeDef == NULL)) {
26765
0
      VERROR_INT("xmlSchemaValidateElem",
26766
0
    "the child element was valid but neither the "
26767
0
    "declaration nor the type was set");
26768
0
      goto internal_error;
26769
0
  }
26770
0
    } else {
26771
  /*
26772
  * Get the declaration of the validation root.
26773
  */
26774
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26775
0
      vctxt->inode->localName,
26776
0
      vctxt->inode->nsName);
26777
0
  if (vctxt->inode->decl == NULL) {
26778
0
      ret = XML_SCHEMAV_CVC_ELT_1;
26779
0
      VERROR(ret, NULL,
26780
0
    "No matching global declaration available "
26781
0
    "for the validation root");
26782
0
      goto exit;
26783
0
  }
26784
0
    }
26785
26786
0
    if (vctxt->inode->decl == NULL)
26787
0
  goto type_validation;
26788
26789
0
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26790
0
  int skip;
26791
  /*
26792
  * Wildcards.
26793
  */
26794
0
  ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26795
0
  if (ret != 0) {
26796
0
      if (ret < 0) {
26797
0
    VERROR_INT("xmlSchemaValidateElem",
26798
0
        "calling xmlSchemaValidateElemWildcard()");
26799
0
    goto internal_error;
26800
0
      }
26801
0
      goto exit;
26802
0
  }
26803
0
  if (skip) {
26804
0
      vctxt->skipDepth = vctxt->depth;
26805
0
      goto exit;
26806
0
  }
26807
  /*
26808
  * The declaration might be set by the wildcard validation,
26809
  * when the processContents is "lax" or "strict".
26810
  */
26811
0
  if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26812
      /*
26813
      * Clear the "decl" field to not confuse further processing.
26814
      */
26815
0
      vctxt->inode->decl = NULL;
26816
0
      goto type_validation;
26817
0
  }
26818
0
    }
26819
    /*
26820
    * Validate against the declaration.
26821
    */
26822
0
    ret = xmlSchemaValidateElemDecl(vctxt);
26823
0
    if (ret != 0) {
26824
0
  if (ret < 0) {
26825
0
      VERROR_INT("xmlSchemaValidateElem",
26826
0
    "calling xmlSchemaValidateElemDecl()");
26827
0
      goto internal_error;
26828
0
  }
26829
0
  goto exit;
26830
0
    }
26831
    /*
26832
    * Validate against the type definition.
26833
    */
26834
0
type_validation:
26835
26836
0
    if (vctxt->inode->typeDef == NULL) {
26837
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26838
0
  ret = XML_SCHEMAV_CVC_TYPE_1;
26839
0
  VERROR(ret, NULL,
26840
0
      "The type definition is absent");
26841
0
  goto exit;
26842
0
    }
26843
0
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26844
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26845
0
  ret = XML_SCHEMAV_CVC_TYPE_2;
26846
0
      VERROR(ret, NULL,
26847
0
      "The type definition is abstract");
26848
0
  goto exit;
26849
0
    }
26850
    /*
26851
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
26852
    * during validation against the declaration. This must be done
26853
    * _before_ attribute validation.
26854
    */
26855
0
    if (vctxt->xpathStates != NULL) {
26856
0
  ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26857
0
  vctxt->inode->appliedXPath = 1;
26858
0
  if (ret == -1) {
26859
0
      VERROR_INT("xmlSchemaValidateElem",
26860
0
    "calling xmlSchemaXPathEvaluate()");
26861
0
      goto internal_error;
26862
0
  }
26863
0
    }
26864
    /*
26865
    * Validate attributes.
26866
    */
26867
0
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26868
0
  if ((vctxt->nbAttrInfos != 0) ||
26869
0
      (vctxt->inode->typeDef->attrUses != NULL)) {
26870
26871
0
      ret = xmlSchemaVAttributesComplex(vctxt);
26872
0
  }
26873
0
    } else if (vctxt->nbAttrInfos != 0) {
26874
26875
0
  ret = xmlSchemaVAttributesSimple(vctxt);
26876
0
    }
26877
    /*
26878
    * Clear registered attributes.
26879
    */
26880
0
    if (vctxt->nbAttrInfos != 0)
26881
0
  xmlSchemaClearAttrInfos(vctxt);
26882
0
    if (ret == -1) {
26883
0
  VERROR_INT("xmlSchemaValidateElem",
26884
0
      "calling attributes validation");
26885
0
  goto internal_error;
26886
0
    }
26887
    /*
26888
    * Don't return an error if attributes are invalid on purpose.
26889
    */
26890
0
    ret = 0;
26891
26892
0
exit:
26893
0
    if (ret != 0)
26894
0
  vctxt->skipDepth = vctxt->depth;
26895
0
    return (ret);
26896
0
internal_error:
26897
0
    return (-1);
26898
0
}
26899
26900
#ifdef XML_SCHEMA_READER_ENABLED
26901
static int
26902
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26903
{
26904
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26905
    int depth, nodeType, ret = 0, consumed;
26906
    xmlSchemaNodeInfoPtr ielem;
26907
26908
    vctxt->depth = -1;
26909
    ret = xmlTextReaderRead(vctxt->reader);
26910
    /*
26911
    * Move to the document element.
26912
    */
26913
    while (ret == 1) {
26914
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26915
  if (nodeType == XML_ELEMENT_NODE)
26916
      goto root_found;
26917
  ret = xmlTextReaderRead(vctxt->reader);
26918
    }
26919
    goto exit;
26920
26921
root_found:
26922
26923
    do {
26924
  depth = xmlTextReaderDepth(vctxt->reader);
26925
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26926
26927
  if (nodeType == XML_ELEMENT_NODE) {
26928
26929
      vctxt->depth++;
26930
      if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26931
    VERROR_INT("xmlSchemaVReaderWalk",
26932
        "calling xmlSchemaValidatorPushElem()");
26933
    goto internal_error;
26934
      }
26935
      ielem = vctxt->inode;
26936
      ielem->localName = xmlTextReaderLocalName(vctxt->reader);
26937
      ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
26938
      ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
26939
      /*
26940
      * Is the element empty?
26941
      */
26942
      ret = xmlTextReaderIsEmptyElement(vctxt->reader);
26943
      if (ret == -1) {
26944
    VERROR_INT("xmlSchemaVReaderWalk",
26945
        "calling xmlTextReaderIsEmptyElement()");
26946
    goto internal_error;
26947
      }
26948
      if (ret) {
26949
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
26950
      }
26951
      /*
26952
      * Register attributes.
26953
      */
26954
      vctxt->nbAttrInfos = 0;
26955
      ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
26956
      if (ret == -1) {
26957
    VERROR_INT("xmlSchemaVReaderWalk",
26958
        "calling xmlTextReaderMoveToFirstAttribute()");
26959
    goto internal_error;
26960
      }
26961
      if (ret == 1) {
26962
    do {
26963
        /*
26964
        * VAL TODO: How do we know that the reader works on a
26965
        * node tree, to be able to pass a node here?
26966
        */
26967
        if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
26968
      (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
26969
      xmlTextReaderNamespaceUri(vctxt->reader), 1,
26970
      xmlTextReaderValue(vctxt->reader), 1) == -1) {
26971
26972
      VERROR_INT("xmlSchemaVReaderWalk",
26973
          "calling xmlSchemaValidatorPushAttribute()");
26974
      goto internal_error;
26975
        }
26976
        ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
26977
        if (ret == -1) {
26978
      VERROR_INT("xmlSchemaVReaderWalk",
26979
          "calling xmlTextReaderMoveToFirstAttribute()");
26980
      goto internal_error;
26981
        }
26982
    } while (ret == 1);
26983
    /*
26984
    * Back to element position.
26985
    */
26986
    ret = xmlTextReaderMoveToElement(vctxt->reader);
26987
    if (ret == -1) {
26988
        VERROR_INT("xmlSchemaVReaderWalk",
26989
      "calling xmlTextReaderMoveToElement()");
26990
        goto internal_error;
26991
    }
26992
      }
26993
      /*
26994
      * Validate the element.
26995
      */
26996
      ret= xmlSchemaValidateElem(vctxt);
26997
      if (ret != 0) {
26998
    if (ret == -1) {
26999
        VERROR_INT("xmlSchemaVReaderWalk",
27000
      "calling xmlSchemaValidateElem()");
27001
        goto internal_error;
27002
    }
27003
    goto exit;
27004
      }
27005
      if (vctxt->depth == vctxt->skipDepth) {
27006
    int curDepth;
27007
    /*
27008
    * Skip all content.
27009
    */
27010
    if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27011
        ret = xmlTextReaderRead(vctxt->reader);
27012
        curDepth = xmlTextReaderDepth(vctxt->reader);
27013
        while ((ret == 1) && (curDepth != depth)) {
27014
      ret = xmlTextReaderRead(vctxt->reader);
27015
      curDepth = xmlTextReaderDepth(vctxt->reader);
27016
        }
27017
        if (ret < 0) {
27018
      /*
27019
      * VAL TODO: A reader error occurred; what to do here?
27020
      */
27021
      ret = 1;
27022
      goto exit;
27023
        }
27024
    }
27025
    goto leave_elem;
27026
      }
27027
      /*
27028
      * READER VAL TODO: Is an END_ELEM really never called
27029
      * if the elem is empty?
27030
      */
27031
      if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27032
    goto leave_elem;
27033
  } else if (nodeType == END_ELEM) {
27034
      /*
27035
      * Process END of element.
27036
      */
27037
leave_elem:
27038
      ret = xmlSchemaValidatorPopElem(vctxt);
27039
      if (ret != 0) {
27040
    if (ret < 0) {
27041
        VERROR_INT("xmlSchemaVReaderWalk",
27042
      "calling xmlSchemaValidatorPopElem()");
27043
        goto internal_error;
27044
    }
27045
    goto exit;
27046
      }
27047
      if (vctxt->depth >= 0)
27048
    ielem = vctxt->inode;
27049
      else
27050
    ielem = NULL;
27051
  } else if ((nodeType == XML_TEXT_NODE) ||
27052
      (nodeType == XML_CDATA_SECTION_NODE) ||
27053
      (nodeType == WHTSP) ||
27054
      (nodeType == SIGN_WHTSP)) {
27055
      /*
27056
      * Process character content.
27057
      */
27058
      xmlChar *value;
27059
27060
      if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27061
    nodeType = XML_TEXT_NODE;
27062
27063
      value = xmlTextReaderValue(vctxt->reader);
27064
      ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27065
    -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27066
      if (! consumed)
27067
    xmlFree(value);
27068
      if (ret == -1) {
27069
    VERROR_INT("xmlSchemaVReaderWalk",
27070
        "calling xmlSchemaVPushText()");
27071
    goto internal_error;
27072
      }
27073
  } else if ((nodeType == XML_ENTITY_NODE) ||
27074
      (nodeType == XML_ENTITY_REF_NODE)) {
27075
      /*
27076
      * VAL TODO: What to do with entities?
27077
      */
27078
      TODO
27079
  }
27080
  /*
27081
  * Read next node.
27082
  */
27083
  ret = xmlTextReaderRead(vctxt->reader);
27084
    } while (ret == 1);
27085
27086
exit:
27087
    return (ret);
27088
internal_error:
27089
    return (-1);
27090
}
27091
#endif
27092
27093
/************************************************************************
27094
 *                  *
27095
 *      SAX validation handlers       *
27096
 *                  *
27097
 ************************************************************************/
27098
27099
/*
27100
* Process text content.
27101
*/
27102
static void
27103
xmlSchemaSAXHandleText(void *ctx,
27104
           const xmlChar * ch,
27105
           int len)
27106
0
{
27107
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27108
27109
0
    if (vctxt->depth < 0)
27110
0
  return;
27111
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27112
0
  return;
27113
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27114
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27115
0
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27116
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27117
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27118
0
      "calling xmlSchemaVPushText()");
27119
0
  vctxt->err = -1;
27120
0
  xmlStopParser(vctxt->parserCtxt);
27121
0
    }
27122
0
}
27123
27124
/*
27125
* Process CDATA content.
27126
*/
27127
static void
27128
xmlSchemaSAXHandleCDataSection(void *ctx,
27129
           const xmlChar * ch,
27130
           int len)
27131
0
{
27132
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27133
27134
0
    if (vctxt->depth < 0)
27135
0
  return;
27136
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27137
0
  return;
27138
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27139
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27140
0
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27141
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27142
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27143
0
      "calling xmlSchemaVPushText()");
27144
0
  vctxt->err = -1;
27145
0
  xmlStopParser(vctxt->parserCtxt);
27146
0
    }
27147
0
}
27148
27149
static void
27150
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27151
          const xmlChar * name ATTRIBUTE_UNUSED)
27152
0
{
27153
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27154
27155
0
    if (vctxt->depth < 0)
27156
0
  return;
27157
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27158
0
  return;
27159
    /* SAX VAL TODO: What to do here? */
27160
0
}
27161
27162
static void
27163
xmlSchemaSAXHandleStartElementNs(void *ctx,
27164
         const xmlChar * localname,
27165
         const xmlChar * prefix ATTRIBUTE_UNUSED,
27166
         const xmlChar * URI,
27167
         int nb_namespaces,
27168
         const xmlChar ** namespaces,
27169
         int nb_attributes,
27170
         int nb_defaulted ATTRIBUTE_UNUSED,
27171
         const xmlChar ** attributes)
27172
0
{
27173
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27174
0
    int ret;
27175
0
    xmlSchemaNodeInfoPtr ielem;
27176
0
    int i, j;
27177
27178
    /*
27179
    * SAX VAL TODO: What to do with nb_defaulted?
27180
    */
27181
    /*
27182
    * Skip elements if inside a "skip" wildcard or invalid.
27183
    */
27184
0
    vctxt->depth++;
27185
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27186
0
  return;
27187
    /*
27188
    * Push the element.
27189
    */
27190
0
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27191
0
  VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27192
0
      "calling xmlSchemaValidatorPushElem()");
27193
0
  goto internal_error;
27194
0
    }
27195
0
    ielem = vctxt->inode;
27196
    /*
27197
    * TODO: Is this OK?
27198
    */
27199
0
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27200
0
    ielem->localName = localname;
27201
0
    ielem->nsName = URI;
27202
0
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27203
    /*
27204
    * Register namespaces on the elem info.
27205
    */
27206
0
    if (nb_namespaces != 0) {
27207
  /*
27208
  * Although the parser builds its own namespace list,
27209
  * we have no access to it, so we'll use an own one.
27210
  */
27211
0
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27212
      /*
27213
      * Store prefix and namespace name.
27214
      */
27215
0
      if (ielem->nsBindings == NULL) {
27216
0
    ielem->nsBindings =
27217
0
        (const xmlChar **) xmlMalloc(10 *
27218
0
      sizeof(const xmlChar *));
27219
0
    if (ielem->nsBindings == NULL) {
27220
0
        xmlSchemaVErrMemory(vctxt);
27221
0
        goto internal_error;
27222
0
    }
27223
0
    ielem->nbNsBindings = 0;
27224
0
    ielem->sizeNsBindings = 5;
27225
0
      } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27226
0
    ielem->sizeNsBindings *= 2;
27227
0
    ielem->nsBindings =
27228
0
        (const xmlChar **) xmlRealloc(
27229
0
      (void *) ielem->nsBindings,
27230
0
      ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27231
0
    if (ielem->nsBindings == NULL) {
27232
0
        xmlSchemaVErrMemory(vctxt);
27233
0
        goto internal_error;
27234
0
    }
27235
0
      }
27236
27237
0
      ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27238
0
      if (namespaces[j+1][0] == 0) {
27239
    /*
27240
    * Handle xmlns="".
27241
    */
27242
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27243
0
      } else
27244
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27245
0
        namespaces[j+1];
27246
0
      ielem->nbNsBindings++;
27247
0
  }
27248
0
    }
27249
    /*
27250
    * Register attributes.
27251
    * SAX VAL TODO: We are not adding namespace declaration
27252
    * attributes yet.
27253
    */
27254
0
    if (nb_attributes != 0) {
27255
0
  int valueLen, k, l;
27256
0
  xmlChar *value;
27257
27258
0
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27259
      /*
27260
      * Duplicate the value, changing any &#38; to a literal ampersand.
27261
      *
27262
      * libxml2 differs from normal SAX here in that it escapes all ampersands
27263
      * as &#38; instead of delivering the raw converted string. Changing the
27264
      * behavior at this point would break applications that use this API, so
27265
      * we are forced to work around it.
27266
      */
27267
0
      valueLen = attributes[j+4] - attributes[j+3];
27268
0
      value = xmlMallocAtomic(valueLen + 1);
27269
0
      if (value == NULL) {
27270
0
    xmlSchemaVErrMemory(vctxt);
27271
0
    goto internal_error;
27272
0
      }
27273
0
      for (k = 0, l = 0; k < valueLen; l++) {
27274
0
    if (k < valueLen - 4 &&
27275
0
        attributes[j+3][k+0] == '&' &&
27276
0
        attributes[j+3][k+1] == '#' &&
27277
0
        attributes[j+3][k+2] == '3' &&
27278
0
        attributes[j+3][k+3] == '8' &&
27279
0
        attributes[j+3][k+4] == ';') {
27280
0
        value[l] = '&';
27281
0
        k += 5;
27282
0
    } else {
27283
0
        value[l] = attributes[j+3][k];
27284
0
        k++;
27285
0
    }
27286
0
      }
27287
0
      value[l] = '\0';
27288
      /*
27289
      * TODO: Set the node line.
27290
      */
27291
0
      ret = xmlSchemaValidatorPushAttribute(vctxt,
27292
0
    NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27293
0
    value, 1);
27294
0
      if (ret == -1) {
27295
0
    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27296
0
        "calling xmlSchemaValidatorPushAttribute()");
27297
0
    goto internal_error;
27298
0
      }
27299
0
  }
27300
0
    }
27301
    /*
27302
    * Validate the element.
27303
    */
27304
0
    ret = xmlSchemaValidateElem(vctxt);
27305
0
    if (ret != 0) {
27306
0
  if (ret == -1) {
27307
0
      VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27308
0
    "calling xmlSchemaValidateElem()");
27309
0
      goto internal_error;
27310
0
  }
27311
0
  goto exit;
27312
0
    }
27313
27314
0
exit:
27315
0
    return;
27316
0
internal_error:
27317
0
    vctxt->err = -1;
27318
0
    xmlStopParser(vctxt->parserCtxt);
27319
0
    return;
27320
0
}
27321
27322
static void
27323
xmlSchemaSAXHandleEndElementNs(void *ctx,
27324
             const xmlChar * localname ATTRIBUTE_UNUSED,
27325
             const xmlChar * prefix ATTRIBUTE_UNUSED,
27326
             const xmlChar * URI ATTRIBUTE_UNUSED)
27327
0
{
27328
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27329
0
    int res;
27330
27331
    /*
27332
    * Skip elements if inside a "skip" wildcard or if invalid.
27333
    */
27334
0
    if (vctxt->skipDepth != -1) {
27335
0
  if (vctxt->depth > vctxt->skipDepth) {
27336
0
      vctxt->depth--;
27337
0
      return;
27338
0
  } else
27339
0
      vctxt->skipDepth = -1;
27340
0
    }
27341
    /*
27342
    * SAX VAL TODO: Just a temporary check.
27343
    */
27344
0
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27345
0
  (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27346
0
  VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27347
0
      "elem pop mismatch");
27348
0
    }
27349
0
    res = xmlSchemaValidatorPopElem(vctxt);
27350
0
    if (res != 0) {
27351
0
  if (res < 0) {
27352
0
      VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27353
0
    "calling xmlSchemaValidatorPopElem()");
27354
0
      goto internal_error;
27355
0
  }
27356
0
  goto exit;
27357
0
    }
27358
0
exit:
27359
0
    return;
27360
0
internal_error:
27361
0
    vctxt->err = -1;
27362
0
    xmlStopParser(vctxt->parserCtxt);
27363
0
    return;
27364
0
}
27365
27366
/************************************************************************
27367
 *                  *
27368
 *      Validation interfaces       *
27369
 *                  *
27370
 ************************************************************************/
27371
27372
/**
27373
 * xmlSchemaNewValidCtxt:
27374
 * @schema:  a precompiled XML Schemas
27375
 *
27376
 * Create an XML Schemas validation context based on the given schema.
27377
 *
27378
 * Returns the validation context or NULL in case of error
27379
 */
27380
xmlSchemaValidCtxtPtr
27381
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27382
6.83k
{
27383
6.83k
    xmlSchemaValidCtxtPtr ret;
27384
27385
6.83k
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27386
6.83k
    if (ret == NULL) {
27387
0
        xmlSchemaVErrMemory(NULL);
27388
0
        return (NULL);
27389
0
    }
27390
6.83k
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27391
6.83k
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27392
6.83k
    ret->dict = xmlDictCreate();
27393
6.83k
    ret->nodeQNames = xmlSchemaItemListCreate();
27394
6.83k
    ret->schema = schema;
27395
6.83k
    return (ret);
27396
6.83k
}
27397
27398
/**
27399
 * xmlSchemaValidateSetFilename:
27400
 * @vctxt: the schema validation context
27401
 * @filename: the file name
27402
 *
27403
 * Workaround to provide file error reporting information when this is
27404
 * not provided by current APIs
27405
 */
27406
void
27407
0
xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27408
0
    if (vctxt == NULL)
27409
0
        return;
27410
0
    if (vctxt->filename != NULL)
27411
0
        xmlFree(vctxt->filename);
27412
0
    if (filename != NULL)
27413
0
        vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27414
0
    else
27415
0
        vctxt->filename = NULL;
27416
0
}
27417
27418
/**
27419
 * xmlSchemaClearValidCtxt:
27420
 * @vctxt: the schema validation context
27421
 *
27422
 * Free the resources associated to the schema validation context;
27423
 * leaves some fields alive intended for reuse of the context.
27424
 */
27425
static void
27426
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27427
0
{
27428
0
    if (vctxt == NULL)
27429
0
        return;
27430
27431
    /*
27432
    * TODO: Should we clear the flags?
27433
    *   Might be problematic if one reuses the context
27434
    *   and assumes that the options remain the same.
27435
    */
27436
0
    vctxt->flags = 0;
27437
0
    vctxt->validationRoot = NULL;
27438
0
    vctxt->doc = NULL;
27439
0
#ifdef LIBXML_READER_ENABLED
27440
0
    vctxt->reader = NULL;
27441
0
#endif
27442
0
    vctxt->hasKeyrefs = 0;
27443
27444
0
    if (vctxt->value != NULL) {
27445
0
        xmlSchemaFreeValue(vctxt->value);
27446
0
  vctxt->value = NULL;
27447
0
    }
27448
    /*
27449
    * Augmented IDC information.
27450
    */
27451
0
    if (vctxt->aidcs != NULL) {
27452
0
  xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27453
0
  do {
27454
0
      next = cur->next;
27455
0
      xmlFree(cur);
27456
0
      cur = next;
27457
0
  } while (cur != NULL);
27458
0
  vctxt->aidcs = NULL;
27459
0
    }
27460
27461
0
    if (vctxt->idcNodes != NULL) {
27462
0
  int i;
27463
0
  xmlSchemaPSVIIDCNodePtr item;
27464
27465
0
  for (i = 0; i < vctxt->nbIdcNodes; i++) {
27466
0
      item = vctxt->idcNodes[i];
27467
0
      xmlFree(item->keys);
27468
0
      xmlFree(item);
27469
0
  }
27470
0
  xmlFree(vctxt->idcNodes);
27471
0
  vctxt->idcNodes = NULL;
27472
0
  vctxt->nbIdcNodes = 0;
27473
0
  vctxt->sizeIdcNodes = 0;
27474
0
    }
27475
27476
0
    if (vctxt->idcKeys != NULL) {
27477
0
  int i;
27478
0
  for (i = 0; i < vctxt->nbIdcKeys; i++)
27479
0
      xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27480
0
  xmlFree(vctxt->idcKeys);
27481
0
  vctxt->idcKeys = NULL;
27482
0
  vctxt->nbIdcKeys = 0;
27483
0
  vctxt->sizeIdcKeys = 0;
27484
0
    }
27485
27486
    /*
27487
    * Note that we won't delete the XPath state pool here.
27488
    */
27489
0
    if (vctxt->xpathStates != NULL) {
27490
0
  xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27491
0
  vctxt->xpathStates = NULL;
27492
0
    }
27493
    /*
27494
    * Attribute info.
27495
    */
27496
0
    if (vctxt->nbAttrInfos != 0) {
27497
0
  xmlSchemaClearAttrInfos(vctxt);
27498
0
    }
27499
    /*
27500
    * Element info.
27501
    */
27502
0
    if (vctxt->elemInfos != NULL) {
27503
0
  int i;
27504
0
  xmlSchemaNodeInfoPtr ei;
27505
27506
0
  for (i = 0; i < vctxt->sizeElemInfos; i++) {
27507
0
      ei = vctxt->elemInfos[i];
27508
0
      if (ei == NULL)
27509
0
    break;
27510
0
      xmlSchemaClearElemInfo(vctxt, ei);
27511
0
  }
27512
0
    }
27513
0
    xmlSchemaItemListClear(vctxt->nodeQNames);
27514
    /* Recreate the dict. */
27515
0
    xmlDictFree(vctxt->dict);
27516
    /*
27517
    * TODO: Is is save to recreate it? Do we have a scenario
27518
    * where the user provides the dict?
27519
    */
27520
0
    vctxt->dict = xmlDictCreate();
27521
27522
0
    if (vctxt->filename != NULL) {
27523
0
        xmlFree(vctxt->filename);
27524
0
  vctxt->filename = NULL;
27525
0
    }
27526
27527
    /*
27528
     * Note that some cleanup functions can move items to the cache,
27529
     * so the cache shouldn't be freed too early.
27530
     */
27531
0
    if (vctxt->idcMatcherCache != NULL) {
27532
0
  xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27533
27534
0
  while (matcher) {
27535
0
      tmp = matcher;
27536
0
      matcher = matcher->nextCached;
27537
0
      xmlSchemaIDCFreeMatcherList(tmp);
27538
0
  }
27539
0
  vctxt->idcMatcherCache = NULL;
27540
0
    }
27541
0
}
27542
27543
/**
27544
 * xmlSchemaFreeValidCtxt:
27545
 * @ctxt:  the schema validation context
27546
 *
27547
 * Free the resources associated to the schema validation context
27548
 */
27549
void
27550
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27551
6.83k
{
27552
6.83k
    if (ctxt == NULL)
27553
0
        return;
27554
6.83k
    if (ctxt->value != NULL)
27555
0
        xmlSchemaFreeValue(ctxt->value);
27556
6.83k
    if (ctxt->pctxt != NULL)
27557
0
  xmlSchemaFreeParserCtxt(ctxt->pctxt);
27558
6.83k
    if (ctxt->idcNodes != NULL) {
27559
0
  int i;
27560
0
  xmlSchemaPSVIIDCNodePtr item;
27561
27562
0
  for (i = 0; i < ctxt->nbIdcNodes; i++) {
27563
0
      item = ctxt->idcNodes[i];
27564
0
      xmlFree(item->keys);
27565
0
      xmlFree(item);
27566
0
  }
27567
0
  xmlFree(ctxt->idcNodes);
27568
0
    }
27569
6.83k
    if (ctxt->idcKeys != NULL) {
27570
0
  int i;
27571
0
  for (i = 0; i < ctxt->nbIdcKeys; i++)
27572
0
      xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27573
0
  xmlFree(ctxt->idcKeys);
27574
0
    }
27575
27576
6.83k
    if (ctxt->xpathStates != NULL) {
27577
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27578
0
  ctxt->xpathStates = NULL;
27579
0
    }
27580
6.83k
    if (ctxt->xpathStatePool != NULL) {
27581
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27582
0
  ctxt->xpathStatePool = NULL;
27583
0
    }
27584
27585
    /*
27586
    * Augmented IDC information.
27587
    */
27588
6.83k
    if (ctxt->aidcs != NULL) {
27589
0
  xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27590
0
  do {
27591
0
      next = cur->next;
27592
0
      xmlFree(cur);
27593
0
      cur = next;
27594
0
  } while (cur != NULL);
27595
0
    }
27596
6.83k
    if (ctxt->attrInfos != NULL) {
27597
0
  int i;
27598
0
  xmlSchemaAttrInfoPtr attr;
27599
27600
  /* Just a paranoid call to the cleanup. */
27601
0
  if (ctxt->nbAttrInfos != 0)
27602
0
      xmlSchemaClearAttrInfos(ctxt);
27603
0
  for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27604
0
      attr = ctxt->attrInfos[i];
27605
0
      xmlFree(attr);
27606
0
  }
27607
0
  xmlFree(ctxt->attrInfos);
27608
0
    }
27609
6.83k
    if (ctxt->elemInfos != NULL) {
27610
0
  int i;
27611
0
  xmlSchemaNodeInfoPtr ei;
27612
27613
0
  for (i = 0; i < ctxt->sizeElemInfos; i++) {
27614
0
      ei = ctxt->elemInfos[i];
27615
0
      if (ei == NULL)
27616
0
    break;
27617
0
      xmlSchemaClearElemInfo(ctxt, ei);
27618
0
      xmlFree(ei);
27619
0
  }
27620
0
  xmlFree(ctxt->elemInfos);
27621
0
    }
27622
6.83k
    if (ctxt->nodeQNames != NULL)
27623
6.83k
  xmlSchemaItemListFree(ctxt->nodeQNames);
27624
6.83k
    if (ctxt->dict != NULL)
27625
6.83k
  xmlDictFree(ctxt->dict);
27626
6.83k
    if (ctxt->filename != NULL)
27627
0
  xmlFree(ctxt->filename);
27628
6.83k
    xmlFree(ctxt);
27629
6.83k
}
27630
27631
/**
27632
 * xmlSchemaIsValid:
27633
 * @ctxt: the schema validation context
27634
 *
27635
 * Check if any error was detected during validation.
27636
 *
27637
 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27638
 *         of internal error.
27639
 */
27640
int
27641
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27642
0
{
27643
0
    if (ctxt == NULL)
27644
0
        return(-1);
27645
0
    return(ctxt->err == 0);
27646
0
}
27647
27648
/**
27649
 * xmlSchemaSetValidErrors:
27650
 * @ctxt:  a schema validation context
27651
 * @err:  the error function
27652
 * @warn: the warning function
27653
 * @ctx: the functions context
27654
 *
27655
 * DEPRECATED: Use xmlSchemaSetValidStructuredErrors.
27656
 *
27657
 * Set the error and warning callback information
27658
 */
27659
void
27660
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27661
                        xmlSchemaValidityErrorFunc err,
27662
                        xmlSchemaValidityWarningFunc warn, void *ctx)
27663
6.83k
{
27664
6.83k
    if (ctxt == NULL)
27665
0
        return;
27666
6.83k
    ctxt->error = err;
27667
6.83k
    ctxt->warning = warn;
27668
6.83k
    ctxt->errCtxt = ctx;
27669
6.83k
    if (ctxt->pctxt != NULL)
27670
0
  xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27671
6.83k
}
27672
27673
/**
27674
 * xmlSchemaSetValidStructuredErrors:
27675
 * @ctxt:  a schema validation context
27676
 * @serror:  the structured error function
27677
 * @ctx: the functions context
27678
 *
27679
 * Set the structured error callback
27680
 */
27681
void
27682
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27683
          xmlStructuredErrorFunc serror, void *ctx)
27684
6.83k
{
27685
6.83k
    if (ctxt == NULL)
27686
0
        return;
27687
6.83k
    ctxt->serror = serror;
27688
6.83k
    ctxt->error = NULL;
27689
6.83k
    ctxt->warning = NULL;
27690
6.83k
    ctxt->errCtxt = ctx;
27691
6.83k
    if (ctxt->pctxt != NULL)
27692
0
  xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27693
6.83k
}
27694
27695
/**
27696
 * xmlSchemaGetValidErrors:
27697
 * @ctxt: a XML-Schema validation context
27698
 * @err: the error function result
27699
 * @warn: the warning function result
27700
 * @ctx: the functions context result
27701
 *
27702
 * Get the error and warning callback information
27703
 *
27704
 * Returns -1 in case of error and 0 otherwise
27705
 */
27706
int
27707
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27708
      xmlSchemaValidityErrorFunc * err,
27709
      xmlSchemaValidityWarningFunc * warn, void **ctx)
27710
0
{
27711
0
  if (ctxt == NULL)
27712
0
    return (-1);
27713
0
  if (err != NULL)
27714
0
    *err = ctxt->error;
27715
0
  if (warn != NULL)
27716
0
    *warn = ctxt->warning;
27717
0
  if (ctx != NULL)
27718
0
    *ctx = ctxt->errCtxt;
27719
0
  return (0);
27720
0
}
27721
27722
27723
/**
27724
 * xmlSchemaSetValidOptions:
27725
 * @ctxt: a schema validation context
27726
 * @options: a combination of xmlSchemaValidOption
27727
 *
27728
 * Sets the options to be used during the validation.
27729
 *
27730
 * Returns 0 in case of success, -1 in case of an
27731
 * API error.
27732
 */
27733
int
27734
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27735
       int options)
27736
27737
0
{
27738
0
    int i;
27739
27740
0
    if (ctxt == NULL)
27741
0
  return (-1);
27742
    /*
27743
    * WARNING: Change the start value if adding to the
27744
    * xmlSchemaValidOption.
27745
    * TODO: Is there an other, more easy to maintain,
27746
    * way?
27747
    */
27748
0
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
27749
0
        if (options & 1<<i)
27750
0
      return (-1);
27751
0
    }
27752
0
    ctxt->options = options;
27753
0
    return (0);
27754
0
}
27755
27756
/**
27757
 * xmlSchemaValidCtxtGetOptions:
27758
 * @ctxt: a schema validation context
27759
 *
27760
 * Get the validation context options.
27761
 *
27762
 * Returns the option combination or -1 on error.
27763
 */
27764
int
27765
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27766
27767
0
{
27768
0
    if (ctxt == NULL)
27769
0
  return (-1);
27770
0
    else
27771
0
  return (ctxt->options);
27772
0
}
27773
27774
static int
27775
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27776
0
{
27777
0
    xmlAttrPtr attr;
27778
0
    int ret = 0;
27779
0
    xmlSchemaNodeInfoPtr ielem = NULL;
27780
0
    xmlNodePtr node, valRoot;
27781
0
    const xmlChar *nsName;
27782
27783
    /* DOC VAL TODO: Move this to the start function. */
27784
0
    if (vctxt->validationRoot != NULL)
27785
0
        valRoot = vctxt->validationRoot;
27786
0
    else
27787
0
  valRoot = xmlDocGetRootElement(vctxt->doc);
27788
0
    if (valRoot == NULL) {
27789
  /* VAL TODO: Error code? */
27790
0
  VERROR(1, NULL, "The document has no document element");
27791
0
  return (1);
27792
0
    }
27793
0
    vctxt->depth = -1;
27794
0
    vctxt->validationRoot = valRoot;
27795
0
    node = valRoot;
27796
0
    while (node != NULL) {
27797
0
  if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27798
0
      goto next_sibling;
27799
0
  if (node->type == XML_ELEMENT_NODE) {
27800
27801
      /*
27802
      * Init the node-info.
27803
      */
27804
0
      vctxt->depth++;
27805
0
      if (xmlSchemaValidatorPushElem(vctxt) == -1)
27806
0
    goto internal_error;
27807
0
      ielem = vctxt->inode;
27808
0
      ielem->node = node;
27809
0
      ielem->nodeLine = node->line;
27810
0
      ielem->localName = node->name;
27811
0
      if (node->ns != NULL)
27812
0
    ielem->nsName = node->ns->href;
27813
0
      ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27814
      /*
27815
      * Register attributes.
27816
      * DOC VAL TODO: We do not register namespace declaration
27817
      * attributes yet.
27818
      */
27819
0
      vctxt->nbAttrInfos = 0;
27820
0
      if (node->properties != NULL) {
27821
0
    attr = node->properties;
27822
0
    do {
27823
0
        if (attr->ns != NULL)
27824
0
      nsName = attr->ns->href;
27825
0
        else
27826
0
      nsName = NULL;
27827
0
        ret = xmlSchemaValidatorPushAttribute(vctxt,
27828
0
      (xmlNodePtr) attr,
27829
      /*
27830
      * Note that we give it the line number of the
27831
      * parent element.
27832
      */
27833
0
      ielem->nodeLine,
27834
0
      attr->name, nsName, 0,
27835
0
      xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27836
0
        if (ret == -1) {
27837
0
      VERROR_INT("xmlSchemaDocWalk",
27838
0
          "calling xmlSchemaValidatorPushAttribute()");
27839
0
      goto internal_error;
27840
0
        }
27841
0
        attr = attr->next;
27842
0
    } while (attr);
27843
0
      }
27844
      /*
27845
      * Validate the element.
27846
      */
27847
0
      ret = xmlSchemaValidateElem(vctxt);
27848
0
      if (ret != 0) {
27849
0
    if (ret == -1) {
27850
0
        VERROR_INT("xmlSchemaDocWalk",
27851
0
      "calling xmlSchemaValidateElem()");
27852
0
        goto internal_error;
27853
0
    }
27854
    /*
27855
    * Don't stop validation; just skip the content
27856
    * of this element.
27857
    */
27858
0
    goto leave_node;
27859
0
      }
27860
0
      if ((vctxt->skipDepth != -1) &&
27861
0
    (vctxt->depth >= vctxt->skipDepth))
27862
0
    goto leave_node;
27863
0
  } else if ((node->type == XML_TEXT_NODE) ||
27864
0
      (node->type == XML_CDATA_SECTION_NODE)) {
27865
      /*
27866
      * Process character content.
27867
      */
27868
0
      if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27869
0
    ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27870
0
      ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27871
0
    -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27872
0
      if (ret < 0) {
27873
0
    VERROR_INT("xmlSchemaVDocWalk",
27874
0
        "calling xmlSchemaVPushText()");
27875
0
    goto internal_error;
27876
0
      }
27877
      /*
27878
      * DOC VAL TODO: Should we skip further validation of the
27879
      * element content here?
27880
      */
27881
0
  } else if ((node->type == XML_ENTITY_NODE) ||
27882
0
      (node->type == XML_ENTITY_REF_NODE)) {
27883
      /*
27884
      * DOC VAL TODO: What to do with entities?
27885
      */
27886
0
      VERROR_INT("xmlSchemaVDocWalk",
27887
0
    "there is at least one entity reference in the node-tree "
27888
0
    "currently being validated. Processing of entities with "
27889
0
    "this XML Schema processor is not supported (yet). Please "
27890
0
    "substitute entities before validation.");
27891
0
      goto internal_error;
27892
0
  } else {
27893
0
      goto leave_node;
27894
      /*
27895
      * DOC VAL TODO: XInclude nodes, etc.
27896
      */
27897
0
  }
27898
  /*
27899
  * Walk the doc.
27900
  */
27901
0
  if (node->children != NULL) {
27902
0
      node = node->children;
27903
0
      continue;
27904
0
  }
27905
0
leave_node:
27906
0
  if (node->type == XML_ELEMENT_NODE) {
27907
      /*
27908
      * Leaving the scope of an element.
27909
      */
27910
0
      if (node != vctxt->inode->node) {
27911
0
    VERROR_INT("xmlSchemaVDocWalk",
27912
0
        "element position mismatch");
27913
0
    goto internal_error;
27914
0
      }
27915
0
      ret = xmlSchemaValidatorPopElem(vctxt);
27916
0
      if (ret != 0) {
27917
0
    if (ret < 0) {
27918
0
        VERROR_INT("xmlSchemaVDocWalk",
27919
0
      "calling xmlSchemaValidatorPopElem()");
27920
0
        goto internal_error;
27921
0
    }
27922
0
      }
27923
0
      if (node == valRoot)
27924
0
    goto exit;
27925
0
  }
27926
0
next_sibling:
27927
0
  if (node->next != NULL)
27928
0
      node = node->next;
27929
0
  else {
27930
0
      node = node->parent;
27931
0
      goto leave_node;
27932
0
  }
27933
0
    }
27934
27935
0
exit:
27936
0
    return (ret);
27937
0
internal_error:
27938
0
    return (-1);
27939
0
}
27940
27941
static int
27942
0
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27943
    /*
27944
    * Some initialization.
27945
    */
27946
0
    vctxt->err = 0;
27947
0
    vctxt->nberrors = 0;
27948
0
    vctxt->depth = -1;
27949
0
    vctxt->skipDepth = -1;
27950
0
    vctxt->hasKeyrefs = 0;
27951
#ifdef ENABLE_IDC_NODE_TABLES_TEST
27952
    vctxt->createIDCNodeTables = 1;
27953
#else
27954
0
    vctxt->createIDCNodeTables = 0;
27955
0
#endif
27956
    /*
27957
    * Create a schema + parser if necessary.
27958
    */
27959
0
    if (vctxt->schema == NULL) {
27960
0
  xmlSchemaParserCtxtPtr pctxt;
27961
27962
0
  vctxt->xsiAssemble = 1;
27963
  /*
27964
  * If not schema was given then we will create a schema
27965
  * dynamically using XSI schema locations.
27966
  *
27967
  * Create the schema parser context.
27968
  */
27969
0
  if ((vctxt->pctxt == NULL) &&
27970
0
     (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27971
0
     return (-1);
27972
0
  pctxt = vctxt->pctxt;
27973
0
  pctxt->xsiAssemble = 1;
27974
  /*
27975
  * Create the schema.
27976
  */
27977
0
  vctxt->schema = xmlSchemaNewSchema(pctxt);
27978
0
  if (vctxt->schema == NULL)
27979
0
      return (-1);
27980
  /*
27981
  * Create the schema construction context.
27982
  */
27983
0
  pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
27984
0
  if (pctxt->constructor == NULL)
27985
0
      return(-1);
27986
0
  pctxt->constructor->mainSchema = vctxt->schema;
27987
  /*
27988
  * Take ownership of the constructor to be able to free it.
27989
  */
27990
0
  pctxt->ownsConstructor = 1;
27991
0
    }
27992
    /*
27993
    * Augment the IDC definitions for the main schema and all imported ones
27994
    * NOTE: main schema if the first in the imported list
27995
    */
27996
0
    xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
27997
0
                vctxt);
27998
27999
0
    return(0);
28000
0
}
28001
28002
static void
28003
0
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28004
0
    if (vctxt->xsiAssemble) {
28005
0
  if (vctxt->schema != NULL) {
28006
0
      xmlSchemaFree(vctxt->schema);
28007
0
      vctxt->schema = NULL;
28008
0
  }
28009
0
    }
28010
0
    xmlSchemaClearValidCtxt(vctxt);
28011
0
}
28012
28013
static int
28014
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28015
0
{
28016
0
    int ret = 0;
28017
28018
0
    if (xmlSchemaPreRun(vctxt) < 0)
28019
0
        return(-1);
28020
28021
0
    if (vctxt->doc != NULL) {
28022
  /*
28023
   * Tree validation.
28024
   */
28025
0
  ret = xmlSchemaVDocWalk(vctxt);
28026
0
#ifdef LIBXML_READER_ENABLED
28027
0
    } else if (vctxt->reader != NULL) {
28028
  /*
28029
   * XML Reader validation.
28030
   */
28031
#ifdef XML_SCHEMA_READER_ENABLED
28032
  ret = xmlSchemaVReaderWalk(vctxt);
28033
#endif
28034
0
#endif
28035
0
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28036
  /*
28037
   * SAX validation.
28038
   */
28039
0
  ret = xmlParseDocument(vctxt->parserCtxt);
28040
0
    } else {
28041
0
  VERROR_INT("xmlSchemaVStart",
28042
0
      "no instance to validate");
28043
0
  ret = -1;
28044
0
    }
28045
28046
0
    xmlSchemaPostRun(vctxt);
28047
0
    if (ret == 0)
28048
0
  ret = vctxt->err;
28049
0
    return (ret);
28050
0
}
28051
28052
/**
28053
 * xmlSchemaValidateOneElement:
28054
 * @ctxt:  a schema validation context
28055
 * @elem:  an element node
28056
 *
28057
 * Validate a branch of a tree, starting with the given @elem.
28058
 *
28059
 * Returns 0 if the element and its subtree is valid, a positive error
28060
 * code number otherwise and -1 in case of an internal or API error.
28061
 */
28062
int
28063
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28064
0
{
28065
0
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28066
0
  return (-1);
28067
28068
0
    if (ctxt->schema == NULL)
28069
0
  return (-1);
28070
28071
0
    ctxt->doc = elem->doc;
28072
0
    ctxt->node = elem;
28073
0
    ctxt->validationRoot = elem;
28074
0
    return(xmlSchemaVStart(ctxt));
28075
0
}
28076
28077
/**
28078
 * xmlSchemaValidateDoc:
28079
 * @ctxt:  a schema validation context
28080
 * @doc:  a parsed document tree
28081
 *
28082
 * Validate a document tree in memory.
28083
 *
28084
 * Returns 0 if the document is schemas valid, a positive error code
28085
 *     number otherwise and -1 in case of internal or API error.
28086
 */
28087
int
28088
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28089
0
{
28090
0
    if ((ctxt == NULL) || (doc == NULL))
28091
0
        return (-1);
28092
28093
0
    ctxt->doc = doc;
28094
0
    ctxt->node = xmlDocGetRootElement(doc);
28095
0
    if (ctxt->node == NULL) {
28096
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
28097
0
      XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28098
0
      (xmlNodePtr) doc, NULL,
28099
0
      "The document has no document element", NULL, NULL);
28100
0
        return (ctxt->err);
28101
0
    }
28102
0
    ctxt->validationRoot = ctxt->node;
28103
0
    return (xmlSchemaVStart(ctxt));
28104
0
}
28105
28106
28107
/************************************************************************
28108
 *                  *
28109
 *    Function and data for SAX streaming API     *
28110
 *                  *
28111
 ************************************************************************/
28112
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28113
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28114
28115
struct _xmlSchemaSplitSAXData {
28116
    xmlSAXHandlerPtr      user_sax;
28117
    void                 *user_data;
28118
    xmlSchemaValidCtxtPtr ctxt;
28119
    xmlSAXHandlerPtr      schemas_sax;
28120
};
28121
28122
0
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28123
28124
struct _xmlSchemaSAXPlug {
28125
    unsigned int magic;
28126
28127
    /* the original callbacks information */
28128
    xmlSAXHandlerPtr     *user_sax_ptr;
28129
    xmlSAXHandlerPtr      user_sax;
28130
    void                **user_data_ptr;
28131
    void                 *user_data;
28132
28133
    /* the block plugged back and validation information */
28134
    xmlSAXHandler         schemas_sax;
28135
    xmlSchemaValidCtxtPtr ctxt;
28136
};
28137
28138
/* All those functions just bounces to the user provided SAX handlers */
28139
static void
28140
internalSubsetSplit(void *ctx, const xmlChar *name,
28141
         const xmlChar *ExternalID, const xmlChar *SystemID)
28142
0
{
28143
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28144
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28145
0
        (ctxt->user_sax->internalSubset != NULL))
28146
0
  ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28147
0
                                 SystemID);
28148
0
}
28149
28150
static int
28151
isStandaloneSplit(void *ctx)
28152
0
{
28153
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28154
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28155
0
        (ctxt->user_sax->isStandalone != NULL))
28156
0
  return(ctxt->user_sax->isStandalone(ctxt->user_data));
28157
0
    return(0);
28158
0
}
28159
28160
static int
28161
hasInternalSubsetSplit(void *ctx)
28162
0
{
28163
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28164
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28165
0
        (ctxt->user_sax->hasInternalSubset != NULL))
28166
0
  return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28167
0
    return(0);
28168
0
}
28169
28170
static int
28171
hasExternalSubsetSplit(void *ctx)
28172
0
{
28173
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28174
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28175
0
        (ctxt->user_sax->hasExternalSubset != NULL))
28176
0
  return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28177
0
    return(0);
28178
0
}
28179
28180
static void
28181
externalSubsetSplit(void *ctx, const xmlChar *name,
28182
         const xmlChar *ExternalID, const xmlChar *SystemID)
28183
0
{
28184
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28185
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28186
0
        (ctxt->user_sax->externalSubset != NULL))
28187
0
  ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28188
0
                                 SystemID);
28189
0
}
28190
28191
static xmlParserInputPtr
28192
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28193
0
{
28194
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28195
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28196
0
        (ctxt->user_sax->resolveEntity != NULL))
28197
0
  return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28198
0
                                       systemId));
28199
0
    return(NULL);
28200
0
}
28201
28202
static xmlEntityPtr
28203
getEntitySplit(void *ctx, const xmlChar *name)
28204
0
{
28205
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28206
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28207
0
        (ctxt->user_sax->getEntity != NULL))
28208
0
  return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28209
0
    return(NULL);
28210
0
}
28211
28212
static xmlEntityPtr
28213
getParameterEntitySplit(void *ctx, const xmlChar *name)
28214
0
{
28215
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28216
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28217
0
        (ctxt->user_sax->getParameterEntity != NULL))
28218
0
  return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28219
0
    return(NULL);
28220
0
}
28221
28222
28223
static void
28224
entityDeclSplit(void *ctx, const xmlChar *name, int type,
28225
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28226
0
{
28227
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28228
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28229
0
        (ctxt->user_sax->entityDecl != NULL))
28230
0
  ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28231
0
                             systemId, content);
28232
0
}
28233
28234
static void
28235
attributeDeclSplit(void *ctx, const xmlChar * elem,
28236
                   const xmlChar * name, int type, int def,
28237
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
28238
0
{
28239
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28240
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28241
0
        (ctxt->user_sax->attributeDecl != NULL)) {
28242
0
  ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28243
0
                                def, defaultValue, tree);
28244
0
    } else {
28245
0
  xmlFreeEnumeration(tree);
28246
0
    }
28247
0
}
28248
28249
static void
28250
elementDeclSplit(void *ctx, const xmlChar *name, int type,
28251
      xmlElementContentPtr content)
28252
0
{
28253
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28254
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28255
0
        (ctxt->user_sax->elementDecl != NULL))
28256
0
  ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28257
0
}
28258
28259
static void
28260
notationDeclSplit(void *ctx, const xmlChar *name,
28261
       const xmlChar *publicId, const xmlChar *systemId)
28262
0
{
28263
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28264
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28265
0
        (ctxt->user_sax->notationDecl != NULL))
28266
0
  ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28267
0
                               systemId);
28268
0
}
28269
28270
static void
28271
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28272
       const xmlChar *publicId, const xmlChar *systemId,
28273
       const xmlChar *notationName)
28274
0
{
28275
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28276
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28277
0
        (ctxt->user_sax->unparsedEntityDecl != NULL))
28278
0
  ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28279
0
                                     systemId, notationName);
28280
0
}
28281
28282
static void
28283
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28284
0
{
28285
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28286
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28287
0
        (ctxt->user_sax->setDocumentLocator != NULL))
28288
0
  ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28289
0
}
28290
28291
static void
28292
startDocumentSplit(void *ctx)
28293
0
{
28294
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28295
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28296
0
        (ctxt->user_sax->startDocument != NULL))
28297
0
  ctxt->user_sax->startDocument(ctxt->user_data);
28298
0
}
28299
28300
static void
28301
endDocumentSplit(void *ctx)
28302
0
{
28303
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28304
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28305
0
        (ctxt->user_sax->endDocument != NULL))
28306
0
  ctxt->user_sax->endDocument(ctxt->user_data);
28307
0
}
28308
28309
static void
28310
processingInstructionSplit(void *ctx, const xmlChar *target,
28311
                      const xmlChar *data)
28312
0
{
28313
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28314
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28315
0
        (ctxt->user_sax->processingInstruction != NULL))
28316
0
  ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28317
0
}
28318
28319
static void
28320
commentSplit(void *ctx, const xmlChar *value)
28321
0
{
28322
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28323
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28324
0
        (ctxt->user_sax->comment != NULL))
28325
0
  ctxt->user_sax->comment(ctxt->user_data, value);
28326
0
}
28327
28328
/*
28329
 * Varargs error callbacks to the user application, harder ...
28330
 */
28331
28332
static void
28333
0
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28334
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28335
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28336
0
        (ctxt->user_sax->warning != NULL)) {
28337
  /* TODO */
28338
0
    }
28339
0
}
28340
static void
28341
0
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28342
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28343
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28344
0
        (ctxt->user_sax->error != NULL)) {
28345
  /* TODO */
28346
0
    }
28347
0
}
28348
static void
28349
0
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28350
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28351
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28352
0
        (ctxt->user_sax->fatalError != NULL)) {
28353
  /* TODO */
28354
0
    }
28355
0
}
28356
28357
/*
28358
 * Those are function where both the user handler and the schemas handler
28359
 * need to be called.
28360
 */
28361
static void
28362
charactersSplit(void *ctx, const xmlChar *ch, int len)
28363
0
{
28364
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28365
0
    if (ctxt == NULL)
28366
0
        return;
28367
0
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28368
0
  ctxt->user_sax->characters(ctxt->user_data, ch, len);
28369
0
    if (ctxt->ctxt != NULL)
28370
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28371
0
}
28372
28373
static void
28374
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28375
0
{
28376
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28377
0
    if (ctxt == NULL)
28378
0
        return;
28379
0
    if ((ctxt->user_sax != NULL) &&
28380
0
        (ctxt->user_sax->ignorableWhitespace != NULL))
28381
0
  ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28382
0
    if (ctxt->ctxt != NULL)
28383
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28384
0
}
28385
28386
static void
28387
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28388
0
{
28389
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28390
0
    if (ctxt == NULL)
28391
0
        return;
28392
0
    if ((ctxt->user_sax != NULL) &&
28393
0
        (ctxt->user_sax->cdataBlock != NULL))
28394
0
  ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28395
0
    if (ctxt->ctxt != NULL)
28396
0
  xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28397
0
}
28398
28399
static void
28400
referenceSplit(void *ctx, const xmlChar *name)
28401
0
{
28402
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28403
0
    if (ctxt == NULL)
28404
0
        return;
28405
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28406
0
        (ctxt->user_sax->reference != NULL))
28407
0
  ctxt->user_sax->reference(ctxt->user_data, name);
28408
0
    if (ctxt->ctxt != NULL)
28409
0
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
28410
0
}
28411
28412
static void
28413
startElementNsSplit(void *ctx, const xmlChar * localname,
28414
        const xmlChar * prefix, const xmlChar * URI,
28415
        int nb_namespaces, const xmlChar ** namespaces,
28416
        int nb_attributes, int nb_defaulted,
28417
0
        const xmlChar ** attributes) {
28418
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28419
0
    if (ctxt == NULL)
28420
0
        return;
28421
0
    if ((ctxt->user_sax != NULL) &&
28422
0
        (ctxt->user_sax->startElementNs != NULL))
28423
0
  ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28424
0
                                 URI, nb_namespaces, namespaces,
28425
0
               nb_attributes, nb_defaulted,
28426
0
               attributes);
28427
0
    if (ctxt->ctxt != NULL)
28428
0
  xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28429
0
                                   URI, nb_namespaces, namespaces,
28430
0
           nb_attributes, nb_defaulted,
28431
0
           attributes);
28432
0
}
28433
28434
static void
28435
endElementNsSplit(void *ctx, const xmlChar * localname,
28436
0
        const xmlChar * prefix, const xmlChar * URI) {
28437
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28438
0
    if (ctxt == NULL)
28439
0
        return;
28440
0
    if ((ctxt->user_sax != NULL) &&
28441
0
        (ctxt->user_sax->endElementNs != NULL))
28442
0
  ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28443
0
    if (ctxt->ctxt != NULL)
28444
0
  xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28445
0
}
28446
28447
/**
28448
 * xmlSchemaSAXPlug:
28449
 * @ctxt:  a schema validation context
28450
 * @sax:  a pointer to the original xmlSAXHandlerPtr
28451
 * @user_data:  a pointer to the original SAX user data pointer
28452
 *
28453
 * Plug a SAX based validation layer in a SAX parsing event flow.
28454
 * The original @saxptr and @dataptr data are replaced by new pointers
28455
 * but the calls to the original will be maintained.
28456
 *
28457
 * Returns a pointer to a data structure needed to unplug the validation layer
28458
 *         or NULL in case of errors.
28459
 */
28460
xmlSchemaSAXPlugPtr
28461
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28462
     xmlSAXHandlerPtr *sax, void **user_data)
28463
0
{
28464
0
    xmlSchemaSAXPlugPtr ret;
28465
0
    xmlSAXHandlerPtr old_sax;
28466
28467
0
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28468
0
        return(NULL);
28469
28470
    /*
28471
     * We only allow to plug into SAX2 event streams
28472
     */
28473
0
    old_sax = *sax;
28474
0
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28475
0
        return(NULL);
28476
0
    if ((old_sax != NULL) &&
28477
0
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28478
0
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28479
0
        return(NULL);
28480
28481
    /*
28482
     * everything seems right allocate the local data needed for that layer
28483
     */
28484
0
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28485
0
    if (ret == NULL) {
28486
0
        return(NULL);
28487
0
    }
28488
0
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28489
0
    ret->magic = XML_SAX_PLUG_MAGIC;
28490
0
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28491
0
    ret->ctxt = ctxt;
28492
0
    ret->user_sax_ptr = sax;
28493
0
    ret->user_sax = old_sax;
28494
0
    if (old_sax == NULL) {
28495
        /*
28496
   * go direct, no need for the split block and functions.
28497
   */
28498
0
  ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28499
0
  ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28500
  /*
28501
   * Note that we use the same text-function for both, to prevent
28502
   * the parser from testing for ignorable whitespace.
28503
   */
28504
0
  ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28505
0
  ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28506
28507
0
  ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28508
0
  ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28509
28510
0
  ret->user_data = ctxt;
28511
0
  *user_data = ctxt;
28512
0
    } else {
28513
       /*
28514
        * for each callback unused by Schemas initialize it to the Split
28515
  * routine only if non NULL in the user block, this can speed up
28516
  * things at the SAX level.
28517
  */
28518
0
        if (old_sax->internalSubset != NULL)
28519
0
            ret->schemas_sax.internalSubset = internalSubsetSplit;
28520
0
        if (old_sax->isStandalone != NULL)
28521
0
            ret->schemas_sax.isStandalone = isStandaloneSplit;
28522
0
        if (old_sax->hasInternalSubset != NULL)
28523
0
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28524
0
        if (old_sax->hasExternalSubset != NULL)
28525
0
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28526
0
        if (old_sax->resolveEntity != NULL)
28527
0
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
28528
0
        if (old_sax->getEntity != NULL)
28529
0
            ret->schemas_sax.getEntity = getEntitySplit;
28530
0
        if (old_sax->entityDecl != NULL)
28531
0
            ret->schemas_sax.entityDecl = entityDeclSplit;
28532
0
        if (old_sax->notationDecl != NULL)
28533
0
            ret->schemas_sax.notationDecl = notationDeclSplit;
28534
0
        if (old_sax->attributeDecl != NULL)
28535
0
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
28536
0
        if (old_sax->elementDecl != NULL)
28537
0
            ret->schemas_sax.elementDecl = elementDeclSplit;
28538
0
        if (old_sax->unparsedEntityDecl != NULL)
28539
0
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28540
0
        if (old_sax->setDocumentLocator != NULL)
28541
0
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28542
0
        if (old_sax->startDocument != NULL)
28543
0
            ret->schemas_sax.startDocument = startDocumentSplit;
28544
0
        if (old_sax->endDocument != NULL)
28545
0
            ret->schemas_sax.endDocument = endDocumentSplit;
28546
0
        if (old_sax->processingInstruction != NULL)
28547
0
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
28548
0
        if (old_sax->comment != NULL)
28549
0
            ret->schemas_sax.comment = commentSplit;
28550
0
        if (old_sax->warning != NULL)
28551
0
            ret->schemas_sax.warning = warningSplit;
28552
0
        if (old_sax->error != NULL)
28553
0
            ret->schemas_sax.error = errorSplit;
28554
0
        if (old_sax->fatalError != NULL)
28555
0
            ret->schemas_sax.fatalError = fatalErrorSplit;
28556
0
        if (old_sax->getParameterEntity != NULL)
28557
0
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28558
0
        if (old_sax->externalSubset != NULL)
28559
0
            ret->schemas_sax.externalSubset = externalSubsetSplit;
28560
28561
  /*
28562
   * the 6 schemas callback have to go to the splitter functions
28563
   * Note that we use the same text-function for ignorableWhitespace
28564
   * if possible, to prevent the parser from testing for ignorable
28565
   * whitespace.
28566
   */
28567
0
        ret->schemas_sax.characters = charactersSplit;
28568
0
  if ((old_sax->ignorableWhitespace != NULL) &&
28569
0
      (old_sax->ignorableWhitespace != old_sax->characters))
28570
0
      ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28571
0
  else
28572
0
      ret->schemas_sax.ignorableWhitespace = charactersSplit;
28573
0
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
28574
0
        ret->schemas_sax.reference = referenceSplit;
28575
0
        ret->schemas_sax.startElementNs = startElementNsSplit;
28576
0
        ret->schemas_sax.endElementNs = endElementNsSplit;
28577
28578
0
  ret->user_data_ptr = user_data;
28579
0
  ret->user_data = *user_data;
28580
0
  *user_data = ret;
28581
0
    }
28582
28583
    /*
28584
     * plug the pointers back.
28585
     */
28586
0
    *sax = &(ret->schemas_sax);
28587
0
    ctxt->sax = *sax;
28588
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28589
0
    xmlSchemaPreRun(ctxt);
28590
0
    return(ret);
28591
0
}
28592
28593
/**
28594
 * xmlSchemaSAXUnplug:
28595
 * @plug:  a data structure returned by xmlSchemaSAXPlug
28596
 *
28597
 * Unplug a SAX based validation layer in a SAX parsing event flow.
28598
 * The original pointers used in the call are restored.
28599
 *
28600
 * Returns 0 in case of success and -1 in case of failure.
28601
 */
28602
int
28603
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28604
0
{
28605
0
    xmlSAXHandlerPtr *sax;
28606
0
    void **user_data;
28607
28608
0
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28609
0
        return(-1);
28610
0
    plug->magic = 0;
28611
28612
0
    xmlSchemaPostRun(plug->ctxt);
28613
    /* restore the data */
28614
0
    sax = plug->user_sax_ptr;
28615
0
    *sax = plug->user_sax;
28616
0
    if (plug->user_sax != NULL) {
28617
0
  user_data = plug->user_data_ptr;
28618
0
  *user_data = plug->user_data;
28619
0
    }
28620
28621
    /* free and return */
28622
0
    xmlFree(plug);
28623
0
    return(0);
28624
0
}
28625
28626
/**
28627
 * xmlSchemaValidateSetLocator:
28628
 * @vctxt: a schema validation context
28629
 * @f: the locator function pointer
28630
 * @ctxt: the locator context
28631
 *
28632
 * Allows to set a locator function to the validation context,
28633
 * which will be used to provide file and line information since
28634
 * those are not provided as part of the SAX validation flow
28635
 * Setting @f to NULL disable the locator.
28636
 */
28637
28638
void
28639
xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
28640
                            xmlSchemaValidityLocatorFunc f,
28641
          void *ctxt)
28642
0
{
28643
0
    if (vctxt == NULL) return;
28644
0
    vctxt->locFunc = f;
28645
0
    vctxt->locCtxt = ctxt;
28646
0
}
28647
28648
/**
28649
 * xmlSchemaValidateStreamLocator:
28650
 * @ctx: the xmlTextReaderPtr used
28651
 * @file: returned file information
28652
 * @line: returned line information
28653
 *
28654
 * Internal locator function for the readers
28655
 *
28656
 * Returns 0 in case the Schema validation could be (de)activated and
28657
 *         -1 in case of error.
28658
 */
28659
static int
28660
xmlSchemaValidateStreamLocator(void *ctx, const char **file,
28661
0
                               unsigned long *line) {
28662
0
    xmlParserCtxtPtr ctxt;
28663
28664
0
    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
28665
0
        return(-1);
28666
28667
0
    if (file != NULL)
28668
0
        *file = NULL;
28669
0
    if (line != NULL)
28670
0
        *line = 0;
28671
28672
0
    ctxt = (xmlParserCtxtPtr) ctx;
28673
0
    if (ctxt->input != NULL) {
28674
0
       if (file != NULL)
28675
0
           *file = ctxt->input->filename;
28676
0
       if (line != NULL)
28677
0
           *line = ctxt->input->line;
28678
0
       return(0);
28679
0
    }
28680
0
    return(-1);
28681
0
}
28682
28683
/**
28684
 * xmlSchemaValidateStreamInternal:
28685
 * @ctxt:  a schema validation context
28686
 * @pctxt:  a parser context
28687
 *
28688
 * Returns 0 if the document is schemas valid, a positive error code
28689
 *     number otherwise and -1 in case of internal or API error.
28690
 */
28691
static int
28692
xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
28693
0
                                 xmlParserCtxtPtr pctxt) {
28694
0
    xmlSchemaSAXPlugPtr plug = NULL;
28695
0
    int ret;
28696
28697
0
    pctxt->linenumbers = 1;
28698
0
    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
28699
28700
0
    ctxt->parserCtxt = pctxt;
28701
0
    ctxt->input = pctxt->input->buf;
28702
28703
    /*
28704
     * Plug the validation and launch the parsing
28705
     */
28706
0
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28707
0
    if (plug == NULL) {
28708
0
        ret = -1;
28709
0
  goto done;
28710
0
    }
28711
0
    ctxt->input = pctxt->input->buf;
28712
0
    ctxt->sax = pctxt->sax;
28713
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28714
0
    ret = xmlSchemaVStart(ctxt);
28715
28716
0
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28717
0
  ret = ctxt->parserCtxt->errNo;
28718
0
  if (ret == 0)
28719
0
      ret = 1;
28720
0
    }
28721
28722
0
done:
28723
0
    ctxt->parserCtxt = NULL;
28724
0
    ctxt->sax = NULL;
28725
0
    ctxt->input = NULL;
28726
0
    if (plug != NULL) {
28727
0
        xmlSchemaSAXUnplug(plug);
28728
0
    }
28729
0
    return (ret);
28730
0
}
28731
28732
/**
28733
 * xmlSchemaValidateStream:
28734
 * @ctxt:  a schema validation context
28735
 * @input:  the input to use for reading the data
28736
 * @enc:  an optional encoding information
28737
 * @sax:  a SAX handler for the resulting events
28738
 * @user_data:  the context to provide to the SAX handler.
28739
 *
28740
 * Validate an input based on a flow of SAX event from the parser
28741
 * and forward the events to the @sax handler with the provided @user_data
28742
 * the user provided @sax handler must be a SAX2 one.
28743
 *
28744
 * Returns 0 if the document is schemas valid, a positive error code
28745
 *     number otherwise and -1 in case of internal or API error.
28746
 */
28747
int
28748
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28749
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
28750
                        xmlSAXHandlerPtr sax, void *user_data)
28751
0
{
28752
0
    xmlParserCtxtPtr pctxt = NULL;
28753
0
    xmlParserInputPtr inputStream = NULL;
28754
0
    int ret;
28755
28756
0
    if ((ctxt == NULL) || (input == NULL))
28757
0
        return (-1);
28758
28759
    /*
28760
     * prepare the parser
28761
     */
28762
0
    if (sax != NULL) {
28763
0
        pctxt = xmlNewSAXParserCtxt(sax, user_data);
28764
0
        if (pctxt == NULL)
28765
0
            return (-1);
28766
0
    } else {
28767
0
        pctxt = xmlNewParserCtxt();
28768
0
        if (pctxt == NULL)
28769
0
            return (-1);
28770
        /* We really want pctxt->sax to be NULL here. */
28771
0
        xmlFree(pctxt->sax);
28772
0
        pctxt->sax = NULL;
28773
0
    }
28774
#if 0
28775
    if (options)
28776
        xmlCtxtUseOptions(pctxt, options);
28777
#endif
28778
28779
0
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28780
0
    if (inputStream == NULL) {
28781
0
        ret = -1;
28782
0
  goto done;
28783
0
    }
28784
0
    inputPush(pctxt, inputStream);
28785
28786
0
    ctxt->enc = enc;
28787
28788
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28789
28790
0
done:
28791
    /* cleanup */
28792
0
    if (pctxt != NULL) {
28793
0
  xmlFreeParserCtxt(pctxt);
28794
0
    }
28795
0
    return (ret);
28796
0
}
28797
28798
/**
28799
 * xmlSchemaValidateFile:
28800
 * @ctxt: a schema validation context
28801
 * @filename: the URI of the instance
28802
 * @options: a future set of options, currently unused
28803
 *
28804
 * Do a schemas validation of the given resource, it will use the
28805
 * SAX streamable validation internally.
28806
 *
28807
 * Returns 0 if the document is valid, a positive error code
28808
 *     number otherwise and -1 in case of an internal or API error.
28809
 */
28810
int
28811
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28812
                      const char * filename,
28813
          int options ATTRIBUTE_UNUSED)
28814
0
{
28815
0
    int ret;
28816
0
    xmlParserCtxtPtr pctxt = NULL;
28817
28818
0
    if ((ctxt == NULL) || (filename == NULL))
28819
0
        return (-1);
28820
28821
0
    pctxt = xmlCreateURLParserCtxt(filename, 0);
28822
0
    if (pctxt == NULL)
28823
0
  return (-1);
28824
    /* We really want pctxt->sax to be NULL here. */
28825
0
    xmlFree(pctxt->sax);
28826
0
    pctxt->sax = NULL;
28827
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28828
0
    xmlFreeParserCtxt(pctxt);
28829
0
    return (ret);
28830
0
}
28831
28832
/**
28833
 * xmlSchemaValidCtxtGetParserCtxt:
28834
 * @ctxt: a schema validation context
28835
 *
28836
 * allow access to the parser context of the schema validation context
28837
 *
28838
 * Returns the parser context of the schema validation context or NULL
28839
 *         in case of error.
28840
 */
28841
xmlParserCtxtPtr
28842
xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28843
0
{
28844
0
    if (ctxt == NULL)
28845
0
        return(NULL);
28846
0
    return (ctxt->parserCtxt);
28847
0
}
28848
28849
#endif /* LIBXML_SCHEMAS_ENABLED */