Coverage Report

Created: 2024-08-27 12:19

/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 DEBUG 1 */
83
84
/* #define DEBUG_CONTENT 1 */
85
86
/* #define DEBUG_TYPE 1 */
87
88
/* #define DEBUG_CONTENT_REGEXP 1 */
89
90
/* #define DEBUG_AUTOMATA 1 */
91
92
/* #define DEBUG_IDC */
93
94
/* #define DEBUG_IDC_NODE_TABLE */
95
96
/* #define WXS_ELEM_DECL_CONS_ENABLED */
97
98
#ifdef DEBUG_IDC
99
 #ifndef DEBUG_IDC_NODE_TABLE
100
  #define DEBUG_IDC_NODE_TABLE
101
 #endif
102
#endif
103
104
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
105
106
#define ENABLE_REDEFINE
107
108
/* #define ENABLE_NAMED_LOCALS */
109
110
/* #define ENABLE_IDC_NODE_TABLES_TEST */
111
112
#define DUMP_CONTENT_MODEL
113
114
#ifdef LIBXML_READER_ENABLED
115
/* #define XML_SCHEMA_READER_ENABLED */
116
#endif
117
118
0
#define UNBOUNDED (1 << 30)
119
#define TODO                \
120
0
    xmlGenericError(xmlGenericErrorContext,       \
121
0
      "Unimplemented block at %s:%d\n",       \
122
0
            __FILE__, __LINE__);
123
124
0
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
125
126
/*
127
 * The XML Schemas namespaces
128
 */
129
static const xmlChar *xmlSchemaNs = (const xmlChar *)
130
    "http://www.w3.org/2001/XMLSchema";
131
132
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
133
    "http://www.w3.org/2001/XMLSchema-instance";
134
135
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
136
    "http://www.w3.org/2000/xmlns/";
137
138
/*
139
* Come casting macros.
140
*/
141
0
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
142
0
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
143
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
144
0
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
145
0
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
146
0
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
147
0
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
148
0
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
149
0
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
150
0
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
151
0
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
152
0
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
153
0
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
154
0
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
155
0
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
156
0
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
157
0
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
158
159
/*
160
* Macros to query common properties of components.
161
*/
162
0
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
163
164
0
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
165
/*
166
* Macros for element declarations.
167
*/
168
0
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
169
170
0
#define WXS_SUBST_HEAD(item) (item)->refDecl
171
/*
172
* Macros for attribute declarations.
173
*/
174
0
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
175
/*
176
* Macros for attribute uses.
177
*/
178
0
#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
179
180
0
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
181
182
0
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
183
184
0
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
185
/*
186
* Macros for attribute groups.
187
*/
188
0
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
189
0
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
190
/*
191
* Macros for particles.
192
*/
193
0
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
194
195
0
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
196
197
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
198
199
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
200
/*
201
* Macros for model groups definitions.
202
*/
203
0
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
204
/*
205
* Macros for model groups.
206
*/
207
#define WXS_IS_MODEL_GROUP(i) \
208
0
    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
209
0
     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
210
0
     ((i)->type == XML_SCHEMA_TYPE_ALL))
211
212
0
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
213
/*
214
* Macros for schema buckets.
215
*/
216
0
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
217
0
    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
218
219
0
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
220
0
    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
221
222
0
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
223
224
0
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
225
/*
226
* Macros for complex/simple types.
227
*/
228
#define WXS_IS_ANYTYPE(i) \
229
0
     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
230
0
      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
231
232
#define WXS_IS_COMPLEX(i) \
233
0
    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
234
0
     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
235
236
#define WXS_IS_SIMPLE(item) \
237
0
    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
238
0
     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
239
0
      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
240
241
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
242
0
    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
243
0
      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
244
245
#define WXS_IS_RESTRICTION(t) \
246
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
247
248
#define WXS_IS_EXTENSION(t) \
249
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
250
251
#define WXS_IS_TYPE_NOT_FIXED(i) \
252
0
    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
253
0
     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
254
255
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
256
0
    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
257
0
     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
258
259
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
260
261
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
262
/*
263
* Macros for exclusively for complex types.
264
*/
265
#define WXS_HAS_COMPLEX_CONTENT(item) \
266
    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
267
     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
268
     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
269
270
#define WXS_HAS_SIMPLE_CONTENT(item) \
271
0
    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
272
0
     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
273
274
#define WXS_HAS_MIXED_CONTENT(item) \
275
0
    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
276
277
#define WXS_EMPTIABLE(t) \
278
0
    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
279
280
0
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
281
282
0
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
283
284
0
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
285
/*
286
* Macros for exclusively for simple types.
287
*/
288
0
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
289
290
0
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
291
292
0
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
293
294
0
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
295
/*
296
* Misc parser context macros.
297
*/
298
0
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
299
300
0
#define WXS_HAS_BUCKETS(ctx) \
301
0
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
302
0
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
303
304
0
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
305
306
0
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
307
308
#define WXS_SCHEMA(ctx) (ctx)->schema
309
310
#define WXS_ADD_LOCAL(ctx, item) \
311
0
    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
312
313
#define WXS_ADD_GLOBAL(ctx, item) \
314
0
    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
315
316
#define WXS_ADD_PENDING(ctx, item) \
317
0
    xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
318
/*
319
* xmlSchemaItemList macros.
320
*/
321
0
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
322
/*
323
* Misc macros.
324
*/
325
#define IS_SCHEMA(node, type) \
326
0
   ((node != NULL) && (node->ns != NULL) && \
327
0
    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
328
0
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
329
330
0
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
331
332
/*
333
* Since we put the default/fixed values into the dict, we can
334
* use pointer comparison for those values.
335
* REMOVED: (xmlStrEqual((v1), (v2)))
336
*/
337
0
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
338
339
0
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
340
341
0
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
342
343
0
#define HFAILURE if (res == -1) goto exit_failure;
344
345
0
#define HERROR if (res != 0) goto exit_error;
346
347
0
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
348
/*
349
* Some flags used for various schema constraints.
350
*/
351
0
#define SUBSET_RESTRICTION  1<<0
352
0
#define SUBSET_EXTENSION    1<<1
353
#define SUBSET_SUBSTITUTION 1<<2
354
#define SUBSET_LIST         1<<3
355
#define SUBSET_UNION        1<<4
356
357
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
358
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
359
360
typedef struct _xmlSchemaItemList xmlSchemaItemList;
361
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
362
struct _xmlSchemaItemList {
363
    void **items;  /* used for dynamic addition of schemata */
364
    int nbItems; /* used for dynamic addition of schemata */
365
    int sizeItems; /* used for dynamic addition of schemata */
366
};
367
368
0
#define XML_SCHEMA_CTXT_PARSER 1
369
0
#define XML_SCHEMA_CTXT_VALIDATOR 2
370
371
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
372
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
373
struct _xmlSchemaAbstractCtxt {
374
    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
375
    void *dummy; /* Fix alignment issues */
376
};
377
378
typedef struct _xmlSchemaBucket xmlSchemaBucket;
379
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
380
381
0
#define XML_SCHEMA_SCHEMA_MAIN 0
382
0
#define XML_SCHEMA_SCHEMA_IMPORT 1
383
0
#define XML_SCHEMA_SCHEMA_INCLUDE 2
384
0
#define XML_SCHEMA_SCHEMA_REDEFINE 3
385
386
/**
387
 * xmlSchemaSchemaRelation:
388
 *
389
 * Used to create a graph of schema relationships.
390
 */
391
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
392
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
393
struct _xmlSchemaSchemaRelation {
394
    xmlSchemaSchemaRelationPtr next;
395
    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
396
    const xmlChar *importNamespace;
397
    xmlSchemaBucketPtr bucket;
398
};
399
400
0
#define XML_SCHEMA_BUCKET_MARKED 1<<0
401
0
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
402
403
struct _xmlSchemaBucket {
404
    int type;
405
    int flags;
406
    const xmlChar *schemaLocation;
407
    const xmlChar *origTargetNamespace;
408
    const xmlChar *targetNamespace;
409
    xmlDocPtr doc;
410
    xmlSchemaSchemaRelationPtr relations;
411
    int located;
412
    int parsed;
413
    int imported;
414
    int preserveDoc;
415
    xmlSchemaItemListPtr globals; /* Global components. */
416
    xmlSchemaItemListPtr locals; /* Local components. */
417
};
418
419
/**
420
 * xmlSchemaImport:
421
 * (extends xmlSchemaBucket)
422
 *
423
 * Reflects a schema. Holds some information
424
 * about the schema and its toplevel components. Duplicate
425
 * toplevel components are not checked at this level.
426
 */
427
typedef struct _xmlSchemaImport xmlSchemaImport;
428
typedef xmlSchemaImport *xmlSchemaImportPtr;
429
struct _xmlSchemaImport {
430
    int type; /* Main OR import OR include. */
431
    int flags;
432
    const xmlChar *schemaLocation; /* The URI of the schema document. */
433
    /* For chameleon includes, @origTargetNamespace will be NULL */
434
    const xmlChar *origTargetNamespace;
435
    /*
436
    * For chameleon includes, @targetNamespace will be the
437
    * targetNamespace of the including schema.
438
    */
439
    const xmlChar *targetNamespace;
440
    xmlDocPtr doc; /* The schema node-tree. */
441
    /* @relations will hold any included/imported/redefined schemas. */
442
    xmlSchemaSchemaRelationPtr relations;
443
    int located;
444
    int parsed;
445
    int imported;
446
    int preserveDoc;
447
    xmlSchemaItemListPtr globals;
448
    xmlSchemaItemListPtr locals;
449
    /* The imported schema. */
450
    xmlSchemaPtr schema;
451
};
452
453
/*
454
* (extends xmlSchemaBucket)
455
*/
456
typedef struct _xmlSchemaInclude xmlSchemaInclude;
457
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
458
struct _xmlSchemaInclude {
459
    int type;
460
    int flags;
461
    const xmlChar *schemaLocation;
462
    const xmlChar *origTargetNamespace;
463
    const xmlChar *targetNamespace;
464
    xmlDocPtr doc;
465
    xmlSchemaSchemaRelationPtr relations;
466
    int located;
467
    int parsed;
468
    int imported;
469
    int preserveDoc;
470
    xmlSchemaItemListPtr globals; /* Global components. */
471
    xmlSchemaItemListPtr locals; /* Local components. */
472
473
    /* The owning main or import schema bucket. */
474
    xmlSchemaImportPtr ownerImport;
475
};
476
477
/**
478
 * xmlSchemaBasicItem:
479
 *
480
 * The abstract base type for schema components.
481
 */
482
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
483
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
484
struct _xmlSchemaBasicItem {
485
    xmlSchemaTypeType type;
486
    void *dummy; /* Fix alignment issues */
487
};
488
489
/**
490
 * xmlSchemaAnnotItem:
491
 *
492
 * The abstract base type for annotated schema components.
493
 * (Extends xmlSchemaBasicItem)
494
 */
495
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
496
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
497
struct _xmlSchemaAnnotItem {
498
    xmlSchemaTypeType type;
499
    xmlSchemaAnnotPtr annot;
500
};
501
502
/**
503
 * xmlSchemaTreeItem:
504
 *
505
 * The abstract base type for tree-like structured schema components.
506
 * (Extends xmlSchemaAnnotItem)
507
 */
508
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
509
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
510
struct _xmlSchemaTreeItem {
511
    xmlSchemaTypeType type;
512
    xmlSchemaAnnotPtr annot;
513
    xmlSchemaTreeItemPtr next;
514
    xmlSchemaTreeItemPtr children;
515
};
516
517
518
0
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
519
/**
520
 * xmlSchemaAttributeUsePtr:
521
 *
522
 * The abstract base type for tree-like structured schema components.
523
 * (Extends xmlSchemaTreeItem)
524
 */
525
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
526
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
527
struct _xmlSchemaAttributeUse {
528
    xmlSchemaTypeType type;
529
    xmlSchemaAnnotPtr annot;
530
    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
531
    /*
532
    * The attr. decl. OR a QName-ref. to an attr. decl. OR
533
    * a QName-ref. to an attribute group definition.
534
    */
535
    xmlSchemaAttributePtr attrDecl;
536
537
    int flags;
538
    xmlNodePtr node;
539
    int occurs; /* required, optional */
540
    const xmlChar * defValue;
541
    xmlSchemaValPtr defVal;
542
};
543
544
/**
545
 * xmlSchemaAttributeUseProhibPtr:
546
 *
547
 * A helper component to reflect attribute prohibitions.
548
 * (Extends xmlSchemaBasicItem)
549
 */
550
typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
551
typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
552
struct _xmlSchemaAttributeUseProhib {
553
    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
554
    xmlNodePtr node;
555
    const xmlChar *name;
556
    const xmlChar *targetNamespace;
557
    int isRef;
558
};
559
560
/**
561
 * xmlSchemaRedef:
562
 */
563
typedef struct _xmlSchemaRedef xmlSchemaRedef;
564
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
565
struct _xmlSchemaRedef {
566
    xmlSchemaRedefPtr next;
567
    xmlSchemaBasicItemPtr item; /* The redefining component. */
568
    xmlSchemaBasicItemPtr reference; /* The referencing component. */
569
    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
570
    const xmlChar *refName; /* The name of the to-be-redefined component. */
571
    const xmlChar *refTargetNs; /* The target namespace of the
572
                                   to-be-redefined comp. */
573
    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
574
};
575
576
/**
577
 * xmlSchemaConstructionCtxt:
578
 */
579
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
580
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
581
struct _xmlSchemaConstructionCtxt {
582
    xmlSchemaPtr mainSchema; /* The main schema. */
583
    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
584
    xmlDictPtr dict;
585
    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
586
    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
587
    xmlSchemaBucketPtr bucket; /* The current schema bucket */
588
    xmlSchemaItemListPtr pending; /* All Components of all schemas that
589
                                     need to be fixed. */
590
    xmlHashTablePtr substGroups;
591
    xmlSchemaRedefPtr redefs;
592
    xmlSchemaRedefPtr lastRedef;
593
};
594
595
#define XML_SCHEMAS_PARSE_ERROR   1
596
0
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
597
598
struct _xmlSchemaParserCtxt {
599
    int type;
600
    void *errCtxt;             /* user specific error context */
601
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
602
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
603
    int err;
604
    int nberrors;
605
    xmlStructuredErrorFunc serror;
606
607
    xmlSchemaConstructionCtxtPtr constructor;
608
    int ownsConstructor; /* TODO: Move this to parser *flags*. */
609
610
    /* xmlSchemaPtr topschema;  */
611
    /* xmlHashTablePtr namespaces;  */
612
613
    xmlSchemaPtr schema;        /* The main schema in use */
614
    int counter;
615
616
    const xmlChar *URL;
617
    xmlDocPtr doc;
618
    int preserve;   /* Whether the doc should be freed  */
619
620
    const char *buffer;
621
    int size;
622
623
    /*
624
     * Used to build complex element content models
625
     */
626
    xmlAutomataPtr am;
627
    xmlAutomataStatePtr start;
628
    xmlAutomataStatePtr end;
629
    xmlAutomataStatePtr state;
630
631
    xmlDictPtr dict;    /* dictionary for interned string names */
632
    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
633
    int options;
634
    xmlSchemaValidCtxtPtr vctxt;
635
    int isS4S;
636
    int isRedefine;
637
    int xsiAssemble;
638
    int stop; /* If the parser should stop; i.e. a critical error. */
639
    const xmlChar *targetNamespace;
640
    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
641
642
    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
643
    int redefCounter; /* Used for redefinitions. */
644
    xmlSchemaItemListPtr attrProhibs;
645
};
646
647
/**
648
 * xmlSchemaQNameRef:
649
 *
650
 * A component reference item (not a schema component)
651
 * (Extends xmlSchemaBasicItem)
652
 */
653
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
654
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
655
struct _xmlSchemaQNameRef {
656
    xmlSchemaTypeType type;
657
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
658
    xmlSchemaTypeType itemType;
659
    const xmlChar *name;
660
    const xmlChar *targetNamespace;
661
    xmlNodePtr node;
662
};
663
664
/**
665
 * xmlSchemaParticle:
666
 *
667
 * A particle component.
668
 * (Extends xmlSchemaTreeItem)
669
 */
670
typedef struct _xmlSchemaParticle xmlSchemaParticle;
671
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
672
struct _xmlSchemaParticle {
673
    xmlSchemaTypeType type;
674
    xmlSchemaAnnotPtr annot;
675
    xmlSchemaTreeItemPtr next; /* next particle */
676
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
677
  a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
678
        etc.) */
679
    int minOccurs;
680
    int maxOccurs;
681
    xmlNodePtr node;
682
};
683
684
/**
685
 * xmlSchemaModelGroup:
686
 *
687
 * A model group component.
688
 * (Extends xmlSchemaTreeItem)
689
 */
690
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
691
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
692
struct _xmlSchemaModelGroup {
693
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
694
    xmlSchemaAnnotPtr annot;
695
    xmlSchemaTreeItemPtr next; /* not used */
696
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
697
    xmlNodePtr node;
698
};
699
700
0
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
701
0
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
702
/**
703
 * xmlSchemaModelGroupDef:
704
 *
705
 * A model group definition component.
706
 * (Extends xmlSchemaTreeItem)
707
 */
708
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
709
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
710
struct _xmlSchemaModelGroupDef {
711
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
712
    xmlSchemaAnnotPtr annot;
713
    xmlSchemaTreeItemPtr next; /* not used */
714
    xmlSchemaTreeItemPtr children; /* the "model group" */
715
    const xmlChar *name;
716
    const xmlChar *targetNamespace;
717
    xmlNodePtr node;
718
    int flags;
719
};
720
721
typedef struct _xmlSchemaIDC xmlSchemaIDC;
722
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
723
724
/**
725
 * xmlSchemaIDCSelect:
726
 *
727
 * The identity-constraint "field" and "selector" item, holding the
728
 * XPath expression.
729
 */
730
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
731
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
732
struct _xmlSchemaIDCSelect {
733
    xmlSchemaIDCSelectPtr next;
734
    xmlSchemaIDCPtr idc;
735
    int index; /* an index position if significant for IDC key-sequences */
736
    const xmlChar *xpath; /* the XPath expression */
737
    void *xpathComp; /* the compiled XPath expression */
738
};
739
740
/**
741
 * xmlSchemaIDC:
742
 *
743
 * The identity-constraint definition component.
744
 * (Extends xmlSchemaAnnotItem)
745
 */
746
747
struct _xmlSchemaIDC {
748
    xmlSchemaTypeType type;
749
    xmlSchemaAnnotPtr annot;
750
    xmlSchemaIDCPtr next;
751
    xmlNodePtr node;
752
    const xmlChar *name;
753
    const xmlChar *targetNamespace;
754
    xmlSchemaIDCSelectPtr selector;
755
    xmlSchemaIDCSelectPtr fields;
756
    int nbFields;
757
    xmlSchemaQNameRefPtr ref;
758
};
759
760
/**
761
 * xmlSchemaIDCAug:
762
 *
763
 * The augmented IDC information used for validation.
764
 */
765
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
766
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
767
struct _xmlSchemaIDCAug {
768
    xmlSchemaIDCAugPtr next; /* next in a list */
769
    xmlSchemaIDCPtr def; /* the IDC definition */
770
    int keyrefDepth; /* the lowest tree level to which IDC
771
                        tables need to be bubbled upwards */
772
};
773
774
/**
775
 * xmlSchemaPSVIIDCKeySequence:
776
 *
777
 * The key sequence of a node table item.
778
 */
779
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
780
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
781
struct _xmlSchemaPSVIIDCKey {
782
    xmlSchemaTypePtr type;
783
    xmlSchemaValPtr val;
784
};
785
786
/**
787
 * xmlSchemaPSVIIDCNode:
788
 *
789
 * The node table item of a node table.
790
 */
791
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
792
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
793
struct _xmlSchemaPSVIIDCNode {
794
    xmlNodePtr node;
795
    xmlSchemaPSVIIDCKeyPtr *keys;
796
    int nodeLine;
797
    int nodeQNameID;
798
799
};
800
801
/**
802
 * xmlSchemaPSVIIDCBinding:
803
 *
804
 * The identity-constraint binding item of the [identity-constraint table].
805
 */
806
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
807
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
808
struct _xmlSchemaPSVIIDCBinding {
809
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
810
    xmlSchemaIDCPtr definition; /* the IDC definition */
811
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
812
    int nbNodes; /* number of entries in the node table */
813
    int sizeNodes; /* size of the node table */
814
    xmlSchemaItemListPtr dupls;
815
};
816
817
818
0
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
819
0
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
820
821
#define XPATH_STATE_OBJ_MATCHES -2
822
#define XPATH_STATE_OBJ_BLOCKED -3
823
824
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
825
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
826
827
/**
828
 * xmlSchemaIDCStateObj:
829
 *
830
 * The state object used to evaluate XPath expressions.
831
 */
832
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
833
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
834
struct _xmlSchemaIDCStateObj {
835
    int type;
836
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
837
    int depth; /* depth of creation */
838
    int *history; /* list of (depth, state-id) tuples */
839
    int nbHistory;
840
    int sizeHistory;
841
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
842
                                       matcher */
843
    xmlSchemaIDCSelectPtr sel;
844
    void *xpathCtxt;
845
};
846
847
0
#define IDC_MATCHER 0
848
849
/**
850
 * xmlSchemaIDCMatcher:
851
 *
852
 * Used to evaluate IDC selectors (and fields).
853
 */
854
struct _xmlSchemaIDCMatcher {
855
    int type;
856
    int depth; /* the tree depth at creation time */
857
    xmlSchemaIDCMatcherPtr next; /* next in the list */
858
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
859
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
860
    int idcType;
861
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
862
                                         elements */
863
    int sizeKeySeqs;
864
    xmlSchemaItemListPtr targets; /* list of target-node
865
                                     (xmlSchemaPSVIIDCNodePtr) entries */
866
    xmlHashTablePtr htab;
867
};
868
869
/*
870
* Element info flags.
871
*/
872
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
873
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
874
0
#define XML_SCHEMA_ELEM_INFO_NILLED        1<<2
875
0
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        1<<3
876
877
0
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
878
0
#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
879
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
880
881
0
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
882
0
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
883
0
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
884
0
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
885
886
/**
887
 * xmlSchemaNodeInfo:
888
 *
889
 * Holds information of an element node.
890
 */
891
struct _xmlSchemaNodeInfo {
892
    int nodeType;
893
    xmlNodePtr node;
894
    int nodeLine;
895
    const xmlChar *localName;
896
    const xmlChar *nsName;
897
    const xmlChar *value;
898
    xmlSchemaValPtr val; /* the pre-computed value if any */
899
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
900
901
    int flags; /* combination of node info flags */
902
903
    int valNeeded;
904
    int normVal;
905
906
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
907
    int depth;
908
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
909
                                            for the scope element*/
910
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
911
                                           element */
912
    xmlRegExecCtxtPtr regexCtxt;
913
914
    const xmlChar **nsBindings; /* Namespace bindings on this element */
915
    int nbNsBindings;
916
    int sizeNsBindings;
917
918
    int hasKeyrefs;
919
    int appliedXPath; /* Indicates that an XPath has been applied. */
920
};
921
922
0
#define XML_SCHEMAS_ATTR_UNKNOWN 1
923
0
#define XML_SCHEMAS_ATTR_ASSESSED 2
924
#define XML_SCHEMAS_ATTR_PROHIBITED 3
925
0
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
926
0
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
927
0
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
928
0
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
929
0
#define XML_SCHEMAS_ATTR_DEFAULT 8
930
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
931
0
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
932
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
933
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
934
0
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
935
0
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
936
0
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
937
0
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
938
0
#define XML_SCHEMAS_ATTR_META 17
939
/*
940
* @metaType values of xmlSchemaAttrInfo.
941
*/
942
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
943
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
944
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
945
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
946
0
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
947
948
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
949
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
950
struct _xmlSchemaAttrInfo {
951
    int nodeType;
952
    xmlNodePtr node;
953
    int nodeLine;
954
    const xmlChar *localName;
955
    const xmlChar *nsName;
956
    const xmlChar *value;
957
    xmlSchemaValPtr val; /* the pre-computed value if any */
958
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
959
    int flags; /* combination of node info flags */
960
961
    xmlSchemaAttributePtr decl; /* the attribute declaration */
962
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
963
    int state;
964
    int metaType;
965
    const xmlChar *vcValue; /* the value constraint value */
966
    xmlSchemaNodeInfoPtr parent;
967
};
968
969
970
0
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
971
/**
972
 * xmlSchemaValidCtxt:
973
 *
974
 * A Schemas validation context
975
 */
976
struct _xmlSchemaValidCtxt {
977
    int type;
978
    void *errCtxt;             /* user specific data block */
979
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
980
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
981
    xmlStructuredErrorFunc serror;
982
983
    xmlSchemaPtr schema;        /* The schema in use */
984
    xmlDocPtr doc;
985
    xmlParserInputBufferPtr input;
986
    xmlCharEncoding enc;
987
    xmlSAXHandlerPtr sax;
988
    xmlParserCtxtPtr parserCtxt;
989
    void *user_data; /* TODO: What is this for? */
990
    char *filename;
991
992
    int err;
993
    int nberrors;
994
995
    xmlNodePtr node;
996
    xmlNodePtr cur;
997
    /* xmlSchemaTypePtr type; */
998
999
    xmlRegExecCtxtPtr regexp;
1000
    xmlSchemaValPtr value;
1001
1002
    int valueWS;
1003
    int options;
1004
    xmlNodePtr validationRoot;
1005
    xmlSchemaParserCtxtPtr pctxt;
1006
    int xsiAssemble;
1007
1008
    int depth;
1009
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
1010
    int sizeElemInfos;
1011
    xmlSchemaNodeInfoPtr inode; /* the current element information */
1012
1013
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1014
1015
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1016
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1017
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1018
1019
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1020
    int nbIdcNodes;
1021
    int sizeIdcNodes;
1022
1023
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1024
    int nbIdcKeys;
1025
    int sizeIdcKeys;
1026
1027
    int flags;
1028
1029
    xmlDictPtr dict;
1030
1031
#ifdef LIBXML_READER_ENABLED
1032
    xmlTextReaderPtr reader;
1033
#endif
1034
1035
    xmlSchemaAttrInfoPtr *attrInfos;
1036
    int nbAttrInfos;
1037
    int sizeAttrInfos;
1038
1039
    int skipDepth;
1040
    xmlSchemaItemListPtr nodeQNames;
1041
    int hasKeyrefs;
1042
    int createIDCNodeTables;
1043
    int psviExposeIDCNodeTables;
1044
1045
    /* Locator for error reporting in streaming mode */
1046
    xmlSchemaValidityLocatorFunc locFunc;
1047
    void *locCtxt;
1048
};
1049
1050
/**
1051
 * xmlSchemaSubstGroup:
1052
 *
1053
 *
1054
 */
1055
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1056
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1057
struct _xmlSchemaSubstGroup {
1058
    xmlSchemaElementPtr head;
1059
    xmlSchemaItemListPtr members;
1060
};
1061
1062
/**
1063
 * xmlIDCHashEntry:
1064
 *
1065
 * an entry in hash tables to quickly look up keys/uniques
1066
 */
1067
typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1068
typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1069
struct _xmlIDCHashEntry {
1070
    xmlIDCHashEntryPtr next; /* next item with same hash */
1071
    int index;               /* index into associated item list */
1072
};
1073
1074
/************************************************************************
1075
 *                  *
1076
 *      Some predeclarations        *
1077
 *                  *
1078
 ************************************************************************/
1079
1080
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1081
                                 xmlSchemaPtr schema,
1082
                                 xmlNodePtr node);
1083
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1084
                                 xmlSchemaPtr schema,
1085
                                 xmlNodePtr node);
1086
static int
1087
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1088
                   xmlSchemaAbstractCtxtPtr ctxt);
1089
static const xmlChar *
1090
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1091
static int
1092
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1093
                     xmlNodePtr node);
1094
static int
1095
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1096
                       xmlSchemaParserCtxtPtr ctxt);
1097
static void
1098
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1099
static xmlSchemaWhitespaceValueType
1100
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1101
static xmlSchemaTreeItemPtr
1102
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1103
       xmlNodePtr node, xmlSchemaTypeType type,
1104
       int withParticle);
1105
static const xmlChar *
1106
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1107
static xmlSchemaTypeLinkPtr
1108
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1109
static void
1110
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1111
         const char *funcName,
1112
         const char *message) LIBXML_ATTR_FORMAT(3,0);
1113
static int
1114
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1115
           xmlSchemaTypePtr type,
1116
           xmlSchemaTypePtr baseType,
1117
           int subset);
1118
static void
1119
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1120
           xmlSchemaParserCtxtPtr ctxt);
1121
static void
1122
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1123
static xmlSchemaQNameRefPtr
1124
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1125
        xmlSchemaPtr schema,
1126
        xmlNodePtr node);
1127
1128
/************************************************************************
1129
 *                  *
1130
 *      Helper functions              *
1131
 *                  *
1132
 ************************************************************************/
1133
1134
/**
1135
 * xmlSchemaItemTypeToStr:
1136
 * @type: the type of the schema item
1137
 *
1138
 * Returns the component name of a schema item.
1139
 */
1140
static const xmlChar *
1141
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1142
0
{
1143
0
    switch (type) {
1144
0
  case XML_SCHEMA_TYPE_BASIC:
1145
0
      return(BAD_CAST "simple type definition");
1146
0
  case XML_SCHEMA_TYPE_SIMPLE:
1147
0
      return(BAD_CAST "simple type definition");
1148
0
  case XML_SCHEMA_TYPE_COMPLEX:
1149
0
      return(BAD_CAST "complex type definition");
1150
0
  case XML_SCHEMA_TYPE_ELEMENT:
1151
0
      return(BAD_CAST "element declaration");
1152
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1153
0
      return(BAD_CAST "attribute use");
1154
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1155
0
      return(BAD_CAST "attribute declaration");
1156
0
  case XML_SCHEMA_TYPE_GROUP:
1157
0
      return(BAD_CAST "model group definition");
1158
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1159
0
      return(BAD_CAST "attribute group definition");
1160
0
  case XML_SCHEMA_TYPE_NOTATION:
1161
0
      return(BAD_CAST "notation declaration");
1162
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1163
0
      return(BAD_CAST "model group (sequence)");
1164
0
  case XML_SCHEMA_TYPE_CHOICE:
1165
0
      return(BAD_CAST "model group (choice)");
1166
0
  case XML_SCHEMA_TYPE_ALL:
1167
0
      return(BAD_CAST "model group (all)");
1168
0
  case XML_SCHEMA_TYPE_PARTICLE:
1169
0
      return(BAD_CAST "particle");
1170
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1171
0
      return(BAD_CAST "unique identity-constraint");
1172
      /* return(BAD_CAST "IDC (unique)"); */
1173
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1174
0
      return(BAD_CAST "key identity-constraint");
1175
      /* return(BAD_CAST "IDC (key)"); */
1176
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1177
0
      return(BAD_CAST "keyref identity-constraint");
1178
      /* return(BAD_CAST "IDC (keyref)"); */
1179
0
  case XML_SCHEMA_TYPE_ANY:
1180
0
      return(BAD_CAST "wildcard (any)");
1181
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1182
0
      return(BAD_CAST "[helper component] QName reference");
1183
0
  case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1184
0
      return(BAD_CAST "[helper component] attribute use prohibition");
1185
0
  default:
1186
0
      return(BAD_CAST "Not a schema component");
1187
0
    }
1188
0
}
1189
1190
/**
1191
 * xmlSchemaGetComponentTypeStr:
1192
 * @type: the type of the schema item
1193
 *
1194
 * Returns the component name of a schema item.
1195
 */
1196
static const xmlChar *
1197
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1198
0
{
1199
0
    switch (item->type) {
1200
0
  case XML_SCHEMA_TYPE_BASIC:
1201
0
      if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1202
0
    return(BAD_CAST "complex type definition");
1203
0
      else
1204
0
    return(BAD_CAST "simple type definition");
1205
0
  default:
1206
0
      return(xmlSchemaItemTypeToStr(item->type));
1207
0
    }
1208
0
}
1209
1210
/**
1211
 * xmlSchemaGetComponentNode:
1212
 * @item: a schema component
1213
 *
1214
 * Returns node associated with the schema component.
1215
 * NOTE that such a node need not be available; plus, a component's
1216
 * node need not to reflect the component directly, since there is no
1217
 * one-to-one relationship between the XML Schema representation and
1218
 * the component representation.
1219
 */
1220
static xmlNodePtr
1221
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1222
0
{
1223
0
    switch (item->type) {
1224
0
  case XML_SCHEMA_TYPE_ELEMENT:
1225
0
      return (((xmlSchemaElementPtr) item)->node);
1226
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1227
0
      return (((xmlSchemaAttributePtr) item)->node);
1228
0
  case XML_SCHEMA_TYPE_COMPLEX:
1229
0
  case XML_SCHEMA_TYPE_SIMPLE:
1230
0
      return (((xmlSchemaTypePtr) item)->node);
1231
0
  case XML_SCHEMA_TYPE_ANY:
1232
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1233
0
      return (((xmlSchemaWildcardPtr) item)->node);
1234
0
  case XML_SCHEMA_TYPE_PARTICLE:
1235
0
      return (((xmlSchemaParticlePtr) item)->node);
1236
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1237
0
  case XML_SCHEMA_TYPE_CHOICE:
1238
0
  case XML_SCHEMA_TYPE_ALL:
1239
0
      return (((xmlSchemaModelGroupPtr) item)->node);
1240
0
  case XML_SCHEMA_TYPE_GROUP:
1241
0
      return (((xmlSchemaModelGroupDefPtr) item)->node);
1242
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1243
0
      return (((xmlSchemaAttributeGroupPtr) item)->node);
1244
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1245
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1246
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1247
0
      return (((xmlSchemaIDCPtr) item)->node);
1248
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1249
0
      return(((xmlSchemaQNameRefPtr) item)->node);
1250
  /* TODO: What to do with NOTATIONs?
1251
  case XML_SCHEMA_TYPE_NOTATION:
1252
      return (((xmlSchemaNotationPtr) item)->node);
1253
  */
1254
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1255
0
      return (((xmlSchemaAttributeUsePtr) item)->node);
1256
0
  default:
1257
0
      return (NULL);
1258
0
    }
1259
0
}
1260
1261
#if 0
1262
/**
1263
 * xmlSchemaGetNextComponent:
1264
 * @item: a schema component
1265
 *
1266
 * Returns the next sibling of the schema component.
1267
 */
1268
static xmlSchemaBasicItemPtr
1269
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1270
{
1271
    switch (item->type) {
1272
  case XML_SCHEMA_TYPE_ELEMENT:
1273
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1274
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1275
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1276
  case XML_SCHEMA_TYPE_COMPLEX:
1277
  case XML_SCHEMA_TYPE_SIMPLE:
1278
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1279
  case XML_SCHEMA_TYPE_ANY:
1280
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1281
      return (NULL);
1282
  case XML_SCHEMA_TYPE_PARTICLE:
1283
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1284
  case XML_SCHEMA_TYPE_SEQUENCE:
1285
  case XML_SCHEMA_TYPE_CHOICE:
1286
  case XML_SCHEMA_TYPE_ALL:
1287
      return (NULL);
1288
  case XML_SCHEMA_TYPE_GROUP:
1289
      return (NULL);
1290
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1291
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1292
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1293
  case XML_SCHEMA_TYPE_IDC_KEY:
1294
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1295
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1296
  default:
1297
      return (NULL);
1298
    }
1299
}
1300
#endif
1301
1302
1303
/**
1304
 * xmlSchemaFormatQName:
1305
 * @buf: the string buffer
1306
 * @namespaceName:  the namespace name
1307
 * @localName: the local name
1308
 *
1309
 * Returns the given QName in the format "{namespaceName}localName" or
1310
 * just "localName" if @namespaceName is NULL.
1311
 *
1312
 * Returns the localName if @namespaceName is NULL, a formatted
1313
 * string otherwise.
1314
 */
1315
static const xmlChar*
1316
xmlSchemaFormatQName(xmlChar **buf,
1317
         const xmlChar *namespaceName,
1318
         const xmlChar *localName)
1319
0
{
1320
0
    FREE_AND_NULL(*buf)
1321
0
    if (namespaceName != NULL) {
1322
0
  *buf = xmlStrdup(BAD_CAST "{");
1323
0
  *buf = xmlStrcat(*buf, namespaceName);
1324
0
  *buf = xmlStrcat(*buf, BAD_CAST "}");
1325
0
    }
1326
0
    if (localName != NULL) {
1327
0
  if (namespaceName == NULL)
1328
0
      return(localName);
1329
0
  *buf = xmlStrcat(*buf, localName);
1330
0
    } else {
1331
0
  *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1332
0
    }
1333
0
    return ((const xmlChar *) *buf);
1334
0
}
1335
1336
static const xmlChar*
1337
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1338
0
{
1339
0
    if (ns != NULL)
1340
0
  return (xmlSchemaFormatQName(buf, ns->href, localName));
1341
0
    else
1342
0
  return (xmlSchemaFormatQName(buf, NULL, localName));
1343
0
}
1344
1345
static const xmlChar *
1346
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1347
0
{
1348
0
    if (item == NULL) {
1349
0
        return (NULL);
1350
0
    }
1351
0
    switch (item->type) {
1352
0
  case XML_SCHEMA_TYPE_ELEMENT:
1353
0
      return (((xmlSchemaElementPtr) item)->name);
1354
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1355
0
      return (((xmlSchemaAttributePtr) item)->name);
1356
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1357
0
      return (((xmlSchemaAttributeGroupPtr) item)->name);
1358
0
  case XML_SCHEMA_TYPE_BASIC:
1359
0
  case XML_SCHEMA_TYPE_SIMPLE:
1360
0
  case XML_SCHEMA_TYPE_COMPLEX:
1361
0
      return (((xmlSchemaTypePtr) item)->name);
1362
0
  case XML_SCHEMA_TYPE_GROUP:
1363
0
      return (((xmlSchemaModelGroupDefPtr) item)->name);
1364
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1365
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1366
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1367
0
      return (((xmlSchemaIDCPtr) item)->name);
1368
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1369
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1370
0
    return(xmlSchemaGetComponentName(
1371
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1372
0
      } else
1373
0
    return(NULL);
1374
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1375
0
      return (((xmlSchemaQNameRefPtr) item)->name);
1376
0
  case XML_SCHEMA_TYPE_NOTATION:
1377
0
      return (((xmlSchemaNotationPtr) item)->name);
1378
0
  default:
1379
      /*
1380
      * Other components cannot have names.
1381
      */
1382
0
      break;
1383
0
    }
1384
0
    return (NULL);
1385
0
}
1386
1387
0
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1388
0
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1389
/*
1390
static const xmlChar *
1391
xmlSchemaGetQNameRefName(void *ref)
1392
{
1393
    return(((xmlSchemaQNameRefPtr) ref)->name);
1394
}
1395
1396
static const xmlChar *
1397
xmlSchemaGetQNameRefTargetNs(void *ref)
1398
{
1399
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1400
}
1401
*/
1402
1403
static const xmlChar *
1404
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1405
0
{
1406
0
    if (item == NULL) {
1407
0
        return (NULL);
1408
0
    }
1409
0
    switch (item->type) {
1410
0
  case XML_SCHEMA_TYPE_ELEMENT:
1411
0
      return (((xmlSchemaElementPtr) item)->targetNamespace);
1412
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1413
0
      return (((xmlSchemaAttributePtr) item)->targetNamespace);
1414
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1415
0
      return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1416
0
  case XML_SCHEMA_TYPE_BASIC:
1417
0
      return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1418
0
  case XML_SCHEMA_TYPE_SIMPLE:
1419
0
  case XML_SCHEMA_TYPE_COMPLEX:
1420
0
      return (((xmlSchemaTypePtr) item)->targetNamespace);
1421
0
  case XML_SCHEMA_TYPE_GROUP:
1422
0
      return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1423
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1424
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1425
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1426
0
      return (((xmlSchemaIDCPtr) item)->targetNamespace);
1427
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1428
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1429
0
    return(xmlSchemaGetComponentTargetNs(
1430
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1431
0
      }
1432
      /* TODO: Will returning NULL break something? */
1433
0
      break;
1434
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1435
0
      return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1436
0
  case XML_SCHEMA_TYPE_NOTATION:
1437
0
      return (((xmlSchemaNotationPtr) item)->targetNamespace);
1438
0
  default:
1439
      /*
1440
      * Other components cannot have names.
1441
      */
1442
0
      break;
1443
0
    }
1444
0
    return (NULL);
1445
0
}
1446
1447
static const xmlChar*
1448
xmlSchemaGetComponentQName(xmlChar **buf,
1449
         void *item)
1450
0
{
1451
0
    return (xmlSchemaFormatQName(buf,
1452
0
  xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1453
0
  xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1454
0
}
1455
1456
static const xmlChar*
1457
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1458
0
{
1459
0
    xmlChar *str = NULL;
1460
1461
0
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1462
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1463
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1464
0
  (xmlSchemaBasicItemPtr) item));
1465
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1466
0
    FREE_AND_NULL(str);
1467
0
    return(*buf);
1468
0
}
1469
1470
static const xmlChar*
1471
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1472
0
{
1473
0
    return(xmlSchemaGetComponentDesignation(buf, idc));
1474
0
}
1475
1476
/**
1477
 * xmlSchemaWildcardPCToString:
1478
 * @pc: the type of processContents
1479
 *
1480
 * Returns a string representation of the type of
1481
 * processContents.
1482
 */
1483
static const xmlChar *
1484
xmlSchemaWildcardPCToString(int pc)
1485
0
{
1486
0
    switch (pc) {
1487
0
  case XML_SCHEMAS_ANY_SKIP:
1488
0
      return (BAD_CAST "skip");
1489
0
  case XML_SCHEMAS_ANY_LAX:
1490
0
      return (BAD_CAST "lax");
1491
0
  case XML_SCHEMAS_ANY_STRICT:
1492
0
      return (BAD_CAST "strict");
1493
0
  default:
1494
0
      return (BAD_CAST "invalid process contents");
1495
0
    }
1496
0
}
1497
1498
/**
1499
 * xmlSchemaGetCanonValueWhtspExt:
1500
 * @val: the precomputed value
1501
 * @retValue: the returned value
1502
 * @ws: the whitespace type of the value
1503
 * @for_hash: non-zero if this is supposed to generate a string for hashing
1504
 *
1505
 * Get a the canonical representation of the value.
1506
 * The caller has to free the returned retValue.
1507
 *
1508
 * Returns 0 if the value could be built and -1 in case of
1509
 *         API errors or if the value type is not supported yet.
1510
 */
1511
static int
1512
xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1513
               xmlSchemaWhitespaceValueType ws,
1514
               xmlChar **retValue,
1515
         int for_hash)
1516
0
{
1517
0
    int list;
1518
0
    xmlSchemaValType valType;
1519
0
    const xmlChar *value, *value2 = NULL;
1520
1521
1522
0
    if ((retValue == NULL) || (val == NULL))
1523
0
  return (-1);
1524
0
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1525
0
    *retValue = NULL;
1526
0
    do {
1527
0
  value = NULL;
1528
0
  valType = xmlSchemaGetValType(val);
1529
0
  switch (valType) {
1530
0
      case XML_SCHEMAS_STRING:
1531
0
      case XML_SCHEMAS_NORMSTRING:
1532
0
      case XML_SCHEMAS_ANYSIMPLETYPE:
1533
0
    value = xmlSchemaValueGetAsString(val);
1534
0
    if (value != NULL) {
1535
0
        if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1536
0
      value2 = xmlSchemaCollapseString(value);
1537
0
        else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1538
0
      value2 = xmlSchemaWhiteSpaceReplace(value);
1539
0
        if (value2 != NULL)
1540
0
      value = value2;
1541
0
    }
1542
0
    break;
1543
0
      default:
1544
0
    if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1545
0
        if (value2 != NULL)
1546
0
      xmlFree((xmlChar *) value2);
1547
0
        goto internal_error;
1548
0
    }
1549
0
    if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1550
        /* We can mostly use the canonical value for hashing,
1551
           except in the case of decimal.  There the canonical
1552
           representation requires a trailing '.0' even for
1553
           non-fractional numbers, but for the derived integer
1554
           types it forbids any decimal point.  Nevertheless they
1555
           compare equal if the value is equal.  We need to generate
1556
           the same hash value for this to work, and it's easiest
1557
           to just cut off the useless '.0' suffix for the
1558
           decimal type.  */
1559
0
        int len = xmlStrlen(value2);
1560
0
        if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1561
0
          ((xmlChar*)value2)[len-2] = 0;
1562
0
    }
1563
0
    value = value2;
1564
0
  }
1565
0
  if (*retValue == NULL)
1566
0
      if (value == NULL) {
1567
0
    if (! list)
1568
0
        *retValue = xmlStrdup(BAD_CAST "");
1569
0
      } else
1570
0
    *retValue = xmlStrdup(value);
1571
0
  else if (value != NULL) {
1572
      /* List. */
1573
0
      *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1574
0
      *retValue = xmlStrcat((xmlChar *) *retValue, value);
1575
0
  }
1576
0
  FREE_AND_NULL(value2)
1577
0
  val = xmlSchemaValueGetNext(val);
1578
0
    } while (val != NULL);
1579
1580
0
    return (0);
1581
0
internal_error:
1582
0
    if (*retValue != NULL)
1583
0
  xmlFree((xmlChar *) (*retValue));
1584
0
    if (value2 != NULL)
1585
0
  xmlFree((xmlChar *) value2);
1586
0
    return (-1);
1587
0
}
1588
1589
static int
1590
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1591
             xmlSchemaWhitespaceValueType ws,
1592
             xmlChar **retValue)
1593
0
{
1594
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1595
0
}
1596
1597
static int
1598
xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1599
         xmlChar **retValue)
1600
0
{
1601
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1602
0
              retValue, 1);
1603
0
}
1604
1605
/**
1606
 * xmlSchemaFormatItemForReport:
1607
 * @buf: the string buffer
1608
 * @itemDes: the designation of the item
1609
 * @itemName: the name of the item
1610
 * @item: the item as an object
1611
 * @itemNode: the node of the item
1612
 * @local: the local name
1613
 * @parsing: if the function is used during the parse
1614
 *
1615
 * Returns a representation of the given item used
1616
 * for error reports.
1617
 *
1618
 * The following order is used to build the resulting
1619
 * designation if the arguments are not NULL:
1620
 * 1a. If itemDes not NULL -> itemDes
1621
 * 1b. If (itemDes not NULL) and (itemName not NULL)
1622
 *     -> itemDes + itemName
1623
 * 2. If the preceding was NULL and (item not NULL) -> item
1624
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1625
 *
1626
 * If the itemNode is an attribute node, the name of the attribute
1627
 * will be appended to the result.
1628
 *
1629
 * Returns the formatted string and sets @buf to the resulting value.
1630
 */
1631
static xmlChar*
1632
xmlSchemaFormatItemForReport(xmlChar **buf,
1633
         const xmlChar *itemDes,
1634
         xmlSchemaBasicItemPtr item,
1635
         xmlNodePtr itemNode)
1636
0
{
1637
0
    xmlChar *str = NULL;
1638
0
    int named = 1;
1639
1640
0
    if (*buf != NULL) {
1641
0
  xmlFree(*buf);
1642
0
  *buf = NULL;
1643
0
    }
1644
1645
0
    if (itemDes != NULL) {
1646
0
  *buf = xmlStrdup(itemDes);
1647
0
    } else if (item != NULL) {
1648
0
  switch (item->type) {
1649
0
  case XML_SCHEMA_TYPE_BASIC: {
1650
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1651
1652
0
      if (WXS_IS_ATOMIC(type))
1653
0
    *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1654
0
      else if (WXS_IS_LIST(type))
1655
0
    *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1656
0
      else if (WXS_IS_UNION(type))
1657
0
    *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1658
0
      else
1659
0
    *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1660
0
      *buf = xmlStrcat(*buf, type->name);
1661
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1662
0
      }
1663
0
      break;
1664
0
  case XML_SCHEMA_TYPE_SIMPLE: {
1665
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1666
1667
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1668
0
    *buf = xmlStrdup(BAD_CAST"");
1669
0
      } else {
1670
0
    *buf = xmlStrdup(BAD_CAST "local ");
1671
0
      }
1672
0
      if (WXS_IS_ATOMIC(type))
1673
0
    *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1674
0
      else if (WXS_IS_LIST(type))
1675
0
    *buf = xmlStrcat(*buf, BAD_CAST "list type");
1676
0
      else if (WXS_IS_UNION(type))
1677
0
    *buf = xmlStrcat(*buf, BAD_CAST "union type");
1678
0
      else
1679
0
    *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1680
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1681
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1682
0
    *buf = xmlStrcat(*buf, type->name);
1683
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1684
0
      }
1685
0
      }
1686
0
      break;
1687
0
  case XML_SCHEMA_TYPE_COMPLEX: {
1688
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1689
1690
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1691
0
    *buf = xmlStrdup(BAD_CAST "");
1692
0
      else
1693
0
    *buf = xmlStrdup(BAD_CAST "local ");
1694
0
      *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1695
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1696
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1697
0
    *buf = xmlStrcat(*buf, type->name);
1698
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1699
0
      }
1700
0
      }
1701
0
      break;
1702
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1703
0
    xmlSchemaAttributeUsePtr ause;
1704
1705
0
    ause = WXS_ATTR_USE_CAST item;
1706
0
    *buf = xmlStrdup(BAD_CAST "attribute use ");
1707
0
    if (WXS_ATTRUSE_DECL(ause) != NULL) {
1708
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1709
0
        *buf = xmlStrcat(*buf,
1710
0
      xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1711
0
        FREE_AND_NULL(str)
1712
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1713
0
    } else {
1714
0
        *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1715
0
    }
1716
0
      }
1717
0
      break;
1718
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
1719
0
    xmlSchemaAttributePtr attr;
1720
1721
0
    attr = (xmlSchemaAttributePtr) item;
1722
0
    *buf = xmlStrdup(BAD_CAST "attribute decl.");
1723
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1724
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1725
0
        attr->targetNamespace, attr->name));
1726
0
    FREE_AND_NULL(str)
1727
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1728
0
      }
1729
0
      break;
1730
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1731
0
      xmlSchemaGetComponentDesignation(buf, item);
1732
0
      break;
1733
0
  case XML_SCHEMA_TYPE_ELEMENT: {
1734
0
    xmlSchemaElementPtr elem;
1735
1736
0
    elem = (xmlSchemaElementPtr) item;
1737
0
    *buf = xmlStrdup(BAD_CAST "element decl.");
1738
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1739
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1740
0
        elem->targetNamespace, elem->name));
1741
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1742
0
      }
1743
0
      break;
1744
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1745
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1746
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1747
0
      if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1748
0
    *buf = xmlStrdup(BAD_CAST "unique '");
1749
0
      else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1750
0
    *buf = xmlStrdup(BAD_CAST "key '");
1751
0
      else
1752
0
    *buf = xmlStrdup(BAD_CAST "keyRef '");
1753
0
      *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1754
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1755
0
      break;
1756
0
  case XML_SCHEMA_TYPE_ANY:
1757
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1758
0
      *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1759
0
        ((xmlSchemaWildcardPtr) item)->processContents));
1760
0
      *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1761
0
      break;
1762
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
1763
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
1764
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
1765
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1766
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
1767
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
1768
0
  case XML_SCHEMA_FACET_PATTERN:
1769
0
  case XML_SCHEMA_FACET_ENUMERATION:
1770
0
  case XML_SCHEMA_FACET_WHITESPACE:
1771
0
  case XML_SCHEMA_FACET_LENGTH:
1772
0
  case XML_SCHEMA_FACET_MAXLENGTH:
1773
0
  case XML_SCHEMA_FACET_MINLENGTH:
1774
0
      *buf = xmlStrdup(BAD_CAST "facet '");
1775
0
      *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1776
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1777
0
      break;
1778
0
  case XML_SCHEMA_TYPE_GROUP: {
1779
0
    *buf = xmlStrdup(BAD_CAST "model group def.");
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
0
      break;
1786
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1787
0
  case XML_SCHEMA_TYPE_CHOICE:
1788
0
  case XML_SCHEMA_TYPE_ALL:
1789
0
  case XML_SCHEMA_TYPE_PARTICLE:
1790
0
      *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1791
0
      break;
1792
0
  case XML_SCHEMA_TYPE_NOTATION: {
1793
0
    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1794
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1795
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1796
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1797
0
    FREE_AND_NULL(str);
1798
0
      }
1799
            /* Falls through. */
1800
0
  default:
1801
0
      named = 0;
1802
0
  }
1803
0
    } else
1804
0
  named = 0;
1805
1806
0
    if ((named == 0) && (itemNode != NULL)) {
1807
0
  xmlNodePtr elem;
1808
1809
0
  if (itemNode->type == XML_ATTRIBUTE_NODE)
1810
0
      elem = itemNode->parent;
1811
0
  else
1812
0
      elem = itemNode;
1813
0
  *buf = xmlStrdup(BAD_CAST "Element '");
1814
0
  if (elem->ns != NULL) {
1815
0
      *buf = xmlStrcat(*buf,
1816
0
    xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1817
0
      FREE_AND_NULL(str)
1818
0
  } else
1819
0
      *buf = xmlStrcat(*buf, elem->name);
1820
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1821
1822
0
    }
1823
0
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1824
0
  *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1825
0
  if (itemNode->ns != NULL) {
1826
0
      *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1827
0
    itemNode->ns->href, itemNode->name));
1828
0
      FREE_AND_NULL(str)
1829
0
  } else
1830
0
      *buf = xmlStrcat(*buf, itemNode->name);
1831
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1832
0
    }
1833
0
    FREE_AND_NULL(str)
1834
1835
0
    return (xmlEscapeFormatString(buf));
1836
0
}
1837
1838
/**
1839
 * xmlSchemaFormatFacetEnumSet:
1840
 * @buf: the string buffer
1841
 * @type: the type holding the enumeration facets
1842
 *
1843
 * Builds a string consisting of all enumeration elements.
1844
 *
1845
 * Returns a string of all enumeration elements.
1846
 */
1847
static const xmlChar *
1848
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1849
          xmlChar **buf, xmlSchemaTypePtr type)
1850
0
{
1851
0
    xmlSchemaFacetPtr facet;
1852
0
    xmlSchemaWhitespaceValueType ws;
1853
0
    xmlChar *value = NULL;
1854
0
    int res, found = 0;
1855
1856
0
    if (*buf != NULL)
1857
0
  xmlFree(*buf);
1858
0
    *buf = NULL;
1859
1860
0
    do {
1861
  /*
1862
  * Use the whitespace type of the base type.
1863
  */
1864
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1865
0
  for (facet = type->facets; facet != NULL; facet = facet->next) {
1866
0
      if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1867
0
    continue;
1868
0
      found = 1;
1869
0
      res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1870
0
    ws, &value);
1871
0
      if (res == -1) {
1872
0
    xmlSchemaInternalErr(actxt,
1873
0
        "xmlSchemaFormatFacetEnumSet",
1874
0
        "compute the canonical lexical representation");
1875
0
    if (*buf != NULL)
1876
0
        xmlFree(*buf);
1877
0
    *buf = NULL;
1878
0
    return (NULL);
1879
0
      }
1880
0
      if (*buf == NULL)
1881
0
    *buf = xmlStrdup(BAD_CAST "'");
1882
0
      else
1883
0
    *buf = xmlStrcat(*buf, BAD_CAST ", '");
1884
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
1885
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1886
0
      if (value != NULL) {
1887
0
    xmlFree((xmlChar *)value);
1888
0
    value = NULL;
1889
0
      }
1890
0
  }
1891
  /*
1892
  * The enumeration facet of a type restricts the enumeration
1893
  * facet of the ancestor type; i.e., such restricted enumerations
1894
  * do not belong to the set of the given type. Thus we break
1895
  * on the first found enumeration.
1896
  */
1897
0
  if (found)
1898
0
      break;
1899
0
  type = type->baseType;
1900
0
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1901
1902
0
    return ((const xmlChar *) *buf);
1903
0
}
1904
1905
/************************************************************************
1906
 *                  *
1907
 *      Error functions               *
1908
 *                  *
1909
 ************************************************************************/
1910
1911
#if 0
1912
static void
1913
xmlSchemaErrMemory(const char *msg)
1914
{
1915
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1916
                     msg);
1917
}
1918
#endif
1919
1920
static void
1921
xmlSchemaPSimpleErr(const char *msg)
1922
0
{
1923
0
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1924
0
                     msg);
1925
0
}
1926
1927
/**
1928
 * xmlSchemaPErrMemory:
1929
 * @node: a context node
1930
 * @extra:  extra information
1931
 *
1932
 * Handle an out of memory condition
1933
 */
1934
static void
1935
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1936
                    const char *extra, xmlNodePtr node)
1937
0
{
1938
0
    if (ctxt != NULL)
1939
0
        ctxt->nberrors++;
1940
0
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
1941
0
                     extra);
1942
0
}
1943
1944
/**
1945
 * xmlSchemaPErr:
1946
 * @ctxt: the parsing context
1947
 * @node: the context node
1948
 * @error: the error code
1949
 * @msg: the error message
1950
 * @str1: extra data
1951
 * @str2: extra data
1952
 *
1953
 * Handle a parser error
1954
 */
1955
static void LIBXML_ATTR_FORMAT(4,0)
1956
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1957
              const char *msg, const xmlChar * str1, const xmlChar * str2)
1958
0
{
1959
0
    xmlGenericErrorFunc channel = NULL;
1960
0
    xmlStructuredErrorFunc schannel = NULL;
1961
0
    void *data = NULL;
1962
1963
0
    if (ctxt != NULL) {
1964
0
        ctxt->nberrors++;
1965
0
  ctxt->err = error;
1966
0
        channel = ctxt->error;
1967
0
        data = ctxt->errCtxt;
1968
0
  schannel = ctxt->serror;
1969
0
    }
1970
0
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1971
0
                    error, XML_ERR_ERROR, NULL, 0,
1972
0
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
1973
0
                    msg, str1, str2);
1974
0
}
1975
1976
/**
1977
 * xmlSchemaPErr2:
1978
 * @ctxt: the parsing context
1979
 * @node: the context node
1980
 * @node: the current child
1981
 * @error: the error code
1982
 * @msg: the error message
1983
 * @str1: extra data
1984
 * @str2: extra data
1985
 *
1986
 * Handle a parser error
1987
 */
1988
static void LIBXML_ATTR_FORMAT(5,0)
1989
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1990
               xmlNodePtr child, int error,
1991
               const char *msg, const xmlChar * str1, const xmlChar * str2)
1992
0
{
1993
0
    if (child != NULL)
1994
0
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1995
0
    else
1996
0
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1997
0
}
1998
1999
2000
/**
2001
 * xmlSchemaPErrExt:
2002
 * @ctxt: the parsing context
2003
 * @node: the context node
2004
 * @error: the error code
2005
 * @strData1: extra data
2006
 * @strData2: extra data
2007
 * @strData3: extra data
2008
 * @msg: the message
2009
 * @str1:  extra parameter for the message display
2010
 * @str2:  extra parameter for the message display
2011
 * @str3:  extra parameter for the message display
2012
 * @str4:  extra parameter for the message display
2013
 * @str5:  extra parameter for the message display
2014
 *
2015
 * Handle a parser error
2016
 */
2017
static void LIBXML_ATTR_FORMAT(7,0)
2018
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
2019
    const xmlChar * strData1, const xmlChar * strData2,
2020
    const xmlChar * strData3, const char *msg, const xmlChar * str1,
2021
    const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2022
    const xmlChar * str5)
2023
0
{
2024
2025
0
    xmlGenericErrorFunc channel = NULL;
2026
0
    xmlStructuredErrorFunc schannel = NULL;
2027
0
    void *data = NULL;
2028
2029
0
    if (ctxt != NULL) {
2030
0
        ctxt->nberrors++;
2031
0
  ctxt->err = error;
2032
0
        channel = ctxt->error;
2033
0
        data = ctxt->errCtxt;
2034
0
  schannel = ctxt->serror;
2035
0
    }
2036
0
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
2037
0
                    error, XML_ERR_ERROR, NULL, 0,
2038
0
                    (const char *) strData1, (const char *) strData2,
2039
0
        (const char *) strData3, 0, 0, msg, str1, str2,
2040
0
        str3, str4, str5);
2041
0
}
2042
2043
/************************************************************************
2044
 *                  *
2045
 *      Allround error functions      *
2046
 *                  *
2047
 ************************************************************************/
2048
2049
/**
2050
 * xmlSchemaVTypeErrMemory:
2051
 * @node: a context node
2052
 * @extra:  extra information
2053
 *
2054
 * Handle an out of memory condition
2055
 */
2056
static void
2057
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
2058
                    const char *extra, xmlNodePtr node)
2059
0
{
2060
0
    if (ctxt != NULL) {
2061
0
        ctxt->nberrors++;
2062
0
        ctxt->err = XML_SCHEMAV_INTERNAL;
2063
0
    }
2064
0
    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
2065
0
                     extra);
2066
0
}
2067
2068
static void LIBXML_ATTR_FORMAT(2,0)
2069
xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2070
          const char *msg, const xmlChar *str)
2071
0
{
2072
0
     __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2073
0
   msg, (const char *) str);
2074
0
}
2075
2076
#define WXS_ERROR_TYPE_ERROR 1
2077
#define WXS_ERROR_TYPE_WARNING 2
2078
/**
2079
 * xmlSchemaErr4Line:
2080
 * @ctxt: the validation context
2081
 * @errorLevel: the error level
2082
 * @error: the error code
2083
 * @node: the context node
2084
 * @line: the line number
2085
 * @msg: the error message
2086
 * @str1: extra data
2087
 * @str2: extra data
2088
 * @str3: extra data
2089
 * @str4: extra data
2090
 *
2091
 * Handle a validation error
2092
 */
2093
static void LIBXML_ATTR_FORMAT(6,0)
2094
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2095
      xmlErrorLevel errorLevel,
2096
      int error, xmlNodePtr node, int line, const char *msg,
2097
      const xmlChar *str1, const xmlChar *str2,
2098
      const xmlChar *str3, const xmlChar *str4)
2099
0
{
2100
0
    xmlStructuredErrorFunc schannel = NULL;
2101
0
    xmlGenericErrorFunc channel = NULL;
2102
0
    void *data = NULL;
2103
2104
0
    if (ctxt != NULL) {
2105
0
  if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2106
0
      xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2107
0
      const char *file = NULL;
2108
0
      int col = 0;
2109
0
      if (errorLevel != XML_ERR_WARNING) {
2110
0
    vctxt->nberrors++;
2111
0
    vctxt->err = error;
2112
0
    channel = vctxt->error;
2113
0
      } else {
2114
0
    channel = vctxt->warning;
2115
0
      }
2116
0
      schannel = vctxt->serror;
2117
0
      data = vctxt->errCtxt;
2118
2119
      /*
2120
      * Error node. If we specify a line number, then
2121
      * do not channel any node to the error function.
2122
      */
2123
0
      if (line == 0) {
2124
0
    if ((node == NULL) &&
2125
0
        (vctxt->depth >= 0) &&
2126
0
        (vctxt->inode != NULL)) {
2127
0
        node = vctxt->inode->node;
2128
0
    }
2129
    /*
2130
    * Get filename and line if no node-tree.
2131
    */
2132
0
    if ((node == NULL) &&
2133
0
        (vctxt->parserCtxt != NULL) &&
2134
0
        (vctxt->parserCtxt->input != NULL)) {
2135
0
        file = vctxt->parserCtxt->input->filename;
2136
0
        line = vctxt->parserCtxt->input->line;
2137
0
        col = vctxt->parserCtxt->input->col;
2138
0
    }
2139
0
      } else {
2140
    /*
2141
    * Override the given node's (if any) position
2142
    * and channel only the given line number.
2143
    */
2144
0
    node = NULL;
2145
    /*
2146
    * Get filename.
2147
    */
2148
0
    if (vctxt->doc != NULL)
2149
0
        file = (const char *) vctxt->doc->URL;
2150
0
    else if ((vctxt->parserCtxt != NULL) &&
2151
0
        (vctxt->parserCtxt->input != NULL))
2152
0
        file = vctxt->parserCtxt->input->filename;
2153
0
      }
2154
0
      if (vctxt->locFunc != NULL) {
2155
0
          if ((file == NULL) || (line == 0)) {
2156
0
        unsigned long l;
2157
0
        const char *f;
2158
0
        vctxt->locFunc(vctxt->locCtxt, &f, &l);
2159
0
        if (file == NULL)
2160
0
            file = f;
2161
0
        if (line == 0)
2162
0
            line = (int) l;
2163
0
    }
2164
0
      }
2165
0
      if ((file == NULL) && (vctxt->filename != NULL))
2166
0
          file = vctxt->filename;
2167
2168
0
      __xmlRaiseError(schannel, channel, data, ctxt,
2169
0
    node, XML_FROM_SCHEMASV,
2170
0
    error, errorLevel, file, line,
2171
0
    (const char *) str1, (const char *) str2,
2172
0
    (const char *) str3, 0, col, msg, str1, str2, str3, str4);
2173
2174
0
  } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2175
0
      xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2176
0
      if (errorLevel != XML_ERR_WARNING) {
2177
0
    pctxt->nberrors++;
2178
0
    pctxt->err = error;
2179
0
    channel = pctxt->error;
2180
0
      } else {
2181
0
    channel = pctxt->warning;
2182
0
      }
2183
0
      schannel = pctxt->serror;
2184
0
      data = pctxt->errCtxt;
2185
0
      __xmlRaiseError(schannel, channel, data, ctxt,
2186
0
    node, XML_FROM_SCHEMASP, error,
2187
0
    errorLevel, NULL, 0,
2188
0
    (const char *) str1, (const char *) str2,
2189
0
    (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2190
0
  } else {
2191
0
      TODO
2192
0
  }
2193
0
    }
2194
0
}
2195
2196
/**
2197
 * xmlSchemaErr3:
2198
 * @ctxt: the validation context
2199
 * @node: the context node
2200
 * @error: the error code
2201
 * @msg: the error message
2202
 * @str1: extra data
2203
 * @str2: extra data
2204
 * @str3: extra data
2205
 *
2206
 * Handle a validation error
2207
 */
2208
static void LIBXML_ATTR_FORMAT(4,0)
2209
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2210
        int error, xmlNodePtr node, const char *msg,
2211
        const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2212
0
{
2213
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2214
0
  msg, str1, str2, str3, NULL);
2215
0
}
2216
2217
static void LIBXML_ATTR_FORMAT(4,0)
2218
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2219
        int error, xmlNodePtr node, const char *msg,
2220
        const xmlChar *str1, const xmlChar *str2,
2221
        const xmlChar *str3, const xmlChar *str4)
2222
0
{
2223
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2224
0
  msg, str1, str2, str3, str4);
2225
0
}
2226
2227
static void LIBXML_ATTR_FORMAT(4,0)
2228
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2229
       int error, xmlNodePtr node, const char *msg,
2230
       const xmlChar *str1, const xmlChar *str2)
2231
0
{
2232
0
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2233
0
}
2234
2235
static xmlChar *
2236
xmlSchemaFormatNodeForError(xmlChar ** msg,
2237
          xmlSchemaAbstractCtxtPtr actxt,
2238
          xmlNodePtr node)
2239
0
{
2240
0
    xmlChar *str = NULL;
2241
2242
0
    *msg = NULL;
2243
0
    if ((node != NULL) &&
2244
0
  (node->type != XML_ELEMENT_NODE) &&
2245
0
  (node->type != XML_ATTRIBUTE_NODE))
2246
0
    {
2247
  /*
2248
  * Don't try to format other nodes than element and
2249
  * attribute nodes.
2250
  * Play safe and return an empty string.
2251
  */
2252
0
  *msg = xmlStrdup(BAD_CAST "");
2253
0
  return(*msg);
2254
0
    }
2255
0
    if (node != NULL) {
2256
  /*
2257
  * Work on tree nodes.
2258
  */
2259
0
  if (node->type == XML_ATTRIBUTE_NODE) {
2260
0
      xmlNodePtr elem = node->parent;
2261
2262
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2263
0
      if (elem->ns != NULL)
2264
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2265
0
        elem->ns->href, elem->name));
2266
0
      else
2267
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2268
0
        NULL, elem->name));
2269
0
      FREE_AND_NULL(str);
2270
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2271
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2272
0
  } else {
2273
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2274
0
  }
2275
0
  if (node->ns != NULL)
2276
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2277
0
      node->ns->href, node->name));
2278
0
  else
2279
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2280
0
      NULL, node->name));
2281
0
  FREE_AND_NULL(str);
2282
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2283
0
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2284
0
  xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2285
  /*
2286
  * Work on node infos.
2287
  */
2288
0
  if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2289
0
      xmlSchemaNodeInfoPtr ielem =
2290
0
    vctxt->elemInfos[vctxt->depth];
2291
2292
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2293
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2294
0
    ielem->nsName, ielem->localName));
2295
0
      FREE_AND_NULL(str);
2296
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2297
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2298
0
  } else {
2299
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2300
0
  }
2301
0
  *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2302
0
      vctxt->inode->nsName, vctxt->inode->localName));
2303
0
  FREE_AND_NULL(str);
2304
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2305
0
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2306
  /*
2307
  * Hmm, no node while parsing?
2308
  * Return an empty string, in case NULL will break something.
2309
  */
2310
0
  *msg = xmlStrdup(BAD_CAST "");
2311
0
    } else {
2312
0
  TODO
2313
0
  return (NULL);
2314
0
    }
2315
2316
    /*
2317
     * xmlSchemaFormatItemForReport() also returns an escaped format
2318
     * string, so do this before calling it below (in the future).
2319
     */
2320
0
    xmlEscapeFormatString(msg);
2321
2322
    /*
2323
    * VAL TODO: The output of the given schema component is currently
2324
    * disabled.
2325
    */
2326
#if 0
2327
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2328
  *msg = xmlStrcat(*msg, BAD_CAST " [");
2329
  *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2330
      NULL, type, NULL, 0));
2331
  FREE_AND_NULL(str)
2332
  *msg = xmlStrcat(*msg, BAD_CAST "]");
2333
    }
2334
#endif
2335
0
    return (*msg);
2336
0
}
2337
2338
static void LIBXML_ATTR_FORMAT(3,0)
2339
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2340
         const char *funcName,
2341
         const char *message,
2342
         const xmlChar *str1,
2343
         const xmlChar *str2)
2344
0
{
2345
0
    xmlChar *msg = NULL;
2346
2347
0
    if (actxt == NULL)
2348
0
        return;
2349
0
    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2350
0
    msg = xmlStrcat(msg, BAD_CAST message);
2351
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2352
2353
0
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2354
0
  xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2355
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2356
0
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2357
0
  xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2358
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2359
2360
0
    FREE_AND_NULL(msg)
2361
0
}
2362
2363
static void LIBXML_ATTR_FORMAT(3,0)
2364
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2365
         const char *funcName,
2366
         const char *message)
2367
0
{
2368
0
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2369
0
}
2370
2371
#if 0
2372
static void LIBXML_ATTR_FORMAT(3,0)
2373
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2374
         const char *funcName,
2375
         const char *message,
2376
         const xmlChar *str1,
2377
         const xmlChar *str2)
2378
{
2379
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2380
  str1, str2);
2381
}
2382
#endif
2383
2384
static void LIBXML_ATTR_FORMAT(5,0)
2385
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2386
       xmlParserErrors error,
2387
       xmlNodePtr node,
2388
       xmlSchemaBasicItemPtr item,
2389
       const char *message,
2390
       const xmlChar *str1, const xmlChar *str2,
2391
       const xmlChar *str3, const xmlChar *str4)
2392
0
{
2393
0
    xmlChar *msg = NULL;
2394
2395
0
    if ((node == NULL) && (item != NULL) &&
2396
0
  (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2397
0
  node = WXS_ITEM_NODE(item);
2398
0
  xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2399
0
  msg = xmlStrcat(msg, BAD_CAST ": ");
2400
0
    } else
2401
0
  xmlSchemaFormatNodeForError(&msg, actxt, node);
2402
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2403
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2404
0
    xmlSchemaErr4(actxt, error, node,
2405
0
  (const char *) msg, str1, str2, str3, str4);
2406
0
    FREE_AND_NULL(msg)
2407
0
}
2408
2409
static void LIBXML_ATTR_FORMAT(5,0)
2410
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2411
       xmlParserErrors error,
2412
       xmlNodePtr node,
2413
       xmlSchemaBasicItemPtr item,
2414
       const char *message,
2415
       const xmlChar *str1,
2416
       const xmlChar *str2)
2417
0
{
2418
0
    xmlSchemaCustomErr4(actxt, error, node, item,
2419
0
  message, str1, str2, NULL, NULL);
2420
0
}
2421
2422
2423
2424
static void LIBXML_ATTR_FORMAT(5,0)
2425
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2426
       xmlParserErrors error,
2427
       xmlNodePtr node,
2428
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2429
       const char *message,
2430
       const xmlChar *str1,
2431
       const xmlChar *str2,
2432
       const xmlChar *str3)
2433
0
{
2434
0
    xmlChar *msg = NULL;
2435
2436
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2437
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2438
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2439
2440
    /* URGENT TODO: Set the error code to something sane. */
2441
0
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2442
0
  (const char *) msg, str1, str2, str3, NULL);
2443
2444
0
    FREE_AND_NULL(msg)
2445
0
}
2446
2447
2448
2449
static void LIBXML_ATTR_FORMAT(5,0)
2450
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2451
       xmlParserErrors error,
2452
       xmlSchemaPSVIIDCNodePtr idcNode,
2453
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2454
       const char *message,
2455
       const xmlChar *str1,
2456
       const xmlChar *str2)
2457
0
{
2458
0
    xmlChar *msg = NULL, *qname = NULL;
2459
2460
0
    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2461
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2462
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2463
0
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2464
0
  error, NULL, idcNode->nodeLine, (const char *) msg,
2465
0
  xmlSchemaFormatQName(&qname,
2466
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2467
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2468
0
  str1, str2, NULL);
2469
0
    FREE_AND_NULL(qname);
2470
0
    FREE_AND_NULL(msg);
2471
0
}
2472
2473
static int
2474
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2475
         xmlNodePtr node)
2476
0
{
2477
0
    if (node != NULL)
2478
0
  return (node->type);
2479
0
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2480
0
  (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2481
0
  return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2482
0
    return (-1);
2483
0
}
2484
2485
static int
2486
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2487
0
{
2488
0
    switch (item->type) {
2489
0
  case XML_SCHEMA_TYPE_COMPLEX:
2490
0
  case XML_SCHEMA_TYPE_SIMPLE:
2491
0
      if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2492
0
    return(1);
2493
0
      break;
2494
0
  case XML_SCHEMA_TYPE_GROUP:
2495
0
      return (1);
2496
0
  case XML_SCHEMA_TYPE_ELEMENT:
2497
0
      if ( ((xmlSchemaElementPtr) item)->flags &
2498
0
    XML_SCHEMAS_ELEM_GLOBAL)
2499
0
    return(1);
2500
0
      break;
2501
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
2502
0
      if ( ((xmlSchemaAttributePtr) item)->flags &
2503
0
    XML_SCHEMAS_ATTR_GLOBAL)
2504
0
    return(1);
2505
0
      break;
2506
  /* Note that attribute groups are always global. */
2507
0
  default:
2508
0
      return(1);
2509
0
    }
2510
0
    return (0);
2511
0
}
2512
2513
static void
2514
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2515
           xmlParserErrors error,
2516
           xmlNodePtr node,
2517
           const xmlChar *value,
2518
           xmlSchemaTypePtr type,
2519
           int displayValue)
2520
0
{
2521
0
    xmlChar *msg = NULL;
2522
2523
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2524
2525
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2526
0
      XML_ATTRIBUTE_NODE))
2527
0
  msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2528
0
    else
2529
0
  msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2530
0
      "value of ");
2531
2532
0
    if (! xmlSchemaIsGlobalItem(type))
2533
0
  msg = xmlStrcat(msg, BAD_CAST "the local ");
2534
0
    else
2535
0
  msg = xmlStrcat(msg, BAD_CAST "the ");
2536
2537
0
    if (WXS_IS_ATOMIC(type))
2538
0
  msg = xmlStrcat(msg, BAD_CAST "atomic type");
2539
0
    else if (WXS_IS_LIST(type))
2540
0
  msg = xmlStrcat(msg, BAD_CAST "list type");
2541
0
    else if (WXS_IS_UNION(type))
2542
0
  msg = xmlStrcat(msg, BAD_CAST "union type");
2543
2544
0
    if (xmlSchemaIsGlobalItem(type)) {
2545
0
  xmlChar *str = NULL;
2546
0
  msg = xmlStrcat(msg, BAD_CAST " '");
2547
0
  if (type->builtInType != 0) {
2548
0
      msg = xmlStrcat(msg, BAD_CAST "xs:");
2549
0
      str = xmlStrdup(type->name);
2550
0
  } else {
2551
0
      const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2552
0
      if (!str)
2553
0
    str = xmlStrdup(qName);
2554
0
  }
2555
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2556
0
  msg = xmlStrcat(msg, BAD_CAST "'");
2557
0
  FREE_AND_NULL(str);
2558
0
    }
2559
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2560
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2561
0
      XML_ATTRIBUTE_NODE))
2562
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2563
0
    else
2564
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2565
0
    FREE_AND_NULL(msg)
2566
0
}
2567
2568
static const xmlChar *
2569
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2570
            xmlSchemaNodeInfoPtr ni,
2571
            xmlNodePtr node)
2572
0
{
2573
0
    if (node != NULL) {
2574
0
  if (node->ns != NULL)
2575
0
      return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2576
0
  else
2577
0
      return (xmlSchemaFormatQName(str, NULL, node->name));
2578
0
    } else if (ni != NULL)
2579
0
  return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2580
0
    return (NULL);
2581
0
}
2582
2583
static void
2584
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2585
      xmlParserErrors error,
2586
      xmlSchemaAttrInfoPtr ni,
2587
      xmlNodePtr node)
2588
0
{
2589
0
    xmlChar *msg = NULL, *str = NULL;
2590
2591
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2592
0
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2593
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2594
0
  xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2595
0
  NULL);
2596
0
    FREE_AND_NULL(str)
2597
0
    FREE_AND_NULL(msg)
2598
0
}
2599
2600
static void LIBXML_ATTR_FORMAT(5,0)
2601
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2602
            xmlParserErrors error,
2603
            xmlNodePtr node,
2604
      xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2605
      const char *message,
2606
      int nbval,
2607
      int nbneg,
2608
      xmlChar **values)
2609
0
{
2610
0
    xmlChar *str = NULL, *msg = NULL;
2611
0
    xmlChar *localName, *nsName;
2612
0
    const xmlChar *cur, *end;
2613
0
    int i;
2614
2615
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2616
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2617
0
    msg = xmlStrcat(msg, BAD_CAST ".");
2618
    /*
2619
    * Note that is does not make sense to report that we have a
2620
    * wildcard here, since the wildcard might be unfolded into
2621
    * multiple transitions.
2622
    */
2623
0
    if (nbval + nbneg > 0) {
2624
0
  if (nbval + nbneg > 1) {
2625
0
      str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2626
0
  } else
2627
0
      str = xmlStrdup(BAD_CAST " Expected is ( ");
2628
0
  nsName = NULL;
2629
2630
0
  for (i = 0; i < nbval + nbneg; i++) {
2631
0
      cur = values[i];
2632
0
      if (cur == NULL)
2633
0
          continue;
2634
0
      if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2635
0
          (cur[3] == ' ')) {
2636
0
    cur += 4;
2637
0
    str = xmlStrcat(str, BAD_CAST "##other");
2638
0
      }
2639
      /*
2640
      * Get the local name.
2641
      */
2642
0
      localName = NULL;
2643
2644
0
      end = cur;
2645
0
      if (*end == '*') {
2646
0
    localName = xmlStrdup(BAD_CAST "*");
2647
0
    end++;
2648
0
      } else {
2649
0
    while ((*end != 0) && (*end != '|'))
2650
0
        end++;
2651
0
    localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2652
0
      }
2653
0
      if (*end != 0) {
2654
0
    end++;
2655
    /*
2656
    * Skip "*|*" if they come with negated expressions, since
2657
    * they represent the same negated wildcard.
2658
    */
2659
0
    if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2660
        /*
2661
        * Get the namespace name.
2662
        */
2663
0
        cur = end;
2664
0
        if (*end == '*') {
2665
0
      nsName = xmlStrdup(BAD_CAST "{*}");
2666
0
        } else {
2667
0
      while (*end != 0)
2668
0
          end++;
2669
2670
0
      if (i >= nbval)
2671
0
          nsName = xmlStrdup(BAD_CAST "{##other:");
2672
0
      else
2673
0
          nsName = xmlStrdup(BAD_CAST "{");
2674
2675
0
      nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2676
0
      nsName = xmlStrcat(nsName, BAD_CAST "}");
2677
0
        }
2678
0
        str = xmlStrcat(str, BAD_CAST nsName);
2679
0
        FREE_AND_NULL(nsName)
2680
0
    } else {
2681
0
        FREE_AND_NULL(localName);
2682
0
        continue;
2683
0
    }
2684
0
      }
2685
0
      str = xmlStrcat(str, BAD_CAST localName);
2686
0
      FREE_AND_NULL(localName);
2687
2688
0
      if (i < nbval + nbneg -1)
2689
0
    str = xmlStrcat(str, BAD_CAST ", ");
2690
0
  }
2691
0
  str = xmlStrcat(str, BAD_CAST " ).\n");
2692
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2693
0
  FREE_AND_NULL(str)
2694
0
    } else
2695
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
2696
0
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2697
0
    xmlFree(msg);
2698
0
}
2699
2700
static void LIBXML_ATTR_FORMAT(8,0)
2701
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2702
      xmlParserErrors error,
2703
      xmlNodePtr node,
2704
      const xmlChar *value,
2705
      unsigned long length,
2706
      xmlSchemaTypePtr type,
2707
      xmlSchemaFacetPtr facet,
2708
      const char *message,
2709
      const xmlChar *str1,
2710
      const xmlChar *str2)
2711
0
{
2712
0
    xmlChar *str = NULL, *msg = NULL;
2713
0
    xmlSchemaTypeType facetType;
2714
0
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2715
2716
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2717
0
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2718
0
  facetType = XML_SCHEMA_FACET_ENUMERATION;
2719
  /*
2720
  * If enumerations are validated, one must not expect the
2721
  * facet to be given.
2722
  */
2723
0
    } else
2724
0
  facetType = facet->type;
2725
0
    msg = xmlStrcat(msg, BAD_CAST "[");
2726
0
    msg = xmlStrcat(msg, BAD_CAST "facet '");
2727
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2728
0
    msg = xmlStrcat(msg, BAD_CAST "'] ");
2729
0
    if (message == NULL) {
2730
  /*
2731
  * Use a default message.
2732
  */
2733
0
  if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2734
0
      (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2735
0
      (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2736
2737
0
      char len[25], actLen[25];
2738
2739
      /* FIXME, TODO: What is the max expected string length of the
2740
      * this value?
2741
      */
2742
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2743
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2744
0
      else
2745
0
    msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2746
2747
0
      snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2748
0
      snprintf(actLen, 24, "%lu", length);
2749
2750
0
      if (facetType == XML_SCHEMA_FACET_LENGTH)
2751
0
    msg = xmlStrcat(msg,
2752
0
    BAD_CAST "this differs from the allowed length of '%s'.\n");
2753
0
      else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2754
0
    msg = xmlStrcat(msg,
2755
0
    BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2756
0
      else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2757
0
    msg = xmlStrcat(msg,
2758
0
    BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2759
2760
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2761
0
    xmlSchemaErr3(actxt, error, node, (const char *) msg,
2762
0
        value, (const xmlChar *) actLen, (const xmlChar *) len);
2763
0
      else
2764
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2765
0
        (const xmlChar *) actLen, (const xmlChar *) len);
2766
2767
0
  } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2768
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2769
0
    "of the set {%s}.\n");
2770
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2771
0
    xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2772
0
  } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2773
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2774
0
    "by the pattern '%s'.\n");
2775
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2776
0
    facet->value);
2777
0
  } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2778
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2779
0
    "minimum value allowed ('%s').\n");
2780
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2781
0
    facet->value);
2782
0
  } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2783
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2784
0
    "maximum value allowed ('%s').\n");
2785
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2786
0
    facet->value);
2787
0
  } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2788
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2789
0
    "'%s'.\n");
2790
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2791
0
    facet->value);
2792
0
  } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2793
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2794
0
    "'%s'.\n");
2795
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2796
0
    facet->value);
2797
0
  } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2798
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2799
0
    "digits than are allowed ('%s').\n");
2800
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2801
0
    facet->value);
2802
0
  } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2803
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2804
0
    "digits than are allowed ('%s').\n");
2805
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2806
0
    facet->value);
2807
0
  } else if (nodeType == XML_ATTRIBUTE_NODE) {
2808
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2809
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2810
0
  } else {
2811
0
      msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2812
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2813
0
  }
2814
0
    } else {
2815
0
  msg = xmlStrcat(msg, (const xmlChar *) message);
2816
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
2817
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2818
0
    }
2819
0
    FREE_AND_NULL(str)
2820
0
    xmlFree(msg);
2821
0
}
2822
2823
#define VERROR(err, type, msg) \
2824
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2825
2826
0
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2827
2828
0
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2829
0
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2830
2831
0
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2832
2833
2834
/**
2835
 * xmlSchemaPMissingAttrErr:
2836
 * @ctxt: the schema validation context
2837
 * @ownerItem: the owner as a schema object
2838
 * @ownerElem: the owner as an element node
2839
 * @node: the parent element node of the missing attribute node
2840
 * @type: the corresponding type of the attribute node
2841
 *
2842
 * Reports an illegal attribute.
2843
 */
2844
static void
2845
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2846
       xmlParserErrors error,
2847
       xmlSchemaBasicItemPtr ownerItem,
2848
       xmlNodePtr ownerElem,
2849
       const char *name,
2850
       const char *message)
2851
0
{
2852
0
    xmlChar *des = NULL;
2853
2854
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2855
2856
0
    if (message != NULL)
2857
0
  xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2858
0
    else
2859
0
  xmlSchemaPErr(ctxt, ownerElem, error,
2860
0
      "%s: The attribute '%s' is required but missing.\n",
2861
0
      BAD_CAST des, BAD_CAST name);
2862
0
    FREE_AND_NULL(des);
2863
0
}
2864
2865
2866
/**
2867
 * xmlSchemaPResCompAttrErr:
2868
 * @ctxt: the schema validation context
2869
 * @error: the error code
2870
 * @ownerItem: the owner as a schema object
2871
 * @ownerElem: the owner as an element node
2872
 * @name: the name of the attribute holding the QName
2873
 * @refName: the referenced local name
2874
 * @refURI: the referenced namespace URI
2875
 * @message: optional message
2876
 *
2877
 * Used to report QName attribute values that failed to resolve
2878
 * to schema components.
2879
 */
2880
static void
2881
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2882
       xmlParserErrors error,
2883
       xmlSchemaBasicItemPtr ownerItem,
2884
       xmlNodePtr ownerElem,
2885
       const char *name,
2886
       const xmlChar *refName,
2887
       const xmlChar *refURI,
2888
       xmlSchemaTypeType refType,
2889
       const char *refTypeStr)
2890
0
{
2891
0
    xmlChar *des = NULL, *strA = NULL;
2892
2893
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2894
0
    if (refTypeStr == NULL)
2895
0
  refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2896
0
    xmlSchemaPErrExt(ctxt, ownerElem, error,
2897
0
      NULL, NULL, NULL,
2898
0
      "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2899
0
      "%s.\n", BAD_CAST des, BAD_CAST name,
2900
0
      xmlSchemaFormatQName(&strA, refURI, refName),
2901
0
      BAD_CAST refTypeStr, NULL);
2902
0
    FREE_AND_NULL(des)
2903
0
    FREE_AND_NULL(strA)
2904
0
}
2905
2906
/**
2907
 * xmlSchemaPCustomAttrErr:
2908
 * @ctxt: the schema parser context
2909
 * @error: the error code
2910
 * @ownerDes: the designation of the owner
2911
 * @ownerItem: the owner as a schema object
2912
 * @attr: the illegal attribute node
2913
 *
2914
 * Reports an illegal attribute during the parse.
2915
 */
2916
static void
2917
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2918
      xmlParserErrors error,
2919
      xmlChar **ownerDes,
2920
      xmlSchemaBasicItemPtr ownerItem,
2921
      xmlAttrPtr attr,
2922
      const char *msg)
2923
0
{
2924
0
    xmlChar *des = NULL;
2925
2926
0
    if (ownerDes == NULL)
2927
0
  xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2928
0
    else if (*ownerDes == NULL) {
2929
0
  xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2930
0
  des = *ownerDes;
2931
0
    } else
2932
0
  des = *ownerDes;
2933
0
    if (attr == NULL) {
2934
0
  xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2935
0
      "%s, attribute '%s': %s.\n",
2936
0
      BAD_CAST des, (const xmlChar *) "Unknown",
2937
0
      (const xmlChar *) msg, NULL, NULL);
2938
0
    } else {
2939
0
  xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2940
0
      "%s, attribute '%s': %s.\n",
2941
0
      BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2942
0
    }
2943
0
    if (ownerDes == NULL)
2944
0
  FREE_AND_NULL(des);
2945
0
}
2946
2947
/**
2948
 * xmlSchemaPIllegalAttrErr:
2949
 * @ctxt: the schema parser context
2950
 * @error: the error code
2951
 * @ownerItem: the attribute's owner item
2952
 * @attr: the illegal attribute node
2953
 *
2954
 * Reports an illegal attribute during the parse.
2955
 */
2956
static void
2957
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2958
       xmlParserErrors error,
2959
       xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2960
       xmlAttrPtr attr)
2961
0
{
2962
0
    xmlChar *strA = NULL, *strB = NULL;
2963
2964
0
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2965
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2966
0
  "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2967
0
  xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2968
0
  NULL, NULL);
2969
0
    FREE_AND_NULL(strA);
2970
0
    FREE_AND_NULL(strB);
2971
0
}
2972
2973
/**
2974
 * xmlSchemaPCustomErr:
2975
 * @ctxt: the schema parser context
2976
 * @error: the error code
2977
 * @itemDes: the designation of the schema item
2978
 * @item: the schema item
2979
 * @itemElem: the node of the schema item
2980
 * @message: the error message
2981
 * @str1: an optional param for the error message
2982
 * @str2: an optional param for the error message
2983
 * @str3: an optional param for the error message
2984
 *
2985
 * Reports an error during parsing.
2986
 */
2987
static void LIBXML_ATTR_FORMAT(5,0)
2988
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2989
        xmlParserErrors error,
2990
        xmlSchemaBasicItemPtr item,
2991
        xmlNodePtr itemElem,
2992
        const char *message,
2993
        const xmlChar *str1,
2994
        const xmlChar *str2,
2995
        const xmlChar *str3)
2996
0
{
2997
0
    xmlChar *des = NULL, *msg = NULL;
2998
2999
0
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
3000
0
    msg = xmlStrdup(BAD_CAST "%s: ");
3001
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3002
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3003
0
    if ((itemElem == NULL) && (item != NULL))
3004
0
  itemElem = WXS_ITEM_NODE(item);
3005
0
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3006
0
  (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3007
0
    FREE_AND_NULL(des);
3008
0
    FREE_AND_NULL(msg);
3009
0
}
3010
3011
/**
3012
 * xmlSchemaPCustomErr:
3013
 * @ctxt: the schema parser context
3014
 * @error: the error code
3015
 * @itemDes: the designation of the schema item
3016
 * @item: the schema item
3017
 * @itemElem: the node of the schema item
3018
 * @message: the error message
3019
 * @str1: the optional param for the error message
3020
 *
3021
 * Reports an error during parsing.
3022
 */
3023
static void LIBXML_ATTR_FORMAT(5,0)
3024
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3025
        xmlParserErrors error,
3026
        xmlSchemaBasicItemPtr item,
3027
        xmlNodePtr itemElem,
3028
        const char *message,
3029
        const xmlChar *str1)
3030
0
{
3031
0
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3032
0
  str1, NULL, NULL);
3033
0
}
3034
3035
/**
3036
 * xmlSchemaPAttrUseErr:
3037
 * @ctxt: the schema parser context
3038
 * @error: the error code
3039
 * @itemDes: the designation of the schema type
3040
 * @item: the schema type
3041
 * @itemElem: the node of the schema type
3042
 * @attr: the invalid schema attribute
3043
 * @message: the error message
3044
 * @str1: the optional param for the error message
3045
 *
3046
 * Reports an attribute use error during parsing.
3047
 */
3048
static void LIBXML_ATTR_FORMAT(6,0)
3049
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3050
        xmlParserErrors error,
3051
        xmlNodePtr node,
3052
        xmlSchemaBasicItemPtr ownerItem,
3053
        const xmlSchemaAttributeUsePtr attruse,
3054
        const char *message,
3055
        const xmlChar *str1, const xmlChar *str2,
3056
        const xmlChar *str3,const xmlChar *str4)
3057
0
{
3058
0
    xmlChar *str = NULL, *msg = NULL;
3059
3060
0
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3061
0
    msg = xmlStrcat(msg, BAD_CAST ", ");
3062
0
    msg = xmlStrcat(msg,
3063
0
  BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3064
0
  WXS_BASIC_CAST attruse, NULL));
3065
0
    FREE_AND_NULL(str);
3066
0
    msg = xmlStrcat(msg, BAD_CAST ": ");
3067
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3068
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3069
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3070
0
  (const char *) msg, str1, str2, str3, str4);
3071
0
    xmlFree(msg);
3072
0
}
3073
3074
/**
3075
 * xmlSchemaPIllegalFacetAtomicErr:
3076
 * @ctxt: the schema parser context
3077
 * @error: the error code
3078
 * @type: the schema type
3079
 * @baseType: the base type of type
3080
 * @facet: the illegal facet
3081
 *
3082
 * Reports an illegal facet for atomic simple types.
3083
 */
3084
static void
3085
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3086
        xmlParserErrors error,
3087
        xmlSchemaTypePtr type,
3088
        xmlSchemaTypePtr baseType,
3089
        xmlSchemaFacetPtr facet)
3090
0
{
3091
0
    xmlChar *des = NULL, *strT = NULL;
3092
3093
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3094
0
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3095
0
  "%s: The facet '%s' is not allowed on types derived from the "
3096
0
  "type %s.\n",
3097
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3098
0
  xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3099
0
  NULL, NULL);
3100
0
    FREE_AND_NULL(des);
3101
0
    FREE_AND_NULL(strT);
3102
0
}
3103
3104
/**
3105
 * xmlSchemaPIllegalFacetListUnionErr:
3106
 * @ctxt: the schema parser context
3107
 * @error: the error code
3108
 * @itemDes: the designation of the schema item involved
3109
 * @item: the schema item involved
3110
 * @facet: the illegal facet
3111
 *
3112
 * Reports an illegal facet for <list> and <union>.
3113
 */
3114
static void
3115
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3116
        xmlParserErrors error,
3117
        xmlSchemaTypePtr type,
3118
        xmlSchemaFacetPtr facet)
3119
0
{
3120
0
    xmlChar *des = NULL;
3121
3122
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3123
0
  type->node);
3124
0
    xmlSchemaPErr(ctxt, type->node, error,
3125
0
  "%s: The facet '%s' is not allowed.\n",
3126
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3127
0
    FREE_AND_NULL(des);
3128
0
}
3129
3130
/**
3131
 * xmlSchemaPMutualExclAttrErr:
3132
 * @ctxt: the schema validation context
3133
 * @error: the error code
3134
 * @elemDes: the designation of the parent element node
3135
 * @attr: the bad attribute node
3136
 * @type: the corresponding type of the attribute node
3137
 *
3138
 * Reports an illegal attribute.
3139
 */
3140
static void
3141
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3142
       xmlParserErrors error,
3143
       xmlSchemaBasicItemPtr ownerItem,
3144
       xmlAttrPtr attr,
3145
       const char *name1,
3146
       const char *name2)
3147
0
{
3148
0
    xmlChar *des = NULL;
3149
3150
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3151
0
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3152
0
  "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3153
0
  BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3154
0
    FREE_AND_NULL(des);
3155
0
}
3156
3157
/**
3158
 * xmlSchemaPSimpleTypeErr:
3159
 * @ctxt:  the schema validation context
3160
 * @error: the error code
3161
 * @type: the type specifier
3162
 * @ownerItem: the schema object if existent
3163
 * @node: the validated node
3164
 * @value: the validated value
3165
 *
3166
 * Reports a simple type validation error.
3167
 * TODO: Should this report the value of an element as well?
3168
 */
3169
static void LIBXML_ATTR_FORMAT(8,0)
3170
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3171
      xmlParserErrors error,
3172
      xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3173
      xmlNodePtr node,
3174
      xmlSchemaTypePtr type,
3175
      const char *expected,
3176
      const xmlChar *value,
3177
      const char *message,
3178
      const xmlChar *str1,
3179
      const xmlChar *str2)
3180
0
{
3181
0
    xmlChar *msg = NULL;
3182
3183
0
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3184
0
    if (message == NULL) {
3185
  /*
3186
  * Use default messages.
3187
  */
3188
0
  if (type != NULL) {
3189
0
      if (node->type == XML_ATTRIBUTE_NODE)
3190
0
    msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3191
0
      else
3192
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3193
0
    "valid value of ");
3194
0
      if (! xmlSchemaIsGlobalItem(type))
3195
0
    msg = xmlStrcat(msg, BAD_CAST "the local ");
3196
0
      else
3197
0
    msg = xmlStrcat(msg, BAD_CAST "the ");
3198
3199
0
      if (WXS_IS_ATOMIC(type))
3200
0
    msg = xmlStrcat(msg, BAD_CAST "atomic type");
3201
0
      else if (WXS_IS_LIST(type))
3202
0
    msg = xmlStrcat(msg, BAD_CAST "list type");
3203
0
      else if (WXS_IS_UNION(type))
3204
0
    msg = xmlStrcat(msg, BAD_CAST "union type");
3205
3206
0
      if (xmlSchemaIsGlobalItem(type)) {
3207
0
    xmlChar *str = NULL;
3208
0
    msg = xmlStrcat(msg, BAD_CAST " '");
3209
0
    if (type->builtInType != 0) {
3210
0
        msg = xmlStrcat(msg, BAD_CAST "xs:");
3211
0
        str = xmlStrdup(type->name);
3212
0
    } else {
3213
0
        const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3214
0
        if (!str)
3215
0
      str = xmlStrdup(qName);
3216
0
    }
3217
0
    msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3218
0
    msg = xmlStrcat(msg, BAD_CAST "'.");
3219
0
    FREE_AND_NULL(str);
3220
0
      }
3221
0
  } else {
3222
0
      if (node->type == XML_ATTRIBUTE_NODE)
3223
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3224
0
      else
3225
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3226
0
    "valid.");
3227
0
  }
3228
0
  if (expected) {
3229
0
      xmlChar *expectedEscaped = xmlCharStrdup(expected);
3230
0
      msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3231
0
      msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3232
0
      FREE_AND_NULL(expectedEscaped);
3233
0
      msg = xmlStrcat(msg, BAD_CAST "'.\n");
3234
0
  } else
3235
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
3236
0
  if (node->type == XML_ATTRIBUTE_NODE)
3237
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3238
0
  else
3239
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3240
0
    } else {
3241
0
  msg = xmlStrcat(msg, BAD_CAST message);
3242
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
3243
0
  xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3244
0
       (const char*) msg, str1, str2, NULL, NULL, NULL);
3245
0
    }
3246
    /* Cleanup. */
3247
0
    FREE_AND_NULL(msg)
3248
0
}
3249
3250
/**
3251
 * xmlSchemaPContentErr:
3252
 * @ctxt: the schema parser context
3253
 * @error: the error code
3254
 * @ownerItem: the owner item of the holder of the content
3255
 * @ownerElem: the node of the holder of the content
3256
 * @child: the invalid child node
3257
 * @message: the optional error message
3258
 * @content: the optional string describing the correct content
3259
 *
3260
 * Reports an error concerning the content of a schema element.
3261
 */
3262
static void
3263
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3264
         xmlParserErrors error,
3265
         xmlSchemaBasicItemPtr ownerItem,
3266
         xmlNodePtr ownerElem,
3267
         xmlNodePtr child,
3268
         const char *message,
3269
         const char *content)
3270
0
{
3271
0
    xmlChar *des = NULL;
3272
3273
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3274
0
    if (message != NULL)
3275
0
  xmlSchemaPErr2(ctxt, ownerElem, child, error,
3276
0
      "%s: %s.\n",
3277
0
      BAD_CAST des, BAD_CAST message);
3278
0
    else {
3279
0
  if (content != NULL) {
3280
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3281
0
    "%s: The content is not valid. Expected is %s.\n",
3282
0
    BAD_CAST des, BAD_CAST content);
3283
0
  } else {
3284
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3285
0
    "%s: The content is not valid.\n",
3286
0
    BAD_CAST des, NULL);
3287
0
  }
3288
0
    }
3289
0
    FREE_AND_NULL(des)
3290
0
}
3291
3292
/************************************************************************
3293
 *                  *
3294
 *      Streamable error functions                      *
3295
 *                  *
3296
 ************************************************************************/
3297
3298
3299
3300
3301
/************************************************************************
3302
 *                  *
3303
 *      Validation helper functions     *
3304
 *                  *
3305
 ************************************************************************/
3306
3307
3308
/************************************************************************
3309
 *                  *
3310
 *      Allocation functions        *
3311
 *                  *
3312
 ************************************************************************/
3313
3314
/**
3315
 * xmlSchemaNewSchemaForParserCtxt:
3316
 * @ctxt:  a schema validation context
3317
 *
3318
 * Allocate a new Schema structure.
3319
 *
3320
 * Returns the newly allocated structure or NULL in case or error
3321
 */
3322
static xmlSchemaPtr
3323
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3324
0
{
3325
0
    xmlSchemaPtr ret;
3326
3327
0
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3328
0
    if (ret == NULL) {
3329
0
        xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
3330
0
        return (NULL);
3331
0
    }
3332
0
    memset(ret, 0, sizeof(xmlSchema));
3333
0
    ret->dict = ctxt->dict;
3334
0
    xmlDictReference(ret->dict);
3335
3336
0
    return (ret);
3337
0
}
3338
3339
/**
3340
 * xmlSchemaNewFacet:
3341
 *
3342
 * Allocate a new Facet structure.
3343
 *
3344
 * Returns the newly allocated structure or NULL in case or error
3345
 */
3346
xmlSchemaFacetPtr
3347
xmlSchemaNewFacet(void)
3348
0
{
3349
0
    xmlSchemaFacetPtr ret;
3350
3351
0
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3352
0
    if (ret == NULL) {
3353
0
        return (NULL);
3354
0
    }
3355
0
    memset(ret, 0, sizeof(xmlSchemaFacet));
3356
3357
0
    return (ret);
3358
0
}
3359
3360
/**
3361
 * xmlSchemaNewAnnot:
3362
 * @ctxt:  a schema validation context
3363
 * @node:  a node
3364
 *
3365
 * Allocate a new annotation structure.
3366
 *
3367
 * Returns the newly allocated structure or NULL in case or error
3368
 */
3369
static xmlSchemaAnnotPtr
3370
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3371
0
{
3372
0
    xmlSchemaAnnotPtr ret;
3373
3374
0
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3375
0
    if (ret == NULL) {
3376
0
        xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3377
0
        return (NULL);
3378
0
    }
3379
0
    memset(ret, 0, sizeof(xmlSchemaAnnot));
3380
0
    ret->content = node;
3381
0
    return (ret);
3382
0
}
3383
3384
static xmlSchemaItemListPtr
3385
xmlSchemaItemListCreate(void)
3386
0
{
3387
0
    xmlSchemaItemListPtr ret;
3388
3389
0
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3390
0
    if (ret == NULL) {
3391
0
  xmlSchemaPErrMemory(NULL,
3392
0
      "allocating an item list structure", NULL);
3393
0
  return (NULL);
3394
0
    }
3395
0
    memset(ret, 0, sizeof(xmlSchemaItemList));
3396
0
    return (ret);
3397
0
}
3398
3399
static void
3400
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3401
0
{
3402
0
    if (list->items != NULL) {
3403
0
  xmlFree(list->items);
3404
0
  list->items = NULL;
3405
0
    }
3406
0
    list->nbItems = 0;
3407
0
    list->sizeItems = 0;
3408
0
}
3409
3410
static int
3411
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3412
0
{
3413
0
    if (list->items == NULL) {
3414
0
  list->items = (void **) xmlMalloc(
3415
0
      20 * sizeof(void *));
3416
0
  if (list->items == NULL) {
3417
0
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3418
0
      return(-1);
3419
0
  }
3420
0
  list->sizeItems = 20;
3421
0
    } else if (list->sizeItems <= list->nbItems) {
3422
0
  list->sizeItems *= 2;
3423
0
  list->items = (void **) xmlRealloc(list->items,
3424
0
      list->sizeItems * sizeof(void *));
3425
0
  if (list->items == NULL) {
3426
0
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3427
0
      list->sizeItems = 0;
3428
0
      return(-1);
3429
0
  }
3430
0
    }
3431
0
    list->items[list->nbItems++] = item;
3432
0
    return(0);
3433
0
}
3434
3435
static int
3436
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3437
       int initialSize,
3438
       void *item)
3439
0
{
3440
0
    if (list->items == NULL) {
3441
0
  if (initialSize <= 0)
3442
0
      initialSize = 1;
3443
0
  list->items = (void **) xmlMalloc(
3444
0
      initialSize * sizeof(void *));
3445
0
  if (list->items == NULL) {
3446
0
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3447
0
      return(-1);
3448
0
  }
3449
0
  list->sizeItems = initialSize;
3450
0
    } else if (list->sizeItems <= list->nbItems) {
3451
0
  list->sizeItems *= 2;
3452
0
  list->items = (void **) xmlRealloc(list->items,
3453
0
      list->sizeItems * sizeof(void *));
3454
0
  if (list->items == NULL) {
3455
0
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3456
0
      list->sizeItems = 0;
3457
0
      return(-1);
3458
0
  }
3459
0
    }
3460
0
    list->items[list->nbItems++] = item;
3461
0
    return(0);
3462
0
}
3463
3464
static int
3465
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3466
0
{
3467
0
    if (list->items == NULL) {
3468
0
  list->items = (void **) xmlMalloc(
3469
0
      20 * sizeof(void *));
3470
0
  if (list->items == NULL) {
3471
0
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3472
0
      return(-1);
3473
0
  }
3474
0
  list->sizeItems = 20;
3475
0
    } else if (list->sizeItems <= list->nbItems) {
3476
0
  list->sizeItems *= 2;
3477
0
  list->items = (void **) xmlRealloc(list->items,
3478
0
      list->sizeItems * sizeof(void *));
3479
0
  if (list->items == NULL) {
3480
0
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3481
0
      list->sizeItems = 0;
3482
0
      return(-1);
3483
0
  }
3484
0
    }
3485
    /*
3486
    * Just append if the index is greater/equal than the item count.
3487
    */
3488
0
    if (idx >= list->nbItems) {
3489
0
  list->items[list->nbItems++] = item;
3490
0
    } else {
3491
0
  int i;
3492
0
  for (i = list->nbItems; i > idx; i--)
3493
0
      list->items[i] = list->items[i-1];
3494
0
  list->items[idx] = item;
3495
0
  list->nbItems++;
3496
0
    }
3497
0
    return(0);
3498
0
}
3499
3500
#if 0 /* enable if ever needed */
3501
static int
3502
xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3503
          int initialSize,
3504
          void *item,
3505
          int idx)
3506
{
3507
    if (list->items == NULL) {
3508
  if (initialSize <= 0)
3509
      initialSize = 1;
3510
  list->items = (void **) xmlMalloc(
3511
      initialSize * sizeof(void *));
3512
  if (list->items == NULL) {
3513
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3514
      return(-1);
3515
  }
3516
  list->sizeItems = initialSize;
3517
    } else if (list->sizeItems <= list->nbItems) {
3518
  list->sizeItems *= 2;
3519
  list->items = (void **) xmlRealloc(list->items,
3520
      list->sizeItems * sizeof(void *));
3521
  if (list->items == NULL) {
3522
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3523
      list->sizeItems = 0;
3524
      return(-1);
3525
  }
3526
    }
3527
    /*
3528
    * Just append if the index is greater/equal than the item count.
3529
    */
3530
    if (idx >= list->nbItems) {
3531
  list->items[list->nbItems++] = item;
3532
    } else {
3533
  int i;
3534
  for (i = list->nbItems; i > idx; i--)
3535
      list->items[i] = list->items[i-1];
3536
  list->items[idx] = item;
3537
  list->nbItems++;
3538
    }
3539
    return(0);
3540
}
3541
#endif
3542
3543
static int
3544
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3545
0
{
3546
0
    int i;
3547
0
    if ((list->items == NULL) || (idx >= list->nbItems)) {
3548
0
  xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3549
0
      "index error.\n");
3550
0
  return(-1);
3551
0
    }
3552
3553
0
    if (list->nbItems == 1) {
3554
  /* TODO: Really free the list? */
3555
0
  xmlFree(list->items);
3556
0
  list->items = NULL;
3557
0
  list->nbItems = 0;
3558
0
  list->sizeItems = 0;
3559
0
    } else if (list->nbItems -1 == idx) {
3560
0
  list->nbItems--;
3561
0
    } else {
3562
0
  for (i = idx; i < list->nbItems -1; i++)
3563
0
      list->items[i] = list->items[i+1];
3564
0
  list->nbItems--;
3565
0
    }
3566
0
    return(0);
3567
0
}
3568
3569
/**
3570
 * xmlSchemaItemListFree:
3571
 * @annot:  a schema type structure
3572
 *
3573
 * Deallocate a annotation structure
3574
 */
3575
static void
3576
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3577
0
{
3578
0
    if (list == NULL)
3579
0
  return;
3580
0
    if (list->items != NULL)
3581
0
  xmlFree(list->items);
3582
0
    xmlFree(list);
3583
0
}
3584
3585
static void
3586
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3587
0
{
3588
0
    if (bucket == NULL)
3589
0
  return;
3590
0
    if (bucket->globals != NULL) {
3591
0
  xmlSchemaComponentListFree(bucket->globals);
3592
0
  xmlSchemaItemListFree(bucket->globals);
3593
0
    }
3594
0
    if (bucket->locals != NULL) {
3595
0
  xmlSchemaComponentListFree(bucket->locals);
3596
0
  xmlSchemaItemListFree(bucket->locals);
3597
0
    }
3598
0
    if (bucket->relations != NULL) {
3599
0
  xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3600
0
  do {
3601
0
      prev = cur;
3602
0
      cur = cur->next;
3603
0
      xmlFree(prev);
3604
0
  } while (cur != NULL);
3605
0
    }
3606
0
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3607
0
  xmlFreeDoc(bucket->doc);
3608
0
    }
3609
0
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3610
0
  if (WXS_IMPBUCKET(bucket)->schema != NULL)
3611
0
      xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3612
0
    }
3613
0
    xmlFree(bucket);
3614
0
}
3615
3616
static void
3617
xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3618
0
{
3619
0
    xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3620
0
}
3621
3622
static xmlSchemaBucketPtr
3623
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3624
       int type, const xmlChar *targetNamespace)
3625
0
{
3626
0
    xmlSchemaBucketPtr ret;
3627
0
    int size;
3628
0
    xmlSchemaPtr mainSchema;
3629
3630
0
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3631
0
  PERROR_INT("xmlSchemaBucketCreate",
3632
0
      "no main schema on constructor");
3633
0
  return(NULL);
3634
0
    }
3635
0
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3636
    /* Create the schema bucket. */
3637
0
    if (WXS_IS_BUCKET_INCREDEF(type))
3638
0
  size = sizeof(xmlSchemaInclude);
3639
0
    else
3640
0
  size = sizeof(xmlSchemaImport);
3641
0
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3642
0
    if (ret == NULL) {
3643
0
  xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
3644
0
  return(NULL);
3645
0
    }
3646
0
    memset(ret, 0, size);
3647
0
    ret->targetNamespace = targetNamespace;
3648
0
    ret->type = type;
3649
0
    ret->globals = xmlSchemaItemListCreate();
3650
0
    if (ret->globals == NULL) {
3651
0
  xmlFree(ret);
3652
0
  return(NULL);
3653
0
    }
3654
0
    ret->locals = xmlSchemaItemListCreate();
3655
0
    if (ret->locals == NULL) {
3656
0
  xmlFree(ret);
3657
0
  return(NULL);
3658
0
    }
3659
    /*
3660
    * The following will assure that only the first bucket is marked as
3661
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3662
    * For each following import buckets an xmlSchema will be created.
3663
    * An xmlSchema will be created for every distinct targetNamespace.
3664
    * We assign the targetNamespace to the schemata here.
3665
    */
3666
0
    if (! WXS_HAS_BUCKETS(pctxt)) {
3667
0
  if (WXS_IS_BUCKET_INCREDEF(type)) {
3668
0
      PERROR_INT("xmlSchemaBucketCreate",
3669
0
    "first bucket but it's an include or redefine");
3670
0
      xmlSchemaBucketFree(ret);
3671
0
      return(NULL);
3672
0
  }
3673
  /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3674
0
  ret->type = XML_SCHEMA_SCHEMA_MAIN;
3675
  /* Point to the *main* schema. */
3676
0
  WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3677
0
  WXS_IMPBUCKET(ret)->schema = mainSchema;
3678
  /*
3679
  * Ensure that the main schema gets a targetNamespace.
3680
  */
3681
0
  mainSchema->targetNamespace = targetNamespace;
3682
0
    } else {
3683
0
  if (type == XML_SCHEMA_SCHEMA_MAIN) {
3684
0
      PERROR_INT("xmlSchemaBucketCreate",
3685
0
    "main bucket but it's not the first one");
3686
0
      xmlSchemaBucketFree(ret);
3687
0
      return(NULL);
3688
0
  } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3689
      /*
3690
      * Create a schema for imports and assign the
3691
      * targetNamespace.
3692
      */
3693
0
      WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3694
0
      if (WXS_IMPBUCKET(ret)->schema == NULL) {
3695
0
    xmlSchemaBucketFree(ret);
3696
0
    return(NULL);
3697
0
      }
3698
0
      WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3699
0
  }
3700
0
    }
3701
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3702
0
  int res;
3703
  /*
3704
  * Imports go into the "schemasImports" slot of the main *schema*.
3705
  * Note that we create an import entry for the main schema as well; i.e.,
3706
  * even if there's only one schema, we'll get an import.
3707
  */
3708
0
  if (mainSchema->schemasImports == NULL) {
3709
0
      mainSchema->schemasImports = xmlHashCreateDict(5,
3710
0
    WXS_CONSTRUCTOR(pctxt)->dict);
3711
0
      if (mainSchema->schemasImports == NULL) {
3712
0
    xmlSchemaBucketFree(ret);
3713
0
    return(NULL);
3714
0
      }
3715
0
  }
3716
0
  if (targetNamespace == NULL)
3717
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3718
0
    XML_SCHEMAS_NO_NAMESPACE, ret);
3719
0
  else
3720
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3721
0
    targetNamespace, ret);
3722
0
  if (res != 0) {
3723
0
      PERROR_INT("xmlSchemaBucketCreate",
3724
0
    "failed to add the schema bucket to the hash");
3725
0
      xmlSchemaBucketFree(ret);
3726
0
      return(NULL);
3727
0
  }
3728
0
    } else {
3729
  /* Set the @ownerImport of an include bucket. */
3730
0
  if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3731
0
      WXS_INCBUCKET(ret)->ownerImport =
3732
0
    WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3733
0
  else
3734
0
      WXS_INCBUCKET(ret)->ownerImport =
3735
0
    WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3736
3737
  /* Includes got into the "includes" slot of the *main* schema. */
3738
0
  if (mainSchema->includes == NULL) {
3739
0
      mainSchema->includes = xmlSchemaItemListCreate();
3740
0
      if (mainSchema->includes == NULL) {
3741
0
    xmlSchemaBucketFree(ret);
3742
0
    return(NULL);
3743
0
      }
3744
0
  }
3745
0
  xmlSchemaItemListAdd(mainSchema->includes, ret);
3746
0
    }
3747
    /*
3748
    * Add to list of all buckets; this is used for lookup
3749
    * during schema construction time only.
3750
    */
3751
0
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3752
0
  return(NULL);
3753
0
    return(ret);
3754
0
}
3755
3756
static int
3757
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3758
0
{
3759
0
    if (*list == NULL) {
3760
0
  *list = xmlSchemaItemListCreate();
3761
0
  if (*list == NULL)
3762
0
      return(-1);
3763
0
    }
3764
0
    xmlSchemaItemListAddSize(*list, initialSize, item);
3765
0
    return(0);
3766
0
}
3767
3768
/**
3769
 * xmlSchemaFreeAnnot:
3770
 * @annot:  a schema type structure
3771
 *
3772
 * Deallocate a annotation structure
3773
 */
3774
static void
3775
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3776
0
{
3777
0
    if (annot == NULL)
3778
0
        return;
3779
0
    if (annot->next == NULL) {
3780
0
  xmlFree(annot);
3781
0
    } else {
3782
0
  xmlSchemaAnnotPtr prev;
3783
3784
0
  do {
3785
0
      prev = annot;
3786
0
      annot = annot->next;
3787
0
      xmlFree(prev);
3788
0
  } while (annot != NULL);
3789
0
    }
3790
0
}
3791
3792
/**
3793
 * xmlSchemaFreeNotation:
3794
 * @schema:  a schema notation structure
3795
 *
3796
 * Deallocate a Schema Notation structure.
3797
 */
3798
static void
3799
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3800
0
{
3801
0
    if (nota == NULL)
3802
0
        return;
3803
0
    xmlFree(nota);
3804
0
}
3805
3806
/**
3807
 * xmlSchemaFreeAttribute:
3808
 * @attr:  an attribute declaration
3809
 *
3810
 * Deallocates an attribute declaration structure.
3811
 */
3812
static void
3813
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3814
0
{
3815
0
    if (attr == NULL)
3816
0
        return;
3817
0
    if (attr->annot != NULL)
3818
0
  xmlSchemaFreeAnnot(attr->annot);
3819
0
    if (attr->defVal != NULL)
3820
0
  xmlSchemaFreeValue(attr->defVal);
3821
0
    xmlFree(attr);
3822
0
}
3823
3824
/**
3825
 * xmlSchemaFreeAttributeUse:
3826
 * @use:  an attribute use
3827
 *
3828
 * Deallocates an attribute use structure.
3829
 */
3830
static void
3831
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3832
0
{
3833
0
    if (use == NULL)
3834
0
        return;
3835
0
    if (use->annot != NULL)
3836
0
  xmlSchemaFreeAnnot(use->annot);
3837
0
    if (use->defVal != NULL)
3838
0
  xmlSchemaFreeValue(use->defVal);
3839
0
    xmlFree(use);
3840
0
}
3841
3842
/**
3843
 * xmlSchemaFreeAttributeUseProhib:
3844
 * @prohib:  an attribute use prohibition
3845
 *
3846
 * Deallocates an attribute use structure.
3847
 */
3848
static void
3849
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3850
0
{
3851
0
    if (prohib == NULL)
3852
0
        return;
3853
0
    xmlFree(prohib);
3854
0
}
3855
3856
/**
3857
 * xmlSchemaFreeWildcardNsSet:
3858
 * set:  a schema wildcard namespace
3859
 *
3860
 * Deallocates a list of wildcard constraint structures.
3861
 */
3862
static void
3863
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3864
0
{
3865
0
    xmlSchemaWildcardNsPtr next;
3866
3867
0
    while (set != NULL) {
3868
0
  next = set->next;
3869
0
  xmlFree(set);
3870
0
  set = next;
3871
0
    }
3872
0
}
3873
3874
/**
3875
 * xmlSchemaFreeWildcard:
3876
 * @wildcard:  a wildcard structure
3877
 *
3878
 * Deallocates a wildcard structure.
3879
 */
3880
void
3881
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3882
0
{
3883
0
    if (wildcard == NULL)
3884
0
        return;
3885
0
    if (wildcard->annot != NULL)
3886
0
        xmlSchemaFreeAnnot(wildcard->annot);
3887
0
    if (wildcard->nsSet != NULL)
3888
0
  xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3889
0
    if (wildcard->negNsSet != NULL)
3890
0
  xmlFree(wildcard->negNsSet);
3891
0
    xmlFree(wildcard);
3892
0
}
3893
3894
/**
3895
 * xmlSchemaFreeAttributeGroup:
3896
 * @schema:  a schema attribute group structure
3897
 *
3898
 * Deallocate a Schema Attribute Group structure.
3899
 */
3900
static void
3901
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3902
0
{
3903
0
    if (attrGr == NULL)
3904
0
        return;
3905
0
    if (attrGr->annot != NULL)
3906
0
        xmlSchemaFreeAnnot(attrGr->annot);
3907
0
    if (attrGr->attrUses != NULL)
3908
0
  xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3909
0
    xmlFree(attrGr);
3910
0
}
3911
3912
/**
3913
 * xmlSchemaFreeQNameRef:
3914
 * @item: a QName reference structure
3915
 *
3916
 * Deallocatea a QName reference structure.
3917
 */
3918
static void
3919
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3920
0
{
3921
0
    xmlFree(item);
3922
0
}
3923
3924
/**
3925
 * xmlSchemaFreeTypeLinkList:
3926
 * @alink: a type link
3927
 *
3928
 * Deallocate a list of types.
3929
 */
3930
static void
3931
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3932
0
{
3933
0
    xmlSchemaTypeLinkPtr next;
3934
3935
0
    while (link != NULL) {
3936
0
  next = link->next;
3937
0
  xmlFree(link);
3938
0
  link = next;
3939
0
    }
3940
0
}
3941
3942
static void
3943
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3944
0
{
3945
0
    xmlSchemaIDCStateObjPtr next;
3946
0
    while (sto != NULL) {
3947
0
  next = sto->next;
3948
0
  if (sto->history != NULL)
3949
0
      xmlFree(sto->history);
3950
0
  if (sto->xpathCtxt != NULL)
3951
0
      xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3952
0
  xmlFree(sto);
3953
0
  sto = next;
3954
0
    }
3955
0
}
3956
3957
/**
3958
 * xmlSchemaFreeIDC:
3959
 * @idc: a identity-constraint definition
3960
 *
3961
 * Deallocates an identity-constraint definition.
3962
 */
3963
static void
3964
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3965
0
{
3966
0
    xmlSchemaIDCSelectPtr cur, prev;
3967
3968
0
    if (idcDef == NULL)
3969
0
  return;
3970
0
    if (idcDef->annot != NULL)
3971
0
        xmlSchemaFreeAnnot(idcDef->annot);
3972
    /* Selector */
3973
0
    if (idcDef->selector != NULL) {
3974
0
  if (idcDef->selector->xpathComp != NULL)
3975
0
      xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3976
0
  xmlFree(idcDef->selector);
3977
0
    }
3978
    /* Fields */
3979
0
    if (idcDef->fields != NULL) {
3980
0
  cur = idcDef->fields;
3981
0
  do {
3982
0
      prev = cur;
3983
0
      cur = cur->next;
3984
0
      if (prev->xpathComp != NULL)
3985
0
    xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3986
0
      xmlFree(prev);
3987
0
  } while (cur != NULL);
3988
0
    }
3989
0
    xmlFree(idcDef);
3990
0
}
3991
3992
/**
3993
 * xmlSchemaFreeElement:
3994
 * @schema:  a schema element structure
3995
 *
3996
 * Deallocate a Schema Element structure.
3997
 */
3998
static void
3999
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
4000
0
{
4001
0
    if (elem == NULL)
4002
0
        return;
4003
0
    if (elem->annot != NULL)
4004
0
        xmlSchemaFreeAnnot(elem->annot);
4005
0
    if (elem->contModel != NULL)
4006
0
        xmlRegFreeRegexp(elem->contModel);
4007
0
    if (elem->defVal != NULL)
4008
0
  xmlSchemaFreeValue(elem->defVal);
4009
0
    xmlFree(elem);
4010
0
}
4011
4012
/**
4013
 * xmlSchemaFreeFacet:
4014
 * @facet:  a schema facet structure
4015
 *
4016
 * Deallocate a Schema Facet structure.
4017
 */
4018
void
4019
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4020
0
{
4021
0
    if (facet == NULL)
4022
0
        return;
4023
0
    if (facet->val != NULL)
4024
0
        xmlSchemaFreeValue(facet->val);
4025
0
    if (facet->regexp != NULL)
4026
0
        xmlRegFreeRegexp(facet->regexp);
4027
0
    if (facet->annot != NULL)
4028
0
        xmlSchemaFreeAnnot(facet->annot);
4029
0
    xmlFree(facet);
4030
0
}
4031
4032
/**
4033
 * xmlSchemaFreeType:
4034
 * @type:  a schema type structure
4035
 *
4036
 * Deallocate a Schema Type structure.
4037
 */
4038
void
4039
xmlSchemaFreeType(xmlSchemaTypePtr type)
4040
0
{
4041
0
    if (type == NULL)
4042
0
        return;
4043
0
    if (type->annot != NULL)
4044
0
        xmlSchemaFreeAnnot(type->annot);
4045
0
    if (type->facets != NULL) {
4046
0
        xmlSchemaFacetPtr facet, next;
4047
4048
0
        facet = type->facets;
4049
0
        while (facet != NULL) {
4050
0
            next = facet->next;
4051
0
            xmlSchemaFreeFacet(facet);
4052
0
            facet = next;
4053
0
        }
4054
0
    }
4055
0
    if (type->attrUses != NULL)
4056
0
  xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4057
0
    if (type->memberTypes != NULL)
4058
0
  xmlSchemaFreeTypeLinkList(type->memberTypes);
4059
0
    if (type->facetSet != NULL) {
4060
0
  xmlSchemaFacetLinkPtr next, link;
4061
4062
0
  link = type->facetSet;
4063
0
  do {
4064
0
      next = link->next;
4065
0
      xmlFree(link);
4066
0
      link = next;
4067
0
  } while (link != NULL);
4068
0
    }
4069
0
    if (type->contModel != NULL)
4070
0
        xmlRegFreeRegexp(type->contModel);
4071
0
    xmlFree(type);
4072
0
}
4073
4074
/**
4075
 * xmlSchemaFreeModelGroupDef:
4076
 * @item:  a schema model group definition
4077
 *
4078
 * Deallocates a schema model group definition.
4079
 */
4080
static void
4081
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4082
0
{
4083
0
    if (item->annot != NULL)
4084
0
  xmlSchemaFreeAnnot(item->annot);
4085
0
    xmlFree(item);
4086
0
}
4087
4088
/**
4089
 * xmlSchemaFreeModelGroup:
4090
 * @item:  a schema model group
4091
 *
4092
 * Deallocates a schema model group structure.
4093
 */
4094
static void
4095
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4096
0
{
4097
0
    if (item->annot != NULL)
4098
0
  xmlSchemaFreeAnnot(item->annot);
4099
0
    xmlFree(item);
4100
0
}
4101
4102
static void
4103
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4104
0
{
4105
0
    if ((list == NULL) || (list->nbItems == 0))
4106
0
  return;
4107
0
    {
4108
0
  xmlSchemaTreeItemPtr item;
4109
0
  xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4110
0
  int i;
4111
4112
0
  for (i = 0; i < list->nbItems; i++) {
4113
0
      item = items[i];
4114
0
      if (item == NULL)
4115
0
    continue;
4116
0
      switch (item->type) {
4117
0
    case XML_SCHEMA_TYPE_SIMPLE:
4118
0
    case XML_SCHEMA_TYPE_COMPLEX:
4119
0
        xmlSchemaFreeType((xmlSchemaTypePtr) item);
4120
0
        break;
4121
0
    case XML_SCHEMA_TYPE_ATTRIBUTE:
4122
0
        xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4123
0
        break;
4124
0
    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4125
0
        xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4126
0
        break;
4127
0
    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4128
0
        xmlSchemaFreeAttributeUseProhib(
4129
0
      (xmlSchemaAttributeUseProhibPtr) item);
4130
0
        break;
4131
0
    case XML_SCHEMA_TYPE_ELEMENT:
4132
0
        xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4133
0
        break;
4134
0
    case XML_SCHEMA_TYPE_PARTICLE:
4135
0
        if (item->annot != NULL)
4136
0
      xmlSchemaFreeAnnot(item->annot);
4137
0
        xmlFree(item);
4138
0
        break;
4139
0
    case XML_SCHEMA_TYPE_SEQUENCE:
4140
0
    case XML_SCHEMA_TYPE_CHOICE:
4141
0
    case XML_SCHEMA_TYPE_ALL:
4142
0
        xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4143
0
        break;
4144
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4145
0
        xmlSchemaFreeAttributeGroup(
4146
0
      (xmlSchemaAttributeGroupPtr) item);
4147
0
        break;
4148
0
    case XML_SCHEMA_TYPE_GROUP:
4149
0
        xmlSchemaFreeModelGroupDef(
4150
0
      (xmlSchemaModelGroupDefPtr) item);
4151
0
        break;
4152
0
    case XML_SCHEMA_TYPE_ANY:
4153
0
    case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4154
0
        xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4155
0
        break;
4156
0
    case XML_SCHEMA_TYPE_IDC_KEY:
4157
0
    case XML_SCHEMA_TYPE_IDC_UNIQUE:
4158
0
    case XML_SCHEMA_TYPE_IDC_KEYREF:
4159
0
        xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4160
0
        break;
4161
0
    case XML_SCHEMA_TYPE_NOTATION:
4162
0
        xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4163
0
        break;
4164
0
    case XML_SCHEMA_EXTRA_QNAMEREF:
4165
0
        xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4166
0
        break;
4167
0
    default: {
4168
        /* TODO: This should never be hit. */
4169
0
        xmlSchemaPSimpleInternalErr(NULL,
4170
0
      "Internal error: xmlSchemaComponentListFree, "
4171
0
      "unexpected component type '%s'\n",
4172
0
      (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
4173
0
       }
4174
0
        break;
4175
0
      }
4176
0
  }
4177
0
  list->nbItems = 0;
4178
0
    }
4179
0
}
4180
4181
/**
4182
 * xmlSchemaFree:
4183
 * @schema:  a schema structure
4184
 *
4185
 * Deallocate a Schema structure.
4186
 */
4187
void
4188
xmlSchemaFree(xmlSchemaPtr schema)
4189
0
{
4190
0
    if (schema == NULL)
4191
0
        return;
4192
    /* @volatiles is not used anymore :-/ */
4193
0
    if (schema->volatiles != NULL)
4194
0
  TODO
4195
    /*
4196
    * Note that those slots are not responsible for freeing
4197
    * schema components anymore; this will now be done by
4198
    * the schema buckets.
4199
    */
4200
0
    if (schema->notaDecl != NULL)
4201
0
        xmlHashFree(schema->notaDecl, NULL);
4202
0
    if (schema->attrDecl != NULL)
4203
0
        xmlHashFree(schema->attrDecl, NULL);
4204
0
    if (schema->attrgrpDecl != NULL)
4205
0
        xmlHashFree(schema->attrgrpDecl, NULL);
4206
0
    if (schema->elemDecl != NULL)
4207
0
        xmlHashFree(schema->elemDecl, NULL);
4208
0
    if (schema->typeDecl != NULL)
4209
0
        xmlHashFree(schema->typeDecl, NULL);
4210
0
    if (schema->groupDecl != NULL)
4211
0
        xmlHashFree(schema->groupDecl, NULL);
4212
0
    if (schema->idcDef != NULL)
4213
0
        xmlHashFree(schema->idcDef, NULL);
4214
4215
0
    if (schema->schemasImports != NULL)
4216
0
  xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4217
0
    if (schema->includes != NULL) {
4218
0
  xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4219
0
  int i;
4220
0
  for (i = 0; i < list->nbItems; i++) {
4221
0
      xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4222
0
  }
4223
0
  xmlSchemaItemListFree(list);
4224
0
    }
4225
0
    if (schema->annot != NULL)
4226
0
        xmlSchemaFreeAnnot(schema->annot);
4227
    /* Never free the doc here, since this will be done by the buckets. */
4228
4229
0
    xmlDictFree(schema->dict);
4230
0
    xmlFree(schema);
4231
0
}
4232
4233
/************************************************************************
4234
 *                  *
4235
 *      Debug functions         *
4236
 *                  *
4237
 ************************************************************************/
4238
4239
#ifdef LIBXML_OUTPUT_ENABLED
4240
4241
static void
4242
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4243
4244
/**
4245
 * xmlSchemaElementDump:
4246
 * @elem:  an element
4247
 * @output:  the file output
4248
 *
4249
 * Dump the element
4250
 */
4251
static void
4252
xmlSchemaElementDump(void *payload, void *data,
4253
                     const xmlChar * name ATTRIBUTE_UNUSED,
4254
         const xmlChar * namespace ATTRIBUTE_UNUSED,
4255
                     const xmlChar * context ATTRIBUTE_UNUSED)
4256
0
{
4257
0
    xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4258
0
    FILE *output = (FILE *) data;
4259
0
    if (elem == NULL)
4260
0
        return;
4261
4262
4263
0
    fprintf(output, "Element");
4264
0
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4265
0
  fprintf(output, " (global)");
4266
0
    fprintf(output, ": '%s' ", elem->name);
4267
0
    if (namespace != NULL)
4268
0
  fprintf(output, "ns '%s'", namespace);
4269
0
    fprintf(output, "\n");
4270
#if 0
4271
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4272
  fprintf(output, "  min %d ", elem->minOccurs);
4273
        if (elem->maxOccurs >= UNBOUNDED)
4274
            fprintf(output, "max: unbounded\n");
4275
        else if (elem->maxOccurs != 1)
4276
            fprintf(output, "max: %d\n", elem->maxOccurs);
4277
        else
4278
            fprintf(output, "\n");
4279
    }
4280
#endif
4281
    /*
4282
    * Misc other properties.
4283
    */
4284
0
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4285
0
  (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4286
0
  (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4287
0
  (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4288
0
  fprintf(output, "  props: ");
4289
0
  if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4290
0
      fprintf(output, "[fixed] ");
4291
0
  if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4292
0
      fprintf(output, "[default] ");
4293
0
  if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4294
0
      fprintf(output, "[abstract] ");
4295
0
  if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4296
0
      fprintf(output, "[nillable] ");
4297
0
  fprintf(output, "\n");
4298
0
    }
4299
    /*
4300
    * Default/fixed value.
4301
    */
4302
0
    if (elem->value != NULL)
4303
0
  fprintf(output, "  value: '%s'\n", elem->value);
4304
    /*
4305
    * Type.
4306
    */
4307
0
    if (elem->namedType != NULL) {
4308
0
  fprintf(output, "  type: '%s' ", elem->namedType);
4309
0
  if (elem->namedTypeNs != NULL)
4310
0
      fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4311
0
  else
4312
0
      fprintf(output, "\n");
4313
0
    } else if (elem->subtypes != NULL) {
4314
  /*
4315
  * Dump local types.
4316
  */
4317
0
  xmlSchemaTypeDump(elem->subtypes, output);
4318
0
    }
4319
    /*
4320
    * Substitution group.
4321
    */
4322
0
    if (elem->substGroup != NULL) {
4323
0
  fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4324
0
  if (elem->substGroupNs != NULL)
4325
0
      fprintf(output, "ns '%s'\n", elem->substGroupNs);
4326
0
  else
4327
0
      fprintf(output, "\n");
4328
0
    }
4329
0
}
4330
4331
/**
4332
 * xmlSchemaAnnotDump:
4333
 * @output:  the file output
4334
 * @annot:  a annotation
4335
 *
4336
 * Dump the annotation
4337
 */
4338
static void
4339
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4340
0
{
4341
0
    xmlChar *content;
4342
4343
0
    if (annot == NULL)
4344
0
        return;
4345
4346
0
    content = xmlNodeGetContent(annot->content);
4347
0
    if (content != NULL) {
4348
0
        fprintf(output, "  Annot: %s\n", content);
4349
0
        xmlFree(content);
4350
0
    } else
4351
0
        fprintf(output, "  Annot: empty\n");
4352
0
}
4353
4354
/**
4355
 * xmlSchemaContentModelDump:
4356
 * @particle: the schema particle
4357
 * @output: the file output
4358
 * @depth: the depth used for indentation
4359
 *
4360
 * Dump a SchemaType structure
4361
 */
4362
static void
4363
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4364
0
{
4365
0
    xmlChar *str = NULL;
4366
0
    xmlSchemaTreeItemPtr term;
4367
0
    char shift[100];
4368
0
    int i;
4369
4370
0
    if (particle == NULL)
4371
0
  return;
4372
0
    for (i = 0;((i < depth) && (i < 25));i++)
4373
0
        shift[2 * i] = shift[2 * i + 1] = ' ';
4374
0
    shift[2 * i] = shift[2 * i + 1] = 0;
4375
0
    fprintf(output, "%s", shift);
4376
0
    if (particle->children == NULL) {
4377
0
  fprintf(output, "MISSING particle term\n");
4378
0
  return;
4379
0
    }
4380
0
    term = particle->children;
4381
0
    if (term == NULL) {
4382
0
  fprintf(output, "(NULL)");
4383
0
    } else {
4384
0
  switch (term->type) {
4385
0
      case XML_SCHEMA_TYPE_ELEMENT:
4386
0
    fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4387
0
        ((xmlSchemaElementPtr)term)->targetNamespace,
4388
0
        ((xmlSchemaElementPtr)term)->name));
4389
0
    FREE_AND_NULL(str);
4390
0
    break;
4391
0
      case XML_SCHEMA_TYPE_SEQUENCE:
4392
0
    fprintf(output, "SEQUENCE");
4393
0
    break;
4394
0
      case XML_SCHEMA_TYPE_CHOICE:
4395
0
    fprintf(output, "CHOICE");
4396
0
    break;
4397
0
      case XML_SCHEMA_TYPE_ALL:
4398
0
    fprintf(output, "ALL");
4399
0
    break;
4400
0
      case XML_SCHEMA_TYPE_ANY:
4401
0
    fprintf(output, "ANY");
4402
0
    break;
4403
0
      default:
4404
0
    fprintf(output, "UNKNOWN\n");
4405
0
    return;
4406
0
  }
4407
0
    }
4408
0
    if (particle->minOccurs != 1)
4409
0
  fprintf(output, " min: %d", particle->minOccurs);
4410
0
    if (particle->maxOccurs >= UNBOUNDED)
4411
0
  fprintf(output, " max: unbounded");
4412
0
    else if (particle->maxOccurs != 1)
4413
0
  fprintf(output, " max: %d", particle->maxOccurs);
4414
0
    fprintf(output, "\n");
4415
0
    if (term &&
4416
0
  ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4417
0
   (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4418
0
   (term->type == XML_SCHEMA_TYPE_ALL)) &&
4419
0
   (term->children != NULL)) {
4420
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4421
0
      output, depth +1);
4422
0
    }
4423
0
    if (particle->next != NULL)
4424
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4425
0
    output, depth);
4426
0
}
4427
4428
/**
4429
 * xmlSchemaAttrUsesDump:
4430
 * @uses:  attribute uses list
4431
 * @output:  the file output
4432
 *
4433
 * Dumps a list of attribute use components.
4434
 */
4435
static void
4436
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4437
0
{
4438
0
    xmlSchemaAttributeUsePtr use;
4439
0
    xmlSchemaAttributeUseProhibPtr prohib;
4440
0
    xmlSchemaQNameRefPtr ref;
4441
0
    const xmlChar *name, *tns;
4442
0
    xmlChar *str = NULL;
4443
0
    int i;
4444
4445
0
    if ((uses == NULL) || (uses->nbItems == 0))
4446
0
        return;
4447
4448
0
    fprintf(output, "  attributes:\n");
4449
0
    for (i = 0; i < uses->nbItems; i++) {
4450
0
  use = uses->items[i];
4451
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4452
0
      fprintf(output, "  [prohibition] ");
4453
0
      prohib = (xmlSchemaAttributeUseProhibPtr) use;
4454
0
      name = prohib->name;
4455
0
      tns = prohib->targetNamespace;
4456
0
  } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4457
0
      fprintf(output, "  [reference] ");
4458
0
      ref = (xmlSchemaQNameRefPtr) use;
4459
0
      name = ref->name;
4460
0
      tns = ref->targetNamespace;
4461
0
  } else {
4462
0
      fprintf(output, "  [use] ");
4463
0
      name = WXS_ATTRUSE_DECL_NAME(use);
4464
0
      tns = WXS_ATTRUSE_DECL_TNS(use);
4465
0
  }
4466
0
  fprintf(output, "'%s'\n",
4467
0
      (const char *) xmlSchemaFormatQName(&str, tns, name));
4468
0
  FREE_AND_NULL(str);
4469
0
    }
4470
0
}
4471
4472
/**
4473
 * xmlSchemaTypeDump:
4474
 * @output:  the file output
4475
 * @type:  a type structure
4476
 *
4477
 * Dump a SchemaType structure
4478
 */
4479
static void
4480
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4481
0
{
4482
0
    if (type == NULL) {
4483
0
        fprintf(output, "Type: NULL\n");
4484
0
        return;
4485
0
    }
4486
0
    fprintf(output, "Type: ");
4487
0
    if (type->name != NULL)
4488
0
        fprintf(output, "'%s' ", type->name);
4489
0
    else
4490
0
        fprintf(output, "(no name) ");
4491
0
    if (type->targetNamespace != NULL)
4492
0
  fprintf(output, "ns '%s' ", type->targetNamespace);
4493
0
    switch (type->type) {
4494
0
        case XML_SCHEMA_TYPE_BASIC:
4495
0
            fprintf(output, "[basic] ");
4496
0
            break;
4497
0
        case XML_SCHEMA_TYPE_SIMPLE:
4498
0
            fprintf(output, "[simple] ");
4499
0
            break;
4500
0
        case XML_SCHEMA_TYPE_COMPLEX:
4501
0
            fprintf(output, "[complex] ");
4502
0
            break;
4503
0
        case XML_SCHEMA_TYPE_SEQUENCE:
4504
0
            fprintf(output, "[sequence] ");
4505
0
            break;
4506
0
        case XML_SCHEMA_TYPE_CHOICE:
4507
0
            fprintf(output, "[choice] ");
4508
0
            break;
4509
0
        case XML_SCHEMA_TYPE_ALL:
4510
0
            fprintf(output, "[all] ");
4511
0
            break;
4512
0
        case XML_SCHEMA_TYPE_UR:
4513
0
            fprintf(output, "[ur] ");
4514
0
            break;
4515
0
        case XML_SCHEMA_TYPE_RESTRICTION:
4516
0
            fprintf(output, "[restriction] ");
4517
0
            break;
4518
0
        case XML_SCHEMA_TYPE_EXTENSION:
4519
0
            fprintf(output, "[extension] ");
4520
0
            break;
4521
0
        default:
4522
0
            fprintf(output, "[unknown type %d] ", type->type);
4523
0
            break;
4524
0
    }
4525
0
    fprintf(output, "content: ");
4526
0
    switch (type->contentType) {
4527
0
        case XML_SCHEMA_CONTENT_UNKNOWN:
4528
0
            fprintf(output, "[unknown] ");
4529
0
            break;
4530
0
        case XML_SCHEMA_CONTENT_EMPTY:
4531
0
            fprintf(output, "[empty] ");
4532
0
            break;
4533
0
        case XML_SCHEMA_CONTENT_ELEMENTS:
4534
0
            fprintf(output, "[element] ");
4535
0
            break;
4536
0
        case XML_SCHEMA_CONTENT_MIXED:
4537
0
            fprintf(output, "[mixed] ");
4538
0
            break;
4539
0
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4540
  /* not used. */
4541
0
            break;
4542
0
        case XML_SCHEMA_CONTENT_BASIC:
4543
0
            fprintf(output, "[basic] ");
4544
0
            break;
4545
0
        case XML_SCHEMA_CONTENT_SIMPLE:
4546
0
            fprintf(output, "[simple] ");
4547
0
            break;
4548
0
        case XML_SCHEMA_CONTENT_ANY:
4549
0
            fprintf(output, "[any] ");
4550
0
            break;
4551
0
    }
4552
0
    fprintf(output, "\n");
4553
0
    if (type->base != NULL) {
4554
0
        fprintf(output, "  base type: '%s'", type->base);
4555
0
  if (type->baseNs != NULL)
4556
0
      fprintf(output, " ns '%s'\n", type->baseNs);
4557
0
  else
4558
0
      fprintf(output, "\n");
4559
0
    }
4560
0
    if (type->attrUses != NULL)
4561
0
  xmlSchemaAttrUsesDump(type->attrUses, output);
4562
0
    if (type->annot != NULL)
4563
0
        xmlSchemaAnnotDump(output, type->annot);
4564
0
#ifdef DUMP_CONTENT_MODEL
4565
0
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4566
0
  (type->subtypes != NULL)) {
4567
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4568
0
      output, 1);
4569
0
    }
4570
0
#endif
4571
0
}
4572
4573
static void
4574
xmlSchemaTypeDumpEntry(void *type, void *output,
4575
                       const xmlChar *name ATTRIBUTE_UNUSED)
4576
0
{
4577
0
    xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4578
0
}
4579
4580
/**
4581
 * xmlSchemaDump:
4582
 * @output:  the file output
4583
 * @schema:  a schema structure
4584
 *
4585
 * Dump a Schema structure.
4586
 */
4587
void
4588
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4589
0
{
4590
0
    if (output == NULL)
4591
0
        return;
4592
0
    if (schema == NULL) {
4593
0
        fprintf(output, "Schemas: NULL\n");
4594
0
        return;
4595
0
    }
4596
0
    fprintf(output, "Schemas: ");
4597
0
    if (schema->name != NULL)
4598
0
        fprintf(output, "%s, ", schema->name);
4599
0
    else
4600
0
        fprintf(output, "no name, ");
4601
0
    if (schema->targetNamespace != NULL)
4602
0
        fprintf(output, "%s", (const char *) schema->targetNamespace);
4603
0
    else
4604
0
        fprintf(output, "no target namespace");
4605
0
    fprintf(output, "\n");
4606
0
    if (schema->annot != NULL)
4607
0
        xmlSchemaAnnotDump(output, schema->annot);
4608
0
    xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4609
0
    xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4610
0
}
4611
4612
#ifdef DEBUG_IDC_NODE_TABLE
4613
/**
4614
 * xmlSchemaDebugDumpIDCTable:
4615
 * @vctxt: the WXS validation context
4616
 *
4617
 * Displays the current IDC table for debug purposes.
4618
 */
4619
static void
4620
xmlSchemaDebugDumpIDCTable(FILE * output,
4621
         const xmlChar *namespaceName,
4622
         const xmlChar *localName,
4623
         xmlSchemaPSVIIDCBindingPtr bind)
4624
{
4625
    xmlChar *str = NULL;
4626
    const xmlChar *value;
4627
    xmlSchemaPSVIIDCNodePtr tab;
4628
    xmlSchemaPSVIIDCKeyPtr key;
4629
    int i, j, res;
4630
4631
    fprintf(output, "IDC: TABLES on '%s'\n",
4632
  xmlSchemaFormatQName(&str, namespaceName, localName));
4633
    FREE_AND_NULL(str)
4634
4635
    if (bind == NULL)
4636
  return;
4637
    do {
4638
  fprintf(output, "IDC:   BINDING '%s' (%d)\n",
4639
      xmlSchemaGetComponentQName(&str,
4640
    bind->definition), bind->nbNodes);
4641
  FREE_AND_NULL(str)
4642
  for (i = 0; i < bind->nbNodes; i++) {
4643
      tab = bind->nodeTable[i];
4644
      fprintf(output, "         ( ");
4645
      for (j = 0; j < bind->definition->nbFields; j++) {
4646
    key = tab->keys[j];
4647
    if ((key != NULL) && (key->val != NULL)) {
4648
        res = xmlSchemaGetCanonValue(key->val, &value);
4649
        if (res >= 0)
4650
      fprintf(output, "'%s' ", value);
4651
        else
4652
      fprintf(output, "CANON-VALUE-FAILED ");
4653
        if (res == 0)
4654
      FREE_AND_NULL(value)
4655
    } else if (key != NULL)
4656
        fprintf(output, "(no val), ");
4657
    else
4658
        fprintf(output, "(key missing), ");
4659
      }
4660
      fprintf(output, ")\n");
4661
  }
4662
  if (bind->dupls && bind->dupls->nbItems) {
4663
      fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
4664
      for (i = 0; i < bind->dupls->nbItems; i++) {
4665
    tab = bind->dupls->items[i];
4666
    fprintf(output, "         ( ");
4667
    for (j = 0; j < bind->definition->nbFields; j++) {
4668
        key = tab->keys[j];
4669
        if ((key != NULL) && (key->val != NULL)) {
4670
      res = xmlSchemaGetCanonValue(key->val, &value);
4671
      if (res >= 0)
4672
          fprintf(output, "'%s' ", value);
4673
      else
4674
          fprintf(output, "CANON-VALUE-FAILED ");
4675
      if (res == 0)
4676
          FREE_AND_NULL(value)
4677
        } else if (key != NULL)
4678
        fprintf(output, "(no val), ");
4679
      else
4680
          fprintf(output, "(key missing), ");
4681
    }
4682
    fprintf(output, ")\n");
4683
      }
4684
  }
4685
  bind = bind->next;
4686
    } while (bind != NULL);
4687
}
4688
#endif /* DEBUG_IDC */
4689
#endif /* LIBXML_OUTPUT_ENABLED */
4690
4691
/************************************************************************
4692
 *                  *
4693
 *      Utilities         *
4694
 *                  *
4695
 ************************************************************************/
4696
4697
/**
4698
 * xmlSchemaGetPropNode:
4699
 * @node: the element node
4700
 * @name: the name of the attribute
4701
 *
4702
 * Seeks an attribute with a name of @name in
4703
 * no namespace.
4704
 *
4705
 * Returns the attribute or NULL if not present.
4706
 */
4707
static xmlAttrPtr
4708
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4709
0
{
4710
0
    xmlAttrPtr prop;
4711
4712
0
    if ((node == NULL) || (name == NULL))
4713
0
  return(NULL);
4714
0
    prop = node->properties;
4715
0
    while (prop != NULL) {
4716
0
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4717
0
      return(prop);
4718
0
  prop = prop->next;
4719
0
    }
4720
0
    return (NULL);
4721
0
}
4722
4723
/**
4724
 * xmlSchemaGetPropNodeNs:
4725
 * @node: the element node
4726
 * @uri: the uri
4727
 * @name: the name of the attribute
4728
 *
4729
 * Seeks an attribute with a local name of @name and
4730
 * a namespace URI of @uri.
4731
 *
4732
 * Returns the attribute or NULL if not present.
4733
 */
4734
static xmlAttrPtr
4735
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4736
0
{
4737
0
    xmlAttrPtr prop;
4738
4739
0
    if ((node == NULL) || (name == NULL))
4740
0
  return(NULL);
4741
0
    prop = node->properties;
4742
0
    while (prop != NULL) {
4743
0
  if ((prop->ns != NULL) &&
4744
0
      xmlStrEqual(prop->name, BAD_CAST name) &&
4745
0
      xmlStrEqual(prop->ns->href, BAD_CAST uri))
4746
0
      return(prop);
4747
0
  prop = prop->next;
4748
0
    }
4749
0
    return (NULL);
4750
0
}
4751
4752
static const xmlChar *
4753
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4754
0
{
4755
0
    xmlChar *val;
4756
0
    const xmlChar *ret;
4757
4758
0
    val = xmlNodeGetContent(node);
4759
0
    if (val == NULL)
4760
0
  val = xmlStrdup((xmlChar *)"");
4761
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4762
0
    xmlFree(val);
4763
0
    return(ret);
4764
0
}
4765
4766
static const xmlChar *
4767
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4768
0
{
4769
0
    return((const xmlChar*) xmlNodeGetContent(node));
4770
0
}
4771
4772
/**
4773
 * xmlSchemaGetProp:
4774
 * @ctxt: the parser context
4775
 * @node: the node
4776
 * @name: the property name
4777
 *
4778
 * Read a attribute value and internalize the string
4779
 *
4780
 * Returns the string or NULL if not present.
4781
 */
4782
static const xmlChar *
4783
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4784
                 const char *name)
4785
0
{
4786
0
    xmlChar *val;
4787
0
    const xmlChar *ret;
4788
4789
0
    val = xmlGetNoNsProp(node, BAD_CAST name);
4790
0
    if (val == NULL)
4791
0
        return(NULL);
4792
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4793
0
    xmlFree(val);
4794
0
    return(ret);
4795
0
}
4796
4797
/************************************************************************
4798
 *                  *
4799
 *      Parsing functions       *
4800
 *                  *
4801
 ************************************************************************/
4802
4803
#define WXS_FIND_GLOBAL_ITEM(slot)      \
4804
0
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4805
0
  ret = xmlHashLookup(schema->slot, name); \
4806
0
  if (ret != NULL) goto exit; \
4807
0
    } \
4808
0
    if (xmlHashSize(schema->schemasImports) > 1) { \
4809
0
  xmlSchemaImportPtr import; \
4810
0
  if (nsName == NULL) \
4811
0
      import = xmlHashLookup(schema->schemasImports, \
4812
0
    XML_SCHEMAS_NO_NAMESPACE); \
4813
0
  else \
4814
0
      import = xmlHashLookup(schema->schemasImports, nsName); \
4815
0
  if (import == NULL) \
4816
0
      goto exit; \
4817
0
  ret = xmlHashLookup(import->schema->slot, name); \
4818
0
    }
4819
4820
/**
4821
 * xmlSchemaGetElem:
4822
 * @schema:  the schema context
4823
 * @name:  the element name
4824
 * @ns:  the element namespace
4825
 *
4826
 * Lookup a global element declaration in the schema.
4827
 *
4828
 * Returns the element declaration or NULL if not found.
4829
 */
4830
static xmlSchemaElementPtr
4831
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4832
                 const xmlChar * nsName)
4833
0
{
4834
0
    xmlSchemaElementPtr ret = NULL;
4835
4836
0
    if ((name == NULL) || (schema == NULL))
4837
0
        return(NULL);
4838
0
    if (schema != NULL) {
4839
0
  WXS_FIND_GLOBAL_ITEM(elemDecl)
4840
0
    }
4841
0
exit:
4842
#ifdef DEBUG
4843
    if (ret == NULL) {
4844
        if (nsName == NULL)
4845
            fprintf(stderr, "Unable to lookup element decl. %s", name);
4846
        else
4847
            fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
4848
                    nsName);
4849
    }
4850
#endif
4851
0
    return (ret);
4852
0
}
4853
4854
/**
4855
 * xmlSchemaGetType:
4856
 * @schema:  the main schema
4857
 * @name:  the type's name
4858
 * nsName:  the type's namespace
4859
 *
4860
 * Lookup a type in the schemas or the predefined types
4861
 *
4862
 * Returns the group definition or NULL if not found.
4863
 */
4864
static xmlSchemaTypePtr
4865
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4866
                 const xmlChar * nsName)
4867
0
{
4868
0
    xmlSchemaTypePtr ret = NULL;
4869
4870
0
    if (name == NULL)
4871
0
        return (NULL);
4872
    /* First try the built-in types. */
4873
0
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4874
0
  ret = xmlSchemaGetPredefinedType(name, nsName);
4875
0
  if (ret != NULL)
4876
0
      goto exit;
4877
  /*
4878
  * Note that we try the parsed schemas as well here
4879
  * since one might have parsed the S4S, which contain more
4880
  * than the built-in types.
4881
  * TODO: Can we optimize this?
4882
  */
4883
0
    }
4884
0
    if (schema != NULL) {
4885
0
  WXS_FIND_GLOBAL_ITEM(typeDecl)
4886
0
    }
4887
0
exit:
4888
4889
#ifdef DEBUG
4890
    if (ret == NULL) {
4891
        if (nsName == NULL)
4892
            fprintf(stderr, "Unable to lookup type %s", name);
4893
        else
4894
            fprintf(stderr, "Unable to lookup type %s:%s", name,
4895
                    nsName);
4896
    }
4897
#endif
4898
0
    return (ret);
4899
0
}
4900
4901
/**
4902
 * xmlSchemaGetAttributeDecl:
4903
 * @schema:  the context of the schema
4904
 * @name:  the name of the attribute
4905
 * @ns:  the target namespace of the attribute
4906
 *
4907
 * Lookup a an attribute in the schema or imported schemas
4908
 *
4909
 * Returns the attribute declaration or NULL if not found.
4910
 */
4911
static xmlSchemaAttributePtr
4912
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4913
                 const xmlChar * nsName)
4914
0
{
4915
0
    xmlSchemaAttributePtr ret = NULL;
4916
4917
0
    if ((name == NULL) || (schema == NULL))
4918
0
        return (NULL);
4919
0
    if (schema != NULL) {
4920
0
  WXS_FIND_GLOBAL_ITEM(attrDecl)
4921
0
    }
4922
0
exit:
4923
#ifdef DEBUG
4924
    if (ret == NULL) {
4925
        if (nsName == NULL)
4926
            fprintf(stderr, "Unable to lookup attribute %s", name);
4927
        else
4928
            fprintf(stderr, "Unable to lookup attribute %s:%s", name,
4929
                    nsName);
4930
    }
4931
#endif
4932
0
    return (ret);
4933
0
}
4934
4935
/**
4936
 * xmlSchemaGetAttributeGroup:
4937
 * @schema:  the context of the schema
4938
 * @name:  the name of the attribute group
4939
 * @ns:  the target namespace of the attribute group
4940
 *
4941
 * Lookup a an attribute group in the schema or imported schemas
4942
 *
4943
 * Returns the attribute group definition or NULL if not found.
4944
 */
4945
static xmlSchemaAttributeGroupPtr
4946
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4947
                 const xmlChar * nsName)
4948
0
{
4949
0
    xmlSchemaAttributeGroupPtr ret = NULL;
4950
4951
0
    if ((name == NULL) || (schema == NULL))
4952
0
        return (NULL);
4953
0
    if (schema != NULL) {
4954
0
  WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4955
0
    }
4956
0
exit:
4957
    /* TODO:
4958
    if ((ret != NULL) && (ret->redef != NULL)) {
4959
  * Return the last redefinition. *
4960
  ret = ret->redef;
4961
    }
4962
    */
4963
#ifdef DEBUG
4964
    if (ret == NULL) {
4965
        if (nsName == NULL)
4966
            fprintf(stderr, "Unable to lookup attribute group %s", name);
4967
        else
4968
            fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
4969
                    nsName);
4970
    }
4971
#endif
4972
0
    return (ret);
4973
0
}
4974
4975
/**
4976
 * xmlSchemaGetGroup:
4977
 * @schema:  the context of the schema
4978
 * @name:  the name of the group
4979
 * @ns:  the target namespace of the group
4980
 *
4981
 * Lookup a group in the schema or imported schemas
4982
 *
4983
 * Returns the group definition or NULL if not found.
4984
 */
4985
static xmlSchemaModelGroupDefPtr
4986
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4987
                 const xmlChar * nsName)
4988
0
{
4989
0
    xmlSchemaModelGroupDefPtr ret = NULL;
4990
4991
0
    if ((name == NULL) || (schema == NULL))
4992
0
        return (NULL);
4993
0
    if (schema != NULL) {
4994
0
  WXS_FIND_GLOBAL_ITEM(groupDecl)
4995
0
    }
4996
0
exit:
4997
4998
#ifdef DEBUG
4999
    if (ret == NULL) {
5000
        if (nsName == NULL)
5001
            fprintf(stderr, "Unable to lookup group %s", name);
5002
        else
5003
            fprintf(stderr, "Unable to lookup group %s:%s", name,
5004
                    nsName);
5005
    }
5006
#endif
5007
0
    return (ret);
5008
0
}
5009
5010
static xmlSchemaNotationPtr
5011
xmlSchemaGetNotation(xmlSchemaPtr schema,
5012
         const xmlChar *name,
5013
         const xmlChar *nsName)
5014
0
{
5015
0
    xmlSchemaNotationPtr ret = NULL;
5016
5017
0
    if ((name == NULL) || (schema == NULL))
5018
0
        return (NULL);
5019
0
    if (schema != NULL) {
5020
0
  WXS_FIND_GLOBAL_ITEM(notaDecl)
5021
0
    }
5022
0
exit:
5023
0
    return (ret);
5024
0
}
5025
5026
static xmlSchemaIDCPtr
5027
xmlSchemaGetIDC(xmlSchemaPtr schema,
5028
    const xmlChar *name,
5029
    const xmlChar *nsName)
5030
0
{
5031
0
    xmlSchemaIDCPtr ret = NULL;
5032
5033
0
    if ((name == NULL) || (schema == NULL))
5034
0
        return (NULL);
5035
0
    if (schema != NULL) {
5036
0
  WXS_FIND_GLOBAL_ITEM(idcDef)
5037
0
    }
5038
0
exit:
5039
0
    return (ret);
5040
0
}
5041
5042
/**
5043
 * xmlSchemaGetNamedComponent:
5044
 * @schema:  the schema
5045
 * @name:  the name of the group
5046
 * @ns:  the target namespace of the group
5047
 *
5048
 * Lookup a group in the schema or imported schemas
5049
 *
5050
 * Returns the group definition or NULL if not found.
5051
 */
5052
static xmlSchemaBasicItemPtr
5053
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
5054
         xmlSchemaTypeType itemType,
5055
         const xmlChar *name,
5056
         const xmlChar *targetNs)
5057
0
{
5058
0
    switch (itemType) {
5059
0
  case XML_SCHEMA_TYPE_GROUP:
5060
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
5061
0
    name, targetNs));
5062
0
  case XML_SCHEMA_TYPE_ELEMENT:
5063
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
5064
0
    name, targetNs));
5065
0
  default:
5066
0
      TODO
5067
0
      return (NULL);
5068
0
    }
5069
0
}
5070
5071
/************************************************************************
5072
 *                  *
5073
 *      Parsing functions       *
5074
 *                  *
5075
 ************************************************************************/
5076
5077
#define IS_BLANK_NODE(n)            \
5078
0
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
5079
5080
/**
5081
 * xmlSchemaIsBlank:
5082
 * @str:  a string
5083
 * @len: the length of the string or -1
5084
 *
5085
 * Check if a string is ignorable
5086
 *
5087
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
5088
 */
5089
static int
5090
xmlSchemaIsBlank(xmlChar * str, int len)
5091
0
{
5092
0
    if (str == NULL)
5093
0
        return (1);
5094
0
    if (len < 0) {
5095
0
  while (*str != 0) {
5096
0
      if (!(IS_BLANK_CH(*str)))
5097
0
    return (0);
5098
0
      str++;
5099
0
  }
5100
0
    } else while ((*str != 0) && (len != 0)) {
5101
0
  if (!(IS_BLANK_CH(*str)))
5102
0
      return (0);
5103
0
  str++;
5104
0
  len--;
5105
0
    }
5106
5107
0
    return (1);
5108
0
}
5109
5110
0
#define WXS_COMP_NAME(c, t) ((t) (c))->name
5111
0
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5112
/*
5113
* xmlSchemaFindRedefCompInGraph:
5114
* ATTENTION TODO: This uses pointer comp. for strings.
5115
*/
5116
static xmlSchemaBasicItemPtr
5117
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5118
            xmlSchemaTypeType type,
5119
            const xmlChar *name,
5120
            const xmlChar *nsName)
5121
0
{
5122
0
    xmlSchemaBasicItemPtr ret;
5123
0
    int i;
5124
5125
0
    if ((bucket == NULL) || (name == NULL))
5126
0
  return(NULL);
5127
0
    if ((bucket->globals == NULL) ||
5128
0
  (bucket->globals->nbItems == 0))
5129
0
  goto subschemas;
5130
    /*
5131
    * Search in global components.
5132
    */
5133
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
5134
0
  ret = bucket->globals->items[i];
5135
0
  if (ret->type == type) {
5136
0
      switch (type) {
5137
0
    case XML_SCHEMA_TYPE_COMPLEX:
5138
0
    case XML_SCHEMA_TYPE_SIMPLE:
5139
0
        if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5140
0
      (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5141
0
      nsName))
5142
0
        {
5143
0
      return(ret);
5144
0
        }
5145
0
        break;
5146
0
    case XML_SCHEMA_TYPE_GROUP:
5147
0
        if ((WXS_COMP_NAME(ret,
5148
0
          xmlSchemaModelGroupDefPtr) == name) &&
5149
0
      (WXS_COMP_TNS(ret,
5150
0
          xmlSchemaModelGroupDefPtr) == nsName))
5151
0
        {
5152
0
      return(ret);
5153
0
        }
5154
0
        break;
5155
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5156
0
        if ((WXS_COMP_NAME(ret,
5157
0
          xmlSchemaAttributeGroupPtr) == name) &&
5158
0
      (WXS_COMP_TNS(ret,
5159
0
          xmlSchemaAttributeGroupPtr) == nsName))
5160
0
        {
5161
0
      return(ret);
5162
0
        }
5163
0
        break;
5164
0
    default:
5165
        /* Should not be hit. */
5166
0
        return(NULL);
5167
0
      }
5168
0
  }
5169
0
    }
5170
0
subschemas:
5171
    /*
5172
    * Process imported/included schemas.
5173
    */
5174
0
    if (bucket->relations != NULL) {
5175
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
5176
5177
  /*
5178
  * TODO: Marking the bucket will not avoid multiple searches
5179
  * in the same schema, but avoids at least circularity.
5180
  */
5181
0
  bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5182
0
  do {
5183
0
      if ((rel->bucket != NULL) &&
5184
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5185
0
    ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5186
0
        type, name, nsName);
5187
0
    if (ret != NULL)
5188
0
        return(ret);
5189
0
      }
5190
0
      rel = rel->next;
5191
0
  } while (rel != NULL);
5192
0
   bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5193
0
    }
5194
0
    return(NULL);
5195
0
}
5196
5197
/**
5198
 * xmlSchemaAddNotation:
5199
 * @ctxt:  a schema parser context
5200
 * @schema:  the schema being built
5201
 * @name:  the item name
5202
 *
5203
 * Add an XML schema annotation declaration
5204
 * *WARNING* this interface is highly subject to change
5205
 *
5206
 * Returns the new structure or NULL in case of error
5207
 */
5208
static xmlSchemaNotationPtr
5209
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5210
                     const xmlChar *name, const xmlChar *nsName,
5211
         xmlNodePtr node ATTRIBUTE_UNUSED)
5212
0
{
5213
0
    xmlSchemaNotationPtr ret = NULL;
5214
5215
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5216
0
        return (NULL);
5217
5218
0
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5219
0
    if (ret == NULL) {
5220
0
        xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
5221
0
        return (NULL);
5222
0
    }
5223
0
    memset(ret, 0, sizeof(xmlSchemaNotation));
5224
0
    ret->type = XML_SCHEMA_TYPE_NOTATION;
5225
0
    ret->name = name;
5226
0
    ret->targetNamespace = nsName;
5227
    /* TODO: do we need the node to be set?
5228
    * ret->node = node;*/
5229
0
    WXS_ADD_GLOBAL(ctxt, ret);
5230
0
    return (ret);
5231
0
}
5232
5233
/**
5234
 * xmlSchemaAddAttribute:
5235
 * @ctxt:  a schema parser context
5236
 * @schema:  the schema being built
5237
 * @name:  the item name
5238
 * @namespace:  the namespace
5239
 *
5240
 * Add an XML schema Attribute declaration
5241
 * *WARNING* this interface is highly subject to change
5242
 *
5243
 * Returns the new structure or NULL in case of error
5244
 */
5245
static xmlSchemaAttributePtr
5246
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5247
                      const xmlChar * name, const xmlChar * nsName,
5248
          xmlNodePtr node, int topLevel)
5249
0
{
5250
0
    xmlSchemaAttributePtr ret = NULL;
5251
5252
0
    if ((ctxt == NULL) || (schema == NULL))
5253
0
        return (NULL);
5254
5255
0
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5256
0
    if (ret == NULL) {
5257
0
        xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
5258
0
        return (NULL);
5259
0
    }
5260
0
    memset(ret, 0, sizeof(xmlSchemaAttribute));
5261
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5262
0
    ret->node = node;
5263
0
    ret->name = name;
5264
0
    ret->targetNamespace = nsName;
5265
5266
0
    if (topLevel)
5267
0
  WXS_ADD_GLOBAL(ctxt, ret);
5268
0
    else
5269
0
  WXS_ADD_LOCAL(ctxt, ret);
5270
0
    WXS_ADD_PENDING(ctxt, ret);
5271
0
    return (ret);
5272
0
}
5273
5274
/**
5275
 * xmlSchemaAddAttributeUse:
5276
 * @ctxt:  a schema parser context
5277
 * @schema:  the schema being built
5278
 * @name:  the item name
5279
 * @namespace:  the namespace
5280
 *
5281
 * Add an XML schema Attribute declaration
5282
 * *WARNING* this interface is highly subject to change
5283
 *
5284
 * Returns the new structure or NULL in case of error
5285
 */
5286
static xmlSchemaAttributeUsePtr
5287
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5288
       xmlNodePtr node)
5289
0
{
5290
0
    xmlSchemaAttributeUsePtr ret = NULL;
5291
5292
0
    if (pctxt == NULL)
5293
0
        return (NULL);
5294
5295
0
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5296
0
    if (ret == NULL) {
5297
0
        xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
5298
0
        return (NULL);
5299
0
    }
5300
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5301
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5302
0
    ret->node = node;
5303
5304
0
    WXS_ADD_LOCAL(pctxt, ret);
5305
0
    return (ret);
5306
0
}
5307
5308
/*
5309
* xmlSchemaAddRedef:
5310
*
5311
* Adds a redefinition information. This is used at a later stage to:
5312
* resolve references to the redefined components and to check constraints.
5313
*/
5314
static xmlSchemaRedefPtr
5315
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5316
      xmlSchemaBucketPtr targetBucket,
5317
      void *item,
5318
      const xmlChar *refName,
5319
      const xmlChar *refTargetNs)
5320
0
{
5321
0
    xmlSchemaRedefPtr ret;
5322
5323
0
    ret = (xmlSchemaRedefPtr)
5324
0
  xmlMalloc(sizeof(xmlSchemaRedef));
5325
0
    if (ret == NULL) {
5326
0
  xmlSchemaPErrMemory(pctxt,
5327
0
      "allocating redefinition info", NULL);
5328
0
  return (NULL);
5329
0
    }
5330
0
    memset(ret, 0, sizeof(xmlSchemaRedef));
5331
0
    ret->item = item;
5332
0
    ret->targetBucket = targetBucket;
5333
0
    ret->refName = refName;
5334
0
    ret->refTargetNs = refTargetNs;
5335
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5336
0
  WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5337
0
    else
5338
0
  WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5339
0
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5340
5341
0
    return (ret);
5342
0
}
5343
5344
/**
5345
 * xmlSchemaAddAttributeGroupDefinition:
5346
 * @ctxt:  a schema parser context
5347
 * @schema:  the schema being built
5348
 * @name:  the item name
5349
 * @nsName:  the target namespace
5350
 * @node: the corresponding node
5351
 *
5352
 * Add an XML schema Attribute Group definition.
5353
 *
5354
 * Returns the new structure or NULL in case of error
5355
 */
5356
static xmlSchemaAttributeGroupPtr
5357
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5358
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5359
         const xmlChar *name,
5360
         const xmlChar *nsName,
5361
         xmlNodePtr node)
5362
0
{
5363
0
    xmlSchemaAttributeGroupPtr ret = NULL;
5364
5365
0
    if ((pctxt == NULL) || (name == NULL))
5366
0
        return (NULL);
5367
5368
0
    ret = (xmlSchemaAttributeGroupPtr)
5369
0
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5370
0
    if (ret == NULL) {
5371
0
  xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
5372
0
  return (NULL);
5373
0
    }
5374
0
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5375
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5376
0
    ret->name = name;
5377
0
    ret->targetNamespace = nsName;
5378
0
    ret->node = node;
5379
5380
    /* TODO: Remove the flag. */
5381
0
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5382
0
    if (pctxt->isRedefine) {
5383
0
  pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5384
0
      ret, name, nsName);
5385
0
  if (pctxt->redef == NULL) {
5386
0
      xmlFree(ret);
5387
0
      return(NULL);
5388
0
  }
5389
0
  pctxt->redefCounter = 0;
5390
0
    }
5391
0
    WXS_ADD_GLOBAL(pctxt, ret);
5392
0
    WXS_ADD_PENDING(pctxt, ret);
5393
0
    return (ret);
5394
0
}
5395
5396
/**
5397
 * xmlSchemaAddElement:
5398
 * @ctxt:  a schema parser context
5399
 * @schema:  the schema being built
5400
 * @name:  the type name
5401
 * @namespace:  the type namespace
5402
 *
5403
 * Add an XML schema Element declaration
5404
 * *WARNING* this interface is highly subject to change
5405
 *
5406
 * Returns the new structure or NULL in case of error
5407
 */
5408
static xmlSchemaElementPtr
5409
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5410
                    const xmlChar * name, const xmlChar * nsName,
5411
        xmlNodePtr node, int topLevel)
5412
0
{
5413
0
    xmlSchemaElementPtr ret = NULL;
5414
5415
0
    if ((ctxt == NULL) || (name == NULL))
5416
0
        return (NULL);
5417
5418
0
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5419
0
    if (ret == NULL) {
5420
0
        xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
5421
0
        return (NULL);
5422
0
    }
5423
0
    memset(ret, 0, sizeof(xmlSchemaElement));
5424
0
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5425
0
    ret->name = name;
5426
0
    ret->targetNamespace = nsName;
5427
0
    ret->node = node;
5428
5429
0
    if (topLevel)
5430
0
  WXS_ADD_GLOBAL(ctxt, ret);
5431
0
    else
5432
0
  WXS_ADD_LOCAL(ctxt, ret);
5433
0
    WXS_ADD_PENDING(ctxt, ret);
5434
0
    return (ret);
5435
0
}
5436
5437
/**
5438
 * xmlSchemaAddType:
5439
 * @ctxt:  a schema parser context
5440
 * @schema:  the schema being built
5441
 * @name:  the item name
5442
 * @namespace:  the namespace
5443
 *
5444
 * Add an XML schema item
5445
 * *WARNING* this interface is highly subject to change
5446
 *
5447
 * Returns the new structure or NULL in case of error
5448
 */
5449
static xmlSchemaTypePtr
5450
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5451
     xmlSchemaTypeType type,
5452
                 const xmlChar * name, const xmlChar * nsName,
5453
     xmlNodePtr node, int topLevel)
5454
0
{
5455
0
    xmlSchemaTypePtr ret = NULL;
5456
5457
0
    if ((ctxt == NULL) || (schema == NULL))
5458
0
        return (NULL);
5459
5460
0
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5461
0
    if (ret == NULL) {
5462
0
        xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
5463
0
        return (NULL);
5464
0
    }
5465
0
    memset(ret, 0, sizeof(xmlSchemaType));
5466
0
    ret->type = type;
5467
0
    ret->name = name;
5468
0
    ret->targetNamespace = nsName;
5469
0
    ret->node = node;
5470
0
    if (topLevel) {
5471
0
  if (ctxt->isRedefine) {
5472
0
      ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5473
0
    ret, name, nsName);
5474
0
      if (ctxt->redef == NULL) {
5475
0
    xmlFree(ret);
5476
0
    return(NULL);
5477
0
      }
5478
0
      ctxt->redefCounter = 0;
5479
0
  }
5480
0
  WXS_ADD_GLOBAL(ctxt, ret);
5481
0
    } else
5482
0
  WXS_ADD_LOCAL(ctxt, ret);
5483
0
    WXS_ADD_PENDING(ctxt, ret);
5484
0
    return (ret);
5485
0
}
5486
5487
static xmlSchemaQNameRefPtr
5488
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5489
         xmlSchemaTypeType refType,
5490
         const xmlChar *refName,
5491
         const xmlChar *refNs)
5492
0
{
5493
0
    xmlSchemaQNameRefPtr ret;
5494
5495
0
    ret = (xmlSchemaQNameRefPtr)
5496
0
  xmlMalloc(sizeof(xmlSchemaQNameRef));
5497
0
    if (ret == NULL) {
5498
0
  xmlSchemaPErrMemory(pctxt,
5499
0
      "allocating QName reference item", NULL);
5500
0
  return (NULL);
5501
0
    }
5502
0
    ret->node = NULL;
5503
0
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5504
0
    ret->name = refName;
5505
0
    ret->targetNamespace = refNs;
5506
0
    ret->item = NULL;
5507
0
    ret->itemType = refType;
5508
    /*
5509
    * Store the reference item in the schema.
5510
    */
5511
0
    WXS_ADD_LOCAL(pctxt, ret);
5512
0
    return (ret);
5513
0
}
5514
5515
static xmlSchemaAttributeUseProhibPtr
5516
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5517
0
{
5518
0
    xmlSchemaAttributeUseProhibPtr ret;
5519
5520
0
    ret = (xmlSchemaAttributeUseProhibPtr)
5521
0
  xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5522
0
    if (ret == NULL) {
5523
0
  xmlSchemaPErrMemory(pctxt,
5524
0
      "allocating attribute use prohibition", NULL);
5525
0
  return (NULL);
5526
0
    }
5527
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5528
0
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5529
0
    WXS_ADD_LOCAL(pctxt, ret);
5530
0
    return (ret);
5531
0
}
5532
5533
5534
/**
5535
 * xmlSchemaAddModelGroup:
5536
 * @ctxt:  a schema parser context
5537
 * @schema:  the schema being built
5538
 * @type: the "compositor" type of the model group
5539
 * @node: the node in the schema doc
5540
 *
5541
 * Adds a schema model group
5542
 * *WARNING* this interface is highly subject to change
5543
 *
5544
 * Returns the new structure or NULL in case of error
5545
 */
5546
static xmlSchemaModelGroupPtr
5547
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5548
           xmlSchemaPtr schema,
5549
           xmlSchemaTypeType type,
5550
           xmlNodePtr node)
5551
0
{
5552
0
    xmlSchemaModelGroupPtr ret = NULL;
5553
5554
0
    if ((ctxt == NULL) || (schema == NULL))
5555
0
        return (NULL);
5556
5557
0
    ret = (xmlSchemaModelGroupPtr)
5558
0
  xmlMalloc(sizeof(xmlSchemaModelGroup));
5559
0
    if (ret == NULL) {
5560
0
  xmlSchemaPErrMemory(ctxt, "allocating model group component",
5561
0
      NULL);
5562
0
  return (NULL);
5563
0
    }
5564
0
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5565
0
    ret->type = type;
5566
0
    ret->node = node;
5567
0
    WXS_ADD_LOCAL(ctxt, ret);
5568
0
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5569
0
  (type == XML_SCHEMA_TYPE_CHOICE))
5570
0
  WXS_ADD_PENDING(ctxt, ret);
5571
0
    return (ret);
5572
0
}
5573
5574
5575
/**
5576
 * xmlSchemaAddParticle:
5577
 * @ctxt:  a schema parser context
5578
 * @schema:  the schema being built
5579
 * @node: the corresponding node in the schema doc
5580
 * @min: the minOccurs
5581
 * @max: the maxOccurs
5582
 *
5583
 * Adds an XML schema particle component.
5584
 * *WARNING* this interface is highly subject to change
5585
 *
5586
 * Returns the new structure or NULL in case of error
5587
 */
5588
static xmlSchemaParticlePtr
5589
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5590
         xmlNodePtr node, int min, int max)
5591
0
{
5592
0
    xmlSchemaParticlePtr ret = NULL;
5593
0
    if (ctxt == NULL)
5594
0
        return (NULL);
5595
5596
#ifdef DEBUG
5597
    fprintf(stderr, "Adding particle component\n");
5598
#endif
5599
0
    ret = (xmlSchemaParticlePtr)
5600
0
  xmlMalloc(sizeof(xmlSchemaParticle));
5601
0
    if (ret == NULL) {
5602
0
  xmlSchemaPErrMemory(ctxt, "allocating particle component",
5603
0
      NULL);
5604
0
  return (NULL);
5605
0
    }
5606
0
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5607
0
    ret->annot = NULL;
5608
0
    ret->node = node;
5609
0
    ret->minOccurs = min;
5610
0
    ret->maxOccurs = max;
5611
0
    ret->next = NULL;
5612
0
    ret->children = NULL;
5613
5614
0
    WXS_ADD_LOCAL(ctxt, ret);
5615
    /*
5616
    * Note that addition to pending components will be done locally
5617
    * to the specific parsing function, since the most particles
5618
    * need not to be fixed up (i.e. the reference to be resolved).
5619
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5620
    */
5621
0
    return (ret);
5622
0
}
5623
5624
/**
5625
 * xmlSchemaAddModelGroupDefinition:
5626
 * @ctxt:  a schema validation context
5627
 * @schema:  the schema being built
5628
 * @name:  the group name
5629
 *
5630
 * Add an XML schema Group definition
5631
 *
5632
 * Returns the new structure or NULL in case of error
5633
 */
5634
static xmlSchemaModelGroupDefPtr
5635
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5636
         xmlSchemaPtr schema,
5637
         const xmlChar *name,
5638
         const xmlChar *nsName,
5639
         xmlNodePtr node)
5640
0
{
5641
0
    xmlSchemaModelGroupDefPtr ret = NULL;
5642
5643
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5644
0
        return (NULL);
5645
5646
0
    ret = (xmlSchemaModelGroupDefPtr)
5647
0
  xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5648
0
    if (ret == NULL) {
5649
0
        xmlSchemaPErrMemory(ctxt, "adding group", NULL);
5650
0
        return (NULL);
5651
0
    }
5652
0
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5653
0
    ret->name = name;
5654
0
    ret->type = XML_SCHEMA_TYPE_GROUP;
5655
0
    ret->node = node;
5656
0
    ret->targetNamespace = nsName;
5657
5658
0
    if (ctxt->isRedefine) {
5659
0
  ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5660
0
      ret, name, nsName);
5661
0
  if (ctxt->redef == NULL) {
5662
0
      xmlFree(ret);
5663
0
      return(NULL);
5664
0
  }
5665
0
  ctxt->redefCounter = 0;
5666
0
    }
5667
0
    WXS_ADD_GLOBAL(ctxt, ret);
5668
0
    WXS_ADD_PENDING(ctxt, ret);
5669
0
    return (ret);
5670
0
}
5671
5672
/**
5673
 * xmlSchemaNewWildcardNs:
5674
 * @ctxt:  a schema validation context
5675
 *
5676
 * Creates a new wildcard namespace constraint.
5677
 *
5678
 * Returns the new structure or NULL in case of error
5679
 */
5680
static xmlSchemaWildcardNsPtr
5681
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5682
0
{
5683
0
    xmlSchemaWildcardNsPtr ret;
5684
5685
0
    ret = (xmlSchemaWildcardNsPtr)
5686
0
  xmlMalloc(sizeof(xmlSchemaWildcardNs));
5687
0
    if (ret == NULL) {
5688
0
  xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
5689
0
  return (NULL);
5690
0
    }
5691
0
    ret->value = NULL;
5692
0
    ret->next = NULL;
5693
0
    return (ret);
5694
0
}
5695
5696
static xmlSchemaIDCPtr
5697
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5698
                  const xmlChar *name, const xmlChar *nsName,
5699
      int category, xmlNodePtr node)
5700
0
{
5701
0
    xmlSchemaIDCPtr ret = NULL;
5702
5703
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5704
0
        return (NULL);
5705
5706
0
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5707
0
    if (ret == NULL) {
5708
0
        xmlSchemaPErrMemory(ctxt,
5709
0
      "allocating an identity-constraint definition", NULL);
5710
0
        return (NULL);
5711
0
    }
5712
0
    memset(ret, 0, sizeof(xmlSchemaIDC));
5713
    /* The target namespace of the parent element declaration. */
5714
0
    ret->targetNamespace = nsName;
5715
0
    ret->name = name;
5716
0
    ret->type = category;
5717
0
    ret->node = node;
5718
5719
0
    WXS_ADD_GLOBAL(ctxt, ret);
5720
    /*
5721
    * Only keyrefs need to be fixup up.
5722
    */
5723
0
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5724
0
  WXS_ADD_PENDING(ctxt, ret);
5725
0
    return (ret);
5726
0
}
5727
5728
/**
5729
 * xmlSchemaAddWildcard:
5730
 * @ctxt:  a schema validation context
5731
 * @schema: a schema
5732
 *
5733
 * Adds a wildcard.
5734
 * It corresponds to a xsd:anyAttribute and xsd:any.
5735
 *
5736
 * Returns the new structure or NULL in case of error
5737
 */
5738
static xmlSchemaWildcardPtr
5739
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5740
         xmlSchemaTypeType type, xmlNodePtr node)
5741
0
{
5742
0
    xmlSchemaWildcardPtr ret = NULL;
5743
5744
0
    if ((ctxt == NULL) || (schema == NULL))
5745
0
        return (NULL);
5746
5747
0
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5748
0
    if (ret == NULL) {
5749
0
        xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
5750
0
        return (NULL);
5751
0
    }
5752
0
    memset(ret, 0, sizeof(xmlSchemaWildcard));
5753
0
    ret->type = type;
5754
0
    ret->node = node;
5755
0
    WXS_ADD_LOCAL(ctxt, ret);
5756
0
    return (ret);
5757
0
}
5758
5759
static void
5760
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5761
0
{
5762
0
    if (group == NULL)
5763
0
  return;
5764
0
    if (group->members != NULL)
5765
0
  xmlSchemaItemListFree(group->members);
5766
0
    xmlFree(group);
5767
0
}
5768
5769
static void
5770
xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5771
0
{
5772
0
    xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5773
0
}
5774
5775
static xmlSchemaSubstGroupPtr
5776
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5777
           xmlSchemaElementPtr head)
5778
0
{
5779
0
    xmlSchemaSubstGroupPtr ret;
5780
5781
    /* Init subst group hash. */
5782
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5783
0
  WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5784
0
  if (WXS_SUBST_GROUPS(pctxt) == NULL)
5785
0
      return(NULL);
5786
0
    }
5787
    /* Create a new substitution group. */
5788
0
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5789
0
    if (ret == NULL) {
5790
0
  xmlSchemaPErrMemory(NULL,
5791
0
      "allocating a substitution group container", NULL);
5792
0
  return(NULL);
5793
0
    }
5794
0
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5795
0
    ret->head = head;
5796
    /* Create list of members. */
5797
0
    ret->members = xmlSchemaItemListCreate();
5798
0
    if (ret->members == NULL) {
5799
0
  xmlSchemaSubstGroupFree(ret);
5800
0
  return(NULL);
5801
0
    }
5802
    /* Add subst group to hash. */
5803
0
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5804
0
  head->name, head->targetNamespace, ret) != 0) {
5805
0
  PERROR_INT("xmlSchemaSubstGroupAdd",
5806
0
      "failed to add a new substitution container");
5807
0
  xmlSchemaSubstGroupFree(ret);
5808
0
  return(NULL);
5809
0
    }
5810
0
    return(ret);
5811
0
}
5812
5813
static xmlSchemaSubstGroupPtr
5814
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5815
           xmlSchemaElementPtr head)
5816
0
{
5817
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5818
0
  return(NULL);
5819
0
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5820
0
  head->name, head->targetNamespace));
5821
5822
0
}
5823
5824
/**
5825
 * xmlSchemaAddElementSubstitutionMember:
5826
 * @pctxt:  a schema parser context
5827
 * @head:  the head of the substitution group
5828
 * @member: the new member of the substitution group
5829
 *
5830
 * Allocate a new annotation structure.
5831
 *
5832
 * Returns the newly allocated structure or NULL in case or error
5833
 */
5834
static int
5835
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5836
              xmlSchemaElementPtr head,
5837
              xmlSchemaElementPtr member)
5838
0
{
5839
0
    xmlSchemaSubstGroupPtr substGroup = NULL;
5840
5841
0
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5842
0
  return (-1);
5843
5844
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5845
0
    if (substGroup == NULL)
5846
0
  substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5847
0
    if (substGroup == NULL)
5848
0
  return(-1);
5849
0
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5850
0
  return(-1);
5851
0
    return(0);
5852
0
}
5853
5854
/************************************************************************
5855
 *                  *
5856
 *    Utilities for parsing         *
5857
 *                  *
5858
 ************************************************************************/
5859
5860
/**
5861
 * xmlSchemaPValAttrNodeQNameValue:
5862
 * @ctxt:  a schema parser context
5863
 * @schema: the schema context
5864
 * @ownerItem: the parent as a schema object
5865
 * @value:  the QName value
5866
 * @uri:  the resulting namespace URI if found
5867
 * @local: the resulting local part if found, the attribute value otherwise
5868
 *
5869
 * Extracts the local name and the URI of a QName value and validates it.
5870
 * This one is intended to be used on attribute values that
5871
 * should resolve to schema components.
5872
 *
5873
 * Returns 0, in case the QName is valid, a positive error code
5874
 * if not valid and -1 if an internal error occurs.
5875
 */
5876
static int
5877
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5878
               xmlSchemaPtr schema,
5879
               xmlSchemaBasicItemPtr ownerItem,
5880
               xmlAttrPtr attr,
5881
               const xmlChar *value,
5882
               const xmlChar **uri,
5883
               const xmlChar **local)
5884
0
{
5885
0
    const xmlChar *pref;
5886
0
    xmlNsPtr ns;
5887
0
    int len, ret;
5888
5889
0
    *uri = NULL;
5890
0
    *local = NULL;
5891
0
    ret = xmlValidateQName(value, 1);
5892
0
    if (ret > 0) {
5893
0
  xmlSchemaPSimpleTypeErr(ctxt,
5894
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5895
0
      ownerItem, (xmlNodePtr) attr,
5896
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5897
0
      NULL, value, NULL, NULL, NULL);
5898
0
  *local = value;
5899
0
  return (ctxt->err);
5900
0
    } else if (ret < 0)
5901
0
  return (-1);
5902
5903
0
    if (!strchr((char *) value, ':')) {
5904
0
  ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5905
0
  if (ns && ns->href && ns->href[0])
5906
0
      *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5907
0
  else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5908
      /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5909
      * parser context. */
5910
      /*
5911
      * This one takes care of included schemas with no
5912
      * target namespace.
5913
      */
5914
0
      *uri = ctxt->targetNamespace;
5915
0
  }
5916
0
  *local = xmlDictLookup(ctxt->dict, value, -1);
5917
0
  return (0);
5918
0
    }
5919
    /*
5920
    * At this point xmlSplitQName3 has to return a local name.
5921
    */
5922
0
    *local = xmlSplitQName3(value, &len);
5923
0
    *local = xmlDictLookup(ctxt->dict, *local, -1);
5924
0
    pref = xmlDictLookup(ctxt->dict, value, len);
5925
0
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5926
0
    if (ns == NULL) {
5927
0
  xmlSchemaPSimpleTypeErr(ctxt,
5928
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5929
0
      ownerItem, (xmlNodePtr) attr,
5930
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5931
0
      "The value '%s' of simple type 'xs:QName' has no "
5932
0
      "corresponding namespace declaration in scope", value, NULL);
5933
0
  return (ctxt->err);
5934
0
    } else {
5935
0
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5936
0
    }
5937
0
    return (0);
5938
0
}
5939
5940
/**
5941
 * xmlSchemaPValAttrNodeQName:
5942
 * @ctxt:  a schema parser context
5943
 * @schema: the schema context
5944
 * @ownerItem: the owner as a schema object
5945
 * @attr:  the attribute node
5946
 * @uri:  the resulting namespace URI if found
5947
 * @local: the resulting local part if found, the attribute value otherwise
5948
 *
5949
 * Extracts and validates the QName of an attribute value.
5950
 * This one is intended to be used on attribute values that
5951
 * should resolve to schema components.
5952
 *
5953
 * Returns 0, in case the QName is valid, a positive error code
5954
 * if not valid and -1 if an internal error occurs.
5955
 */
5956
static int
5957
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5958
               xmlSchemaPtr schema,
5959
               xmlSchemaBasicItemPtr ownerItem,
5960
               xmlAttrPtr attr,
5961
               const xmlChar **uri,
5962
               const xmlChar **local)
5963
0
{
5964
0
    const xmlChar *value;
5965
5966
0
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5967
0
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5968
0
  ownerItem, attr, value, uri, local));
5969
0
}
5970
5971
/**
5972
 * xmlSchemaPValAttrQName:
5973
 * @ctxt:  a schema parser context
5974
 * @schema: the schema context
5975
 * @ownerItem: the owner as a schema object
5976
 * @ownerElem:  the parent node of the attribute
5977
 * @name:  the name of the attribute
5978
 * @uri:  the resulting namespace URI if found
5979
 * @local: the resulting local part if found, the attribute value otherwise
5980
 *
5981
 * Extracts and validates the QName of an attribute value.
5982
 *
5983
 * Returns 0, in case the QName is valid, a positive error code
5984
 * if not valid and -1 if an internal error occurs.
5985
 */
5986
static int
5987
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5988
           xmlSchemaPtr schema,
5989
           xmlSchemaBasicItemPtr ownerItem,
5990
           xmlNodePtr ownerElem,
5991
           const char *name,
5992
           const xmlChar **uri,
5993
           const xmlChar **local)
5994
0
{
5995
0
    xmlAttrPtr attr;
5996
5997
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
5998
0
    if (attr == NULL) {
5999
0
  *local = NULL;
6000
0
  *uri = NULL;
6001
0
  return (0);
6002
0
    }
6003
0
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
6004
0
  ownerItem, attr, uri, local));
6005
0
}
6006
6007
/**
6008
 * xmlSchemaPValAttrID:
6009
 * @ctxt:  a schema parser context
6010
 *
6011
 * Extracts and validates the ID of an attribute value.
6012
 *
6013
 * Returns 0, in case the ID is valid, a positive error code
6014
 * if not valid and -1 if an internal error occurs.
6015
 */
6016
static int
6017
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
6018
0
{
6019
0
    int ret;
6020
0
    const xmlChar *value;
6021
6022
0
    if (attr == NULL)
6023
0
  return(0);
6024
0
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
6025
0
    ret = xmlValidateNCName(value, 1);
6026
0
    if (ret == 0) {
6027
  /*
6028
  * NOTE: the IDness might have already be declared in the DTD
6029
  */
6030
0
  if (attr->atype != XML_ATTRIBUTE_ID) {
6031
0
      xmlIDPtr res;
6032
0
      xmlChar *strip;
6033
6034
      /*
6035
      * TODO: Use xmlSchemaStrip here; it's not exported at this
6036
      * moment.
6037
      */
6038
0
      strip = xmlSchemaCollapseString(value);
6039
0
      if (strip != NULL) {
6040
0
    xmlFree((xmlChar *) value);
6041
0
    value = strip;
6042
0
      }
6043
0
      res = xmlAddID(NULL, attr->doc, value, attr);
6044
0
      if (res == NULL) {
6045
0
    ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6046
0
    xmlSchemaPSimpleTypeErr(ctxt,
6047
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6048
0
        NULL, (xmlNodePtr) attr,
6049
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
6050
0
        NULL, NULL, "Duplicate value '%s' of simple "
6051
0
        "type 'xs:ID'", value, NULL);
6052
0
      } else
6053
0
    attr->atype = XML_ATTRIBUTE_ID;
6054
0
  }
6055
0
    } else if (ret > 0) {
6056
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6057
0
  xmlSchemaPSimpleTypeErr(ctxt,
6058
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6059
0
      NULL, (xmlNodePtr) attr,
6060
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
6061
0
      NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
6062
0
      "not a valid 'xs:NCName'",
6063
0
      value, NULL);
6064
0
    }
6065
0
    if (value != NULL)
6066
0
  xmlFree((xmlChar *)value);
6067
6068
0
    return (ret);
6069
0
}
6070
6071
static int
6072
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
6073
        xmlNodePtr ownerElem,
6074
        const xmlChar *name)
6075
0
{
6076
0
    xmlAttrPtr attr;
6077
6078
0
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
6079
0
    if (attr == NULL)
6080
0
  return(0);
6081
0
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
6082
6083
0
}
6084
6085
/**
6086
 * xmlGetMaxOccurs:
6087
 * @ctxt:  a schema validation context
6088
 * @node:  a subtree containing XML Schema information
6089
 *
6090
 * Get the maxOccurs property
6091
 *
6092
 * Returns the default if not found, or the value
6093
 */
6094
static int
6095
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6096
    int min, int max, int def, const char *expected)
6097
0
{
6098
0
    const xmlChar *val, *cur;
6099
0
    int ret = 0;
6100
0
    xmlAttrPtr attr;
6101
6102
0
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
6103
0
    if (attr == NULL)
6104
0
  return (def);
6105
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6106
6107
0
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
6108
0
  if (max != UNBOUNDED) {
6109
0
      xmlSchemaPSimpleTypeErr(ctxt,
6110
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6111
    /* XML_SCHEMAP_INVALID_MINOCCURS, */
6112
0
    NULL, (xmlNodePtr) attr, NULL, expected,
6113
0
    val, NULL, NULL, NULL);
6114
0
      return (def);
6115
0
  } else
6116
0
      return (UNBOUNDED);  /* encoding it with -1 might be another option */
6117
0
    }
6118
6119
0
    cur = val;
6120
0
    while (IS_BLANK_CH(*cur))
6121
0
        cur++;
6122
0
    if (*cur == 0) {
6123
0
        xmlSchemaPSimpleTypeErr(ctxt,
6124
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6125
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6126
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6127
0
      val, NULL, NULL, NULL);
6128
0
  return (def);
6129
0
    }
6130
0
    while ((*cur >= '0') && (*cur <= '9')) {
6131
0
        if (ret > INT_MAX / 10) {
6132
0
            ret = INT_MAX;
6133
0
        } else {
6134
0
            int digit = *cur - '0';
6135
0
            ret *= 10;
6136
0
            if (ret > INT_MAX - digit)
6137
0
                ret = INT_MAX;
6138
0
            else
6139
0
                ret += digit;
6140
0
        }
6141
0
        cur++;
6142
0
    }
6143
0
    while (IS_BLANK_CH(*cur))
6144
0
        cur++;
6145
    /*
6146
    * TODO: Restrict the maximal value to Integer.
6147
    */
6148
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6149
0
  xmlSchemaPSimpleTypeErr(ctxt,
6150
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6151
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6152
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6153
0
      val, NULL, NULL, NULL);
6154
0
        return (def);
6155
0
    }
6156
0
    return (ret);
6157
0
}
6158
6159
/**
6160
 * xmlGetMinOccurs:
6161
 * @ctxt:  a schema validation context
6162
 * @node:  a subtree containing XML Schema information
6163
 *
6164
 * Get the minOccurs property
6165
 *
6166
 * Returns the default if not found, or the value
6167
 */
6168
static int
6169
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6170
    int min, int max, int def, const char *expected)
6171
0
{
6172
0
    const xmlChar *val, *cur;
6173
0
    int ret = 0;
6174
0
    xmlAttrPtr attr;
6175
6176
0
    attr = xmlSchemaGetPropNode(node, "minOccurs");
6177
0
    if (attr == NULL)
6178
0
  return (def);
6179
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6180
0
    cur = val;
6181
0
    while (IS_BLANK_CH(*cur))
6182
0
        cur++;
6183
0
    if (*cur == 0) {
6184
0
        xmlSchemaPSimpleTypeErr(ctxt,
6185
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6186
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6187
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6188
0
      val, NULL, NULL, NULL);
6189
0
        return (def);
6190
0
    }
6191
0
    while ((*cur >= '0') && (*cur <= '9')) {
6192
0
        if (ret > INT_MAX / 10) {
6193
0
            ret = INT_MAX;
6194
0
        } else {
6195
0
            int digit = *cur - '0';
6196
0
            ret *= 10;
6197
0
            if (ret > INT_MAX - digit)
6198
0
                ret = INT_MAX;
6199
0
            else
6200
0
                ret += digit;
6201
0
        }
6202
0
        cur++;
6203
0
    }
6204
0
    while (IS_BLANK_CH(*cur))
6205
0
        cur++;
6206
    /*
6207
    * TODO: Restrict the maximal value to Integer.
6208
    */
6209
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6210
0
  xmlSchemaPSimpleTypeErr(ctxt,
6211
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6212
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6213
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6214
0
      val, NULL, NULL, NULL);
6215
0
        return (def);
6216
0
    }
6217
0
    return (ret);
6218
0
}
6219
6220
/**
6221
 * xmlSchemaPGetBoolNodeValue:
6222
 * @ctxt:  a schema validation context
6223
 * @ownerItem:  the owner as a schema item
6224
 * @node: the node holding the value
6225
 *
6226
 * Converts a boolean string value into 1 or 0.
6227
 *
6228
 * Returns 0 or 1.
6229
 */
6230
static int
6231
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6232
         xmlSchemaBasicItemPtr ownerItem,
6233
         xmlNodePtr node)
6234
0
{
6235
0
    xmlChar *value = NULL;
6236
0
    int res = 0;
6237
6238
0
    value = xmlNodeGetContent(node);
6239
    /*
6240
    * 3.2.2.1 Lexical representation
6241
    * An instance of a datatype that is defined as `boolean`
6242
    * can have the following legal literals {true, false, 1, 0}.
6243
    */
6244
0
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6245
0
        res = 1;
6246
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6247
0
        res = 0;
6248
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6249
0
  res = 1;
6250
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6251
0
        res = 0;
6252
0
    else {
6253
0
        xmlSchemaPSimpleTypeErr(ctxt,
6254
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6255
0
      ownerItem, node,
6256
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6257
0
      NULL, BAD_CAST value,
6258
0
      NULL, NULL, NULL);
6259
0
    }
6260
0
    if (value != NULL)
6261
0
  xmlFree(value);
6262
0
    return (res);
6263
0
}
6264
6265
/**
6266
 * xmlGetBooleanProp:
6267
 * @ctxt:  a schema validation context
6268
 * @node:  a subtree containing XML Schema information
6269
 * @name:  the attribute name
6270
 * @def:  the default value
6271
 *
6272
 * Evaluate if a boolean property is set
6273
 *
6274
 * Returns the default if not found, 0 if found to be false,
6275
 * 1 if found to be true
6276
 */
6277
static int
6278
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6279
      xmlNodePtr node,
6280
                  const char *name, int def)
6281
0
{
6282
0
    const xmlChar *val;
6283
6284
0
    val = xmlSchemaGetProp(ctxt, node, name);
6285
0
    if (val == NULL)
6286
0
        return (def);
6287
    /*
6288
    * 3.2.2.1 Lexical representation
6289
    * An instance of a datatype that is defined as `boolean`
6290
    * can have the following legal literals {true, false, 1, 0}.
6291
    */
6292
0
    if (xmlStrEqual(val, BAD_CAST "true"))
6293
0
        def = 1;
6294
0
    else if (xmlStrEqual(val, BAD_CAST "false"))
6295
0
        def = 0;
6296
0
    else if (xmlStrEqual(val, BAD_CAST "1"))
6297
0
  def = 1;
6298
0
    else if (xmlStrEqual(val, BAD_CAST "0"))
6299
0
        def = 0;
6300
0
    else {
6301
0
        xmlSchemaPSimpleTypeErr(ctxt,
6302
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6303
0
      NULL,
6304
0
      (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6305
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6306
0
      NULL, val, NULL, NULL, NULL);
6307
0
    }
6308
0
    return (def);
6309
0
}
6310
6311
/************************************************************************
6312
 *                  *
6313
 *    Schema extraction from an Infoset     *
6314
 *                  *
6315
 ************************************************************************/
6316
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6317
                                                 ctxt, xmlSchemaPtr schema,
6318
                                                 xmlNodePtr node,
6319
             int topLevel);
6320
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6321
                                                  ctxt,
6322
                                                  xmlSchemaPtr schema,
6323
                                                  xmlNodePtr node,
6324
              int topLevel);
6325
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6326
                                                  ctxt,
6327
                                                  xmlSchemaPtr schema,
6328
                                                  xmlNodePtr node,
6329
              xmlSchemaTypeType parentType);
6330
static xmlSchemaBasicItemPtr
6331
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6332
           xmlSchemaPtr schema,
6333
           xmlNodePtr node,
6334
           xmlSchemaItemListPtr uses,
6335
           int parentType);
6336
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6337
                                           xmlSchemaPtr schema,
6338
                                           xmlNodePtr node);
6339
static xmlSchemaWildcardPtr
6340
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6341
                           xmlSchemaPtr schema, xmlNodePtr node);
6342
6343
/**
6344
 * xmlSchemaPValAttrNodeValue:
6345
 *
6346
 * @pctxt:  a schema parser context
6347
 * @ownerItem: the schema object owner if existent
6348
 * @attr:  the schema attribute node being validated
6349
 * @value: the value
6350
 * @type: the built-in type to be validated against
6351
 *
6352
 * Validates a value against the given built-in type.
6353
 * This one is intended to be used internally for validation
6354
 * of schema attribute values during parsing of the schema.
6355
 *
6356
 * Returns 0 if the value is valid, a positive error code
6357
 * number otherwise and -1 in case of an internal or API error.
6358
 */
6359
static int
6360
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6361
         xmlSchemaBasicItemPtr ownerItem,
6362
         xmlAttrPtr attr,
6363
         const xmlChar *value,
6364
         xmlSchemaTypePtr type)
6365
0
{
6366
6367
0
    int ret = 0;
6368
6369
    /*
6370
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6371
    * one is really meant to be used internally, so better not.
6372
    */
6373
0
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6374
0
  return (-1);
6375
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6376
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6377
0
      "the given type is not a built-in type");
6378
0
  return (-1);
6379
0
    }
6380
0
    switch (type->builtInType) {
6381
0
  case XML_SCHEMAS_NCNAME:
6382
0
  case XML_SCHEMAS_QNAME:
6383
0
  case XML_SCHEMAS_ANYURI:
6384
0
  case XML_SCHEMAS_TOKEN:
6385
0
  case XML_SCHEMAS_LANGUAGE:
6386
0
      ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6387
0
    (xmlNodePtr) attr);
6388
0
      break;
6389
0
  default: {
6390
0
      PERROR_INT("xmlSchemaPValAttrNodeValue",
6391
0
    "validation using the given type is not supported while "
6392
0
    "parsing a schema");
6393
0
      return (-1);
6394
0
  }
6395
0
    }
6396
    /*
6397
    * TODO: Should we use the S4S error codes instead?
6398
    */
6399
0
    if (ret < 0) {
6400
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6401
0
      "failed to validate a schema attribute value");
6402
0
  return (-1);
6403
0
    } else if (ret > 0) {
6404
0
  if (WXS_IS_LIST(type))
6405
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6406
0
  else
6407
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6408
0
  xmlSchemaPSimpleTypeErr(pctxt,
6409
0
      ret, ownerItem, (xmlNodePtr) attr,
6410
0
      type, NULL, value, NULL, NULL, NULL);
6411
0
    }
6412
0
    return (ret);
6413
0
}
6414
6415
/**
6416
 * xmlSchemaPValAttrNode:
6417
 *
6418
 * @ctxt:  a schema parser context
6419
 * @ownerItem: the schema object owner if existent
6420
 * @attr:  the schema attribute node being validated
6421
 * @type: the built-in type to be validated against
6422
 * @value: the resulting value if any
6423
 *
6424
 * Extracts and validates a value against the given built-in type.
6425
 * This one is intended to be used internally for validation
6426
 * of schema attribute values during parsing of the schema.
6427
 *
6428
 * Returns 0 if the value is valid, a positive error code
6429
 * number otherwise and -1 in case of an internal or API error.
6430
 */
6431
static int
6432
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6433
         xmlSchemaBasicItemPtr ownerItem,
6434
         xmlAttrPtr attr,
6435
         xmlSchemaTypePtr type,
6436
         const xmlChar **value)
6437
0
{
6438
0
    const xmlChar *val;
6439
6440
0
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6441
0
  return (-1);
6442
6443
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6444
0
    if (value != NULL)
6445
0
  *value = val;
6446
6447
0
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6448
0
  val, type));
6449
0
}
6450
6451
/**
6452
 * xmlSchemaPValAttr:
6453
 *
6454
 * @ctxt:  a schema parser context
6455
 * @node: the element node of the attribute
6456
 * @ownerItem: the schema object owner if existent
6457
 * @ownerElem: the owner element node
6458
 * @name:  the name of the schema attribute node
6459
 * @type: the built-in type to be validated against
6460
 * @value: the resulting value if any
6461
 *
6462
 * Extracts and validates a value against the given built-in type.
6463
 * This one is intended to be used internally for validation
6464
 * of schema attribute values during parsing of the schema.
6465
 *
6466
 * Returns 0 if the value is valid, a positive error code
6467
 * number otherwise and -1 in case of an internal or API error.
6468
 */
6469
static int
6470
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6471
           xmlSchemaBasicItemPtr ownerItem,
6472
           xmlNodePtr ownerElem,
6473
           const char *name,
6474
           xmlSchemaTypePtr type,
6475
           const xmlChar **value)
6476
0
{
6477
0
    xmlAttrPtr attr;
6478
6479
0
    if ((ctxt == NULL) || (type == NULL)) {
6480
0
  if (value != NULL)
6481
0
      *value = NULL;
6482
0
  return (-1);
6483
0
    }
6484
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6485
0
  if (value != NULL)
6486
0
      *value = NULL;
6487
0
  xmlSchemaPErr(ctxt, ownerElem,
6488
0
      XML_SCHEMAP_INTERNAL,
6489
0
      "Internal error: xmlSchemaPValAttr, the given "
6490
0
      "type '%s' is not a built-in type.\n",
6491
0
      type->name, NULL);
6492
0
  return (-1);
6493
0
    }
6494
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
6495
0
    if (attr == NULL) {
6496
0
  if (value != NULL)
6497
0
      *value = NULL;
6498
0
  return (0);
6499
0
    }
6500
0
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6501
0
  type, value));
6502
0
}
6503
6504
static int
6505
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6506
      xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6507
      xmlNodePtr node,
6508
      xmlAttrPtr attr,
6509
      const xmlChar *namespaceName)
6510
0
{
6511
    /* TODO: Pointer comparison instead? */
6512
0
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6513
0
  return (0);
6514
0
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
6515
0
  return (0);
6516
    /*
6517
    * Check if the referenced namespace was <import>ed.
6518
    */
6519
0
    if (WXS_BUCKET(pctxt)->relations != NULL) {
6520
0
  xmlSchemaSchemaRelationPtr rel;
6521
6522
0
  rel = WXS_BUCKET(pctxt)->relations;
6523
0
  do {
6524
0
      if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6525
0
    xmlStrEqual(namespaceName, rel->importNamespace))
6526
0
    return (0);
6527
0
      rel = rel->next;
6528
0
  } while (rel != NULL);
6529
0
    }
6530
    /*
6531
    * No matching <import>ed namespace found.
6532
    */
6533
0
    {
6534
0
  xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6535
6536
0
  if (namespaceName == NULL)
6537
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6538
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6539
0
    "References from this schema to components in no "
6540
0
    "namespace are not allowed, since not indicated by an "
6541
0
    "import statement", NULL, NULL);
6542
0
  else
6543
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6544
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6545
0
    "References from this schema to components in the "
6546
0
    "namespace '%s' are not allowed, since not indicated by an "
6547
0
    "import statement", namespaceName, NULL);
6548
0
    }
6549
0
    return (XML_SCHEMAP_SRC_RESOLVE);
6550
0
}
6551
6552
/**
6553
 * xmlSchemaParseLocalAttributes:
6554
 * @ctxt:  a schema validation context
6555
 * @schema:  the schema being built
6556
 * @node:  a subtree containing XML Schema information
6557
 * @type:  the hosting type where the attributes will be anchored
6558
 *
6559
 * Parses attribute uses and attribute declarations and
6560
 * attribute group references.
6561
 */
6562
static int
6563
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6564
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
6565
      int parentType, int *hasRefs)
6566
0
{
6567
0
    void *item;
6568
6569
0
    while ((IS_SCHEMA((*child), "attribute")) ||
6570
0
           (IS_SCHEMA((*child), "attributeGroup"))) {
6571
0
        if (IS_SCHEMA((*child), "attribute")) {
6572
0
      item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6573
0
    *list, parentType);
6574
0
        } else {
6575
0
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6576
0
      if ((item != NULL) && (hasRefs != NULL))
6577
0
    *hasRefs = 1;
6578
0
        }
6579
0
  if (item != NULL) {
6580
0
      if (*list == NULL) {
6581
    /* TODO: Customize grow factor. */
6582
0
    *list = xmlSchemaItemListCreate();
6583
0
    if (*list == NULL)
6584
0
        return(-1);
6585
0
      }
6586
0
      if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6587
0
    return(-1);
6588
0
  }
6589
0
        *child = (*child)->next;
6590
0
    }
6591
0
    return (0);
6592
0
}
6593
6594
/**
6595
 * xmlSchemaParseAnnotation:
6596
 * @ctxt:  a schema validation context
6597
 * @schema:  the schema being built
6598
 * @node:  a subtree containing XML Schema information
6599
 *
6600
 * parse a XML schema Attribute declaration
6601
 * *WARNING* this interface is highly subject to change
6602
 *
6603
 * Returns -1 in case of error, 0 if the declaration is improper and
6604
 *         1 in case of success.
6605
 */
6606
static xmlSchemaAnnotPtr
6607
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6608
0
{
6609
0
    xmlSchemaAnnotPtr ret;
6610
0
    xmlNodePtr child = NULL;
6611
0
    xmlAttrPtr attr;
6612
0
    int barked = 0;
6613
6614
    /*
6615
    * INFO: S4S completed.
6616
    */
6617
    /*
6618
    * id = ID
6619
    * {any attributes with non-schema namespace . . .}>
6620
    * Content: (appinfo | documentation)*
6621
    */
6622
0
    if ((ctxt == NULL) || (node == NULL))
6623
0
        return (NULL);
6624
0
    if (needed)
6625
0
  ret = xmlSchemaNewAnnot(ctxt, node);
6626
0
    else
6627
0
  ret = NULL;
6628
0
    attr = node->properties;
6629
0
    while (attr != NULL) {
6630
0
  if (((attr->ns == NULL) &&
6631
0
      (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6632
0
      ((attr->ns != NULL) &&
6633
0
      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6634
6635
0
      xmlSchemaPIllegalAttrErr(ctxt,
6636
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6637
0
  }
6638
0
  attr = attr->next;
6639
0
    }
6640
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6641
    /*
6642
    * And now for the children...
6643
    */
6644
0
    child = node->children;
6645
0
    while (child != NULL) {
6646
0
  if (IS_SCHEMA(child, "appinfo")) {
6647
      /* TODO: make available the content of "appinfo". */
6648
      /*
6649
      * source = anyURI
6650
      * {any attributes with non-schema namespace . . .}>
6651
      * Content: ({any})*
6652
      */
6653
0
      attr = child->properties;
6654
0
      while (attr != NULL) {
6655
0
    if (((attr->ns == NULL) &&
6656
0
         (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6657
0
         ((attr->ns != NULL) &&
6658
0
          xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6659
6660
0
        xmlSchemaPIllegalAttrErr(ctxt,
6661
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6662
0
    }
6663
0
    attr = attr->next;
6664
0
      }
6665
0
      xmlSchemaPValAttr(ctxt, NULL, child, "source",
6666
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6667
0
      child = child->next;
6668
0
  } else if (IS_SCHEMA(child, "documentation")) {
6669
      /* TODO: make available the content of "documentation". */
6670
      /*
6671
      * source = anyURI
6672
      * {any attributes with non-schema namespace . . .}>
6673
      * Content: ({any})*
6674
      */
6675
0
      attr = child->properties;
6676
0
      while (attr != NULL) {
6677
0
    if (attr->ns == NULL) {
6678
0
        if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6679
0
      xmlSchemaPIllegalAttrErr(ctxt,
6680
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6681
0
        }
6682
0
    } else {
6683
0
        if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6684
0
      (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6685
0
      (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6686
6687
0
      xmlSchemaPIllegalAttrErr(ctxt,
6688
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6689
0
        }
6690
0
    }
6691
0
    attr = attr->next;
6692
0
      }
6693
      /*
6694
      * Attribute "xml:lang".
6695
      */
6696
0
      attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6697
0
      if (attr != NULL)
6698
0
    xmlSchemaPValAttrNode(ctxt, NULL, attr,
6699
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6700
0
      child = child->next;
6701
0
  } else {
6702
0
      if (!barked)
6703
0
    xmlSchemaPContentErr(ctxt,
6704
0
        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6705
0
        NULL, node, child, NULL, "(appinfo | documentation)*");
6706
0
      barked = 1;
6707
0
      child = child->next;
6708
0
  }
6709
0
    }
6710
6711
0
    return (ret);
6712
0
}
6713
6714
/**
6715
 * xmlSchemaParseFacet:
6716
 * @ctxt:  a schema validation context
6717
 * @schema:  the schema being built
6718
 * @node:  a subtree containing XML Schema information
6719
 *
6720
 * parse a XML schema Facet declaration
6721
 * *WARNING* this interface is highly subject to change
6722
 *
6723
 * Returns the new type structure or NULL in case of error
6724
 */
6725
static xmlSchemaFacetPtr
6726
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6727
                    xmlNodePtr node)
6728
0
{
6729
0
    xmlSchemaFacetPtr facet;
6730
0
    xmlNodePtr child = NULL;
6731
0
    const xmlChar *value;
6732
6733
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6734
0
        return (NULL);
6735
6736
0
    facet = xmlSchemaNewFacet();
6737
0
    if (facet == NULL) {
6738
0
        xmlSchemaPErrMemory(ctxt, "allocating facet", node);
6739
0
        return (NULL);
6740
0
    }
6741
0
    facet->node = node;
6742
0
    value = xmlSchemaGetProp(ctxt, node, "value");
6743
0
    if (value == NULL) {
6744
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6745
0
                       "Facet %s has no value\n", node->name, NULL);
6746
0
        xmlSchemaFreeFacet(facet);
6747
0
        return (NULL);
6748
0
    }
6749
0
    if (IS_SCHEMA(node, "minInclusive")) {
6750
0
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6751
0
    } else if (IS_SCHEMA(node, "minExclusive")) {
6752
0
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6753
0
    } else if (IS_SCHEMA(node, "maxInclusive")) {
6754
0
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6755
0
    } else if (IS_SCHEMA(node, "maxExclusive")) {
6756
0
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6757
0
    } else if (IS_SCHEMA(node, "totalDigits")) {
6758
0
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6759
0
    } else if (IS_SCHEMA(node, "fractionDigits")) {
6760
0
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6761
0
    } else if (IS_SCHEMA(node, "pattern")) {
6762
0
        facet->type = XML_SCHEMA_FACET_PATTERN;
6763
0
    } else if (IS_SCHEMA(node, "enumeration")) {
6764
0
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
6765
0
    } else if (IS_SCHEMA(node, "whiteSpace")) {
6766
0
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
6767
0
    } else if (IS_SCHEMA(node, "length")) {
6768
0
        facet->type = XML_SCHEMA_FACET_LENGTH;
6769
0
    } else if (IS_SCHEMA(node, "maxLength")) {
6770
0
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6771
0
    } else if (IS_SCHEMA(node, "minLength")) {
6772
0
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
6773
0
    } else {
6774
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6775
0
                       "Unknown facet type %s\n", node->name, NULL);
6776
0
        xmlSchemaFreeFacet(facet);
6777
0
        return (NULL);
6778
0
    }
6779
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6780
0
    facet->value = value;
6781
0
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6782
0
  (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6783
0
  const xmlChar *fixed;
6784
6785
0
  fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6786
0
  if (fixed != NULL) {
6787
0
      if (xmlStrEqual(fixed, BAD_CAST "true"))
6788
0
    facet->fixed = 1;
6789
0
  }
6790
0
    }
6791
0
    child = node->children;
6792
6793
0
    if (IS_SCHEMA(child, "annotation")) {
6794
0
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6795
0
        child = child->next;
6796
0
    }
6797
0
    if (child != NULL) {
6798
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6799
0
                       "Facet %s has unexpected child content\n",
6800
0
                       node->name, NULL);
6801
0
    }
6802
0
    return (facet);
6803
0
}
6804
6805
/**
6806
 * xmlSchemaParseWildcardNs:
6807
 * @ctxt:  a schema parser context
6808
 * @wildc:  the wildcard, already created
6809
 * @node:  a subtree containing XML Schema information
6810
 *
6811
 * Parses the attribute "processContents" and "namespace"
6812
 * of a xsd:anyAttribute and xsd:any.
6813
 * *WARNING* this interface is highly subject to change
6814
 *
6815
 * Returns 0 if everything goes fine, a positive error code
6816
 * if something is not valid and -1 if an internal error occurs.
6817
 */
6818
static int
6819
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6820
       xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6821
       xmlSchemaWildcardPtr wildc,
6822
       xmlNodePtr node)
6823
0
{
6824
0
    const xmlChar *pc, *ns, *dictnsItem;
6825
0
    int ret = 0;
6826
0
    xmlChar *nsItem;
6827
0
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6828
0
    xmlAttrPtr attr;
6829
6830
0
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
6831
0
    if ((pc == NULL)
6832
0
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6833
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6834
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6835
0
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6836
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6837
0
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
6838
0
    } else {
6839
0
        xmlSchemaPSimpleTypeErr(ctxt,
6840
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6841
0
      NULL, node,
6842
0
      NULL, "(strict | skip | lax)", pc,
6843
0
      NULL, NULL, NULL);
6844
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6845
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6846
0
    }
6847
    /*
6848
     * Build the namespace constraints.
6849
     */
6850
0
    attr = xmlSchemaGetPropNode(node, "namespace");
6851
0
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6852
0
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6853
0
  wildc->any = 1;
6854
0
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6855
0
  wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6856
0
  if (wildc->negNsSet == NULL) {
6857
0
      return (-1);
6858
0
  }
6859
0
  wildc->negNsSet->value = ctxt->targetNamespace;
6860
0
    } else {
6861
0
  const xmlChar *end, *cur;
6862
6863
0
  cur = ns;
6864
0
  do {
6865
0
      while (IS_BLANK_CH(*cur))
6866
0
    cur++;
6867
0
      end = cur;
6868
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6869
0
    end++;
6870
0
      if (end == cur)
6871
0
    break;
6872
0
      nsItem = xmlStrndup(cur, end - cur);
6873
0
      if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6874
0
        (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6875
0
    xmlSchemaPSimpleTypeErr(ctxt,
6876
0
        XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6877
0
        NULL, (xmlNodePtr) attr,
6878
0
        NULL,
6879
0
        "((##any | ##other) | List of (xs:anyURI | "
6880
0
        "(##targetNamespace | ##local)))",
6881
0
        nsItem, NULL, NULL, NULL);
6882
0
    ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6883
0
      } else {
6884
0
    if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6885
0
        dictnsItem = ctxt->targetNamespace;
6886
0
    } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6887
0
        dictnsItem = NULL;
6888
0
    } else {
6889
        /*
6890
        * Validate the item (anyURI).
6891
        */
6892
0
        xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6893
0
      nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6894
0
        dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6895
0
    }
6896
    /*
6897
    * Avoid duplicate namespaces.
6898
    */
6899
0
    tmp = wildc->nsSet;
6900
0
    while (tmp != NULL) {
6901
0
        if (dictnsItem == tmp->value)
6902
0
      break;
6903
0
        tmp = tmp->next;
6904
0
    }
6905
0
    if (tmp == NULL) {
6906
0
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6907
0
        if (tmp == NULL) {
6908
0
      xmlFree(nsItem);
6909
0
      return (-1);
6910
0
        }
6911
0
        tmp->value = dictnsItem;
6912
0
        tmp->next = NULL;
6913
0
        if (wildc->nsSet == NULL)
6914
0
      wildc->nsSet = tmp;
6915
0
        else if (lastNs != NULL)
6916
0
      lastNs->next = tmp;
6917
0
        lastNs = tmp;
6918
0
    }
6919
6920
0
      }
6921
0
      xmlFree(nsItem);
6922
0
      cur = end;
6923
0
  } while (*cur != 0);
6924
0
    }
6925
0
    return (ret);
6926
0
}
6927
6928
static int
6929
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6930
         xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6931
         xmlNodePtr node,
6932
         int minOccurs,
6933
0
         int maxOccurs) {
6934
6935
0
    if ((maxOccurs == 0) && ( minOccurs == 0))
6936
0
  return (0);
6937
0
    if (maxOccurs != UNBOUNDED) {
6938
  /*
6939
  * TODO: Maybe we should better not create the particle,
6940
  * if min/max is invalid, since it could confuse the build of the
6941
  * content model.
6942
  */
6943
  /*
6944
  * 3.9.6 Schema Component Constraint: Particle Correct
6945
  *
6946
  */
6947
0
  if (maxOccurs < 1) {
6948
      /*
6949
      * 2.2 {max occurs} must be greater than or equal to 1.
6950
      */
6951
0
      xmlSchemaPCustomAttrErr(ctxt,
6952
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6953
0
    NULL, NULL,
6954
0
    xmlSchemaGetPropNode(node, "maxOccurs"),
6955
0
    "The value must be greater than or equal to 1");
6956
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6957
0
  } else if (minOccurs > maxOccurs) {
6958
      /*
6959
      * 2.1 {min occurs} must not be greater than {max occurs}.
6960
      */
6961
0
      xmlSchemaPCustomAttrErr(ctxt,
6962
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6963
0
    NULL, NULL,
6964
0
    xmlSchemaGetPropNode(node, "minOccurs"),
6965
0
    "The value must not be greater than the value of 'maxOccurs'");
6966
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6967
0
  }
6968
0
    }
6969
0
    return (0);
6970
0
}
6971
6972
/**
6973
 * xmlSchemaParseAny:
6974
 * @ctxt:  a schema validation context
6975
 * @schema:  the schema being built
6976
 * @node:  a subtree containing XML Schema information
6977
 *
6978
 * Parsea a XML schema <any> element. A particle and wildcard
6979
 * will be created (except if minOccurs==maxOccurs==0, in this case
6980
 * nothing will be created).
6981
 * *WARNING* this interface is highly subject to change
6982
 *
6983
 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6984
 */
6985
static xmlSchemaParticlePtr
6986
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6987
                  xmlNodePtr node)
6988
0
{
6989
0
    xmlSchemaParticlePtr particle;
6990
0
    xmlNodePtr child = NULL;
6991
0
    xmlSchemaWildcardPtr wild;
6992
0
    int min, max;
6993
0
    xmlAttrPtr attr;
6994
0
    xmlSchemaAnnotPtr annot = NULL;
6995
6996
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6997
0
        return (NULL);
6998
    /*
6999
    * Check for illegal attributes.
7000
    */
7001
0
    attr = node->properties;
7002
0
    while (attr != NULL) {
7003
0
  if (attr->ns == NULL) {
7004
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7005
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
7006
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
7007
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7008
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7009
0
    xmlSchemaPIllegalAttrErr(ctxt,
7010
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7011
0
      }
7012
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7013
0
      xmlSchemaPIllegalAttrErr(ctxt,
7014
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7015
0
  }
7016
0
  attr = attr->next;
7017
0
    }
7018
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7019
    /*
7020
    * minOccurs/maxOccurs.
7021
    */
7022
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
7023
0
  "(xs:nonNegativeInteger | unbounded)");
7024
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
7025
0
  "xs:nonNegativeInteger");
7026
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
7027
    /*
7028
    * Create & parse the wildcard.
7029
    */
7030
0
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
7031
0
    if (wild == NULL)
7032
0
  return (NULL);
7033
0
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
7034
    /*
7035
    * And now for the children...
7036
    */
7037
0
    child = node->children;
7038
0
    if (IS_SCHEMA(child, "annotation")) {
7039
0
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7040
0
        child = child->next;
7041
0
    }
7042
0
    if (child != NULL) {
7043
0
  xmlSchemaPContentErr(ctxt,
7044
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7045
0
      NULL, node, child,
7046
0
      NULL, "(annotation?)");
7047
0
    }
7048
    /*
7049
    * No component if minOccurs==maxOccurs==0.
7050
    */
7051
0
    if ((min == 0) && (max == 0)) {
7052
  /* Don't free the wildcard, since it's already on the list. */
7053
0
  return (NULL);
7054
0
    }
7055
    /*
7056
    * Create the particle.
7057
    */
7058
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
7059
0
    if (particle == NULL)
7060
0
        return (NULL);
7061
0
    particle->annot = annot;
7062
0
    particle->children = (xmlSchemaTreeItemPtr) wild;
7063
7064
0
    return (particle);
7065
0
}
7066
7067
/**
7068
 * xmlSchemaParseNotation:
7069
 * @ctxt:  a schema validation context
7070
 * @schema:  the schema being built
7071
 * @node:  a subtree containing XML Schema information
7072
 *
7073
 * parse a XML schema Notation declaration
7074
 *
7075
 * Returns the new structure or NULL in case of error
7076
 */
7077
static xmlSchemaNotationPtr
7078
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
7079
                       xmlNodePtr node)
7080
0
{
7081
0
    const xmlChar *name;
7082
0
    xmlSchemaNotationPtr ret;
7083
0
    xmlNodePtr child = NULL;
7084
7085
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7086
0
        return (NULL);
7087
0
    name = xmlSchemaGetProp(ctxt, node, "name");
7088
0
    if (name == NULL) {
7089
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
7090
0
                       "Notation has no name\n", NULL, NULL);
7091
0
        return (NULL);
7092
0
    }
7093
0
    ret = xmlSchemaAddNotation(ctxt, schema, name,
7094
0
  ctxt->targetNamespace, node);
7095
0
    if (ret == NULL)
7096
0
        return (NULL);
7097
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7098
7099
0
    child = node->children;
7100
0
    if (IS_SCHEMA(child, "annotation")) {
7101
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7102
0
        child = child->next;
7103
0
    }
7104
0
    if (child != NULL) {
7105
0
  xmlSchemaPContentErr(ctxt,
7106
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7107
0
      NULL, node, child,
7108
0
      NULL, "(annotation?)");
7109
0
    }
7110
7111
0
    return (ret);
7112
0
}
7113
7114
/**
7115
 * xmlSchemaParseAnyAttribute:
7116
 * @ctxt:  a schema validation context
7117
 * @schema:  the schema being built
7118
 * @node:  a subtree containing XML Schema information
7119
 *
7120
 * parse a XML schema AnyAttribute declaration
7121
 * *WARNING* this interface is highly subject to change
7122
 *
7123
 * Returns a wildcard or NULL.
7124
 */
7125
static xmlSchemaWildcardPtr
7126
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7127
                           xmlSchemaPtr schema, xmlNodePtr node)
7128
0
{
7129
0
    xmlSchemaWildcardPtr ret;
7130
0
    xmlNodePtr child = NULL;
7131
0
    xmlAttrPtr attr;
7132
7133
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7134
0
        return (NULL);
7135
7136
0
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7137
0
  node);
7138
0
    if (ret == NULL) {
7139
0
        return (NULL);
7140
0
    }
7141
    /*
7142
    * Check for illegal attributes.
7143
    */
7144
0
    attr = node->properties;
7145
0
    while (attr != NULL) {
7146
0
  if (attr->ns == NULL) {
7147
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7148
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7149
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7150
0
    xmlSchemaPIllegalAttrErr(ctxt,
7151
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7152
0
      }
7153
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7154
0
      xmlSchemaPIllegalAttrErr(ctxt,
7155
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7156
0
  }
7157
0
  attr = attr->next;
7158
0
    }
7159
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7160
    /*
7161
    * Parse the namespace list.
7162
    */
7163
0
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7164
0
  return (NULL);
7165
    /*
7166
    * And now for the children...
7167
    */
7168
0
    child = node->children;
7169
0
    if (IS_SCHEMA(child, "annotation")) {
7170
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7171
0
        child = child->next;
7172
0
    }
7173
0
    if (child != NULL) {
7174
0
  xmlSchemaPContentErr(ctxt,
7175
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7176
0
      NULL, node, child,
7177
0
      NULL, "(annotation?)");
7178
0
    }
7179
7180
0
    return (ret);
7181
0
}
7182
7183
7184
/**
7185
 * xmlSchemaParseAttribute:
7186
 * @ctxt:  a schema validation context
7187
 * @schema:  the schema being built
7188
 * @node:  a subtree containing XML Schema information
7189
 *
7190
 * parse a XML schema Attribute declaration
7191
 * *WARNING* this interface is highly subject to change
7192
 *
7193
 * Returns the attribute declaration.
7194
 */
7195
static xmlSchemaBasicItemPtr
7196
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7197
           xmlSchemaPtr schema,
7198
           xmlNodePtr node,
7199
           xmlSchemaItemListPtr uses,
7200
           int parentType)
7201
0
{
7202
0
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
7203
0
    xmlSchemaAttributeUsePtr use = NULL;
7204
0
    xmlNodePtr child = NULL;
7205
0
    xmlAttrPtr attr;
7206
0
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7207
0
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7208
0
    int nberrors, hasForm = 0, defValueType = 0;
7209
7210
0
#define WXS_ATTR_DEF_VAL_DEFAULT 1
7211
0
#define WXS_ATTR_DEF_VAL_FIXED 2
7212
7213
    /*
7214
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7215
     */
7216
7217
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7218
0
        return (NULL);
7219
0
    attr = xmlSchemaGetPropNode(node, "ref");
7220
0
    if (attr != NULL) {
7221
0
  if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7222
0
      NULL, attr, &tmpNs, &tmpName) != 0) {
7223
0
      return (NULL);
7224
0
  }
7225
0
  if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7226
0
      return(NULL);
7227
0
  isRef = 1;
7228
0
    }
7229
0
    nberrors = pctxt->nberrors;
7230
    /*
7231
    * Check for illegal attributes.
7232
    */
7233
0
    attr = node->properties;
7234
0
    while (attr != NULL) {
7235
0
  if (attr->ns == NULL) {
7236
0
      if (isRef) {
7237
0
    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7238
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7239
0
        goto attr_next;
7240
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7241
0
        goto attr_next;
7242
0
    }
7243
0
      } else {
7244
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7245
0
        goto attr_next;
7246
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7247
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7248
0
        goto attr_next;
7249
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7250
0
        xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7251
0
      attr, &tmpNs, &tmpName);
7252
0
        goto attr_next;
7253
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7254
        /*
7255
        * Evaluate the target namespace
7256
        */
7257
0
        hasForm = 1;
7258
0
        attrValue = xmlSchemaGetNodeContent(pctxt,
7259
0
      (xmlNodePtr) attr);
7260
0
        if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7261
0
      ns = pctxt->targetNamespace;
7262
0
        } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7263
0
        {
7264
0
      xmlSchemaPSimpleTypeErr(pctxt,
7265
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7266
0
          NULL, (xmlNodePtr) attr,
7267
0
          NULL, "(qualified | unqualified)",
7268
0
          attrValue, NULL, NULL, NULL);
7269
0
        }
7270
0
        goto attr_next;
7271
0
    }
7272
0
      }
7273
0
      if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7274
7275
0
    attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7276
    /* TODO: Maybe we need to normalize the value beforehand. */
7277
0
    if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7278
0
        occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7279
0
    else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7280
0
        occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7281
0
    else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7282
0
        occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7283
0
    else {
7284
0
        xmlSchemaPSimpleTypeErr(pctxt,
7285
0
      XML_SCHEMAP_INVALID_ATTR_USE,
7286
0
      NULL, (xmlNodePtr) attr,
7287
0
      NULL, "(optional | prohibited | required)",
7288
0
      attrValue, NULL, NULL, NULL);
7289
0
    }
7290
0
    goto attr_next;
7291
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7292
    /*
7293
    * 3.2.3 : 1
7294
    * default and fixed must not both be present.
7295
    */
7296
0
    if (defValue) {
7297
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7298
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7299
0
      NULL, attr, "default", "fixed");
7300
0
    } else {
7301
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7302
0
        defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7303
0
    }
7304
0
    goto attr_next;
7305
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7306
    /*
7307
    * 3.2.3 : 1
7308
    * default and fixed must not both be present.
7309
    */
7310
0
    if (defValue) {
7311
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7312
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7313
0
      NULL, attr, "default", "fixed");
7314
0
    } else {
7315
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7316
0
        defValueType = WXS_ATTR_DEF_VAL_FIXED;
7317
0
    }
7318
0
    goto attr_next;
7319
0
      }
7320
0
  } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7321
0
      goto attr_next;
7322
7323
0
  xmlSchemaPIllegalAttrErr(pctxt,
7324
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7325
7326
0
attr_next:
7327
0
  attr = attr->next;
7328
0
    }
7329
    /*
7330
    * 3.2.3 : 2
7331
    * If default and use are both present, use must have
7332
    * the actual value optional.
7333
    */
7334
0
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7335
0
  (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7336
0
  xmlSchemaPSimpleTypeErr(pctxt,
7337
0
      XML_SCHEMAP_SRC_ATTRIBUTE_2,
7338
0
      NULL, node, NULL,
7339
0
      "(optional | prohibited | required)", NULL,
7340
0
      "The value of the attribute 'use' must be 'optional' "
7341
0
      "if the attribute 'default' is present",
7342
0
      NULL, NULL);
7343
0
    }
7344
    /*
7345
    * We want correct attributes.
7346
    */
7347
0
    if (nberrors != pctxt->nberrors)
7348
0
  return(NULL);
7349
0
    if (! isRef) {
7350
0
  xmlSchemaAttributePtr attrDecl;
7351
7352
  /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7353
0
  if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7354
0
      ns = pctxt->targetNamespace;
7355
  /*
7356
  * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7357
  * TODO: Move this to the component layer.
7358
  */
7359
0
  if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7360
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7361
0
    XML_SCHEMAP_NO_XSI,
7362
0
    node, NULL,
7363
0
    "The target namespace must not match '%s'",
7364
0
    xmlSchemaInstanceNs, NULL);
7365
0
  }
7366
0
  attr = xmlSchemaGetPropNode(node, "name");
7367
0
  if (attr == NULL) {
7368
0
      xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7369
0
    NULL, node, "name", NULL);
7370
0
      return (NULL);
7371
0
  }
7372
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7373
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7374
0
      return (NULL);
7375
0
  }
7376
  /*
7377
  * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7378
  * TODO: Move this to the component layer.
7379
  */
7380
0
  if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7381
0
      xmlSchemaPSimpleTypeErr(pctxt,
7382
0
    XML_SCHEMAP_NO_XMLNS,
7383
0
    NULL, (xmlNodePtr) attr,
7384
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7385
0
    "The value of the attribute must not match 'xmlns'",
7386
0
    NULL, NULL);
7387
0
      return (NULL);
7388
0
  }
7389
0
  if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7390
0
      goto check_children;
7391
  /*
7392
  * Create the attribute use component.
7393
  */
7394
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7395
0
  if (use == NULL)
7396
0
      return(NULL);
7397
0
  use->occurs = occurs;
7398
  /*
7399
  * Create the attribute declaration.
7400
  */
7401
0
  attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7402
0
  if (attrDecl == NULL)
7403
0
      return (NULL);
7404
0
  if (tmpName != NULL) {
7405
0
      attrDecl->typeName = tmpName;
7406
0
      attrDecl->typeNs = tmpNs;
7407
0
  }
7408
0
  use->attrDecl = attrDecl;
7409
  /*
7410
  * Value constraint.
7411
  */
7412
0
  if (defValue != NULL) {
7413
0
      attrDecl->defValue = defValue;
7414
0
      if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7415
0
    attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7416
0
  }
7417
0
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7418
0
  xmlSchemaQNameRefPtr ref;
7419
7420
  /*
7421
  * Create the attribute use component.
7422
  */
7423
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7424
0
  if (use == NULL)
7425
0
      return(NULL);
7426
  /*
7427
  * We need to resolve the reference at later stage.
7428
  */
7429
0
  WXS_ADD_PENDING(pctxt, use);
7430
0
  use->occurs = occurs;
7431
  /*
7432
  * Create a QName reference to the attribute declaration.
7433
  */
7434
0
  ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7435
0
      tmpName, tmpNs);
7436
0
  if (ref == NULL)
7437
0
      return(NULL);
7438
  /*
7439
  * Assign the reference. This will be substituted for the
7440
  * referenced attribute declaration when the QName is resolved.
7441
  */
7442
0
  use->attrDecl = WXS_ATTR_CAST ref;
7443
  /*
7444
  * Value constraint.
7445
  */
7446
0
  if (defValue != NULL)
7447
0
      use->defValue = defValue;
7448
0
  if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7449
0
      use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7450
0
    }
7451
7452
0
check_children:
7453
    /*
7454
    * And now for the children...
7455
    */
7456
0
    child = node->children;
7457
0
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7458
0
  xmlSchemaAttributeUseProhibPtr prohib;
7459
7460
0
  if (IS_SCHEMA(child, "annotation")) {
7461
0
      xmlSchemaParseAnnotation(pctxt, child, 0);
7462
0
      child = child->next;
7463
0
  }
7464
0
  if (child != NULL) {
7465
0
      xmlSchemaPContentErr(pctxt,
7466
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7467
0
    NULL, node, child, NULL,
7468
0
    "(annotation?)");
7469
0
  }
7470
  /*
7471
  * Check for pointlessness of attribute prohibitions.
7472
  */
7473
0
  if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7474
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7475
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7476
0
    node, NULL,
7477
0
    "Skipping attribute use prohibition, since it is "
7478
0
    "pointless inside an <attributeGroup>",
7479
0
    NULL, NULL, NULL);
7480
0
      return(NULL);
7481
0
  } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7482
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7483
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7484
0
    node, NULL,
7485
0
    "Skipping attribute use prohibition, since it is "
7486
0
    "pointless when extending a type",
7487
0
    NULL, NULL, NULL);
7488
0
      return(NULL);
7489
0
  }
7490
0
  if (! isRef) {
7491
0
      tmpName = name;
7492
0
      tmpNs = ns;
7493
0
  }
7494
  /*
7495
  * Check for duplicate attribute prohibitions.
7496
  */
7497
0
  if (uses) {
7498
0
      int i;
7499
7500
0
      for (i = 0; i < uses->nbItems; i++) {
7501
0
    use = uses->items[i];
7502
0
    if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7503
0
        (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7504
0
        (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7505
0
    {
7506
0
        xmlChar *str = NULL;
7507
7508
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7509
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7510
0
      node, NULL,
7511
0
      "Skipping duplicate attribute use prohibition '%s'",
7512
0
      xmlSchemaFormatQName(&str, tmpNs, tmpName),
7513
0
      NULL, NULL);
7514
0
        FREE_AND_NULL(str)
7515
0
        return(NULL);
7516
0
    }
7517
0
      }
7518
0
  }
7519
  /*
7520
  * Create the attribute prohibition helper component.
7521
  */
7522
0
  prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7523
0
  if (prohib == NULL)
7524
0
      return(NULL);
7525
0
  prohib->node = node;
7526
0
  prohib->name = tmpName;
7527
0
  prohib->targetNamespace = tmpNs;
7528
0
  if (isRef) {
7529
      /*
7530
      * We need at least to resolve to the attribute declaration.
7531
      */
7532
0
      WXS_ADD_PENDING(pctxt, prohib);
7533
0
  }
7534
0
  return(WXS_BASIC_CAST prohib);
7535
0
    } else {
7536
0
  if (IS_SCHEMA(child, "annotation")) {
7537
      /*
7538
      * TODO: Should this go into the attr decl?
7539
      */
7540
0
      use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7541
0
      child = child->next;
7542
0
  }
7543
0
  if (isRef) {
7544
0
      if (child != NULL) {
7545
0
    if (IS_SCHEMA(child, "simpleType"))
7546
        /*
7547
        * 3.2.3 : 3.2
7548
        * If ref is present, then all of <simpleType>,
7549
        * form and type must be absent.
7550
        */
7551
0
        xmlSchemaPContentErr(pctxt,
7552
0
      XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7553
0
      NULL, node, child, NULL,
7554
0
      "(annotation?)");
7555
0
    else
7556
0
        xmlSchemaPContentErr(pctxt,
7557
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7558
0
      NULL, node, child, NULL,
7559
0
      "(annotation?)");
7560
0
      }
7561
0
  } else {
7562
0
      if (IS_SCHEMA(child, "simpleType")) {
7563
0
    if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7564
        /*
7565
        * 3.2.3 : 4
7566
        * type and <simpleType> must not both be present.
7567
        */
7568
0
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7569
0
      NULL, node, child,
7570
0
      "The attribute 'type' and the <simpleType> child "
7571
0
      "are mutually exclusive", NULL);
7572
0
    } else
7573
0
        WXS_ATTRUSE_TYPEDEF(use) =
7574
0
      xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7575
0
    child = child->next;
7576
0
      }
7577
0
      if (child != NULL)
7578
0
    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7579
0
    NULL, node, child, NULL,
7580
0
    "(annotation?, simpleType?)");
7581
0
  }
7582
0
    }
7583
0
    return (WXS_BASIC_CAST use);
7584
0
}
7585
7586
7587
static xmlSchemaAttributePtr
7588
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7589
            xmlSchemaPtr schema,
7590
            xmlNodePtr node)
7591
0
{
7592
0
    const xmlChar *attrValue;
7593
0
    xmlSchemaAttributePtr ret;
7594
0
    xmlNodePtr child = NULL;
7595
0
    xmlAttrPtr attr;
7596
7597
    /*
7598
     * Note that the w3c spec assumes the schema to be validated with schema
7599
     * for schemas beforehand.
7600
     *
7601
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7602
     */
7603
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7604
0
        return (NULL);
7605
    /*
7606
    * 3.2.3 : 3.1
7607
    * One of ref or name must be present, but not both
7608
    */
7609
0
    attr = xmlSchemaGetPropNode(node, "name");
7610
0
    if (attr == NULL) {
7611
0
  xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7612
0
      NULL, node, "name", NULL);
7613
0
  return (NULL);
7614
0
    }
7615
0
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7616
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7617
0
  return (NULL);
7618
0
    }
7619
    /*
7620
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7621
    * TODO: Move this to the component layer.
7622
    */
7623
0
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7624
0
  xmlSchemaPSimpleTypeErr(pctxt,
7625
0
      XML_SCHEMAP_NO_XMLNS,
7626
0
      NULL, (xmlNodePtr) attr,
7627
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7628
0
      "The value of the attribute must not match 'xmlns'",
7629
0
      NULL, NULL);
7630
0
  return (NULL);
7631
0
    }
7632
    /*
7633
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7634
    * TODO: Move this to the component layer.
7635
    *       Or better leave it here and add it to the component layer
7636
    *       if we have a schema construction API.
7637
    */
7638
0
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7639
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
7640
0
      XML_SCHEMAP_NO_XSI, node, NULL,
7641
0
      "The target namespace must not match '%s'",
7642
0
      xmlSchemaInstanceNs, NULL);
7643
0
    }
7644
7645
0
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7646
0
  pctxt->targetNamespace, node, 1);
7647
0
    if (ret == NULL)
7648
0
  return (NULL);
7649
0
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7650
7651
    /*
7652
    * Check for illegal attributes.
7653
    */
7654
0
    attr = node->properties;
7655
0
    while (attr != NULL) {
7656
0
  if (attr->ns == NULL) {
7657
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7658
0
    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7659
0
    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7660
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7661
0
    (!xmlStrEqual(attr->name, BAD_CAST "type")))
7662
0
      {
7663
0
    xmlSchemaPIllegalAttrErr(pctxt,
7664
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7665
0
      }
7666
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7667
0
      xmlSchemaPIllegalAttrErr(pctxt,
7668
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7669
0
  }
7670
0
  attr = attr->next;
7671
0
    }
7672
0
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
7673
0
  node, "type", &ret->typeNs, &ret->typeName);
7674
7675
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7676
    /*
7677
    * Attribute "fixed".
7678
    */
7679
0
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7680
0
    if (ret->defValue != NULL)
7681
0
  ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7682
    /*
7683
    * Attribute "default".
7684
    */
7685
0
    attr = xmlSchemaGetPropNode(node, "default");
7686
0
    if (attr != NULL) {
7687
  /*
7688
  * 3.2.3 : 1
7689
  * default and fixed must not both be present.
7690
  */
7691
0
  if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7692
0
      xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7693
0
    WXS_BASIC_CAST ret, attr, "default", "fixed");
7694
0
  } else
7695
0
      ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7696
0
    }
7697
    /*
7698
    * And now for the children...
7699
    */
7700
0
    child = node->children;
7701
0
    if (IS_SCHEMA(child, "annotation")) {
7702
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7703
0
        child = child->next;
7704
0
    }
7705
0
    if (IS_SCHEMA(child, "simpleType")) {
7706
0
  if (ret->typeName != NULL) {
7707
      /*
7708
      * 3.2.3 : 4
7709
      * type and <simpleType> must not both be present.
7710
      */
7711
0
      xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7712
0
    NULL, node, child,
7713
0
    "The attribute 'type' and the <simpleType> child "
7714
0
    "are mutually exclusive", NULL);
7715
0
  } else
7716
0
      ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7717
0
  child = child->next;
7718
0
    }
7719
0
    if (child != NULL)
7720
0
  xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7721
0
      NULL, node, child, NULL,
7722
0
      "(annotation?, simpleType?)");
7723
7724
0
    return (ret);
7725
0
}
7726
7727
/**
7728
 * xmlSchemaParseAttributeGroupRef:
7729
 * @ctxt:  a schema validation context
7730
 * @schema:  the schema being built
7731
 * @node:  a subtree containing XML Schema information
7732
 *
7733
 * Parse an attribute group definition reference.
7734
 * Note that a reference to an attribute group does not
7735
 * correspond to any component at all.
7736
 * *WARNING* this interface is highly subject to change
7737
 *
7738
 * Returns the attribute group or NULL in case of error.
7739
 */
7740
static xmlSchemaQNameRefPtr
7741
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7742
        xmlSchemaPtr schema,
7743
        xmlNodePtr node)
7744
0
{
7745
0
    xmlSchemaQNameRefPtr ret;
7746
0
    xmlNodePtr child = NULL;
7747
0
    xmlAttrPtr attr;
7748
0
    const xmlChar *refNs = NULL, *ref = NULL;
7749
7750
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7751
0
        return (NULL);
7752
7753
0
    attr = xmlSchemaGetPropNode(node, "ref");
7754
0
    if (attr == NULL) {
7755
0
  xmlSchemaPMissingAttrErr(pctxt,
7756
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7757
0
      NULL, node, "ref", NULL);
7758
0
  return (NULL);
7759
0
    }
7760
0
    xmlSchemaPValAttrNodeQName(pctxt, schema,
7761
0
  NULL, attr, &refNs, &ref);
7762
0
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7763
0
  return(NULL);
7764
7765
    /*
7766
    * Check for illegal attributes.
7767
    */
7768
0
    attr = node->properties;
7769
0
    while (attr != NULL) {
7770
0
  if (attr->ns == NULL) {
7771
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7772
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7773
0
      {
7774
0
    xmlSchemaPIllegalAttrErr(pctxt,
7775
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7776
0
      }
7777
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7778
0
      xmlSchemaPIllegalAttrErr(pctxt,
7779
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7780
0
  }
7781
0
  attr = attr->next;
7782
0
    }
7783
    /* Attribute ID */
7784
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7785
7786
    /*
7787
    * And now for the children...
7788
    */
7789
0
    child = node->children;
7790
0
    if (IS_SCHEMA(child, "annotation")) {
7791
  /*
7792
  * TODO: We do not have a place to store the annotation, do we?
7793
  */
7794
0
        xmlSchemaParseAnnotation(pctxt, child, 0);
7795
0
        child = child->next;
7796
0
    }
7797
0
    if (child != NULL) {
7798
0
  xmlSchemaPContentErr(pctxt,
7799
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7800
0
      NULL, node, child, NULL,
7801
0
      "(annotation?)");
7802
0
    }
7803
7804
    /*
7805
    * Handle attribute group redefinitions.
7806
    */
7807
0
    if (pctxt->isRedefine && pctxt->redef &&
7808
0
  (pctxt->redef->item->type ==
7809
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7810
0
  (ref == pctxt->redef->refName) &&
7811
0
  (refNs == pctxt->redef->refTargetNs))
7812
0
    {
7813
  /*
7814
  * SPEC src-redefine:
7815
  * (7.1) "If it has an <attributeGroup> among its contents
7816
  * the `actual value` of whose ref [attribute] is the same
7817
  * as the `actual value` of its own name attribute plus
7818
  * target namespace, then it must have exactly one such group."
7819
  */
7820
0
  if (pctxt->redefCounter != 0) {
7821
0
      xmlChar *str = NULL;
7822
7823
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7824
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7825
0
    "The redefining attribute group definition "
7826
0
    "'%s' must not contain more than one "
7827
0
    "reference to the redefined definition",
7828
0
    xmlSchemaFormatQName(&str, refNs, ref), NULL);
7829
0
      FREE_AND_NULL(str);
7830
0
      return(NULL);
7831
0
  }
7832
0
  pctxt->redefCounter++;
7833
  /*
7834
  * URGENT TODO: How to ensure that the reference will not be
7835
  * handled by the normal component resolution mechanism?
7836
  */
7837
0
  ret = xmlSchemaNewQNameRef(pctxt,
7838
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7839
0
  if (ret == NULL)
7840
0
      return(NULL);
7841
0
  ret->node = node;
7842
0
  pctxt->redef->reference = WXS_BASIC_CAST ret;
7843
0
    } else {
7844
  /*
7845
  * Create a QName-reference helper component. We will substitute this
7846
  * component for the attribute uses of the referenced attribute group
7847
  * definition.
7848
  */
7849
0
  ret = xmlSchemaNewQNameRef(pctxt,
7850
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7851
0
  if (ret == NULL)
7852
0
      return(NULL);
7853
0
  ret->node = node;
7854
  /* Add to pending items, to be able to resolve the reference. */
7855
0
  WXS_ADD_PENDING(pctxt, ret);
7856
0
    }
7857
0
    return (ret);
7858
0
}
7859
7860
/**
7861
 * xmlSchemaParseAttributeGroupDefinition:
7862
 * @pctxt:  a schema validation context
7863
 * @schema:  the schema being built
7864
 * @node:  a subtree containing XML Schema information
7865
 *
7866
 * parse a XML schema Attribute Group declaration
7867
 * *WARNING* this interface is highly subject to change
7868
 *
7869
 * Returns the attribute group definition or NULL in case of error.
7870
 */
7871
static xmlSchemaAttributeGroupPtr
7872
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7873
               xmlSchemaPtr schema,
7874
               xmlNodePtr node)
7875
0
{
7876
0
    const xmlChar *name;
7877
0
    xmlSchemaAttributeGroupPtr ret;
7878
0
    xmlNodePtr child = NULL;
7879
0
    xmlAttrPtr attr;
7880
0
    int hasRefs = 0;
7881
7882
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7883
0
        return (NULL);
7884
7885
0
    attr = xmlSchemaGetPropNode(node, "name");
7886
0
    if (attr == NULL) {
7887
0
  xmlSchemaPMissingAttrErr(pctxt,
7888
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7889
0
      NULL, node, "name", NULL);
7890
0
  return (NULL);
7891
0
    }
7892
    /*
7893
    * The name is crucial, exit if invalid.
7894
    */
7895
0
    if (xmlSchemaPValAttrNode(pctxt,
7896
0
  NULL, attr,
7897
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7898
0
  return (NULL);
7899
0
    }
7900
0
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7901
0
  name, pctxt->targetNamespace, node);
7902
0
    if (ret == NULL)
7903
0
  return (NULL);
7904
    /*
7905
    * Check for illegal attributes.
7906
    */
7907
0
    attr = node->properties;
7908
0
    while (attr != NULL) {
7909
0
  if (attr->ns == NULL) {
7910
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7911
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7912
0
      {
7913
0
    xmlSchemaPIllegalAttrErr(pctxt,
7914
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7915
0
      }
7916
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7917
0
      xmlSchemaPIllegalAttrErr(pctxt,
7918
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7919
0
  }
7920
0
  attr = attr->next;
7921
0
    }
7922
    /* Attribute ID */
7923
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7924
    /*
7925
    * And now for the children...
7926
    */
7927
0
    child = node->children;
7928
0
    if (IS_SCHEMA(child, "annotation")) {
7929
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7930
0
        child = child->next;
7931
0
    }
7932
    /*
7933
    * Parse contained attribute decls/refs.
7934
    */
7935
0
    if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7936
0
  (xmlSchemaItemListPtr *) &(ret->attrUses),
7937
0
  XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7938
0
  return(NULL);
7939
0
    if (hasRefs)
7940
0
  ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7941
    /*
7942
    * Parse the attribute wildcard.
7943
    */
7944
0
    if (IS_SCHEMA(child, "anyAttribute")) {
7945
0
  ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7946
0
      schema, child);
7947
0
  child = child->next;
7948
0
    }
7949
0
    if (child != NULL) {
7950
0
  xmlSchemaPContentErr(pctxt,
7951
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7952
0
      NULL, node, child, NULL,
7953
0
      "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7954
0
    }
7955
0
    return (ret);
7956
0
}
7957
7958
/**
7959
 * xmlSchemaPValAttrFormDefault:
7960
 * @value:  the value
7961
 * @flags: the flags to be modified
7962
 * @flagQualified: the specific flag for "qualified"
7963
 *
7964
 * Returns 0 if the value is valid, 1 otherwise.
7965
 */
7966
static int
7967
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7968
           int *flags,
7969
           int flagQualified)
7970
0
{
7971
0
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
7972
0
  if  ((*flags & flagQualified) == 0)
7973
0
      *flags |= flagQualified;
7974
0
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7975
0
  return (1);
7976
7977
0
    return (0);
7978
0
}
7979
7980
/**
7981
 * xmlSchemaPValAttrBlockFinal:
7982
 * @value:  the value
7983
 * @flags: the flags to be modified
7984
 * @flagAll: the specific flag for "#all"
7985
 * @flagExtension: the specific flag for "extension"
7986
 * @flagRestriction: the specific flag for "restriction"
7987
 * @flagSubstitution: the specific flag for "substitution"
7988
 * @flagList: the specific flag for "list"
7989
 * @flagUnion: the specific flag for "union"
7990
 *
7991
 * Validates the value of the attribute "final" and "block". The value
7992
 * is converted into the specified flag values and returned in @flags.
7993
 *
7994
 * Returns 0 if the value is valid, 1 otherwise.
7995
 */
7996
7997
static int
7998
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7999
          int *flags,
8000
          int flagAll,
8001
          int flagExtension,
8002
          int flagRestriction,
8003
          int flagSubstitution,
8004
          int flagList,
8005
          int flagUnion)
8006
0
{
8007
0
    int ret = 0;
8008
8009
    /*
8010
    * TODO: This does not check for duplicate entries.
8011
    */
8012
0
    if ((flags == NULL) || (value == NULL))
8013
0
  return (-1);
8014
0
    if (value[0] == 0)
8015
0
  return (0);
8016
0
    if (xmlStrEqual(value, BAD_CAST "#all")) {
8017
0
  if (flagAll != -1)
8018
0
      *flags |= flagAll;
8019
0
  else {
8020
0
      if (flagExtension != -1)
8021
0
    *flags |= flagExtension;
8022
0
      if (flagRestriction != -1)
8023
0
    *flags |= flagRestriction;
8024
0
      if (flagSubstitution != -1)
8025
0
    *flags |= flagSubstitution;
8026
0
      if (flagList != -1)
8027
0
    *flags |= flagList;
8028
0
      if (flagUnion != -1)
8029
0
    *flags |= flagUnion;
8030
0
  }
8031
0
    } else {
8032
0
  const xmlChar *end, *cur = value;
8033
0
  xmlChar *item;
8034
8035
0
  do {
8036
0
      while (IS_BLANK_CH(*cur))
8037
0
    cur++;
8038
0
      end = cur;
8039
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8040
0
    end++;
8041
0
      if (end == cur)
8042
0
    break;
8043
0
      item = xmlStrndup(cur, end - cur);
8044
0
      if (xmlStrEqual(item, BAD_CAST "extension")) {
8045
0
    if (flagExtension != -1) {
8046
0
        if ((*flags & flagExtension) == 0)
8047
0
      *flags |= flagExtension;
8048
0
    } else
8049
0
        ret = 1;
8050
0
      } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
8051
0
    if (flagRestriction != -1) {
8052
0
        if ((*flags & flagRestriction) == 0)
8053
0
      *flags |= flagRestriction;
8054
0
    } else
8055
0
        ret = 1;
8056
0
      } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
8057
0
    if (flagSubstitution != -1) {
8058
0
        if ((*flags & flagSubstitution) == 0)
8059
0
      *flags |= flagSubstitution;
8060
0
    } else
8061
0
        ret = 1;
8062
0
      } else if (xmlStrEqual(item, BAD_CAST "list")) {
8063
0
    if (flagList != -1) {
8064
0
        if ((*flags & flagList) == 0)
8065
0
      *flags |= flagList;
8066
0
    } else
8067
0
        ret = 1;
8068
0
      } else if (xmlStrEqual(item, BAD_CAST "union")) {
8069
0
    if (flagUnion != -1) {
8070
0
        if ((*flags & flagUnion) == 0)
8071
0
      *flags |= flagUnion;
8072
0
    } else
8073
0
        ret = 1;
8074
0
      } else
8075
0
    ret = 1;
8076
0
      if (item != NULL)
8077
0
    xmlFree(item);
8078
0
      cur = end;
8079
0
  } while ((ret == 0) && (*cur != 0));
8080
0
    }
8081
8082
0
    return (ret);
8083
0
}
8084
8085
static int
8086
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
8087
           xmlSchemaIDCPtr idc,
8088
           xmlSchemaIDCSelectPtr selector,
8089
           xmlAttrPtr attr,
8090
           int isField)
8091
0
{
8092
0
    xmlNodePtr node;
8093
8094
    /*
8095
    * c-selector-xpath:
8096
    * Schema Component Constraint: Selector Value OK
8097
    *
8098
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
8099
    * in [XPath].
8100
    */
8101
0
    if (selector == NULL) {
8102
0
  xmlSchemaPErr(ctxt, idc->node,
8103
0
      XML_SCHEMAP_INTERNAL,
8104
0
      "Internal error: xmlSchemaCheckCSelectorXPath, "
8105
0
      "the selector is not specified.\n", NULL, NULL);
8106
0
  return (-1);
8107
0
    }
8108
0
    if (attr == NULL)
8109
0
  node = idc->node;
8110
0
    else
8111
0
  node = (xmlNodePtr) attr;
8112
0
    if (selector->xpath == NULL) {
8113
0
  xmlSchemaPCustomErr(ctxt,
8114
      /* TODO: Adjust error code. */
8115
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8116
0
      NULL, node,
8117
0
      "The XPath expression of the selector is not valid", NULL);
8118
0
  return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8119
0
    } else {
8120
0
  const xmlChar **nsArray = NULL;
8121
0
  xmlNsPtr *nsList = NULL;
8122
  /*
8123
  * Compile the XPath expression.
8124
  */
8125
  /*
8126
  * TODO: We need the array of in-scope namespaces for compilation.
8127
  * TODO: Call xmlPatterncompile with different options for selector/
8128
  * field.
8129
  */
8130
0
  if (attr == NULL)
8131
0
      nsList = NULL;
8132
0
  else
8133
0
      nsList = xmlGetNsList(attr->doc, attr->parent);
8134
  /*
8135
  * Build an array of prefixes and namespaces.
8136
  */
8137
0
  if (nsList != NULL) {
8138
0
      int i, count = 0;
8139
8140
0
      for (i = 0; nsList[i] != NULL; i++)
8141
0
    count++;
8142
8143
0
      nsArray = (const xmlChar **) xmlMalloc(
8144
0
    (count * 2 + 1) * sizeof(const xmlChar *));
8145
0
      if (nsArray == NULL) {
8146
0
    xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
8147
0
        NULL);
8148
0
    xmlFree(nsList);
8149
0
    return (-1);
8150
0
      }
8151
0
      for (i = 0; i < count; i++) {
8152
0
    nsArray[2 * i] = nsList[i]->href;
8153
0
    nsArray[2 * i + 1] = nsList[i]->prefix;
8154
0
      }
8155
0
      nsArray[count * 2] = NULL;
8156
0
      xmlFree(nsList);
8157
0
  }
8158
  /*
8159
  * TODO: Differentiate between "selector" and "field".
8160
  */
8161
0
  if (isField)
8162
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8163
0
    NULL, XML_PATTERN_XSFIELD, nsArray);
8164
0
  else
8165
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8166
0
    NULL, XML_PATTERN_XSSEL, nsArray);
8167
0
  if (nsArray != NULL)
8168
0
      xmlFree((xmlChar **) nsArray);
8169
8170
0
  if (selector->xpathComp == NULL) {
8171
0
      xmlSchemaPCustomErr(ctxt,
8172
    /* TODO: Adjust error code? */
8173
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8174
0
    NULL, node,
8175
0
    "The XPath expression '%s' could not be "
8176
0
    "compiled", selector->xpath);
8177
0
      return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8178
0
  }
8179
0
    }
8180
0
    return (0);
8181
0
}
8182
8183
#define ADD_ANNOTATION(annot)   \
8184
0
    xmlSchemaAnnotPtr cur = item->annot; \
8185
0
    if (item->annot == NULL) {  \
8186
0
  item->annot = annot;    \
8187
0
  return (annot);         \
8188
0
    }                           \
8189
0
    cur = item->annot;          \
8190
0
    if (cur->next != NULL) {    \
8191
0
  cur = cur->next;  \
8192
0
    }                           \
8193
0
    cur->next = annot;
8194
8195
/**
8196
 * xmlSchemaAssignAnnotation:
8197
 * @item: the schema component
8198
 * @annot: the annotation
8199
 *
8200
 * Adds the annotation to the given schema component.
8201
 *
8202
 * Returns the given annotation.
8203
 */
8204
static xmlSchemaAnnotPtr
8205
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8206
           xmlSchemaAnnotPtr annot)
8207
0
{
8208
0
    if ((annItem == NULL) || (annot == NULL))
8209
0
  return (NULL);
8210
0
    switch (annItem->type) {
8211
0
  case XML_SCHEMA_TYPE_ELEMENT: {
8212
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8213
0
    ADD_ANNOTATION(annot)
8214
0
      }
8215
0
      break;
8216
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
8217
0
    xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8218
0
    ADD_ANNOTATION(annot)
8219
0
      }
8220
0
      break;
8221
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8222
0
  case XML_SCHEMA_TYPE_ANY: {
8223
0
    xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8224
0
    ADD_ANNOTATION(annot)
8225
0
      }
8226
0
      break;
8227
0
  case XML_SCHEMA_TYPE_PARTICLE:
8228
0
  case XML_SCHEMA_TYPE_IDC_KEY:
8229
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
8230
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8231
0
    xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8232
0
    ADD_ANNOTATION(annot)
8233
0
      }
8234
0
      break;
8235
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8236
0
    xmlSchemaAttributeGroupPtr item =
8237
0
        (xmlSchemaAttributeGroupPtr) annItem;
8238
0
    ADD_ANNOTATION(annot)
8239
0
      }
8240
0
      break;
8241
0
  case XML_SCHEMA_TYPE_NOTATION: {
8242
0
    xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8243
0
    ADD_ANNOTATION(annot)
8244
0
      }
8245
0
      break;
8246
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
8247
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
8248
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
8249
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8250
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
8251
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
8252
0
  case XML_SCHEMA_FACET_PATTERN:
8253
0
  case XML_SCHEMA_FACET_ENUMERATION:
8254
0
  case XML_SCHEMA_FACET_WHITESPACE:
8255
0
  case XML_SCHEMA_FACET_LENGTH:
8256
0
  case XML_SCHEMA_FACET_MAXLENGTH:
8257
0
  case XML_SCHEMA_FACET_MINLENGTH: {
8258
0
    xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8259
0
    ADD_ANNOTATION(annot)
8260
0
      }
8261
0
      break;
8262
0
  case XML_SCHEMA_TYPE_SIMPLE:
8263
0
  case XML_SCHEMA_TYPE_COMPLEX: {
8264
0
    xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8265
0
    ADD_ANNOTATION(annot)
8266
0
      }
8267
0
      break;
8268
0
  case XML_SCHEMA_TYPE_GROUP: {
8269
0
    xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8270
0
    ADD_ANNOTATION(annot)
8271
0
      }
8272
0
      break;
8273
0
  case XML_SCHEMA_TYPE_SEQUENCE:
8274
0
  case XML_SCHEMA_TYPE_CHOICE:
8275
0
  case XML_SCHEMA_TYPE_ALL: {
8276
0
    xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8277
0
    ADD_ANNOTATION(annot)
8278
0
      }
8279
0
      break;
8280
0
  default:
8281
0
       xmlSchemaPCustomErr(NULL,
8282
0
    XML_SCHEMAP_INTERNAL,
8283
0
    NULL, NULL,
8284
0
    "Internal error: xmlSchemaAddAnnotation, "
8285
0
    "The item is not a annotated schema component", NULL);
8286
0
       break;
8287
0
    }
8288
0
    return (annot);
8289
0
}
8290
8291
/**
8292
 * xmlSchemaParseIDCSelectorAndField:
8293
 * @ctxt:  a schema validation context
8294
 * @schema:  the schema being built
8295
 * @node:  a subtree containing XML Schema information
8296
 *
8297
 * Parses a XML Schema identity-constraint definition's
8298
 * <selector> and <field> elements.
8299
 *
8300
 * Returns the parsed identity-constraint definition.
8301
 */
8302
static xmlSchemaIDCSelectPtr
8303
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8304
        xmlSchemaIDCPtr idc,
8305
        xmlNodePtr node,
8306
        int isField)
8307
0
{
8308
0
    xmlSchemaIDCSelectPtr item;
8309
0
    xmlNodePtr child = NULL;
8310
0
    xmlAttrPtr attr;
8311
8312
    /*
8313
    * Check for illegal attributes.
8314
    */
8315
0
    attr = node->properties;
8316
0
    while (attr != NULL) {
8317
0
  if (attr->ns == NULL) {
8318
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8319
0
    (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8320
0
    xmlSchemaPIllegalAttrErr(ctxt,
8321
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8322
0
      }
8323
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8324
0
      xmlSchemaPIllegalAttrErr(ctxt,
8325
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8326
0
  }
8327
0
  attr = attr->next;
8328
0
    }
8329
    /*
8330
    * Create the item.
8331
    */
8332
0
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8333
0
    if (item == NULL) {
8334
0
        xmlSchemaPErrMemory(ctxt,
8335
0
      "allocating a 'selector' of an identity-constraint definition",
8336
0
      NULL);
8337
0
        return (NULL);
8338
0
    }
8339
0
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
8340
    /*
8341
    * Attribute "xpath" (mandatory).
8342
    */
8343
0
    attr = xmlSchemaGetPropNode(node, "xpath");
8344
0
    if (attr == NULL) {
8345
0
  xmlSchemaPMissingAttrErr(ctxt,
8346
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8347
0
      NULL, node,
8348
0
      "name", NULL);
8349
0
    } else {
8350
0
  item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8351
  /*
8352
  * URGENT TODO: "field"s have an other syntax than "selector"s.
8353
  */
8354
8355
0
  if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8356
0
      isField) == -1) {
8357
0
      xmlSchemaPErr(ctxt,
8358
0
    (xmlNodePtr) attr,
8359
0
    XML_SCHEMAP_INTERNAL,
8360
0
    "Internal error: xmlSchemaParseIDCSelectorAndField, "
8361
0
    "validating the XPath expression of a IDC selector.\n",
8362
0
    NULL, NULL);
8363
0
  }
8364
8365
0
    }
8366
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8367
    /*
8368
    * And now for the children...
8369
    */
8370
0
    child = node->children;
8371
0
    if (IS_SCHEMA(child, "annotation")) {
8372
  /*
8373
  * Add the annotation to the parent IDC.
8374
  */
8375
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8376
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8377
0
  child = child->next;
8378
0
    }
8379
0
    if (child != NULL) {
8380
0
  xmlSchemaPContentErr(ctxt,
8381
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8382
0
      NULL, node, child,
8383
0
      NULL, "(annotation?)");
8384
0
    }
8385
8386
0
    return (item);
8387
0
}
8388
8389
/**
8390
 * xmlSchemaParseIDC:
8391
 * @ctxt:  a schema validation context
8392
 * @schema:  the schema being built
8393
 * @node:  a subtree containing XML Schema information
8394
 *
8395
 * Parses a XML Schema identity-constraint definition.
8396
 *
8397
 * Returns the parsed identity-constraint definition.
8398
 */
8399
static xmlSchemaIDCPtr
8400
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8401
      xmlSchemaPtr schema,
8402
      xmlNodePtr node,
8403
      xmlSchemaTypeType idcCategory,
8404
      const xmlChar *targetNamespace)
8405
0
{
8406
0
    xmlSchemaIDCPtr item = NULL;
8407
0
    xmlNodePtr child = NULL;
8408
0
    xmlAttrPtr attr;
8409
0
    const xmlChar *name = NULL;
8410
0
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8411
8412
    /*
8413
    * Check for illegal attributes.
8414
    */
8415
0
    attr = node->properties;
8416
0
    while (attr != NULL) {
8417
0
  if (attr->ns == NULL) {
8418
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8419
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8420
0
    ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8421
0
     (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8422
0
    xmlSchemaPIllegalAttrErr(ctxt,
8423
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8424
0
      }
8425
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8426
0
      xmlSchemaPIllegalAttrErr(ctxt,
8427
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8428
0
  }
8429
0
  attr = attr->next;
8430
0
    }
8431
    /*
8432
    * Attribute "name" (mandatory).
8433
    */
8434
0
    attr = xmlSchemaGetPropNode(node, "name");
8435
0
    if (attr == NULL) {
8436
0
  xmlSchemaPMissingAttrErr(ctxt,
8437
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8438
0
      NULL, node,
8439
0
      "name", NULL);
8440
0
  return (NULL);
8441
0
    } else if (xmlSchemaPValAttrNode(ctxt,
8442
0
  NULL, attr,
8443
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8444
0
  return (NULL);
8445
0
    }
8446
    /* Create the component. */
8447
0
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8448
0
  idcCategory, node);
8449
0
    if (item == NULL)
8450
0
  return(NULL);
8451
8452
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8453
0
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8454
  /*
8455
  * Attribute "refer" (mandatory).
8456
  */
8457
0
  attr = xmlSchemaGetPropNode(node, "refer");
8458
0
  if (attr == NULL) {
8459
0
      xmlSchemaPMissingAttrErr(ctxt,
8460
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8461
0
    NULL, node,
8462
0
    "refer", NULL);
8463
0
  } else {
8464
      /*
8465
      * Create a reference item.
8466
      */
8467
0
      item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8468
0
    NULL, NULL);
8469
0
      if (item->ref == NULL)
8470
0
    return (NULL);
8471
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8472
0
    NULL, attr,
8473
0
    &(item->ref->targetNamespace),
8474
0
    &(item->ref->name));
8475
0
      xmlSchemaCheckReference(ctxt, schema, node, attr,
8476
0
    item->ref->targetNamespace);
8477
0
  }
8478
0
    }
8479
    /*
8480
    * And now for the children...
8481
    */
8482
0
    child = node->children;
8483
0
    if (IS_SCHEMA(child, "annotation")) {
8484
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8485
0
  child = child->next;
8486
0
    }
8487
0
    if (child == NULL) {
8488
0
  xmlSchemaPContentErr(ctxt,
8489
0
    XML_SCHEMAP_S4S_ELEM_MISSING,
8490
0
    NULL, node, child,
8491
0
    "A child element is missing",
8492
0
    "(annotation?, (selector, field+))");
8493
0
    }
8494
    /*
8495
    * Child element <selector>.
8496
    */
8497
0
    if (IS_SCHEMA(child, "selector")) {
8498
0
  item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8499
0
      item, child, 0);
8500
0
  child = child->next;
8501
  /*
8502
  * Child elements <field>.
8503
  */
8504
0
  if (IS_SCHEMA(child, "field")) {
8505
0
      do {
8506
0
    field = xmlSchemaParseIDCSelectorAndField(ctxt,
8507
0
        item, child, 1);
8508
0
    if (field != NULL) {
8509
0
        field->index = item->nbFields;
8510
0
        item->nbFields++;
8511
0
        if (lastField != NULL)
8512
0
      lastField->next = field;
8513
0
        else
8514
0
      item->fields = field;
8515
0
        lastField = field;
8516
0
    }
8517
0
    child = child->next;
8518
0
      } while (IS_SCHEMA(child, "field"));
8519
0
  } else {
8520
0
      xmlSchemaPContentErr(ctxt,
8521
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8522
0
    NULL, node, child,
8523
0
    NULL, "(annotation?, (selector, field+))");
8524
0
  }
8525
0
    }
8526
0
    if (child != NULL) {
8527
0
  xmlSchemaPContentErr(ctxt,
8528
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8529
0
      NULL, node, child,
8530
0
      NULL, "(annotation?, (selector, field+))");
8531
0
    }
8532
8533
0
    return (item);
8534
0
}
8535
8536
/**
8537
 * xmlSchemaParseElement:
8538
 * @ctxt:  a schema validation context
8539
 * @schema:  the schema being built
8540
 * @node:  a subtree containing XML Schema information
8541
 * @topLevel: indicates if this is global declaration
8542
 *
8543
 * Parses a XML schema element declaration.
8544
 * *WARNING* this interface is highly subject to change
8545
 *
8546
 * Returns the element declaration or a particle; NULL in case
8547
 * of an error or if the particle has minOccurs==maxOccurs==0.
8548
 */
8549
static xmlSchemaBasicItemPtr
8550
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8551
                      xmlNodePtr node, int *isElemRef, int topLevel)
8552
0
{
8553
0
    xmlSchemaElementPtr decl = NULL;
8554
0
    xmlSchemaParticlePtr particle = NULL;
8555
0
    xmlSchemaAnnotPtr annot = NULL;
8556
0
    xmlNodePtr child = NULL;
8557
0
    xmlAttrPtr attr, nameAttr;
8558
0
    int min, max, isRef = 0;
8559
0
    xmlChar *des = NULL;
8560
8561
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
8562
    /* TODO: Complete implementation of 3.3.6 */
8563
8564
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8565
0
        return (NULL);
8566
8567
0
    if (isElemRef != NULL)
8568
0
  *isElemRef = 0;
8569
    /*
8570
    * If we get a "ref" attribute on a local <element> we will assume it's
8571
    * a reference - even if there's a "name" attribute; this seems to be more
8572
    * robust.
8573
    */
8574
0
    nameAttr = xmlSchemaGetPropNode(node, "name");
8575
0
    attr = xmlSchemaGetPropNode(node, "ref");
8576
0
    if ((topLevel) || (attr == NULL)) {
8577
0
  if (nameAttr == NULL) {
8578
0
      xmlSchemaPMissingAttrErr(ctxt,
8579
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8580
0
    NULL, node, "name", NULL);
8581
0
      return (NULL);
8582
0
  }
8583
0
    } else
8584
0
  isRef = 1;
8585
8586
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8587
0
    child = node->children;
8588
0
    if (IS_SCHEMA(child, "annotation")) {
8589
0
  annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8590
0
  child = child->next;
8591
0
    }
8592
    /*
8593
    * Skip particle part if a global declaration.
8594
    */
8595
0
    if (topLevel)
8596
0
  goto declaration_part;
8597
    /*
8598
    * The particle part ==================================================
8599
    */
8600
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8601
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8602
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8603
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
8604
0
    if (particle == NULL)
8605
0
  goto return_null;
8606
8607
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8608
8609
0
    if (isRef) {
8610
0
  const xmlChar *refNs = NULL, *ref = NULL;
8611
0
  xmlSchemaQNameRefPtr refer = NULL;
8612
  /*
8613
  * The reference part =============================================
8614
  */
8615
0
  if (isElemRef != NULL)
8616
0
      *isElemRef = 1;
8617
8618
0
  xmlSchemaPValAttrNodeQName(ctxt, schema,
8619
0
      NULL, attr, &refNs, &ref);
8620
0
  xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8621
  /*
8622
  * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8623
  */
8624
0
  if (nameAttr != NULL) {
8625
0
      xmlSchemaPMutualExclAttrErr(ctxt,
8626
0
    XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8627
0
  }
8628
  /*
8629
  * Check for illegal attributes.
8630
  */
8631
0
  attr = node->properties;
8632
0
  while (attr != NULL) {
8633
0
      if (attr->ns == NULL) {
8634
0
    if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8635
0
        xmlStrEqual(attr->name, BAD_CAST "name") ||
8636
0
        xmlStrEqual(attr->name, BAD_CAST "id") ||
8637
0
        xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8638
0
        xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8639
0
    {
8640
0
        attr = attr->next;
8641
0
        continue;
8642
0
    } else {
8643
        /* SPEC (3.3.3 : 2.2) */
8644
0
        xmlSchemaPCustomAttrErr(ctxt,
8645
0
      XML_SCHEMAP_SRC_ELEMENT_2_2,
8646
0
      NULL, NULL, attr,
8647
0
      "Only the attributes 'minOccurs', 'maxOccurs' and "
8648
0
      "'id' are allowed in addition to 'ref'");
8649
0
        break;
8650
0
    }
8651
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8652
0
    xmlSchemaPIllegalAttrErr(ctxt,
8653
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8654
0
      }
8655
0
      attr = attr->next;
8656
0
  }
8657
  /*
8658
  * No children except <annotation> expected.
8659
  */
8660
0
  if (child != NULL) {
8661
0
      xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8662
0
    NULL, node, child, NULL, "(annotation?)");
8663
0
  }
8664
0
  if ((min == 0) && (max == 0))
8665
0
      goto return_null;
8666
  /*
8667
  * Create the reference item and attach it to the particle.
8668
  */
8669
0
  refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8670
0
      ref, refNs);
8671
0
  if (refer == NULL)
8672
0
      goto return_null;
8673
0
  particle->children = (xmlSchemaTreeItemPtr) refer;
8674
0
  particle->annot = annot;
8675
  /*
8676
  * Add the particle to pending components, since the reference
8677
  * need to be resolved.
8678
  */
8679
0
  WXS_ADD_PENDING(ctxt, particle);
8680
0
  return ((xmlSchemaBasicItemPtr) particle);
8681
0
    }
8682
    /*
8683
    * The declaration part ===============================================
8684
    */
8685
0
declaration_part:
8686
0
    {
8687
0
  const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8688
0
  xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8689
8690
0
  if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8691
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8692
0
      goto return_null;
8693
  /*
8694
  * Evaluate the target namespace.
8695
  */
8696
0
  if (topLevel) {
8697
0
      ns = ctxt->targetNamespace;
8698
0
  } else {
8699
0
      attr = xmlSchemaGetPropNode(node, "form");
8700
0
      if (attr != NULL) {
8701
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8702
0
    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8703
0
        ns = ctxt->targetNamespace;
8704
0
    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8705
0
        xmlSchemaPSimpleTypeErr(ctxt,
8706
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8707
0
      NULL, (xmlNodePtr) attr,
8708
0
      NULL, "(qualified | unqualified)",
8709
0
      attrValue, NULL, NULL, NULL);
8710
0
    }
8711
0
      } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8712
0
    ns = ctxt->targetNamespace;
8713
0
  }
8714
0
  decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8715
0
  if (decl == NULL) {
8716
0
      goto return_null;
8717
0
  }
8718
  /*
8719
  * Check for illegal attributes.
8720
  */
8721
0
  attr = node->properties;
8722
0
  while (attr != NULL) {
8723
0
      if (attr->ns == NULL) {
8724
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8725
0
        (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8726
0
        (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8727
0
        (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8728
0
        (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8729
0
        (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8730
0
        (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8731
0
    {
8732
0
        if (topLevel == 0) {
8733
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8734
0
          (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8735
0
          (!xmlStrEqual(attr->name, BAD_CAST "form")))
8736
0
      {
8737
0
          xmlSchemaPIllegalAttrErr(ctxt,
8738
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8739
0
      }
8740
0
        } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8741
0
      (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8742
0
      (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8743
8744
0
      xmlSchemaPIllegalAttrErr(ctxt,
8745
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8746
0
        }
8747
0
    }
8748
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8749
8750
0
    xmlSchemaPIllegalAttrErr(ctxt,
8751
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8752
0
      }
8753
0
      attr = attr->next;
8754
0
  }
8755
  /*
8756
  * Extract/validate attributes.
8757
  */
8758
0
  if (topLevel) {
8759
      /*
8760
      * Process top attributes of global element declarations here.
8761
      */
8762
0
      decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8763
0
      decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8764
0
      xmlSchemaPValAttrQName(ctxt, schema,
8765
0
    NULL, node, "substitutionGroup",
8766
0
    &(decl->substGroupNs), &(decl->substGroup));
8767
0
      if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8768
0
    decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8769
      /*
8770
      * Attribute "final".
8771
      */
8772
0
      attr = xmlSchemaGetPropNode(node, "final");
8773
0
      if (attr == NULL) {
8774
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8775
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8776
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8777
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8778
0
      } else {
8779
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8780
0
    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8781
0
        -1,
8782
0
        XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8783
0
        XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8784
0
        xmlSchemaPSimpleTypeErr(ctxt,
8785
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8786
0
      NULL, (xmlNodePtr) attr,
8787
0
      NULL, "(#all | List of (extension | restriction))",
8788
0
      attrValue, NULL, NULL, NULL);
8789
0
    }
8790
0
      }
8791
0
  }
8792
  /*
8793
  * Attribute "block".
8794
  */
8795
0
  attr = xmlSchemaGetPropNode(node, "block");
8796
0
  if (attr == NULL) {
8797
      /*
8798
      * Apply default "block" values.
8799
      */
8800
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8801
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8802
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8803
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8804
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8805
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8806
0
  } else {
8807
0
      attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8808
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8809
0
    -1,
8810
0
    XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8811
0
    XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8812
0
    XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8813
0
    xmlSchemaPSimpleTypeErr(ctxt,
8814
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8815
0
        NULL, (xmlNodePtr) attr,
8816
0
        NULL, "(#all | List of (extension | "
8817
0
        "restriction | substitution))", attrValue,
8818
0
        NULL, NULL, NULL);
8819
0
      }
8820
0
  }
8821
0
  if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8822
0
      decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8823
8824
0
  attr = xmlSchemaGetPropNode(node, "type");
8825
0
  if (attr != NULL) {
8826
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8827
0
    NULL, attr,
8828
0
    &(decl->namedTypeNs), &(decl->namedType));
8829
0
      xmlSchemaCheckReference(ctxt, schema, node,
8830
0
    attr, decl->namedTypeNs);
8831
0
  }
8832
0
  decl->value = xmlSchemaGetProp(ctxt, node, "default");
8833
0
  attr = xmlSchemaGetPropNode(node, "fixed");
8834
0
  if (attr != NULL) {
8835
0
      fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8836
0
      if (decl->value != NULL) {
8837
    /*
8838
    * 3.3.3 : 1
8839
    * default and fixed must not both be present.
8840
    */
8841
0
    xmlSchemaPMutualExclAttrErr(ctxt,
8842
0
        XML_SCHEMAP_SRC_ELEMENT_1,
8843
0
        NULL, attr, "default", "fixed");
8844
0
      } else {
8845
0
    decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8846
0
    decl->value = fixed;
8847
0
      }
8848
0
  }
8849
  /*
8850
  * And now for the children...
8851
  */
8852
0
  if (IS_SCHEMA(child, "complexType")) {
8853
      /*
8854
      * 3.3.3 : 3
8855
      * "type" and either <simpleType> or <complexType> are mutually
8856
      * exclusive
8857
      */
8858
0
      if (decl->namedType != NULL) {
8859
0
    xmlSchemaPContentErr(ctxt,
8860
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8861
0
        NULL, node, child,
8862
0
        "The attribute 'type' and the <complexType> child are "
8863
0
        "mutually exclusive", NULL);
8864
0
      } else
8865
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8866
0
      child = child->next;
8867
0
  } else if (IS_SCHEMA(child, "simpleType")) {
8868
      /*
8869
      * 3.3.3 : 3
8870
      * "type" and either <simpleType> or <complexType> are
8871
      * mutually exclusive
8872
      */
8873
0
      if (decl->namedType != NULL) {
8874
0
    xmlSchemaPContentErr(ctxt,
8875
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8876
0
        NULL, node, child,
8877
0
        "The attribute 'type' and the <simpleType> child are "
8878
0
        "mutually exclusive", NULL);
8879
0
      } else
8880
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8881
0
      child = child->next;
8882
0
  }
8883
0
  while ((IS_SCHEMA(child, "unique")) ||
8884
0
      (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8885
0
      if (IS_SCHEMA(child, "unique")) {
8886
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8887
0
        XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8888
0
      } else if (IS_SCHEMA(child, "key")) {
8889
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8890
0
        XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8891
0
      } else if (IS_SCHEMA(child, "keyref")) {
8892
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8893
0
        XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8894
0
      }
8895
0
      if (lastIDC != NULL)
8896
0
    lastIDC->next = curIDC;
8897
0
      else
8898
0
    decl->idcs = (void *) curIDC;
8899
0
      lastIDC = curIDC;
8900
0
      child = child->next;
8901
0
  }
8902
0
  if (child != NULL) {
8903
0
      xmlSchemaPContentErr(ctxt,
8904
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8905
0
    NULL, node, child,
8906
0
    NULL, "(annotation?, ((simpleType | complexType)?, "
8907
0
    "(unique | key | keyref)*))");
8908
0
  }
8909
0
  decl->annot = annot;
8910
0
    }
8911
    /*
8912
    * NOTE: Element Declaration Representation OK 4. will be checked at a
8913
    * different layer.
8914
    */
8915
0
    FREE_AND_NULL(des)
8916
0
    if (topLevel)
8917
0
  return ((xmlSchemaBasicItemPtr) decl);
8918
0
    else {
8919
0
  particle->children = (xmlSchemaTreeItemPtr) decl;
8920
0
  return ((xmlSchemaBasicItemPtr) particle);
8921
0
    }
8922
8923
0
return_null:
8924
0
    FREE_AND_NULL(des);
8925
0
    if (annot != NULL) {
8926
0
  if (particle != NULL)
8927
0
      particle->annot = NULL;
8928
0
  if (decl != NULL)
8929
0
      decl->annot = NULL;
8930
0
  xmlSchemaFreeAnnot(annot);
8931
0
    }
8932
0
    return (NULL);
8933
0
}
8934
8935
/**
8936
 * xmlSchemaParseUnion:
8937
 * @ctxt:  a schema validation context
8938
 * @schema:  the schema being built
8939
 * @node:  a subtree containing XML Schema information
8940
 *
8941
 * parse a XML schema Union definition
8942
 * *WARNING* this interface is highly subject to change
8943
 *
8944
 * Returns -1 in case of internal error, 0 in case of success and a positive
8945
 * error code otherwise.
8946
 */
8947
static int
8948
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8949
                    xmlNodePtr node)
8950
0
{
8951
0
    xmlSchemaTypePtr type;
8952
0
    xmlNodePtr child = NULL;
8953
0
    xmlAttrPtr attr;
8954
0
    const xmlChar *cur = NULL;
8955
8956
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8957
0
        return (-1);
8958
    /* Not a component, don't create it. */
8959
0
    type = ctxt->ctxtType;
8960
    /*
8961
    * Mark the simple type as being of variety "union".
8962
    */
8963
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8964
    /*
8965
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8966
    * then the `simple ur-type definition`."
8967
    */
8968
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8969
    /*
8970
    * Check for illegal attributes.
8971
    */
8972
0
    attr = node->properties;
8973
0
    while (attr != NULL) {
8974
0
  if (attr->ns == NULL) {
8975
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8976
0
    (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8977
0
    xmlSchemaPIllegalAttrErr(ctxt,
8978
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8979
0
      }
8980
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8981
0
      xmlSchemaPIllegalAttrErr(ctxt,
8982
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8983
0
  }
8984
0
  attr = attr->next;
8985
0
    }
8986
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8987
    /*
8988
    * Attribute "memberTypes". This is a list of QNames.
8989
    * TODO: Check the value to contain anything.
8990
    */
8991
0
    attr = xmlSchemaGetPropNode(node, "memberTypes");
8992
0
    if (attr != NULL) {
8993
0
  const xmlChar *end;
8994
0
  xmlChar *tmp;
8995
0
  const xmlChar *localName, *nsName;
8996
0
  xmlSchemaTypeLinkPtr link, lastLink = NULL;
8997
0
  xmlSchemaQNameRefPtr ref;
8998
8999
0
  cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9000
0
  type->base = cur;
9001
0
  do {
9002
0
      while (IS_BLANK_CH(*cur))
9003
0
    cur++;
9004
0
      end = cur;
9005
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
9006
0
    end++;
9007
0
      if (end == cur)
9008
0
    break;
9009
0
      tmp = xmlStrndup(cur, end - cur);
9010
0
      if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
9011
0
    NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
9012
    /*
9013
    * Create the member type link.
9014
    */
9015
0
    link = (xmlSchemaTypeLinkPtr)
9016
0
        xmlMalloc(sizeof(xmlSchemaTypeLink));
9017
0
    if (link == NULL) {
9018
0
        xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
9019
0
      "allocating a type link", NULL);
9020
0
        return (-1);
9021
0
    }
9022
0
    link->type = NULL;
9023
0
    link->next = NULL;
9024
0
    if (lastLink == NULL)
9025
0
        type->memberTypes = link;
9026
0
    else
9027
0
        lastLink->next = link;
9028
0
    lastLink = link;
9029
    /*
9030
    * Create a reference item.
9031
    */
9032
0
    ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
9033
0
        localName, nsName);
9034
0
    if (ref == NULL) {
9035
0
        FREE_AND_NULL(tmp)
9036
0
        return (-1);
9037
0
    }
9038
    /*
9039
    * Assign the reference to the link, it will be resolved
9040
    * later during fixup of the union simple type.
9041
    */
9042
0
    link->type = (xmlSchemaTypePtr) ref;
9043
0
      }
9044
0
      FREE_AND_NULL(tmp)
9045
0
      cur = end;
9046
0
  } while (*cur != 0);
9047
9048
0
    }
9049
    /*
9050
    * And now for the children...
9051
    */
9052
0
    child = node->children;
9053
0
    if (IS_SCHEMA(child, "annotation")) {
9054
  /*
9055
  * Add the annotation to the simple type ancestor.
9056
  */
9057
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9058
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
9059
0
        child = child->next;
9060
0
    }
9061
0
    if (IS_SCHEMA(child, "simpleType")) {
9062
0
  xmlSchemaTypePtr subtype, last = NULL;
9063
9064
  /*
9065
  * Anchor the member types in the "subtypes" field of the
9066
  * simple type.
9067
  */
9068
0
  while (IS_SCHEMA(child, "simpleType")) {
9069
0
      subtype = (xmlSchemaTypePtr)
9070
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9071
0
      if (subtype != NULL) {
9072
0
    if (last == NULL) {
9073
0
        type->subtypes = subtype;
9074
0
        last = subtype;
9075
0
    } else {
9076
0
        last->next = subtype;
9077
0
        last = subtype;
9078
0
    }
9079
0
    last->next = NULL;
9080
0
      }
9081
0
      child = child->next;
9082
0
  }
9083
0
    }
9084
0
    if (child != NULL) {
9085
0
  xmlSchemaPContentErr(ctxt,
9086
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9087
0
      NULL, node, child, NULL, "(annotation?, simpleType*)");
9088
0
    }
9089
0
    if ((attr == NULL) && (type->subtypes == NULL)) {
9090
   /*
9091
  * src-union-memberTypes-or-simpleTypes
9092
  * Either the memberTypes [attribute] of the <union> element must
9093
  * be non-empty or there must be at least one simpleType [child].
9094
  */
9095
0
  xmlSchemaPCustomErr(ctxt,
9096
0
      XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
9097
0
      NULL, node,
9098
0
      "Either the attribute 'memberTypes' or "
9099
0
      "at least one <simpleType> child must be present", NULL);
9100
0
    }
9101
0
    return (0);
9102
0
}
9103
9104
/**
9105
 * xmlSchemaParseList:
9106
 * @ctxt:  a schema validation context
9107
 * @schema:  the schema being built
9108
 * @node:  a subtree containing XML Schema information
9109
 *
9110
 * parse a XML schema List definition
9111
 * *WARNING* this interface is highly subject to change
9112
 *
9113
 * Returns -1 in case of error, 0 if the declaration is improper and
9114
 *         1 in case of success.
9115
 */
9116
static xmlSchemaTypePtr
9117
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9118
                   xmlNodePtr node)
9119
0
{
9120
0
    xmlSchemaTypePtr type;
9121
0
    xmlNodePtr child = NULL;
9122
0
    xmlAttrPtr attr;
9123
9124
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9125
0
        return (NULL);
9126
    /* Not a component, don't create it. */
9127
0
    type = ctxt->ctxtType;
9128
    /*
9129
    * Mark the type as being of variety "list".
9130
    */
9131
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9132
    /*
9133
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9134
    * then the `simple ur-type definition`."
9135
    */
9136
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9137
    /*
9138
    * Check for illegal attributes.
9139
    */
9140
0
    attr = node->properties;
9141
0
    while (attr != NULL) {
9142
0
  if (attr->ns == NULL) {
9143
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9144
0
    (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
9145
0
    xmlSchemaPIllegalAttrErr(ctxt,
9146
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9147
0
      }
9148
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9149
0
      xmlSchemaPIllegalAttrErr(ctxt,
9150
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9151
0
  }
9152
0
  attr = attr->next;
9153
0
    }
9154
9155
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9156
9157
    /*
9158
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9159
    * fields for holding the reference to the itemType.
9160
    *
9161
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9162
    * the "ref" fields.
9163
    */
9164
0
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
9165
0
  node, "itemType", &(type->baseNs), &(type->base));
9166
    /*
9167
    * And now for the children...
9168
    */
9169
0
    child = node->children;
9170
0
    if (IS_SCHEMA(child, "annotation")) {
9171
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9172
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
9173
0
        child = child->next;
9174
0
    }
9175
0
    if (IS_SCHEMA(child, "simpleType")) {
9176
  /*
9177
  * src-list-itemType-or-simpleType
9178
  * Either the itemType [attribute] or the <simpleType> [child] of
9179
  * the <list> element must be present, but not both.
9180
  */
9181
0
  if (type->base != NULL) {
9182
0
      xmlSchemaPCustomErr(ctxt,
9183
0
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9184
0
    NULL, node,
9185
0
    "The attribute 'itemType' and the <simpleType> child "
9186
0
    "are mutually exclusive", NULL);
9187
0
  } else {
9188
0
      type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9189
0
  }
9190
0
        child = child->next;
9191
0
    } else if (type->base == NULL) {
9192
0
  xmlSchemaPCustomErr(ctxt,
9193
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9194
0
      NULL, node,
9195
0
      "Either the attribute 'itemType' or the <simpleType> child "
9196
0
      "must be present", NULL);
9197
0
    }
9198
0
    if (child != NULL) {
9199
0
  xmlSchemaPContentErr(ctxt,
9200
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9201
0
      NULL, node, child, NULL, "(annotation?, simpleType?)");
9202
0
    }
9203
0
    if ((type->base == NULL) &&
9204
0
  (type->subtypes == NULL) &&
9205
0
  (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9206
0
  xmlSchemaPCustomErr(ctxt,
9207
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9208
0
      NULL, node,
9209
0
      "Either the attribute 'itemType' or the <simpleType> child "
9210
0
      "must be present", NULL);
9211
0
    }
9212
0
    return (NULL);
9213
0
}
9214
9215
/**
9216
 * xmlSchemaParseSimpleType:
9217
 * @ctxt:  a schema validation context
9218
 * @schema:  the schema being built
9219
 * @node:  a subtree containing XML Schema information
9220
 *
9221
 * parse a XML schema Simple Type definition
9222
 * *WARNING* this interface is highly subject to change
9223
 *
9224
 * Returns -1 in case of error, 0 if the declaration is improper and
9225
 * 1 in case of success.
9226
 */
9227
static xmlSchemaTypePtr
9228
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9229
                         xmlNodePtr node, int topLevel)
9230
0
{
9231
0
    xmlSchemaTypePtr type, oldCtxtType;
9232
0
    xmlNodePtr child = NULL;
9233
0
    const xmlChar *attrValue = NULL;
9234
0
    xmlAttrPtr attr;
9235
0
    int hasRestriction = 0;
9236
9237
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9238
0
        return (NULL);
9239
9240
0
    if (topLevel) {
9241
0
  attr = xmlSchemaGetPropNode(node, "name");
9242
0
  if (attr == NULL) {
9243
0
      xmlSchemaPMissingAttrErr(ctxt,
9244
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
9245
0
    NULL, node,
9246
0
    "name", NULL);
9247
0
      return (NULL);
9248
0
  } else {
9249
0
      if (xmlSchemaPValAttrNode(ctxt,
9250
0
    NULL, attr,
9251
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9252
0
    return (NULL);
9253
      /*
9254
      * Skip built-in types.
9255
      */
9256
0
      if (ctxt->isS4S) {
9257
0
    xmlSchemaTypePtr biType;
9258
9259
0
    if (ctxt->isRedefine) {
9260
        /*
9261
        * REDEFINE: Disallow redefinition of built-in-types.
9262
        * TODO: It seems that the spec does not say anything
9263
        * about this case.
9264
        */
9265
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9266
0
      NULL, node,
9267
0
      "Redefinition of built-in simple types is not "
9268
0
      "supported", NULL);
9269
0
        return(NULL);
9270
0
    }
9271
0
    biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9272
0
    if (biType != NULL)
9273
0
        return (biType);
9274
0
      }
9275
0
  }
9276
0
    }
9277
    /*
9278
    * TargetNamespace:
9279
    * SPEC "The `actual value` of the targetNamespace [attribute]
9280
    * of the <schema> ancestor element information item if present,
9281
    * otherwise `absent`.
9282
    */
9283
0
    if (topLevel == 0) {
9284
#ifdef ENABLE_NAMED_LOCALS
9285
        char buf[40];
9286
#endif
9287
  /*
9288
  * Parse as local simple type definition.
9289
  */
9290
#ifdef ENABLE_NAMED_LOCALS
9291
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9292
  type = xmlSchemaAddType(ctxt, schema,
9293
      XML_SCHEMA_TYPE_SIMPLE,
9294
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9295
      ctxt->targetNamespace, node, 0);
9296
#else
9297
0
  type = xmlSchemaAddType(ctxt, schema,
9298
0
      XML_SCHEMA_TYPE_SIMPLE,
9299
0
      NULL, ctxt->targetNamespace, node, 0);
9300
0
#endif
9301
0
  if (type == NULL)
9302
0
      return (NULL);
9303
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9304
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9305
  /*
9306
  * Check for illegal attributes.
9307
  */
9308
0
  attr = node->properties;
9309
0
  while (attr != NULL) {
9310
0
      if (attr->ns == NULL) {
9311
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9312
0
        xmlSchemaPIllegalAttrErr(ctxt,
9313
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9314
0
    }
9315
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9316
0
        xmlSchemaPIllegalAttrErr(ctxt,
9317
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9318
0
      }
9319
0
      attr = attr->next;
9320
0
  }
9321
0
    } else {
9322
  /*
9323
  * Parse as global simple type definition.
9324
  *
9325
  * Note that attrValue is the value of the attribute "name" here.
9326
  */
9327
0
  type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9328
0
      attrValue, ctxt->targetNamespace, node, 1);
9329
0
  if (type == NULL)
9330
0
      return (NULL);
9331
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9332
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9333
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9334
  /*
9335
  * Check for illegal attributes.
9336
  */
9337
0
  attr = node->properties;
9338
0
  while (attr != NULL) {
9339
0
      if (attr->ns == NULL) {
9340
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9341
0
        (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9342
0
        (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9343
0
        xmlSchemaPIllegalAttrErr(ctxt,
9344
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9345
0
    }
9346
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9347
0
    xmlSchemaPIllegalAttrErr(ctxt,
9348
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9349
0
      }
9350
0
      attr = attr->next;
9351
0
  }
9352
  /*
9353
  * Attribute "final".
9354
  */
9355
0
  attr = xmlSchemaGetPropNode(node, "final");
9356
0
  if (attr == NULL) {
9357
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9358
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9359
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9360
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9361
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9362
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9363
0
  } else {
9364
0
      attrValue = xmlSchemaGetProp(ctxt, node, "final");
9365
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9366
0
    -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9367
0
    XML_SCHEMAS_TYPE_FINAL_LIST,
9368
0
    XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9369
9370
0
    xmlSchemaPSimpleTypeErr(ctxt,
9371
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9372
0
        WXS_BASIC_CAST type, (xmlNodePtr) attr,
9373
0
        NULL, "(#all | List of (list | union | restriction)",
9374
0
        attrValue, NULL, NULL, NULL);
9375
0
      }
9376
0
  }
9377
0
    }
9378
0
    type->targetNamespace = ctxt->targetNamespace;
9379
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9380
    /*
9381
    * And now for the children...
9382
    */
9383
0
    oldCtxtType = ctxt->ctxtType;
9384
9385
0
    ctxt->ctxtType = type;
9386
9387
0
    child = node->children;
9388
0
    if (IS_SCHEMA(child, "annotation")) {
9389
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9390
0
        child = child->next;
9391
0
    }
9392
0
    if (child == NULL) {
9393
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9394
0
      NULL, node, child, NULL,
9395
0
      "(annotation?, (restriction | list | union))");
9396
0
    } else if (IS_SCHEMA(child, "restriction")) {
9397
0
        xmlSchemaParseRestriction(ctxt, schema, child,
9398
0
      XML_SCHEMA_TYPE_SIMPLE);
9399
0
  hasRestriction = 1;
9400
0
        child = child->next;
9401
0
    } else if (IS_SCHEMA(child, "list")) {
9402
0
        xmlSchemaParseList(ctxt, schema, child);
9403
0
        child = child->next;
9404
0
    } else if (IS_SCHEMA(child, "union")) {
9405
0
        xmlSchemaParseUnion(ctxt, schema, child);
9406
0
        child = child->next;
9407
0
    }
9408
0
    if (child != NULL) {
9409
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9410
0
      NULL, node, child, NULL,
9411
0
      "(annotation?, (restriction | list | union))");
9412
0
    }
9413
    /*
9414
    * REDEFINE: SPEC src-redefine (5)
9415
    * "Within the [children], each <simpleType> must have a
9416
    * <restriction> among its [children] ... the `actual value` of whose
9417
    * base [attribute] must be the same as the `actual value` of its own
9418
    * name attribute plus target namespace;"
9419
    */
9420
0
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9421
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9422
0
      NULL, node, "This is a redefinition, thus the "
9423
0
      "<simpleType> must have a <restriction> child", NULL);
9424
0
    }
9425
9426
0
    ctxt->ctxtType = oldCtxtType;
9427
0
    return (type);
9428
0
}
9429
9430
/**
9431
 * xmlSchemaParseModelGroupDefRef:
9432
 * @ctxt:  the parser context
9433
 * @schema: the schema being built
9434
 * @node:  the node
9435
 *
9436
 * Parses a reference to a model group definition.
9437
 *
9438
 * We will return a particle component with a qname-component or
9439
 * NULL in case of an error.
9440
 */
9441
static xmlSchemaTreeItemPtr
9442
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9443
             xmlSchemaPtr schema,
9444
             xmlNodePtr node)
9445
0
{
9446
0
    xmlSchemaParticlePtr item;
9447
0
    xmlNodePtr child = NULL;
9448
0
    xmlAttrPtr attr;
9449
0
    const xmlChar *ref = NULL, *refNs = NULL;
9450
0
    int min, max;
9451
9452
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9453
0
        return (NULL);
9454
9455
0
    attr = xmlSchemaGetPropNode(node, "ref");
9456
0
    if (attr == NULL) {
9457
0
  xmlSchemaPMissingAttrErr(ctxt,
9458
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9459
0
      NULL, node, "ref", NULL);
9460
0
  return (NULL);
9461
0
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9462
0
  attr, &refNs, &ref) != 0) {
9463
0
  return (NULL);
9464
0
    }
9465
0
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9466
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9467
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9468
0
  "(xs:nonNegativeInteger | unbounded)");
9469
    /*
9470
    * Check for illegal attributes.
9471
    */
9472
0
    attr = node->properties;
9473
0
    while (attr != NULL) {
9474
0
  if (attr->ns == NULL) {
9475
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9476
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9477
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9478
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9479
0
    xmlSchemaPIllegalAttrErr(ctxt,
9480
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9481
0
      }
9482
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9483
0
      xmlSchemaPIllegalAttrErr(ctxt,
9484
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9485
0
  }
9486
0
  attr = attr->next;
9487
0
    }
9488
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9489
0
    item = xmlSchemaAddParticle(ctxt, node, min, max);
9490
0
    if (item == NULL)
9491
0
  return (NULL);
9492
    /*
9493
    * Create a qname-reference and set as the term; it will be substituted
9494
    * for the model group after the reference has been resolved.
9495
    */
9496
0
    item->children = (xmlSchemaTreeItemPtr)
9497
0
  xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9498
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9499
    /*
9500
    * And now for the children...
9501
    */
9502
0
    child = node->children;
9503
    /* TODO: Is annotation even allowed for a model group reference? */
9504
0
    if (IS_SCHEMA(child, "annotation")) {
9505
  /*
9506
  * TODO: What to do exactly with the annotation?
9507
  */
9508
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9509
0
  child = child->next;
9510
0
    }
9511
0
    if (child != NULL) {
9512
0
  xmlSchemaPContentErr(ctxt,
9513
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9514
0
      NULL, node, child, NULL,
9515
0
      "(annotation?)");
9516
0
    }
9517
    /*
9518
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
9519
    */
9520
0
    if ((min == 0) && (max == 0))
9521
0
  return (NULL);
9522
9523
0
    return ((xmlSchemaTreeItemPtr) item);
9524
0
}
9525
9526
/**
9527
 * xmlSchemaParseModelGroupDefinition:
9528
 * @ctxt:  a schema validation context
9529
 * @schema:  the schema being built
9530
 * @node:  a subtree containing XML Schema information
9531
 *
9532
 * Parses a XML schema model group definition.
9533
 *
9534
 * Note that the constraint src-redefine (6.2) can't be applied until
9535
 * references have been resolved. So we will do this at the
9536
 * component fixup level.
9537
 *
9538
 * *WARNING* this interface is highly subject to change
9539
 *
9540
 * Returns -1 in case of error, 0 if the declaration is improper and
9541
 *         1 in case of success.
9542
 */
9543
static xmlSchemaModelGroupDefPtr
9544
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9545
           xmlSchemaPtr schema,
9546
           xmlNodePtr node)
9547
0
{
9548
0
    xmlSchemaModelGroupDefPtr item;
9549
0
    xmlNodePtr child = NULL;
9550
0
    xmlAttrPtr attr;
9551
0
    const xmlChar *name;
9552
9553
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9554
0
        return (NULL);
9555
9556
0
    attr = xmlSchemaGetPropNode(node, "name");
9557
0
    if (attr == NULL) {
9558
0
  xmlSchemaPMissingAttrErr(ctxt,
9559
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9560
0
      NULL, node,
9561
0
      "name", NULL);
9562
0
  return (NULL);
9563
0
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9564
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9565
0
  return (NULL);
9566
0
    }
9567
0
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9568
0
  ctxt->targetNamespace, node);
9569
0
    if (item == NULL)
9570
0
  return (NULL);
9571
    /*
9572
    * Check for illegal attributes.
9573
    */
9574
0
    attr = node->properties;
9575
0
    while (attr != NULL) {
9576
0
  if (attr->ns == NULL) {
9577
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9578
0
    (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9579
0
    xmlSchemaPIllegalAttrErr(ctxt,
9580
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9581
0
      }
9582
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9583
0
      xmlSchemaPIllegalAttrErr(ctxt,
9584
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9585
0
  }
9586
0
  attr = attr->next;
9587
0
    }
9588
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9589
    /*
9590
    * And now for the children...
9591
    */
9592
0
    child = node->children;
9593
0
    if (IS_SCHEMA(child, "annotation")) {
9594
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9595
0
  child = child->next;
9596
0
    }
9597
0
    if (IS_SCHEMA(child, "all")) {
9598
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9599
0
      XML_SCHEMA_TYPE_ALL, 0);
9600
0
  child = child->next;
9601
0
    } else if (IS_SCHEMA(child, "choice")) {
9602
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9603
0
      XML_SCHEMA_TYPE_CHOICE, 0);
9604
0
  child = child->next;
9605
0
    } else if (IS_SCHEMA(child, "sequence")) {
9606
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9607
0
      XML_SCHEMA_TYPE_SEQUENCE, 0);
9608
0
  child = child->next;
9609
0
    }
9610
9611
9612
9613
0
    if (child != NULL) {
9614
0
  xmlSchemaPContentErr(ctxt,
9615
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9616
0
      NULL, node, child, NULL,
9617
0
      "(annotation?, (all | choice | sequence)?)");
9618
0
    }
9619
0
    return (item);
9620
0
}
9621
9622
/**
9623
 * xmlSchemaCleanupDoc:
9624
 * @ctxt:  a schema validation context
9625
 * @node:  the root of the document.
9626
 *
9627
 * removes unwanted nodes in a schemas document tree
9628
 */
9629
static void
9630
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9631
0
{
9632
0
    xmlNodePtr delete, cur;
9633
9634
0
    if ((ctxt == NULL) || (root == NULL)) return;
9635
9636
    /*
9637
     * Remove all the blank text nodes
9638
     */
9639
0
    delete = NULL;
9640
0
    cur = root;
9641
0
    while (cur != NULL) {
9642
0
        if (delete != NULL) {
9643
0
            xmlUnlinkNode(delete);
9644
0
            xmlFreeNode(delete);
9645
0
            delete = NULL;
9646
0
        }
9647
0
        if (cur->type == XML_TEXT_NODE) {
9648
0
            if (IS_BLANK_NODE(cur)) {
9649
0
                if (xmlNodeGetSpacePreserve(cur) != 1) {
9650
0
                    delete = cur;
9651
0
                }
9652
0
            }
9653
0
        } else if ((cur->type != XML_ELEMENT_NODE) &&
9654
0
                   (cur->type != XML_CDATA_SECTION_NODE)) {
9655
0
            delete = cur;
9656
0
            goto skip_children;
9657
0
        }
9658
9659
        /*
9660
         * Skip to next node
9661
         */
9662
0
        if (cur->children != NULL) {
9663
0
            if ((cur->children->type != XML_ENTITY_DECL) &&
9664
0
                (cur->children->type != XML_ENTITY_REF_NODE) &&
9665
0
                (cur->children->type != XML_ENTITY_NODE)) {
9666
0
                cur = cur->children;
9667
0
                continue;
9668
0
            }
9669
0
        }
9670
0
      skip_children:
9671
0
        if (cur->next != NULL) {
9672
0
            cur = cur->next;
9673
0
            continue;
9674
0
        }
9675
9676
0
        do {
9677
0
            cur = cur->parent;
9678
0
            if (cur == NULL)
9679
0
                break;
9680
0
            if (cur == root) {
9681
0
                cur = NULL;
9682
0
                break;
9683
0
            }
9684
0
            if (cur->next != NULL) {
9685
0
                cur = cur->next;
9686
0
                break;
9687
0
            }
9688
0
        } while (cur != NULL);
9689
0
    }
9690
0
    if (delete != NULL) {
9691
0
        xmlUnlinkNode(delete);
9692
0
        xmlFreeNode(delete);
9693
0
        delete = NULL;
9694
0
    }
9695
0
}
9696
9697
9698
static void
9699
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9700
0
{
9701
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9702
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9703
9704
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9705
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9706
9707
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9708
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9709
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9710
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9711
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9712
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9713
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9714
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9715
9716
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9717
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9718
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9719
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9720
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9721
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9722
0
}
9723
9724
static int
9725
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9726
           xmlSchemaPtr schema,
9727
           xmlNodePtr node)
9728
0
{
9729
0
    xmlAttrPtr attr;
9730
0
    const xmlChar *val;
9731
0
    int res = 0, oldErrs = ctxt->nberrors;
9732
9733
    /*
9734
    * Those flags should be moved to the parser context flags,
9735
    * since they are not visible at the component level. I.e.
9736
    * they are used if processing schema *documents* only.
9737
    */
9738
0
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9739
0
    HFAILURE;
9740
9741
    /*
9742
    * Since the version is of type xs:token, we won't bother to
9743
    * check it.
9744
    */
9745
    /* REMOVED:
9746
    attr = xmlSchemaGetPropNode(node, "version");
9747
    if (attr != NULL) {
9748
  res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9749
      xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9750
  HFAILURE;
9751
    }
9752
    */
9753
0
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
9754
0
    if (attr != NULL) {
9755
0
  res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9756
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9757
0
  HFAILURE;
9758
0
  if (res != 0) {
9759
0
      ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9760
0
      goto exit;
9761
0
  }
9762
0
    }
9763
0
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9764
0
    if (attr != NULL) {
9765
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9766
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9767
0
      XML_SCHEMAS_QUALIF_ELEM);
9768
0
  HFAILURE;
9769
0
  if (res != 0) {
9770
0
      xmlSchemaPSimpleTypeErr(ctxt,
9771
0
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9772
0
    NULL, (xmlNodePtr) attr, NULL,
9773
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9774
0
  }
9775
0
    }
9776
0
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9777
0
    if (attr != NULL) {
9778
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9779
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9780
0
      XML_SCHEMAS_QUALIF_ATTR);
9781
0
  HFAILURE;
9782
0
  if (res != 0) {
9783
0
      xmlSchemaPSimpleTypeErr(ctxt,
9784
0
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9785
0
    NULL, (xmlNodePtr) attr, NULL,
9786
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9787
0
  }
9788
0
    }
9789
0
    attr = xmlSchemaGetPropNode(node, "finalDefault");
9790
0
    if (attr != NULL) {
9791
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9792
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9793
0
      XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9794
0
      XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9795
0
      -1,
9796
0
      XML_SCHEMAS_FINAL_DEFAULT_LIST,
9797
0
      XML_SCHEMAS_FINAL_DEFAULT_UNION);
9798
0
  HFAILURE;
9799
0
  if (res != 0) {
9800
0
      xmlSchemaPSimpleTypeErr(ctxt,
9801
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9802
0
    NULL, (xmlNodePtr) attr, NULL,
9803
0
    "(#all | List of (extension | restriction | list | union))",
9804
0
    val, NULL, NULL, NULL);
9805
0
  }
9806
0
    }
9807
0
    attr = xmlSchemaGetPropNode(node, "blockDefault");
9808
0
    if (attr != NULL) {
9809
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9810
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9811
0
      XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9812
0
      XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9813
0
      XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9814
0
  HFAILURE;
9815
0
  if (res != 0) {
9816
0
      xmlSchemaPSimpleTypeErr(ctxt,
9817
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9818
0
    NULL, (xmlNodePtr) attr, NULL,
9819
0
    "(#all | List of (extension | restriction | substitution))",
9820
0
    val, NULL, NULL, NULL);
9821
0
  }
9822
0
    }
9823
9824
0
exit:
9825
0
    if (oldErrs != ctxt->nberrors)
9826
0
  res = ctxt->err;
9827
0
    return(res);
9828
0
exit_failure:
9829
0
    return(-1);
9830
0
}
9831
9832
/**
9833
 * xmlSchemaParseSchemaTopLevel:
9834
 * @ctxt:  a schema validation context
9835
 * @schema:  the schemas
9836
 * @nodes:  the list of top level nodes
9837
 *
9838
 * Returns the internal XML Schema structure built from the resource or
9839
 *         NULL in case of error
9840
 */
9841
static int
9842
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9843
                             xmlSchemaPtr schema, xmlNodePtr nodes)
9844
0
{
9845
0
    xmlNodePtr child;
9846
0
    xmlSchemaAnnotPtr annot;
9847
0
    int res = 0, oldErrs, tmpOldErrs;
9848
9849
0
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9850
0
        return(-1);
9851
9852
0
    oldErrs = ctxt->nberrors;
9853
0
    child = nodes;
9854
0
    while ((IS_SCHEMA(child, "include")) ||
9855
0
     (IS_SCHEMA(child, "import")) ||
9856
0
     (IS_SCHEMA(child, "redefine")) ||
9857
0
     (IS_SCHEMA(child, "annotation"))) {
9858
0
  if (IS_SCHEMA(child, "annotation")) {
9859
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9860
0
      if (schema->annot == NULL)
9861
0
    schema->annot = annot;
9862
0
      else
9863
0
    xmlSchemaFreeAnnot(annot);
9864
0
  } else if (IS_SCHEMA(child, "import")) {
9865
0
      tmpOldErrs = ctxt->nberrors;
9866
0
      res = xmlSchemaParseImport(ctxt, schema, child);
9867
0
      HFAILURE;
9868
0
      HSTOP(ctxt);
9869
0
      if (tmpOldErrs != ctxt->nberrors)
9870
0
    goto exit;
9871
0
  } else if (IS_SCHEMA(child, "include")) {
9872
0
      tmpOldErrs = ctxt->nberrors;
9873
0
      res = xmlSchemaParseInclude(ctxt, schema, child);
9874
0
      HFAILURE;
9875
0
      HSTOP(ctxt);
9876
0
      if (tmpOldErrs != ctxt->nberrors)
9877
0
    goto exit;
9878
0
  } else if (IS_SCHEMA(child, "redefine")) {
9879
0
      tmpOldErrs = ctxt->nberrors;
9880
0
      res = xmlSchemaParseRedefine(ctxt, schema, child);
9881
0
      HFAILURE;
9882
0
      HSTOP(ctxt);
9883
0
      if (tmpOldErrs != ctxt->nberrors)
9884
0
    goto exit;
9885
0
  }
9886
0
  child = child->next;
9887
0
    }
9888
    /*
9889
    * URGENT TODO: Change the functions to return int results.
9890
    * We need especially to catch internal errors.
9891
    */
9892
0
    while (child != NULL) {
9893
0
  if (IS_SCHEMA(child, "complexType")) {
9894
0
      xmlSchemaParseComplexType(ctxt, schema, child, 1);
9895
0
      child = child->next;
9896
0
  } else if (IS_SCHEMA(child, "simpleType")) {
9897
0
      xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9898
0
      child = child->next;
9899
0
  } else if (IS_SCHEMA(child, "element")) {
9900
0
      xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9901
0
      child = child->next;
9902
0
  } else if (IS_SCHEMA(child, "attribute")) {
9903
0
      xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9904
0
      child = child->next;
9905
0
  } else if (IS_SCHEMA(child, "attributeGroup")) {
9906
0
      xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9907
0
      child = child->next;
9908
0
  } else if (IS_SCHEMA(child, "group")) {
9909
0
      xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9910
0
      child = child->next;
9911
0
  } else if (IS_SCHEMA(child, "notation")) {
9912
0
      xmlSchemaParseNotation(ctxt, schema, child);
9913
0
      child = child->next;
9914
0
  } else {
9915
0
      xmlSchemaPContentErr(ctxt,
9916
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9917
0
    NULL, child->parent, child,
9918
0
    NULL, "((include | import | redefine | annotation)*, "
9919
0
    "(((simpleType | complexType | group | attributeGroup) "
9920
0
    "| element | attribute | notation), annotation*)*)");
9921
0
      child = child->next;
9922
0
  }
9923
0
  while (IS_SCHEMA(child, "annotation")) {
9924
      /*
9925
      * TODO: We should add all annotations.
9926
      */
9927
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9928
0
      if (schema->annot == NULL)
9929
0
    schema->annot = annot;
9930
0
      else
9931
0
    xmlSchemaFreeAnnot(annot);
9932
0
      child = child->next;
9933
0
  }
9934
0
    }
9935
0
exit:
9936
0
    ctxt->ctxtType = NULL;
9937
0
    if (oldErrs != ctxt->nberrors)
9938
0
  res = ctxt->err;
9939
0
    return(res);
9940
0
exit_failure:
9941
0
    return(-1);
9942
0
}
9943
9944
static xmlSchemaSchemaRelationPtr
9945
xmlSchemaSchemaRelationCreate(void)
9946
0
{
9947
0
    xmlSchemaSchemaRelationPtr ret;
9948
9949
0
    ret = (xmlSchemaSchemaRelationPtr)
9950
0
  xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9951
0
    if (ret == NULL) {
9952
0
  xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
9953
0
  return(NULL);
9954
0
    }
9955
0
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9956
0
    return(ret);
9957
0
}
9958
9959
#if 0
9960
static void
9961
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9962
{
9963
    xmlFree(rel);
9964
}
9965
#endif
9966
9967
static void
9968
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9969
0
{
9970
0
    xmlSchemaRedefPtr prev;
9971
9972
0
    while (redef != NULL) {
9973
0
  prev = redef;
9974
0
  redef = redef->next;
9975
0
  xmlFree(prev);
9976
0
    }
9977
0
}
9978
9979
static void
9980
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9981
0
{
9982
    /*
9983
    * After the construction context has been freed, there will be
9984
    * no schema graph available any more. Only the schema buckets
9985
    * will stay alive, which are put into the "schemasImports" and
9986
    * "includes" slots of the xmlSchema.
9987
    */
9988
0
    if (con->buckets != NULL)
9989
0
  xmlSchemaItemListFree(con->buckets);
9990
0
    if (con->pending != NULL)
9991
0
  xmlSchemaItemListFree(con->pending);
9992
0
    if (con->substGroups != NULL)
9993
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9994
0
    if (con->redefs != NULL)
9995
0
  xmlSchemaRedefListFree(con->redefs);
9996
0
    if (con->dict != NULL)
9997
0
  xmlDictFree(con->dict);
9998
0
    xmlFree(con);
9999
0
}
10000
10001
static xmlSchemaConstructionCtxtPtr
10002
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
10003
0
{
10004
0
    xmlSchemaConstructionCtxtPtr ret;
10005
10006
0
    ret = (xmlSchemaConstructionCtxtPtr)
10007
0
  xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
10008
0
    if (ret == NULL) {
10009
0
        xmlSchemaPErrMemory(NULL,
10010
0
      "allocating schema construction context", NULL);
10011
0
        return (NULL);
10012
0
    }
10013
0
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
10014
10015
0
    ret->buckets = xmlSchemaItemListCreate();
10016
0
    if (ret->buckets == NULL) {
10017
0
  xmlSchemaPErrMemory(NULL,
10018
0
      "allocating list of schema buckets", NULL);
10019
0
  xmlFree(ret);
10020
0
        return (NULL);
10021
0
    }
10022
0
    ret->pending = xmlSchemaItemListCreate();
10023
0
    if (ret->pending == NULL) {
10024
0
  xmlSchemaPErrMemory(NULL,
10025
0
      "allocating list of pending global components", NULL);
10026
0
  xmlSchemaConstructionCtxtFree(ret);
10027
0
        return (NULL);
10028
0
    }
10029
0
    ret->dict = dict;
10030
0
    xmlDictReference(dict);
10031
0
    return(ret);
10032
0
}
10033
10034
static xmlSchemaParserCtxtPtr
10035
xmlSchemaParserCtxtCreate(void)
10036
0
{
10037
0
    xmlSchemaParserCtxtPtr ret;
10038
10039
0
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
10040
0
    if (ret == NULL) {
10041
0
        xmlSchemaPErrMemory(NULL, "allocating schema parser context",
10042
0
                            NULL);
10043
0
        return (NULL);
10044
0
    }
10045
0
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
10046
0
    ret->type = XML_SCHEMA_CTXT_PARSER;
10047
0
    ret->attrProhibs = xmlSchemaItemListCreate();
10048
0
    if (ret->attrProhibs == NULL) {
10049
0
  xmlFree(ret);
10050
0
  return(NULL);
10051
0
    }
10052
0
    return(ret);
10053
0
}
10054
10055
/**
10056
 * xmlSchemaNewParserCtxtUseDict:
10057
 * @URL:  the location of the schema
10058
 * @dict: the dictionary to be used
10059
 *
10060
 * Create an XML Schemas parse context for that file/resource expected
10061
 * to contain an XML Schemas file.
10062
 *
10063
 * Returns the parser context or NULL in case of error
10064
 */
10065
static xmlSchemaParserCtxtPtr
10066
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
10067
0
{
10068
0
    xmlSchemaParserCtxtPtr ret;
10069
10070
0
    ret = xmlSchemaParserCtxtCreate();
10071
0
    if (ret == NULL)
10072
0
        return (NULL);
10073
0
    ret->dict = dict;
10074
0
    xmlDictReference(dict);
10075
0
    if (URL != NULL)
10076
0
  ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
10077
0
    return (ret);
10078
0
}
10079
10080
static int
10081
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
10082
0
{
10083
0
    if (vctxt->pctxt == NULL) {
10084
0
        if (vctxt->schema != NULL)
10085
0
      vctxt->pctxt =
10086
0
    xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
10087
0
  else
10088
0
      vctxt->pctxt = xmlSchemaNewParserCtxt("*");
10089
0
  if (vctxt->pctxt == NULL) {
10090
0
      VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
10091
0
    "failed to create a temp. parser context");
10092
0
      return (-1);
10093
0
  }
10094
  /* TODO: Pass user data. */
10095
0
  xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
10096
0
      vctxt->warning, vctxt->errCtxt);
10097
0
  xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
10098
0
      vctxt->errCtxt);
10099
0
    }
10100
0
    return (0);
10101
0
}
10102
10103
/**
10104
 * xmlSchemaGetSchemaBucket:
10105
 * @pctxt: the schema parser context
10106
 * @schemaLocation: the URI of the schema document
10107
 *
10108
 * Returns a schema bucket if it was already parsed.
10109
 *
10110
 * Returns a schema bucket if it was already parsed from
10111
 *         @schemaLocation, NULL otherwise.
10112
 */
10113
static xmlSchemaBucketPtr
10114
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10115
          const xmlChar *schemaLocation)
10116
0
{
10117
0
    xmlSchemaBucketPtr cur;
10118
0
    xmlSchemaItemListPtr list;
10119
10120
0
    list = pctxt->constructor->buckets;
10121
0
    if (list->nbItems == 0)
10122
0
  return(NULL);
10123
0
    else {
10124
0
  int i;
10125
0
  for (i = 0; i < list->nbItems; i++) {
10126
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10127
      /* Pointer comparison! */
10128
0
      if (cur->schemaLocation == schemaLocation)
10129
0
    return(cur);
10130
0
  }
10131
0
    }
10132
0
    return(NULL);
10133
0
}
10134
10135
static xmlSchemaBucketPtr
10136
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10137
             const xmlChar *schemaLocation,
10138
             const xmlChar *targetNamespace)
10139
0
{
10140
0
    xmlSchemaBucketPtr cur;
10141
0
    xmlSchemaItemListPtr list;
10142
10143
0
    list = pctxt->constructor->buckets;
10144
0
    if (list->nbItems == 0)
10145
0
  return(NULL);
10146
0
    else {
10147
0
  int i;
10148
0
  for (i = 0; i < list->nbItems; i++) {
10149
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10150
      /* Pointer comparison! */
10151
0
      if ((cur->origTargetNamespace == NULL) &&
10152
0
    (cur->schemaLocation == schemaLocation) &&
10153
0
    (cur->targetNamespace == targetNamespace))
10154
0
    return(cur);
10155
0
  }
10156
0
    }
10157
0
    return(NULL);
10158
0
}
10159
10160
10161
#define IS_BAD_SCHEMA_DOC(b) \
10162
0
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10163
10164
static xmlSchemaBucketPtr
10165
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10166
         const xmlChar *targetNamespace,
10167
         int imported)
10168
0
{
10169
0
    xmlSchemaBucketPtr cur;
10170
0
    xmlSchemaItemListPtr list;
10171
10172
0
    list = pctxt->constructor->buckets;
10173
0
    if (list->nbItems == 0)
10174
0
  return(NULL);
10175
0
    else {
10176
0
  int i;
10177
0
  for (i = 0; i < list->nbItems; i++) {
10178
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10179
0
      if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10180
0
    (cur->origTargetNamespace == targetNamespace) &&
10181
0
    ((imported && cur->imported) ||
10182
0
     ((!imported) && (!cur->imported))))
10183
0
    return(cur);
10184
0
  }
10185
0
    }
10186
0
    return(NULL);
10187
0
}
10188
10189
static int
10190
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10191
         xmlSchemaPtr schema,
10192
         xmlSchemaBucketPtr bucket)
10193
0
{
10194
0
    int oldFlags;
10195
0
    xmlDocPtr oldDoc;
10196
0
    xmlNodePtr node;
10197
0
    int ret, oldErrs;
10198
0
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10199
10200
    /*
10201
    * Save old values; reset the *main* schema.
10202
    * URGENT TODO: This is not good; move the per-document information
10203
    * to the parser. Get rid of passing the main schema to the
10204
    * parsing functions.
10205
    */
10206
0
    oldFlags = schema->flags;
10207
0
    oldDoc = schema->doc;
10208
0
    if (schema->flags != 0)
10209
0
  xmlSchemaClearSchemaDefaults(schema);
10210
0
    schema->doc = bucket->doc;
10211
0
    pctxt->schema = schema;
10212
    /*
10213
    * Keep the current target namespace on the parser *not* on the
10214
    * main schema.
10215
    */
10216
0
    pctxt->targetNamespace = bucket->targetNamespace;
10217
0
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10218
10219
0
    if ((bucket->targetNamespace != NULL) &&
10220
0
  xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10221
  /*
10222
  * We are parsing the schema for schemas!
10223
  */
10224
0
  pctxt->isS4S = 1;
10225
0
    }
10226
    /* Mark it as parsed, even if parsing fails. */
10227
0
    bucket->parsed++;
10228
    /* Compile the schema doc. */
10229
0
    node = xmlDocGetRootElement(bucket->doc);
10230
0
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10231
0
    if (ret != 0)
10232
0
  goto exit;
10233
    /* An empty schema; just get out. */
10234
0
    if (node->children == NULL)
10235
0
  goto exit;
10236
0
    oldErrs = pctxt->nberrors;
10237
0
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10238
0
    if (ret != 0)
10239
0
  goto exit;
10240
    /*
10241
    * TODO: Not nice, but I'm not 100% sure we will get always an error
10242
    * as a result of the above functions; so better rely on pctxt->err
10243
    * as well.
10244
    */
10245
0
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10246
0
  ret = pctxt->err;
10247
0
  goto exit;
10248
0
    }
10249
10250
0
exit:
10251
0
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10252
    /* Restore schema values. */
10253
0
    schema->doc = oldDoc;
10254
0
    schema->flags = oldFlags;
10255
0
    return(ret);
10256
0
}
10257
10258
static int
10259
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10260
         xmlSchemaPtr schema,
10261
         xmlSchemaBucketPtr bucket)
10262
0
{
10263
0
    xmlSchemaParserCtxtPtr newpctxt;
10264
0
    int res = 0;
10265
10266
0
    if (bucket == NULL)
10267
0
  return(0);
10268
0
    if (bucket->parsed) {
10269
0
  PERROR_INT("xmlSchemaParseNewDoc",
10270
0
      "reparsing a schema doc");
10271
0
  return(-1);
10272
0
    }
10273
0
    if (bucket->doc == NULL) {
10274
0
  PERROR_INT("xmlSchemaParseNewDoc",
10275
0
      "parsing a schema doc, but there's no doc");
10276
0
  return(-1);
10277
0
    }
10278
0
    if (pctxt->constructor == NULL) {
10279
0
  PERROR_INT("xmlSchemaParseNewDoc",
10280
0
      "no constructor");
10281
0
  return(-1);
10282
0
    }
10283
    /* Create and init the temporary parser context. */
10284
0
    newpctxt = xmlSchemaNewParserCtxtUseDict(
10285
0
  (const char *) bucket->schemaLocation, pctxt->dict);
10286
0
    if (newpctxt == NULL)
10287
0
  return(-1);
10288
0
    newpctxt->constructor = pctxt->constructor;
10289
    /*
10290
    * TODO: Can we avoid that the parser knows about the main schema?
10291
    * It would be better if he knows about the current schema bucket
10292
    * only.
10293
    */
10294
0
    newpctxt->schema = schema;
10295
0
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10296
0
  pctxt->errCtxt);
10297
0
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10298
0
  pctxt->errCtxt);
10299
0
    newpctxt->counter = pctxt->counter;
10300
10301
10302
0
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10303
10304
    /* Channel back errors and cleanup the temporary parser context. */
10305
0
    if (res != 0)
10306
0
  pctxt->err = res;
10307
0
    pctxt->nberrors += newpctxt->nberrors;
10308
0
    pctxt->counter = newpctxt->counter;
10309
0
    newpctxt->constructor = NULL;
10310
    /* Free the parser context. */
10311
0
    xmlSchemaFreeParserCtxt(newpctxt);
10312
0
    return(res);
10313
0
}
10314
10315
static void
10316
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10317
        xmlSchemaSchemaRelationPtr rel)
10318
0
{
10319
0
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
10320
10321
0
    if (cur == NULL) {
10322
0
  bucket->relations = rel;
10323
0
  return;
10324
0
    }
10325
0
    while (cur->next != NULL)
10326
0
  cur = cur->next;
10327
0
    cur->next = rel;
10328
0
}
10329
10330
10331
static const xmlChar *
10332
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10333
        xmlNodePtr ctxtNode)
10334
0
{
10335
    /*
10336
    * Build an absolute location URI.
10337
    */
10338
0
    if (location != NULL) {
10339
0
  if (ctxtNode == NULL)
10340
0
      return(location);
10341
0
  else {
10342
0
      xmlChar *base, *URI;
10343
0
      const xmlChar *ret = NULL;
10344
10345
0
      base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10346
0
      if (base == NULL) {
10347
0
    URI = xmlBuildURI(location, ctxtNode->doc->URL);
10348
0
      } else {
10349
0
    URI = xmlBuildURI(location, base);
10350
0
    xmlFree(base);
10351
0
      }
10352
0
      if (URI != NULL) {
10353
0
    ret = xmlDictLookup(dict, URI, -1);
10354
0
    xmlFree(URI);
10355
0
    return(ret);
10356
0
      }
10357
0
  }
10358
0
    }
10359
0
    return(NULL);
10360
0
}
10361
10362
10363
10364
/**
10365
 * xmlSchemaAddSchemaDoc:
10366
 * @pctxt:  a schema validation context
10367
 * @schema:  the schema being built
10368
 * @node:  a subtree containing XML Schema information
10369
 *
10370
 * Parse an included (and to-be-redefined) XML schema document.
10371
 *
10372
 * Returns 0 on success, a positive error code on errors and
10373
 *         -1 in case of an internal or API error.
10374
 */
10375
10376
static int
10377
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10378
    int type, /* import or include or redefine */
10379
    const xmlChar *schemaLocation,
10380
    xmlDocPtr schemaDoc,
10381
    const char *schemaBuffer,
10382
    int schemaBufferLen,
10383
    xmlNodePtr invokingNode,
10384
    const xmlChar *sourceTargetNamespace,
10385
    const xmlChar *importNamespace,
10386
    xmlSchemaBucketPtr *bucket)
10387
0
{
10388
0
    const xmlChar *targetNamespace = NULL;
10389
0
    xmlSchemaSchemaRelationPtr relation = NULL;
10390
0
    xmlDocPtr doc = NULL;
10391
0
    int res = 0, err = 0, located = 0, preserveDoc = 0;
10392
0
    xmlSchemaBucketPtr bkt = NULL;
10393
10394
0
    if (bucket != NULL)
10395
0
  *bucket = NULL;
10396
10397
0
    switch (type) {
10398
0
  case XML_SCHEMA_SCHEMA_IMPORT:
10399
0
  case XML_SCHEMA_SCHEMA_MAIN:
10400
0
      err = XML_SCHEMAP_SRC_IMPORT;
10401
0
      break;
10402
0
  case XML_SCHEMA_SCHEMA_INCLUDE:
10403
0
      err = XML_SCHEMAP_SRC_INCLUDE;
10404
0
      break;
10405
0
  case XML_SCHEMA_SCHEMA_REDEFINE:
10406
0
      err = XML_SCHEMAP_SRC_REDEFINE;
10407
0
      break;
10408
0
    }
10409
10410
10411
    /* Special handling for the main schema:
10412
    * skip the location and relation logic and just parse the doc.
10413
    * We need just a bucket to be returned in this case.
10414
    */
10415
0
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10416
0
  goto doc_load;
10417
10418
    /* Note that we expect the location to be an absolute URI. */
10419
0
    if (schemaLocation != NULL) {
10420
0
  bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10421
0
  if ((bkt != NULL) &&
10422
0
      (pctxt->constructor->bucket == bkt)) {
10423
      /* Report self-imports/inclusions/redefinitions. */
10424
10425
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10426
0
    invokingNode, NULL,
10427
0
    "The schema must not import/include/redefine itself",
10428
0
    NULL, NULL);
10429
0
      goto exit;
10430
0
  }
10431
0
    }
10432
    /*
10433
    * Create a relation for the graph of schemas.
10434
    */
10435
0
    relation = xmlSchemaSchemaRelationCreate();
10436
0
    if (relation == NULL)
10437
0
  return(-1);
10438
0
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10439
0
  relation);
10440
0
    relation->type = type;
10441
10442
    /*
10443
    * Save the namespace import information.
10444
    */
10445
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10446
0
  relation->importNamespace = importNamespace;
10447
0
  if (schemaLocation == NULL) {
10448
      /*
10449
      * No location; this is just an import of the namespace.
10450
      * Note that we don't assign a bucket to the relation
10451
      * in this case.
10452
      */
10453
0
      goto exit;
10454
0
  }
10455
0
  targetNamespace = importNamespace;
10456
0
    }
10457
10458
    /* Did we already fetch the doc? */
10459
0
    if (bkt != NULL) {
10460
0
  if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10461
      /*
10462
      * We included/redefined and then try to import a schema,
10463
      * but the new location provided for import was different.
10464
      */
10465
0
      if (schemaLocation == NULL)
10466
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10467
0
      if (!xmlStrEqual(schemaLocation,
10468
0
    bkt->schemaLocation)) {
10469
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10470
0
        invokingNode, NULL,
10471
0
        "The schema document '%s' cannot be imported, since "
10472
0
        "it was already included or redefined",
10473
0
        schemaLocation, NULL);
10474
0
    goto exit;
10475
0
      }
10476
0
  } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10477
      /*
10478
      * We imported and then try to include/redefine a schema,
10479
      * but the new location provided for the include/redefine
10480
      * was different.
10481
      */
10482
0
      if (schemaLocation == NULL)
10483
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10484
0
      if (!xmlStrEqual(schemaLocation,
10485
0
    bkt->schemaLocation)) {
10486
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10487
0
        invokingNode, NULL,
10488
0
        "The schema document '%s' cannot be included or "
10489
0
        "redefined, since it was already imported",
10490
0
        schemaLocation, NULL);
10491
0
    goto exit;
10492
0
      }
10493
0
  }
10494
0
    }
10495
10496
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10497
  /*
10498
  * Given that the schemaLocation [attribute] is only a hint, it is open
10499
  * to applications to ignore all but the first <import> for a given
10500
  * namespace, regardless of the `actual value` of schemaLocation, but
10501
  * such a strategy risks missing useful information when new
10502
  * schemaLocations are offered.
10503
  *
10504
  * We will use the first <import> that comes with a location.
10505
  * Further <import>s *with* a location, will result in an error.
10506
  * TODO: Better would be to just report a warning here, but
10507
  * we'll try it this way until someone complains.
10508
  *
10509
  * Schema Document Location Strategy:
10510
  * 3 Based on the namespace name, identify an existing schema document,
10511
  * either as a resource which is an XML document or a <schema> element
10512
  * information item, in some local schema repository;
10513
  * 5 Attempt to resolve the namespace name to locate such a resource.
10514
  *
10515
  * NOTE: (3) and (5) are not supported.
10516
  */
10517
0
  if (bkt != NULL) {
10518
0
      relation->bucket = bkt;
10519
0
      goto exit;
10520
0
  }
10521
0
  bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10522
0
      importNamespace, 1);
10523
10524
0
  if (bkt != NULL) {
10525
0
      relation->bucket = bkt;
10526
0
      if (bkt->schemaLocation == NULL) {
10527
    /* First given location of the schema; load the doc. */
10528
0
    bkt->schemaLocation = schemaLocation;
10529
0
      } else {
10530
0
    if (!xmlStrEqual(schemaLocation,
10531
0
        bkt->schemaLocation)) {
10532
        /*
10533
        * Additional location given; just skip it.
10534
        * URGENT TODO: We should report a warning here.
10535
        * res = XML_SCHEMAP_SRC_IMPORT;
10536
        */
10537
0
        if (schemaLocation == NULL)
10538
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10539
10540
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10541
0
      XML_SCHEMAP_WARN_SKIP_SCHEMA,
10542
0
      invokingNode, NULL,
10543
0
      "Skipping import of schema located at '%s' for the "
10544
0
      "namespace '%s', since this namespace was already "
10545
0
      "imported with the schema located at '%s'",
10546
0
      schemaLocation, importNamespace, bkt->schemaLocation);
10547
0
    }
10548
0
    goto exit;
10549
0
      }
10550
0
  }
10551
  /*
10552
  * No bucket + first location: load the doc and create a
10553
  * bucket.
10554
  */
10555
0
    } else {
10556
  /* <include> and <redefine> */
10557
0
  if (bkt != NULL) {
10558
10559
0
      if ((bkt->origTargetNamespace == NULL) &&
10560
0
    (bkt->targetNamespace != sourceTargetNamespace)) {
10561
0
    xmlSchemaBucketPtr chamel;
10562
10563
    /*
10564
    * Chameleon include/redefine: skip loading only if it was
10565
    * already build for the targetNamespace of the including
10566
    * schema.
10567
    */
10568
    /*
10569
    * URGENT TODO: If the schema is a chameleon-include then copy
10570
    * the components into the including schema and modify the
10571
    * targetNamespace of those components, do nothing otherwise.
10572
    * NOTE: This is currently worked-around by compiling the
10573
    * chameleon for every distinct including targetNamespace; thus
10574
    * not performant at the moment.
10575
    * TODO: Check when the namespace in wildcards for chameleons
10576
    * needs to be converted: before we built wildcard intersections
10577
    * or after.
10578
    *   Answer: after!
10579
    */
10580
0
    chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10581
0
        schemaLocation, sourceTargetNamespace);
10582
0
    if (chamel != NULL) {
10583
        /* A fitting chameleon was already parsed; NOP. */
10584
0
        relation->bucket = chamel;
10585
0
        goto exit;
10586
0
    }
10587
    /*
10588
    * We need to parse the chameleon again for a different
10589
    * targetNamespace.
10590
    * CHAMELEON TODO: Optimize this by only parsing the
10591
    * chameleon once, and then copying the components to
10592
    * the new targetNamespace.
10593
    */
10594
0
    bkt = NULL;
10595
0
      } else {
10596
0
    relation->bucket = bkt;
10597
0
    goto exit;
10598
0
      }
10599
0
  }
10600
0
    }
10601
0
    if ((bkt != NULL) && (bkt->doc != NULL)) {
10602
0
  PERROR_INT("xmlSchemaAddSchemaDoc",
10603
0
      "trying to load a schema doc, but a doc is already "
10604
0
      "assigned to the schema bucket");
10605
0
  goto exit_failure;
10606
0
    }
10607
10608
0
doc_load:
10609
    /*
10610
    * Load the document.
10611
    */
10612
0
    if (schemaDoc != NULL) {
10613
0
  doc = schemaDoc;
10614
  /* Don' free this one, since it was provided by the caller. */
10615
0
  preserveDoc = 1;
10616
  /* TODO: Does the context or the doc hold the location? */
10617
0
  if (schemaDoc->URL != NULL)
10618
0
      schemaLocation = xmlDictLookup(pctxt->dict,
10619
0
    schemaDoc->URL, -1);
10620
0
        else
10621
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10622
0
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10623
0
  xmlParserCtxtPtr parserCtxt;
10624
10625
0
  parserCtxt = xmlNewParserCtxt();
10626
0
  if (parserCtxt == NULL) {
10627
0
      xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10628
0
    "allocating a parser context", NULL);
10629
0
      goto exit_failure;
10630
0
  }
10631
0
  if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10632
      /*
10633
      * TODO: Do we have to burden the schema parser dict with all
10634
      * the content of the schema doc?
10635
      */
10636
0
      xmlDictFree(parserCtxt->dict);
10637
0
      parserCtxt->dict = pctxt->dict;
10638
0
      xmlDictReference(parserCtxt->dict);
10639
0
  }
10640
0
  if (schemaLocation != NULL) {
10641
      /* Parse from file. */
10642
0
      doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10643
0
    NULL, SCHEMAS_PARSE_OPTIONS);
10644
0
  } else if (schemaBuffer != NULL) {
10645
      /* Parse from memory buffer. */
10646
0
      doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10647
0
    NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10648
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10649
0
      if (doc != NULL)
10650
0
    doc->URL = xmlStrdup(schemaLocation);
10651
0
  }
10652
  /*
10653
  * For <import>:
10654
  * 2.1 The referent is (a fragment of) a resource which is an
10655
  * XML document (see clause 1.1), which in turn corresponds to
10656
  * a <schema> element information item in a well-formed information
10657
  * set, which in turn corresponds to a valid schema.
10658
  * TODO: (2.1) fragments of XML documents are not supported.
10659
  *
10660
  * 2.2 The referent is a <schema> element information item in
10661
  * a well-formed information set, which in turn corresponds
10662
  * to a valid schema.
10663
  * TODO: (2.2) is not supported.
10664
  */
10665
0
  if (doc == NULL) {
10666
0
      xmlErrorPtr lerr;
10667
0
      lerr = xmlGetLastError();
10668
      /*
10669
      * Check if this a parser error, or if the document could
10670
      * just not be located.
10671
      * TODO: Try to find specific error codes to react only on
10672
      * localisation failures.
10673
      */
10674
0
      if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10675
    /*
10676
    * We assume a parser error here.
10677
    */
10678
0
    located = 1;
10679
    /* TODO: Error code ?? */
10680
0
    res = XML_SCHEMAP_SRC_IMPORT_2_1;
10681
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10682
0
        invokingNode, NULL,
10683
0
        "Failed to parse the XML resource '%s'",
10684
0
        schemaLocation, NULL);
10685
0
      }
10686
0
  }
10687
0
  xmlFreeParserCtxt(parserCtxt);
10688
0
  if ((doc == NULL) && located)
10689
0
      goto exit_error;
10690
0
    } else {
10691
0
  xmlSchemaPErr(pctxt, NULL,
10692
0
      XML_SCHEMAP_NOTHING_TO_PARSE,
10693
0
      "No information for parsing was provided with the "
10694
0
      "given schema parser context.\n",
10695
0
      NULL, NULL);
10696
0
  goto exit_failure;
10697
0
    }
10698
    /*
10699
    * Preprocess the document.
10700
    */
10701
0
    if (doc != NULL) {
10702
0
  xmlNodePtr docElem = NULL;
10703
10704
0
  located = 1;
10705
0
  docElem = xmlDocGetRootElement(doc);
10706
0
  if (docElem == NULL) {
10707
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10708
0
    invokingNode, NULL,
10709
0
    "The document '%s' has no document element",
10710
0
    schemaLocation, NULL);
10711
0
      goto exit_error;
10712
0
  }
10713
  /*
10714
  * Remove all the blank text nodes.
10715
  */
10716
0
  xmlSchemaCleanupDoc(pctxt, docElem);
10717
  /*
10718
  * Check the schema's top level element.
10719
  */
10720
0
  if (!IS_SCHEMA(docElem, "schema")) {
10721
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10722
0
    invokingNode, NULL,
10723
0
    "The XML document '%s' is not a schema document",
10724
0
    schemaLocation, NULL);
10725
0
      goto exit_error;
10726
0
  }
10727
  /*
10728
  * Note that we don't apply a type check for the
10729
  * targetNamespace value here.
10730
  */
10731
0
  targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10732
0
      "targetNamespace");
10733
0
    }
10734
10735
/* after_doc_loading: */
10736
0
    if ((bkt == NULL) && located) {
10737
  /* Only create a bucket if the schema was located. */
10738
0
        bkt = xmlSchemaBucketCreate(pctxt, type,
10739
0
      targetNamespace);
10740
0
  if (bkt == NULL)
10741
0
      goto exit_failure;
10742
0
    }
10743
0
    if (bkt != NULL) {
10744
0
  bkt->schemaLocation = schemaLocation;
10745
0
  bkt->located = located;
10746
0
  if (doc != NULL) {
10747
0
      bkt->doc = doc;
10748
0
      bkt->targetNamespace = targetNamespace;
10749
0
      bkt->origTargetNamespace = targetNamespace;
10750
0
      if (preserveDoc)
10751
0
    bkt->preserveDoc = 1;
10752
0
  }
10753
0
  if (WXS_IS_BUCKET_IMPMAIN(type))
10754
0
      bkt->imported++;
10755
      /*
10756
      * Add it to the graph of schemas.
10757
      */
10758
0
  if (relation != NULL)
10759
0
      relation->bucket = bkt;
10760
0
    }
10761
10762
0
exit:
10763
    /*
10764
    * Return the bucket explicitly; this is needed for the
10765
    * main schema.
10766
    */
10767
0
    if (bucket != NULL)
10768
0
  *bucket = bkt;
10769
0
    return (0);
10770
10771
0
exit_error:
10772
0
    if ((doc != NULL) && (! preserveDoc)) {
10773
0
  xmlFreeDoc(doc);
10774
0
  if (bkt != NULL)
10775
0
      bkt->doc = NULL;
10776
0
    }
10777
0
    return(pctxt->err);
10778
10779
0
exit_failure:
10780
0
    if ((doc != NULL) && (! preserveDoc)) {
10781
0
  xmlFreeDoc(doc);
10782
0
  if (bkt != NULL)
10783
0
      bkt->doc = NULL;
10784
0
    }
10785
0
    return (-1);
10786
0
}
10787
10788
/**
10789
 * xmlSchemaParseImport:
10790
 * @ctxt:  a schema validation context
10791
 * @schema:  the schema being built
10792
 * @node:  a subtree containing XML Schema information
10793
 *
10794
 * parse a XML schema Import definition
10795
 * *WARNING* this interface is highly subject to change
10796
 *
10797
 * Returns 0 in case of success, a positive error code if
10798
 * not valid and -1 in case of an internal error.
10799
 */
10800
static int
10801
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10802
                     xmlNodePtr node)
10803
0
{
10804
0
    xmlNodePtr child;
10805
0
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10806
0
    const xmlChar *thisTargetNamespace;
10807
0
    xmlAttrPtr attr;
10808
0
    int ret = 0;
10809
0
    xmlSchemaBucketPtr bucket = NULL;
10810
10811
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10812
0
        return (-1);
10813
10814
    /*
10815
    * Check for illegal attributes.
10816
    */
10817
0
    attr = node->properties;
10818
0
    while (attr != NULL) {
10819
0
  if (attr->ns == NULL) {
10820
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10821
0
    (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10822
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10823
0
    xmlSchemaPIllegalAttrErr(pctxt,
10824
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10825
0
      }
10826
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10827
0
      xmlSchemaPIllegalAttrErr(pctxt,
10828
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10829
0
  }
10830
0
  attr = attr->next;
10831
0
    }
10832
    /*
10833
    * Extract and validate attributes.
10834
    */
10835
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10836
0
  "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10837
0
  &namespaceName) != 0) {
10838
0
  xmlSchemaPSimpleTypeErr(pctxt,
10839
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10840
0
      NULL, node,
10841
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10842
0
      NULL, namespaceName, NULL, NULL, NULL);
10843
0
  return (pctxt->err);
10844
0
    }
10845
10846
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10847
0
  "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10848
0
  &schemaLocation) != 0) {
10849
0
  xmlSchemaPSimpleTypeErr(pctxt,
10850
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10851
0
      NULL, node,
10852
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10853
0
      NULL, schemaLocation, NULL, NULL, NULL);
10854
0
  return (pctxt->err);
10855
0
    }
10856
    /*
10857
    * And now for the children...
10858
    */
10859
0
    child = node->children;
10860
0
    if (IS_SCHEMA(child, "annotation")) {
10861
        /*
10862
         * the annotation here is simply discarded ...
10863
   * TODO: really?
10864
         */
10865
0
        child = child->next;
10866
0
    }
10867
0
    if (child != NULL) {
10868
0
  xmlSchemaPContentErr(pctxt,
10869
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10870
0
      NULL, node, child, NULL,
10871
0
      "(annotation?)");
10872
0
    }
10873
    /*
10874
    * Apply additional constraints.
10875
    *
10876
    * Note that it is important to use the original @targetNamespace
10877
    * (or none at all), to rule out imports of schemas _with_ a
10878
    * @targetNamespace if the importing schema is a chameleon schema
10879
    * (with no @targetNamespace).
10880
    */
10881
0
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10882
0
    if (namespaceName != NULL) {
10883
  /*
10884
  * 1.1 If the namespace [attribute] is present, then its `actual value`
10885
  * must not match the `actual value` of the enclosing <schema>'s
10886
  * targetNamespace [attribute].
10887
  */
10888
0
  if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10889
0
      xmlSchemaPCustomErr(pctxt,
10890
0
    XML_SCHEMAP_SRC_IMPORT_1_1,
10891
0
    NULL, node,
10892
0
    "The value of the attribute 'namespace' must not match "
10893
0
    "the target namespace '%s' of the importing schema",
10894
0
    thisTargetNamespace);
10895
0
      return (pctxt->err);
10896
0
  }
10897
0
    } else {
10898
  /*
10899
  * 1.2 If the namespace [attribute] is not present, then the enclosing
10900
  * <schema> must have a targetNamespace [attribute].
10901
  */
10902
0
  if (thisTargetNamespace == NULL) {
10903
0
      xmlSchemaPCustomErr(pctxt,
10904
0
    XML_SCHEMAP_SRC_IMPORT_1_2,
10905
0
    NULL, node,
10906
0
    "The attribute 'namespace' must be existent if "
10907
0
    "the importing schema has no target namespace",
10908
0
    NULL);
10909
0
      return (pctxt->err);
10910
0
  }
10911
0
    }
10912
    /*
10913
    * Locate and acquire the schema document.
10914
    */
10915
0
    if (schemaLocation != NULL)
10916
0
  schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10917
0
      schemaLocation, node);
10918
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10919
0
  schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10920
0
  namespaceName, &bucket);
10921
10922
0
    if (ret != 0)
10923
0
  return(ret);
10924
10925
    /*
10926
    * For <import>: "It is *not* an error for the application
10927
    * schema reference strategy to fail."
10928
    * So just don't parse if no schema document was found.
10929
    * Note that we will get no bucket if the schema could not be
10930
    * located or if there was no schemaLocation.
10931
    */
10932
0
    if ((bucket == NULL) && (schemaLocation != NULL)) {
10933
0
  xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10934
0
      XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10935
0
      node, NULL,
10936
0
      "Failed to locate a schema at location '%s'. "
10937
0
      "Skipping the import", schemaLocation, NULL, NULL);
10938
0
    }
10939
10940
0
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10941
0
  ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10942
0
    }
10943
10944
0
    return (ret);
10945
0
}
10946
10947
static int
10948
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10949
             xmlSchemaPtr schema,
10950
             xmlNodePtr node,
10951
             xmlChar **schemaLocation,
10952
             int type)
10953
0
{
10954
0
    xmlAttrPtr attr;
10955
10956
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10957
0
  (schemaLocation == NULL))
10958
0
        return (-1);
10959
10960
0
    *schemaLocation = NULL;
10961
    /*
10962
    * Check for illegal attributes.
10963
    * Applies for both <include> and <redefine>.
10964
    */
10965
0
    attr = node->properties;
10966
0
    while (attr != NULL) {
10967
0
  if (attr->ns == NULL) {
10968
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10969
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10970
0
    xmlSchemaPIllegalAttrErr(pctxt,
10971
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10972
0
      }
10973
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10974
0
      xmlSchemaPIllegalAttrErr(pctxt,
10975
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10976
0
  }
10977
0
  attr = attr->next;
10978
0
    }
10979
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10980
    /*
10981
    * Preliminary step, extract the URI-Reference and make an URI
10982
    * from the base.
10983
    */
10984
    /*
10985
    * Attribute "schemaLocation" is mandatory.
10986
    */
10987
0
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
10988
0
    if (attr != NULL) {
10989
0
        xmlChar *base = NULL;
10990
0
        xmlChar *uri = NULL;
10991
10992
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10993
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10994
0
      (const xmlChar **) schemaLocation) != 0)
10995
0
      goto exit_error;
10996
0
  base = xmlNodeGetBase(node->doc, node);
10997
0
  if (base == NULL) {
10998
0
      uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10999
0
  } else {
11000
0
      uri = xmlBuildURI(*schemaLocation, base);
11001
0
      xmlFree(base);
11002
0
  }
11003
0
  if (uri == NULL) {
11004
0
      PERROR_INT("xmlSchemaParseIncludeOrRedefine",
11005
0
    "could not build an URI from the schemaLocation")
11006
0
      goto exit_failure;
11007
0
  }
11008
0
  (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
11009
0
  xmlFree(uri);
11010
0
    } else {
11011
0
  xmlSchemaPMissingAttrErr(pctxt,
11012
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11013
0
      NULL, node, "schemaLocation", NULL);
11014
0
  goto exit_error;
11015
0
    }
11016
    /*
11017
    * Report self-inclusion and self-redefinition.
11018
    */
11019
0
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
11020
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11021
0
      xmlSchemaPCustomErr(pctxt,
11022
0
    XML_SCHEMAP_SRC_REDEFINE,
11023
0
    NULL, node,
11024
0
    "The schema document '%s' cannot redefine itself.",
11025
0
    *schemaLocation);
11026
0
  } else {
11027
0
      xmlSchemaPCustomErr(pctxt,
11028
0
    XML_SCHEMAP_SRC_INCLUDE,
11029
0
    NULL, node,
11030
0
    "The schema document '%s' cannot include itself.",
11031
0
    *schemaLocation);
11032
0
  }
11033
0
  goto exit_error;
11034
0
    }
11035
11036
0
    return(0);
11037
0
exit_error:
11038
0
    return(pctxt->err);
11039
0
exit_failure:
11040
0
    return(-1);
11041
0
}
11042
11043
static int
11044
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
11045
        xmlSchemaPtr schema,
11046
        xmlNodePtr node,
11047
        int type)
11048
0
{
11049
0
    xmlNodePtr child = NULL;
11050
0
    const xmlChar *schemaLocation = NULL;
11051
0
    int res = 0; /* hasRedefinitions = 0 */
11052
0
    int isChameleon = 0, wasChameleon = 0;
11053
0
    xmlSchemaBucketPtr bucket = NULL;
11054
11055
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
11056
0
        return (-1);
11057
11058
    /*
11059
    * Parse attributes. Note that the returned schemaLocation will
11060
    * be already converted to an absolute URI.
11061
    */
11062
0
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
11063
0
  node, (xmlChar **) (&schemaLocation), type);
11064
0
    if (res != 0)
11065
0
  return(res);
11066
    /*
11067
    * Load and add the schema document.
11068
    */
11069
0
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
11070
0
  NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
11071
0
    if (res != 0)
11072
0
  return(res);
11073
    /*
11074
    * If we get no schema bucket back, then this means that the schema
11075
    * document could not be located or was broken XML or was not
11076
    * a schema document.
11077
    */
11078
0
    if ((bucket == NULL) || (bucket->doc == NULL)) {
11079
0
  if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
11080
      /*
11081
      * WARNING for <include>:
11082
      * We will raise an error if the schema cannot be located
11083
      * for inclusions, since the that was the feedback from the
11084
      * schema people. I.e. the following spec piece will *not* be
11085
      * satisfied:
11086
      * SPEC src-include: "It is not an error for the `actual value` of the
11087
      * schemaLocation [attribute] to fail to resolve it all, in which
11088
      * case no corresponding inclusion is performed.
11089
      * So do we need a warning report here?"
11090
      */
11091
0
      res = XML_SCHEMAP_SRC_INCLUDE;
11092
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
11093
0
    node, NULL,
11094
0
    "Failed to load the document '%s' for inclusion",
11095
0
    schemaLocation, NULL);
11096
0
  } else {
11097
      /*
11098
      * NOTE: This was changed to raise an error even if no redefinitions
11099
      * are specified.
11100
      *
11101
      * SPEC src-redefine (1)
11102
      * "If there are any element information items among the [children]
11103
      * other than <annotation> then the `actual value` of the
11104
      * schemaLocation [attribute] must successfully resolve."
11105
      * TODO: Ask the WG if a the location has always to resolve
11106
      * here as well!
11107
      */
11108
0
      res = XML_SCHEMAP_SRC_REDEFINE;
11109
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
11110
0
    node, NULL,
11111
0
    "Failed to load the document '%s' for redefinition",
11112
0
    schemaLocation, NULL);
11113
0
  }
11114
0
    } else {
11115
  /*
11116
  * Check targetNamespace sanity before parsing the new schema.
11117
  * TODO: Note that we won't check further content if the
11118
  * targetNamespace was bad.
11119
  */
11120
0
  if (bucket->origTargetNamespace != NULL) {
11121
      /*
11122
      * SPEC src-include (2.1)
11123
      * "SII has a targetNamespace [attribute], and its `actual
11124
      * value` is identical to the `actual value` of the targetNamespace
11125
      * [attribute] of SII' (which must have such an [attribute])."
11126
      */
11127
0
      if (pctxt->targetNamespace == NULL) {
11128
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
11129
0
        XML_SCHEMAP_SRC_INCLUDE,
11130
0
        node, NULL,
11131
0
        "The target namespace of the included/redefined schema "
11132
0
        "'%s' has to be absent, since the including/redefining "
11133
0
        "schema has no target namespace",
11134
0
        schemaLocation, NULL);
11135
0
    goto exit_error;
11136
0
      } else if (!xmlStrEqual(bucket->origTargetNamespace,
11137
0
    pctxt->targetNamespace)) {
11138
    /* TODO: Change error function. */
11139
0
    xmlSchemaPCustomErrExt(pctxt,
11140
0
        XML_SCHEMAP_SRC_INCLUDE,
11141
0
        NULL, node,
11142
0
        "The target namespace '%s' of the included/redefined "
11143
0
        "schema '%s' differs from '%s' of the "
11144
0
        "including/redefining schema",
11145
0
        bucket->origTargetNamespace, schemaLocation,
11146
0
        pctxt->targetNamespace);
11147
0
    goto exit_error;
11148
0
      }
11149
0
  } else if (pctxt->targetNamespace != NULL) {
11150
      /*
11151
      * Chameleons: the original target namespace will
11152
      * differ from the resulting namespace.
11153
      */
11154
0
      isChameleon = 1;
11155
0
      if (bucket->parsed &&
11156
0
    bucket->origTargetNamespace != NULL) {
11157
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
11158
0
        XML_SCHEMAP_SRC_INCLUDE,
11159
0
        node, NULL,
11160
0
        "The target namespace of the included/redefined schema "
11161
0
        "'%s' has to be absent or the same as the "
11162
0
        "including/redefining schema's target namespace",
11163
0
        schemaLocation, NULL);
11164
0
    goto exit_error;
11165
0
      }
11166
0
      bucket->targetNamespace = pctxt->targetNamespace;
11167
0
  }
11168
0
    }
11169
    /*
11170
    * Parse the schema.
11171
    */
11172
0
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11173
0
  if (isChameleon) {
11174
      /* TODO: Get rid of this flag on the schema itself. */
11175
0
      if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11176
0
    schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11177
0
      } else
11178
0
    wasChameleon = 1;
11179
0
  }
11180
0
  xmlSchemaParseNewDoc(pctxt, schema, bucket);
11181
  /* Restore chameleon flag. */
11182
0
  if (isChameleon && (!wasChameleon))
11183
0
      schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11184
0
    }
11185
    /*
11186
    * And now for the children...
11187
    */
11188
0
    child = node->children;
11189
0
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11190
  /*
11191
  * Parse (simpleType | complexType | group | attributeGroup))*
11192
  */
11193
0
  pctxt->redefined = bucket;
11194
  /*
11195
  * How to proceed if the redefined schema was not located?
11196
  */
11197
0
  pctxt->isRedefine = 1;
11198
0
  while (IS_SCHEMA(child, "annotation") ||
11199
0
      IS_SCHEMA(child, "simpleType") ||
11200
0
      IS_SCHEMA(child, "complexType") ||
11201
0
      IS_SCHEMA(child, "group") ||
11202
0
      IS_SCHEMA(child, "attributeGroup")) {
11203
0
      if (IS_SCHEMA(child, "annotation")) {
11204
    /*
11205
    * TODO: discard or not?
11206
    */
11207
0
      } else if (IS_SCHEMA(child, "simpleType")) {
11208
0
    xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11209
0
      } else if (IS_SCHEMA(child, "complexType")) {
11210
0
    xmlSchemaParseComplexType(pctxt, schema, child, 1);
11211
    /* hasRedefinitions = 1; */
11212
0
      } else if (IS_SCHEMA(child, "group")) {
11213
    /* hasRedefinitions = 1; */
11214
0
    xmlSchemaParseModelGroupDefinition(pctxt,
11215
0
        schema, child);
11216
0
      } else if (IS_SCHEMA(child, "attributeGroup")) {
11217
    /* hasRedefinitions = 1; */
11218
0
    xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11219
0
        child);
11220
0
      }
11221
0
      child = child->next;
11222
0
  }
11223
0
  pctxt->redefined = NULL;
11224
0
  pctxt->isRedefine = 0;
11225
0
    } else {
11226
0
  if (IS_SCHEMA(child, "annotation")) {
11227
      /*
11228
      * TODO: discard or not?
11229
      */
11230
0
      child = child->next;
11231
0
  }
11232
0
    }
11233
0
    if (child != NULL) {
11234
0
  res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11235
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11236
0
      xmlSchemaPContentErr(pctxt, res,
11237
0
    NULL, node, child, NULL,
11238
0
    "(annotation | (simpleType | complexType | group | attributeGroup))*");
11239
0
  } else {
11240
0
       xmlSchemaPContentErr(pctxt, res,
11241
0
    NULL, node, child, NULL,
11242
0
    "(annotation?)");
11243
0
  }
11244
0
    }
11245
0
    return(res);
11246
11247
0
exit_error:
11248
0
    return(pctxt->err);
11249
0
}
11250
11251
static int
11252
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11253
                       xmlNodePtr node)
11254
0
{
11255
0
    int res;
11256
#ifndef ENABLE_REDEFINE
11257
    TODO
11258
    return(0);
11259
#endif
11260
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11261
0
  XML_SCHEMA_SCHEMA_REDEFINE);
11262
0
    if (res != 0)
11263
0
  return(res);
11264
0
    return(0);
11265
0
}
11266
11267
static int
11268
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11269
                       xmlNodePtr node)
11270
0
{
11271
0
    int res;
11272
11273
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11274
0
  XML_SCHEMA_SCHEMA_INCLUDE);
11275
0
    if (res != 0)
11276
0
  return(res);
11277
0
    return(0);
11278
0
}
11279
11280
/**
11281
 * xmlSchemaParseModelGroup:
11282
 * @ctxt:  a schema validation context
11283
 * @schema:  the schema being built
11284
 * @node:  a subtree containing XML Schema information
11285
 * @type: the "compositor" type
11286
 * @particleNeeded: if a a model group with a particle
11287
 *
11288
 * parse a XML schema Sequence definition.
11289
 * Applies parts of:
11290
 *   Schema Representation Constraint:
11291
 *     Redefinition Constraints and Semantics (src-redefine)
11292
 *     (6.1), (6.1.1), (6.1.2)
11293
 *
11294
 *   Schema Component Constraint:
11295
 *     All Group Limited (cos-all-limited) (2)
11296
 *     TODO: Actually this should go to component-level checks,
11297
 *     but is done here due to performance. Move it to an other layer
11298
 *     is schema construction via an API is implemented.
11299
 *
11300
 * *WARNING* this interface is highly subject to change
11301
 *
11302
 * Returns -1 in case of error, 0 if the declaration is improper and
11303
 *         1 in case of success.
11304
 */
11305
static xmlSchemaTreeItemPtr
11306
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11307
       xmlNodePtr node, xmlSchemaTypeType type,
11308
       int withParticle)
11309
0
{
11310
0
    xmlSchemaModelGroupPtr item;
11311
0
    xmlSchemaParticlePtr particle = NULL;
11312
0
    xmlNodePtr child = NULL;
11313
0
    xmlAttrPtr attr;
11314
0
    int min = 1, max = 1, isElemRef, hasRefs = 0;
11315
11316
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11317
0
        return (NULL);
11318
    /*
11319
    * Create a model group with the given compositor.
11320
    */
11321
0
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11322
0
    if (item == NULL)
11323
0
  return (NULL);
11324
11325
0
    if (withParticle) {
11326
0
  if (type == XML_SCHEMA_TYPE_ALL) {
11327
0
      min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11328
0
      max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11329
0
  } else {
11330
      /* choice + sequence */
11331
0
      min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11332
0
      max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11333
0
    "(xs:nonNegativeInteger | unbounded)");
11334
0
  }
11335
0
  xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11336
  /*
11337
  * Create a particle
11338
  */
11339
0
  particle = xmlSchemaAddParticle(ctxt, node, min, max);
11340
0
  if (particle == NULL)
11341
0
      return (NULL);
11342
0
  particle->children = (xmlSchemaTreeItemPtr) item;
11343
  /*
11344
  * Check for illegal attributes.
11345
  */
11346
0
  attr = node->properties;
11347
0
  while (attr != NULL) {
11348
0
      if (attr->ns == NULL) {
11349
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11350
0
        (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11351
0
        (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11352
0
        xmlSchemaPIllegalAttrErr(ctxt,
11353
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11354
0
    }
11355
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11356
0
    xmlSchemaPIllegalAttrErr(ctxt,
11357
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11358
0
      }
11359
0
      attr = attr->next;
11360
0
  }
11361
0
    } else {
11362
  /*
11363
  * Check for illegal attributes.
11364
  */
11365
0
  attr = node->properties;
11366
0
  while (attr != NULL) {
11367
0
      if (attr->ns == NULL) {
11368
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11369
0
        xmlSchemaPIllegalAttrErr(ctxt,
11370
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11371
0
    }
11372
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11373
0
    xmlSchemaPIllegalAttrErr(ctxt,
11374
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11375
0
      }
11376
0
      attr = attr->next;
11377
0
  }
11378
0
    }
11379
11380
    /*
11381
    * Extract and validate attributes.
11382
    */
11383
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11384
    /*
11385
    * And now for the children...
11386
    */
11387
0
    child = node->children;
11388
0
    if (IS_SCHEMA(child, "annotation")) {
11389
0
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11390
0
        child = child->next;
11391
0
    }
11392
0
    if (type == XML_SCHEMA_TYPE_ALL) {
11393
0
  xmlSchemaParticlePtr part, last = NULL;
11394
11395
0
  while (IS_SCHEMA(child, "element")) {
11396
0
      part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11397
0
    schema, child, &isElemRef, 0);
11398
      /*
11399
      * SPEC cos-all-limited (2)
11400
      * "The {max occurs} of all the particles in the {particles}
11401
      * of the ('all') group must be 0 or 1.
11402
      */
11403
0
      if (part != NULL) {
11404
0
    if (isElemRef)
11405
0
        hasRefs++;
11406
0
    if (part->minOccurs > 1) {
11407
0
        xmlSchemaPCustomErr(ctxt,
11408
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11409
0
      NULL, child,
11410
0
      "Invalid value for minOccurs (must be 0 or 1)",
11411
0
      NULL);
11412
        /* Reset to 1. */
11413
0
        part->minOccurs = 1;
11414
0
    }
11415
0
    if (part->maxOccurs > 1) {
11416
0
        xmlSchemaPCustomErr(ctxt,
11417
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11418
0
      NULL, child,
11419
0
      "Invalid value for maxOccurs (must be 0 or 1)",
11420
0
      NULL);
11421
        /* Reset to 1. */
11422
0
        part->maxOccurs = 1;
11423
0
    }
11424
0
    if (last == NULL)
11425
0
        item->children = (xmlSchemaTreeItemPtr) part;
11426
0
    else
11427
0
        last->next = (xmlSchemaTreeItemPtr) part;
11428
0
    last = part;
11429
0
      }
11430
0
      child = child->next;
11431
0
  }
11432
0
  if (child != NULL) {
11433
0
      xmlSchemaPContentErr(ctxt,
11434
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11435
0
    NULL, node, child, NULL,
11436
0
    "(annotation?, (annotation?, element*)");
11437
0
  }
11438
0
    } else {
11439
  /* choice + sequence */
11440
0
  xmlSchemaTreeItemPtr part = NULL, last = NULL;
11441
11442
0
  while ((IS_SCHEMA(child, "element")) ||
11443
0
      (IS_SCHEMA(child, "group")) ||
11444
0
      (IS_SCHEMA(child, "any")) ||
11445
0
      (IS_SCHEMA(child, "choice")) ||
11446
0
      (IS_SCHEMA(child, "sequence"))) {
11447
11448
0
      if (IS_SCHEMA(child, "element")) {
11449
0
    part = (xmlSchemaTreeItemPtr)
11450
0
        xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11451
0
    if (part && isElemRef)
11452
0
        hasRefs++;
11453
0
      } else if (IS_SCHEMA(child, "group")) {
11454
0
    part =
11455
0
        xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11456
0
    if (part != NULL)
11457
0
        hasRefs++;
11458
    /*
11459
    * Handle redefinitions.
11460
    */
11461
0
    if (ctxt->isRedefine && ctxt->redef &&
11462
0
        (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11463
0
        part && part->children)
11464
0
    {
11465
0
        if ((xmlSchemaGetQNameRefName(part->children) ==
11466
0
          ctxt->redef->refName) &&
11467
0
      (xmlSchemaGetQNameRefTargetNs(part->children) ==
11468
0
          ctxt->redef->refTargetNs))
11469
0
        {
11470
      /*
11471
      * SPEC src-redefine:
11472
      * (6.1) "If it has a <group> among its contents at
11473
      * some level the `actual value` of whose ref
11474
      * [attribute] is the same as the `actual value` of
11475
      * its own name attribute plus target namespace, then
11476
      * all of the following must be true:"
11477
      * (6.1.1) "It must have exactly one such group."
11478
      */
11479
0
      if (ctxt->redefCounter != 0) {
11480
0
          xmlChar *str = NULL;
11481
11482
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11483
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11484
0
        "The redefining model group definition "
11485
0
        "'%s' must not contain more than one "
11486
0
        "reference to the redefined definition",
11487
0
        xmlSchemaFormatQName(&str,
11488
0
            ctxt->redef->refTargetNs,
11489
0
            ctxt->redef->refName),
11490
0
        NULL);
11491
0
          FREE_AND_NULL(str)
11492
0
          part = NULL;
11493
0
      } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11494
0
          ((WXS_PARTICLE(part))->maxOccurs != 1))
11495
0
      {
11496
0
          xmlChar *str = NULL;
11497
          /*
11498
          * SPEC src-redefine:
11499
          * (6.1.2) "The `actual value` of both that
11500
          * group's minOccurs and maxOccurs [attribute]
11501
          * must be 1 (or `absent`).
11502
          */
11503
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11504
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11505
0
        "The redefining model group definition "
11506
0
        "'%s' must not contain a reference to the "
11507
0
        "redefined definition with a "
11508
0
        "maxOccurs/minOccurs other than 1",
11509
0
        xmlSchemaFormatQName(&str,
11510
0
            ctxt->redef->refTargetNs,
11511
0
            ctxt->redef->refName),
11512
0
        NULL);
11513
0
          FREE_AND_NULL(str)
11514
0
          part = NULL;
11515
0
      }
11516
0
      ctxt->redef->reference = WXS_BASIC_CAST part;
11517
0
      ctxt->redefCounter++;
11518
0
        }
11519
0
    }
11520
0
      } else if (IS_SCHEMA(child, "any")) {
11521
0
    part = (xmlSchemaTreeItemPtr)
11522
0
        xmlSchemaParseAny(ctxt, schema, child);
11523
0
      } else if (IS_SCHEMA(child, "choice")) {
11524
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11525
0
        XML_SCHEMA_TYPE_CHOICE, 1);
11526
0
      } else if (IS_SCHEMA(child, "sequence")) {
11527
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11528
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11529
0
      }
11530
0
      if (part != NULL) {
11531
0
    if (last == NULL)
11532
0
        item->children = part;
11533
0
    else
11534
0
        last->next = part;
11535
0
    last = part;
11536
0
      }
11537
0
      child = child->next;
11538
0
  }
11539
0
  if (child != NULL) {
11540
0
      xmlSchemaPContentErr(ctxt,
11541
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11542
0
    NULL, node, child, NULL,
11543
0
    "(annotation?, (element | group | choice | sequence | any)*)");
11544
0
  }
11545
0
    }
11546
0
    if ((max == 0) && (min == 0))
11547
0
  return (NULL);
11548
0
    if (hasRefs) {
11549
  /*
11550
  * We need to resolve references.
11551
  */
11552
0
  WXS_ADD_PENDING(ctxt, item);
11553
0
    }
11554
0
    if (withParticle)
11555
0
  return ((xmlSchemaTreeItemPtr) particle);
11556
0
    else
11557
0
  return ((xmlSchemaTreeItemPtr) item);
11558
0
}
11559
11560
/**
11561
 * xmlSchemaParseRestriction:
11562
 * @ctxt:  a schema validation context
11563
 * @schema:  the schema being built
11564
 * @node:  a subtree containing XML Schema information
11565
 *
11566
 * parse a XML schema Restriction definition
11567
 * *WARNING* this interface is highly subject to change
11568
 *
11569
 * Returns the type definition or NULL in case of error
11570
 */
11571
static xmlSchemaTypePtr
11572
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11573
                          xmlNodePtr node, xmlSchemaTypeType parentType)
11574
0
{
11575
0
    xmlSchemaTypePtr type;
11576
0
    xmlNodePtr child = NULL;
11577
0
    xmlAttrPtr attr;
11578
11579
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11580
0
        return (NULL);
11581
    /* Not a component, don't create it. */
11582
0
    type = ctxt->ctxtType;
11583
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11584
11585
    /*
11586
    * Check for illegal attributes.
11587
    */
11588
0
    attr = node->properties;
11589
0
    while (attr != NULL) {
11590
0
  if (attr->ns == NULL) {
11591
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11592
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11593
0
    xmlSchemaPIllegalAttrErr(ctxt,
11594
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11595
0
      }
11596
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11597
0
      xmlSchemaPIllegalAttrErr(ctxt,
11598
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11599
0
  }
11600
0
  attr = attr->next;
11601
0
    }
11602
    /*
11603
    * Extract and validate attributes.
11604
    */
11605
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11606
    /*
11607
    * Attribute
11608
    */
11609
    /*
11610
    * Extract the base type. The "base" attribute is mandatory if inside
11611
    * a complex type or if redefining.
11612
    *
11613
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11614
    * among its [children]), the simple type definition which is
11615
    * the {content type} of the type definition `resolved` to by
11616
    * the `actual value` of the base [attribute]"
11617
    */
11618
0
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11619
0
  &(type->baseNs), &(type->base)) == 0)
11620
0
    {
11621
0
  if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11622
0
      xmlSchemaPMissingAttrErr(ctxt,
11623
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
11624
0
    NULL, node, "base", NULL);
11625
0
  } else if ((ctxt->isRedefine) &&
11626
0
      (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11627
0
  {
11628
0
      if (type->base == NULL) {
11629
0
    xmlSchemaPMissingAttrErr(ctxt,
11630
0
        XML_SCHEMAP_S4S_ATTR_MISSING,
11631
0
        NULL, node, "base", NULL);
11632
0
      } else if ((! xmlStrEqual(type->base, type->name)) ||
11633
0
    (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11634
0
      {
11635
0
    xmlChar *str1 = NULL, *str2 = NULL;
11636
    /*
11637
    * REDEFINE: SPEC src-redefine (5)
11638
    * "Within the [children], each <simpleType> must have a
11639
    * <restriction> among its [children] ... the `actual value` of
11640
    * whose base [attribute] must be the same as the `actual value`
11641
    * of its own name attribute plus target namespace;"
11642
    */
11643
0
    xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11644
0
        NULL, node, "This is a redefinition, but the QName "
11645
0
        "value '%s' of the 'base' attribute does not match the "
11646
0
        "type's designation '%s'",
11647
0
        xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11648
0
        xmlSchemaFormatQName(&str2, type->targetNamespace,
11649
0
      type->name), NULL);
11650
0
    FREE_AND_NULL(str1);
11651
0
    FREE_AND_NULL(str2);
11652
    /* Avoid confusion and erase the values. */
11653
0
    type->base = NULL;
11654
0
    type->baseNs = NULL;
11655
0
      }
11656
0
  }
11657
0
    }
11658
    /*
11659
    * And now for the children...
11660
    */
11661
0
    child = node->children;
11662
0
    if (IS_SCHEMA(child, "annotation")) {
11663
  /*
11664
  * Add the annotation to the simple type ancestor.
11665
  */
11666
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11667
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11668
0
        child = child->next;
11669
0
    }
11670
0
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11671
  /*
11672
  * Corresponds to <simpleType><restriction><simpleType>.
11673
  */
11674
0
  if (IS_SCHEMA(child, "simpleType")) {
11675
0
      if (type->base != NULL) {
11676
    /*
11677
    * src-restriction-base-or-simpleType
11678
    * Either the base [attribute] or the simpleType [child] of the
11679
    * <restriction> element must be present, but not both.
11680
    */
11681
0
    xmlSchemaPContentErr(ctxt,
11682
0
        XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11683
0
        NULL, node, child,
11684
0
        "The attribute 'base' and the <simpleType> child are "
11685
0
        "mutually exclusive", NULL);
11686
0
      } else {
11687
0
    type->baseType = (xmlSchemaTypePtr)
11688
0
        xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11689
0
      }
11690
0
      child = child->next;
11691
0
  } else if (type->base == NULL) {
11692
0
      xmlSchemaPContentErr(ctxt,
11693
0
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11694
0
    NULL, node, child,
11695
0
    "Either the attribute 'base' or a <simpleType> child "
11696
0
    "must be present", NULL);
11697
0
  }
11698
0
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11699
  /*
11700
  * Corresponds to <complexType><complexContent><restriction>...
11701
  * followed by:
11702
  *
11703
  * Model groups <all>, <choice> and <sequence>.
11704
  */
11705
0
  if (IS_SCHEMA(child, "all")) {
11706
0
      type->subtypes = (xmlSchemaTypePtr)
11707
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11708
0
        XML_SCHEMA_TYPE_ALL, 1);
11709
0
      child = child->next;
11710
0
  } else if (IS_SCHEMA(child, "choice")) {
11711
0
      type->subtypes = (xmlSchemaTypePtr)
11712
0
    xmlSchemaParseModelGroup(ctxt,
11713
0
        schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11714
0
      child = child->next;
11715
0
  } else if (IS_SCHEMA(child, "sequence")) {
11716
0
      type->subtypes = (xmlSchemaTypePtr)
11717
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11718
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11719
0
      child = child->next;
11720
  /*
11721
  * Model group reference <group>.
11722
  */
11723
0
  } else if (IS_SCHEMA(child, "group")) {
11724
0
      type->subtypes = (xmlSchemaTypePtr)
11725
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11726
      /*
11727
      * Note that the reference will be resolved in
11728
      * xmlSchemaResolveTypeReferences();
11729
      */
11730
0
      child = child->next;
11731
0
  }
11732
0
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11733
  /*
11734
  * Corresponds to <complexType><simpleContent><restriction>...
11735
  *
11736
  * "1.1 the simple type definition corresponding to the <simpleType>
11737
  * among the [children] of <restriction> if there is one;"
11738
  */
11739
0
  if (IS_SCHEMA(child, "simpleType")) {
11740
      /*
11741
      * We will store the to-be-restricted simple type in
11742
      * type->contentTypeDef *temporarily*.
11743
      */
11744
0
      type->contentTypeDef = (xmlSchemaTypePtr)
11745
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11746
0
      if ( type->contentTypeDef == NULL)
11747
0
    return (NULL);
11748
0
      child = child->next;
11749
0
  }
11750
0
    }
11751
11752
0
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11753
0
  (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11754
0
  xmlSchemaFacetPtr facet, lastfacet = NULL;
11755
  /*
11756
  * Corresponds to <complexType><simpleContent><restriction>...
11757
  * <simpleType><restriction>...
11758
  */
11759
11760
  /*
11761
  * Add the facets to the simple type ancestor.
11762
  */
11763
  /*
11764
  * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11765
  * Simple Type Definition Schema Representation Constraint:
11766
  * *Single Facet Value*
11767
  */
11768
0
  while ((IS_SCHEMA(child, "minInclusive")) ||
11769
0
      (IS_SCHEMA(child, "minExclusive")) ||
11770
0
      (IS_SCHEMA(child, "maxInclusive")) ||
11771
0
      (IS_SCHEMA(child, "maxExclusive")) ||
11772
0
      (IS_SCHEMA(child, "totalDigits")) ||
11773
0
      (IS_SCHEMA(child, "fractionDigits")) ||
11774
0
      (IS_SCHEMA(child, "pattern")) ||
11775
0
      (IS_SCHEMA(child, "enumeration")) ||
11776
0
      (IS_SCHEMA(child, "whiteSpace")) ||
11777
0
      (IS_SCHEMA(child, "length")) ||
11778
0
      (IS_SCHEMA(child, "maxLength")) ||
11779
0
      (IS_SCHEMA(child, "minLength"))) {
11780
0
      facet = xmlSchemaParseFacet(ctxt, schema, child);
11781
0
      if (facet != NULL) {
11782
0
    if (lastfacet == NULL)
11783
0
        type->facets = facet;
11784
0
    else
11785
0
        lastfacet->next = facet;
11786
0
    lastfacet = facet;
11787
0
    lastfacet->next = NULL;
11788
0
      }
11789
0
      child = child->next;
11790
0
  }
11791
  /*
11792
  * Create links for derivation and validation.
11793
  */
11794
0
  if (type->facets != NULL) {
11795
0
      xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11796
11797
0
      facet = type->facets;
11798
0
      do {
11799
0
    facetLink = (xmlSchemaFacetLinkPtr)
11800
0
        xmlMalloc(sizeof(xmlSchemaFacetLink));
11801
0
    if (facetLink == NULL) {
11802
0
        xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11803
0
        xmlFree(facetLink);
11804
0
        return (NULL);
11805
0
    }
11806
0
    facetLink->facet = facet;
11807
0
    facetLink->next = NULL;
11808
0
    if (lastFacetLink == NULL)
11809
0
        type->facetSet = facetLink;
11810
0
    else
11811
0
        lastFacetLink->next = facetLink;
11812
0
    lastFacetLink = facetLink;
11813
0
    facet = facet->next;
11814
0
      } while (facet != NULL);
11815
0
  }
11816
0
    }
11817
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11818
  /*
11819
  * Attribute uses/declarations.
11820
  */
11821
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11822
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11823
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11824
0
      return(NULL);
11825
  /*
11826
  * Attribute wildcard.
11827
  */
11828
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11829
0
      type->attributeWildcard =
11830
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11831
0
      child = child->next;
11832
0
  }
11833
0
    }
11834
0
    if (child != NULL) {
11835
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11836
0
      xmlSchemaPContentErr(ctxt,
11837
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11838
0
    NULL, node, child, NULL,
11839
0
    "annotation?, (group | all | choice | sequence)?, "
11840
0
    "((attribute | attributeGroup)*, anyAttribute?))");
11841
0
  } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11842
0
       xmlSchemaPContentErr(ctxt,
11843
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11844
0
    NULL, node, child, NULL,
11845
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11846
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11847
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11848
0
    "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11849
0
  } else {
11850
      /* Simple type */
11851
0
      xmlSchemaPContentErr(ctxt,
11852
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11853
0
    NULL, node, child, NULL,
11854
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11855
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11856
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11857
0
    "pattern)*))");
11858
0
  }
11859
0
    }
11860
0
    return (NULL);
11861
0
}
11862
11863
/**
11864
 * xmlSchemaParseExtension:
11865
 * @ctxt:  a schema validation context
11866
 * @schema:  the schema being built
11867
 * @node:  a subtree containing XML Schema information
11868
 *
11869
 * Parses an <extension>, which is found inside a
11870
 * <simpleContent> or <complexContent>.
11871
 * *WARNING* this interface is highly subject to change.
11872
 *
11873
 * TODO: Returns the type definition or NULL in case of error
11874
 */
11875
static xmlSchemaTypePtr
11876
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11877
                        xmlNodePtr node, xmlSchemaTypeType parentType)
11878
0
{
11879
0
    xmlSchemaTypePtr type;
11880
0
    xmlNodePtr child = NULL;
11881
0
    xmlAttrPtr attr;
11882
11883
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11884
0
        return (NULL);
11885
    /* Not a component, don't create it. */
11886
0
    type = ctxt->ctxtType;
11887
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11888
11889
    /*
11890
    * Check for illegal attributes.
11891
    */
11892
0
    attr = node->properties;
11893
0
    while (attr != NULL) {
11894
0
  if (attr->ns == NULL) {
11895
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11896
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11897
0
    xmlSchemaPIllegalAttrErr(ctxt,
11898
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11899
0
      }
11900
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11901
0
      xmlSchemaPIllegalAttrErr(ctxt,
11902
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11903
0
  }
11904
0
  attr = attr->next;
11905
0
    }
11906
11907
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11908
11909
    /*
11910
    * Attribute "base" - mandatory.
11911
    */
11912
0
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11913
0
  "base", &(type->baseNs), &(type->base)) == 0) &&
11914
0
  (type->base == NULL)) {
11915
0
  xmlSchemaPMissingAttrErr(ctxt,
11916
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11917
0
      NULL, node, "base", NULL);
11918
0
    }
11919
    /*
11920
    * And now for the children...
11921
    */
11922
0
    child = node->children;
11923
0
    if (IS_SCHEMA(child, "annotation")) {
11924
  /*
11925
  * Add the annotation to the type ancestor.
11926
  */
11927
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11928
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11929
0
        child = child->next;
11930
0
    }
11931
0
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11932
  /*
11933
  * Corresponds to <complexType><complexContent><extension>... and:
11934
  *
11935
  * Model groups <all>, <choice>, <sequence> and <group>.
11936
  */
11937
0
  if (IS_SCHEMA(child, "all")) {
11938
0
      type->subtypes = (xmlSchemaTypePtr)
11939
0
    xmlSchemaParseModelGroup(ctxt, schema,
11940
0
        child, XML_SCHEMA_TYPE_ALL, 1);
11941
0
      child = child->next;
11942
0
  } else if (IS_SCHEMA(child, "choice")) {
11943
0
      type->subtypes = (xmlSchemaTypePtr)
11944
0
    xmlSchemaParseModelGroup(ctxt, schema,
11945
0
        child, XML_SCHEMA_TYPE_CHOICE, 1);
11946
0
      child = child->next;
11947
0
  } else if (IS_SCHEMA(child, "sequence")) {
11948
0
      type->subtypes = (xmlSchemaTypePtr)
11949
0
    xmlSchemaParseModelGroup(ctxt, schema,
11950
0
    child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11951
0
      child = child->next;
11952
0
  } else if (IS_SCHEMA(child, "group")) {
11953
0
      type->subtypes = (xmlSchemaTypePtr)
11954
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11955
      /*
11956
      * Note that the reference will be resolved in
11957
      * xmlSchemaResolveTypeReferences();
11958
      */
11959
0
      child = child->next;
11960
0
  }
11961
0
    }
11962
0
    if (child != NULL) {
11963
  /*
11964
  * Attribute uses/declarations.
11965
  */
11966
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11967
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11968
0
      XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11969
0
      return(NULL);
11970
  /*
11971
  * Attribute wildcard.
11972
  */
11973
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11974
0
      ctxt->ctxtType->attributeWildcard =
11975
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11976
0
      child = child->next;
11977
0
  }
11978
0
    }
11979
0
    if (child != NULL) {
11980
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11981
      /* Complex content extension. */
11982
0
      xmlSchemaPContentErr(ctxt,
11983
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11984
0
    NULL, node, child, NULL,
11985
0
    "(annotation?, ((group | all | choice | sequence)?, "
11986
0
    "((attribute | attributeGroup)*, anyAttribute?)))");
11987
0
  } else {
11988
      /* Simple content extension. */
11989
0
      xmlSchemaPContentErr(ctxt,
11990
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11991
0
    NULL, node, child, NULL,
11992
0
    "(annotation?, ((attribute | attributeGroup)*, "
11993
0
    "anyAttribute?))");
11994
0
  }
11995
0
    }
11996
0
    return (NULL);
11997
0
}
11998
11999
/**
12000
 * xmlSchemaParseSimpleContent:
12001
 * @ctxt:  a schema validation context
12002
 * @schema:  the schema being built
12003
 * @node:  a subtree containing XML Schema information
12004
 *
12005
 * parse a XML schema SimpleContent definition
12006
 * *WARNING* this interface is highly subject to change
12007
 *
12008
 * Returns the type definition or NULL in case of error
12009
 */
12010
static int
12011
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
12012
                            xmlSchemaPtr schema, xmlNodePtr node,
12013
          int *hasRestrictionOrExtension)
12014
0
{
12015
0
    xmlSchemaTypePtr type;
12016
0
    xmlNodePtr child = NULL;
12017
0
    xmlAttrPtr attr;
12018
12019
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
12020
0
  (hasRestrictionOrExtension == NULL))
12021
0
        return (-1);
12022
0
    *hasRestrictionOrExtension = 0;
12023
    /* Not a component, don't create it. */
12024
0
    type = ctxt->ctxtType;
12025
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
12026
    /*
12027
    * Check for illegal attributes.
12028
    */
12029
0
    attr = node->properties;
12030
0
    while (attr != NULL) {
12031
0
  if (attr->ns == NULL) {
12032
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
12033
0
    xmlSchemaPIllegalAttrErr(ctxt,
12034
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12035
0
      }
12036
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12037
0
      xmlSchemaPIllegalAttrErr(ctxt,
12038
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12039
0
  }
12040
0
  attr = attr->next;
12041
0
    }
12042
12043
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12044
12045
    /*
12046
    * And now for the children...
12047
    */
12048
0
    child = node->children;
12049
0
    if (IS_SCHEMA(child, "annotation")) {
12050
  /*
12051
  * Add the annotation to the complex type ancestor.
12052
  */
12053
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12054
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
12055
0
        child = child->next;
12056
0
    }
12057
0
    if (child == NULL) {
12058
0
  xmlSchemaPContentErr(ctxt,
12059
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12060
0
      NULL, node, NULL, NULL,
12061
0
      "(annotation?, (restriction | extension))");
12062
0
    }
12063
0
    if (child == NULL) {
12064
0
  xmlSchemaPContentErr(ctxt,
12065
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12066
0
      NULL, node, NULL, NULL,
12067
0
      "(annotation?, (restriction | extension))");
12068
0
    }
12069
0
    if (IS_SCHEMA(child, "restriction")) {
12070
0
        xmlSchemaParseRestriction(ctxt, schema, child,
12071
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
12072
0
  (*hasRestrictionOrExtension) = 1;
12073
0
        child = child->next;
12074
0
    } else if (IS_SCHEMA(child, "extension")) {
12075
0
        xmlSchemaParseExtension(ctxt, schema, child,
12076
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
12077
0
  (*hasRestrictionOrExtension) = 1;
12078
0
        child = child->next;
12079
0
    }
12080
0
    if (child != NULL) {
12081
0
  xmlSchemaPContentErr(ctxt,
12082
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12083
0
      NULL, node, child, NULL,
12084
0
      "(annotation?, (restriction | extension))");
12085
0
    }
12086
0
    return (0);
12087
0
}
12088
12089
/**
12090
 * xmlSchemaParseComplexContent:
12091
 * @ctxt:  a schema validation context
12092
 * @schema:  the schema being built
12093
 * @node:  a subtree containing XML Schema information
12094
 *
12095
 * parse a XML schema ComplexContent definition
12096
 * *WARNING* this interface is highly subject to change
12097
 *
12098
 * Returns the type definition or NULL in case of error
12099
 */
12100
static int
12101
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
12102
                             xmlSchemaPtr schema, xmlNodePtr node,
12103
           int *hasRestrictionOrExtension)
12104
0
{
12105
0
    xmlSchemaTypePtr type;
12106
0
    xmlNodePtr child = NULL;
12107
0
    xmlAttrPtr attr;
12108
12109
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
12110
0
  (hasRestrictionOrExtension == NULL))
12111
0
        return (-1);
12112
0
    *hasRestrictionOrExtension = 0;
12113
    /* Not a component, don't create it. */
12114
0
    type = ctxt->ctxtType;
12115
    /*
12116
    * Check for illegal attributes.
12117
    */
12118
0
    attr = node->properties;
12119
0
    while (attr != NULL) {
12120
0
  if (attr->ns == NULL) {
12121
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
12122
0
    (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
12123
0
      {
12124
0
    xmlSchemaPIllegalAttrErr(ctxt,
12125
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12126
0
      }
12127
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12128
0
      xmlSchemaPIllegalAttrErr(ctxt,
12129
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12130
0
  }
12131
0
  attr = attr->next;
12132
0
    }
12133
12134
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12135
12136
    /*
12137
    * Set the 'mixed' on the complex type ancestor.
12138
    */
12139
0
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12140
0
  if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12141
0
      type->flags |= XML_SCHEMAS_TYPE_MIXED;
12142
0
    }
12143
0
    child = node->children;
12144
0
    if (IS_SCHEMA(child, "annotation")) {
12145
  /*
12146
  * Add the annotation to the complex type ancestor.
12147
  */
12148
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12149
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
12150
0
        child = child->next;
12151
0
    }
12152
0
    if (child == NULL) {
12153
0
  xmlSchemaPContentErr(ctxt,
12154
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12155
0
      NULL, node, NULL,
12156
0
      NULL, "(annotation?, (restriction | extension))");
12157
0
    }
12158
0
    if (child == NULL) {
12159
0
  xmlSchemaPContentErr(ctxt,
12160
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12161
0
      NULL, node, NULL,
12162
0
      NULL, "(annotation?, (restriction | extension))");
12163
0
    }
12164
0
    if (IS_SCHEMA(child, "restriction")) {
12165
0
        xmlSchemaParseRestriction(ctxt, schema, child,
12166
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12167
0
  (*hasRestrictionOrExtension) = 1;
12168
0
        child = child->next;
12169
0
    } else if (IS_SCHEMA(child, "extension")) {
12170
0
        xmlSchemaParseExtension(ctxt, schema, child,
12171
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12172
0
  (*hasRestrictionOrExtension) = 1;
12173
0
        child = child->next;
12174
0
    }
12175
0
    if (child != NULL) {
12176
0
  xmlSchemaPContentErr(ctxt,
12177
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12178
0
      NULL, node, child,
12179
0
      NULL, "(annotation?, (restriction | extension))");
12180
0
    }
12181
0
    return (0);
12182
0
}
12183
12184
/**
12185
 * xmlSchemaParseComplexType:
12186
 * @ctxt:  a schema validation context
12187
 * @schema:  the schema being built
12188
 * @node:  a subtree containing XML Schema information
12189
 *
12190
 * parse a XML schema Complex Type definition
12191
 * *WARNING* this interface is highly subject to change
12192
 *
12193
 * Returns the type definition or NULL in case of error
12194
 */
12195
static xmlSchemaTypePtr
12196
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12197
                          xmlNodePtr node, int topLevel)
12198
0
{
12199
0
    xmlSchemaTypePtr type, ctxtType;
12200
0
    xmlNodePtr child = NULL;
12201
0
    const xmlChar *name = NULL;
12202
0
    xmlAttrPtr attr;
12203
0
    const xmlChar *attrValue;
12204
#ifdef ENABLE_NAMED_LOCALS
12205
    char buf[40];
12206
#endif
12207
0
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
12208
12209
12210
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12211
0
        return (NULL);
12212
12213
0
    ctxtType = ctxt->ctxtType;
12214
12215
0
    if (topLevel) {
12216
0
  attr = xmlSchemaGetPropNode(node, "name");
12217
0
  if (attr == NULL) {
12218
0
      xmlSchemaPMissingAttrErr(ctxt,
12219
0
    XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12220
0
      return (NULL);
12221
0
  } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12222
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12223
0
      return (NULL);
12224
0
  }
12225
0
    }
12226
12227
0
    if (topLevel == 0) {
12228
  /*
12229
  * Parse as local complex type definition.
12230
  */
12231
#ifdef ENABLE_NAMED_LOCALS
12232
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12233
  type = xmlSchemaAddType(ctxt, schema,
12234
      XML_SCHEMA_TYPE_COMPLEX,
12235
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12236
      ctxt->targetNamespace, node, 0);
12237
#else
12238
0
  type = xmlSchemaAddType(ctxt, schema,
12239
0
      XML_SCHEMA_TYPE_COMPLEX,
12240
0
      NULL, ctxt->targetNamespace, node, 0);
12241
0
#endif
12242
0
  if (type == NULL)
12243
0
      return (NULL);
12244
0
  name = type->name;
12245
0
  type->node = node;
12246
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12247
  /*
12248
  * TODO: We need the target namespace.
12249
  */
12250
0
    } else {
12251
  /*
12252
  * Parse as global complex type definition.
12253
  */
12254
0
  type = xmlSchemaAddType(ctxt, schema,
12255
0
      XML_SCHEMA_TYPE_COMPLEX,
12256
0
      name, ctxt->targetNamespace, node, 1);
12257
0
  if (type == NULL)
12258
0
      return (NULL);
12259
0
  type->node = node;
12260
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12261
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12262
0
    }
12263
0
    type->targetNamespace = ctxt->targetNamespace;
12264
    /*
12265
    * Handle attributes.
12266
    */
12267
0
    attr = node->properties;
12268
0
    while (attr != NULL) {
12269
0
  if (attr->ns == NULL) {
12270
0
      if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12271
    /*
12272
    * Attribute "id".
12273
    */
12274
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12275
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12276
    /*
12277
    * Attribute "mixed".
12278
    */
12279
0
    if (xmlSchemaPGetBoolNodeValue(ctxt,
12280
0
      NULL, (xmlNodePtr) attr))
12281
0
        type->flags |= XML_SCHEMAS_TYPE_MIXED;
12282
0
      } else if (topLevel) {
12283
    /*
12284
    * Attributes of global complex type definitions.
12285
    */
12286
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12287
        /* Pass. */
12288
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12289
        /*
12290
        * Attribute "abstract".
12291
        */
12292
0
        if (xmlSchemaPGetBoolNodeValue(ctxt,
12293
0
          NULL, (xmlNodePtr) attr))
12294
0
      type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12295
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12296
        /*
12297
        * Attribute "final".
12298
        */
12299
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12300
0
      (xmlNodePtr) attr);
12301
0
        if (xmlSchemaPValAttrBlockFinal(attrValue,
12302
0
      &(type->flags),
12303
0
      -1,
12304
0
      XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12305
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12306
0
      -1, -1, -1) != 0)
12307
0
        {
12308
0
      xmlSchemaPSimpleTypeErr(ctxt,
12309
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12310
0
          NULL, (xmlNodePtr) attr, NULL,
12311
0
          "(#all | List of (extension | restriction))",
12312
0
          attrValue, NULL, NULL, NULL);
12313
0
        } else
12314
0
      final = 1;
12315
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12316
        /*
12317
        * Attribute "block".
12318
        */
12319
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12320
0
      (xmlNodePtr) attr);
12321
0
        if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12322
0
      -1,
12323
0
      XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12324
0
      XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12325
0
      -1, -1, -1) != 0) {
12326
0
      xmlSchemaPSimpleTypeErr(ctxt,
12327
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12328
0
          NULL, (xmlNodePtr) attr, NULL,
12329
0
          "(#all | List of (extension | restriction)) ",
12330
0
          attrValue, NULL, NULL, NULL);
12331
0
        } else
12332
0
      block = 1;
12333
0
    } else {
12334
0
      xmlSchemaPIllegalAttrErr(ctxt,
12335
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12336
0
    }
12337
0
      } else {
12338
0
    xmlSchemaPIllegalAttrErr(ctxt,
12339
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12340
0
      }
12341
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12342
0
      xmlSchemaPIllegalAttrErr(ctxt,
12343
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12344
0
  }
12345
0
  attr = attr->next;
12346
0
    }
12347
0
    if (! block) {
12348
  /*
12349
  * Apply default "block" values.
12350
  */
12351
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12352
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12353
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12354
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12355
0
    }
12356
0
    if (! final) {
12357
  /*
12358
  * Apply default "block" values.
12359
  */
12360
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12361
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12362
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12363
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12364
0
    }
12365
    /*
12366
    * And now for the children...
12367
    */
12368
0
    child = node->children;
12369
0
    if (IS_SCHEMA(child, "annotation")) {
12370
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12371
0
        child = child->next;
12372
0
    }
12373
0
    ctxt->ctxtType = type;
12374
0
    if (IS_SCHEMA(child, "simpleContent")) {
12375
  /*
12376
  * <complexType><simpleContent>...
12377
  * 3.4.3 : 2.2
12378
  * Specifying mixed='true' when the <simpleContent>
12379
  * alternative is chosen has no effect
12380
  */
12381
0
  if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12382
0
      type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12383
0
        xmlSchemaParseSimpleContent(ctxt, schema, child,
12384
0
      &hasRestrictionOrExtension);
12385
0
        child = child->next;
12386
0
    } else if (IS_SCHEMA(child, "complexContent")) {
12387
  /*
12388
  * <complexType><complexContent>...
12389
  */
12390
0
  type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12391
0
        xmlSchemaParseComplexContent(ctxt, schema, child,
12392
0
      &hasRestrictionOrExtension);
12393
0
        child = child->next;
12394
0
    } else {
12395
  /*
12396
  * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12397
  *
12398
  * SPEC
12399
  * "...the third alternative (neither <simpleContent> nor
12400
  * <complexContent>) is chosen. This case is understood as shorthand
12401
  * for complex content restricting the `ur-type definition`, and the
12402
  * details of the mappings should be modified as necessary.
12403
  */
12404
0
  type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12405
0
  type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12406
  /*
12407
  * Parse model groups.
12408
  */
12409
0
        if (IS_SCHEMA(child, "all")) {
12410
0
            type->subtypes = (xmlSchemaTypePtr)
12411
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12412
0
        XML_SCHEMA_TYPE_ALL, 1);
12413
0
            child = child->next;
12414
0
        } else if (IS_SCHEMA(child, "choice")) {
12415
0
            type->subtypes = (xmlSchemaTypePtr)
12416
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12417
0
        XML_SCHEMA_TYPE_CHOICE, 1);
12418
0
            child = child->next;
12419
0
        } else if (IS_SCHEMA(child, "sequence")) {
12420
0
            type->subtypes = (xmlSchemaTypePtr)
12421
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12422
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
12423
0
            child = child->next;
12424
0
        } else if (IS_SCHEMA(child, "group")) {
12425
0
            type->subtypes = (xmlSchemaTypePtr)
12426
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12427
      /*
12428
      * Note that the reference will be resolved in
12429
      * xmlSchemaResolveTypeReferences();
12430
      */
12431
0
            child = child->next;
12432
0
        }
12433
  /*
12434
  * Parse attribute decls/refs.
12435
  */
12436
0
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12437
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
12438
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12439
0
      return(NULL);
12440
  /*
12441
  * Parse attribute wildcard.
12442
  */
12443
0
  if (IS_SCHEMA(child, "anyAttribute")) {
12444
0
      type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12445
0
      child = child->next;
12446
0
  }
12447
0
    }
12448
0
    if (child != NULL) {
12449
0
  xmlSchemaPContentErr(ctxt,
12450
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12451
0
      NULL, node, child,
12452
0
      NULL, "(annotation?, (simpleContent | complexContent | "
12453
0
      "((group | all | choice | sequence)?, ((attribute | "
12454
0
      "attributeGroup)*, anyAttribute?))))");
12455
0
    }
12456
    /*
12457
    * REDEFINE: SPEC src-redefine (5)
12458
    */
12459
0
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12460
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12461
0
      NULL, node, "This is a redefinition, thus the "
12462
0
      "<complexType> must have a <restriction> or <extension> "
12463
0
      "grand-child", NULL);
12464
0
    }
12465
0
    ctxt->ctxtType = ctxtType;
12466
0
    return (type);
12467
0
}
12468
12469
/************************************************************************
12470
 *                  *
12471
 *      Validating using Schemas      *
12472
 *                  *
12473
 ************************************************************************/
12474
12475
/************************************************************************
12476
 *                  *
12477
 *      Reading/Writing Schemas       *
12478
 *                  *
12479
 ************************************************************************/
12480
12481
#if 0 /* Will be enabled if it is clear what options are needed. */
12482
/**
12483
 * xmlSchemaParserCtxtSetOptions:
12484
 * @ctxt: a schema parser context
12485
 * @options: a combination of xmlSchemaParserOption
12486
 *
12487
 * Sets the options to be used during the parse.
12488
 *
12489
 * Returns 0 in case of success, -1 in case of an
12490
 * API error.
12491
 */
12492
static int
12493
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12494
            int options)
12495
12496
{
12497
    int i;
12498
12499
    if (ctxt == NULL)
12500
  return (-1);
12501
    /*
12502
    * WARNING: Change the start value if adding to the
12503
    * xmlSchemaParseOption.
12504
    */
12505
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
12506
        if (options & 1<<i) {
12507
      return (-1);
12508
        }
12509
    }
12510
    ctxt->options = options;
12511
    return (0);
12512
}
12513
12514
/**
12515
 * xmlSchemaValidCtxtGetOptions:
12516
 * @ctxt: a schema parser context
12517
 *
12518
 * Returns the option combination of the parser context.
12519
 */
12520
static int
12521
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12522
12523
{
12524
    if (ctxt == NULL)
12525
  return (-1);
12526
    else
12527
  return (ctxt->options);
12528
}
12529
#endif
12530
12531
/**
12532
 * xmlSchemaNewParserCtxt:
12533
 * @URL:  the location of the schema
12534
 *
12535
 * Create an XML Schemas parse context for that file/resource expected
12536
 * to contain an XML Schemas file.
12537
 *
12538
 * Returns the parser context or NULL in case of error
12539
 */
12540
xmlSchemaParserCtxtPtr
12541
xmlSchemaNewParserCtxt(const char *URL)
12542
0
{
12543
0
    xmlSchemaParserCtxtPtr ret;
12544
12545
0
    if (URL == NULL)
12546
0
        return (NULL);
12547
12548
0
    ret = xmlSchemaParserCtxtCreate();
12549
0
    if (ret == NULL)
12550
0
  return(NULL);
12551
0
    ret->dict = xmlDictCreate();
12552
0
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12553
0
    return (ret);
12554
0
}
12555
12556
/**
12557
 * xmlSchemaNewMemParserCtxt:
12558
 * @buffer:  a pointer to a char array containing the schemas
12559
 * @size:  the size of the array
12560
 *
12561
 * Create an XML Schemas parse context for that memory buffer expected
12562
 * to contain an XML Schemas file.
12563
 *
12564
 * Returns the parser context or NULL in case of error
12565
 */
12566
xmlSchemaParserCtxtPtr
12567
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12568
0
{
12569
0
    xmlSchemaParserCtxtPtr ret;
12570
12571
0
    if ((buffer == NULL) || (size <= 0))
12572
0
        return (NULL);
12573
0
    ret = xmlSchemaParserCtxtCreate();
12574
0
    if (ret == NULL)
12575
0
  return(NULL);
12576
0
    ret->buffer = buffer;
12577
0
    ret->size = size;
12578
0
    ret->dict = xmlDictCreate();
12579
0
    return (ret);
12580
0
}
12581
12582
/**
12583
 * xmlSchemaNewDocParserCtxt:
12584
 * @doc:  a preparsed document tree
12585
 *
12586
 * Create an XML Schemas parse context for that document.
12587
 * NB. The document may be modified during the parsing process.
12588
 *
12589
 * Returns the parser context or NULL in case of error
12590
 */
12591
xmlSchemaParserCtxtPtr
12592
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12593
0
{
12594
0
    xmlSchemaParserCtxtPtr ret;
12595
12596
0
    if (doc == NULL)
12597
0
      return (NULL);
12598
0
    ret = xmlSchemaParserCtxtCreate();
12599
0
    if (ret == NULL)
12600
0
  return(NULL);
12601
0
    ret->doc = doc;
12602
0
    ret->dict = xmlDictCreate();
12603
    /* The application has responsibility for the document */
12604
0
    ret->preserve = 1;
12605
12606
0
    return (ret);
12607
0
}
12608
12609
/**
12610
 * xmlSchemaFreeParserCtxt:
12611
 * @ctxt:  the schema parser context
12612
 *
12613
 * Free the resources associated to the schema parser context
12614
 */
12615
void
12616
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12617
0
{
12618
0
    if (ctxt == NULL)
12619
0
        return;
12620
0
    if (ctxt->doc != NULL && !ctxt->preserve)
12621
0
        xmlFreeDoc(ctxt->doc);
12622
0
    if (ctxt->vctxt != NULL) {
12623
0
  xmlSchemaFreeValidCtxt(ctxt->vctxt);
12624
0
    }
12625
0
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12626
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
12627
0
  ctxt->constructor = NULL;
12628
0
  ctxt->ownsConstructor = 0;
12629
0
    }
12630
0
    if (ctxt->attrProhibs != NULL)
12631
0
  xmlSchemaItemListFree(ctxt->attrProhibs);
12632
0
    xmlDictFree(ctxt->dict);
12633
0
    xmlFree(ctxt);
12634
0
}
12635
12636
/************************************************************************
12637
 *                  *
12638
 *      Building the content models     *
12639
 *                  *
12640
 ************************************************************************/
12641
12642
/**
12643
 * xmlSchemaBuildContentModelForSubstGroup:
12644
 *
12645
 * Returns 1 if nillable, 0 otherwise
12646
 */
12647
static int
12648
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12649
  xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12650
0
{
12651
0
    xmlAutomataStatePtr start, tmp;
12652
0
    xmlSchemaElementPtr elemDecl, member;
12653
0
    xmlSchemaSubstGroupPtr substGroup;
12654
0
    int i;
12655
0
    int ret = 0;
12656
12657
0
    elemDecl = (xmlSchemaElementPtr) particle->children;
12658
    /*
12659
    * Wrap the substitution group with a CHOICE.
12660
    */
12661
0
    start = pctxt->state;
12662
0
    if (end == NULL)
12663
0
  end = xmlAutomataNewState(pctxt->am);
12664
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12665
0
    if (substGroup == NULL) {
12666
0
  xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12667
0
      XML_SCHEMAP_INTERNAL,
12668
0
      "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12669
0
      "declaration is marked having a subst. group but none "
12670
0
      "available.\n", elemDecl->name, NULL);
12671
0
  return(0);
12672
0
    }
12673
0
    if (counter >= 0) {
12674
  /*
12675
  * NOTE that we put the declaration in, even if it's abstract.
12676
  * However, an error will be raised during *validation* if an element
12677
  * information item shall be validated against an abstract element
12678
  * declaration.
12679
  */
12680
0
  tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12681
0
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
12682
0
              elemDecl->name, elemDecl->targetNamespace, elemDecl);
12683
  /*
12684
  * Add subst. group members.
12685
  */
12686
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12687
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12688
0
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
12689
0
                   member->name, member->targetNamespace, member);
12690
0
  }
12691
0
    } else if (particle->maxOccurs == 1) {
12692
  /*
12693
  * NOTE that we put the declaration in, even if it's abstract,
12694
  */
12695
0
  xmlAutomataNewEpsilon(pctxt->am,
12696
0
      xmlAutomataNewTransition2(pctxt->am,
12697
0
      start, NULL,
12698
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12699
  /*
12700
  * Add subst. group members.
12701
  */
12702
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12703
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12704
      /*
12705
      * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12706
      *  was incorrectly used instead of xmlAutomataNewTransition2()
12707
      *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12708
      *  section in xmlSchemaBuildAContentModel() ).
12709
      * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12710
      *  intended for the above "counter" section originally. I.e.,
12711
      *  check xs:all with subst-groups.
12712
      *
12713
      * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12714
      *                member->name, member->targetNamespace,
12715
      *          1, 1, member);
12716
      */
12717
0
      tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12718
0
    member->name, member->targetNamespace, member);
12719
0
      xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12720
0
  }
12721
0
    } else {
12722
0
  xmlAutomataStatePtr hop;
12723
0
  int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12724
0
      UNBOUNDED : particle->maxOccurs - 1;
12725
0
  int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12726
12727
0
  counter =
12728
0
      xmlAutomataNewCounter(pctxt->am, minOccurs,
12729
0
      maxOccurs);
12730
0
  hop = xmlAutomataNewState(pctxt->am);
12731
12732
0
  xmlAutomataNewEpsilon(pctxt->am,
12733
0
      xmlAutomataNewTransition2(pctxt->am,
12734
0
      start, NULL,
12735
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl),
12736
0
      hop);
12737
  /*
12738
   * Add subst. group members.
12739
   */
12740
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12741
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12742
0
      xmlAutomataNewEpsilon(pctxt->am,
12743
0
    xmlAutomataNewTransition2(pctxt->am,
12744
0
    start, NULL,
12745
0
    member->name, member->targetNamespace, member),
12746
0
    hop);
12747
0
  }
12748
0
  xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12749
0
  xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12750
0
    }
12751
0
    if (particle->minOccurs == 0) {
12752
0
  xmlAutomataNewEpsilon(pctxt->am, start, end);
12753
0
        ret = 1;
12754
0
    }
12755
0
    pctxt->state = end;
12756
0
    return(ret);
12757
0
}
12758
12759
/**
12760
 * xmlSchemaBuildContentModelForElement:
12761
 *
12762
 * Returns 1 if nillable, 0 otherwise
12763
 */
12764
static int
12765
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12766
             xmlSchemaParticlePtr particle)
12767
0
{
12768
0
    int ret = 0;
12769
12770
0
    if (((xmlSchemaElementPtr) particle->children)->flags &
12771
0
  XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12772
  /*
12773
  * Substitution groups.
12774
  */
12775
0
  ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12776
0
    } else {
12777
0
  xmlSchemaElementPtr elemDecl;
12778
0
  xmlAutomataStatePtr start;
12779
12780
0
  elemDecl = (xmlSchemaElementPtr) particle->children;
12781
12782
0
  if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12783
0
      return(0);
12784
0
  if (particle->maxOccurs == 1) {
12785
0
      start = ctxt->state;
12786
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12787
0
        elemDecl->name, elemDecl->targetNamespace, elemDecl);
12788
0
  } else if ((particle->maxOccurs >= UNBOUNDED) &&
12789
0
             (particle->minOccurs < 2)) {
12790
      /* Special case. */
12791
0
      start = ctxt->state;
12792
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12793
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12794
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12795
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12796
0
  } else {
12797
0
      int counter;
12798
0
      int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12799
0
          UNBOUNDED : particle->maxOccurs - 1;
12800
0
      int minOccurs = particle->minOccurs < 1 ?
12801
0
          0 : particle->minOccurs - 1;
12802
12803
0
      start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12804
0
      counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12805
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12806
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12807
0
      xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12808
0
      ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12809
0
    NULL, counter);
12810
0
  }
12811
0
  if (particle->minOccurs == 0) {
12812
0
      xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12813
0
            ret = 1;
12814
0
        }
12815
0
    }
12816
0
    return(ret);
12817
0
}
12818
12819
/**
12820
 * xmlSchemaBuildAContentModel:
12821
 * @ctxt:  the schema parser context
12822
 * @particle:  the particle component
12823
 * @name:  the complex type's name whose content is being built
12824
 *
12825
 * Create the automaton for the {content type} of a complex type.
12826
 *
12827
 * Returns 1 if the content is nillable, 0 otherwise
12828
 */
12829
static int
12830
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12831
          xmlSchemaParticlePtr particle)
12832
0
{
12833
0
    int ret = 0, tmp2;
12834
12835
0
    if (particle == NULL) {
12836
0
  PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12837
0
  return(1);
12838
0
    }
12839
0
    if (particle->children == NULL) {
12840
  /*
12841
  * Just return in this case. A missing "term" of the particle
12842
  * might arise due to an invalid "term" component.
12843
  */
12844
0
  return(1);
12845
0
    }
12846
12847
0
    switch (particle->children->type) {
12848
0
  case XML_SCHEMA_TYPE_ANY: {
12849
0
      xmlAutomataStatePtr start, end;
12850
0
      xmlSchemaWildcardPtr wild;
12851
0
      xmlSchemaWildcardNsPtr ns;
12852
12853
0
      wild = (xmlSchemaWildcardPtr) particle->children;
12854
12855
0
      start = pctxt->state;
12856
0
      end = xmlAutomataNewState(pctxt->am);
12857
12858
0
      if (particle->maxOccurs == 1) {
12859
0
    if (wild->any == 1) {
12860
        /*
12861
        * We need to add both transitions:
12862
        *
12863
        * 1. the {"*", "*"} for elements in a namespace.
12864
        */
12865
0
        pctxt->state =
12866
0
      xmlAutomataNewTransition2(pctxt->am,
12867
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12868
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12869
        /*
12870
        * 2. the {"*"} for elements in no namespace.
12871
        */
12872
0
        pctxt->state =
12873
0
      xmlAutomataNewTransition2(pctxt->am,
12874
0
      start, NULL, BAD_CAST "*", NULL, wild);
12875
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12876
12877
0
    } else if (wild->nsSet != NULL) {
12878
0
        ns = wild->nsSet;
12879
0
        do {
12880
0
      pctxt->state = start;
12881
0
      pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12882
0
          pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12883
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12884
0
      ns = ns->next;
12885
0
        } while (ns != NULL);
12886
12887
0
    } else if (wild->negNsSet != NULL) {
12888
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12889
0
      start, end, BAD_CAST "*", wild->negNsSet->value,
12890
0
      wild);
12891
0
    }
12892
0
      } else {
12893
0
    int counter;
12894
0
    xmlAutomataStatePtr hop;
12895
0
    int maxOccurs =
12896
0
        particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12897
0
                                           particle->maxOccurs - 1;
12898
0
    int minOccurs =
12899
0
        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12900
12901
0
    counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12902
0
    hop = xmlAutomataNewState(pctxt->am);
12903
0
    if (wild->any == 1) {
12904
0
        pctxt->state =
12905
0
      xmlAutomataNewTransition2(pctxt->am,
12906
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12907
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12908
0
        pctxt->state =
12909
0
      xmlAutomataNewTransition2(pctxt->am,
12910
0
      start, NULL, BAD_CAST "*", NULL, wild);
12911
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12912
0
    } else if (wild->nsSet != NULL) {
12913
0
        ns = wild->nsSet;
12914
0
        do {
12915
0
      pctxt->state =
12916
0
          xmlAutomataNewTransition2(pctxt->am,
12917
0
        start, NULL, BAD_CAST "*", ns->value, wild);
12918
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12919
0
      ns = ns->next;
12920
0
        } while (ns != NULL);
12921
12922
0
    } else if (wild->negNsSet != NULL) {
12923
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12924
0
      start, hop, BAD_CAST "*", wild->negNsSet->value,
12925
0
      wild);
12926
0
    }
12927
0
    xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12928
0
    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12929
0
      }
12930
0
      if (particle->minOccurs == 0) {
12931
0
    xmlAutomataNewEpsilon(pctxt->am, start, end);
12932
0
                ret = 1;
12933
0
      }
12934
0
      pctxt->state = end;
12935
0
            break;
12936
0
  }
12937
0
        case XML_SCHEMA_TYPE_ELEMENT:
12938
0
      ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12939
0
      break;
12940
0
        case XML_SCHEMA_TYPE_SEQUENCE:{
12941
0
            xmlSchemaTreeItemPtr sub;
12942
12943
0
            ret = 1;
12944
            /*
12945
             * If max and min occurrences are default (1) then
12946
             * simply iterate over the particles of the <sequence>.
12947
             */
12948
0
            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12949
0
                sub = particle->children->children;
12950
12951
0
                while (sub != NULL) {
12952
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12953
0
                                        (xmlSchemaParticlePtr) sub);
12954
0
                    if (tmp2 != 1) ret = 0;
12955
0
                    sub = sub->next;
12956
0
                }
12957
0
            } else {
12958
0
                xmlAutomataStatePtr oldstate = pctxt->state;
12959
12960
0
                if (particle->maxOccurs >= UNBOUNDED) {
12961
0
                    if (particle->minOccurs > 1) {
12962
0
                        xmlAutomataStatePtr tmp;
12963
0
                        int counter;
12964
12965
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12966
0
                            oldstate, NULL);
12967
0
                        oldstate = pctxt->state;
12968
12969
0
                        counter = xmlAutomataNewCounter(pctxt->am,
12970
0
                            particle->minOccurs - 1, UNBOUNDED);
12971
12972
0
                        sub = particle->children->children;
12973
0
                        while (sub != NULL) {
12974
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12975
0
                                            (xmlSchemaParticlePtr) sub);
12976
0
                            if (tmp2 != 1) ret = 0;
12977
0
                            sub = sub->next;
12978
0
                        }
12979
0
                        tmp = pctxt->state;
12980
0
                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
12981
0
                                                   oldstate, counter);
12982
0
                        pctxt->state =
12983
0
                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
12984
0
                                                       NULL, counter);
12985
0
                        if (ret == 1)
12986
0
                            xmlAutomataNewEpsilon(pctxt->am,
12987
0
                                                oldstate, pctxt->state);
12988
12989
0
                    } else {
12990
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12991
0
                            oldstate, NULL);
12992
0
                        oldstate = pctxt->state;
12993
12994
0
                        sub = particle->children->children;
12995
0
                        while (sub != NULL) {
12996
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12997
0
                                        (xmlSchemaParticlePtr) sub);
12998
0
                            if (tmp2 != 1) ret = 0;
12999
0
                            sub = sub->next;
13000
0
                        }
13001
0
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
13002
0
                                              oldstate);
13003
                        /*
13004
                         * epsilon needed to block previous trans from
13005
                         * being allowed to enter back from another
13006
                         * construct
13007
                         */
13008
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13009
0
                                            pctxt->state, NULL);
13010
0
                        if (particle->minOccurs == 0) {
13011
0
                            xmlAutomataNewEpsilon(pctxt->am,
13012
0
                                oldstate, pctxt->state);
13013
0
                            ret = 1;
13014
0
                        }
13015
0
                    }
13016
0
                } else if ((particle->maxOccurs > 1)
13017
0
                           || (particle->minOccurs > 1)) {
13018
0
                    xmlAutomataStatePtr tmp;
13019
0
                    int counter;
13020
13021
0
                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13022
0
                        oldstate, NULL);
13023
0
                    oldstate = pctxt->state;
13024
13025
0
                    counter = xmlAutomataNewCounter(pctxt->am,
13026
0
                        particle->minOccurs - 1,
13027
0
                        particle->maxOccurs - 1);
13028
13029
0
                    sub = particle->children->children;
13030
0
                    while (sub != NULL) {
13031
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
13032
0
                                        (xmlSchemaParticlePtr) sub);
13033
0
                        if (tmp2 != 1) ret = 0;
13034
0
                        sub = sub->next;
13035
0
                    }
13036
0
                    tmp = pctxt->state;
13037
0
                    xmlAutomataNewCountedTrans(pctxt->am,
13038
0
                        tmp, oldstate, counter);
13039
0
                    pctxt->state =
13040
0
                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
13041
0
                                                   counter);
13042
0
                    if ((particle->minOccurs == 0) || (ret == 1)) {
13043
0
                        xmlAutomataNewEpsilon(pctxt->am,
13044
0
                                            oldstate, pctxt->state);
13045
0
                        ret = 1;
13046
0
                    }
13047
0
                } else {
13048
0
                    sub = particle->children->children;
13049
0
                    while (sub != NULL) {
13050
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
13051
0
                                        (xmlSchemaParticlePtr) sub);
13052
0
                        if (tmp2 != 1) ret = 0;
13053
0
                        sub = sub->next;
13054
0
                    }
13055
13056
        /*
13057
         * epsilon needed to block previous trans from
13058
         * being allowed to enter back from another
13059
         * construct
13060
         */
13061
0
        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13062
0
          pctxt->state, NULL);
13063
13064
0
                    if (particle->minOccurs == 0) {
13065
0
                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
13066
0
                                              pctxt->state);
13067
0
                        ret = 1;
13068
0
                    }
13069
0
                }
13070
0
            }
13071
0
            break;
13072
0
        }
13073
0
        case XML_SCHEMA_TYPE_CHOICE:{
13074
0
            xmlSchemaTreeItemPtr sub;
13075
0
            xmlAutomataStatePtr start, end;
13076
13077
0
            ret = 0;
13078
0
            start = pctxt->state;
13079
0
            end = xmlAutomataNewState(pctxt->am);
13080
13081
            /*
13082
             * iterate over the subtypes and remerge the end with an
13083
             * epsilon transition
13084
             */
13085
0
            if (particle->maxOccurs == 1) {
13086
0
                sub = particle->children->children;
13087
0
                while (sub != NULL) {
13088
0
                    pctxt->state = start;
13089
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
13090
0
                                        (xmlSchemaParticlePtr) sub);
13091
0
                    if (tmp2 == 1) ret = 1;
13092
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
13093
0
                    sub = sub->next;
13094
0
                }
13095
0
            } else {
13096
0
                int counter;
13097
0
                xmlAutomataStatePtr hop, base;
13098
0
                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
13099
0
                    UNBOUNDED : particle->maxOccurs - 1;
13100
0
                int minOccurs =
13101
0
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
13102
13103
                /*
13104
                 * use a counter to keep track of the number of transitions
13105
                 * which went through the choice.
13106
                 */
13107
0
                counter =
13108
0
                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
13109
0
                hop = xmlAutomataNewState(pctxt->am);
13110
0
                base = xmlAutomataNewState(pctxt->am);
13111
13112
0
                sub = particle->children->children;
13113
0
                while (sub != NULL) {
13114
0
                    pctxt->state = base;
13115
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
13116
0
                                        (xmlSchemaParticlePtr) sub);
13117
0
                    if (tmp2 == 1) ret = 1;
13118
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
13119
0
                    sub = sub->next;
13120
0
                }
13121
0
                xmlAutomataNewEpsilon(pctxt->am, start, base);
13122
0
                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
13123
0
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
13124
0
                if (ret == 1)
13125
0
                    xmlAutomataNewEpsilon(pctxt->am, base, end);
13126
0
            }
13127
0
            if (particle->minOccurs == 0) {
13128
0
                xmlAutomataNewEpsilon(pctxt->am, start, end);
13129
0
                ret = 1;
13130
0
            }
13131
0
            pctxt->state = end;
13132
0
            break;
13133
0
        }
13134
0
        case XML_SCHEMA_TYPE_ALL:{
13135
0
            xmlAutomataStatePtr start, tmp;
13136
0
            xmlSchemaParticlePtr sub;
13137
0
            xmlSchemaElementPtr elemDecl;
13138
13139
0
            ret = 1;
13140
13141
0
            sub = (xmlSchemaParticlePtr) particle->children->children;
13142
0
            if (sub == NULL)
13143
0
                break;
13144
13145
0
            ret = 0;
13146
13147
0
            start = pctxt->state;
13148
0
            tmp = xmlAutomataNewState(pctxt->am);
13149
0
            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13150
0
            pctxt->state = tmp;
13151
0
            while (sub != NULL) {
13152
0
                pctxt->state = tmp;
13153
13154
0
                elemDecl = (xmlSchemaElementPtr) sub->children;
13155
0
                if (elemDecl == NULL) {
13156
0
                    PERROR_INT("xmlSchemaBuildAContentModel",
13157
0
                        "<element> particle has no term");
13158
0
                    return(ret);
13159
0
                };
13160
                /*
13161
                * NOTE: The {max occurs} of all the particles in the
13162
                * {particles} of the group must be 0 or 1; this is
13163
                * already ensured during the parse of the content of
13164
                * <all>.
13165
                */
13166
0
                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13167
0
                    int counter;
13168
13169
                    /*
13170
                     * This is an abstract group, we need to share
13171
                     * the same counter for all the element transitions
13172
                     * derived from the group
13173
                     */
13174
0
                    counter = xmlAutomataNewCounter(pctxt->am,
13175
0
                                       sub->minOccurs, sub->maxOccurs);
13176
0
                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
13177
0
                                       sub, counter, pctxt->state);
13178
0
                } else {
13179
0
                    if ((sub->minOccurs == 1) &&
13180
0
                        (sub->maxOccurs == 1)) {
13181
0
                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13182
0
                                                pctxt->state,
13183
0
                                                elemDecl->name,
13184
0
                                                elemDecl->targetNamespace,
13185
0
                                                1, 1, elemDecl);
13186
0
                    } else if ((sub->minOccurs == 0) &&
13187
0
                        (sub->maxOccurs == 1)) {
13188
13189
0
                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13190
0
                                                 pctxt->state,
13191
0
                                                 elemDecl->name,
13192
0
                                                 elemDecl->targetNamespace,
13193
0
                                                 0,
13194
0
                                                 1,
13195
0
                                                 elemDecl);
13196
0
                    }
13197
0
                }
13198
0
                sub = (xmlSchemaParticlePtr) sub->next;
13199
0
            }
13200
0
            pctxt->state =
13201
0
                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13202
0
            if (particle->minOccurs == 0) {
13203
0
                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13204
0
                ret = 1;
13205
0
            }
13206
0
            break;
13207
0
        }
13208
0
  case XML_SCHEMA_TYPE_GROUP:
13209
      /*
13210
      * If we hit a model group definition, then this means that
13211
      * it was empty, thus was not substituted for the containing
13212
      * model group. Just do nothing in this case.
13213
      * TODO: But the group should be substituted and not occur at
13214
      * all in the content model at this point. Fix this.
13215
      */
13216
0
            ret = 1;
13217
0
      break;
13218
0
        default:
13219
0
      xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13220
0
    "xmlSchemaBuildAContentModel",
13221
0
    "found unexpected term of type '%s' in content model",
13222
0
    WXS_ITEM_TYPE_NAME(particle->children), NULL);
13223
0
            return(ret);
13224
0
    }
13225
0
    return(ret);
13226
0
}
13227
13228
/**
13229
 * xmlSchemaBuildContentModel:
13230
 * @ctxt:  the schema parser context
13231
 * @type:  the complex type definition
13232
 * @name:  the element name
13233
 *
13234
 * Builds the content model of the complex type.
13235
 */
13236
static void
13237
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13238
         xmlSchemaParserCtxtPtr ctxt)
13239
0
{
13240
0
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13241
0
  (type->contModel != NULL) ||
13242
0
  ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13243
0
  (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13244
0
  return;
13245
13246
#ifdef DEBUG_CONTENT
13247
    xmlGenericError(xmlGenericErrorContext,
13248
                    "Building content model for %s\n", name);
13249
#endif
13250
0
    ctxt->am = NULL;
13251
0
    ctxt->am = xmlNewAutomata();
13252
0
    if (ctxt->am == NULL) {
13253
0
        xmlGenericError(xmlGenericErrorContext,
13254
0
      "Cannot create automata for complex type %s\n", type->name);
13255
0
        return;
13256
0
    }
13257
0
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
13258
    /*
13259
    * Build the automaton.
13260
    */
13261
0
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13262
0
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13263
0
    type->contModel = xmlAutomataCompile(ctxt->am);
13264
0
    if (type->contModel == NULL) {
13265
0
        xmlSchemaPCustomErr(ctxt,
13266
0
      XML_SCHEMAP_INTERNAL,
13267
0
      WXS_BASIC_CAST type, type->node,
13268
0
      "Failed to compile the content model", NULL);
13269
0
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13270
0
        xmlSchemaPCustomErr(ctxt,
13271
0
      XML_SCHEMAP_NOT_DETERMINISTIC,
13272
      /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13273
0
      WXS_BASIC_CAST type, type->node,
13274
0
      "The content model is not determinist", NULL);
13275
0
    } else {
13276
#ifdef DEBUG_CONTENT_REGEXP
13277
        xmlGenericError(xmlGenericErrorContext,
13278
                        "Content model of %s:\n", type->name);
13279
        xmlRegexpPrint(stderr, type->contModel);
13280
#endif
13281
0
    }
13282
0
    ctxt->state = NULL;
13283
0
    xmlFreeAutomata(ctxt->am);
13284
0
    ctxt->am = NULL;
13285
0
}
13286
13287
/**
13288
 * xmlSchemaResolveElementReferences:
13289
 * @elem:  the schema element context
13290
 * @ctxt:  the schema parser context
13291
 *
13292
 * Resolves the references of an element declaration
13293
 * or particle, which has an element declaration as it's
13294
 * term.
13295
 */
13296
static void
13297
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13298
          xmlSchemaParserCtxtPtr ctxt)
13299
0
{
13300
0
    if ((ctxt == NULL) || (elemDecl == NULL) ||
13301
0
  ((elemDecl != NULL) &&
13302
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13303
0
        return;
13304
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13305
13306
0
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13307
0
  xmlSchemaTypePtr type;
13308
13309
  /* (type definition) ... otherwise the type definition `resolved`
13310
  * to by the `actual value` of the type [attribute] ...
13311
  */
13312
0
  type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13313
0
      elemDecl->namedTypeNs);
13314
0
  if (type == NULL) {
13315
0
      xmlSchemaPResCompAttrErr(ctxt,
13316
0
    XML_SCHEMAP_SRC_RESOLVE,
13317
0
    WXS_BASIC_CAST elemDecl, elemDecl->node,
13318
0
    "type", elemDecl->namedType, elemDecl->namedTypeNs,
13319
0
    XML_SCHEMA_TYPE_BASIC, "type definition");
13320
0
  } else
13321
0
      elemDecl->subtypes = type;
13322
0
    }
13323
0
    if (elemDecl->substGroup != NULL) {
13324
0
  xmlSchemaElementPtr substHead;
13325
13326
  /*
13327
  * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13328
  * substitutionGroup?
13329
  */
13330
0
  substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13331
0
      elemDecl->substGroupNs);
13332
0
  if (substHead == NULL) {
13333
0
      xmlSchemaPResCompAttrErr(ctxt,
13334
0
    XML_SCHEMAP_SRC_RESOLVE,
13335
0
    WXS_BASIC_CAST elemDecl, NULL,
13336
0
    "substitutionGroup", elemDecl->substGroup,
13337
0
    elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13338
0
  } else {
13339
0
      xmlSchemaResolveElementReferences(substHead, ctxt);
13340
      /*
13341
      * Set the "substitution group affiliation".
13342
      * NOTE that now we use the "refDecl" field for this.
13343
      */
13344
0
      WXS_SUBST_HEAD(elemDecl) = substHead;
13345
      /*
13346
      * The type definitions is set to:
13347
      * SPEC "...the {type definition} of the element
13348
      * declaration `resolved` to by the `actual value`
13349
      * of the substitutionGroup [attribute], if present"
13350
      */
13351
0
      if (elemDecl->subtypes == NULL) {
13352
0
                if (substHead->subtypes == NULL) {
13353
                    /*
13354
                     * This can happen with self-referencing substitution
13355
                     * groups. The cycle will be detected later, but we have
13356
                     * to set subtypes to avoid null-pointer dereferences.
13357
                     */
13358
0
              elemDecl->subtypes = xmlSchemaGetBuiltInType(
13359
0
                            XML_SCHEMAS_ANYTYPE);
13360
0
                } else {
13361
0
        elemDecl->subtypes = substHead->subtypes;
13362
0
                }
13363
0
            }
13364
0
  }
13365
0
    }
13366
    /*
13367
    * SPEC "The definition of anyType serves as the default type definition
13368
    * for element declarations whose XML representation does not specify one."
13369
    */
13370
0
    if ((elemDecl->subtypes == NULL) &&
13371
0
  (elemDecl->namedType == NULL) &&
13372
0
  (elemDecl->substGroup == NULL))
13373
0
  elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13374
0
}
13375
13376
/**
13377
 * xmlSchemaResolveUnionMemberTypes:
13378
 * @ctxt:  the schema parser context
13379
 * @type:  the schema simple type definition
13380
 *
13381
 * Checks and builds the "member type definitions" property of the union
13382
 * simple type. This handles part (1), part (2) is done in
13383
 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13384
 *
13385
 * Returns -1 in case of an internal error, 0 otherwise.
13386
 */
13387
static int
13388
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13389
         xmlSchemaTypePtr type)
13390
0
{
13391
13392
0
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
13393
0
    xmlSchemaTypePtr memberType;
13394
13395
    /*
13396
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13397
    * define the explicit members as the type definitions `resolved`
13398
    * to by the items in the `actual value` of the memberTypes [attribute],
13399
    * if any, followed by the type definitions corresponding to the
13400
    * <simpleType>s among the [children] of <union>, if any."
13401
    */
13402
    /*
13403
    * Resolve references.
13404
    */
13405
0
    link = type->memberTypes;
13406
0
    lastLink = NULL;
13407
0
    while (link != NULL) {
13408
0
  const xmlChar *name, *nsName;
13409
13410
0
  name = ((xmlSchemaQNameRefPtr) link->type)->name;
13411
0
  nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13412
13413
0
  memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13414
0
  if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13415
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13416
0
    WXS_BASIC_CAST type, type->node, "memberTypes",
13417
0
    name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13418
      /*
13419
      * Remove the member type link.
13420
      */
13421
0
      if (lastLink == NULL)
13422
0
    type->memberTypes = link->next;
13423
0
      else
13424
0
    lastLink->next = link->next;
13425
0
      newLink = link;
13426
0
      link = link->next;
13427
0
      xmlFree(newLink);
13428
0
  } else {
13429
0
      link->type = memberType;
13430
0
      lastLink = link;
13431
0
      link = link->next;
13432
0
  }
13433
0
    }
13434
    /*
13435
    * Add local simple types,
13436
    */
13437
0
    memberType = type->subtypes;
13438
0
    while (memberType != NULL) {
13439
0
  link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13440
0
  if (link == NULL) {
13441
0
      xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
13442
0
      return (-1);
13443
0
  }
13444
0
  link->type = memberType;
13445
0
  link->next = NULL;
13446
0
  if (lastLink == NULL)
13447
0
      type->memberTypes = link;
13448
0
  else
13449
0
      lastLink->next = link;
13450
0
  lastLink = link;
13451
0
  memberType = memberType->next;
13452
0
    }
13453
0
    return (0);
13454
0
}
13455
13456
/**
13457
 * xmlSchemaIsDerivedFromBuiltInType:
13458
 * @ctxt:  the schema parser context
13459
 * @type:  the type definition
13460
 * @valType: the value type
13461
 *
13462
 *
13463
 * Returns 1 if the type has the given value type, or
13464
 * is derived from such a type.
13465
 */
13466
static int
13467
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13468
0
{
13469
0
    if (type == NULL)
13470
0
  return (0);
13471
0
    if (WXS_IS_COMPLEX(type))
13472
0
  return (0);
13473
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13474
0
  if (type->builtInType == valType)
13475
0
      return(1);
13476
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13477
0
      (type->builtInType == XML_SCHEMAS_ANYTYPE))
13478
0
      return (0);
13479
0
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13480
0
    }
13481
0
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13482
0
}
13483
13484
#if 0
13485
/**
13486
 * xmlSchemaIsDerivedFromBuiltInType:
13487
 * @ctxt:  the schema parser context
13488
 * @type:  the type definition
13489
 * @valType: the value type
13490
 *
13491
 *
13492
 * Returns 1 if the type has the given value type, or
13493
 * is derived from such a type.
13494
 */
13495
static int
13496
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13497
{
13498
    if (type == NULL)
13499
  return (0);
13500
    if (WXS_IS_COMPLEX(type))
13501
  return (0);
13502
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13503
  if (type->builtInType == valType)
13504
      return(1);
13505
  return (0);
13506
    } else
13507
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13508
13509
    return (0);
13510
}
13511
13512
static xmlSchemaTypePtr
13513
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13514
{
13515
    if (type == NULL)
13516
  return (NULL);
13517
    if (WXS_IS_COMPLEX(type))
13518
  return (NULL);
13519
    if (type->type == XML_SCHEMA_TYPE_BASIC)
13520
  return(type);
13521
    return(xmlSchemaQueryBuiltInType(type->subtypes));
13522
}
13523
#endif
13524
13525
/**
13526
 * xmlSchemaGetPrimitiveType:
13527
 * @type:  the simpleType definition
13528
 *
13529
 * Returns the primitive type of the given type or
13530
 * NULL in case of error.
13531
 */
13532
static xmlSchemaTypePtr
13533
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13534
0
{
13535
13536
0
    while (type != NULL) {
13537
  /*
13538
  * Note that anySimpleType is actually not a primitive type
13539
  * but we need that here.
13540
  */
13541
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13542
0
     (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13543
0
      return (type);
13544
0
  type = type->baseType;
13545
0
    }
13546
13547
0
    return (NULL);
13548
0
}
13549
13550
#if 0
13551
/**
13552
 * xmlSchemaGetBuiltInTypeAncestor:
13553
 * @type:  the simpleType definition
13554
 *
13555
 * Returns the primitive type of the given type or
13556
 * NULL in case of error.
13557
 */
13558
static xmlSchemaTypePtr
13559
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13560
{
13561
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13562
  return (0);
13563
    while (type != NULL) {
13564
  if (type->type == XML_SCHEMA_TYPE_BASIC)
13565
      return (type);
13566
  type = type->baseType;
13567
    }
13568
13569
    return (NULL);
13570
}
13571
#endif
13572
13573
/**
13574
 * xmlSchemaCloneWildcardNsConstraints:
13575
 * @ctxt:  the schema parser context
13576
 * @dest:  the destination wildcard
13577
 * @source: the source wildcard
13578
 *
13579
 * Clones the namespace constraints of source
13580
 * and assigns them to dest.
13581
 * Returns -1 on internal error, 0 otherwise.
13582
 */
13583
static int
13584
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13585
            xmlSchemaWildcardPtr dest,
13586
            xmlSchemaWildcardPtr source)
13587
0
{
13588
0
    xmlSchemaWildcardNsPtr cur, tmp, last;
13589
13590
0
    if ((source == NULL) || (dest == NULL))
13591
0
  return(-1);
13592
0
    dest->any = source->any;
13593
0
    cur = source->nsSet;
13594
0
    last = NULL;
13595
0
    while (cur != NULL) {
13596
0
  tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13597
0
  if (tmp == NULL)
13598
0
      return(-1);
13599
0
  tmp->value = cur->value;
13600
0
  if (last == NULL)
13601
0
      dest->nsSet = tmp;
13602
0
  else
13603
0
      last->next = tmp;
13604
0
  last = tmp;
13605
0
  cur = cur->next;
13606
0
    }
13607
0
    if (dest->negNsSet != NULL)
13608
0
  xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13609
0
    if (source->negNsSet != NULL) {
13610
0
  dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13611
0
  if (dest->negNsSet == NULL)
13612
0
      return(-1);
13613
0
  dest->negNsSet->value = source->negNsSet->value;
13614
0
    } else
13615
0
  dest->negNsSet = NULL;
13616
0
    return(0);
13617
0
}
13618
13619
/**
13620
 * xmlSchemaUnionWildcards:
13621
 * @ctxt:  the schema parser context
13622
 * @completeWild:  the first wildcard
13623
 * @curWild: the second wildcard
13624
 *
13625
 * Unions the namespace constraints of the given wildcards.
13626
 * @completeWild will hold the resulting union.
13627
 * Returns a positive error code on failure, -1 in case of an
13628
 * internal error, 0 otherwise.
13629
 */
13630
static int
13631
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13632
          xmlSchemaWildcardPtr completeWild,
13633
          xmlSchemaWildcardPtr curWild)
13634
0
{
13635
0
    xmlSchemaWildcardNsPtr cur, curB, tmp;
13636
13637
    /*
13638
    * 1 If O1 and O2 are the same value, then that value must be the
13639
    * value.
13640
    */
13641
0
    if ((completeWild->any == curWild->any) &&
13642
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13643
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13644
13645
0
  if ((completeWild->negNsSet == NULL) ||
13646
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13647
13648
0
      if (completeWild->nsSet != NULL) {
13649
0
    int found = 0;
13650
13651
    /*
13652
    * Check equality of sets.
13653
    */
13654
0
    cur = completeWild->nsSet;
13655
0
    while (cur != NULL) {
13656
0
        found = 0;
13657
0
        curB = curWild->nsSet;
13658
0
        while (curB != NULL) {
13659
0
      if (cur->value == curB->value) {
13660
0
          found = 1;
13661
0
          break;
13662
0
      }
13663
0
      curB = curB->next;
13664
0
        }
13665
0
        if (!found)
13666
0
      break;
13667
0
        cur = cur->next;
13668
0
    }
13669
0
    if (found)
13670
0
        return(0);
13671
0
      } else
13672
0
    return(0);
13673
0
  }
13674
0
    }
13675
    /*
13676
    * 2 If either O1 or O2 is any, then any must be the value
13677
    */
13678
0
    if (completeWild->any != curWild->any) {
13679
0
  if (completeWild->any == 0) {
13680
0
      completeWild->any = 1;
13681
0
      if (completeWild->nsSet != NULL) {
13682
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13683
0
    completeWild->nsSet = NULL;
13684
0
      }
13685
0
      if (completeWild->negNsSet != NULL) {
13686
0
    xmlFree(completeWild->negNsSet);
13687
0
    completeWild->negNsSet = NULL;
13688
0
      }
13689
0
  }
13690
0
  return (0);
13691
0
    }
13692
    /*
13693
    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13694
    * then the union of those sets must be the value.
13695
    */
13696
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13697
0
  int found;
13698
0
  xmlSchemaWildcardNsPtr start;
13699
13700
0
  cur = curWild->nsSet;
13701
0
  start = completeWild->nsSet;
13702
0
  while (cur != NULL) {
13703
0
      found = 0;
13704
0
      curB = start;
13705
0
      while (curB != NULL) {
13706
0
    if (cur->value == curB->value) {
13707
0
        found = 1;
13708
0
        break;
13709
0
    }
13710
0
    curB = curB->next;
13711
0
      }
13712
0
      if (!found) {
13713
0
    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13714
0
    if (tmp == NULL)
13715
0
        return (-1);
13716
0
    tmp->value = cur->value;
13717
0
    tmp->next = completeWild->nsSet;
13718
0
    completeWild->nsSet = tmp;
13719
0
      }
13720
0
      cur = cur->next;
13721
0
  }
13722
13723
0
  return(0);
13724
0
    }
13725
    /*
13726
    * 4 If the two are negations of different values (namespace names
13727
    * or `absent`), then a pair of not and `absent` must be the value.
13728
    */
13729
0
    if ((completeWild->negNsSet != NULL) &&
13730
0
  (curWild->negNsSet != NULL) &&
13731
0
  (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13732
0
  completeWild->negNsSet->value = NULL;
13733
13734
0
  return(0);
13735
0
    }
13736
    /*
13737
     * 5.
13738
     */
13739
0
    if (((completeWild->negNsSet != NULL) &&
13740
0
  (completeWild->negNsSet->value != NULL) &&
13741
0
  (curWild->nsSet != NULL)) ||
13742
0
  ((curWild->negNsSet != NULL) &&
13743
0
  (curWild->negNsSet->value != NULL) &&
13744
0
  (completeWild->nsSet != NULL))) {
13745
13746
0
  int nsFound, absentFound = 0;
13747
13748
0
  if (completeWild->nsSet != NULL) {
13749
0
      cur = completeWild->nsSet;
13750
0
      curB = curWild->negNsSet;
13751
0
  } else {
13752
0
      cur = curWild->nsSet;
13753
0
      curB = completeWild->negNsSet;
13754
0
  }
13755
0
  nsFound = 0;
13756
0
  while (cur != NULL) {
13757
0
      if (cur->value == NULL)
13758
0
    absentFound = 1;
13759
0
      else if (cur->value == curB->value)
13760
0
    nsFound = 1;
13761
0
      if (nsFound && absentFound)
13762
0
    break;
13763
0
      cur = cur->next;
13764
0
  }
13765
13766
0
  if (nsFound && absentFound) {
13767
      /*
13768
      * 5.1 If the set S includes both the negated namespace
13769
      * name and `absent`, then any must be the value.
13770
      */
13771
0
      completeWild->any = 1;
13772
0
      if (completeWild->nsSet != NULL) {
13773
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13774
0
    completeWild->nsSet = NULL;
13775
0
      }
13776
0
      if (completeWild->negNsSet != NULL) {
13777
0
    xmlFree(completeWild->negNsSet);
13778
0
    completeWild->negNsSet = NULL;
13779
0
      }
13780
0
  } else if (nsFound && (!absentFound)) {
13781
      /*
13782
      * 5.2 If the set S includes the negated namespace name
13783
      * but not `absent`, then a pair of not and `absent` must
13784
      * be the value.
13785
      */
13786
0
      if (completeWild->nsSet != NULL) {
13787
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13788
0
    completeWild->nsSet = NULL;
13789
0
      }
13790
0
      if (completeWild->negNsSet == NULL) {
13791
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13792
0
    if (completeWild->negNsSet == NULL)
13793
0
        return (-1);
13794
0
      }
13795
0
      completeWild->negNsSet->value = NULL;
13796
0
  } else if ((!nsFound) && absentFound) {
13797
      /*
13798
      * 5.3 If the set S includes `absent` but not the negated
13799
      * namespace name, then the union is not expressible.
13800
      */
13801
0
      xmlSchemaPErr(ctxt, completeWild->node,
13802
0
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13803
0
    "The union of the wildcard is not expressible.\n",
13804
0
    NULL, NULL);
13805
0
      return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13806
0
  } else if ((!nsFound) && (!absentFound)) {
13807
      /*
13808
      * 5.4 If the set S does not include either the negated namespace
13809
      * name or `absent`, then whichever of O1 or O2 is a pair of not
13810
      * and a namespace name must be the value.
13811
      */
13812
0
      if (completeWild->negNsSet == NULL) {
13813
0
    if (completeWild->nsSet != NULL) {
13814
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13815
0
        completeWild->nsSet = NULL;
13816
0
    }
13817
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13818
0
    if (completeWild->negNsSet == NULL)
13819
0
        return (-1);
13820
0
    completeWild->negNsSet->value = curWild->negNsSet->value;
13821
0
      }
13822
0
  }
13823
0
  return (0);
13824
0
    }
13825
    /*
13826
     * 6.
13827
     */
13828
0
    if (((completeWild->negNsSet != NULL) &&
13829
0
  (completeWild->negNsSet->value == NULL) &&
13830
0
  (curWild->nsSet != NULL)) ||
13831
0
  ((curWild->negNsSet != NULL) &&
13832
0
  (curWild->negNsSet->value == NULL) &&
13833
0
  (completeWild->nsSet != NULL))) {
13834
13835
0
  if (completeWild->nsSet != NULL) {
13836
0
      cur = completeWild->nsSet;
13837
0
  } else {
13838
0
      cur = curWild->nsSet;
13839
0
  }
13840
0
  while (cur != NULL) {
13841
0
      if (cur->value == NULL) {
13842
    /*
13843
    * 6.1 If the set S includes `absent`, then any must be the
13844
    * value.
13845
    */
13846
0
    completeWild->any = 1;
13847
0
    if (completeWild->nsSet != NULL) {
13848
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13849
0
        completeWild->nsSet = NULL;
13850
0
    }
13851
0
    if (completeWild->negNsSet != NULL) {
13852
0
        xmlFree(completeWild->negNsSet);
13853
0
        completeWild->negNsSet = NULL;
13854
0
    }
13855
0
    return (0);
13856
0
      }
13857
0
      cur = cur->next;
13858
0
  }
13859
0
  if (completeWild->negNsSet == NULL) {
13860
      /*
13861
      * 6.2 If the set S does not include `absent`, then a pair of not
13862
      * and `absent` must be the value.
13863
      */
13864
0
      if (completeWild->nsSet != NULL) {
13865
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13866
0
    completeWild->nsSet = NULL;
13867
0
      }
13868
0
      completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13869
0
      if (completeWild->negNsSet == NULL)
13870
0
    return (-1);
13871
0
      completeWild->negNsSet->value = NULL;
13872
0
  }
13873
0
  return (0);
13874
0
    }
13875
0
    return (0);
13876
13877
0
}
13878
13879
/**
13880
 * xmlSchemaIntersectWildcards:
13881
 * @ctxt:  the schema parser context
13882
 * @completeWild:  the first wildcard
13883
 * @curWild: the second wildcard
13884
 *
13885
 * Intersects the namespace constraints of the given wildcards.
13886
 * @completeWild will hold the resulting intersection.
13887
 * Returns a positive error code on failure, -1 in case of an
13888
 * internal error, 0 otherwise.
13889
 */
13890
static int
13891
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13892
          xmlSchemaWildcardPtr completeWild,
13893
          xmlSchemaWildcardPtr curWild)
13894
0
{
13895
0
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13896
13897
    /*
13898
    * 1 If O1 and O2 are the same value, then that value must be the
13899
    * value.
13900
    */
13901
0
    if ((completeWild->any == curWild->any) &&
13902
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13903
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13904
13905
0
  if ((completeWild->negNsSet == NULL) ||
13906
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13907
13908
0
      if (completeWild->nsSet != NULL) {
13909
0
    int found = 0;
13910
13911
    /*
13912
    * Check equality of sets.
13913
    */
13914
0
    cur = completeWild->nsSet;
13915
0
    while (cur != NULL) {
13916
0
        found = 0;
13917
0
        curB = curWild->nsSet;
13918
0
        while (curB != NULL) {
13919
0
      if (cur->value == curB->value) {
13920
0
          found = 1;
13921
0
          break;
13922
0
      }
13923
0
      curB = curB->next;
13924
0
        }
13925
0
        if (!found)
13926
0
      break;
13927
0
        cur = cur->next;
13928
0
    }
13929
0
    if (found)
13930
0
        return(0);
13931
0
      } else
13932
0
    return(0);
13933
0
  }
13934
0
    }
13935
    /*
13936
    * 2 If either O1 or O2 is any, then the other must be the value.
13937
    */
13938
0
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
13939
0
  if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13940
0
      return(-1);
13941
0
  return(0);
13942
0
    }
13943
    /*
13944
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
13945
    * name or `absent`) and the other is a set of (namespace names or
13946
    * `absent`), then that set, minus the negated value if it was in
13947
    * the set, minus `absent` if it was in the set, must be the value.
13948
    */
13949
0
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13950
0
  ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13951
0
  const xmlChar *neg;
13952
13953
0
  if (completeWild->nsSet == NULL) {
13954
0
      neg = completeWild->negNsSet->value;
13955
0
      if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13956
0
    return(-1);
13957
0
  } else
13958
0
      neg = curWild->negNsSet->value;
13959
  /*
13960
  * Remove absent and negated.
13961
  */
13962
0
  prev = NULL;
13963
0
  cur = completeWild->nsSet;
13964
0
  while (cur != NULL) {
13965
0
      if (cur->value == NULL) {
13966
0
    if (prev == NULL)
13967
0
        completeWild->nsSet = cur->next;
13968
0
    else
13969
0
        prev->next = cur->next;
13970
0
    xmlFree(cur);
13971
0
    break;
13972
0
      }
13973
0
      prev = cur;
13974
0
      cur = cur->next;
13975
0
  }
13976
0
  if (neg != NULL) {
13977
0
      prev = NULL;
13978
0
      cur = completeWild->nsSet;
13979
0
      while (cur != NULL) {
13980
0
    if (cur->value == neg) {
13981
0
        if (prev == NULL)
13982
0
      completeWild->nsSet = cur->next;
13983
0
        else
13984
0
      prev->next = cur->next;
13985
0
        xmlFree(cur);
13986
0
        break;
13987
0
    }
13988
0
    prev = cur;
13989
0
    cur = cur->next;
13990
0
      }
13991
0
  }
13992
13993
0
  return(0);
13994
0
    }
13995
    /*
13996
    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13997
    * then the intersection of those sets must be the value.
13998
    */
13999
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
14000
0
  int found;
14001
14002
0
  cur = completeWild->nsSet;
14003
0
  prev = NULL;
14004
0
  while (cur != NULL) {
14005
0
      found = 0;
14006
0
      curB = curWild->nsSet;
14007
0
      while (curB != NULL) {
14008
0
    if (cur->value == curB->value) {
14009
0
        found = 1;
14010
0
        break;
14011
0
    }
14012
0
    curB = curB->next;
14013
0
      }
14014
0
      if (!found) {
14015
0
    if (prev == NULL)
14016
0
        completeWild->nsSet = cur->next;
14017
0
    else
14018
0
        prev->next = cur->next;
14019
0
    tmp = cur->next;
14020
0
    xmlFree(cur);
14021
0
    cur = tmp;
14022
0
    continue;
14023
0
      }
14024
0
      prev = cur;
14025
0
      cur = cur->next;
14026
0
  }
14027
14028
0
  return(0);
14029
0
    }
14030
    /* 5 If the two are negations of different namespace names,
14031
    * then the intersection is not expressible
14032
    */
14033
0
    if ((completeWild->negNsSet != NULL) &&
14034
0
  (curWild->negNsSet != NULL) &&
14035
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
14036
0
  (completeWild->negNsSet->value != NULL) &&
14037
0
  (curWild->negNsSet->value != NULL)) {
14038
14039
0
  xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
14040
0
      "The intersection of the wildcard is not expressible.\n",
14041
0
      NULL, NULL);
14042
0
  return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
14043
0
    }
14044
    /*
14045
    * 6 If the one is a negation of a namespace name and the other
14046
    * is a negation of `absent`, then the one which is the negation
14047
    * of a namespace name must be the value.
14048
    */
14049
0
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
14050
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
14051
0
  (completeWild->negNsSet->value == NULL)) {
14052
0
  completeWild->negNsSet->value =  curWild->negNsSet->value;
14053
0
    }
14054
0
    return(0);
14055
0
}
14056
14057
/**
14058
 * xmlSchemaIsWildcardNsConstraintSubset:
14059
 * @ctxt:  the schema parser context
14060
 * @sub:  the first wildcard
14061
 * @super: the second wildcard
14062
 *
14063
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
14064
 *
14065
 * Returns 0 if the namespace constraint of @sub is an intensional
14066
 * subset of @super, 1 otherwise.
14067
 */
14068
static int
14069
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
14070
        xmlSchemaWildcardPtr super)
14071
0
{
14072
    /*
14073
    * 1 super must be any.
14074
    */
14075
0
    if (super->any)
14076
0
  return (0);
14077
    /*
14078
    * 2.1 sub must be a pair of not and a namespace name or `absent`.
14079
    * 2.2 super must be a pair of not and the same value.
14080
    */
14081
0
    if ((sub->negNsSet != NULL) &&
14082
0
  (super->negNsSet != NULL) &&
14083
0
  (sub->negNsSet->value == super->negNsSet->value))
14084
0
  return (0);
14085
    /*
14086
    * 3.1 sub must be a set whose members are either namespace names or `absent`.
14087
    */
14088
0
    if (sub->nsSet != NULL) {
14089
  /*
14090
  * 3.2.1 super must be the same set or a superset thereof.
14091
  */
14092
0
  if (super->nsSet != NULL) {
14093
0
      xmlSchemaWildcardNsPtr cur, curB;
14094
0
      int found = 0;
14095
14096
0
      cur = sub->nsSet;
14097
0
      while (cur != NULL) {
14098
0
    found = 0;
14099
0
    curB = super->nsSet;
14100
0
    while (curB != NULL) {
14101
0
        if (cur->value == curB->value) {
14102
0
      found = 1;
14103
0
      break;
14104
0
        }
14105
0
        curB = curB->next;
14106
0
    }
14107
0
    if (!found)
14108
0
        return (1);
14109
0
    cur = cur->next;
14110
0
      }
14111
0
      if (found)
14112
0
    return (0);
14113
0
  } else if (super->negNsSet != NULL) {
14114
0
      xmlSchemaWildcardNsPtr cur;
14115
      /*
14116
      * 3.2.2 super must be a pair of not and a namespace name or
14117
      * `absent` and that value must not be in sub's set.
14118
      */
14119
0
      cur = sub->nsSet;
14120
0
      while (cur != NULL) {
14121
0
    if (cur->value == super->negNsSet->value)
14122
0
        return (1);
14123
0
    cur = cur->next;
14124
0
      }
14125
0
      return (0);
14126
0
  }
14127
0
    }
14128
0
    return (1);
14129
0
}
14130
14131
static int
14132
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
14133
             int *fixed,
14134
             const xmlChar **value,
14135
             xmlSchemaValPtr *val)
14136
0
{
14137
0
    *fixed = 0;
14138
0
    *value = NULL;
14139
0
    if (val != 0)
14140
0
  *val = NULL;
14141
14142
0
    if (attruse->defValue != NULL) {
14143
0
  *value = attruse->defValue;
14144
0
  if (val != NULL)
14145
0
      *val = attruse->defVal;
14146
0
  if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14147
0
      *fixed = 1;
14148
0
  return(1);
14149
0
    } else if ((attruse->attrDecl != NULL) &&
14150
0
  (attruse->attrDecl->defValue != NULL)) {
14151
0
  *value = attruse->attrDecl->defValue;
14152
0
  if (val != NULL)
14153
0
      *val = attruse->attrDecl->defVal;
14154
0
  if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14155
0
      *fixed = 1;
14156
0
  return(1);
14157
0
    }
14158
0
    return(0);
14159
0
}
14160
/**
14161
 * xmlSchemaCheckCVCWildcardNamespace:
14162
 * @wild:  the wildcard
14163
 * @ns:  the namespace
14164
 *
14165
 * Validation Rule: Wildcard allows Namespace Name
14166
 * (cvc-wildcard-namespace)
14167
 *
14168
 * Returns 0 if the given namespace matches the wildcard,
14169
 * 1 otherwise and -1 on API errors.
14170
 */
14171
static int
14172
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14173
           const xmlChar* ns)
14174
0
{
14175
0
    if (wild == NULL)
14176
0
  return(-1);
14177
14178
0
    if (wild->any)
14179
0
  return(0);
14180
0
    else if (wild->nsSet != NULL) {
14181
0
  xmlSchemaWildcardNsPtr cur;
14182
14183
0
  cur = wild->nsSet;
14184
0
  while (cur != NULL) {
14185
0
      if (xmlStrEqual(cur->value, ns))
14186
0
    return(0);
14187
0
      cur = cur->next;
14188
0
  }
14189
0
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14190
0
  (!xmlStrEqual(wild->negNsSet->value, ns)))
14191
0
  return(0);
14192
14193
0
    return(1);
14194
0
}
14195
14196
0
#define XML_SCHEMA_ACTION_DERIVE 0
14197
0
#define XML_SCHEMA_ACTION_REDEFINE 1
14198
14199
0
#define WXS_ACTION_STR(a) \
14200
0
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14201
14202
/*
14203
* Schema Component Constraint:
14204
*   Derivation Valid (Restriction, Complex)
14205
*   derivation-ok-restriction (2) - (4)
14206
*
14207
* ATTENTION:
14208
* In XML Schema 1.1 this will be:
14209
* Validation Rule:
14210
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14211
*
14212
*/
14213
static int
14214
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14215
               int action,
14216
               xmlSchemaBasicItemPtr item,
14217
               xmlSchemaBasicItemPtr baseItem,
14218
               xmlSchemaItemListPtr uses,
14219
               xmlSchemaItemListPtr baseUses,
14220
               xmlSchemaWildcardPtr wild,
14221
               xmlSchemaWildcardPtr baseWild)
14222
0
{
14223
0
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
14224
0
    int i, j, found; /* err = 0; */
14225
0
    const xmlChar *bEffValue;
14226
0
    int effFixed;
14227
14228
0
    if (uses != NULL) {
14229
0
  for (i = 0; i < uses->nbItems; i++) {
14230
0
      cur = uses->items[i];
14231
0
      found = 0;
14232
0
      if (baseUses == NULL)
14233
0
    goto not_found;
14234
0
      for (j = 0; j < baseUses->nbItems; j++) {
14235
0
    bcur = baseUses->items[j];
14236
0
    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14237
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14238
0
        (WXS_ATTRUSE_DECL_TNS(cur) ==
14239
0
      WXS_ATTRUSE_DECL_TNS(bcur)))
14240
0
    {
14241
        /*
14242
        * (2.1) "If there is an attribute use in the {attribute
14243
        * uses} of the {base type definition} (call this B) whose
14244
        * {attribute declaration} has the same {name} and {target
14245
        * namespace}, then  all of the following must be true:"
14246
        */
14247
0
        found = 1;
14248
14249
0
        if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14250
0
      (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14251
0
        {
14252
0
      xmlChar *str = NULL;
14253
      /*
14254
      * (2.1.1) "one of the following must be true:"
14255
      * (2.1.1.1) "B's {required} is false."
14256
      * (2.1.1.2) "R's {required} is true."
14257
      */
14258
0
      xmlSchemaPAttrUseErr4(pctxt,
14259
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14260
0
          WXS_ITEM_NODE(item), item, cur,
14261
0
          "The 'optional' attribute use is inconsistent "
14262
0
          "with the corresponding 'required' attribute use of "
14263
0
          "the %s %s",
14264
0
          WXS_ACTION_STR(action),
14265
0
          xmlSchemaGetComponentDesignation(&str, baseItem),
14266
0
          NULL, NULL);
14267
0
      FREE_AND_NULL(str);
14268
      /* err = pctxt->err; */
14269
0
        } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14270
0
      WXS_ATTRUSE_TYPEDEF(cur),
14271
0
      WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14272
0
        {
14273
0
      xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14274
14275
      /*
14276
      * SPEC (2.1.2) "R's {attribute declaration}'s
14277
      * {type definition} must be validly derived from
14278
      * B's {type definition} given the empty set as
14279
      * defined in Type Derivation OK (Simple) ($3.14.6)."
14280
      */
14281
0
      xmlSchemaPAttrUseErr4(pctxt,
14282
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14283
0
          WXS_ITEM_NODE(item), item, cur,
14284
0
          "The attribute declaration's %s "
14285
0
          "is not validly derived from "
14286
0
          "the corresponding %s of the "
14287
0
          "attribute declaration in the %s %s",
14288
0
          xmlSchemaGetComponentDesignation(&strA,
14289
0
        WXS_ATTRUSE_TYPEDEF(cur)),
14290
0
          xmlSchemaGetComponentDesignation(&strB,
14291
0
        WXS_ATTRUSE_TYPEDEF(bcur)),
14292
0
          WXS_ACTION_STR(action),
14293
0
          xmlSchemaGetComponentDesignation(&strC, baseItem));
14294
          /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14295
0
      FREE_AND_NULL(strA);
14296
0
      FREE_AND_NULL(strB);
14297
0
      FREE_AND_NULL(strC);
14298
      /* err = pctxt->err; */
14299
0
        } else {
14300
      /*
14301
      * 2.1.3 [Definition:]  Let the effective value
14302
      * constraint of an attribute use be its {value
14303
      * constraint}, if present, otherwise its {attribute
14304
      * declaration}'s {value constraint} .
14305
      */
14306
0
      xmlSchemaGetEffectiveValueConstraint(bcur,
14307
0
          &effFixed, &bEffValue, NULL);
14308
      /*
14309
      * 2.1.3 ... one of the following must be true
14310
      *
14311
      * 2.1.3.1 B's `effective value constraint` is
14312
      * `absent` or default.
14313
      */
14314
0
      if ((bEffValue != NULL) &&
14315
0
          (effFixed == 1)) {
14316
0
          const xmlChar *rEffValue = NULL;
14317
14318
0
          xmlSchemaGetEffectiveValueConstraint(bcur,
14319
0
        &effFixed, &rEffValue, NULL);
14320
          /*
14321
          * 2.1.3.2 R's `effective value constraint` is
14322
          * fixed with the same string as B's.
14323
          * MAYBE TODO: Compare the computed values.
14324
          *       Hmm, it says "same string" so
14325
          *       string-equality might really be sufficient.
14326
          */
14327
0
          if ((effFixed == 0) ||
14328
0
        (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14329
0
          {
14330
0
        xmlChar *str = NULL;
14331
14332
0
        xmlSchemaPAttrUseErr4(pctxt,
14333
0
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14334
0
            WXS_ITEM_NODE(item), item, cur,
14335
0
            "The effective value constraint of the "
14336
0
            "attribute use is inconsistent with "
14337
0
            "its correspondent in the %s %s",
14338
0
            WXS_ACTION_STR(action),
14339
0
            xmlSchemaGetComponentDesignation(&str,
14340
0
          baseItem),
14341
0
            NULL, NULL);
14342
0
        FREE_AND_NULL(str);
14343
        /* err = pctxt->err; */
14344
0
          }
14345
0
      }
14346
0
        }
14347
0
        break;
14348
0
    }
14349
0
      }
14350
0
not_found:
14351
0
      if (!found) {
14352
    /*
14353
    * (2.2) "otherwise the {base type definition} must have an
14354
    * {attribute wildcard} and the {target namespace} of the
14355
    * R's {attribute declaration} must be `valid` with respect
14356
    * to that wildcard, as defined in Wildcard allows Namespace
14357
    * Name ($3.10.4)."
14358
    */
14359
0
    if ((baseWild == NULL) ||
14360
0
        (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14361
0
        (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14362
0
    {
14363
0
        xmlChar *str = NULL;
14364
14365
0
        xmlSchemaPAttrUseErr4(pctxt,
14366
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14367
0
      WXS_ITEM_NODE(item), item, cur,
14368
0
      "Neither a matching attribute use, "
14369
0
      "nor a matching wildcard exists in the %s %s",
14370
0
      WXS_ACTION_STR(action),
14371
0
      xmlSchemaGetComponentDesignation(&str, baseItem),
14372
0
      NULL, NULL);
14373
0
        FREE_AND_NULL(str);
14374
        /* err = pctxt->err; */
14375
0
    }
14376
0
      }
14377
0
  }
14378
0
    }
14379
    /*
14380
    * SPEC derivation-ok-restriction (3):
14381
    * (3) "For each attribute use in the {attribute uses} of the {base type
14382
    * definition} whose {required} is true, there must be an attribute
14383
    * use with an {attribute declaration} with the same {name} and
14384
    * {target namespace} as its {attribute declaration} in the {attribute
14385
    * uses} of the complex type definition itself whose {required} is true.
14386
    */
14387
0
    if (baseUses != NULL) {
14388
0
  for (j = 0; j < baseUses->nbItems; j++) {
14389
0
      bcur = baseUses->items[j];
14390
0
      if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14391
0
    continue;
14392
0
      found = 0;
14393
0
      if (uses != NULL) {
14394
0
    for (i = 0; i < uses->nbItems; i++) {
14395
0
        cur = uses->items[i];
14396
0
        if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14397
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14398
0
      (WXS_ATTRUSE_DECL_TNS(cur) ==
14399
0
      WXS_ATTRUSE_DECL_TNS(bcur))) {
14400
0
      found = 1;
14401
0
      break;
14402
0
        }
14403
0
    }
14404
0
      }
14405
0
      if (!found) {
14406
0
    xmlChar *strA = NULL, *strB = NULL;
14407
14408
0
    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14409
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14410
0
        NULL, item,
14411
0
        "A matching attribute use for the "
14412
0
        "'required' %s of the %s %s is missing",
14413
0
        xmlSchemaGetComponentDesignation(&strA, bcur),
14414
0
        WXS_ACTION_STR(action),
14415
0
        xmlSchemaGetComponentDesignation(&strB, baseItem),
14416
0
        NULL);
14417
0
    FREE_AND_NULL(strA);
14418
0
    FREE_AND_NULL(strB);
14419
0
      }
14420
0
  }
14421
0
    }
14422
    /*
14423
    * derivation-ok-restriction (4)
14424
    */
14425
0
    if (wild != NULL) {
14426
  /*
14427
  * (4) "If there is an {attribute wildcard}, all of the
14428
  * following must be true:"
14429
  */
14430
0
  if (baseWild == NULL) {
14431
0
      xmlChar *str = NULL;
14432
14433
      /*
14434
      * (4.1) "The {base type definition} must also have one."
14435
      */
14436
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14437
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14438
0
    NULL, item,
14439
0
    "The %s has an attribute wildcard, "
14440
0
    "but the %s %s '%s' does not have one",
14441
0
    WXS_ITEM_TYPE_NAME(item),
14442
0
    WXS_ACTION_STR(action),
14443
0
    WXS_ITEM_TYPE_NAME(baseItem),
14444
0
    xmlSchemaGetComponentQName(&str, baseItem));
14445
0
      FREE_AND_NULL(str);
14446
0
      return(pctxt->err);
14447
0
  } else if ((baseWild->any == 0) &&
14448
0
    xmlSchemaCheckCOSNSSubset(wild, baseWild))
14449
0
  {
14450
0
      xmlChar *str = NULL;
14451
      /*
14452
      * (4.2) "The complex type definition's {attribute wildcard}'s
14453
      * {namespace constraint} must be a subset of the {base type
14454
      * definition}'s {attribute wildcard}'s {namespace constraint},
14455
      * as defined by Wildcard Subset ($3.10.6)."
14456
      */
14457
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14458
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14459
0
    NULL, item,
14460
0
    "The attribute wildcard is not a valid "
14461
0
    "subset of the wildcard in the %s %s '%s'",
14462
0
    WXS_ACTION_STR(action),
14463
0
    WXS_ITEM_TYPE_NAME(baseItem),
14464
0
    xmlSchemaGetComponentQName(&str, baseItem),
14465
0
    NULL);
14466
0
      FREE_AND_NULL(str);
14467
0
      return(pctxt->err);
14468
0
  }
14469
  /* 4.3 Unless the {base type definition} is the `ur-type
14470
  * definition`, the complex type definition's {attribute
14471
  * wildcard}'s {process contents} must be identical to or
14472
  * stronger than the {base type definition}'s {attribute
14473
  * wildcard}'s {process contents}, where strict is stronger
14474
  * than lax is stronger than skip.
14475
  */
14476
0
  if ((! WXS_IS_ANYTYPE(baseItem)) &&
14477
0
      (wild->processContents < baseWild->processContents)) {
14478
0
      xmlChar *str = NULL;
14479
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14480
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14481
0
    NULL, baseItem,
14482
0
    "The {process contents} of the attribute wildcard is "
14483
0
    "weaker than the one in the %s %s '%s'",
14484
0
    WXS_ACTION_STR(action),
14485
0
    WXS_ITEM_TYPE_NAME(baseItem),
14486
0
    xmlSchemaGetComponentQName(&str, baseItem),
14487
0
    NULL);
14488
0
      FREE_AND_NULL(str)
14489
0
    return(pctxt->err);
14490
0
  }
14491
0
    }
14492
0
    return(0);
14493
0
}
14494
14495
14496
static int
14497
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14498
          xmlSchemaBasicItemPtr item,
14499
          xmlSchemaWildcardPtr *completeWild,
14500
          xmlSchemaItemListPtr list,
14501
          xmlSchemaItemListPtr prohibs);
14502
/**
14503
 * xmlSchemaFixupTypeAttributeUses:
14504
 * @ctxt:  the schema parser context
14505
 * @type:  the complex type definition
14506
 *
14507
 *
14508
 * Builds the wildcard and the attribute uses on the given complex type.
14509
 * Returns -1 if an internal error occurs, 0 otherwise.
14510
 *
14511
 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14512
 * strings, so recheck this if we start to hardcode some schemata, since
14513
 * they might not be in the same dict.
14514
 * NOTE: It is allowed to "extend" the xs:anyType type.
14515
 */
14516
static int
14517
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14518
          xmlSchemaTypePtr type)
14519
0
{
14520
0
    xmlSchemaTypePtr baseType = NULL;
14521
0
    xmlSchemaAttributeUsePtr use;
14522
0
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14523
14524
0
    if (type->baseType == NULL) {
14525
0
  PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14526
0
      "no base type");
14527
0
        return (-1);
14528
0
    }
14529
0
    baseType = type->baseType;
14530
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14531
0
  if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14532
0
      return(-1);
14533
14534
0
    uses = type->attrUses;
14535
0
    baseUses = baseType->attrUses;
14536
    /*
14537
    * Expand attribute group references. And build the 'complete'
14538
    * wildcard, i.e. intersect multiple wildcards.
14539
    * Move attribute prohibitions into a separate list.
14540
    */
14541
0
    if (uses != NULL) {
14542
0
  if (WXS_IS_RESTRICTION(type)) {
14543
      /*
14544
      * This one will transfer all attr. prohibitions
14545
      * into pctxt->attrProhibs.
14546
      */
14547
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14548
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14549
0
    pctxt->attrProhibs) == -1)
14550
0
      {
14551
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14552
0
    "failed to expand attributes");
14553
0
      }
14554
0
      if (pctxt->attrProhibs->nbItems != 0)
14555
0
    prohibs = pctxt->attrProhibs;
14556
0
  } else {
14557
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14558
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14559
0
    NULL) == -1)
14560
0
      {
14561
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14562
0
    "failed to expand attributes");
14563
0
      }
14564
0
  }
14565
0
    }
14566
    /*
14567
    * Inherit the attribute uses of the base type.
14568
    */
14569
0
    if (baseUses != NULL) {
14570
0
  int i, j;
14571
0
  xmlSchemaAttributeUseProhibPtr pro;
14572
14573
0
  if (WXS_IS_RESTRICTION(type)) {
14574
0
      int usesCount;
14575
0
      xmlSchemaAttributeUsePtr tmp;
14576
14577
0
      if (uses != NULL)
14578
0
    usesCount = uses->nbItems;
14579
0
      else
14580
0
    usesCount = 0;
14581
14582
      /* Restriction. */
14583
0
      for (i = 0; i < baseUses->nbItems; i++) {
14584
0
    use = baseUses->items[i];
14585
0
    if (prohibs) {
14586
        /*
14587
        * Filter out prohibited uses.
14588
        */
14589
0
        for (j = 0; j < prohibs->nbItems; j++) {
14590
0
      pro = prohibs->items[j];
14591
0
      if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14592
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14593
0
        pro->targetNamespace))
14594
0
      {
14595
0
          goto inherit_next;
14596
0
      }
14597
0
        }
14598
0
    }
14599
0
    if (usesCount) {
14600
        /*
14601
        * Filter out existing uses.
14602
        */
14603
0
        for (j = 0; j < usesCount; j++) {
14604
0
      tmp = uses->items[j];
14605
0
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
14606
0
        WXS_ATTRUSE_DECL_NAME(tmp)) &&
14607
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14608
0
        WXS_ATTRUSE_DECL_TNS(tmp)))
14609
0
      {
14610
0
          goto inherit_next;
14611
0
      }
14612
0
        }
14613
0
    }
14614
0
    if (uses == NULL) {
14615
0
        type->attrUses = xmlSchemaItemListCreate();
14616
0
        if (type->attrUses == NULL)
14617
0
      goto exit_failure;
14618
0
        uses = type->attrUses;
14619
0
    }
14620
0
    xmlSchemaItemListAddSize(uses, 2, use);
14621
0
inherit_next: {}
14622
0
      }
14623
0
  } else {
14624
      /* Extension. */
14625
0
      for (i = 0; i < baseUses->nbItems; i++) {
14626
0
    use = baseUses->items[i];
14627
0
    if (uses == NULL) {
14628
0
        type->attrUses = xmlSchemaItemListCreate();
14629
0
        if (type->attrUses == NULL)
14630
0
      goto exit_failure;
14631
0
        uses = type->attrUses;
14632
0
    }
14633
0
    xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14634
0
      }
14635
0
  }
14636
0
    }
14637
    /*
14638
    * Shrink attr. uses.
14639
    */
14640
0
    if (uses) {
14641
0
  if (uses->nbItems == 0) {
14642
0
      xmlSchemaItemListFree(uses);
14643
0
      type->attrUses = NULL;
14644
0
  }
14645
  /*
14646
  * TODO: We could shrink the size of the array
14647
  * to fit the actual number of items.
14648
  */
14649
0
    }
14650
    /*
14651
    * Compute the complete wildcard.
14652
    */
14653
0
    if (WXS_IS_EXTENSION(type)) {
14654
0
  if (baseType->attributeWildcard != NULL) {
14655
      /*
14656
      * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14657
      * the appropriate case among the following:"
14658
      */
14659
0
      if (type->attributeWildcard != NULL) {
14660
    /*
14661
    * Union the complete wildcard with the base wildcard.
14662
    * SPEC {attribute wildcard}
14663
    * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14664
    * and {annotation} are those of the `complete wildcard`,
14665
    * and whose {namespace constraint} is the intensional union
14666
    * of the {namespace constraint} of the `complete wildcard`
14667
    * and of the `base wildcard`, as defined in Attribute
14668
    * Wildcard Union ($3.10.6)."
14669
    */
14670
0
    if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14671
0
        baseType->attributeWildcard) == -1)
14672
0
        goto exit_failure;
14673
0
      } else {
14674
    /*
14675
    * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14676
    * then the `base wildcard`."
14677
    */
14678
0
    type->attributeWildcard = baseType->attributeWildcard;
14679
0
      }
14680
0
  } else {
14681
      /*
14682
      * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14683
      * `complete wildcard`"
14684
      * NOOP
14685
      */
14686
0
  }
14687
0
    } else {
14688
  /*
14689
  * SPEC {attribute wildcard}
14690
  * (3.1) "If the <restriction> alternative is chosen, then the
14691
  * `complete wildcard`;"
14692
  * NOOP
14693
  */
14694
0
    }
14695
14696
0
    return (0);
14697
14698
0
exit_failure:
14699
0
    return(-1);
14700
0
}
14701
14702
/**
14703
 * xmlSchemaTypeFinalContains:
14704
 * @schema:  the schema
14705
 * @type:  the type definition
14706
 * @final: the final
14707
 *
14708
 * Evaluates if a type definition contains the given "final".
14709
 * This does take "finalDefault" into account as well.
14710
 *
14711
 * Returns 1 if the type does contain the given "final",
14712
 * 0 otherwise.
14713
 */
14714
static int
14715
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14716
0
{
14717
0
    if (type == NULL)
14718
0
  return (0);
14719
0
    if (type->flags & final)
14720
0
  return (1);
14721
0
    else
14722
0
  return (0);
14723
0
}
14724
14725
/**
14726
 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14727
 * @type:  the Union Simple Type
14728
 *
14729
 * Returns a list of member types of @type if existing,
14730
 * returns NULL otherwise.
14731
 */
14732
static xmlSchemaTypeLinkPtr
14733
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14734
0
{
14735
0
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14736
0
  if (type->memberTypes != NULL)
14737
0
      return (type->memberTypes);
14738
0
  else
14739
0
      type = type->baseType;
14740
0
    }
14741
0
    return (NULL);
14742
0
}
14743
14744
#if 0
14745
/**
14746
 * xmlSchemaGetParticleTotalRangeMin:
14747
 * @particle: the particle
14748
 *
14749
 * Schema Component Constraint: Effective Total Range
14750
 * (all and sequence) + (choice)
14751
 *
14752
 * Returns the minimum Effective Total Range.
14753
 */
14754
static int
14755
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14756
{
14757
    if ((particle->children == NULL) ||
14758
  (particle->minOccurs == 0))
14759
  return (0);
14760
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14761
  int min = -1, cur;
14762
  xmlSchemaParticlePtr part =
14763
      (xmlSchemaParticlePtr) particle->children->children;
14764
14765
  if (part == NULL)
14766
      return (0);
14767
  while (part != NULL) {
14768
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14769
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14770
    cur = part->minOccurs;
14771
      else
14772
    cur = xmlSchemaGetParticleTotalRangeMin(part);
14773
      if (cur == 0)
14774
    return (0);
14775
      if ((min > cur) || (min == -1))
14776
    min = cur;
14777
      part = (xmlSchemaParticlePtr) part->next;
14778
  }
14779
  return (particle->minOccurs * min);
14780
    } else {
14781
  /* <all> and <sequence> */
14782
  int sum = 0;
14783
  xmlSchemaParticlePtr part =
14784
      (xmlSchemaParticlePtr) particle->children->children;
14785
14786
  if (part == NULL)
14787
      return (0);
14788
  do {
14789
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14790
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14791
    sum += part->minOccurs;
14792
      else
14793
    sum += xmlSchemaGetParticleTotalRangeMin(part);
14794
      part = (xmlSchemaParticlePtr) part->next;
14795
  } while (part != NULL);
14796
  return (particle->minOccurs * sum);
14797
    }
14798
}
14799
14800
/**
14801
 * xmlSchemaGetParticleTotalRangeMax:
14802
 * @particle: the particle
14803
 *
14804
 * Schema Component Constraint: Effective Total Range
14805
 * (all and sequence) + (choice)
14806
 *
14807
 * Returns the maximum Effective Total Range.
14808
 */
14809
static int
14810
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14811
{
14812
    if ((particle->children == NULL) ||
14813
  (particle->children->children == NULL))
14814
  return (0);
14815
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14816
  int max = -1, cur;
14817
  xmlSchemaParticlePtr part =
14818
      (xmlSchemaParticlePtr) particle->children->children;
14819
14820
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14821
      if (part->children == NULL)
14822
    continue;
14823
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14824
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14825
    cur = part->maxOccurs;
14826
      else
14827
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14828
      if (cur == UNBOUNDED)
14829
    return (UNBOUNDED);
14830
      if ((max < cur) || (max == -1))
14831
    max = cur;
14832
  }
14833
  /* TODO: Handle overflows? */
14834
  return (particle->maxOccurs * max);
14835
    } else {
14836
  /* <all> and <sequence> */
14837
  int sum = 0, cur;
14838
  xmlSchemaParticlePtr part =
14839
      (xmlSchemaParticlePtr) particle->children->children;
14840
14841
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14842
      if (part->children == NULL)
14843
    continue;
14844
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14845
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14846
    cur = part->maxOccurs;
14847
      else
14848
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14849
      if (cur == UNBOUNDED)
14850
    return (UNBOUNDED);
14851
      if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14852
    return (UNBOUNDED);
14853
      sum += cur;
14854
  }
14855
  /* TODO: Handle overflows? */
14856
  return (particle->maxOccurs * sum);
14857
    }
14858
}
14859
#endif
14860
14861
/**
14862
 * xmlSchemaGetParticleEmptiable:
14863
 * @particle: the particle
14864
 *
14865
 * Returns 1 if emptiable, 0 otherwise.
14866
 */
14867
static int
14868
xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14869
0
{
14870
0
    xmlSchemaParticlePtr part;
14871
0
    int emptiable;
14872
14873
0
    if ((particle->children == NULL) || (particle->minOccurs == 0))
14874
0
  return (1);
14875
14876
0
    part = (xmlSchemaParticlePtr) particle->children->children;
14877
0
    if (part == NULL)
14878
0
        return (1);
14879
14880
0
    while (part != NULL) {
14881
0
        if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14882
0
            (part->children->type == XML_SCHEMA_TYPE_ANY))
14883
0
            emptiable = (part->minOccurs == 0);
14884
0
        else
14885
0
            emptiable = xmlSchemaGetParticleEmptiable(part);
14886
0
        if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14887
0
            if (emptiable)
14888
0
                return (1);
14889
0
        } else {
14890
      /* <all> and <sequence> */
14891
0
            if (!emptiable)
14892
0
                return (0);
14893
0
        }
14894
0
        part = (xmlSchemaParticlePtr) part->next;
14895
0
    }
14896
14897
0
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14898
0
        return (0);
14899
0
    else
14900
0
        return (1);
14901
0
}
14902
14903
/**
14904
 * xmlSchemaIsParticleEmptiable:
14905
 * @particle: the particle
14906
 *
14907
 * Schema Component Constraint: Particle Emptiable
14908
 * Checks whether the given particle is emptiable.
14909
 *
14910
 * Returns 1 if emptiable, 0 otherwise.
14911
 */
14912
static int
14913
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14914
0
{
14915
    /*
14916
    * SPEC (1) "Its {min occurs} is 0."
14917
    */
14918
0
    if ((particle == NULL) || (particle->minOccurs == 0) ||
14919
0
  (particle->children == NULL))
14920
0
  return (1);
14921
    /*
14922
    * SPEC (2) "Its {term} is a group and the minimum part of the
14923
    * effective total range of that group, [...] is 0."
14924
    */
14925
0
    if (WXS_IS_MODEL_GROUP(particle->children))
14926
0
  return (xmlSchemaGetParticleEmptiable(particle));
14927
0
    return (0);
14928
0
}
14929
14930
/**
14931
 * xmlSchemaCheckCOSSTDerivedOK:
14932
 * @actxt: a context
14933
 * @type:  the derived simple type definition
14934
 * @baseType:  the base type definition
14935
 * @subset: the subset of ('restriction', etc.)
14936
 *
14937
 * Schema Component Constraint:
14938
 * Type Derivation OK (Simple) (cos-st-derived-OK)
14939
 *
14940
 * Checks whether @type can be validly
14941
 * derived from @baseType.
14942
 *
14943
 * Returns 0 on success, an positive error code otherwise.
14944
 */
14945
static int
14946
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14947
           xmlSchemaTypePtr type,
14948
           xmlSchemaTypePtr baseType,
14949
           int subset)
14950
0
{
14951
    /*
14952
    * 1 They are the same type definition.
14953
    * TODO: The identity check might have to be more complex than this.
14954
    */
14955
0
    if (type == baseType)
14956
0
  return (0);
14957
    /*
14958
    * 2.1 restriction is not in the subset, or in the {final}
14959
    * of its own {base type definition};
14960
    *
14961
    * NOTE that this will be used also via "xsi:type".
14962
    *
14963
    * TODO: Revise this, it looks strange. How can the "type"
14964
    * not be fixed or *in* fixing?
14965
    */
14966
0
    if (WXS_IS_TYPE_NOT_FIXED(type))
14967
0
  if (xmlSchemaTypeFixup(type, actxt) == -1)
14968
0
      return(-1);
14969
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14970
0
  if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14971
0
      return(-1);
14972
0
    if ((subset & SUBSET_RESTRICTION) ||
14973
0
  (xmlSchemaTypeFinalContains(type->baseType,
14974
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14975
0
  return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14976
0
    }
14977
    /* 2.2 */
14978
0
    if (type->baseType == baseType) {
14979
  /*
14980
  * 2.2.1 D's `base type definition` is B.
14981
  */
14982
0
  return (0);
14983
0
    }
14984
    /*
14985
    * 2.2.2 D's `base type definition` is not the `ur-type definition`
14986
    * and is validly derived from B given the subset, as defined by this
14987
    * constraint.
14988
    */
14989
0
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14990
0
  (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14991
0
      baseType, subset) == 0)) {
14992
0
  return (0);
14993
0
    }
14994
    /*
14995
    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14996
    * definition`.
14997
    */
14998
0
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14999
0
  (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
15000
0
  return (0);
15001
0
    }
15002
    /*
15003
    * 2.2.4 B's {variety} is union and D is validly derived from a type
15004
    * definition in B's {member type definitions} given the subset, as
15005
    * defined by this constraint.
15006
    *
15007
    * NOTE: This seems not to involve built-in types, since there is no
15008
    * built-in Union Simple Type.
15009
    */
15010
0
    if (WXS_IS_UNION(baseType)) {
15011
0
  xmlSchemaTypeLinkPtr cur;
15012
15013
0
  cur = baseType->memberTypes;
15014
0
  while (cur != NULL) {
15015
0
      if (WXS_IS_TYPE_NOT_FIXED(cur->type))
15016
0
    if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
15017
0
        return(-1);
15018
0
      if (xmlSchemaCheckCOSSTDerivedOK(actxt,
15019
0
        type, cur->type, subset) == 0)
15020
0
      {
15021
    /*
15022
    * It just has to be validly derived from at least one
15023
    * member-type.
15024
    */
15025
0
    return (0);
15026
0
      }
15027
0
      cur = cur->next;
15028
0
  }
15029
0
    }
15030
0
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
15031
0
}
15032
15033
/**
15034
 * xmlSchemaCheckTypeDefCircularInternal:
15035
 * @pctxt:  the schema parser context
15036
 * @ctxtType:  the type definition
15037
 * @ancestor: an ancestor of @ctxtType
15038
 *
15039
 * Checks st-props-correct (2) + ct-props-correct (3).
15040
 * Circular type definitions are not allowed.
15041
 *
15042
 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
15043
 * circular, 0 otherwise.
15044
 */
15045
static int
15046
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
15047
         xmlSchemaTypePtr ctxtType,
15048
         xmlSchemaTypePtr ancestor)
15049
0
{
15050
0
    int ret;
15051
15052
0
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
15053
0
  return (0);
15054
15055
0
    if (ctxtType == ancestor) {
15056
0
  xmlSchemaPCustomErr(pctxt,
15057
0
      XML_SCHEMAP_ST_PROPS_CORRECT_2,
15058
0
      WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
15059
0
      "The definition is circular", NULL);
15060
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
15061
0
    }
15062
0
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
15063
  /*
15064
  * Avoid infinite recursion on circular types not yet checked.
15065
  */
15066
0
  return (0);
15067
0
    }
15068
0
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
15069
0
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
15070
0
  ancestor->baseType);
15071
0
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
15072
0
    return (ret);
15073
0
}
15074
15075
/**
15076
 * xmlSchemaCheckTypeDefCircular:
15077
 * @item:  the complex/simple type definition
15078
 * @ctxt:  the parser context
15079
 * @name:  the name
15080
 *
15081
 * Checks for circular type definitions.
15082
 */
15083
static void
15084
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
15085
            xmlSchemaParserCtxtPtr ctxt)
15086
0
{
15087
0
    if ((item == NULL) ||
15088
0
  (item->type == XML_SCHEMA_TYPE_BASIC) ||
15089
0
  (item->baseType == NULL))
15090
0
  return;
15091
0
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
15092
0
  item->baseType);
15093
0
}
15094
15095
/*
15096
* Simple Type Definition Representation OK (src-simple-type) 4
15097
*
15098
* "4 Circular union type definition is disallowed. That is, if the
15099
* <union> alternative is chosen, there must not be any entries in the
15100
* memberTypes [attribute] at any depth which resolve to the component
15101
* corresponding to the <simpleType>."
15102
*
15103
* Note that this should work on the *representation* of a component,
15104
* thus assumes any union types in the member types not being yet
15105
* substituted. At this stage we need the variety of the types
15106
* to be already computed.
15107
*/
15108
static int
15109
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
15110
          xmlSchemaTypePtr ctxType,
15111
          xmlSchemaTypeLinkPtr members)
15112
0
{
15113
0
    xmlSchemaTypeLinkPtr member;
15114
0
    xmlSchemaTypePtr memberType;
15115
15116
0
    member = members;
15117
0
    while (member != NULL) {
15118
0
  memberType = member->type;
15119
0
  while ((memberType != NULL) &&
15120
0
      (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
15121
0
      if (memberType == ctxType) {
15122
0
    xmlSchemaPCustomErr(pctxt,
15123
0
        XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
15124
0
        WXS_BASIC_CAST ctxType, NULL,
15125
0
        "The union type definition is circular", NULL);
15126
0
    return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
15127
0
      }
15128
0
      if ((WXS_IS_UNION(memberType)) &&
15129
0
    ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
15130
0
      {
15131
0
    int res;
15132
0
    memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
15133
0
    res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
15134
0
        ctxType,
15135
0
        xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
15136
0
    memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
15137
0
    if (res != 0)
15138
0
        return(res);
15139
0
      }
15140
0
      memberType = memberType->baseType;
15141
0
  }
15142
0
  member = member->next;
15143
0
    }
15144
0
    return(0);
15145
0
}
15146
15147
static int
15148
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15149
           xmlSchemaTypePtr type)
15150
0
{
15151
0
    if (! WXS_IS_UNION(type))
15152
0
  return(0);
15153
0
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15154
0
  type->memberTypes));
15155
0
}
15156
15157
/**
15158
 * xmlSchemaResolveTypeReferences:
15159
 * @item:  the complex/simple type definition
15160
 * @ctxt:  the parser context
15161
 * @name:  the name
15162
 *
15163
 * Resolves type definition references
15164
 */
15165
static void
15166
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15167
       xmlSchemaParserCtxtPtr ctxt)
15168
0
{
15169
0
    if (typeDef == NULL)
15170
0
  return;
15171
15172
    /*
15173
    * Resolve the base type.
15174
    */
15175
0
    if (typeDef->baseType == NULL) {
15176
0
  typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15177
0
      typeDef->base, typeDef->baseNs);
15178
0
  if (typeDef->baseType == NULL) {
15179
0
      xmlSchemaPResCompAttrErr(ctxt,
15180
0
    XML_SCHEMAP_SRC_RESOLVE,
15181
0
    WXS_BASIC_CAST typeDef, typeDef->node,
15182
0
    "base", typeDef->base, typeDef->baseNs,
15183
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
15184
0
      return;
15185
0
  }
15186
0
    }
15187
0
    if (WXS_IS_SIMPLE(typeDef)) {
15188
0
  if (WXS_IS_UNION(typeDef)) {
15189
      /*
15190
      * Resolve the memberTypes.
15191
      */
15192
0
      xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15193
0
      return;
15194
0
  } else if (WXS_IS_LIST(typeDef)) {
15195
      /*
15196
      * Resolve the itemType.
15197
      */
15198
0
      if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15199
15200
0
    typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15201
0
        typeDef->base, typeDef->baseNs);
15202
15203
0
    if ((typeDef->subtypes == NULL) ||
15204
0
        (! WXS_IS_SIMPLE(typeDef->subtypes)))
15205
0
    {
15206
0
        typeDef->subtypes = NULL;
15207
0
        xmlSchemaPResCompAttrErr(ctxt,
15208
0
      XML_SCHEMAP_SRC_RESOLVE,
15209
0
      WXS_BASIC_CAST typeDef, typeDef->node,
15210
0
      "itemType", typeDef->base, typeDef->baseNs,
15211
0
      XML_SCHEMA_TYPE_SIMPLE, NULL);
15212
0
    }
15213
0
      }
15214
0
      return;
15215
0
  }
15216
0
    }
15217
    /*
15218
    * The ball of letters below means, that if we have a particle
15219
    * which has a QName-helper component as its {term}, we want
15220
    * to resolve it...
15221
    */
15222
0
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15223
0
  ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15224
0
      XML_SCHEMA_TYPE_PARTICLE) &&
15225
0
  (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15226
0
  ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15227
0
      XML_SCHEMA_EXTRA_QNAMEREF))
15228
0
    {
15229
0
  xmlSchemaQNameRefPtr ref =
15230
0
      WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15231
0
  xmlSchemaModelGroupDefPtr groupDef;
15232
15233
  /*
15234
  * URGENT TODO: Test this.
15235
  */
15236
0
  WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15237
  /*
15238
  * Resolve the MG definition reference.
15239
  */
15240
0
  groupDef =
15241
0
      WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15242
0
    ref->itemType, ref->name, ref->targetNamespace);
15243
0
  if (groupDef == NULL) {
15244
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15245
0
    NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15246
0
    "ref", ref->name, ref->targetNamespace, ref->itemType,
15247
0
    NULL);
15248
      /* Remove the particle. */
15249
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15250
0
  } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15251
      /* Remove the particle. */
15252
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15253
0
  else {
15254
      /*
15255
      * Assign the MG definition's {model group} to the
15256
      * particle's {term}.
15257
      */
15258
0
      WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15259
15260
0
      if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15261
    /*
15262
    * SPEC cos-all-limited (1.2)
15263
    * "1.2 the {term} property of a particle with
15264
    * {max occurs}=1 which is part of a pair which constitutes
15265
    * the {content type} of a complex type definition."
15266
    */
15267
0
    if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15268
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
15269
      /* TODO: error code */
15270
0
      XML_SCHEMAP_COS_ALL_LIMITED,
15271
0
      WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15272
0
      "The particle's {max occurs} must be 1, since the "
15273
0
      "reference resolves to an 'all' model group",
15274
0
      NULL, NULL);
15275
0
    }
15276
0
      }
15277
0
  }
15278
0
    }
15279
0
}
15280
15281
15282
15283
/**
15284
 * xmlSchemaCheckSTPropsCorrect:
15285
 * @ctxt:  the schema parser context
15286
 * @type:  the simple type definition
15287
 *
15288
 * Checks st-props-correct.
15289
 *
15290
 * Returns 0 if the properties are correct,
15291
 * if not, a positive error code and -1 on internal
15292
 * errors.
15293
 */
15294
static int
15295
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15296
           xmlSchemaTypePtr type)
15297
0
{
15298
0
    xmlSchemaTypePtr baseType = type->baseType;
15299
0
    xmlChar *str = NULL;
15300
15301
    /* STATE: error funcs converted. */
15302
    /*
15303
    * Schema Component Constraint: Simple Type Definition Properties Correct
15304
    *
15305
    * NOTE: This is somehow redundant, since we actually built a simple type
15306
    * to have all the needed information; this acts as an self test.
15307
    */
15308
    /* Base type: If the datatype has been `derived` by `restriction`
15309
    * then the Simple Type Definition component from which it is `derived`,
15310
    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15311
    */
15312
0
    if (baseType == NULL) {
15313
  /*
15314
  * TODO: Think about: "modulo the impact of Missing
15315
  * Sub-components ($5.3)."
15316
  */
15317
0
  xmlSchemaPCustomErr(ctxt,
15318
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15319
0
      WXS_BASIC_CAST type, NULL,
15320
0
      "No base type existent", NULL);
15321
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15322
15323
0
    }
15324
0
    if (! WXS_IS_SIMPLE(baseType)) {
15325
0
  xmlSchemaPCustomErr(ctxt,
15326
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15327
0
      WXS_BASIC_CAST type, NULL,
15328
0
      "The base type '%s' is not a simple type",
15329
0
      xmlSchemaGetComponentQName(&str, baseType));
15330
0
  FREE_AND_NULL(str)
15331
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15332
0
    }
15333
0
    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15334
0
  (WXS_IS_RESTRICTION(type) == 0) &&
15335
0
  ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15336
0
         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15337
0
  xmlSchemaPCustomErr(ctxt,
15338
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15339
0
      WXS_BASIC_CAST type, NULL,
15340
0
      "A type, derived by list or union, must have "
15341
0
      "the simple ur-type definition as base type, not '%s'",
15342
0
      xmlSchemaGetComponentQName(&str, baseType));
15343
0
  FREE_AND_NULL(str)
15344
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15345
0
    }
15346
    /*
15347
    * Variety: One of {atomic, list, union}.
15348
    */
15349
0
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15350
0
  (! WXS_IS_LIST(type))) {
15351
0
  xmlSchemaPCustomErr(ctxt,
15352
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15353
0
      WXS_BASIC_CAST type, NULL,
15354
0
      "The variety is absent", NULL);
15355
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15356
0
    }
15357
    /* TODO: Finish this. Hmm, is this finished? */
15358
15359
    /*
15360
    * 3 The {final} of the {base type definition} must not contain restriction.
15361
    */
15362
0
    if (xmlSchemaTypeFinalContains(baseType,
15363
0
  XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15364
0
  xmlSchemaPCustomErr(ctxt,
15365
0
      XML_SCHEMAP_ST_PROPS_CORRECT_3,
15366
0
      WXS_BASIC_CAST type, NULL,
15367
0
      "The 'final' of its base type '%s' must not contain "
15368
0
      "'restriction'",
15369
0
      xmlSchemaGetComponentQName(&str, baseType));
15370
0
  FREE_AND_NULL(str)
15371
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15372
0
    }
15373
15374
    /*
15375
    * 2 All simple type definitions must be derived ultimately from the `simple
15376
    * ur-type definition` (so circular definitions are disallowed). That is, it
15377
    * must be possible to reach a built-in primitive datatype or the `simple
15378
    * ur-type definition` by repeatedly following the {base type definition}.
15379
    *
15380
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15381
    */
15382
0
    return (0);
15383
0
}
15384
15385
/**
15386
 * xmlSchemaCheckCOSSTRestricts:
15387
 * @ctxt:  the schema parser context
15388
 * @type:  the simple type definition
15389
 *
15390
 * Schema Component Constraint:
15391
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15392
15393
 * Checks if the given @type (simpleType) is derived validly by restriction.
15394
 * STATUS:
15395
 *
15396
 * Returns -1 on internal errors, 0 if the type is validly derived,
15397
 * a positive error code otherwise.
15398
 */
15399
static int
15400
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15401
           xmlSchemaTypePtr type)
15402
0
{
15403
0
    xmlChar *str = NULL;
15404
15405
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15406
0
  PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15407
0
      "given type is not a user-derived simpleType");
15408
0
  return (-1);
15409
0
    }
15410
15411
0
    if (WXS_IS_ATOMIC(type)) {
15412
0
  xmlSchemaTypePtr primitive;
15413
  /*
15414
  * 1.1 The {base type definition} must be an atomic simple
15415
  * type definition or a built-in primitive datatype.
15416
  */
15417
0
  if (! WXS_IS_ATOMIC(type->baseType)) {
15418
0
      xmlSchemaPCustomErr(pctxt,
15419
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15420
0
    WXS_BASIC_CAST type, NULL,
15421
0
    "The base type '%s' is not an atomic simple type",
15422
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15423
0
      FREE_AND_NULL(str)
15424
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15425
0
  }
15426
  /* 1.2 The {final} of the {base type definition} must not contain
15427
  * restriction.
15428
  */
15429
  /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15430
0
  if (xmlSchemaTypeFinalContains(type->baseType,
15431
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15432
0
      xmlSchemaPCustomErr(pctxt,
15433
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15434
0
    WXS_BASIC_CAST type, NULL,
15435
0
    "The final of its base type '%s' must not contain 'restriction'",
15436
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15437
0
      FREE_AND_NULL(str)
15438
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15439
0
  }
15440
15441
  /*
15442
  * 1.3.1 DF must be an allowed constraining facet for the {primitive
15443
  * type definition}, as specified in the appropriate subsection of 3.2
15444
  * Primitive datatypes.
15445
  */
15446
0
  if (type->facets != NULL) {
15447
0
      xmlSchemaFacetPtr facet;
15448
0
      int ok = 1;
15449
15450
0
      primitive = xmlSchemaGetPrimitiveType(type);
15451
0
      if (primitive == NULL) {
15452
0
    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15453
0
        "failed to get primitive type");
15454
0
    return (-1);
15455
0
      }
15456
0
      facet = type->facets;
15457
0
      do {
15458
0
    if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15459
0
        ok = 0;
15460
0
        xmlSchemaPIllegalFacetAtomicErr(pctxt,
15461
0
      XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15462
0
      type, primitive, facet);
15463
0
    }
15464
0
    facet = facet->next;
15465
0
      } while (facet != NULL);
15466
0
      if (ok == 0)
15467
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15468
0
  }
15469
  /*
15470
  * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15471
  * of the {base type definition} (call this BF),then the DF's {value}
15472
  * must be a valid restriction of BF's {value} as defined in
15473
  * [XML Schemas: Datatypes]."
15474
  *
15475
  * NOTE (1.3.2) Facet derivation constraints are currently handled in
15476
  * xmlSchemaDeriveAndValidateFacets()
15477
  */
15478
0
    } else if (WXS_IS_LIST(type)) {
15479
0
  xmlSchemaTypePtr itemType = NULL;
15480
15481
0
  itemType = type->subtypes;
15482
0
  if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15483
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15484
0
    "failed to evaluate the item type");
15485
0
      return (-1);
15486
0
  }
15487
0
  if (WXS_IS_TYPE_NOT_FIXED(itemType))
15488
0
      xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15489
  /*
15490
  * 2.1 The {item type definition} must have a {variety} of atomic or
15491
  * union (in which case all the {member type definitions}
15492
  * must be atomic).
15493
  */
15494
0
  if ((! WXS_IS_ATOMIC(itemType)) &&
15495
0
      (! WXS_IS_UNION(itemType))) {
15496
0
      xmlSchemaPCustomErr(pctxt,
15497
0
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15498
0
    WXS_BASIC_CAST type, NULL,
15499
0
    "The item type '%s' does not have a variety of atomic or union",
15500
0
    xmlSchemaGetComponentQName(&str, itemType));
15501
0
      FREE_AND_NULL(str)
15502
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15503
0
  } else if (WXS_IS_UNION(itemType)) {
15504
0
      xmlSchemaTypeLinkPtr member;
15505
15506
0
      member = itemType->memberTypes;
15507
0
      while (member != NULL) {
15508
0
    if (! WXS_IS_ATOMIC(member->type)) {
15509
0
        xmlSchemaPCustomErr(pctxt,
15510
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15511
0
      WXS_BASIC_CAST type, NULL,
15512
0
      "The item type is a union type, but the "
15513
0
      "member type '%s' of this item type is not atomic",
15514
0
      xmlSchemaGetComponentQName(&str, member->type));
15515
0
        FREE_AND_NULL(str)
15516
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15517
0
    }
15518
0
    member = member->next;
15519
0
      }
15520
0
  }
15521
15522
0
  if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15523
0
      xmlSchemaFacetPtr facet;
15524
      /*
15525
      * This is the case if we have: <simpleType><list ..
15526
      */
15527
      /*
15528
      * 2.3.1
15529
      * 2.3.1.1 The {final} of the {item type definition} must not
15530
      * contain list.
15531
      */
15532
0
      if (xmlSchemaTypeFinalContains(itemType,
15533
0
    XML_SCHEMAS_TYPE_FINAL_LIST)) {
15534
0
    xmlSchemaPCustomErr(pctxt,
15535
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15536
0
        WXS_BASIC_CAST type, NULL,
15537
0
        "The final of its item type '%s' must not contain 'list'",
15538
0
        xmlSchemaGetComponentQName(&str, itemType));
15539
0
    FREE_AND_NULL(str)
15540
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15541
0
      }
15542
      /*
15543
      * 2.3.1.2 The {facets} must only contain the whiteSpace
15544
      * facet component.
15545
      * OPTIMIZE TODO: the S4S already disallows any facet
15546
      * to be specified.
15547
      */
15548
0
      if (type->facets != NULL) {
15549
0
    facet = type->facets;
15550
0
    do {
15551
0
        if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15552
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15553
0
          XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15554
0
          type, facet);
15555
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15556
0
        }
15557
0
        facet = facet->next;
15558
0
    } while (facet != NULL);
15559
0
      }
15560
      /*
15561
      * MAYBE TODO: (Hmm, not really) Datatypes states:
15562
      * A `list` datatype can be `derived` from an `atomic` datatype
15563
      * whose `lexical space` allows space (such as string or anyURI)or
15564
      * a `union` datatype any of whose {member type definitions}'s
15565
      * `lexical space` allows space.
15566
      */
15567
0
  } else {
15568
      /*
15569
      * This is the case if we have: <simpleType><restriction ...
15570
      * I.e. the variety of "list" is inherited.
15571
      */
15572
      /*
15573
      * 2.3.2
15574
      * 2.3.2.1 The {base type definition} must have a {variety} of list.
15575
      */
15576
0
      if (! WXS_IS_LIST(type->baseType)) {
15577
0
    xmlSchemaPCustomErr(pctxt,
15578
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15579
0
        WXS_BASIC_CAST type, NULL,
15580
0
        "The base type '%s' must be a list type",
15581
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15582
0
    FREE_AND_NULL(str)
15583
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15584
0
      }
15585
      /*
15586
      * 2.3.2.2 The {final} of the {base type definition} must not
15587
      * contain restriction.
15588
      */
15589
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15590
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15591
0
    xmlSchemaPCustomErr(pctxt,
15592
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15593
0
        WXS_BASIC_CAST type, NULL,
15594
0
        "The 'final' of the base type '%s' must not contain 'restriction'",
15595
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15596
0
    FREE_AND_NULL(str)
15597
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15598
0
      }
15599
      /*
15600
      * 2.3.2.3 The {item type definition} must be validly derived
15601
      * from the {base type definition}'s {item type definition} given
15602
      * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15603
      */
15604
0
      {
15605
0
    xmlSchemaTypePtr baseItemType;
15606
15607
0
    baseItemType = type->baseType->subtypes;
15608
0
    if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15609
0
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15610
0
      "failed to eval the item type of a base type");
15611
0
        return (-1);
15612
0
    }
15613
0
    if ((itemType != baseItemType) &&
15614
0
        (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15615
0
      baseItemType, 0) != 0)) {
15616
0
        xmlChar *strBIT = NULL, *strBT = NULL;
15617
0
        xmlSchemaPCustomErrExt(pctxt,
15618
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15619
0
      WXS_BASIC_CAST type, NULL,
15620
0
      "The item type '%s' is not validly derived from "
15621
0
      "the item type '%s' of the base type '%s'",
15622
0
      xmlSchemaGetComponentQName(&str, itemType),
15623
0
      xmlSchemaGetComponentQName(&strBIT, baseItemType),
15624
0
      xmlSchemaGetComponentQName(&strBT, type->baseType));
15625
15626
0
        FREE_AND_NULL(str)
15627
0
        FREE_AND_NULL(strBIT)
15628
0
        FREE_AND_NULL(strBT)
15629
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15630
0
    }
15631
0
      }
15632
15633
0
      if (type->facets != NULL) {
15634
0
    xmlSchemaFacetPtr facet;
15635
0
    int ok = 1;
15636
    /*
15637
    * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15638
    * and enumeration facet components are allowed among the {facets}.
15639
    */
15640
0
    facet = type->facets;
15641
0
    do {
15642
0
        switch (facet->type) {
15643
0
      case XML_SCHEMA_FACET_LENGTH:
15644
0
      case XML_SCHEMA_FACET_MINLENGTH:
15645
0
      case XML_SCHEMA_FACET_MAXLENGTH:
15646
0
      case XML_SCHEMA_FACET_WHITESPACE:
15647
          /*
15648
          * TODO: 2.5.1.2 List datatypes
15649
          * The value of `whiteSpace` is fixed to the value collapse.
15650
          */
15651
0
      case XML_SCHEMA_FACET_PATTERN:
15652
0
      case XML_SCHEMA_FACET_ENUMERATION:
15653
0
          break;
15654
0
      default: {
15655
0
          xmlSchemaPIllegalFacetListUnionErr(pctxt,
15656
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15657
0
        type, facet);
15658
          /*
15659
          * We could return, but it's nicer to report all
15660
          * invalid facets.
15661
          */
15662
0
          ok = 0;
15663
0
      }
15664
0
        }
15665
0
        facet = facet->next;
15666
0
    } while (facet != NULL);
15667
0
    if (ok == 0)
15668
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15669
    /*
15670
    * SPEC (2.3.2.5) (same as 1.3.2)
15671
    *
15672
    * NOTE (2.3.2.5) This is currently done in
15673
    * xmlSchemaDeriveAndValidateFacets()
15674
    */
15675
0
      }
15676
0
  }
15677
0
    } else if (WXS_IS_UNION(type)) {
15678
  /*
15679
  * 3.1 The {member type definitions} must all have {variety} of
15680
  * atomic or list.
15681
  */
15682
0
  xmlSchemaTypeLinkPtr member;
15683
15684
0
  member = type->memberTypes;
15685
0
  while (member != NULL) {
15686
0
      if (WXS_IS_TYPE_NOT_FIXED(member->type))
15687
0
    xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15688
15689
0
      if ((! WXS_IS_ATOMIC(member->type)) &&
15690
0
    (! WXS_IS_LIST(member->type))) {
15691
0
    xmlSchemaPCustomErr(pctxt,
15692
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15693
0
        WXS_BASIC_CAST type, NULL,
15694
0
        "The member type '%s' is neither an atomic, nor a list type",
15695
0
        xmlSchemaGetComponentQName(&str, member->type));
15696
0
    FREE_AND_NULL(str)
15697
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15698
0
      }
15699
0
      member = member->next;
15700
0
  }
15701
  /*
15702
  * 3.3.1 If the {base type definition} is the `simple ur-type
15703
  * definition`
15704
  */
15705
0
  if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15706
      /*
15707
      * 3.3.1.1 All of the {member type definitions} must have a
15708
      * {final} which does not contain union.
15709
      */
15710
0
      member = type->memberTypes;
15711
0
      while (member != NULL) {
15712
0
    if (xmlSchemaTypeFinalContains(member->type,
15713
0
        XML_SCHEMAS_TYPE_FINAL_UNION)) {
15714
0
        xmlSchemaPCustomErr(pctxt,
15715
0
      XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15716
0
      WXS_BASIC_CAST type, NULL,
15717
0
      "The 'final' of member type '%s' contains 'union'",
15718
0
      xmlSchemaGetComponentQName(&str, member->type));
15719
0
        FREE_AND_NULL(str)
15720
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15721
0
    }
15722
0
    member = member->next;
15723
0
      }
15724
      /*
15725
      * 3.3.1.2 The {facets} must be empty.
15726
      */
15727
0
      if (type->facetSet != NULL) {
15728
0
    xmlSchemaPCustomErr(pctxt,
15729
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15730
0
        WXS_BASIC_CAST type, NULL,
15731
0
        "No facets allowed", NULL);
15732
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15733
0
      }
15734
0
  } else {
15735
      /*
15736
      * 3.3.2.1 The {base type definition} must have a {variety} of union.
15737
      * I.e. the variety of "list" is inherited.
15738
      */
15739
0
      if (! WXS_IS_UNION(type->baseType)) {
15740
0
    xmlSchemaPCustomErr(pctxt,
15741
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15742
0
        WXS_BASIC_CAST type, NULL,
15743
0
        "The base type '%s' is not a union type",
15744
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15745
0
    FREE_AND_NULL(str)
15746
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15747
0
      }
15748
      /*
15749
      * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15750
      */
15751
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15752
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15753
0
    xmlSchemaPCustomErr(pctxt,
15754
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15755
0
        WXS_BASIC_CAST type, NULL,
15756
0
        "The 'final' of its base type '%s' must not contain 'restriction'",
15757
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15758
0
    FREE_AND_NULL(str)
15759
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15760
0
      }
15761
      /*
15762
      * 3.3.2.3 The {member type definitions}, in order, must be validly
15763
      * derived from the corresponding type definitions in the {base
15764
      * type definition}'s {member type definitions} given the empty set,
15765
      * as defined in Type Derivation OK (Simple) ($3.14.6).
15766
      */
15767
0
      {
15768
0
    xmlSchemaTypeLinkPtr baseMember;
15769
15770
    /*
15771
    * OPTIMIZE: if the type is restricting, it has no local defined
15772
    * member types and inherits the member types of the base type;
15773
    * thus a check for equality can be skipped.
15774
    */
15775
    /*
15776
    * Even worse: I cannot see a scenario where a restricting
15777
    * union simple type can have other member types as the member
15778
    * types of it's base type. This check seems not necessary with
15779
    * respect to the derivation process in libxml2.
15780
    * But necessary if constructing types with an API.
15781
    */
15782
0
    if (type->memberTypes != NULL) {
15783
0
        member = type->memberTypes;
15784
0
        baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15785
0
        if ((member == NULL) && (baseMember != NULL)) {
15786
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15787
0
          "different number of member types in base");
15788
0
        }
15789
0
        while (member != NULL) {
15790
0
      if (baseMember == NULL) {
15791
0
          PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15792
0
          "different number of member types in base");
15793
0
      } else if ((member->type != baseMember->type) &&
15794
0
          (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15795
0
        member->type, baseMember->type, 0) != 0)) {
15796
0
          xmlChar *strBMT = NULL, *strBT = NULL;
15797
15798
0
          xmlSchemaPCustomErrExt(pctxt,
15799
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15800
0
        WXS_BASIC_CAST type, NULL,
15801
0
        "The member type %s is not validly "
15802
0
        "derived from its corresponding member "
15803
0
        "type %s of the base type %s",
15804
0
        xmlSchemaGetComponentQName(&str, member->type),
15805
0
        xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15806
0
        xmlSchemaGetComponentQName(&strBT, type->baseType));
15807
0
          FREE_AND_NULL(str)
15808
0
          FREE_AND_NULL(strBMT)
15809
0
          FREE_AND_NULL(strBT)
15810
0
          return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15811
0
      }
15812
0
      member = member->next;
15813
0
                        if (baseMember != NULL)
15814
0
                            baseMember = baseMember->next;
15815
0
        }
15816
0
    }
15817
0
      }
15818
      /*
15819
      * 3.3.2.4 Only pattern and enumeration facet components are
15820
      * allowed among the {facets}.
15821
      */
15822
0
      if (type->facets != NULL) {
15823
0
    xmlSchemaFacetPtr facet;
15824
0
    int ok = 1;
15825
15826
0
    facet = type->facets;
15827
0
    do {
15828
0
        if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15829
0
      (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15830
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15831
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15832
0
        type, facet);
15833
0
      ok = 0;
15834
0
        }
15835
0
        facet = facet->next;
15836
0
    } while (facet != NULL);
15837
0
    if (ok == 0)
15838
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15839
15840
0
      }
15841
      /*
15842
      * SPEC (3.3.2.5) (same as 1.3.2)
15843
      *
15844
      * NOTE (3.3.2.5) This is currently done in
15845
      * xmlSchemaDeriveAndValidateFacets()
15846
      */
15847
0
  }
15848
0
    }
15849
15850
0
    return (0);
15851
0
}
15852
15853
/**
15854
 * xmlSchemaCheckSRCSimpleType:
15855
 * @ctxt:  the schema parser context
15856
 * @type:  the simple type definition
15857
 *
15858
 * Checks crc-simple-type constraints.
15859
 *
15860
 * Returns 0 if the constraints are satisfied,
15861
 * if not a positive error code and -1 on internal
15862
 * errors.
15863
 */
15864
#if 0
15865
static int
15866
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15867
          xmlSchemaTypePtr type)
15868
{
15869
    /*
15870
    * src-simple-type.1 The corresponding simple type definition, if any,
15871
    * must satisfy the conditions set out in Constraints on Simple Type
15872
    * Definition Schema Components ($3.14.6).
15873
    */
15874
    if (WXS_IS_RESTRICTION(type)) {
15875
  /*
15876
  * src-simple-type.2 "If the <restriction> alternative is chosen,
15877
  * either it must have a base [attribute] or a <simpleType> among its
15878
  * [children], but not both."
15879
  * NOTE: This is checked in the parse function of <restriction>.
15880
  */
15881
  /*
15882
  *
15883
  */
15884
    } else if (WXS_IS_LIST(type)) {
15885
  /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15886
  * an itemType [attribute] or a <simpleType> among its [children],
15887
  * but not both."
15888
  *
15889
  * NOTE: This is checked in the parse function of <list>.
15890
  */
15891
    } else if (WXS_IS_UNION(type)) {
15892
  /*
15893
  * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15894
  */
15895
    }
15896
    return (0);
15897
}
15898
#endif
15899
15900
static int
15901
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15902
0
{
15903
0
   if (ctxt->vctxt == NULL) {
15904
0
  ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15905
0
  if (ctxt->vctxt == NULL) {
15906
0
      xmlSchemaPErr(ctxt, NULL,
15907
0
    XML_SCHEMAP_INTERNAL,
15908
0
    "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15909
0
    "failed to create a temp. validation context.\n",
15910
0
    NULL, NULL);
15911
0
      return (-1);
15912
0
  }
15913
  /* TODO: Pass user data. */
15914
0
  xmlSchemaSetValidErrors(ctxt->vctxt,
15915
0
      ctxt->error, ctxt->warning, ctxt->errCtxt);
15916
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15917
0
      ctxt->serror, ctxt->errCtxt);
15918
0
    }
15919
0
    return (0);
15920
0
}
15921
15922
static int
15923
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15924
           xmlNodePtr node,
15925
           xmlSchemaTypePtr type,
15926
           const xmlChar *value,
15927
           xmlSchemaValPtr *retVal,
15928
           int fireErrors,
15929
           int normalize,
15930
           int isNormalized);
15931
15932
/**
15933
 * xmlSchemaParseCheckCOSValidDefault:
15934
 * @pctxt:  the schema parser context
15935
 * @type:  the simple type definition
15936
 * @value: the default value
15937
 * @node: an optional node (the holder of the value)
15938
 *
15939
 * Schema Component Constraint: Element Default Valid (Immediate)
15940
 * (cos-valid-default)
15941
 * This will be used by the parser only. For the validator there's
15942
 * an other version.
15943
 *
15944
 * Returns 0 if the constraints are satisfied,
15945
 * if not, a positive error code and -1 on internal
15946
 * errors.
15947
 */
15948
static int
15949
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15950
           xmlNodePtr node,
15951
           xmlSchemaTypePtr type,
15952
           const xmlChar *value,
15953
           xmlSchemaValPtr *val)
15954
0
{
15955
0
    int ret = 0;
15956
15957
    /*
15958
    * cos-valid-default:
15959
    * Schema Component Constraint: Element Default Valid (Immediate)
15960
    * For a string to be a valid default with respect to a type
15961
    * definition the appropriate case among the following must be true:
15962
    */
15963
0
    if WXS_IS_COMPLEX(type) {
15964
  /*
15965
  * Complex type.
15966
  *
15967
  * SPEC (2.1) "its {content type} must be a simple type definition
15968
  * or mixed."
15969
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15970
  * type}'s particle must be `emptiable` as defined by
15971
  * Particle Emptiable ($3.9.6)."
15972
  */
15973
0
  if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15974
0
      ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15975
      /* NOTE that this covers (2.2.2) as well. */
15976
0
      xmlSchemaPCustomErr(pctxt,
15977
0
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15978
0
    WXS_BASIC_CAST type, type->node,
15979
0
    "For a string to be a valid default, the type definition "
15980
0
    "must be a simple type or a complex type with mixed content "
15981
0
    "and a particle emptiable", NULL);
15982
0
      return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15983
0
  }
15984
0
    }
15985
    /*
15986
    * 1 If the type definition is a simple type definition, then the string
15987
    * must be `valid` with respect to that definition as defined by String
15988
    * Valid ($3.14.4).
15989
    *
15990
    * AND
15991
    *
15992
    * 2.2.1 If the {content type} is a simple type definition, then the
15993
    * string must be `valid` with respect to that simple type definition
15994
    * as defined by String Valid ($3.14.4).
15995
    */
15996
0
    if (WXS_IS_SIMPLE(type))
15997
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15998
0
      type, value, val, 1, 1, 0);
15999
0
    else if (WXS_HAS_SIMPLE_CONTENT(type))
16000
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
16001
0
      type->contentTypeDef, value, val, 1, 1, 0);
16002
0
    else
16003
0
  return (ret);
16004
16005
0
    if (ret < 0) {
16006
0
  PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
16007
0
      "calling xmlSchemaVCheckCVCSimpleType()");
16008
0
    }
16009
16010
0
    return (ret);
16011
0
}
16012
16013
/**
16014
 * xmlSchemaCheckCTPropsCorrect:
16015
 * @ctxt:  the schema parser context
16016
 * @type:  the complex type definition
16017
 *
16018
 *.(4.6) Constraints on Complex Type Definition Schema Components
16019
 * Schema Component Constraint:
16020
 * Complex Type Definition Properties Correct (ct-props-correct)
16021
 * STATUS: (seems) complete
16022
 *
16023
 * Returns 0 if the constraints are satisfied, a positive
16024
 * error code if not and -1 if an internal error occurred.
16025
 */
16026
static int
16027
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
16028
           xmlSchemaTypePtr type)
16029
0
{
16030
    /*
16031
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
16032
    *
16033
    * SPEC (1) "The values of the properties of a complex type definition must
16034
    * be as described in the property tableau in The Complex Type Definition
16035
    * Schema Component ($3.4.1), modulo the impact of Missing
16036
    * Sub-components ($5.3)."
16037
    */
16038
0
    if ((type->baseType != NULL) &&
16039
0
  (WXS_IS_SIMPLE(type->baseType)) &&
16040
0
  (WXS_IS_EXTENSION(type) == 0)) {
16041
  /*
16042
  * SPEC (2) "If the {base type definition} is a simple type definition,
16043
  * the {derivation method} must be extension."
16044
  */
16045
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
16046
0
      XML_SCHEMAP_SRC_CT_1,
16047
0
      NULL, WXS_BASIC_CAST type,
16048
0
      "If the base type is a simple type, the derivation method must be "
16049
0
      "'extension'", NULL, NULL);
16050
0
  return (XML_SCHEMAP_SRC_CT_1);
16051
0
    }
16052
    /*
16053
    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
16054
    * definition`. That is, it must be possible to reach the `ur-type
16055
    * definition` by repeatedly following the {base type definition}."
16056
    *
16057
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
16058
    */
16059
    /*
16060
    * NOTE that (4) and (5) need the following:
16061
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
16062
    *   - attribute group references need to be expanded already
16063
    *   - simple types need to be typefixed already
16064
    */
16065
0
    if (type->attrUses &&
16066
0
  (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
16067
0
    {
16068
0
  xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
16069
0
  xmlSchemaAttributeUsePtr use, tmp;
16070
0
  int i, j, hasId = 0;
16071
16072
0
  for (i = uses->nbItems -1; i >= 0; i--) {
16073
0
      use = uses->items[i];
16074
16075
      /*
16076
      * SPEC ct-props-correct
16077
      * (4) "Two distinct attribute declarations in the
16078
      * {attribute uses} must not have identical {name}s and
16079
      * {target namespace}s."
16080
      */
16081
0
      if (i > 0) {
16082
0
    for (j = i -1; j >= 0; j--) {
16083
0
        tmp = uses->items[j];
16084
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
16085
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
16086
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
16087
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
16088
0
        {
16089
0
      xmlChar *str = NULL;
16090
16091
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
16092
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
16093
0
          NULL, WXS_BASIC_CAST type,
16094
0
          "Duplicate %s",
16095
0
          xmlSchemaGetComponentDesignation(&str, use),
16096
0
          NULL);
16097
0
      FREE_AND_NULL(str);
16098
      /*
16099
      * Remove the duplicate.
16100
      */
16101
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
16102
0
          goto exit_failure;
16103
0
      goto next_use;
16104
0
        }
16105
0
    }
16106
0
      }
16107
      /*
16108
      * SPEC ct-props-correct
16109
      * (5) "Two distinct attribute declarations in the
16110
      * {attribute uses} must not have {type definition}s which
16111
      * are or are derived from ID."
16112
      */
16113
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
16114
0
    if (xmlSchemaIsDerivedFromBuiltInType(
16115
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
16116
0
    {
16117
0
        if (hasId) {
16118
0
      xmlChar *str = NULL;
16119
16120
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
16121
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
16122
0
          NULL, WXS_BASIC_CAST type,
16123
0
          "There must not exist more than one attribute "
16124
0
          "declaration of type 'xs:ID' "
16125
0
          "(or derived from 'xs:ID'). The %s violates this "
16126
0
          "constraint",
16127
0
          xmlSchemaGetComponentDesignation(&str, use),
16128
0
          NULL);
16129
0
      FREE_AND_NULL(str);
16130
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
16131
0
          goto exit_failure;
16132
0
        }
16133
16134
0
        hasId = 1;
16135
0
    }
16136
0
      }
16137
0
next_use: {}
16138
0
  }
16139
0
    }
16140
0
    return (0);
16141
0
exit_failure:
16142
0
    return(-1);
16143
0
}
16144
16145
static int
16146
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16147
           xmlSchemaTypePtr typeB)
16148
0
{
16149
    /*
16150
    * TODO: This should implement component-identity
16151
    * in the future.
16152
    */
16153
0
    if ((typeA == NULL) || (typeB == NULL))
16154
0
  return (0);
16155
0
    return (typeA == typeB);
16156
0
}
16157
16158
/**
16159
 * xmlSchemaCheckCOSCTDerivedOK:
16160
 * @ctxt:  the schema parser context
16161
 * @type:  the to-be derived complex type definition
16162
 * @baseType:  the base complex type definition
16163
 * @set: the given set
16164
 *
16165
 * Schema Component Constraint:
16166
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16167
 *
16168
 * STATUS: completed
16169
 *
16170
 * Returns 0 if the constraints are satisfied, or 1
16171
 * if not.
16172
 */
16173
static int
16174
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16175
           xmlSchemaTypePtr type,
16176
           xmlSchemaTypePtr baseType,
16177
           int set)
16178
0
{
16179
0
    int equal = xmlSchemaAreEqualTypes(type, baseType);
16180
    /* TODO: Error codes. */
16181
    /*
16182
    * SPEC "For a complex type definition (call it D, for derived)
16183
    * to be validly derived from a type definition (call this
16184
    * B, for base) given a subset of {extension, restriction}
16185
    * all of the following must be true:"
16186
    */
16187
0
    if (! equal) {
16188
  /*
16189
  * SPEC (1) "If B and D are not the same type definition, then the
16190
  * {derivation method} of D must not be in the subset."
16191
  */
16192
0
  if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16193
0
      ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16194
0
      return (1);
16195
0
    } else {
16196
  /*
16197
  * SPEC (2.1) "B and D must be the same type definition."
16198
  */
16199
0
  return (0);
16200
0
    }
16201
    /*
16202
    * SPEC (2.2) "B must be D's {base type definition}."
16203
    */
16204
0
    if (type->baseType == baseType)
16205
0
  return (0);
16206
    /*
16207
    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16208
    * definition`."
16209
    */
16210
0
    if (WXS_IS_ANYTYPE(type->baseType))
16211
0
  return (1);
16212
16213
0
    if (WXS_IS_COMPLEX(type->baseType)) {
16214
  /*
16215
  * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16216
  * must be validly derived from B given the subset as defined by this
16217
  * constraint."
16218
  */
16219
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16220
0
      baseType, set));
16221
0
    } else {
16222
  /*
16223
  * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16224
  * must be validly derived from B given the subset as defined in Type
16225
  * Derivation OK (Simple) ($3.14.6).
16226
  */
16227
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16228
0
      baseType, set));
16229
0
    }
16230
0
}
16231
16232
/**
16233
 * xmlSchemaCheckCOSDerivedOK:
16234
 * @type:  the derived simple type definition
16235
 * @baseType:  the base type definition
16236
 *
16237
 * Calls:
16238
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16239
 *
16240
 * Checks whether @type can be validly derived from @baseType.
16241
 *
16242
 * Returns 0 on success, an positive error code otherwise.
16243
 */
16244
static int
16245
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16246
         xmlSchemaTypePtr type,
16247
         xmlSchemaTypePtr baseType,
16248
         int set)
16249
0
{
16250
0
    if (WXS_IS_SIMPLE(type))
16251
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16252
0
    else
16253
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16254
0
}
16255
16256
/**
16257
 * xmlSchemaCheckCOSCTExtends:
16258
 * @ctxt:  the schema parser context
16259
 * @type:  the complex type definition
16260
 *
16261
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16262
 * Schema Component Constraint:
16263
 * Derivation Valid (Extension) (cos-ct-extends)
16264
 *
16265
 * STATUS:
16266
 *   missing:
16267
 *     (1.5)
16268
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16269
 *
16270
 * Returns 0 if the constraints are satisfied, a positive
16271
 * error code if not and -1 if an internal error occurred.
16272
 */
16273
static int
16274
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16275
         xmlSchemaTypePtr type)
16276
0
{
16277
0
    xmlSchemaTypePtr base = type->baseType;
16278
    /*
16279
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16280
    * temporarily only.
16281
    */
16282
    /*
16283
    * SPEC (1) "If the {base type definition} is a complex type definition,
16284
    * then all of the following must be true:"
16285
    */
16286
0
    if (WXS_IS_COMPLEX(base)) {
16287
  /*
16288
  * SPEC (1.1) "The {final} of the {base type definition} must not
16289
  * contain extension."
16290
  */
16291
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16292
0
      xmlSchemaPCustomErr(ctxt,
16293
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16294
0
    WXS_BASIC_CAST type, NULL,
16295
0
    "The 'final' of the base type definition "
16296
0
    "contains 'extension'", NULL);
16297
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16298
0
  }
16299
16300
  /*
16301
  * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16302
  * since they are automatically satisfied through the
16303
  * inheriting mechanism.
16304
  * Note that even if redefining components, the inheriting mechanism
16305
  * is used.
16306
  */
16307
#if 0
16308
  /*
16309
  * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16310
  * uses}
16311
  * of the complex type definition itself, that is, for every attribute
16312
  * use in the {attribute uses} of the {base type definition}, there
16313
  * must be an attribute use in the {attribute uses} of the complex
16314
  * type definition itself whose {attribute declaration} has the same
16315
  * {name}, {target namespace} and {type definition} as its attribute
16316
  * declaration"
16317
  */
16318
  if (base->attrUses != NULL) {
16319
      int i, j, found;
16320
      xmlSchemaAttributeUsePtr use, buse;
16321
16322
      for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16323
    buse = (WXS_LIST_CAST base->attrUses)->items[i];
16324
    found = 0;
16325
    if (type->attrUses != NULL) {
16326
        use = (WXS_LIST_CAST type->attrUses)->items[j];
16327
        for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16328
        {
16329
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
16330
        WXS_ATTRUSE_DECL_NAME(buse)) &&
16331
          (WXS_ATTRUSE_DECL_TNS(use) ==
16332
        WXS_ATTRUSE_DECL_TNS(buse)) &&
16333
          (WXS_ATTRUSE_TYPEDEF(use) ==
16334
        WXS_ATTRUSE_TYPEDEF(buse))
16335
      {
16336
          found = 1;
16337
          break;
16338
      }
16339
        }
16340
    }
16341
    if (! found) {
16342
        xmlChar *str = NULL;
16343
16344
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
16345
      XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16346
      NULL, WXS_BASIC_CAST type,
16347
      /*
16348
      * TODO: The report does not indicate that also the
16349
      * type needs to be the same.
16350
      */
16351
      "This type is missing a matching correspondent "
16352
      "for its {base type}'s %s in its {attribute uses}",
16353
      xmlSchemaGetComponentDesignation(&str,
16354
          buse->children),
16355
      NULL);
16356
        FREE_AND_NULL(str)
16357
    }
16358
      }
16359
  }
16360
  /*
16361
  * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16362
  * definition must also have one, and the base type definition's
16363
  * {attribute  wildcard}'s {namespace constraint} must be a subset
16364
  * of the complex  type definition's {attribute wildcard}'s {namespace
16365
  * constraint}, as defined by Wildcard Subset ($3.10.6)."
16366
  */
16367
16368
  /*
16369
  * MAYBE TODO: Enable if ever needed. But this will be needed only
16370
  * if created the type via a schema construction API.
16371
  */
16372
  if (base->attributeWildcard != NULL) {
16373
      if (type->attributeWildcard == NULL) {
16374
    xmlChar *str = NULL;
16375
16376
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16377
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16378
        NULL, type,
16379
        "The base %s has an attribute wildcard, "
16380
        "but this type is missing an attribute wildcard",
16381
        xmlSchemaGetComponentDesignation(&str, base));
16382
    FREE_AND_NULL(str)
16383
16384
      } else if (xmlSchemaCheckCOSNSSubset(
16385
    base->attributeWildcard, type->attributeWildcard))
16386
      {
16387
    xmlChar *str = NULL;
16388
16389
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16390
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16391
        NULL, type,
16392
        "The attribute wildcard is not a valid "
16393
        "superset of the one in the base %s",
16394
        xmlSchemaGetComponentDesignation(&str, base));
16395
    FREE_AND_NULL(str)
16396
      }
16397
  }
16398
#endif
16399
  /*
16400
  * SPEC (1.4) "One of the following must be true:"
16401
  */
16402
0
  if ((type->contentTypeDef != NULL) &&
16403
0
      (type->contentTypeDef == base->contentTypeDef)) {
16404
      /*
16405
      * SPEC (1.4.1) "The {content type} of the {base type definition}
16406
      * and the {content type} of the complex type definition itself
16407
      * must be the same simple type definition"
16408
      * PASS
16409
      */
16410
0
  } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16411
0
      (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16412
      /*
16413
      * SPEC (1.4.2) "The {content type} of both the {base type
16414
      * definition} and the complex type definition itself must
16415
      * be empty."
16416
      * PASS
16417
      */
16418
0
  } else {
16419
      /*
16420
      * SPEC (1.4.3) "All of the following must be true:"
16421
      */
16422
0
      if (type->subtypes == NULL) {
16423
    /*
16424
    * SPEC 1.4.3.1 The {content type} of the complex type
16425
    * definition itself must specify a particle.
16426
    */
16427
0
    xmlSchemaPCustomErr(ctxt,
16428
0
        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16429
0
        WXS_BASIC_CAST type, NULL,
16430
0
        "The content type must specify a particle", NULL);
16431
0
    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16432
0
      }
16433
      /*
16434
      * SPEC (1.4.3.2) "One of the following must be true:"
16435
      */
16436
0
      if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16437
    /*
16438
    * SPEC (1.4.3.2.1) "The {content type} of the {base type
16439
    * definition} must be empty.
16440
    * PASS
16441
    */
16442
0
      } else {
16443
    /*
16444
    * SPEC (1.4.3.2.2) "All of the following must be true:"
16445
    */
16446
0
    if ((type->contentType != base->contentType) ||
16447
0
        ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16448
0
        (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16449
        /*
16450
        * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16451
        * or both must be element-only."
16452
        */
16453
0
        xmlSchemaPCustomErr(ctxt,
16454
0
      XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16455
0
      WXS_BASIC_CAST type, NULL,
16456
0
      "The content type of both, the type and its base "
16457
0
      "type, must either 'mixed' or 'element-only'", NULL);
16458
0
        return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16459
0
    }
16460
    /*
16461
    * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16462
    * complex type definition must be a `valid extension`
16463
    * of the {base type definition}'s particle, as defined
16464
    * in Particle Valid (Extension) ($3.9.6)."
16465
    *
16466
    * NOTE that we won't check "Particle Valid (Extension)",
16467
    * since it is ensured by the derivation process in
16468
    * xmlSchemaTypeFixup(). We need to implement this when heading
16469
    * for a construction API
16470
    * TODO: !! This is needed to be checked if redefining a type !!
16471
    */
16472
0
      }
16473
      /*
16474
      * URGENT TODO (1.5)
16475
      */
16476
0
  }
16477
0
    } else {
16478
  /*
16479
  * SPEC (2) "If the {base type definition} is a simple type definition,
16480
  * then all of the following must be true:"
16481
  */
16482
0
  if (type->contentTypeDef != base) {
16483
      /*
16484
      * SPEC (2.1) "The {content type} must be the same simple type
16485
      * definition."
16486
      */
16487
0
      xmlSchemaPCustomErr(ctxt,
16488
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16489
0
    WXS_BASIC_CAST type, NULL,
16490
0
    "The content type must be the simple base type", NULL);
16491
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16492
0
  }
16493
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16494
      /*
16495
      * SPEC (2.2) "The {final} of the {base type definition} must not
16496
      * contain extension"
16497
      * NOTE that this is the same as (1.1).
16498
      */
16499
0
      xmlSchemaPCustomErr(ctxt,
16500
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16501
0
    WXS_BASIC_CAST type, NULL,
16502
0
    "The 'final' of the base type definition "
16503
0
    "contains 'extension'", NULL);
16504
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16505
0
  }
16506
0
    }
16507
0
    return (0);
16508
0
}
16509
16510
/**
16511
 * xmlSchemaCheckDerivationOKRestriction:
16512
 * @ctxt:  the schema parser context
16513
 * @type:  the complex type definition
16514
 *
16515
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16516
 * Schema Component Constraint:
16517
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16518
 *
16519
 * STATUS:
16520
 *   missing:
16521
 *     (5.4.2) ???
16522
 *
16523
 * ATTENTION:
16524
 * In XML Schema 1.1 this will be:
16525
 * Validation Rule: Checking complex type subsumption
16526
 *
16527
 * Returns 0 if the constraints are satisfied, a positive
16528
 * error code if not and -1 if an internal error occurred.
16529
 */
16530
static int
16531
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16532
              xmlSchemaTypePtr type)
16533
0
{
16534
0
    xmlSchemaTypePtr base;
16535
16536
    /*
16537
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16538
    * temporarily only.
16539
    */
16540
0
    base = type->baseType;
16541
0
    if (! WXS_IS_COMPLEX(base)) {
16542
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16543
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16544
0
      type->node, WXS_BASIC_CAST type,
16545
0
      "The base type must be a complex type", NULL, NULL);
16546
0
  return(ctxt->err);
16547
0
    }
16548
0
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16549
  /*
16550
  * SPEC (1) "The {base type definition} must be a complex type
16551
  * definition whose {final} does not contain restriction."
16552
  */
16553
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16554
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16555
0
      type->node, WXS_BASIC_CAST type,
16556
0
      "The 'final' of the base type definition "
16557
0
      "contains 'restriction'", NULL, NULL);
16558
0
  return (ctxt->err);
16559
0
    }
16560
    /*
16561
    * SPEC (2), (3) and (4)
16562
    * Those are handled in a separate function, since the
16563
    * same constraints are needed for redefinition of
16564
    * attribute groups as well.
16565
    */
16566
0
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16567
0
  XML_SCHEMA_ACTION_DERIVE,
16568
0
  WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16569
0
  type->attrUses, base->attrUses,
16570
0
  type->attributeWildcard,
16571
0
  base->attributeWildcard) == -1)
16572
0
    {
16573
0
  return(-1);
16574
0
    }
16575
    /*
16576
    * SPEC (5) "One of the following must be true:"
16577
    */
16578
0
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16579
  /*
16580
  * SPEC (5.1) "The {base type definition} must be the
16581
  * `ur-type definition`."
16582
  * PASS
16583
  */
16584
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16585
0
      (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16586
  /*
16587
  * SPEC (5.2.1) "The {content type} of the complex type definition
16588
  * must be a simple type definition"
16589
  *
16590
  * SPEC (5.2.2) "One of the following must be true:"
16591
  */
16592
0
  if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16593
0
      (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16594
0
  {
16595
0
      int err;
16596
      /*
16597
      * SPEC (5.2.2.1) "The {content type} of the {base type
16598
      * definition} must be a simple type definition from which
16599
      * the {content type} is validly derived given the empty
16600
      * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16601
      *
16602
      * ATTENTION TODO: This seems not needed if the type implicitly
16603
      * derived from the base type.
16604
      *
16605
      */
16606
0
      err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16607
0
    type->contentTypeDef, base->contentTypeDef, 0);
16608
0
      if (err != 0) {
16609
0
    xmlChar *strA = NULL, *strB = NULL;
16610
16611
0
    if (err == -1)
16612
0
        return(-1);
16613
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16614
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16615
0
        NULL, WXS_BASIC_CAST type,
16616
0
        "The {content type} %s is not validly derived from the "
16617
0
        "base type's {content type} %s",
16618
0
        xmlSchemaGetComponentDesignation(&strA,
16619
0
      type->contentTypeDef),
16620
0
        xmlSchemaGetComponentDesignation(&strB,
16621
0
      base->contentTypeDef));
16622
0
    FREE_AND_NULL(strA);
16623
0
    FREE_AND_NULL(strB);
16624
0
    return(ctxt->err);
16625
0
      }
16626
0
  } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16627
0
      (xmlSchemaIsParticleEmptiable(
16628
0
    (xmlSchemaParticlePtr) base->subtypes))) {
16629
      /*
16630
      * SPEC (5.2.2.2) "The {base type definition} must be mixed
16631
      * and have a particle which is `emptiable` as defined in
16632
      * Particle Emptiable ($3.9.6)."
16633
      * PASS
16634
      */
16635
0
  } else {
16636
0
      xmlSchemaPCustomErr(ctxt,
16637
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16638
0
    WXS_BASIC_CAST type, NULL,
16639
0
    "The content type of the base type must be either "
16640
0
    "a simple type or 'mixed' and an emptiable particle", NULL);
16641
0
      return (ctxt->err);
16642
0
  }
16643
0
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16644
  /*
16645
  * SPEC (5.3.1) "The {content type} of the complex type itself must
16646
  * be empty"
16647
  */
16648
0
  if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16649
      /*
16650
      * SPEC (5.3.2.1) "The {content type} of the {base type
16651
      * definition} must also be empty."
16652
      * PASS
16653
      */
16654
0
  } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16655
0
      (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16656
0
      xmlSchemaIsParticleEmptiable(
16657
0
    (xmlSchemaParticlePtr) base->subtypes)) {
16658
      /*
16659
      * SPEC (5.3.2.2) "The {content type} of the {base type
16660
      * definition} must be elementOnly or mixed and have a particle
16661
      * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16662
      * PASS
16663
      */
16664
0
  } else {
16665
0
      xmlSchemaPCustomErr(ctxt,
16666
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16667
0
    WXS_BASIC_CAST type, NULL,
16668
0
    "The content type of the base type must be either "
16669
0
    "empty or 'mixed' (or 'elements-only') and an emptiable "
16670
0
    "particle", NULL);
16671
0
      return (ctxt->err);
16672
0
  }
16673
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16674
0
  WXS_HAS_MIXED_CONTENT(type)) {
16675
  /*
16676
  * SPEC (5.4.1.1) "The {content type} of the complex type definition
16677
  * itself must be element-only"
16678
  */
16679
0
  if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16680
      /*
16681
      * SPEC (5.4.1.2) "The {content type} of the complex type
16682
      * definition itself and of the {base type definition} must be
16683
      * mixed"
16684
      */
16685
0
      xmlSchemaPCustomErr(ctxt,
16686
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16687
0
    WXS_BASIC_CAST type, NULL,
16688
0
    "If the content type is 'mixed', then the content type of the "
16689
0
    "base type must also be 'mixed'", NULL);
16690
0
      return (ctxt->err);
16691
0
  }
16692
  /*
16693
  * SPEC (5.4.2) "The particle of the complex type definition itself
16694
  * must be a `valid restriction` of the particle of the {content
16695
  * type} of the {base type definition} as defined in Particle Valid
16696
  * (Restriction) ($3.9.6).
16697
  *
16698
  * URGENT TODO: (5.4.2)
16699
  */
16700
0
    } else {
16701
0
  xmlSchemaPCustomErr(ctxt,
16702
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16703
0
      WXS_BASIC_CAST type, NULL,
16704
0
      "The type is not a valid restriction of its base type", NULL);
16705
0
  return (ctxt->err);
16706
0
    }
16707
0
    return (0);
16708
0
}
16709
16710
/**
16711
 * xmlSchemaCheckCTComponent:
16712
 * @ctxt:  the schema parser context
16713
 * @type:  the complex type definition
16714
 *
16715
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16716
 *
16717
 * Returns 0 if the constraints are satisfied, a positive
16718
 * error code if not and -1 if an internal error occurred.
16719
 */
16720
static int
16721
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16722
        xmlSchemaTypePtr type)
16723
0
{
16724
0
    int ret;
16725
    /*
16726
    * Complex Type Definition Properties Correct
16727
    */
16728
0
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16729
0
    if (ret != 0)
16730
0
  return (ret);
16731
0
    if (WXS_IS_EXTENSION(type))
16732
0
  ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16733
0
    else
16734
0
  ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16735
0
    return (ret);
16736
0
}
16737
16738
/**
16739
 * xmlSchemaCheckSRCCT:
16740
 * @ctxt:  the schema parser context
16741
 * @type:  the complex type definition
16742
 *
16743
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16744
 * Schema Representation Constraint:
16745
 * Complex Type Definition Representation OK (src-ct)
16746
 *
16747
 * Returns 0 if the constraints are satisfied, a positive
16748
 * error code if not and -1 if an internal error occurred.
16749
 */
16750
static int
16751
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16752
        xmlSchemaTypePtr type)
16753
0
{
16754
0
    xmlSchemaTypePtr base;
16755
0
    int ret = 0;
16756
16757
    /*
16758
    * TODO: Adjust the error codes here, as I used
16759
    * XML_SCHEMAP_SRC_CT_1 only yet.
16760
    */
16761
0
    base = type->baseType;
16762
0
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16763
  /*
16764
  * 1 If the <complexContent> alternative is chosen, the type definition
16765
  * `resolved` to by the `actual value` of the base [attribute]
16766
  * must be a complex type definition;
16767
  */
16768
0
  if (! WXS_IS_COMPLEX(base)) {
16769
0
      xmlChar *str = NULL;
16770
0
      xmlSchemaPCustomErr(ctxt,
16771
0
    XML_SCHEMAP_SRC_CT_1,
16772
0
    WXS_BASIC_CAST type, type->node,
16773
0
    "If using <complexContent>, the base type is expected to be "
16774
0
    "a complex type. The base type '%s' is a simple type",
16775
0
    xmlSchemaFormatQName(&str, base->targetNamespace,
16776
0
    base->name));
16777
0
      FREE_AND_NULL(str)
16778
0
      return (XML_SCHEMAP_SRC_CT_1);
16779
0
  }
16780
0
    } else {
16781
  /*
16782
  * SPEC
16783
  * 2 If the <simpleContent> alternative is chosen, all of the
16784
  * following must be true:
16785
  * 2.1 The type definition `resolved` to by the `actual value` of the
16786
  * base [attribute] must be one of the following:
16787
  */
16788
0
  if (WXS_IS_SIMPLE(base)) {
16789
0
      if (WXS_IS_EXTENSION(type) == 0) {
16790
0
    xmlChar *str = NULL;
16791
    /*
16792
    * 2.1.3 only if the <extension> alternative is also
16793
    * chosen, a simple type definition.
16794
    */
16795
    /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16796
0
    xmlSchemaPCustomErr(ctxt,
16797
0
        XML_SCHEMAP_SRC_CT_1,
16798
0
        WXS_BASIC_CAST type, NULL,
16799
0
        "If using <simpleContent> and <restriction>, the base "
16800
0
        "type must be a complex type. The base type '%s' is "
16801
0
        "a simple type",
16802
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16803
0
      base->name));
16804
0
    FREE_AND_NULL(str)
16805
0
    return (XML_SCHEMAP_SRC_CT_1);
16806
0
      }
16807
0
  } else {
16808
      /* Base type is a complex type. */
16809
0
      if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16810
0
    (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16811
    /*
16812
    * 2.1.1 a complex type definition whose {content type} is a
16813
    * simple type definition;
16814
    * PASS
16815
    */
16816
0
    if (base->contentTypeDef == NULL) {
16817
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16818
0
      WXS_BASIC_CAST type, NULL,
16819
0
      "Internal error: xmlSchemaCheckSRCCT, "
16820
0
      "'%s', base type has no content type",
16821
0
      type->name);
16822
0
        return (-1);
16823
0
    }
16824
0
      } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16825
0
    (WXS_IS_RESTRICTION(type))) {
16826
16827
    /*
16828
    * 2.1.2 only if the <restriction> alternative is also
16829
    * chosen, a complex type definition whose {content type}
16830
    * is mixed and a particle emptiable.
16831
    */
16832
0
    if (! xmlSchemaIsParticleEmptiable(
16833
0
        (xmlSchemaParticlePtr) base->subtypes)) {
16834
0
        ret = XML_SCHEMAP_SRC_CT_1;
16835
0
    } else
16836
        /*
16837
        * Attention: at this point the <simpleType> child is in
16838
        * ->contentTypeDef (put there during parsing).
16839
        */
16840
0
        if (type->contentTypeDef == NULL) {
16841
0
        xmlChar *str = NULL;
16842
        /*
16843
        * 2.2 If clause 2.1.2 above is satisfied, then there
16844
        * must be a <simpleType> among the [children] of
16845
        * <restriction>.
16846
        */
16847
        /* TODO: Change error code to ..._SRC_CT_2_2. */
16848
0
        xmlSchemaPCustomErr(ctxt,
16849
0
      XML_SCHEMAP_SRC_CT_1,
16850
0
      WXS_BASIC_CAST type, NULL,
16851
0
      "A <simpleType> is expected among the children "
16852
0
      "of <restriction>, if <simpleContent> is used and "
16853
0
      "the base type '%s' is a complex type",
16854
0
      xmlSchemaFormatQName(&str, base->targetNamespace,
16855
0
      base->name));
16856
0
        FREE_AND_NULL(str)
16857
0
        return (XML_SCHEMAP_SRC_CT_1);
16858
0
    }
16859
0
      } else {
16860
0
    ret = XML_SCHEMAP_SRC_CT_1;
16861
0
      }
16862
0
  }
16863
0
  if (ret > 0) {
16864
0
      xmlChar *str = NULL;
16865
0
      if (WXS_IS_RESTRICTION(type)) {
16866
0
    xmlSchemaPCustomErr(ctxt,
16867
0
        XML_SCHEMAP_SRC_CT_1,
16868
0
        WXS_BASIC_CAST type, NULL,
16869
0
        "If <simpleContent> and <restriction> is used, the "
16870
0
        "base type must be a simple type or a complex type with "
16871
0
        "mixed content and particle emptiable. The base type "
16872
0
        "'%s' is none of those",
16873
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16874
0
        base->name));
16875
0
      } else {
16876
0
    xmlSchemaPCustomErr(ctxt,
16877
0
        XML_SCHEMAP_SRC_CT_1,
16878
0
        WXS_BASIC_CAST type, NULL,
16879
0
        "If <simpleContent> and <extension> is used, the "
16880
0
        "base type must be a simple type. The base type '%s' "
16881
0
        "is a complex type",
16882
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16883
0
        base->name));
16884
0
      }
16885
0
      FREE_AND_NULL(str)
16886
0
  }
16887
0
    }
16888
    /*
16889
    * SPEC (3) "The corresponding complex type definition component must
16890
    * satisfy the conditions set out in Constraints on Complex Type
16891
    * Definition Schema Components ($3.4.6);"
16892
    * NOTE (3) will be done in xmlSchemaTypeFixup().
16893
    */
16894
    /*
16895
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16896
    * above for {attribute wildcard} is satisfied, the intensional
16897
    * intersection must be expressible, as defined in Attribute Wildcard
16898
    * Intersection ($3.10.6).
16899
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16900
    */
16901
0
    return (ret);
16902
0
}
16903
16904
#ifdef ENABLE_PARTICLE_RESTRICTION
16905
/**
16906
 * xmlSchemaCheckParticleRangeOK:
16907
 * @ctxt:  the schema parser context
16908
 * @type:  the complex type definition
16909
 *
16910
 * (3.9.6) Constraints on Particle Schema Components
16911
 * Schema Component Constraint:
16912
 * Occurrence Range OK (range-ok)
16913
 *
16914
 * STATUS: complete
16915
 *
16916
 * Returns 0 if the constraints are satisfied, a positive
16917
 * error code if not and -1 if an internal error occurred.
16918
 */
16919
static int
16920
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16921
            int bmin, int bmax)
16922
{
16923
    if (rmin < bmin)
16924
  return (1);
16925
    if ((bmax != UNBOUNDED) &&
16926
  (rmax > bmax))
16927
  return (1);
16928
    return (0);
16929
}
16930
16931
/**
16932
 * xmlSchemaCheckRCaseNameAndTypeOK:
16933
 * @ctxt:  the schema parser context
16934
 * @r: the restricting element declaration particle
16935
 * @b: the base element declaration particle
16936
 *
16937
 * (3.9.6) Constraints on Particle Schema Components
16938
 * Schema Component Constraint:
16939
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16940
 * (rcase-NameAndTypeOK)
16941
 *
16942
 * STATUS:
16943
 *   MISSING (3.2.3)
16944
 *   CLARIFY: (3.2.2)
16945
 *
16946
 * Returns 0 if the constraints are satisfied, a positive
16947
 * error code if not and -1 if an internal error occurred.
16948
 */
16949
static int
16950
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16951
         xmlSchemaParticlePtr r,
16952
         xmlSchemaParticlePtr b)
16953
{
16954
    xmlSchemaElementPtr elemR, elemB;
16955
16956
    /* TODO: Error codes (rcase-NameAndTypeOK). */
16957
    elemR = (xmlSchemaElementPtr) r->children;
16958
    elemB = (xmlSchemaElementPtr) b->children;
16959
    /*
16960
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
16961
    * the same."
16962
    */
16963
    if ((elemR != elemB) &&
16964
  ((! xmlStrEqual(elemR->name, elemB->name)) ||
16965
  (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16966
  return (1);
16967
    /*
16968
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16969
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16970
    */
16971
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16972
      b->minOccurs, b->maxOccurs) != 0)
16973
  return (1);
16974
    /*
16975
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16976
    * {scope} are global."
16977
    */
16978
    if (elemR == elemB)
16979
  return (0);
16980
    /*
16981
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16982
    */
16983
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16984
  (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16985
   return (1);
16986
    /*
16987
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16988
    * or is not fixed, or R's declaration's {value constraint} is fixed
16989
    * with the same value."
16990
    */
16991
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16992
  ((elemR->value == NULL) ||
16993
   ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16994
   /* TODO: Equality of the initial value or normalized or canonical? */
16995
   (! xmlStrEqual(elemR->value, elemB->value))))
16996
   return (1);
16997
    /*
16998
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16999
    * definitions} is a subset of B's declaration's {identity-constraint
17000
    * definitions}, if any."
17001
    */
17002
    if (elemB->idcs != NULL) {
17003
  /* TODO */
17004
    }
17005
    /*
17006
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
17007
    * superset of B's declaration's {disallowed substitutions}."
17008
    */
17009
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
17010
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
17011
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
17012
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
17013
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
17014
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
17015
   return (1);
17016
    /*
17017
    * SPEC (3.2.5) "R's {type definition} is validly derived given
17018
    * {extension, list, union} from B's {type definition}"
17019
    *
17020
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
17021
    * set, if the corresponding constraints handle "restriction" and
17022
    * "extension" only?
17023
    *
17024
    */
17025
    {
17026
  int set = 0;
17027
17028
  set |= SUBSET_EXTENSION;
17029
  set |= SUBSET_LIST;
17030
  set |= SUBSET_UNION;
17031
  if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
17032
      elemB->subtypes, set) != 0)
17033
      return (1);
17034
    }
17035
    return (0);
17036
}
17037
17038
/**
17039
 * xmlSchemaCheckRCaseNSCompat:
17040
 * @ctxt:  the schema parser context
17041
 * @r: the restricting element declaration particle
17042
 * @b: the base wildcard particle
17043
 *
17044
 * (3.9.6) Constraints on Particle Schema Components
17045
 * Schema Component Constraint:
17046
 * Particle Derivation OK (Elt:Any -- NSCompat)
17047
 * (rcase-NSCompat)
17048
 *
17049
 * STATUS: complete
17050
 *
17051
 * Returns 0 if the constraints are satisfied, a positive
17052
 * error code if not and -1 if an internal error occurred.
17053
 */
17054
static int
17055
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
17056
          xmlSchemaParticlePtr r,
17057
          xmlSchemaParticlePtr b)
17058
{
17059
    /* TODO:Error codes (rcase-NSCompat). */
17060
    /*
17061
    * SPEC "For an element declaration particle to be a `valid restriction`
17062
    * of a wildcard particle all of the following must be true:"
17063
    *
17064
    * SPEC (1) "The element declaration's {target namespace} is `valid`
17065
    * with respect to the wildcard's {namespace constraint} as defined by
17066
    * Wildcard allows Namespace Name ($3.10.4)."
17067
    */
17068
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
17069
  ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
17070
  return (1);
17071
    /*
17072
    * SPEC (2) "R's occurrence range is a valid restriction of B's
17073
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17074
    */
17075
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17076
      b->minOccurs, b->maxOccurs) != 0)
17077
  return (1);
17078
17079
    return (0);
17080
}
17081
17082
/**
17083
 * xmlSchemaCheckRCaseRecurseAsIfGroup:
17084
 * @ctxt:  the schema parser context
17085
 * @r: the restricting element declaration particle
17086
 * @b: the base model group particle
17087
 *
17088
 * (3.9.6) Constraints on Particle Schema Components
17089
 * Schema Component Constraint:
17090
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
17091
 * (rcase-RecurseAsIfGroup)
17092
 *
17093
 * STATUS: TODO
17094
 *
17095
 * Returns 0 if the constraints are satisfied, a positive
17096
 * error code if not and -1 if an internal error occurred.
17097
 */
17098
static int
17099
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
17100
            xmlSchemaParticlePtr r,
17101
            xmlSchemaParticlePtr b)
17102
{
17103
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
17104
    TODO
17105
    return (0);
17106
}
17107
17108
/**
17109
 * xmlSchemaCheckRCaseNSSubset:
17110
 * @ctxt:  the schema parser context
17111
 * @r: the restricting wildcard particle
17112
 * @b: the base wildcard particle
17113
 *
17114
 * (3.9.6) Constraints on Particle Schema Components
17115
 * Schema Component Constraint:
17116
 * Particle Derivation OK (Any:Any -- NSSubset)
17117
 * (rcase-NSSubset)
17118
 *
17119
 * STATUS: complete
17120
 *
17121
 * Returns 0 if the constraints are satisfied, a positive
17122
 * error code if not and -1 if an internal error occurred.
17123
 */
17124
static int
17125
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
17126
            xmlSchemaParticlePtr r,
17127
            xmlSchemaParticlePtr b,
17128
            int isAnyTypeBase)
17129
{
17130
    /* TODO: Error codes (rcase-NSSubset). */
17131
    /*
17132
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17133
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17134
    */
17135
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17136
      b->minOccurs, b->maxOccurs))
17137
  return (1);
17138
    /*
17139
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
17140
    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17141
    */
17142
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
17143
  (xmlSchemaWildcardPtr) b->children))
17144
  return (1);
17145
    /*
17146
    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17147
    * definition`, R's {process contents} must be identical to or stronger
17148
    * than B's {process contents}, where strict is stronger than lax is
17149
    * stronger than skip."
17150
    */
17151
    if (! isAnyTypeBase) {
17152
  if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17153
      ((xmlSchemaWildcardPtr) b->children)->processContents)
17154
      return (1);
17155
    }
17156
17157
    return (0);
17158
}
17159
17160
/**
17161
 * xmlSchemaCheckCOSParticleRestrict:
17162
 * @ctxt:  the schema parser context
17163
 * @type:  the complex type definition
17164
 *
17165
 * (3.9.6) Constraints on Particle Schema Components
17166
 * Schema Component Constraint:
17167
 * Particle Valid (Restriction) (cos-particle-restrict)
17168
 *
17169
 * STATUS: TODO
17170
 *
17171
 * Returns 0 if the constraints are satisfied, a positive
17172
 * error code if not and -1 if an internal error occurred.
17173
 */
17174
static int
17175
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17176
          xmlSchemaParticlePtr r,
17177
          xmlSchemaParticlePtr b)
17178
{
17179
    int ret = 0;
17180
17181
    /*part = WXS_TYPE_PARTICLE(type);
17182
    basePart = WXS_TYPE_PARTICLE(base);
17183
    */
17184
17185
    TODO
17186
17187
    /*
17188
    * SPEC (1) "They are the same particle."
17189
    */
17190
    if (r == b)
17191
  return (0);
17192
17193
17194
    return (0);
17195
}
17196
17197
#if 0
17198
/**
17199
 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17200
 * @ctxt:  the schema parser context
17201
 * @r: the model group particle
17202
 * @b: the base wildcard particle
17203
 *
17204
 * (3.9.6) Constraints on Particle Schema Components
17205
 * Schema Component Constraint:
17206
 * Particle Derivation OK (All/Choice/Sequence:Any --
17207
 *                         NSRecurseCheckCardinality)
17208
 * (rcase-NSRecurseCheckCardinality)
17209
 *
17210
 * STATUS: TODO: subst-groups
17211
 *
17212
 * Returns 0 if the constraints are satisfied, a positive
17213
 * error code if not and -1 if an internal error occurred.
17214
 */
17215
static int
17216
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17217
               xmlSchemaParticlePtr r,
17218
               xmlSchemaParticlePtr b)
17219
{
17220
    xmlSchemaParticlePtr part;
17221
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17222
    if ((r->children == NULL) || (r->children->children == NULL))
17223
  return (-1);
17224
    /*
17225
    * SPEC "For a group particle to be a `valid restriction` of a
17226
    * wildcard particle..."
17227
    *
17228
    * SPEC (1) "Every member of the {particles} of the group is a `valid
17229
    * restriction` of the wildcard as defined by
17230
    * Particle Valid (Restriction) ($3.9.6)."
17231
    */
17232
    part = (xmlSchemaParticlePtr) r->children->children;
17233
    do {
17234
  if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17235
      return (1);
17236
  part = (xmlSchemaParticlePtr) part->next;
17237
    } while (part != NULL);
17238
    /*
17239
    * SPEC (2) "The effective total range of the group [...] is a
17240
    * valid restriction of B's occurrence range as defined by
17241
    * Occurrence Range OK ($3.9.6)."
17242
    */
17243
    if (xmlSchemaCheckParticleRangeOK(
17244
      xmlSchemaGetParticleTotalRangeMin(r),
17245
      xmlSchemaGetParticleTotalRangeMax(r),
17246
      b->minOccurs, b->maxOccurs) != 0)
17247
  return (1);
17248
    return (0);
17249
}
17250
#endif
17251
17252
/**
17253
 * xmlSchemaCheckRCaseRecurse:
17254
 * @ctxt:  the schema parser context
17255
 * @r: the <all> or <sequence> model group particle
17256
 * @b: the base <all> or <sequence> model group particle
17257
 *
17258
 * (3.9.6) Constraints on Particle Schema Components
17259
 * Schema Component Constraint:
17260
 * Particle Derivation OK (All:All,Sequence:Sequence --
17261
                           Recurse)
17262
 * (rcase-Recurse)
17263
 *
17264
 * STATUS:  ?
17265
 * TODO: subst-groups
17266
 *
17267
 * Returns 0 if the constraints are satisfied, a positive
17268
 * error code if not and -1 if an internal error occurred.
17269
 */
17270
static int
17271
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17272
         xmlSchemaParticlePtr r,
17273
         xmlSchemaParticlePtr b)
17274
{
17275
    /* xmlSchemaParticlePtr part; */
17276
    /* TODO: Error codes (rcase-Recurse). */
17277
    if ((r->children == NULL) || (b->children == NULL) ||
17278
  (r->children->type != b->children->type))
17279
  return (-1);
17280
    /*
17281
    * SPEC "For an all or sequence group particle to be a `valid
17282
    * restriction` of another group particle with the same {compositor}..."
17283
    *
17284
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17285
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17286
    */
17287
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17288
      b->minOccurs, b->maxOccurs))
17289
  return (1);
17290
17291
17292
    return (0);
17293
}
17294
17295
#endif
17296
17297
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17298
0
    xmlSchemaPCustomErrExt(pctxt,      \
17299
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17300
0
  WXS_BASIC_CAST fac1, fac1->node, \
17301
0
  "It is an error for both '%s' and '%s' to be specified on the "\
17302
0
  "same type definition", \
17303
0
  BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17304
0
  BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17305
17306
#define FACET_RESTR_ERR(fac1, msg) \
17307
0
    xmlSchemaPCustomErr(pctxt,      \
17308
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17309
0
  WXS_BASIC_CAST fac1, fac1->node, \
17310
0
  msg, NULL);
17311
17312
#define FACET_RESTR_FIXED_ERR(fac) \
17313
0
    xmlSchemaPCustomErr(pctxt, \
17314
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17315
0
  WXS_BASIC_CAST fac, fac->node, \
17316
0
  "The base type's facet is 'fixed', thus the value must not " \
17317
0
  "differ", NULL);
17318
17319
static void
17320
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17321
      xmlSchemaFacetPtr facet1,
17322
      xmlSchemaFacetPtr facet2,
17323
      int lessGreater,
17324
      int orEqual,
17325
      int ofBase)
17326
0
{
17327
0
    xmlChar *msg = NULL;
17328
17329
0
    msg = xmlStrdup(BAD_CAST "'");
17330
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17331
0
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
17332
0
    if (lessGreater == 0)
17333
0
  msg = xmlStrcat(msg, BAD_CAST " equal to");
17334
0
    if (lessGreater == 1)
17335
0
  msg = xmlStrcat(msg, BAD_CAST " greater than");
17336
0
    else
17337
0
  msg = xmlStrcat(msg, BAD_CAST " less than");
17338
17339
0
    if (orEqual)
17340
0
  msg = xmlStrcat(msg, BAD_CAST " or equal to");
17341
0
    msg = xmlStrcat(msg, BAD_CAST " '");
17342
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17343
0
    if (ofBase)
17344
0
  msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17345
0
    else
17346
0
  msg = xmlStrcat(msg, BAD_CAST "'");
17347
17348
0
    xmlSchemaPCustomErr(pctxt,
17349
0
  XML_SCHEMAP_INVALID_FACET_VALUE,
17350
0
  WXS_BASIC_CAST facet1, NULL,
17351
0
  (const char *) msg, NULL);
17352
17353
0
    if (msg != NULL)
17354
0
  xmlFree(msg);
17355
0
}
17356
17357
/*
17358
* xmlSchemaDeriveAndValidateFacets:
17359
*
17360
* Schema Component Constraint: Simple Type Restriction (Facets)
17361
* (st-restrict-facets)
17362
*/
17363
static int
17364
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17365
         xmlSchemaTypePtr type)
17366
0
{
17367
0
    xmlSchemaTypePtr base = type->baseType;
17368
0
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
17369
0
    xmlSchemaFacetPtr facet, bfacet,
17370
0
  flength = NULL, ftotdig = NULL, ffracdig = NULL,
17371
0
  fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17372
0
  fmininc = NULL, fmaxinc = NULL,
17373
0
  fminexc = NULL, fmaxexc = NULL,
17374
0
  bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17375
0
  bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17376
0
  bfmininc = NULL, bfmaxinc = NULL,
17377
0
  bfminexc = NULL, bfmaxexc = NULL;
17378
0
    int res; /* err = 0, fixedErr; */
17379
17380
    /*
17381
    * SPEC st-restrict-facets 1:
17382
    * "The {variety} of R is the same as that of B."
17383
    */
17384
    /*
17385
    * SPEC st-restrict-facets 2:
17386
    * "If {variety} is atomic, the {primitive type definition}
17387
    * of R is the same as that of B."
17388
    *
17389
    * NOTE: we leave 1 & 2 out for now, since this will be
17390
    * satisfied by the derivation process.
17391
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
17392
    */
17393
    /*
17394
    * SPEC st-restrict-facets 3:
17395
    * "The {facets} of R are the union of S and the {facets}
17396
    * of B, eliminating duplicates. To eliminate duplicates,
17397
    * when a facet of the same kind occurs in both S and the
17398
    * {facets} of B, the one in the {facets} of B is not
17399
    * included, with the exception of enumeration and pattern
17400
    * facets, for which multiple occurrences with distinct values
17401
    * are allowed."
17402
    */
17403
17404
0
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
17405
0
  return (0);
17406
17407
0
    last = type->facetSet;
17408
0
    if (last != NULL)
17409
0
  while (last->next != NULL)
17410
0
      last = last->next;
17411
17412
0
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17413
0
  facet = cur->facet;
17414
0
  switch (facet->type) {
17415
0
      case XML_SCHEMA_FACET_LENGTH:
17416
0
    flength = facet; break;
17417
0
      case XML_SCHEMA_FACET_MINLENGTH:
17418
0
    fminlen = facet; break;
17419
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17420
0
    fmininc = facet; break;
17421
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17422
0
    fminexc = facet; break;
17423
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17424
0
    fmaxlen = facet; break;
17425
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17426
0
    fmaxinc = facet; break;
17427
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17428
0
    fmaxexc = facet; break;
17429
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17430
0
    ftotdig = facet; break;
17431
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17432
0
    ffracdig = facet; break;
17433
0
      default:
17434
0
    break;
17435
0
  }
17436
0
    }
17437
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17438
0
  facet = cur->facet;
17439
0
  switch (facet->type) {
17440
0
      case XML_SCHEMA_FACET_LENGTH:
17441
0
    bflength = facet; break;
17442
0
      case XML_SCHEMA_FACET_MINLENGTH:
17443
0
    bfminlen = facet; break;
17444
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17445
0
    bfmininc = facet; break;
17446
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17447
0
    bfminexc = facet; break;
17448
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17449
0
    bfmaxlen = facet; break;
17450
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17451
0
    bfmaxinc = facet; break;
17452
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17453
0
    bfmaxexc = facet; break;
17454
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17455
0
    bftotdig = facet; break;
17456
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17457
0
    bffracdig = facet; break;
17458
0
      default:
17459
0
    break;
17460
0
  }
17461
0
    }
17462
    /*
17463
    * length and minLength or maxLength (2.2) + (3.2)
17464
    */
17465
0
    if (flength && (fminlen || fmaxlen)) {
17466
0
  FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17467
0
      "either of 'minLength' or 'maxLength' to be specified on "
17468
0
      "the same type definition")
17469
0
    }
17470
    /*
17471
    * Mutual exclusions in the same derivation step.
17472
    */
17473
0
    if ((fmaxinc) && (fmaxexc)) {
17474
  /*
17475
  * SCC "maxInclusive and maxExclusive"
17476
  */
17477
0
  FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17478
0
    }
17479
0
    if ((fmininc) && (fminexc)) {
17480
  /*
17481
  * SCC "minInclusive and minExclusive"
17482
  */
17483
0
  FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17484
0
    }
17485
17486
0
    if (flength && bflength) {
17487
  /*
17488
  * SCC "length valid restriction"
17489
  * The values have to be equal.
17490
  */
17491
0
  res = xmlSchemaCompareValues(flength->val, bflength->val);
17492
0
  if (res == -2)
17493
0
      goto internal_error;
17494
0
  if (res != 0)
17495
0
      xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17496
0
  if ((res != 0) && (bflength->fixed)) {
17497
0
      FACET_RESTR_FIXED_ERR(flength)
17498
0
  }
17499
17500
0
    }
17501
0
    if (fminlen && bfminlen) {
17502
  /*
17503
  * SCC "minLength valid restriction"
17504
  * minLength >= BASE minLength
17505
  */
17506
0
  res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17507
0
  if (res == -2)
17508
0
      goto internal_error;
17509
0
  if (res == -1)
17510
0
      xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17511
0
  if ((res != 0) && (bfminlen->fixed)) {
17512
0
      FACET_RESTR_FIXED_ERR(fminlen)
17513
0
  }
17514
0
    }
17515
0
    if (fmaxlen && bfmaxlen) {
17516
  /*
17517
  * SCC "maxLength valid restriction"
17518
  * maxLength <= BASE minLength
17519
  */
17520
0
  res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17521
0
  if (res == -2)
17522
0
      goto internal_error;
17523
0
  if (res == 1)
17524
0
      xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17525
0
  if ((res != 0) && (bfmaxlen->fixed)) {
17526
0
      FACET_RESTR_FIXED_ERR(fmaxlen)
17527
0
  }
17528
0
    }
17529
    /*
17530
    * SCC "length and minLength or maxLength"
17531
    */
17532
0
    if (! flength)
17533
0
  flength = bflength;
17534
0
    if (flength) {
17535
0
  if (! fminlen)
17536
0
      fminlen = bfminlen;
17537
0
  if (fminlen) {
17538
      /* (1.1) length >= minLength */
17539
0
      res = xmlSchemaCompareValues(flength->val, fminlen->val);
17540
0
      if (res == -2)
17541
0
    goto internal_error;
17542
0
      if (res == -1)
17543
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17544
0
  }
17545
0
  if (! fmaxlen)
17546
0
      fmaxlen = bfmaxlen;
17547
0
  if (fmaxlen) {
17548
      /* (2.1) length <= maxLength */
17549
0
      res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17550
0
      if (res == -2)
17551
0
    goto internal_error;
17552
0
      if (res == 1)
17553
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17554
0
  }
17555
0
    }
17556
0
    if (fmaxinc) {
17557
  /*
17558
  * "maxInclusive"
17559
  */
17560
0
  if (fmininc) {
17561
      /* SCC "maxInclusive >= minInclusive" */
17562
0
      res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17563
0
      if (res == -2)
17564
0
    goto internal_error;
17565
0
      if (res == -1) {
17566
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17567
0
      }
17568
0
  }
17569
  /*
17570
  * SCC "maxInclusive valid restriction"
17571
  */
17572
0
  if (bfmaxinc) {
17573
      /* maxInclusive <= BASE maxInclusive */
17574
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17575
0
      if (res == -2)
17576
0
    goto internal_error;
17577
0
      if (res == 1)
17578
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17579
0
      if ((res != 0) && (bfmaxinc->fixed)) {
17580
0
    FACET_RESTR_FIXED_ERR(fmaxinc)
17581
0
      }
17582
0
  }
17583
0
  if (bfmaxexc) {
17584
      /* maxInclusive < BASE maxExclusive */
17585
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17586
0
      if (res == -2)
17587
0
    goto internal_error;
17588
0
      if (res != -1) {
17589
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17590
0
      }
17591
0
  }
17592
0
  if (bfmininc) {
17593
      /* maxInclusive >= BASE minInclusive */
17594
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17595
0
      if (res == -2)
17596
0
    goto internal_error;
17597
0
      if (res == -1) {
17598
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17599
0
      }
17600
0
  }
17601
0
  if (bfminexc) {
17602
      /* maxInclusive > BASE minExclusive */
17603
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17604
0
      if (res == -2)
17605
0
    goto internal_error;
17606
0
      if (res != 1) {
17607
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17608
0
      }
17609
0
  }
17610
0
    }
17611
0
    if (fmaxexc) {
17612
  /*
17613
  * "maxExclusive >= minExclusive"
17614
  */
17615
0
  if (fminexc) {
17616
0
      res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17617
0
      if (res == -2)
17618
0
    goto internal_error;
17619
0
      if (res == -1) {
17620
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17621
0
      }
17622
0
  }
17623
  /*
17624
  * "maxExclusive valid restriction"
17625
  */
17626
0
  if (bfmaxexc) {
17627
      /* maxExclusive <= BASE maxExclusive */
17628
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17629
0
      if (res == -2)
17630
0
    goto internal_error;
17631
0
      if (res == 1) {
17632
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17633
0
      }
17634
0
      if ((res != 0) && (bfmaxexc->fixed)) {
17635
0
    FACET_RESTR_FIXED_ERR(fmaxexc)
17636
0
      }
17637
0
  }
17638
0
  if (bfmaxinc) {
17639
      /* maxExclusive <= BASE maxInclusive */
17640
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17641
0
      if (res == -2)
17642
0
    goto internal_error;
17643
0
      if (res == 1) {
17644
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17645
0
      }
17646
0
  }
17647
0
  if (bfmininc) {
17648
      /* maxExclusive > BASE minInclusive */
17649
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17650
0
      if (res == -2)
17651
0
    goto internal_error;
17652
0
      if (res != 1) {
17653
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17654
0
      }
17655
0
  }
17656
0
  if (bfminexc) {
17657
      /* maxExclusive > BASE minExclusive */
17658
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17659
0
      if (res == -2)
17660
0
    goto internal_error;
17661
0
      if (res != 1) {
17662
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17663
0
      }
17664
0
  }
17665
0
    }
17666
0
    if (fminexc) {
17667
  /*
17668
  * "minExclusive < maxInclusive"
17669
  */
17670
0
  if (fmaxinc) {
17671
0
      res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17672
0
      if (res == -2)
17673
0
    goto internal_error;
17674
0
      if (res != -1) {
17675
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17676
0
      }
17677
0
  }
17678
  /*
17679
  * "minExclusive valid restriction"
17680
  */
17681
0
  if (bfminexc) {
17682
      /* minExclusive >= BASE minExclusive */
17683
0
      res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17684
0
      if (res == -2)
17685
0
    goto internal_error;
17686
0
      if (res == -1) {
17687
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17688
0
      }
17689
0
      if ((res != 0) && (bfminexc->fixed)) {
17690
0
    FACET_RESTR_FIXED_ERR(fminexc)
17691
0
      }
17692
0
  }
17693
0
  if (bfmaxinc) {
17694
      /* minExclusive <= BASE maxInclusive */
17695
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17696
0
      if (res == -2)
17697
0
    goto internal_error;
17698
0
      if (res == 1) {
17699
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17700
0
      }
17701
0
  }
17702
0
  if (bfmininc) {
17703
      /* minExclusive >= BASE minInclusive */
17704
0
      res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17705
0
      if (res == -2)
17706
0
    goto internal_error;
17707
0
      if (res == -1) {
17708
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17709
0
      }
17710
0
  }
17711
0
  if (bfmaxexc) {
17712
      /* minExclusive < BASE maxExclusive */
17713
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17714
0
      if (res == -2)
17715
0
    goto internal_error;
17716
0
      if (res != -1) {
17717
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17718
0
      }
17719
0
  }
17720
0
    }
17721
0
    if (fmininc) {
17722
  /*
17723
  * "minInclusive < maxExclusive"
17724
  */
17725
0
  if (fmaxexc) {
17726
0
      res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17727
0
      if (res == -2)
17728
0
    goto internal_error;
17729
0
      if (res != -1) {
17730
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17731
0
      }
17732
0
  }
17733
  /*
17734
  * "minExclusive valid restriction"
17735
  */
17736
0
  if (bfmininc) {
17737
      /* minInclusive >= BASE minInclusive */
17738
0
      res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17739
0
      if (res == -2)
17740
0
    goto internal_error;
17741
0
      if (res == -1) {
17742
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17743
0
      }
17744
0
      if ((res != 0) && (bfmininc->fixed)) {
17745
0
    FACET_RESTR_FIXED_ERR(fmininc)
17746
0
      }
17747
0
  }
17748
0
  if (bfmaxinc) {
17749
      /* minInclusive <= BASE maxInclusive */
17750
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17751
0
      if (res == -2)
17752
0
    goto internal_error;
17753
0
      if (res == 1) {
17754
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17755
0
      }
17756
0
  }
17757
0
  if (bfminexc) {
17758
      /* minInclusive > BASE minExclusive */
17759
0
      res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17760
0
      if (res == -2)
17761
0
    goto internal_error;
17762
0
      if (res != 1)
17763
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17764
0
  }
17765
0
  if (bfmaxexc) {
17766
      /* minInclusive < BASE maxExclusive */
17767
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17768
0
      if (res == -2)
17769
0
    goto internal_error;
17770
0
      if (res != -1)
17771
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17772
0
  }
17773
0
    }
17774
0
    if (ftotdig && bftotdig) {
17775
  /*
17776
  * SCC " totalDigits valid restriction"
17777
  * totalDigits <= BASE totalDigits
17778
  */
17779
0
  res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17780
0
  if (res == -2)
17781
0
      goto internal_error;
17782
0
  if (res == 1)
17783
0
      xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17784
0
      -1, 1, 1);
17785
0
  if ((res != 0) && (bftotdig->fixed)) {
17786
0
      FACET_RESTR_FIXED_ERR(ftotdig)
17787
0
  }
17788
0
    }
17789
0
    if (ffracdig && bffracdig) {
17790
  /*
17791
  * SCC  "fractionDigits valid restriction"
17792
  * fractionDigits <= BASE fractionDigits
17793
  */
17794
0
  res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17795
0
  if (res == -2)
17796
0
      goto internal_error;
17797
0
  if (res == 1)
17798
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17799
0
      -1, 1, 1);
17800
0
  if ((res != 0) && (bffracdig->fixed)) {
17801
0
      FACET_RESTR_FIXED_ERR(ffracdig)
17802
0
  }
17803
0
    }
17804
    /*
17805
    * SCC "fractionDigits less than or equal to totalDigits"
17806
    */
17807
0
    if (! ftotdig)
17808
0
  ftotdig = bftotdig;
17809
0
    if (! ffracdig)
17810
0
  ffracdig = bffracdig;
17811
0
    if (ftotdig && ffracdig) {
17812
0
  res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17813
0
  if (res == -2)
17814
0
      goto internal_error;
17815
0
  if (res == 1)
17816
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17817
0
    -1, 1, 0);
17818
0
    }
17819
    /*
17820
    * *Enumerations* won' be added here, since only the first set
17821
    * of enumerations in the ancestor-or-self axis is used
17822
    * for validation, plus we need to use the base type of those
17823
    * enumerations for whitespace.
17824
    *
17825
    * *Patterns*: won't be add here, since they are ORed at
17826
    * type level and ANDed at ancestor level. This will
17827
    * happen during validation by walking the base axis
17828
    * of the type.
17829
    */
17830
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17831
0
  bfacet = cur->facet;
17832
  /*
17833
  * Special handling of enumerations and patterns.
17834
  * TODO: hmm, they should not appear in the set, so remove this.
17835
  */
17836
0
  if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17837
0
      (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17838
0
      continue;
17839
  /*
17840
  * Search for a duplicate facet in the current type.
17841
  */
17842
0
  link = type->facetSet;
17843
  /* err = 0; */
17844
  /* fixedErr = 0; */
17845
0
  while (link != NULL) {
17846
0
      facet = link->facet;
17847
0
      if (facet->type == bfacet->type) {
17848
0
    switch (facet->type) {
17849
0
        case XML_SCHEMA_FACET_WHITESPACE:
17850
      /*
17851
      * The whitespace must be stronger.
17852
      */
17853
0
      if (facet->whitespace < bfacet->whitespace) {
17854
0
          FACET_RESTR_ERR(facet,
17855
0
        "The 'whitespace' value has to be equal to "
17856
0
        "or stronger than the 'whitespace' value of "
17857
0
        "the base type")
17858
0
      }
17859
0
      if ((bfacet->fixed) &&
17860
0
          (facet->whitespace != bfacet->whitespace)) {
17861
0
          FACET_RESTR_FIXED_ERR(facet)
17862
0
      }
17863
0
      break;
17864
0
        default:
17865
0
      break;
17866
0
    }
17867
    /* Duplicate found. */
17868
0
    break;
17869
0
      }
17870
0
      link = link->next;
17871
0
  }
17872
  /*
17873
  * If no duplicate was found: add the base types's facet
17874
  * to the set.
17875
  */
17876
0
  if (link == NULL) {
17877
0
      link = (xmlSchemaFacetLinkPtr)
17878
0
    xmlMalloc(sizeof(xmlSchemaFacetLink));
17879
0
      if (link == NULL) {
17880
0
    xmlSchemaPErrMemory(pctxt,
17881
0
        "deriving facets, creating a facet link", NULL);
17882
0
    return (-1);
17883
0
      }
17884
0
      link->facet = cur->facet;
17885
0
      link->next = NULL;
17886
0
      if (last == NULL)
17887
0
    type->facetSet = link;
17888
0
      else
17889
0
    last->next = link;
17890
0
      last = link;
17891
0
  }
17892
17893
0
    }
17894
17895
0
    return (0);
17896
0
internal_error:
17897
0
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17898
0
  "an error occurred");
17899
0
    return (-1);
17900
0
}
17901
17902
static int
17903
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17904
               xmlSchemaTypePtr type)
17905
0
{
17906
0
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17907
    /*
17908
    * The actual value is then formed by replacing any union type
17909
    * definition in the `explicit members` with the members of their
17910
    * {member type definitions}, in order.
17911
    *
17912
    * TODO: There's a bug entry at
17913
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17914
    * which indicates that we'll keep the union types the future.
17915
    */
17916
0
    link = type->memberTypes;
17917
0
    while (link != NULL) {
17918
17919
0
  if (WXS_IS_TYPE_NOT_FIXED(link->type))
17920
0
      xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17921
17922
0
  if (WXS_IS_UNION(link->type)) {
17923
0
      subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17924
0
      if (subLink != NULL) {
17925
0
    link->type = subLink->type;
17926
0
    if (subLink->next != NULL) {
17927
0
        lastLink = link->next;
17928
0
        subLink = subLink->next;
17929
0
        prevLink = link;
17930
0
        while (subLink != NULL) {
17931
0
      newLink = (xmlSchemaTypeLinkPtr)
17932
0
          xmlMalloc(sizeof(xmlSchemaTypeLink));
17933
0
      if (newLink == NULL) {
17934
0
          xmlSchemaPErrMemory(pctxt, "allocating a type link",
17935
0
        NULL);
17936
0
          return (-1);
17937
0
      }
17938
0
      newLink->type = subLink->type;
17939
0
      prevLink->next = newLink;
17940
0
      prevLink = newLink;
17941
0
      newLink->next = lastLink;
17942
17943
0
      subLink = subLink->next;
17944
0
        }
17945
0
    }
17946
0
      }
17947
0
  }
17948
0
  link = link->next;
17949
0
    }
17950
0
    return (0);
17951
0
}
17952
17953
static void
17954
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17955
0
{
17956
0
    int has = 0, needVal = 0, normVal = 0;
17957
17958
0
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17959
0
    if (has) {
17960
0
  needVal = (type->baseType->flags &
17961
0
      XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17962
0
  normVal = (type->baseType->flags &
17963
0
      XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17964
0
    }
17965
0
    if (type->facets != NULL) {
17966
0
  xmlSchemaFacetPtr fac;
17967
17968
0
  for (fac = type->facets; fac != NULL; fac = fac->next) {
17969
0
      switch (fac->type) {
17970
0
    case XML_SCHEMA_FACET_WHITESPACE:
17971
0
        break;
17972
0
    case XML_SCHEMA_FACET_PATTERN:
17973
0
        normVal = 1;
17974
0
        has = 1;
17975
0
        break;
17976
0
    case XML_SCHEMA_FACET_ENUMERATION:
17977
0
        needVal = 1;
17978
0
        normVal = 1;
17979
0
        has = 1;
17980
0
        break;
17981
0
    default:
17982
0
        has = 1;
17983
0
        break;
17984
0
      }
17985
0
  }
17986
0
    }
17987
0
    if (normVal)
17988
0
  type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17989
0
    if (needVal)
17990
0
  type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17991
0
    if (has)
17992
0
  type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17993
17994
0
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17995
0
  xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17996
  /*
17997
  * OPTIMIZE VAL TODO: Some facets need a computed value.
17998
  */
17999
0
  if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
18000
0
      (prim->builtInType != XML_SCHEMAS_STRING)) {
18001
0
      type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
18002
0
  }
18003
0
    }
18004
0
}
18005
18006
static int
18007
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
18008
0
{
18009
18010
18011
    /*
18012
    * Evaluate the whitespace-facet value.
18013
    */
18014
0
    if (WXS_IS_LIST(type)) {
18015
0
  type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18016
0
  return (0);
18017
0
    } else if (WXS_IS_UNION(type))
18018
0
  return (0);
18019
18020
0
    if (type->facetSet != NULL) {
18021
0
  xmlSchemaFacetLinkPtr lin;
18022
18023
0
  for (lin = type->facetSet; lin != NULL; lin = lin->next) {
18024
0
      if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
18025
0
    switch (lin->facet->whitespace) {
18026
0
    case XML_SCHEMAS_FACET_PRESERVE:
18027
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
18028
0
        break;
18029
0
    case XML_SCHEMAS_FACET_REPLACE:
18030
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
18031
0
        break;
18032
0
    case XML_SCHEMAS_FACET_COLLAPSE:
18033
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18034
0
        break;
18035
0
    default:
18036
0
        return (-1);
18037
0
    }
18038
0
    return (0);
18039
0
      }
18040
0
  }
18041
0
    }
18042
    /*
18043
    * For all `atomic` datatypes other than string (and types `derived`
18044
    * by `restriction` from it) the value of whiteSpace is fixed to
18045
    * collapse
18046
    */
18047
0
    {
18048
0
  xmlSchemaTypePtr anc;
18049
18050
0
  for (anc = type->baseType; anc != NULL &&
18051
0
    anc->builtInType != XML_SCHEMAS_ANYTYPE;
18052
0
    anc = anc->baseType) {
18053
18054
0
      if (anc->type == XML_SCHEMA_TYPE_BASIC) {
18055
0
    if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
18056
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
18057
18058
0
    } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
18059
0
        (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
18060
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
18061
18062
0
    } else
18063
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18064
0
    break;
18065
0
      }
18066
0
  }
18067
0
    }
18068
0
    return (0);
18069
0
}
18070
18071
static int
18072
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
18073
        xmlSchemaTypePtr type)
18074
0
{
18075
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18076
0
  return(0);
18077
0
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
18078
0
  return(0);
18079
0
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
18080
18081
0
    if (WXS_IS_LIST(type)) {
18082
  /*
18083
  * Corresponds to <simpleType><list>...
18084
  */
18085
0
  if (type->subtypes == NULL) {
18086
      /*
18087
      * This one is really needed, so get out.
18088
      */
18089
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18090
0
    "list type has no item-type assigned");
18091
0
      return(-1);
18092
0
  }
18093
0
    } else if (WXS_IS_UNION(type)) {
18094
  /*
18095
  * Corresponds to <simpleType><union>...
18096
  */
18097
0
  if (type->memberTypes == NULL) {
18098
      /*
18099
      * This one is really needed, so get out.
18100
      */
18101
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18102
0
    "union type has no member-types assigned");
18103
0
      return(-1);
18104
0
  }
18105
0
    } else {
18106
  /*
18107
  * Corresponds to <simpleType><restriction>...
18108
  */
18109
0
  if (type->baseType == NULL) {
18110
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18111
0
    "type has no base-type assigned");
18112
0
      return(-1);
18113
0
  }
18114
0
  if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
18115
0
      if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
18116
0
    return(-1);
18117
  /*
18118
  * Variety
18119
  * If the <restriction> alternative is chosen, then the
18120
  * {variety} of the {base type definition}.
18121
  */
18122
0
  if (WXS_IS_ATOMIC(type->baseType))
18123
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
18124
0
  else if (WXS_IS_LIST(type->baseType)) {
18125
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
18126
      /*
18127
      * Inherit the itemType.
18128
      */
18129
0
      type->subtypes = type->baseType->subtypes;
18130
0
  } else if (WXS_IS_UNION(type->baseType)) {
18131
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
18132
      /*
18133
      * NOTE that we won't assign the memberTypes of the base,
18134
      * since this will make trouble when freeing them; we will
18135
      * use a lookup function to access them instead.
18136
      */
18137
0
  }
18138
0
    }
18139
0
    return(0);
18140
0
}
18141
18142
#ifdef DEBUG_TYPE
18143
static void
18144
xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
18145
           xmlSchemaTypePtr type)
18146
{
18147
    if (type->node != NULL) {
18148
        xmlGenericError(xmlGenericErrorContext,
18149
                        "Type of %s : %s:%d :", name,
18150
                        type->node->doc->URL,
18151
                        xmlGetLineNo(type->node));
18152
    } else {
18153
        xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
18154
    }
18155
    if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
18156
  switch (type->contentType) {
18157
      case XML_SCHEMA_CONTENT_SIMPLE:
18158
    xmlGenericError(xmlGenericErrorContext, "simple\n");
18159
    break;
18160
      case XML_SCHEMA_CONTENT_ELEMENTS:
18161
    xmlGenericError(xmlGenericErrorContext, "elements\n");
18162
    break;
18163
      case XML_SCHEMA_CONTENT_UNKNOWN:
18164
    xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
18165
    break;
18166
      case XML_SCHEMA_CONTENT_EMPTY:
18167
    xmlGenericError(xmlGenericErrorContext, "empty\n");
18168
    break;
18169
      case XML_SCHEMA_CONTENT_MIXED:
18170
    if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
18171
        type->subtypes))
18172
        xmlGenericError(xmlGenericErrorContext,
18173
      "mixed as emptiable particle\n");
18174
    else
18175
        xmlGenericError(xmlGenericErrorContext, "mixed\n");
18176
    break;
18177
    /* Removed, since not used. */
18178
    /*
18179
    case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18180
    xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18181
    break;
18182
    */
18183
      case XML_SCHEMA_CONTENT_BASIC:
18184
    xmlGenericError(xmlGenericErrorContext, "basic\n");
18185
    break;
18186
      default:
18187
    xmlGenericError(xmlGenericErrorContext,
18188
        "not registered !!!\n");
18189
    break;
18190
  }
18191
    }
18192
}
18193
#endif
18194
18195
/*
18196
* 3.14.6 Constraints on Simple Type Definition Schema Components
18197
*/
18198
static int
18199
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18200
         xmlSchemaTypePtr type)
18201
0
{
18202
0
    int res, olderrs = pctxt->nberrors;
18203
18204
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18205
0
  return(-1);
18206
18207
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18208
0
  return(0);
18209
18210
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18211
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18212
18213
0
    if (type->baseType == NULL) {
18214
0
  PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18215
0
      "missing baseType");
18216
0
  goto exit_failure;
18217
0
    }
18218
0
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18219
0
  xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18220
    /*
18221
    * If a member type of a union is a union itself, we need to substitute
18222
    * that member type for its member types.
18223
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18224
    * types in WXS 1.1.
18225
    */
18226
0
    if ((type->memberTypes != NULL) &&
18227
0
  (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18228
0
  return(-1);
18229
    /*
18230
    * SPEC src-simple-type 1
18231
    * "The corresponding simple type definition, if any, must satisfy
18232
    * the conditions set out in Constraints on Simple Type Definition
18233
    * Schema Components ($3.14.6)."
18234
    */
18235
    /*
18236
    * Schema Component Constraint: Simple Type Definition Properties Correct
18237
    * (st-props-correct)
18238
    */
18239
0
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18240
0
    HFAILURE HERROR
18241
    /*
18242
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18243
    * (cos-st-restricts)
18244
    */
18245
0
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18246
0
    HFAILURE HERROR
18247
    /*
18248
    * TODO: Removed the error report, since it got annoying to get an
18249
    * extra error report, if anything failed until now.
18250
    * Enable this if needed.
18251
    *
18252
    * xmlSchemaPErr(ctxt, type->node,
18253
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18254
    *    "Simple type '%s' does not satisfy the constraints "
18255
    *    "on simple type definitions.\n",
18256
    *    type->name, NULL);
18257
    */
18258
    /*
18259
    * Schema Component Constraint: Simple Type Restriction (Facets)
18260
    * (st-restrict-facets)
18261
    */
18262
0
    res = xmlSchemaCheckFacetValues(type, pctxt);
18263
0
    HFAILURE HERROR
18264
0
    if ((type->facetSet != NULL) ||
18265
0
  (type->baseType->facetSet != NULL)) {
18266
0
  res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18267
0
  HFAILURE HERROR
18268
0
    }
18269
    /*
18270
    * Whitespace value.
18271
    */
18272
0
    res = xmlSchemaTypeFixupWhitespace(type);
18273
0
    HFAILURE HERROR
18274
0
    xmlSchemaTypeFixupOptimFacets(type);
18275
18276
0
exit_error:
18277
#ifdef DEBUG_TYPE
18278
    xmlSchemaDebugFixedType(pctxt, type);
18279
#endif
18280
0
    if (olderrs != pctxt->nberrors)
18281
0
  return(pctxt->err);
18282
0
    return(0);
18283
18284
0
exit_failure:
18285
#ifdef DEBUG_TYPE
18286
    xmlSchemaDebugFixedType(pctxt, type);
18287
#endif
18288
0
    return(-1);
18289
0
}
18290
18291
static int
18292
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18293
        xmlSchemaTypePtr type)
18294
0
{
18295
0
    int res = 0, olderrs = pctxt->nberrors;
18296
0
    xmlSchemaTypePtr baseType = type->baseType;
18297
18298
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18299
0
  return(0);
18300
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18301
0
    if (baseType == NULL) {
18302
0
  PERROR_INT("xmlSchemaFixupComplexType",
18303
0
      "missing baseType");
18304
0
  goto exit_failure;
18305
0
    }
18306
    /*
18307
    * Fixup the base type.
18308
    */
18309
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
18310
0
  xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18311
0
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18312
  /*
18313
  * Skip fixup if the base type is invalid.
18314
  * TODO: Generate a warning!
18315
  */
18316
0
  return(0);
18317
0
    }
18318
    /*
18319
    * This basically checks if the base type can be derived.
18320
    */
18321
0
    res = xmlSchemaCheckSRCCT(pctxt, type);
18322
0
    HFAILURE HERROR
18323
    /*
18324
    * Fixup the content type.
18325
    */
18326
0
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18327
  /*
18328
  * Corresponds to <complexType><simpleContent>...
18329
  */
18330
0
  if ((WXS_IS_COMPLEX(baseType)) &&
18331
0
      (baseType->contentTypeDef != NULL) &&
18332
0
      (WXS_IS_RESTRICTION(type))) {
18333
0
      xmlSchemaTypePtr contentBase, content;
18334
#ifdef ENABLE_NAMED_LOCALS
18335
      char buf[30];
18336
      const xmlChar *tmpname;
18337
#endif
18338
      /*
18339
      * SPEC (1) If <restriction> + base type is <complexType>,
18340
      * "whose own {content type} is a simple type..."
18341
      */
18342
0
      if (type->contentTypeDef != NULL) {
18343
    /*
18344
    * SPEC (1.1) "the simple type definition corresponding to the
18345
    * <simpleType> among the [children] of <restriction> if there
18346
    * is one;"
18347
    * Note that this "<simpleType> among the [children]" was put
18348
    * into ->contentTypeDef during parsing.
18349
    */
18350
0
    contentBase = type->contentTypeDef;
18351
0
    type->contentTypeDef = NULL;
18352
0
      } else {
18353
    /*
18354
    * (1.2) "...otherwise (<restriction> has no <simpleType>
18355
    * among its [children]), the simple type definition which
18356
    * is the {content type} of the ... base type."
18357
    */
18358
0
    contentBase = baseType->contentTypeDef;
18359
0
      }
18360
      /*
18361
      * SPEC
18362
      * "... a simple type definition which restricts the simple
18363
      * type definition identified in clause 1.1 or clause 1.2
18364
      * with a set of facet components"
18365
      *
18366
      * Create the anonymous simple type, which will be the content
18367
      * type of the complex type.
18368
      */
18369
#ifdef ENABLE_NAMED_LOCALS
18370
      snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18371
      tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18372
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18373
    XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18374
    type->node, 0);
18375
#else
18376
0
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18377
0
    XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18378
0
    type->node, 0);
18379
0
#endif
18380
0
      if (content == NULL)
18381
0
    goto exit_failure;
18382
      /*
18383
      * We will use the same node as for the <complexType>
18384
      * to have it somehow anchored in the schema doc.
18385
      */
18386
0
      content->type = XML_SCHEMA_TYPE_SIMPLE;
18387
0
      content->baseType = contentBase;
18388
      /*
18389
      * Move the facets, previously anchored on the
18390
      * complexType during parsing.
18391
      */
18392
0
      content->facets = type->facets;
18393
0
      type->facets = NULL;
18394
0
      content->facetSet = type->facetSet;
18395
0
      type->facetSet = NULL;
18396
18397
0
      type->contentTypeDef = content;
18398
0
      if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18399
0
    xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18400
      /*
18401
      * Fixup the newly created type. We don't need to check
18402
      * for circularity here.
18403
      */
18404
0
      res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18405
0
      HFAILURE HERROR
18406
0
      res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18407
0
      HFAILURE HERROR
18408
18409
0
  } else if ((WXS_IS_COMPLEX(baseType)) &&
18410
0
      (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18411
0
      (WXS_IS_RESTRICTION(type))) {
18412
      /*
18413
      * SPEC (2) If <restriction> + base is a mixed <complexType> with
18414
      * an emptiable particle, then a simple type definition which
18415
      * restricts the <restriction>'s <simpleType> child.
18416
      */
18417
0
      if ((type->contentTypeDef == NULL) ||
18418
0
    (type->contentTypeDef->baseType == NULL)) {
18419
    /*
18420
    * TODO: Check if this ever happens.
18421
    */
18422
0
    xmlSchemaPCustomErr(pctxt,
18423
0
        XML_SCHEMAP_INTERNAL,
18424
0
        WXS_BASIC_CAST type, NULL,
18425
0
        "Internal error: xmlSchemaTypeFixup, "
18426
0
        "complex type '%s': the <simpleContent><restriction> "
18427
0
        "is missing a <simpleType> child, but was not caught "
18428
0
        "by xmlSchemaCheckSRCCT()", type->name);
18429
0
    goto exit_failure;
18430
0
      }
18431
0
  } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18432
      /*
18433
      * SPEC (3) If <extension> + base is <complexType> with
18434
      * <simpleType> content, "...then the {content type} of that
18435
      * complex type definition"
18436
      */
18437
0
      if (baseType->contentTypeDef == NULL) {
18438
    /*
18439
    * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18440
    * should have caught this already.
18441
    */
18442
0
    xmlSchemaPCustomErr(pctxt,
18443
0
        XML_SCHEMAP_INTERNAL,
18444
0
        WXS_BASIC_CAST type, NULL,
18445
0
        "Internal error: xmlSchemaTypeFixup, "
18446
0
        "complex type '%s': the <extension>ed base type is "
18447
0
        "a complex type with no simple content type",
18448
0
        type->name);
18449
0
    goto exit_failure;
18450
0
      }
18451
0
      type->contentTypeDef = baseType->contentTypeDef;
18452
0
  } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18453
      /*
18454
      * SPEC (4) <extension> + base is <simpleType>
18455
      * "... then that simple type definition"
18456
      */
18457
0
      type->contentTypeDef = baseType;
18458
0
  } else {
18459
      /*
18460
      * TODO: Check if this ever happens.
18461
      */
18462
0
      xmlSchemaPCustomErr(pctxt,
18463
0
    XML_SCHEMAP_INTERNAL,
18464
0
    WXS_BASIC_CAST type, NULL,
18465
0
    "Internal error: xmlSchemaTypeFixup, "
18466
0
    "complex type '%s' with <simpleContent>: unhandled "
18467
0
    "derivation case", type->name);
18468
0
      goto exit_failure;
18469
0
  }
18470
0
    } else {
18471
0
  int dummySequence = 0;
18472
0
  xmlSchemaParticlePtr particle =
18473
0
      (xmlSchemaParticlePtr) type->subtypes;
18474
  /*
18475
  * Corresponds to <complexType><complexContent>...
18476
  *
18477
  * NOTE that the effective mixed was already set during parsing of
18478
  * <complexType> and <complexContent>; its flag value is
18479
  * XML_SCHEMAS_TYPE_MIXED.
18480
  *
18481
  * Compute the "effective content":
18482
  * (2.1.1) + (2.1.2) + (2.1.3)
18483
  */
18484
0
  if ((particle == NULL) ||
18485
0
      ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18486
0
      ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18487
0
      (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18488
0
      ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18489
0
      (particle->minOccurs == 0))) &&
18490
0
      ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18491
0
      if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18492
    /*
18493
    * SPEC (2.1.4) "If the `effective mixed` is true, then
18494
    * a particle whose properties are as follows:..."
18495
    *
18496
    * Empty sequence model group with
18497
    * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18498
    * NOTE that we sill assign it the <complexType> node to
18499
    * somehow anchor it in the doc.
18500
    */
18501
0
    if ((particle == NULL) ||
18502
0
        (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18503
        /*
18504
        * Create the particle.
18505
        */
18506
0
        particle = xmlSchemaAddParticle(pctxt,
18507
0
      type->node, 1, 1);
18508
0
        if (particle == NULL)
18509
0
      goto exit_failure;
18510
        /*
18511
        * Create the model group.
18512
        */ /* URGENT TODO: avoid adding to pending items. */
18513
0
        particle->children = (xmlSchemaTreeItemPtr)
18514
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18515
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18516
0
        if (particle->children == NULL)
18517
0
      goto exit_failure;
18518
18519
0
        type->subtypes = (xmlSchemaTypePtr) particle;
18520
0
    }
18521
0
    dummySequence = 1;
18522
0
    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18523
0
      } else {
18524
    /*
18525
    * SPEC (2.1.5) "otherwise empty"
18526
    */
18527
0
    type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18528
0
      }
18529
0
  } else {
18530
      /*
18531
      * SPEC (2.2) "otherwise the particle corresponding to the
18532
      * <all>, <choice>, <group> or <sequence> among the
18533
      * [children]."
18534
      */
18535
0
      type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18536
0
  }
18537
  /*
18538
  * Compute the "content type".
18539
  */
18540
0
  if (WXS_IS_RESTRICTION(type)) {
18541
      /*
18542
      * SPEC (3.1) "If <restriction>..."
18543
      * (3.1.1) + (3.1.2) */
18544
0
      if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18545
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18546
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18547
0
      }
18548
0
  } else {
18549
      /*
18550
      * SPEC (3.2) "If <extension>..."
18551
      */
18552
0
      if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18553
    /*
18554
    * SPEC (3.2.1)
18555
    * "If the `effective content` is empty, then the
18556
    *  {content type} of the [...] base ..."
18557
    */
18558
0
    type->contentType = baseType->contentType;
18559
0
    type->subtypes = baseType->subtypes;
18560
    /*
18561
    * Fixes bug #347316:
18562
    * This is the case when the base type has a simple
18563
    * type definition as content.
18564
    */
18565
0
    type->contentTypeDef = baseType->contentTypeDef;
18566
    /*
18567
    * NOTE that the effective mixed is ignored here.
18568
    */
18569
0
      } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18570
    /*
18571
    * SPEC (3.2.2)
18572
    */
18573
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18574
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18575
0
      } else {
18576
    /*
18577
    * SPEC (3.2.3)
18578
    */
18579
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18580
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18581
        /*
18582
        * "A model group whose {compositor} is sequence and whose
18583
        * {particles} are..."
18584
        */
18585
0
    if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18586
0
        (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18587
0
        ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18588
0
      XML_SCHEMA_TYPE_ALL))
18589
0
    {
18590
        /*
18591
        * SPEC cos-all-limited (1)
18592
        */
18593
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18594
      /* TODO: error code */
18595
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18596
0
      WXS_ITEM_NODE(type), NULL,
18597
0
      "The type has an 'all' model group in its "
18598
0
      "{content type} and thus cannot be derived from "
18599
0
      "a non-empty type, since this would produce a "
18600
0
      "'sequence' model group containing the 'all' "
18601
0
      "model group; 'all' model groups are not "
18602
0
      "allowed to appear inside other model groups",
18603
0
      NULL, NULL);
18604
18605
0
    } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18606
0
        (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18607
0
        ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18608
0
      XML_SCHEMA_TYPE_ALL))
18609
0
    {
18610
        /*
18611
        * SPEC cos-all-limited (1)
18612
        */
18613
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18614
      /* TODO: error code */
18615
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18616
0
      WXS_ITEM_NODE(type), NULL,
18617
0
      "A type cannot be derived by extension from a type "
18618
0
      "which has an 'all' model group in its "
18619
0
      "{content type}, since this would produce a "
18620
0
      "'sequence' model group containing the 'all' "
18621
0
      "model group; 'all' model groups are not "
18622
0
      "allowed to appear inside other model groups",
18623
0
      NULL, NULL);
18624
18625
0
    } else if (! dummySequence) {
18626
0
        xmlSchemaTreeItemPtr effectiveContent =
18627
0
      (xmlSchemaTreeItemPtr) type->subtypes;
18628
        /*
18629
        * Create the particle.
18630
        */
18631
0
        particle = xmlSchemaAddParticle(pctxt,
18632
0
      type->node, 1, 1);
18633
0
        if (particle == NULL)
18634
0
      goto exit_failure;
18635
        /*
18636
        * Create the "sequence" model group.
18637
        */
18638
0
        particle->children = (xmlSchemaTreeItemPtr)
18639
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18640
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18641
0
        if (particle->children == NULL)
18642
0
      goto exit_failure;
18643
0
        WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18644
        /*
18645
        * SPEC "the particle of the {content type} of
18646
        * the ... base ..."
18647
        * Create a duplicate of the base type's particle
18648
        * and assign its "term" to it.
18649
        */
18650
0
        particle->children->children =
18651
0
      (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18652
0
      type->node,
18653
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18654
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18655
0
        if (particle->children->children == NULL)
18656
0
      goto exit_failure;
18657
0
        particle = (xmlSchemaParticlePtr)
18658
0
      particle->children->children;
18659
0
        particle->children =
18660
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18661
        /*
18662
        * SPEC "followed by the `effective content`."
18663
        */
18664
0
        particle->next = effectiveContent;
18665
        /*
18666
        * This all will result in:
18667
        * new-particle
18668
        *   --> new-sequence(
18669
        *         new-particle
18670
        *           --> base-model,
18671
        *         this-particle
18672
        *         --> this-model
18673
        *     )
18674
        */
18675
0
    } else {
18676
        /*
18677
        * This is the case when there is already an empty
18678
        * <sequence> with minOccurs==maxOccurs==1.
18679
        * Just add the base types's content type.
18680
        * NOTE that, although we miss to add an intermediate
18681
        * <sequence>, this should produce no difference to
18682
        * neither the regex compilation of the content model,
18683
        * nor to the complex type constraints.
18684
        */
18685
0
        particle->children->children =
18686
0
      (xmlSchemaTreeItemPtr) baseType->subtypes;
18687
0
    }
18688
0
      }
18689
0
  }
18690
0
    }
18691
    /*
18692
    * Now fixup attribute uses:
18693
    *   - expand attr. group references
18694
    *     - intersect attribute wildcards
18695
    *   - inherit attribute uses of the base type
18696
    *   - inherit or union attr. wildcards if extending
18697
    *   - apply attr. use prohibitions if restricting
18698
    */
18699
0
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18700
0
    HFAILURE HERROR
18701
    /*
18702
    * Apply the complex type component constraints; this will not
18703
    * check attributes, since this is done in
18704
    * xmlSchemaFixupTypeAttributeUses().
18705
    */
18706
0
    res = xmlSchemaCheckCTComponent(pctxt, type);
18707
0
    HFAILURE HERROR
18708
18709
#ifdef DEBUG_TYPE
18710
    xmlSchemaDebugFixedType(pctxt, type);
18711
#endif
18712
0
    if (olderrs != pctxt->nberrors)
18713
0
  return(pctxt->err);
18714
0
    else
18715
0
  return(0);
18716
18717
0
exit_error:
18718
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18719
#ifdef DEBUG_TYPE
18720
    xmlSchemaDebugFixedType(pctxt, type);
18721
#endif
18722
0
    return(pctxt->err);
18723
18724
0
exit_failure:
18725
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18726
#ifdef DEBUG_TYPE
18727
    xmlSchemaDebugFixedType(pctxt, type);
18728
#endif
18729
0
    return(-1);
18730
0
}
18731
18732
18733
/**
18734
 * xmlSchemaTypeFixup:
18735
 * @typeDecl:  the schema type definition
18736
 * @ctxt:  the schema parser context
18737
 *
18738
 * Fixes the content model of the type.
18739
 * URGENT TODO: We need an int result!
18740
 */
18741
static int
18742
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18743
                   xmlSchemaAbstractCtxtPtr actxt)
18744
0
{
18745
0
    if (type == NULL)
18746
0
        return(0);
18747
0
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18748
0
  AERROR_INT("xmlSchemaTypeFixup",
18749
0
      "this function needs a parser context");
18750
0
  return(-1);
18751
0
    }
18752
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18753
0
  return(0);
18754
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18755
0
  return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18756
0
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18757
0
  return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18758
0
    return(0);
18759
0
}
18760
18761
/**
18762
 * xmlSchemaCheckFacet:
18763
 * @facet:  the facet
18764
 * @typeDecl:  the schema type definition
18765
 * @pctxt:  the schema parser context or NULL
18766
 * @name: the optional name of the type
18767
 *
18768
 * Checks and computes the values of facets.
18769
 *
18770
 * Returns 0 if valid, a positive error code if not valid and
18771
 *         -1 in case of an internal or API error.
18772
 */
18773
int
18774
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18775
                    xmlSchemaTypePtr typeDecl,
18776
                    xmlSchemaParserCtxtPtr pctxt,
18777
        const xmlChar * name ATTRIBUTE_UNUSED)
18778
0
{
18779
0
    int ret = 0, ctxtGiven;
18780
18781
0
    if ((facet == NULL) || (typeDecl == NULL))
18782
0
        return(-1);
18783
    /*
18784
    * TODO: will the parser context be given if used from
18785
    * the relaxNG module?
18786
    */
18787
0
    if (pctxt == NULL)
18788
0
  ctxtGiven = 0;
18789
0
    else
18790
0
  ctxtGiven = 1;
18791
18792
0
    switch (facet->type) {
18793
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
18794
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
18795
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
18796
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18797
0
  case XML_SCHEMA_FACET_ENUMERATION: {
18798
                /*
18799
                 * Okay we need to validate the value
18800
                 * at that point.
18801
                 */
18802
0
    xmlSchemaTypePtr base;
18803
18804
    /* 4.3.5.5 Constraints on enumeration Schema Components
18805
    * Schema Component Constraint: enumeration valid restriction
18806
    * It is an `error` if any member of {value} is not in the
18807
    * `value space` of {base type definition}.
18808
    *
18809
    * minInclusive, maxInclusive, minExclusive, maxExclusive:
18810
    * The value `must` be in the
18811
    * `value space` of the `base type`.
18812
    */
18813
    /*
18814
    * This function is intended to deliver a compiled value
18815
    * on the facet. In this implementation of XML Schemata the
18816
    * type holding a facet, won't be a built-in type.
18817
    * Thus to ensure that other API
18818
    * calls (relaxng) do work, if the given type is a built-in
18819
    * type, we will assume that the given built-in type *is
18820
    * already* the base type.
18821
    */
18822
0
    if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18823
0
        base = typeDecl->baseType;
18824
0
        if (base == NULL) {
18825
0
      PERROR_INT("xmlSchemaCheckFacet",
18826
0
          "a type user derived type has no base type");
18827
0
      return (-1);
18828
0
        }
18829
0
    } else
18830
0
        base = typeDecl;
18831
18832
0
    if (! ctxtGiven) {
18833
        /*
18834
        * A context is needed if called from RelaxNG.
18835
        */
18836
0
        pctxt = xmlSchemaNewParserCtxt("*");
18837
0
        if (pctxt == NULL)
18838
0
      return (-1);
18839
0
    }
18840
    /*
18841
    * NOTE: This call does not check the content nodes,
18842
    * since they are not available:
18843
    * facet->node is just the node holding the facet
18844
    * definition, *not* the attribute holding the *value*
18845
    * of the facet.
18846
    */
18847
0
    ret = xmlSchemaVCheckCVCSimpleType(
18848
0
        ACTXT_CAST pctxt, facet->node, base,
18849
0
        facet->value, &(facet->val), 1, 1, 0);
18850
0
                if (ret != 0) {
18851
0
        if (ret < 0) {
18852
      /* No error message for RelaxNG. */
18853
0
      if (ctxtGiven) {
18854
0
          xmlSchemaCustomErr(ACTXT_CAST pctxt,
18855
0
        XML_SCHEMAP_INTERNAL, facet->node, NULL,
18856
0
        "Internal error: xmlSchemaCheckFacet, "
18857
0
        "failed to validate the value '%s' of the "
18858
0
        "facet '%s' against the base type",
18859
0
        facet->value, xmlSchemaFacetTypeToString(facet->type));
18860
0
      }
18861
0
      goto internal_error;
18862
0
        }
18863
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18864
        /* No error message for RelaxNG. */
18865
0
        if (ctxtGiven) {
18866
0
      xmlChar *str = NULL;
18867
18868
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18869
0
          ret, facet->node, WXS_BASIC_CAST facet,
18870
0
          "The value '%s' of the facet does not validate "
18871
0
          "against the base type '%s'",
18872
0
          facet->value,
18873
0
          xmlSchemaFormatQName(&str,
18874
0
        base->targetNamespace, base->name));
18875
0
      FREE_AND_NULL(str);
18876
0
        }
18877
0
        goto exit;
18878
0
                } else if (facet->val == NULL) {
18879
0
        if (ctxtGiven) {
18880
0
      PERROR_INT("xmlSchemaCheckFacet",
18881
0
          "value was not computed");
18882
0
        }
18883
0
        TODO
18884
0
    }
18885
0
                break;
18886
0
            }
18887
0
        case XML_SCHEMA_FACET_PATTERN:
18888
0
            facet->regexp = xmlRegexpCompile(facet->value);
18889
0
            if (facet->regexp == NULL) {
18890
0
    ret = XML_SCHEMAP_REGEXP_INVALID;
18891
    /* No error message for RelaxNG. */
18892
0
    if (ctxtGiven) {
18893
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18894
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18895
0
      "The value '%s' of the facet 'pattern' is not a "
18896
0
      "valid regular expression",
18897
0
      facet->value, NULL);
18898
0
    }
18899
0
            }
18900
0
            break;
18901
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
18902
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
18903
0
        case XML_SCHEMA_FACET_LENGTH:
18904
0
        case XML_SCHEMA_FACET_MAXLENGTH:
18905
0
        case XML_SCHEMA_FACET_MINLENGTH:
18906
18907
0
      if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18908
0
    ret = xmlSchemaValidatePredefinedType(
18909
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18910
0
        facet->value, &(facet->val));
18911
0
      } else {
18912
0
    ret = xmlSchemaValidatePredefinedType(
18913
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18914
0
        facet->value, &(facet->val));
18915
0
      }
18916
0
      if (ret != 0) {
18917
0
    if (ret < 0) {
18918
        /* No error message for RelaxNG. */
18919
0
        if (ctxtGiven) {
18920
0
      PERROR_INT("xmlSchemaCheckFacet",
18921
0
          "validating facet value");
18922
0
        }
18923
0
        goto internal_error;
18924
0
    }
18925
0
    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18926
    /* No error message for RelaxNG. */
18927
0
    if (ctxtGiven) {
18928
        /* error code */
18929
0
        xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18930
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18931
0
      "The value '%s' of the facet '%s' is not a valid '%s'",
18932
0
      facet->value,
18933
0
      xmlSchemaFacetTypeToString(facet->type),
18934
0
      (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18935
0
          BAD_CAST "nonNegativeInteger" :
18936
0
          BAD_CAST "positiveInteger",
18937
0
      NULL);
18938
0
    }
18939
0
      }
18940
0
      break;
18941
18942
0
        case XML_SCHEMA_FACET_WHITESPACE:{
18943
0
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18944
0
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18945
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18946
0
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18947
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18948
0
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18949
0
                } else {
18950
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18951
                    /* No error message for RelaxNG. */
18952
0
        if (ctxtGiven) {
18953
      /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18954
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18955
0
          ret, facet->node, WXS_BASIC_CAST typeDecl,
18956
0
          "The value '%s' of the facet 'whitespace' is not "
18957
0
          "valid", facet->value, NULL);
18958
0
                    }
18959
0
                }
18960
0
            }
18961
0
        default:
18962
0
            break;
18963
0
    }
18964
0
exit:
18965
0
    if ((! ctxtGiven) && (pctxt != NULL))
18966
0
  xmlSchemaFreeParserCtxt(pctxt);
18967
0
    return (ret);
18968
0
internal_error:
18969
0
    if ((! ctxtGiven) && (pctxt != NULL))
18970
0
  xmlSchemaFreeParserCtxt(pctxt);
18971
0
    return (-1);
18972
0
}
18973
18974
/**
18975
 * xmlSchemaCheckFacetValues:
18976
 * @typeDecl:  the schema type definition
18977
 * @ctxt:  the schema parser context
18978
 *
18979
 * Checks the default values types, especially for facets
18980
 */
18981
static int
18982
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18983
        xmlSchemaParserCtxtPtr pctxt)
18984
0
{
18985
0
    int res, olderrs = pctxt->nberrors;
18986
0
    const xmlChar *name = typeDecl->name;
18987
    /*
18988
    * NOTE: It is intended to use the facets list, instead
18989
    * of facetSet.
18990
    */
18991
0
    if (typeDecl->facets != NULL) {
18992
0
  xmlSchemaFacetPtr facet = typeDecl->facets;
18993
18994
  /*
18995
  * Temporarily assign the "schema" to the validation context
18996
  * of the parser context. This is needed for NOTATION validation.
18997
  */
18998
0
  if (pctxt->vctxt == NULL) {
18999
0
      if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
19000
0
    return(-1);
19001
0
  }
19002
0
  pctxt->vctxt->schema = pctxt->schema;
19003
0
  while (facet != NULL) {
19004
0
      res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
19005
0
      HFAILURE
19006
0
      facet = facet->next;
19007
0
  }
19008
0
  pctxt->vctxt->schema = NULL;
19009
0
    }
19010
0
    if (olderrs != pctxt->nberrors)
19011
0
  return(pctxt->err);
19012
0
    return(0);
19013
0
exit_failure:
19014
0
    return(-1);
19015
0
}
19016
19017
/**
19018
 * xmlSchemaGetCircModelGrDefRef:
19019
 * @ctxtMGroup: the searched model group
19020
 * @selfMGroup: the second searched model group
19021
 * @particle: the first particle
19022
 *
19023
 * This one is intended to be used by
19024
 * xmlSchemaCheckGroupDefCircular only.
19025
 *
19026
 * Returns the particle with the circular model group definition reference,
19027
 * otherwise NULL.
19028
 */
19029
static xmlSchemaTreeItemPtr
19030
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
19031
            xmlSchemaTreeItemPtr particle)
19032
0
{
19033
0
    xmlSchemaTreeItemPtr circ = NULL;
19034
0
    xmlSchemaTreeItemPtr term;
19035
0
    xmlSchemaModelGroupDefPtr gdef;
19036
19037
0
    for (; particle != NULL; particle = particle->next) {
19038
0
  term = particle->children;
19039
0
  if (term == NULL)
19040
0
      continue;
19041
0
  switch (term->type) {
19042
0
      case XML_SCHEMA_TYPE_GROUP:
19043
0
    gdef = (xmlSchemaModelGroupDefPtr) term;
19044
0
    if (gdef == groupDef)
19045
0
        return (particle);
19046
    /*
19047
    * Mark this model group definition to avoid infinite
19048
    * recursion on circular references not yet examined.
19049
    */
19050
0
    if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
19051
0
        continue;
19052
0
    if (gdef->children != NULL) {
19053
0
        gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
19054
0
        circ = xmlSchemaGetCircModelGrDefRef(groupDef,
19055
0
      gdef->children->children);
19056
0
        gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
19057
0
        if (circ != NULL)
19058
0
      return (circ);
19059
0
    }
19060
0
    break;
19061
0
      case XML_SCHEMA_TYPE_SEQUENCE:
19062
0
      case XML_SCHEMA_TYPE_CHOICE:
19063
0
      case XML_SCHEMA_TYPE_ALL:
19064
0
    circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
19065
0
    if (circ != NULL)
19066
0
        return (circ);
19067
0
    break;
19068
0
      default:
19069
0
    break;
19070
0
  }
19071
0
    }
19072
0
    return (NULL);
19073
0
}
19074
19075
/**
19076
 * xmlSchemaCheckGroupDefCircular:
19077
 * @item:  the model group definition
19078
 * @ctxt:  the parser context
19079
 * @name:  the name
19080
 *
19081
 * Checks for circular references to model group definitions.
19082
 */
19083
static void
19084
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
19085
             xmlSchemaParserCtxtPtr ctxt)
19086
0
{
19087
    /*
19088
    * Schema Component Constraint: Model Group Correct
19089
    * 2 Circular groups are disallowed. That is, within the {particles}
19090
    * of a group there must not be at any depth a particle whose {term}
19091
    * is the group itself.
19092
    */
19093
0
    if ((item == NULL) ||
19094
0
  (item->type != XML_SCHEMA_TYPE_GROUP) ||
19095
0
  (item->children == NULL))
19096
0
  return;
19097
0
    {
19098
0
  xmlSchemaTreeItemPtr circ;
19099
19100
0
  circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
19101
0
  if (circ != NULL) {
19102
0
      xmlChar *str = NULL;
19103
      /*
19104
      * TODO: The error report is not adequate: this constraint
19105
      * is defined for model groups but not definitions, but since
19106
      * there cannot be any circular model groups without a model group
19107
      * definition (if not using a construction API), we check those
19108
      * definitions only.
19109
      */
19110
0
      xmlSchemaPCustomErr(ctxt,
19111
0
    XML_SCHEMAP_MG_PROPS_CORRECT_2,
19112
0
    NULL, WXS_ITEM_NODE(circ),
19113
0
    "Circular reference to the model group definition '%s' "
19114
0
    "defined", xmlSchemaFormatQName(&str,
19115
0
        item->targetNamespace, item->name));
19116
0
      FREE_AND_NULL(str)
19117
      /*
19118
      * NOTE: We will cut the reference to avoid further
19119
      * confusion of the processor. This is a fatal error.
19120
      */
19121
0
      circ->children = NULL;
19122
0
  }
19123
0
    }
19124
0
}
19125
19126
/**
19127
 * xmlSchemaModelGroupToModelGroupDefFixup:
19128
 * @ctxt:  the parser context
19129
 * @mg:  the model group
19130
 *
19131
 * Assigns the model group of model group definitions to the "term"
19132
 * of the referencing particle.
19133
 * In xmlSchemaResolveModelGroupParticleReferences the model group
19134
 * definitions were assigned to the "term", since needed for the
19135
 * circularity check.
19136
 *
19137
 * Schema Component Constraint:
19138
 *     All Group Limited (cos-all-limited) (1.2)
19139
 */
19140
static void
19141
xmlSchemaModelGroupToModelGroupDefFixup(
19142
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
19143
    xmlSchemaModelGroupPtr mg)
19144
0
{
19145
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19146
19147
0
    while (particle != NULL) {
19148
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19149
0
      ((WXS_PARTICLE_TERM(particle))->type !=
19150
0
    XML_SCHEMA_TYPE_GROUP))
19151
0
  {
19152
0
      particle = WXS_PTC_CAST particle->next;
19153
0
      continue;
19154
0
  }
19155
0
  if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
19156
      /*
19157
      * TODO: Remove the particle.
19158
      */
19159
0
      WXS_PARTICLE_TERM(particle) = NULL;
19160
0
      particle = WXS_PTC_CAST particle->next;
19161
0
      continue;
19162
0
  }
19163
  /*
19164
  * Assign the model group to the {term} of the particle.
19165
  */
19166
0
  WXS_PARTICLE_TERM(particle) =
19167
0
      WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
19168
19169
0
  particle = WXS_PTC_CAST particle->next;
19170
0
    }
19171
0
}
19172
19173
/**
19174
 * xmlSchemaCheckAttrGroupCircularRecur:
19175
 * @ctxtGr: the searched attribute group
19176
 * @attr: the current attribute list to be processed
19177
 *
19178
 * This one is intended to be used by
19179
 * xmlSchemaCheckAttrGroupCircular only.
19180
 *
19181
 * Returns the circular attribute group reference, otherwise NULL.
19182
 */
19183
static xmlSchemaQNameRefPtr
19184
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
19185
             xmlSchemaItemListPtr list)
19186
0
{
19187
0
    xmlSchemaAttributeGroupPtr gr;
19188
0
    xmlSchemaQNameRefPtr ref, circ;
19189
0
    int i;
19190
    /*
19191
    * We will search for an attribute group reference which
19192
    * references the context attribute group.
19193
    */
19194
0
    for (i = 0; i < list->nbItems; i++) {
19195
0
  ref = list->items[i];
19196
0
  if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19197
0
      (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
19198
0
      (ref->item != NULL))
19199
0
  {
19200
0
      gr = WXS_ATTR_GROUP_CAST ref->item;
19201
0
      if (gr == ctxtGr)
19202
0
    return(ref);
19203
0
      if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19204
0
    continue;
19205
      /*
19206
      * Mark as visited to avoid infinite recursion on
19207
      * circular references not yet examined.
19208
      */
19209
0
      if ((gr->attrUses) &&
19210
0
    (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19211
0
      {
19212
0
    gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19213
0
    circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19214
0
        (xmlSchemaItemListPtr) gr->attrUses);
19215
0
    gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19216
0
    if (circ != NULL)
19217
0
        return (circ);
19218
0
      }
19219
19220
0
  }
19221
0
    }
19222
0
    return (NULL);
19223
0
}
19224
19225
/**
19226
 * xmlSchemaCheckAttrGroupCircular:
19227
 * attrGr:  the attribute group definition
19228
 * @ctxt:  the parser context
19229
 * @name:  the name
19230
 *
19231
 * Checks for circular references of attribute groups.
19232
 */
19233
static int
19234
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19235
        xmlSchemaParserCtxtPtr ctxt)
19236
0
{
19237
    /*
19238
    * Schema Representation Constraint:
19239
    * Attribute Group Definition Representation OK
19240
    * 3 Circular group reference is disallowed outside <redefine>.
19241
    * That is, unless this element information item's parent is
19242
    * <redefine>, then among the [children], if any, there must
19243
    * not be an <attributeGroup> with ref [attribute] which resolves
19244
    * to the component corresponding to this <attributeGroup>. Indirect
19245
    * circularity is also ruled out. That is, when QName resolution
19246
    * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19247
    * any <attributeGroup>s with a ref [attribute] among the [children],
19248
    * it must not be the case that a `QName` is encountered at any depth
19249
    * which resolves to the component corresponding to this <attributeGroup>.
19250
    */
19251
0
    if (attrGr->attrUses == NULL)
19252
0
  return(0);
19253
0
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19254
0
  return(0);
19255
0
    else {
19256
0
  xmlSchemaQNameRefPtr circ;
19257
19258
0
  circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19259
0
      (xmlSchemaItemListPtr) attrGr->attrUses);
19260
0
  if (circ != NULL) {
19261
0
      xmlChar *str = NULL;
19262
      /*
19263
      * TODO: Report the referenced attr group as QName.
19264
      */
19265
0
      xmlSchemaPCustomErr(ctxt,
19266
0
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19267
0
    NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19268
0
    "Circular reference to the attribute group '%s' "
19269
0
    "defined", xmlSchemaGetComponentQName(&str, attrGr));
19270
0
      FREE_AND_NULL(str);
19271
      /*
19272
      * NOTE: We will cut the reference to avoid further
19273
      * confusion of the processor.
19274
      * BADSPEC TODO: The spec should define how to process in this case.
19275
      */
19276
0
      circ->item = NULL;
19277
0
      return(ctxt->err);
19278
0
  }
19279
0
    }
19280
0
    return(0);
19281
0
}
19282
19283
static int
19284
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19285
          xmlSchemaAttributeGroupPtr attrGr);
19286
19287
/**
19288
 * xmlSchemaExpandAttributeGroupRefs:
19289
 * @pctxt: the parser context
19290
 * @node: the node of the component holding the attribute uses
19291
 * @completeWild: the intersected wildcard to be returned
19292
 * @list: the attribute uses
19293
 *
19294
 * Substitutes contained attribute group references
19295
 * for their attribute uses. Wildcards are intersected.
19296
 * Attribute use prohibitions are removed from the list
19297
 * and returned via the @prohibs list.
19298
 * Pointlessness of attr. prohibs, if a matching attr. decl
19299
 * is existent a well, are checked.
19300
 */
19301
static int
19302
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19303
          xmlSchemaBasicItemPtr item,
19304
          xmlSchemaWildcardPtr *completeWild,
19305
          xmlSchemaItemListPtr list,
19306
          xmlSchemaItemListPtr prohibs)
19307
0
{
19308
0
    xmlSchemaAttributeGroupPtr gr;
19309
0
    xmlSchemaAttributeUsePtr use;
19310
0
    xmlSchemaItemListPtr sublist;
19311
0
    int i, j;
19312
0
    int created = (*completeWild == NULL) ? 0 : 1;
19313
19314
0
    if (prohibs)
19315
0
  prohibs->nbItems = 0;
19316
19317
0
    for (i = 0; i < list->nbItems; i++) {
19318
0
  use = list->items[i];
19319
19320
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19321
0
      if (prohibs == NULL) {
19322
0
    PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19323
0
        "unexpected attr prohibition found");
19324
0
    return(-1);
19325
0
      }
19326
      /*
19327
      * Remove from attribute uses.
19328
      */
19329
0
      if (xmlSchemaItemListRemove(list, i) == -1)
19330
0
    return(-1);
19331
0
      i--;
19332
      /*
19333
      * Note that duplicate prohibitions were already
19334
      * handled at parsing time.
19335
      */
19336
      /*
19337
      * Add to list of prohibitions.
19338
      */
19339
0
      xmlSchemaItemListAddSize(prohibs, 2, use);
19340
0
      continue;
19341
0
  }
19342
0
  if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19343
0
      ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19344
0
  {
19345
0
      if ((WXS_QNAME_CAST use)->item == NULL)
19346
0
    return(-1);
19347
0
      gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19348
      /*
19349
      * Expand the referenced attr. group.
19350
      * TODO: remove this, this is done in a previous step, so
19351
      * already done here.
19352
      */
19353
0
      if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19354
0
    if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19355
0
        return(-1);
19356
0
      }
19357
      /*
19358
      * Build the 'complete' wildcard; i.e. intersect multiple
19359
      * wildcards.
19360
      */
19361
0
      if (gr->attributeWildcard != NULL) {
19362
0
    if (*completeWild == NULL) {
19363
0
        *completeWild = gr->attributeWildcard;
19364
0
    } else {
19365
0
        if (! created) {
19366
0
      xmlSchemaWildcardPtr tmpWild;
19367
19368
       /*
19369
      * Copy the first encountered wildcard as context,
19370
      * except for the annotation.
19371
      *
19372
      * Although the complete wildcard might not correspond
19373
      * to any node in the schema, we will anchor it on
19374
      * the node of the owner component.
19375
      */
19376
0
      tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19377
0
          XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19378
0
          WXS_ITEM_NODE(item));
19379
0
      if (tmpWild == NULL)
19380
0
          return(-1);
19381
0
      if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19382
0
          tmpWild, *completeWild) == -1)
19383
0
          return (-1);
19384
0
      tmpWild->processContents = (*completeWild)->processContents;
19385
0
      *completeWild = tmpWild;
19386
0
      created = 1;
19387
0
        }
19388
19389
0
        if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19390
0
      gr->attributeWildcard) == -1)
19391
0
      return(-1);
19392
0
    }
19393
0
      }
19394
      /*
19395
      * Just remove the reference if the referenced group does not
19396
      * contain any attribute uses.
19397
      */
19398
0
      sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19399
0
      if ((sublist == NULL) || sublist->nbItems == 0) {
19400
0
    if (xmlSchemaItemListRemove(list, i) == -1)
19401
0
        return(-1);
19402
0
    i--;
19403
0
    continue;
19404
0
      }
19405
      /*
19406
      * Add the attribute uses.
19407
      */
19408
0
      list->items[i] = sublist->items[0];
19409
0
      if (sublist->nbItems != 1) {
19410
0
    for (j = 1; j < sublist->nbItems; j++) {
19411
0
        i++;
19412
0
        if (xmlSchemaItemListInsert(list,
19413
0
          sublist->items[j], i) == -1)
19414
0
      return(-1);
19415
0
    }
19416
0
      }
19417
0
  }
19418
19419
0
    }
19420
    /*
19421
    * Handle pointless prohibitions of declared attributes.
19422
    */
19423
0
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19424
0
  xmlSchemaAttributeUseProhibPtr prohib;
19425
19426
0
  for (i = prohibs->nbItems -1; i >= 0; i--) {
19427
0
      prohib = prohibs->items[i];
19428
0
      for (j = 0; j < list->nbItems; j++) {
19429
0
    use = list->items[j];
19430
19431
0
    if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19432
0
        (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19433
0
    {
19434
0
        xmlChar *str = NULL;
19435
19436
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19437
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19438
0
      prohib->node, NULL,
19439
0
      "Skipping pointless attribute use prohibition "
19440
0
      "'%s', since a corresponding attribute use "
19441
0
      "exists already in the type definition",
19442
0
      xmlSchemaFormatQName(&str,
19443
0
          prohib->targetNamespace, prohib->name),
19444
0
      NULL, NULL);
19445
0
        FREE_AND_NULL(str);
19446
        /*
19447
        * Remove the prohibition.
19448
        */
19449
0
        if (xmlSchemaItemListRemove(prohibs, i) == -1)
19450
0
      return(-1);
19451
0
        break;
19452
0
    }
19453
0
      }
19454
0
  }
19455
0
    }
19456
0
    return(0);
19457
0
}
19458
19459
/**
19460
 * xmlSchemaAttributeGroupExpandRefs:
19461
 * @pctxt:  the parser context
19462
 * @attrGr:  the attribute group definition
19463
 *
19464
 * Computation of:
19465
 * {attribute uses} property
19466
 * {attribute wildcard} property
19467
 *
19468
 * Substitutes contained attribute group references
19469
 * for their attribute uses. Wildcards are intersected.
19470
 */
19471
static int
19472
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19473
          xmlSchemaAttributeGroupPtr attrGr)
19474
0
{
19475
0
    if ((attrGr->attrUses == NULL) ||
19476
0
  (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19477
0
  return(0);
19478
19479
0
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19480
0
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19481
0
  &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19482
0
  return(-1);
19483
0
    return(0);
19484
0
}
19485
19486
/**
19487
 * xmlSchemaAttributeGroupExpandRefs:
19488
 * @pctxt:  the parser context
19489
 * @attrGr:  the attribute group definition
19490
 *
19491
 * Substitutes contained attribute group references
19492
 * for their attribute uses. Wildcards are intersected.
19493
 *
19494
 * Schema Component Constraint:
19495
 *    Attribute Group Definition Properties Correct (ag-props-correct)
19496
 */
19497
static int
19498
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19499
          xmlSchemaAttributeGroupPtr attrGr)
19500
0
{
19501
    /*
19502
    * SPEC ag-props-correct
19503
    * (1) "The values of the properties of an attribute group definition
19504
    * must be as described in the property tableau in The Attribute
19505
    * Group Definition Schema Component ($3.6.1), modulo the impact of
19506
    * Missing Sub-components ($5.3);"
19507
    */
19508
19509
0
    if ((attrGr->attrUses != NULL) &&
19510
0
  (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19511
0
    {
19512
0
  xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19513
0
  xmlSchemaAttributeUsePtr use, tmp;
19514
0
  int i, j, hasId = 0;
19515
19516
0
  for (i = uses->nbItems -1; i >= 0; i--) {
19517
0
      use = uses->items[i];
19518
      /*
19519
      * SPEC ag-props-correct
19520
      * (2) "Two distinct members of the {attribute uses} must not have
19521
      * {attribute declaration}s both of whose {name}s match and whose
19522
      * {target namespace}s are identical."
19523
      */
19524
0
      if (i > 0) {
19525
0
    for (j = i -1; j >= 0; j--) {
19526
0
        tmp = uses->items[j];
19527
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
19528
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
19529
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
19530
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
19531
0
        {
19532
0
      xmlChar *str = NULL;
19533
19534
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19535
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19536
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19537
0
          "Duplicate %s",
19538
0
          xmlSchemaGetComponentDesignation(&str, use),
19539
0
          NULL);
19540
0
      FREE_AND_NULL(str);
19541
      /*
19542
      * Remove the duplicate.
19543
      */
19544
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19545
0
          return(-1);
19546
0
      goto next_use;
19547
0
        }
19548
0
    }
19549
0
      }
19550
      /*
19551
      * SPEC ag-props-correct
19552
      * (3) "Two distinct members of the {attribute uses} must not have
19553
      * {attribute declaration}s both of whose {type definition}s are or
19554
      * are derived from ID."
19555
      * TODO: Does 'derived' include member-types of unions?
19556
      */
19557
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19558
0
    if (xmlSchemaIsDerivedFromBuiltInType(
19559
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19560
0
    {
19561
0
        if (hasId) {
19562
0
      xmlChar *str = NULL;
19563
19564
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19565
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19566
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19567
0
          "There must not exist more than one attribute "
19568
0
          "declaration of type 'xs:ID' "
19569
0
          "(or derived from 'xs:ID'). The %s violates this "
19570
0
          "constraint",
19571
0
          xmlSchemaGetComponentDesignation(&str, use),
19572
0
          NULL);
19573
0
      FREE_AND_NULL(str);
19574
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19575
0
          return(-1);
19576
0
        }
19577
0
        hasId = 1;
19578
0
    }
19579
0
      }
19580
0
next_use: {}
19581
0
  }
19582
0
    }
19583
0
    return(0);
19584
0
}
19585
19586
/**
19587
 * xmlSchemaResolveAttrGroupReferences:
19588
 * @attrgrpDecl:  the schema attribute definition
19589
 * @ctxt:  the schema parser context
19590
 * @name:  the attribute name
19591
 *
19592
 * Resolves references to attribute group definitions.
19593
 */
19594
static int
19595
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19596
            xmlSchemaParserCtxtPtr ctxt)
19597
0
{
19598
0
    xmlSchemaAttributeGroupPtr group;
19599
19600
0
    if (ref->item != NULL)
19601
0
        return(0);
19602
0
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
19603
0
  ref->name,
19604
0
  ref->targetNamespace);
19605
0
    if (group == NULL) {
19606
0
  xmlSchemaPResCompAttrErr(ctxt,
19607
0
      XML_SCHEMAP_SRC_RESOLVE,
19608
0
      NULL, ref->node,
19609
0
      "ref", ref->name, ref->targetNamespace,
19610
0
      ref->itemType, NULL);
19611
0
  return(ctxt->err);
19612
0
    }
19613
0
    ref->item = WXS_BASIC_CAST group;
19614
0
    return(0);
19615
0
}
19616
19617
/**
19618
 * xmlSchemaCheckAttrPropsCorrect:
19619
 * @item:  an schema attribute declaration/use
19620
 * @ctxt:  a schema parser context
19621
 * @name:  the name of the attribute
19622
 *
19623
 *
19624
 * Schema Component Constraint:
19625
 *    Attribute Declaration Properties Correct (a-props-correct)
19626
 *
19627
 * Validates the value constraints of an attribute declaration/use.
19628
 * NOTE that this needs the simple type definitions to be already
19629
 *   built and checked.
19630
 */
19631
static int
19632
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19633
             xmlSchemaAttributePtr attr)
19634
0
{
19635
19636
    /*
19637
    * SPEC a-props-correct (1)
19638
    * "The values of the properties of an attribute declaration must
19639
    * be as described in the property tableau in The Attribute
19640
    * Declaration Schema Component ($3.2.1), modulo the impact of
19641
    * Missing Sub-components ($5.3)."
19642
    */
19643
19644
0
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
19645
0
  return(0);
19646
19647
0
    if (attr->defValue != NULL) {
19648
0
  int ret;
19649
19650
  /*
19651
  * SPEC a-props-correct (3)
19652
  * "If the {type definition} is or is derived from ID then there
19653
  * must not be a {value constraint}."
19654
  */
19655
0
  if (xmlSchemaIsDerivedFromBuiltInType(
19656
0
      WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19657
0
  {
19658
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19659
0
    XML_SCHEMAP_A_PROPS_CORRECT_3,
19660
0
    NULL, WXS_BASIC_CAST attr,
19661
0
    "Value constraints are not allowed if the type definition "
19662
0
    "is or is derived from xs:ID",
19663
0
    NULL, NULL);
19664
0
      return(pctxt->err);
19665
0
  }
19666
  /*
19667
  * SPEC a-props-correct (2)
19668
  * "if there is a {value constraint}, the canonical lexical
19669
  * representation of its value must be `valid` with respect
19670
  * to the {type definition} as defined in String Valid ($3.14.4)."
19671
  * TODO: Don't care about the *canonical* stuff here, this requirement
19672
  * will be removed in WXS 1.1 anyway.
19673
  */
19674
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19675
0
      attr->node, WXS_ATTR_TYPEDEF(attr),
19676
0
      attr->defValue, &(attr->defVal),
19677
0
      1, 1, 0);
19678
0
  if (ret != 0) {
19679
0
      if (ret < 0) {
19680
0
    PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19681
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19682
0
    return(-1);
19683
0
      }
19684
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19685
0
    XML_SCHEMAP_A_PROPS_CORRECT_2,
19686
0
    NULL, WXS_BASIC_CAST attr,
19687
0
    "The value of the value constraint is not valid",
19688
0
    NULL, NULL);
19689
0
      return(pctxt->err);
19690
0
  }
19691
0
    }
19692
19693
0
    return(0);
19694
0
}
19695
19696
static xmlSchemaElementPtr
19697
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19698
         xmlSchemaElementPtr ancestor)
19699
0
{
19700
0
    xmlSchemaElementPtr ret;
19701
19702
0
    if (WXS_SUBST_HEAD(ancestor) == NULL)
19703
0
  return (NULL);
19704
0
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19705
0
  return (ancestor);
19706
19707
0
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19708
0
  return (NULL);
19709
0
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19710
0
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19711
0
  WXS_SUBST_HEAD(ancestor));
19712
0
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19713
19714
0
    return (ret);
19715
0
}
19716
19717
/**
19718
 * xmlSchemaCheckElemPropsCorrect:
19719
 * @ctxt:  a schema parser context
19720
 * @decl: the element declaration
19721
 * @name:  the name of the attribute
19722
 *
19723
 * Schema Component Constraint:
19724
 * Element Declaration Properties Correct (e-props-correct)
19725
 *
19726
 * STATUS:
19727
 *   missing: (6)
19728
 */
19729
static int
19730
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19731
             xmlSchemaElementPtr elemDecl)
19732
0
{
19733
0
    int ret = 0;
19734
0
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19735
    /*
19736
    * SPEC (1) "The values of the properties of an element declaration
19737
    * must be as described in the property tableau in The Element
19738
    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19739
    * Sub-components ($5.3)."
19740
    */
19741
0
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19742
0
  xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19743
19744
0
  xmlSchemaCheckElementDeclComponent(head, pctxt);
19745
  /*
19746
  * SPEC (3) "If there is a non-`absent` {substitution group
19747
  * affiliation}, then {scope} must be global."
19748
  */
19749
0
  if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19750
0
      xmlSchemaPCustomErr(pctxt,
19751
0
    XML_SCHEMAP_E_PROPS_CORRECT_3,
19752
0
    WXS_BASIC_CAST elemDecl, NULL,
19753
0
    "Only global element declarations can have a "
19754
0
    "substitution group affiliation", NULL);
19755
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19756
0
  }
19757
  /*
19758
  * TODO: SPEC (6) "Circular substitution groups are disallowed.
19759
  * That is, it must not be possible to return to an element declaration
19760
  * by repeatedly following the {substitution group affiliation}
19761
  * property."
19762
  */
19763
0
  if (head == elemDecl)
19764
0
      circ = head;
19765
0
  else if (WXS_SUBST_HEAD(head) != NULL)
19766
0
      circ = xmlSchemaCheckSubstGroupCircular(head, head);
19767
0
  else
19768
0
      circ = NULL;
19769
0
  if (circ != NULL) {
19770
0
      xmlChar *strA = NULL, *strB = NULL;
19771
19772
0
      xmlSchemaPCustomErrExt(pctxt,
19773
0
    XML_SCHEMAP_E_PROPS_CORRECT_6,
19774
0
    WXS_BASIC_CAST circ, NULL,
19775
0
    "The element declaration '%s' defines a circular "
19776
0
    "substitution group to element declaration '%s'",
19777
0
    xmlSchemaGetComponentQName(&strA, circ),
19778
0
    xmlSchemaGetComponentQName(&strB, head),
19779
0
    NULL);
19780
0
      FREE_AND_NULL(strA)
19781
0
      FREE_AND_NULL(strB)
19782
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19783
0
  }
19784
  /*
19785
  * SPEC (4) "If there is a {substitution group affiliation},
19786
  * the {type definition}
19787
  * of the element declaration must be validly derived from the {type
19788
  * definition} of the {substitution group affiliation}, given the value
19789
  * of the {substitution group exclusions} of the {substitution group
19790
  * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19791
  * (if the {type definition} is complex) or as defined in
19792
  * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19793
  * simple)."
19794
  *
19795
  * NOTE: {substitution group exclusions} means the values of the
19796
  * attribute "final".
19797
  */
19798
19799
0
  if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19800
0
      int set = 0;
19801
19802
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19803
0
    set |= SUBSET_EXTENSION;
19804
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19805
0
    set |= SUBSET_RESTRICTION;
19806
19807
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19808
0
    WXS_ELEM_TYPEDEF(head), set) != 0) {
19809
0
    xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19810
19811
0
    ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19812
0
    xmlSchemaPCustomErrExt(pctxt,
19813
0
        XML_SCHEMAP_E_PROPS_CORRECT_4,
19814
0
        WXS_BASIC_CAST elemDecl, NULL,
19815
0
        "The type definition '%s' was "
19816
0
        "either rejected by the substitution group "
19817
0
        "affiliation '%s', or not validly derived from its type "
19818
0
        "definition '%s'",
19819
0
        xmlSchemaGetComponentQName(&strA, typeDef),
19820
0
        xmlSchemaGetComponentQName(&strB, head),
19821
0
        xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19822
0
    FREE_AND_NULL(strA)
19823
0
    FREE_AND_NULL(strB)
19824
0
    FREE_AND_NULL(strC)
19825
0
      }
19826
0
  }
19827
0
    }
19828
    /*
19829
    * SPEC (5) "If the {type definition} or {type definition}'s
19830
    * {content type}
19831
    * is or is derived from ID then there must not be a {value constraint}.
19832
    * Note: The use of ID as a type definition for elements goes beyond
19833
    * XML 1.0, and should be avoided if backwards compatibility is desired"
19834
    */
19835
0
    if ((elemDecl->value != NULL) &&
19836
0
  ((WXS_IS_SIMPLE(typeDef) &&
19837
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19838
0
   (WXS_IS_COMPLEX(typeDef) &&
19839
0
    WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19840
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19841
0
      XML_SCHEMAS_ID)))) {
19842
19843
0
  ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19844
0
  xmlSchemaPCustomErr(pctxt,
19845
0
      XML_SCHEMAP_E_PROPS_CORRECT_5,
19846
0
      WXS_BASIC_CAST elemDecl, NULL,
19847
0
      "The type definition (or type definition's content type) is or "
19848
0
      "is derived from ID; value constraints are not allowed in "
19849
0
      "conjunction with such a type definition", NULL);
19850
0
    } else if (elemDecl->value != NULL) {
19851
0
  int vcret;
19852
0
  xmlNodePtr node = NULL;
19853
19854
  /*
19855
  * SPEC (2) "If there is a {value constraint}, the canonical lexical
19856
  * representation of its value must be `valid` with respect to the
19857
  * {type definition} as defined in Element Default Valid (Immediate)
19858
  * ($3.3.6)."
19859
  */
19860
0
  if (typeDef == NULL) {
19861
0
      xmlSchemaPErr(pctxt, elemDecl->node,
19862
0
    XML_SCHEMAP_INTERNAL,
19863
0
    "Internal error: xmlSchemaCheckElemPropsCorrect, "
19864
0
    "type is missing... skipping validation of "
19865
0
    "the value constraint", NULL, NULL);
19866
0
      return (-1);
19867
0
  }
19868
0
  if (elemDecl->node != NULL) {
19869
0
      if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19870
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19871
0
        BAD_CAST "fixed");
19872
0
      else
19873
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19874
0
        BAD_CAST "default");
19875
0
  }
19876
0
  vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19877
0
      typeDef, elemDecl->value, &(elemDecl->defVal));
19878
0
  if (vcret != 0) {
19879
0
      if (vcret < 0) {
19880
0
    PERROR_INT("xmlSchemaElemCheckValConstr",
19881
0
        "failed to validate the value constraint of an "
19882
0
        "element declaration");
19883
0
    return (-1);
19884
0
      }
19885
0
      return (vcret);
19886
0
  }
19887
0
    }
19888
19889
0
    return (ret);
19890
0
}
19891
19892
/**
19893
 * xmlSchemaCheckElemSubstGroup:
19894
 * @ctxt:  a schema parser context
19895
 * @decl: the element declaration
19896
 * @name:  the name of the attribute
19897
 *
19898
 * Schema Component Constraint:
19899
 * Substitution Group (cos-equiv-class)
19900
 *
19901
 * In Libxml2 the subst. groups will be precomputed, in terms of that
19902
 * a list will be built for each subst. group head, holding all direct
19903
 * referents to this head.
19904
 * NOTE that this function needs:
19905
 *   1. circular subst. groups to be checked beforehand
19906
 *   2. the declaration's type to be derived from the head's type
19907
 *
19908
 * STATUS:
19909
 *
19910
 */
19911
static void
19912
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19913
           xmlSchemaElementPtr elemDecl)
19914
0
{
19915
0
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19916
  /* SPEC (1) "Its {abstract} is false." */
19917
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19918
0
  return;
19919
0
    {
19920
0
  xmlSchemaElementPtr head;
19921
0
  xmlSchemaTypePtr headType, type;
19922
0
  int set, methSet;
19923
  /*
19924
  * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19925
  * {disallowed substitutions} as the blocking constraint, as defined in
19926
  * Substitution Group OK (Transitive) ($3.3.6)."
19927
  */
19928
0
  for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19929
0
      head = WXS_SUBST_HEAD(head)) {
19930
0
      set = 0;
19931
0
      methSet = 0;
19932
      /*
19933
      * The blocking constraints.
19934
      */
19935
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19936
0
    continue;
19937
0
      headType = head->subtypes;
19938
0
      type = elemDecl->subtypes;
19939
0
      if (headType == type)
19940
0
    goto add_member;
19941
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19942
0
    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19943
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19944
0
    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19945
      /*
19946
      * SPEC: Substitution Group OK (Transitive) (2.3)
19947
      * "The set of all {derivation method}s involved in the
19948
      * derivation of D's {type definition} from C's {type definition}
19949
      * does not intersect with the union of the blocking constraint,
19950
      * C's {prohibited substitutions} (if C is complex, otherwise the
19951
      * empty set) and the {prohibited substitutions} (respectively the
19952
      * empty set) of any intermediate {type definition}s in the
19953
      * derivation of D's {type definition} from C's {type definition}."
19954
      */
19955
      /*
19956
      * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19957
      * subst.head axis, the methSet does not need to be computed for
19958
      * the full depth over and over.
19959
      */
19960
      /*
19961
      * The set of all {derivation method}s involved in the derivation
19962
      */
19963
0
      while ((type != NULL) && (type != headType) &&
19964
0
                   (type != type->baseType)) {
19965
0
    if ((WXS_IS_EXTENSION(type)) &&
19966
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19967
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19968
19969
0
    if (WXS_IS_RESTRICTION(type) &&
19970
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19971
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19972
19973
0
    type = type->baseType;
19974
0
      }
19975
      /*
19976
      * The {prohibited substitutions} of all intermediate types +
19977
      * the head's type.
19978
      */
19979
0
      type = elemDecl->subtypes->baseType;
19980
0
      while (type != NULL) {
19981
0
    if (WXS_IS_COMPLEX(type)) {
19982
0
        if ((type->flags &
19983
0
          XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19984
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19985
0
        set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19986
0
        if ((type->flags &
19987
0
          XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19988
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19989
0
        set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19990
0
    } else
19991
0
        break;
19992
0
    if (type == headType)
19993
0
        break;
19994
0
    type = type->baseType;
19995
0
      }
19996
0
      if ((set != 0) &&
19997
0
    (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19998
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19999
0
    ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
20000
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
20001
0
    continue;
20002
0
      }
20003
0
add_member:
20004
0
      xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
20005
0
      if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
20006
0
    head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
20007
0
  }
20008
0
    }
20009
0
}
20010
20011
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
20012
/**
20013
 * xmlSchemaCheckElementDeclComponent
20014
 * @pctxt: the schema parser context
20015
 * @ctxtComponent: the context component (an element declaration)
20016
 * @ctxtParticle: the first particle of the context component
20017
 * @searchParticle: the element declaration particle to be analysed
20018
 *
20019
 * Schema Component Constraint: Element Declarations Consistent
20020
 */
20021
static int
20022
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
20023
            xmlSchemaBasicItemPtr ctxtComponent,
20024
            xmlSchemaParticlePtr ctxtParticle,
20025
            xmlSchemaParticlePtr searchParticle,
20026
            xmlSchemaParticlePtr curParticle,
20027
            int search)
20028
{
20029
    return(0);
20030
20031
    int ret = 0;
20032
    xmlSchemaParticlePtr cur = curParticle;
20033
    if (curParticle == NULL) {
20034
  return(0);
20035
    }
20036
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
20037
  /*
20038
  * Just return in this case. A missing "term" of the particle
20039
  * might arise due to an invalid "term" component.
20040
  */
20041
  return(0);
20042
    }
20043
    while (cur != NULL) {
20044
  switch (WXS_PARTICLE_TERM(cur)->type) {
20045
      case XML_SCHEMA_TYPE_ANY:
20046
    break;
20047
      case XML_SCHEMA_TYPE_ELEMENT:
20048
    if (search == 0) {
20049
        ret = xmlSchemaCheckElementDeclConsistent(pctxt,
20050
      ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
20051
        if (ret != 0)
20052
      return(ret);
20053
    } else {
20054
        xmlSchemaElementPtr elem =
20055
      WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
20056
        /*
20057
        * SPEC Element Declarations Consistent:
20058
        * "If the {particles} contains, either directly,
20059
        * indirectly (that is, within the {particles} of a
20060
        * contained model group, recursively) or `implicitly`
20061
        * two or more element declaration particles with
20062
        * the same {name} and {target namespace}, then
20063
        * all their type definitions must be the same
20064
        * top-level definition [...]"
20065
        */
20066
        if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
20067
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
20068
      xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
20069
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
20070
        {
20071
      xmlChar *strA = NULL, *strB = NULL;
20072
20073
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20074
          /* TODO: error code */
20075
          XML_SCHEMAP_COS_NONAMBIG,
20076
          WXS_ITEM_NODE(cur), NULL,
20077
          "In the content model of %s, there are multiple "
20078
          "element declarations for '%s' with different "
20079
          "type definitions",
20080
          xmlSchemaGetComponentDesignation(&strA,
20081
        ctxtComponent),
20082
          xmlSchemaFormatQName(&strB,
20083
        WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
20084
        WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
20085
      FREE_AND_NULL(strA);
20086
      FREE_AND_NULL(strB);
20087
      return(XML_SCHEMAP_COS_NONAMBIG);
20088
        }
20089
    }
20090
    break;
20091
      case XML_SCHEMA_TYPE_SEQUENCE: {
20092
    break;
20093
    }
20094
      case XML_SCHEMA_TYPE_CHOICE:{
20095
    /*
20096
    xmlSchemaTreeItemPtr sub;
20097
20098
    sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
20099
    while (sub != NULL) {
20100
        ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
20101
      ctxtParticle, ctxtElem);
20102
        if (ret != 0)
20103
      return(ret);
20104
        sub = sub->next;
20105
    }
20106
    */
20107
    break;
20108
    }
20109
      case XML_SCHEMA_TYPE_ALL:
20110
    break;
20111
      case XML_SCHEMA_TYPE_GROUP:
20112
    break;
20113
      default:
20114
    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
20115
        "xmlSchemaCheckElementDeclConsistent",
20116
        "found unexpected term of type '%s' in content model",
20117
        WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
20118
    return(-1);
20119
  }
20120
  cur = (xmlSchemaParticlePtr) cur->next;
20121
    }
20122
20123
exit:
20124
    return(ret);
20125
}
20126
#endif
20127
20128
/**
20129
 * xmlSchemaCheckElementDeclComponent
20130
 * @item:  an schema element declaration/particle
20131
 * @ctxt:  a schema parser context
20132
 * @name:  the name of the attribute
20133
 *
20134
 * Validates the value constraints of an element declaration.
20135
 * Adds substitution group members.
20136
 */
20137
static void
20138
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
20139
           xmlSchemaParserCtxtPtr ctxt)
20140
0
{
20141
0
    if (elemDecl == NULL)
20142
0
  return;
20143
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
20144
0
  return;
20145
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
20146
0
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
20147
  /*
20148
  * Adds substitution group members.
20149
  */
20150
0
  xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
20151
0
    }
20152
0
}
20153
20154
/**
20155
 * xmlSchemaResolveModelGroupParticleReferences:
20156
 * @particle:  a particle component
20157
 * @ctxt:  a parser context
20158
 *
20159
 * Resolves references of a model group's {particles} to
20160
 * model group definitions and to element declarations.
20161
 */
20162
static void
20163
xmlSchemaResolveModelGroupParticleReferences(
20164
    xmlSchemaParserCtxtPtr ctxt,
20165
    xmlSchemaModelGroupPtr mg)
20166
0
{
20167
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
20168
0
    xmlSchemaQNameRefPtr ref;
20169
0
    xmlSchemaBasicItemPtr refItem;
20170
20171
    /*
20172
    * URGENT TODO: Test this.
20173
    */
20174
0
    while (particle != NULL) {
20175
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
20176
0
      ((WXS_PARTICLE_TERM(particle))->type !=
20177
0
    XML_SCHEMA_EXTRA_QNAMEREF))
20178
0
  {
20179
0
      goto next_particle;
20180
0
  }
20181
0
  ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
20182
  /*
20183
  * Resolve the reference.
20184
  * NULL the {term} by default.
20185
  */
20186
0
  particle->children = NULL;
20187
20188
0
  refItem = xmlSchemaGetNamedComponent(ctxt->schema,
20189
0
      ref->itemType, ref->name, ref->targetNamespace);
20190
0
  if (refItem == NULL) {
20191
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
20192
0
    NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
20193
0
    ref->targetNamespace, ref->itemType, NULL);
20194
      /* TODO: remove the particle. */
20195
0
      goto next_particle;
20196
0
  }
20197
0
  if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
20198
0
      if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
20199
    /* TODO: remove the particle. */
20200
0
    goto next_particle;
20201
      /*
20202
      * NOTE that we will assign the model group definition
20203
      * itself to the "term" of the particle. This will ease
20204
      * the check for circular model group definitions. After
20205
      * that the "term" will be assigned the model group of the
20206
      * model group definition.
20207
      */
20208
0
      if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20209
0
        XML_SCHEMA_TYPE_ALL) {
20210
    /*
20211
    * SPEC cos-all-limited (1)
20212
    * SPEC cos-all-limited (1.2)
20213
    * "It appears only as the value of one or both of the
20214
    * following properties:"
20215
    * (1.1) "the {model group} property of a model group
20216
    *        definition."
20217
    * (1.2) "the {term} property of a particle [... of] the "
20218
    * {content type} of a complex type definition."
20219
    */
20220
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20221
        /* TODO: error code */
20222
0
        XML_SCHEMAP_COS_ALL_LIMITED,
20223
0
        WXS_ITEM_NODE(particle), NULL,
20224
0
        "A model group definition is referenced, but "
20225
0
        "it contains an 'all' model group, which "
20226
0
        "cannot be contained by model groups",
20227
0
        NULL, NULL);
20228
    /* TODO: remove the particle. */
20229
0
    goto next_particle;
20230
0
      }
20231
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20232
0
  } else {
20233
      /*
20234
      * TODO: Are referenced element declarations the only
20235
      * other components we expect here?
20236
      */
20237
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20238
0
  }
20239
0
next_particle:
20240
0
  particle = WXS_PTC_CAST particle->next;
20241
0
    }
20242
0
}
20243
20244
static int
20245
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20246
           xmlSchemaValPtr y)
20247
0
{
20248
0
    xmlSchemaTypePtr tx, ty, ptx, pty;
20249
0
    int ret;
20250
20251
0
    while (x != NULL) {
20252
  /* Same types. */
20253
0
  tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20254
0
  ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20255
0
  ptx = xmlSchemaGetPrimitiveType(tx);
20256
0
  pty = xmlSchemaGetPrimitiveType(ty);
20257
  /*
20258
  * (1) if a datatype T' is `derived` by `restriction` from an
20259
  * atomic datatype T then the `value space` of T' is a subset of
20260
  * the `value space` of T. */
20261
  /*
20262
  * (2) if datatypes T' and T'' are `derived` by `restriction`
20263
  * from a common atomic ancestor T then the `value space`s of T'
20264
  * and T'' may overlap.
20265
  */
20266
0
  if (ptx != pty)
20267
0
      return(0);
20268
  /*
20269
  * We assume computed values to be normalized, so do a fast
20270
  * string comparison for string based types.
20271
  */
20272
0
  if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20273
0
      WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20274
0
      if (! xmlStrEqual(
20275
0
    xmlSchemaValueGetAsString(x),
20276
0
    xmlSchemaValueGetAsString(y)))
20277
0
    return (0);
20278
0
  } else {
20279
0
      ret = xmlSchemaCompareValuesWhtsp(
20280
0
    x, XML_SCHEMA_WHITESPACE_PRESERVE,
20281
0
    y, XML_SCHEMA_WHITESPACE_PRESERVE);
20282
0
      if (ret == -2)
20283
0
    return(-1);
20284
0
      if (ret != 0)
20285
0
    return(0);
20286
0
  }
20287
  /*
20288
  * Lists.
20289
  */
20290
0
  x = xmlSchemaValueGetNext(x);
20291
0
  if (x != NULL) {
20292
0
      y = xmlSchemaValueGetNext(y);
20293
0
      if (y == NULL)
20294
0
    return (0);
20295
0
  } else if (xmlSchemaValueGetNext(y) != NULL)
20296
0
      return (0);
20297
0
  else
20298
0
      return (1);
20299
0
    }
20300
0
    return (0);
20301
0
}
20302
20303
/**
20304
 * xmlSchemaResolveAttrUseReferences:
20305
 * @item:  an attribute use
20306
 * @ctxt:  a parser context
20307
 *
20308
 * Resolves the referenced attribute declaration.
20309
 */
20310
static int
20311
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20312
          xmlSchemaParserCtxtPtr ctxt)
20313
0
{
20314
0
    if ((ctxt == NULL) || (ause == NULL))
20315
0
  return(-1);
20316
0
    if ((ause->attrDecl == NULL) ||
20317
0
  (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20318
0
  return(0);
20319
20320
0
    {
20321
0
  xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20322
20323
  /*
20324
  * TODO: Evaluate, what errors could occur if the declaration is not
20325
  * found.
20326
  */
20327
0
  ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20328
0
      ref->name, ref->targetNamespace);
20329
0
        if (ause->attrDecl == NULL) {
20330
0
      xmlSchemaPResCompAttrErr(ctxt,
20331
0
    XML_SCHEMAP_SRC_RESOLVE,
20332
0
    WXS_BASIC_CAST ause, ause->node,
20333
0
    "ref", ref->name, ref->targetNamespace,
20334
0
    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20335
0
            return(ctxt->err);;
20336
0
        }
20337
0
    }
20338
0
    return(0);
20339
0
}
20340
20341
/**
20342
 * xmlSchemaCheckAttrUsePropsCorrect:
20343
 * @ctxt:  a parser context
20344
 * @use:  an attribute use
20345
 *
20346
 * Schema Component Constraint:
20347
 * Attribute Use Correct (au-props-correct)
20348
 *
20349
 */
20350
static int
20351
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20352
           xmlSchemaAttributeUsePtr use)
20353
0
{
20354
0
    if ((ctxt == NULL) || (use == NULL))
20355
0
  return(-1);
20356
0
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20357
0
  ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20358
0
  return(0);
20359
20360
    /*
20361
    * SPEC au-props-correct (1)
20362
    * "The values of the properties of an attribute use must be as
20363
    * described in the property tableau in The Attribute Use Schema
20364
    * Component ($3.5.1), modulo the impact of Missing
20365
    * Sub-components ($5.3)."
20366
    */
20367
20368
0
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20369
0
  ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20370
0
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20371
0
    {
20372
0
  xmlSchemaPCustomErr(ctxt,
20373
0
      XML_SCHEMAP_AU_PROPS_CORRECT_2,
20374
0
      WXS_BASIC_CAST use, NULL,
20375
0
      "The attribute declaration has a 'fixed' value constraint "
20376
0
      ", thus the attribute use must also have a 'fixed' value "
20377
0
      "constraint",
20378
0
      NULL);
20379
0
  return(ctxt->err);
20380
0
    }
20381
    /*
20382
    * Compute and check the value constraint's value.
20383
    */
20384
0
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20385
0
  int ret;
20386
  /*
20387
  * TODO: The spec seems to be missing a check of the
20388
  * value constraint of the attribute use. We will do it here.
20389
  */
20390
  /*
20391
  * SPEC a-props-correct (3)
20392
  */
20393
0
  if (xmlSchemaIsDerivedFromBuiltInType(
20394
0
      WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20395
0
  {
20396
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20397
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20398
0
    NULL, WXS_BASIC_CAST use,
20399
0
    "Value constraints are not allowed if the type definition "
20400
0
    "is or is derived from xs:ID",
20401
0
    NULL, NULL);
20402
0
      return(ctxt->err);
20403
0
  }
20404
20405
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20406
0
      use->node, WXS_ATTRUSE_TYPEDEF(use),
20407
0
      use->defValue, &(use->defVal),
20408
0
      1, 1, 0);
20409
0
  if (ret != 0) {
20410
0
      if (ret < 0) {
20411
0
    PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20412
0
        "calling xmlSchemaVCheckCVCSimpleType()");
20413
0
    return(-1);
20414
0
      }
20415
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20416
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20417
0
    NULL, WXS_BASIC_CAST use,
20418
0
    "The value of the value constraint is not valid",
20419
0
    NULL, NULL);
20420
0
      return(ctxt->err);
20421
0
  }
20422
0
    }
20423
    /*
20424
    * SPEC au-props-correct (2)
20425
    * "If the {attribute declaration} has a fixed
20426
    * {value constraint}, then if the attribute use itself has a
20427
    * {value constraint}, it must also be fixed and its value must match
20428
    * that of the {attribute declaration}'s {value constraint}."
20429
    */
20430
0
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20431
0
  (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20432
0
    {
20433
0
  if (! xmlSchemaAreValuesEqual(use->defVal,
20434
0
    (WXS_ATTRUSE_DECL(use))->defVal))
20435
0
  {
20436
0
      xmlSchemaPCustomErr(ctxt,
20437
0
    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20438
0
    WXS_BASIC_CAST use, NULL,
20439
0
    "The 'fixed' value constraint of the attribute use "
20440
0
    "must match the attribute declaration's value "
20441
0
    "constraint '%s'",
20442
0
    (WXS_ATTRUSE_DECL(use))->defValue);
20443
0
  }
20444
0
  return(ctxt->err);
20445
0
    }
20446
0
    return(0);
20447
0
}
20448
20449
20450
20451
20452
/**
20453
 * xmlSchemaResolveAttrTypeReferences:
20454
 * @item:  an attribute declaration
20455
 * @ctxt:  a parser context
20456
 *
20457
 * Resolves the referenced type definition component.
20458
 */
20459
static int
20460
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20461
           xmlSchemaParserCtxtPtr ctxt)
20462
0
{
20463
    /*
20464
    * The simple type definition corresponding to the <simpleType> element
20465
    * information item in the [children], if present, otherwise the simple
20466
    * type definition `resolved` to by the `actual value` of the type
20467
    * [attribute], if present, otherwise the `simple ur-type definition`.
20468
    */
20469
0
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20470
0
  return(0);
20471
0
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20472
0
    if (item->subtypes != NULL)
20473
0
        return(0);
20474
0
    if (item->typeName != NULL) {
20475
0
        xmlSchemaTypePtr type;
20476
20477
0
  type = xmlSchemaGetType(ctxt->schema, item->typeName,
20478
0
      item->typeNs);
20479
0
  if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20480
0
      xmlSchemaPResCompAttrErr(ctxt,
20481
0
    XML_SCHEMAP_SRC_RESOLVE,
20482
0
    WXS_BASIC_CAST item, item->node,
20483
0
    "type", item->typeName, item->typeNs,
20484
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
20485
0
      return(ctxt->err);
20486
0
  } else
20487
0
      item->subtypes = type;
20488
20489
0
    } else {
20490
  /*
20491
  * The type defaults to the xs:anySimpleType.
20492
  */
20493
0
  item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20494
0
    }
20495
0
    return(0);
20496
0
}
20497
20498
/**
20499
 * xmlSchemaResolveIDCKeyReferences:
20500
 * @idc:  the identity-constraint definition
20501
 * @ctxt:  the schema parser context
20502
 * @name:  the attribute name
20503
 *
20504
 * Resolve keyRef references to key/unique IDCs.
20505
 * Schema Component Constraint:
20506
 *   Identity-constraint Definition Properties Correct (c-props-correct)
20507
 */
20508
static int
20509
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20510
        xmlSchemaParserCtxtPtr pctxt)
20511
0
{
20512
0
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20513
0
        return(0);
20514
0
    if (idc->ref->name != NULL) {
20515
0
  idc->ref->item = (xmlSchemaBasicItemPtr)
20516
0
      xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20517
0
    idc->ref->targetNamespace);
20518
0
        if (idc->ref->item == NULL) {
20519
      /*
20520
      * TODO: It is actually not an error to fail to resolve
20521
      * at this stage. BUT we need to be that strict!
20522
      */
20523
0
      xmlSchemaPResCompAttrErr(pctxt,
20524
0
    XML_SCHEMAP_SRC_RESOLVE,
20525
0
    WXS_BASIC_CAST idc, idc->node,
20526
0
    "refer", idc->ref->name,
20527
0
    idc->ref->targetNamespace,
20528
0
    XML_SCHEMA_TYPE_IDC_KEY, NULL);
20529
0
            return(pctxt->err);
20530
0
  } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20531
      /*
20532
      * SPEC c-props-correct (1)
20533
      */
20534
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20535
0
    XML_SCHEMAP_C_PROPS_CORRECT,
20536
0
    NULL, WXS_BASIC_CAST idc,
20537
0
    "The keyref references a keyref",
20538
0
    NULL, NULL);
20539
0
      idc->ref->item = NULL;
20540
0
      return(pctxt->err);
20541
0
  } else {
20542
0
      if (idc->nbFields !=
20543
0
    ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20544
0
    xmlChar *str = NULL;
20545
0
    xmlSchemaIDCPtr refer;
20546
20547
0
    refer = (xmlSchemaIDCPtr) idc->ref->item;
20548
    /*
20549
    * SPEC c-props-correct(2)
20550
    * "If the {identity-constraint category} is keyref,
20551
    * the cardinality of the {fields} must equal that of
20552
    * the {fields} of the {referenced key}.
20553
    */
20554
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20555
0
        XML_SCHEMAP_C_PROPS_CORRECT,
20556
0
        NULL, WXS_BASIC_CAST idc,
20557
0
        "The cardinality of the keyref differs from the "
20558
0
        "cardinality of the referenced key/unique '%s'",
20559
0
        xmlSchemaFormatQName(&str, refer->targetNamespace,
20560
0
      refer->name),
20561
0
        NULL);
20562
0
    FREE_AND_NULL(str)
20563
0
    return(pctxt->err);
20564
0
      }
20565
0
  }
20566
0
    }
20567
0
    return(0);
20568
0
}
20569
20570
static int
20571
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20572
               xmlSchemaParserCtxtPtr pctxt)
20573
0
{
20574
0
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20575
0
  prohib->targetNamespace) == NULL) {
20576
20577
0
  xmlSchemaPResCompAttrErr(pctxt,
20578
0
      XML_SCHEMAP_SRC_RESOLVE,
20579
0
      NULL, prohib->node,
20580
0
      "ref", prohib->name, prohib->targetNamespace,
20581
0
      XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20582
0
  return(XML_SCHEMAP_SRC_RESOLVE);
20583
0
    }
20584
0
    return(0);
20585
0
}
20586
20587
0
#define WXS_REDEFINED_TYPE(c) \
20588
0
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20589
20590
0
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20591
0
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20592
20593
0
#define WXS_REDEFINED_ATTR_GROUP(c) \
20594
0
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20595
20596
static int
20597
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20598
0
{
20599
0
    int err = 0;
20600
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20601
0
    xmlSchemaBasicItemPtr prev, item;
20602
0
    int wasRedefined;
20603
20604
0
    if (redef == NULL)
20605
0
  return(0);
20606
20607
0
    do {
20608
0
  item = redef->item;
20609
  /*
20610
  * First try to locate the redefined component in the
20611
  * schema graph starting with the redefined schema.
20612
  * NOTE: According to this schema bug entry:
20613
  *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20614
  *   it's not clear if the referenced component needs to originate
20615
  *   from the <redefine>d schema _document_ or the schema; the latter
20616
  *   would include all imported and included sub-schemas of the
20617
  *   <redefine>d schema. Currently the latter approach is used.
20618
  *   SUPPLEMENT: It seems that the WG moves towards the latter
20619
  *   approach, so we are doing it right.
20620
  *
20621
  */
20622
0
  prev = xmlSchemaFindRedefCompInGraph(
20623
0
      redef->targetBucket, item->type,
20624
0
      redef->refName, redef->refTargetNs);
20625
0
  if (prev == NULL) {
20626
0
      xmlChar *str = NULL;
20627
0
      xmlNodePtr node;
20628
20629
      /*
20630
      * SPEC src-redefine:
20631
      * (6.2.1) "The `actual value` of its own name attribute plus
20632
      * target namespace must successfully `resolve` to a model
20633
      * group definition in I."
20634
      * (7.2.1) "The `actual value` of its own name attribute plus
20635
      * target namespace must successfully `resolve` to an attribute
20636
      * group definition in I."
20637
20638
      *
20639
      * Note that, if we are redefining with the use of references
20640
      * to components, the spec assumes the src-resolve to be used;
20641
      * but this won't assure that we search only *inside* the
20642
      * redefined schema.
20643
      */
20644
0
      if (redef->reference)
20645
0
    node = WXS_ITEM_NODE(redef->reference);
20646
0
      else
20647
0
    node = WXS_ITEM_NODE(item);
20648
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20649
    /*
20650
    * TODO: error code.
20651
    * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20652
    * reference kind.
20653
    */
20654
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20655
0
    "The %s '%s' to be redefined could not be found in "
20656
0
    "the redefined schema",
20657
0
    WXS_ITEM_TYPE_NAME(item),
20658
0
    xmlSchemaFormatQName(&str, redef->refTargetNs,
20659
0
        redef->refName));
20660
0
      FREE_AND_NULL(str);
20661
0
      err = pctxt->err;
20662
0
      redef = redef->next;
20663
0
      continue;
20664
0
  }
20665
  /*
20666
  * TODO: Obtaining and setting the redefinition state is really
20667
  * clumsy.
20668
  */
20669
0
  wasRedefined = 0;
20670
0
  switch (item->type) {
20671
0
      case XML_SCHEMA_TYPE_COMPLEX:
20672
0
      case XML_SCHEMA_TYPE_SIMPLE:
20673
0
    if ((WXS_TYPE_CAST prev)->flags &
20674
0
        XML_SCHEMAS_TYPE_REDEFINED)
20675
0
    {
20676
0
        wasRedefined = 1;
20677
0
        break;
20678
0
    }
20679
    /* Mark it as redefined. */
20680
0
    (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20681
    /*
20682
    * Assign the redefined type to the
20683
    * base type of the redefining type.
20684
    * TODO: How
20685
    */
20686
0
    ((xmlSchemaTypePtr) item)->baseType =
20687
0
        (xmlSchemaTypePtr) prev;
20688
0
    break;
20689
0
      case XML_SCHEMA_TYPE_GROUP:
20690
0
    if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20691
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20692
0
    {
20693
0
        wasRedefined = 1;
20694
0
        break;
20695
0
    }
20696
    /* Mark it as redefined. */
20697
0
    (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20698
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20699
0
    if (redef->reference != NULL) {
20700
        /*
20701
        * Overwrite the QName-reference with the
20702
        * referenced model group def.
20703
        */
20704
0
        (WXS_PTC_CAST redef->reference)->children =
20705
0
      WXS_TREE_CAST prev;
20706
0
    }
20707
0
    redef->target = prev;
20708
0
    break;
20709
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20710
0
    if ((WXS_ATTR_GROUP_CAST prev)->flags &
20711
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED)
20712
0
    {
20713
0
        wasRedefined = 1;
20714
0
        break;
20715
0
    }
20716
0
    (WXS_ATTR_GROUP_CAST prev)->flags |=
20717
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED;
20718
0
    if (redef->reference != NULL) {
20719
        /*
20720
        * Assign the redefined attribute group to the
20721
        * QName-reference component.
20722
        * This is the easy case, since we will just
20723
        * expand the redefined group.
20724
        */
20725
0
        (WXS_QNAME_CAST redef->reference)->item = prev;
20726
0
        redef->target = NULL;
20727
0
    } else {
20728
        /*
20729
        * This is the complicated case: we need
20730
        * to apply src-redefine (7.2.2) at a later
20731
        * stage, i.e. when attribute group references
20732
        * have been expanded and simple types have
20733
        * been fixed.
20734
        */
20735
0
        redef->target = prev;
20736
0
    }
20737
0
    break;
20738
0
      default:
20739
0
    PERROR_INT("xmlSchemaResolveRedefReferences",
20740
0
        "Unexpected redefined component type");
20741
0
    return(-1);
20742
0
  }
20743
0
  if (wasRedefined) {
20744
0
      xmlChar *str = NULL;
20745
0
      xmlNodePtr node;
20746
20747
0
      if (redef->reference)
20748
0
    node = WXS_ITEM_NODE(redef->reference);
20749
0
      else
20750
0
    node = WXS_ITEM_NODE(redef->item);
20751
20752
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20753
    /* TODO: error code. */
20754
0
    XML_SCHEMAP_SRC_REDEFINE,
20755
0
    node, NULL,
20756
0
    "The referenced %s was already redefined. Multiple "
20757
0
    "redefinition of the same component is not supported",
20758
0
    xmlSchemaGetComponentDesignation(&str, prev),
20759
0
    NULL);
20760
0
      FREE_AND_NULL(str)
20761
0
      err = pctxt->err;
20762
0
      redef = redef->next;
20763
0
      continue;
20764
0
  }
20765
0
  redef = redef->next;
20766
0
    } while (redef != NULL);
20767
20768
0
    return(err);
20769
0
}
20770
20771
static int
20772
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20773
0
{
20774
0
    int err = 0;
20775
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20776
0
    xmlSchemaBasicItemPtr item;
20777
20778
0
    if (redef == NULL)
20779
0
  return(0);
20780
20781
0
    do {
20782
0
  if (redef->target == NULL) {
20783
0
      redef = redef->next;
20784
0
      continue;
20785
0
  }
20786
0
  item = redef->item;
20787
20788
0
  switch (item->type) {
20789
0
      case XML_SCHEMA_TYPE_SIMPLE:
20790
0
      case XML_SCHEMA_TYPE_COMPLEX:
20791
    /*
20792
    * Since the spec wants the {name} of the redefined
20793
    * type to be 'absent', we'll NULL it.
20794
    */
20795
0
    (WXS_TYPE_CAST redef->target)->name = NULL;
20796
20797
    /*
20798
    * TODO: Seems like there's nothing more to do. The normal
20799
    * inheritance mechanism is used. But not 100% sure.
20800
    */
20801
0
    break;
20802
0
      case XML_SCHEMA_TYPE_GROUP:
20803
    /*
20804
    * URGENT TODO:
20805
    * SPEC src-redefine:
20806
    * (6.2.2) "The {model group} of the model group definition
20807
    * which corresponds to it per XML Representation of Model
20808
    * Group Definition Schema Components ($3.7.2) must be a
20809
    * `valid restriction` of the {model group} of that model
20810
    * group definition in I, as defined in Particle Valid
20811
    * (Restriction) ($3.9.6)."
20812
    */
20813
0
    break;
20814
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20815
    /*
20816
    * SPEC src-redefine:
20817
    * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20818
    * the attribute group definition which corresponds to it
20819
    * per XML Representation of Attribute Group Definition Schema
20820
    * Components ($3.6.2) must be `valid restrictions` of the
20821
    * {attribute uses} and {attribute wildcard} of that attribute
20822
    * group definition in I, as defined in clause 2, clause 3 and
20823
    * clause 4 of Derivation Valid (Restriction, Complex)
20824
    * ($3.4.6) (where references to the base type definition are
20825
    * understood as references to the attribute group definition
20826
    * in I)."
20827
    */
20828
0
    err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20829
0
        XML_SCHEMA_ACTION_REDEFINE,
20830
0
        item, redef->target,
20831
0
        (WXS_ATTR_GROUP_CAST item)->attrUses,
20832
0
        (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20833
0
        (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20834
0
        (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20835
0
    if (err == -1)
20836
0
        return(-1);
20837
0
    break;
20838
0
      default:
20839
0
    break;
20840
0
  }
20841
0
  redef = redef->next;
20842
0
    } while (redef != NULL);
20843
0
    return(0);
20844
0
}
20845
20846
20847
static int
20848
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20849
           xmlSchemaBucketPtr bucket)
20850
0
{
20851
0
    xmlSchemaBasicItemPtr item;
20852
0
    int err;
20853
0
    xmlHashTablePtr *table;
20854
0
    const xmlChar *name;
20855
0
    int i;
20856
20857
0
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20858
0
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20859
0
  table = &(WXS_IMPBUCKET((c))->schema->slot); \
20860
0
    else \
20861
0
  table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20862
20863
    /*
20864
    * Add global components to the schema's hash tables.
20865
    * This is the place where duplicate components will be
20866
    * detected.
20867
    * TODO: I think normally we should support imports of the
20868
    *   same namespace from multiple locations. We don't do currently,
20869
    *   but if we do then according to:
20870
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20871
    *   we would need, if imported directly, to import redefined
20872
    *   components as well to be able to catch clashing components.
20873
    *   (I hope I'll still know what this means after some months :-()
20874
    */
20875
0
    if (bucket == NULL)
20876
0
  return(-1);
20877
0
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20878
0
  return(0);
20879
0
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20880
20881
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
20882
0
  item = bucket->globals->items[i];
20883
0
  table = NULL;
20884
0
  switch (item->type) {
20885
0
      case XML_SCHEMA_TYPE_COMPLEX:
20886
0
      case XML_SCHEMA_TYPE_SIMPLE:
20887
0
    if (WXS_REDEFINED_TYPE(item))
20888
0
        continue;
20889
0
    name = (WXS_TYPE_CAST item)->name;
20890
0
    WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20891
0
    break;
20892
0
      case XML_SCHEMA_TYPE_ELEMENT:
20893
0
    name = (WXS_ELEM_CAST item)->name;
20894
0
    WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20895
0
    break;
20896
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20897
0
    name = (WXS_ATTR_CAST item)->name;
20898
0
    WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20899
0
    break;
20900
0
      case XML_SCHEMA_TYPE_GROUP:
20901
0
    if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20902
0
        continue;
20903
0
    name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20904
0
    WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20905
0
    break;
20906
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20907
0
    if (WXS_REDEFINED_ATTR_GROUP(item))
20908
0
        continue;
20909
0
    name = (WXS_ATTR_GROUP_CAST item)->name;
20910
0
    WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20911
0
    break;
20912
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20913
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20914
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20915
0
    name = (WXS_IDC_CAST item)->name;
20916
0
    WXS_GET_GLOBAL_HASH(bucket, idcDef)
20917
0
    break;
20918
0
      case XML_SCHEMA_TYPE_NOTATION:
20919
0
    name = ((xmlSchemaNotationPtr) item)->name;
20920
0
    WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20921
0
    break;
20922
0
      default:
20923
0
    PERROR_INT("xmlSchemaAddComponents",
20924
0
        "Unexpected global component type");
20925
0
    continue;
20926
0
  }
20927
0
  if (*table == NULL) {
20928
0
      *table = xmlHashCreateDict(10, pctxt->dict);
20929
0
      if (*table == NULL) {
20930
0
    PERROR_INT("xmlSchemaAddComponents",
20931
0
        "failed to create a component hash table");
20932
0
    return(-1);
20933
0
      }
20934
0
  }
20935
0
  err = xmlHashAddEntry(*table, name, item);
20936
0
  if (err != 0) {
20937
0
      xmlChar *str = NULL;
20938
20939
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20940
0
    XML_SCHEMAP_REDEFINED_TYPE,
20941
0
    WXS_ITEM_NODE(item),
20942
0
    WXS_BASIC_CAST item,
20943
0
    "A global %s '%s' does already exist",
20944
0
    WXS_ITEM_TYPE_NAME(item),
20945
0
    xmlSchemaGetComponentQName(&str, item));
20946
0
      FREE_AND_NULL(str);
20947
0
  }
20948
0
    }
20949
    /*
20950
    * Process imported/included schemas.
20951
    */
20952
0
    if (bucket->relations != NULL) {
20953
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
20954
0
  do {
20955
0
      if ((rel->bucket != NULL) &&
20956
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20957
0
    if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20958
0
        return(-1);
20959
0
      }
20960
0
      rel = rel->next;
20961
0
  } while (rel != NULL);
20962
0
    }
20963
0
    return(0);
20964
0
}
20965
20966
static int
20967
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20968
       xmlSchemaBucketPtr rootBucket)
20969
0
{
20970
0
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20971
0
    xmlSchemaTreeItemPtr item, *items;
20972
0
    int nbItems, i, ret = 0;
20973
0
    xmlSchemaBucketPtr oldbucket = con->bucket;
20974
0
    xmlSchemaElementPtr elemDecl;
20975
20976
0
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20977
20978
0
    if ((con->pending == NULL) ||
20979
0
  (con->pending->nbItems == 0))
20980
0
  return(0);
20981
20982
    /*
20983
    * Since xmlSchemaFixupComplexType() will create new particles
20984
    * (local components), and those particle components need a bucket
20985
    * on the constructor, we'll assure here that the constructor has
20986
    * a bucket.
20987
    * TODO: Think about storing locals _only_ on the main bucket.
20988
    */
20989
0
    if (con->bucket == NULL)
20990
0
  con->bucket = rootBucket;
20991
20992
    /* TODO:
20993
    * SPEC (src-redefine):
20994
    * (6.2) "If it has no such self-reference, then all of the
20995
    * following must be true:"
20996
20997
    * (6.2.2) The {model group} of the model group definition which
20998
    * corresponds to it per XML Representation of Model Group
20999
    * Definition Schema Components ($3.7.2) must be a `valid
21000
    * restriction` of the {model group} of that model group definition
21001
    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
21002
    */
21003
0
    xmlSchemaCheckSRCRedefineFirst(pctxt);
21004
21005
    /*
21006
    * Add global components to the schemata's hash tables.
21007
    */
21008
0
    xmlSchemaAddComponents(pctxt, rootBucket);
21009
21010
0
    pctxt->ctxtType = NULL;
21011
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
21012
0
    nbItems = con->pending->nbItems;
21013
    /*
21014
    * Now that we have parsed *all* the schema document(s) and converted
21015
    * them to schema components, we can resolve references, apply component
21016
    * constraints, create the FSA from the content model, etc.
21017
    */
21018
    /*
21019
    * Resolve references of..
21020
    *
21021
    * 1. element declarations:
21022
    *   - the type definition
21023
    *   - the substitution group affiliation
21024
    * 2. simple/complex types:
21025
    *   - the base type definition
21026
    *   - the memberTypes of union types
21027
    *   - the itemType of list types
21028
    * 3. attributes declarations and attribute uses:
21029
    *   - the type definition
21030
    *   - if an attribute use, then the attribute declaration
21031
    * 4. attribute group references:
21032
    *   - the attribute group definition
21033
    * 5. particles:
21034
    *   - the term of the particle (e.g. a model group)
21035
    * 6. IDC key-references:
21036
    *   - the referenced IDC 'key' or 'unique' definition
21037
    * 7. Attribute prohibitions which had a "ref" attribute.
21038
    */
21039
0
    for (i = 0; i < nbItems; i++) {
21040
0
  item = items[i];
21041
0
  switch (item->type) {
21042
0
      case XML_SCHEMA_TYPE_ELEMENT:
21043
0
    xmlSchemaResolveElementReferences(
21044
0
        (xmlSchemaElementPtr) item, pctxt);
21045
0
    FIXHFAILURE;
21046
0
    break;
21047
0
      case XML_SCHEMA_TYPE_COMPLEX:
21048
0
      case XML_SCHEMA_TYPE_SIMPLE:
21049
0
    xmlSchemaResolveTypeReferences(
21050
0
        (xmlSchemaTypePtr) item, pctxt);
21051
0
    FIXHFAILURE;
21052
0
    break;
21053
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21054
0
    xmlSchemaResolveAttrTypeReferences(
21055
0
        (xmlSchemaAttributePtr) item, pctxt);
21056
0
    FIXHFAILURE;
21057
0
    break;
21058
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21059
0
    xmlSchemaResolveAttrUseReferences(
21060
0
        (xmlSchemaAttributeUsePtr) item, pctxt);
21061
0
    FIXHFAILURE;
21062
0
    break;
21063
0
      case XML_SCHEMA_EXTRA_QNAMEREF:
21064
0
    if ((WXS_QNAME_CAST item)->itemType ==
21065
0
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
21066
0
    {
21067
0
        xmlSchemaResolveAttrGroupReferences(
21068
0
      WXS_QNAME_CAST item, pctxt);
21069
0
    }
21070
0
    FIXHFAILURE;
21071
0
    break;
21072
0
      case XML_SCHEMA_TYPE_SEQUENCE:
21073
0
      case XML_SCHEMA_TYPE_CHOICE:
21074
0
      case XML_SCHEMA_TYPE_ALL:
21075
0
    xmlSchemaResolveModelGroupParticleReferences(pctxt,
21076
0
        WXS_MODEL_GROUP_CAST item);
21077
0
    FIXHFAILURE;
21078
0
    break;
21079
0
      case XML_SCHEMA_TYPE_IDC_KEY:
21080
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
21081
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
21082
0
    xmlSchemaResolveIDCKeyReferences(
21083
0
        (xmlSchemaIDCPtr) item, pctxt);
21084
0
    FIXHFAILURE;
21085
0
    break;
21086
0
      case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
21087
    /*
21088
    * Handle attribute prohibition which had a
21089
    * "ref" attribute.
21090
    */
21091
0
    xmlSchemaResolveAttrUseProhibReferences(
21092
0
        WXS_ATTR_PROHIB_CAST item, pctxt);
21093
0
    FIXHFAILURE;
21094
0
    break;
21095
0
      default:
21096
0
    break;
21097
0
  }
21098
0
    }
21099
0
    if (pctxt->nberrors != 0)
21100
0
  goto exit_error;
21101
21102
    /*
21103
    * Now that all references are resolved we
21104
    * can check for circularity of...
21105
    * 1. the base axis of type definitions
21106
    * 2. nested model group definitions
21107
    * 3. nested attribute group definitions
21108
    * TODO: check for circular substitution groups.
21109
    */
21110
0
    for (i = 0; i < nbItems; i++) {
21111
0
  item = items[i];
21112
  /*
21113
  * Let's better stop on the first error here.
21114
  */
21115
0
  switch (item->type) {
21116
0
      case XML_SCHEMA_TYPE_COMPLEX:
21117
0
      case XML_SCHEMA_TYPE_SIMPLE:
21118
0
    xmlSchemaCheckTypeDefCircular(
21119
0
        (xmlSchemaTypePtr) item, pctxt);
21120
0
    FIXHFAILURE;
21121
0
    if (pctxt->nberrors != 0)
21122
0
        goto exit_error;
21123
0
    break;
21124
0
      case XML_SCHEMA_TYPE_GROUP:
21125
0
    xmlSchemaCheckGroupDefCircular(
21126
0
        (xmlSchemaModelGroupDefPtr) item, pctxt);
21127
0
    FIXHFAILURE;
21128
0
    if (pctxt->nberrors != 0)
21129
0
        goto exit_error;
21130
0
    break;
21131
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21132
0
    xmlSchemaCheckAttrGroupCircular(
21133
0
        (xmlSchemaAttributeGroupPtr) item, pctxt);
21134
0
    FIXHFAILURE;
21135
0
    if (pctxt->nberrors != 0)
21136
0
        goto exit_error;
21137
0
    break;
21138
0
      default:
21139
0
    break;
21140
0
  }
21141
0
    }
21142
0
    if (pctxt->nberrors != 0)
21143
0
  goto exit_error;
21144
    /*
21145
    * Model group definition references:
21146
    * Such a reference is reflected by a particle at the component
21147
    * level. Until now the 'term' of such particles pointed
21148
    * to the model group definition; this was done, in order to
21149
    * ease circularity checks. Now we need to set the 'term' of
21150
    * such particles to the model group of the model group definition.
21151
    */
21152
0
    for (i = 0; i < nbItems; i++) {
21153
0
  item = items[i];
21154
0
  switch (item->type) {
21155
0
      case XML_SCHEMA_TYPE_SEQUENCE:
21156
0
      case XML_SCHEMA_TYPE_CHOICE:
21157
0
    xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
21158
0
        WXS_MODEL_GROUP_CAST item);
21159
0
    break;
21160
0
      default:
21161
0
    break;
21162
0
  }
21163
0
    }
21164
0
    if (pctxt->nberrors != 0)
21165
0
  goto exit_error;
21166
    /*
21167
    * Expand attribute group references of attribute group definitions.
21168
    */
21169
0
    for (i = 0; i < nbItems; i++) {
21170
0
  item = items[i];
21171
0
  switch (item->type) {
21172
0
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21173
0
    if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
21174
0
        WXS_ATTR_GROUP_HAS_REFS(item))
21175
0
    {
21176
0
        xmlSchemaAttributeGroupExpandRefs(pctxt,
21177
0
      WXS_ATTR_GROUP_CAST item);
21178
0
        FIXHFAILURE;
21179
0
    }
21180
0
    break;
21181
0
      default:
21182
0
    break;
21183
0
  }
21184
0
    }
21185
0
    if (pctxt->nberrors != 0)
21186
0
  goto exit_error;
21187
    /*
21188
    * First compute the variety of simple types. This is needed as
21189
    * a separate step, since otherwise we won't be able to detect
21190
    * circular union types in all cases.
21191
    */
21192
0
    for (i = 0; i < nbItems; i++) {
21193
0
  item = items[i];
21194
0
  switch (item->type) {
21195
0
            case XML_SCHEMA_TYPE_SIMPLE:
21196
0
    if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
21197
0
        xmlSchemaFixupSimpleTypeStageOne(pctxt,
21198
0
      (xmlSchemaTypePtr) item);
21199
0
        FIXHFAILURE;
21200
0
    }
21201
0
    break;
21202
0
      default:
21203
0
    break;
21204
0
  }
21205
0
    }
21206
0
    if (pctxt->nberrors != 0)
21207
0
  goto exit_error;
21208
    /*
21209
    * Detect circular union types. Note that this needs the variety to
21210
    * be already computed.
21211
    */
21212
0
    for (i = 0; i < nbItems; i++) {
21213
0
  item = items[i];
21214
0
  switch (item->type) {
21215
0
            case XML_SCHEMA_TYPE_SIMPLE:
21216
0
    if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21217
0
        xmlSchemaCheckUnionTypeDefCircular(pctxt,
21218
0
      (xmlSchemaTypePtr) item);
21219
0
        FIXHFAILURE;
21220
0
    }
21221
0
    break;
21222
0
      default:
21223
0
    break;
21224
0
  }
21225
0
    }
21226
0
    if (pctxt->nberrors != 0)
21227
0
  goto exit_error;
21228
21229
    /*
21230
    * Do the complete type fixup for simple types.
21231
    */
21232
0
    for (i = 0; i < nbItems; i++) {
21233
0
  item = items[i];
21234
0
  switch (item->type) {
21235
0
            case XML_SCHEMA_TYPE_SIMPLE:
21236
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21237
0
        xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21238
0
        FIXHFAILURE;
21239
0
    }
21240
0
    break;
21241
0
      default:
21242
0
    break;
21243
0
  }
21244
0
    }
21245
0
    if (pctxt->nberrors != 0)
21246
0
  goto exit_error;
21247
    /*
21248
    * At this point we need build and check all simple types.
21249
    */
21250
    /*
21251
    * Apply constraints for attribute declarations.
21252
    */
21253
0
    for (i = 0; i < nbItems; i++) {
21254
0
  item = items[i];
21255
0
  switch (item->type) {
21256
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21257
0
    xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21258
0
    FIXHFAILURE;
21259
0
    break;
21260
0
      default:
21261
0
    break;
21262
0
  }
21263
0
    }
21264
0
    if (pctxt->nberrors != 0)
21265
0
  goto exit_error;
21266
    /*
21267
    * Apply constraints for attribute uses.
21268
    */
21269
0
    for (i = 0; i < nbItems; i++) {
21270
0
  item = items[i];
21271
0
  switch (item->type) {
21272
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21273
0
    if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21274
0
        xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21275
0
      WXS_ATTR_USE_CAST item);
21276
0
        FIXHFAILURE;
21277
0
    }
21278
0
    break;
21279
0
      default:
21280
0
    break;
21281
0
  }
21282
0
    }
21283
0
    if (pctxt->nberrors != 0)
21284
0
  goto exit_error;
21285
21286
    /*
21287
    * Apply constraints for attribute group definitions.
21288
    */
21289
0
    for (i = 0; i < nbItems; i++) {
21290
0
  item = items[i];
21291
0
  switch (item->type) {
21292
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21293
0
      if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21294
0
    ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21295
0
      {
21296
0
    xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21297
0
    FIXHFAILURE;
21298
0
      }
21299
0
      break;
21300
0
  default:
21301
0
      break;
21302
0
  }
21303
0
    }
21304
0
    if (pctxt->nberrors != 0)
21305
0
  goto exit_error;
21306
21307
    /*
21308
    * Apply constraints for redefinitions.
21309
    */
21310
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21311
0
  xmlSchemaCheckSRCRedefineSecond(pctxt);
21312
0
    if (pctxt->nberrors != 0)
21313
0
  goto exit_error;
21314
21315
    /*
21316
    * Complex types are built and checked.
21317
    */
21318
0
    for (i = 0; i < nbItems; i++) {
21319
0
  item = con->pending->items[i];
21320
0
  switch (item->type) {
21321
0
      case XML_SCHEMA_TYPE_COMPLEX:
21322
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21323
0
        xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21324
0
        FIXHFAILURE;
21325
0
    }
21326
0
    break;
21327
0
      default:
21328
0
    break;
21329
0
  }
21330
0
    }
21331
0
    if (pctxt->nberrors != 0)
21332
0
  goto exit_error;
21333
21334
    /*
21335
    * The list could have changed, since xmlSchemaFixupComplexType()
21336
    * will create particles and model groups in some cases.
21337
    */
21338
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
21339
0
    nbItems = con->pending->nbItems;
21340
21341
    /*
21342
    * Apply some constraints for element declarations.
21343
    */
21344
0
    for (i = 0; i < nbItems; i++) {
21345
0
  item = items[i];
21346
0
  switch (item->type) {
21347
0
      case XML_SCHEMA_TYPE_ELEMENT:
21348
0
    elemDecl = (xmlSchemaElementPtr) item;
21349
21350
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21351
0
    {
21352
0
        xmlSchemaCheckElementDeclComponent(
21353
0
      (xmlSchemaElementPtr) elemDecl, pctxt);
21354
0
        FIXHFAILURE;
21355
0
    }
21356
21357
#ifdef WXS_ELEM_DECL_CONS_ENABLED
21358
    /*
21359
    * Schema Component Constraint: Element Declarations Consistent
21360
    * Apply this constraint to local types of element declarations.
21361
    */
21362
    if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21363
        (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21364
        (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21365
    {
21366
        xmlSchemaCheckElementDeclConsistent(pctxt,
21367
      WXS_BASIC_CAST elemDecl,
21368
      WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21369
      NULL, NULL, 0);
21370
    }
21371
#endif
21372
0
    break;
21373
0
      default:
21374
0
    break;
21375
0
  }
21376
0
    }
21377
0
    if (pctxt->nberrors != 0)
21378
0
  goto exit_error;
21379
21380
    /*
21381
    * Finally we can build the automaton from the content model of
21382
    * complex types.
21383
    */
21384
21385
0
    for (i = 0; i < nbItems; i++) {
21386
0
  item = items[i];
21387
0
  switch (item->type) {
21388
0
      case XML_SCHEMA_TYPE_COMPLEX:
21389
0
    xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21390
    /* FIXHFAILURE; */
21391
0
    break;
21392
0
      default:
21393
0
    break;
21394
0
  }
21395
0
    }
21396
0
    if (pctxt->nberrors != 0)
21397
0
  goto exit_error;
21398
    /*
21399
    * URGENT TODO: cos-element-consistent
21400
    */
21401
0
    goto exit;
21402
21403
0
exit_error:
21404
0
    ret = pctxt->err;
21405
0
    goto exit;
21406
21407
0
exit_failure:
21408
0
    ret = -1;
21409
21410
0
exit:
21411
    /*
21412
    * Reset the constructor. This is needed for XSI acquisition, since
21413
    * those items will be processed over and over again for every XSI
21414
    * if not cleared here.
21415
    */
21416
0
    con->bucket = oldbucket;
21417
0
    con->pending->nbItems = 0;
21418
0
    if (con->substGroups != NULL) {
21419
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21420
0
  con->substGroups = NULL;
21421
0
    }
21422
0
    if (con->redefs != NULL) {
21423
0
  xmlSchemaRedefListFree(con->redefs);
21424
0
  con->redefs = NULL;
21425
0
    }
21426
0
    return(ret);
21427
0
}
21428
/**
21429
 * xmlSchemaParse:
21430
 * @ctxt:  a schema validation context
21431
 *
21432
 * parse a schema definition resource and build an internal
21433
 * XML Schema structure which can be used to validate instances.
21434
 *
21435
 * Returns the internal XML Schema structure built from the resource or
21436
 *         NULL in case of error
21437
 */
21438
xmlSchemaPtr
21439
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21440
0
{
21441
0
    xmlSchemaPtr mainSchema = NULL;
21442
0
    xmlSchemaBucketPtr bucket = NULL;
21443
0
    int res;
21444
21445
    /*
21446
    * This one is used if the schema to be parsed was specified via
21447
    * the API; i.e. not automatically by the validated instance document.
21448
    */
21449
21450
0
    xmlSchemaInitTypes();
21451
21452
0
    if (ctxt == NULL)
21453
0
        return (NULL);
21454
21455
    /* TODO: Init the context. Is this all we need?*/
21456
0
    ctxt->nberrors = 0;
21457
0
    ctxt->err = 0;
21458
0
    ctxt->counter = 0;
21459
21460
    /* Create the *main* schema. */
21461
0
    mainSchema = xmlSchemaNewSchema(ctxt);
21462
0
    if (mainSchema == NULL)
21463
0
  goto exit_failure;
21464
    /*
21465
    * Create the schema constructor.
21466
    */
21467
0
    if (ctxt->constructor == NULL) {
21468
0
  ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21469
0
  if (ctxt->constructor == NULL)
21470
0
      return(NULL);
21471
  /* Take ownership of the constructor to be able to free it. */
21472
0
  ctxt->ownsConstructor = 1;
21473
0
    }
21474
0
    ctxt->constructor->mainSchema = mainSchema;
21475
    /*
21476
    * Locate and add the schema document.
21477
    */
21478
0
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21479
0
  ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21480
0
  NULL, NULL, &bucket);
21481
0
    if (res == -1)
21482
0
  goto exit_failure;
21483
0
    if (res != 0)
21484
0
  goto exit;
21485
21486
0
    if (bucket == NULL) {
21487
  /* TODO: Error code, actually we failed to *locate* the schema. */
21488
0
  if (ctxt->URL)
21489
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21490
0
    NULL, NULL,
21491
0
    "Failed to locate the main schema resource at '%s'",
21492
0
    ctxt->URL, NULL);
21493
0
  else
21494
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21495
0
    NULL, NULL,
21496
0
    "Failed to locate the main schema resource",
21497
0
        NULL, NULL);
21498
0
  goto exit;
21499
0
    }
21500
    /* Then do the parsing for good. */
21501
0
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21502
0
  goto exit_failure;
21503
0
    if (ctxt->nberrors != 0)
21504
0
  goto exit;
21505
21506
0
    mainSchema->doc = bucket->doc;
21507
0
    mainSchema->preserve = ctxt->preserve;
21508
21509
0
    ctxt->schema = mainSchema;
21510
21511
0
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21512
0
  goto exit_failure;
21513
21514
    /*
21515
    * TODO: This is not nice, since we cannot distinguish from the
21516
    * result if there was an internal error or not.
21517
    */
21518
0
exit:
21519
0
    if (ctxt->nberrors != 0) {
21520
0
  if (mainSchema) {
21521
0
      xmlSchemaFree(mainSchema);
21522
0
      mainSchema = NULL;
21523
0
  }
21524
0
  if (ctxt->constructor) {
21525
0
      xmlSchemaConstructionCtxtFree(ctxt->constructor);
21526
0
      ctxt->constructor = NULL;
21527
0
      ctxt->ownsConstructor = 0;
21528
0
  }
21529
0
    }
21530
0
    ctxt->schema = NULL;
21531
0
    return(mainSchema);
21532
0
exit_failure:
21533
    /*
21534
    * Quite verbose, but should catch internal errors, which were
21535
    * not communicated.
21536
    */
21537
0
    if (mainSchema) {
21538
0
        xmlSchemaFree(mainSchema);
21539
0
  mainSchema = NULL;
21540
0
    }
21541
0
    if (ctxt->constructor) {
21542
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
21543
0
  ctxt->constructor = NULL;
21544
0
  ctxt->ownsConstructor = 0;
21545
0
    }
21546
0
    PERROR_INT2("xmlSchemaParse",
21547
0
  "An internal error occurred");
21548
0
    ctxt->schema = NULL;
21549
0
    return(NULL);
21550
0
}
21551
21552
/**
21553
 * xmlSchemaSetParserErrors:
21554
 * @ctxt:  a schema validation context
21555
 * @err:  the error callback
21556
 * @warn:  the warning callback
21557
 * @ctx:  contextual data for the callbacks
21558
 *
21559
 * Set the callback functions used to handle errors for a validation context
21560
 */
21561
void
21562
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21563
                         xmlSchemaValidityErrorFunc err,
21564
                         xmlSchemaValidityWarningFunc warn, void *ctx)
21565
0
{
21566
0
    if (ctxt == NULL)
21567
0
        return;
21568
0
    ctxt->error = err;
21569
0
    ctxt->warning = warn;
21570
0
    ctxt->errCtxt = ctx;
21571
0
    if (ctxt->vctxt != NULL)
21572
0
  xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21573
0
}
21574
21575
/**
21576
 * xmlSchemaSetParserStructuredErrors:
21577
 * @ctxt:  a schema parser context
21578
 * @serror:  the structured error function
21579
 * @ctx: the functions context
21580
 *
21581
 * Set the structured error callback
21582
 */
21583
void
21584
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21585
           xmlStructuredErrorFunc serror,
21586
           void *ctx)
21587
0
{
21588
0
    if (ctxt == NULL)
21589
0
  return;
21590
0
    ctxt->serror = serror;
21591
0
    ctxt->errCtxt = ctx;
21592
0
    if (ctxt->vctxt != NULL)
21593
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21594
0
}
21595
21596
/**
21597
 * xmlSchemaGetParserErrors:
21598
 * @ctxt:  a XMl-Schema parser context
21599
 * @err: the error callback result
21600
 * @warn: the warning callback result
21601
 * @ctx: contextual data for the callbacks result
21602
 *
21603
 * Get the callback information used to handle errors for a parser context
21604
 *
21605
 * Returns -1 in case of failure, 0 otherwise
21606
 */
21607
int
21608
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21609
       xmlSchemaValidityErrorFunc * err,
21610
       xmlSchemaValidityWarningFunc * warn, void **ctx)
21611
0
{
21612
0
  if (ctxt == NULL)
21613
0
    return(-1);
21614
0
  if (err != NULL)
21615
0
    *err = ctxt->error;
21616
0
  if (warn != NULL)
21617
0
    *warn = ctxt->warning;
21618
0
  if (ctx != NULL)
21619
0
    *ctx = ctxt->errCtxt;
21620
0
  return(0);
21621
0
}
21622
21623
/**
21624
 * xmlSchemaFacetTypeToString:
21625
 * @type:  the facet type
21626
 *
21627
 * Convert the xmlSchemaTypeType to a char string.
21628
 *
21629
 * Returns the char string representation of the facet type if the
21630
 *     type is a facet and an "Internal Error" string otherwise.
21631
 */
21632
static const xmlChar *
21633
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21634
0
{
21635
0
    switch (type) {
21636
0
        case XML_SCHEMA_FACET_PATTERN:
21637
0
            return (BAD_CAST "pattern");
21638
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21639
0
            return (BAD_CAST "maxExclusive");
21640
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
21641
0
            return (BAD_CAST "maxInclusive");
21642
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
21643
0
            return (BAD_CAST "minExclusive");
21644
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
21645
0
            return (BAD_CAST "minInclusive");
21646
0
        case XML_SCHEMA_FACET_WHITESPACE:
21647
0
            return (BAD_CAST "whiteSpace");
21648
0
        case XML_SCHEMA_FACET_ENUMERATION:
21649
0
            return (BAD_CAST "enumeration");
21650
0
        case XML_SCHEMA_FACET_LENGTH:
21651
0
            return (BAD_CAST "length");
21652
0
        case XML_SCHEMA_FACET_MAXLENGTH:
21653
0
            return (BAD_CAST "maxLength");
21654
0
        case XML_SCHEMA_FACET_MINLENGTH:
21655
0
            return (BAD_CAST "minLength");
21656
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
21657
0
            return (BAD_CAST "totalDigits");
21658
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
21659
0
            return (BAD_CAST "fractionDigits");
21660
0
        default:
21661
0
            break;
21662
0
    }
21663
0
    return (BAD_CAST "Internal Error");
21664
0
}
21665
21666
static xmlSchemaWhitespaceValueType
21667
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21668
0
{
21669
    /*
21670
    * The normalization type can be changed only for types which are derived
21671
    * from xsd:string.
21672
    */
21673
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
21674
  /*
21675
  * Note that we assume a whitespace of preserve for anySimpleType.
21676
  */
21677
0
  if ((type->builtInType == XML_SCHEMAS_STRING) ||
21678
0
      (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21679
0
      return(XML_SCHEMA_WHITESPACE_PRESERVE);
21680
0
  else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21681
0
      return(XML_SCHEMA_WHITESPACE_REPLACE);
21682
0
  else {
21683
      /*
21684
      * For all `atomic` datatypes other than string (and types `derived`
21685
      * by `restriction` from it) the value of whiteSpace is fixed to
21686
      * collapse
21687
      * Note that this includes built-in list datatypes.
21688
      */
21689
0
      return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21690
0
  }
21691
0
    } else if (WXS_IS_LIST(type)) {
21692
  /*
21693
  * For list types the facet "whiteSpace" is fixed to "collapse".
21694
  */
21695
0
  return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21696
0
    } else if (WXS_IS_UNION(type)) {
21697
0
  return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21698
0
    } else if (WXS_IS_ATOMIC(type)) {
21699
0
  if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21700
0
      return (XML_SCHEMA_WHITESPACE_PRESERVE);
21701
0
  else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21702
0
      return (XML_SCHEMA_WHITESPACE_REPLACE);
21703
0
  else
21704
0
      return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21705
0
    }
21706
0
    return (-1);
21707
0
}
21708
21709
/************************************************************************
21710
 *                  *
21711
 *      Simple type validation        *
21712
 *                  *
21713
 ************************************************************************/
21714
21715
21716
/************************************************************************
21717
 *                  *
21718
 *      DOM Validation code       *
21719
 *                  *
21720
 ************************************************************************/
21721
21722
/**
21723
 * xmlSchemaAssembleByLocation:
21724
 * @pctxt:  a schema parser context
21725
 * @vctxt:  a schema validation context
21726
 * @schema: the existing schema
21727
 * @node: the node that fired the assembling
21728
 * @nsName: the namespace name of the new schema
21729
 * @location: the location of the schema
21730
 *
21731
 * Expands an existing schema by an additional schema.
21732
 *
21733
 * Returns 0 if the new schema is correct, a positive error code
21734
 * number otherwise and -1 in case of an internal or API error.
21735
 */
21736
static int
21737
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21738
          xmlSchemaPtr schema,
21739
          xmlNodePtr node,
21740
          const xmlChar *nsName,
21741
          const xmlChar *location)
21742
0
{
21743
0
    int ret = 0;
21744
0
    xmlSchemaParserCtxtPtr pctxt;
21745
0
    xmlSchemaBucketPtr bucket = NULL;
21746
21747
0
    if ((vctxt == NULL) || (schema == NULL))
21748
0
  return (-1);
21749
21750
0
    if (vctxt->pctxt == NULL) {
21751
0
  VERROR_INT("xmlSchemaAssembleByLocation",
21752
0
      "no parser context available");
21753
0
  return(-1);
21754
0
    }
21755
0
    pctxt = vctxt->pctxt;
21756
0
    if (pctxt->constructor == NULL) {
21757
0
  PERROR_INT("xmlSchemaAssembleByLocation",
21758
0
      "no constructor");
21759
0
  return(-1);
21760
0
    }
21761
    /*
21762
    * Acquire the schema document.
21763
    */
21764
0
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21765
0
  location, node);
21766
    /*
21767
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21768
    * the process will automatically change this to
21769
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21770
    */
21771
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21772
0
  location, NULL, NULL, 0, node, NULL, nsName,
21773
0
  &bucket);
21774
0
    if (ret != 0)
21775
0
  return(ret);
21776
0
    if (bucket == NULL) {
21777
  /*
21778
  * Generate a warning that the document could not be located.
21779
  */
21780
0
  xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21781
0
      node, NULL,
21782
0
      "The document at location '%s' could not be acquired",
21783
0
      location, NULL, NULL);
21784
0
  return(ret);
21785
0
    }
21786
    /*
21787
    * The first located schema will be handled as if all other
21788
    * schemas imported by XSI were imported by this first schema.
21789
    */
21790
0
    if ((bucket != NULL) &&
21791
0
  (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21792
0
  WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21793
    /*
21794
    * TODO: Is this handled like an import? I.e. is it not an error
21795
    * if the schema cannot be located?
21796
    */
21797
0
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21798
0
  return(0);
21799
    /*
21800
    * We will reuse the parser context for every schema imported
21801
    * directly via XSI. So reset the context.
21802
    */
21803
0
    pctxt->nberrors = 0;
21804
0
    pctxt->err = 0;
21805
0
    pctxt->doc = bucket->doc;
21806
21807
0
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21808
0
    if (ret == -1) {
21809
0
  pctxt->doc = NULL;
21810
0
  goto exit_failure;
21811
0
    }
21812
    /* Paranoid error channelling. */
21813
0
    if ((ret == 0) && (pctxt->nberrors != 0))
21814
0
  ret = pctxt->err;
21815
0
    if (pctxt->nberrors == 0) {
21816
  /*
21817
  * Only bother to fixup pending components, if there was
21818
  * no error yet.
21819
  * For every XSI acquired schema (and its sub-schemata) we will
21820
  * fixup the components.
21821
  */
21822
0
  xmlSchemaFixupComponents(pctxt, bucket);
21823
0
  ret = pctxt->err;
21824
  /*
21825
  * Not nice, but we need somehow to channel the schema parser
21826
  * error to the validation context.
21827
  */
21828
0
  if ((ret != 0) && (vctxt->err == 0))
21829
0
      vctxt->err = ret;
21830
0
  vctxt->nberrors += pctxt->nberrors;
21831
0
    } else {
21832
  /* Add to validation error sum. */
21833
0
  vctxt->nberrors += pctxt->nberrors;
21834
0
    }
21835
0
    pctxt->doc = NULL;
21836
0
    return(ret);
21837
0
exit_failure:
21838
0
    pctxt->doc = NULL;
21839
0
    return (-1);
21840
0
}
21841
21842
static xmlSchemaAttrInfoPtr
21843
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21844
       int metaType)
21845
0
{
21846
0
    if (vctxt->nbAttrInfos == 0)
21847
0
  return (NULL);
21848
0
    {
21849
0
  int i;
21850
0
  xmlSchemaAttrInfoPtr iattr;
21851
21852
0
  for (i = 0; i < vctxt->nbAttrInfos; i++) {
21853
0
      iattr = vctxt->attrInfos[i];
21854
0
      if (iattr->metaType == metaType)
21855
0
    return (iattr);
21856
0
  }
21857
21858
0
    }
21859
0
    return (NULL);
21860
0
}
21861
21862
/**
21863
 * xmlSchemaAssembleByXSI:
21864
 * @vctxt:  a schema validation context
21865
 *
21866
 * Expands an existing schema by an additional schema using
21867
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21868
 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21869
 * must be set to 1.
21870
 *
21871
 * Returns 0 if the new schema is correct, a positive error code
21872
 * number otherwise and -1 in case of an internal or API error.
21873
 */
21874
static int
21875
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21876
0
{
21877
0
    const xmlChar *cur, *end;
21878
0
    const xmlChar *nsname = NULL, *location;
21879
0
    int ret = 0;
21880
0
    xmlSchemaAttrInfoPtr iattr;
21881
21882
    /*
21883
    * Parse the value; we will assume an even number of values
21884
    * to be given (this is how Xerces and XSV work).
21885
    *
21886
    * URGENT TODO: !! This needs to work for both
21887
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
21888
    * element !!
21889
    */
21890
0
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21891
0
  XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21892
0
    if (iattr == NULL)
21893
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21894
0
  XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21895
0
    if (iattr == NULL)
21896
0
  return (0);
21897
0
    cur = iattr->value;
21898
0
    do {
21899
  /*
21900
  * TODO: Move the string parsing mechanism away from here.
21901
  */
21902
0
  if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21903
      /*
21904
      * Get the namespace name.
21905
      */
21906
0
      while (IS_BLANK_CH(*cur))
21907
0
    cur++;
21908
0
      end = cur;
21909
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21910
0
    end++;
21911
0
      if (end == cur)
21912
0
    break;
21913
      /* TODO: Don't use the schema's dict. */
21914
0
      nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21915
0
      cur = end;
21916
0
  }
21917
  /*
21918
  * Get the URI.
21919
  */
21920
0
  while (IS_BLANK_CH(*cur))
21921
0
      cur++;
21922
0
  end = cur;
21923
0
  while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21924
0
      end++;
21925
0
  if (end == cur) {
21926
0
      if (iattr->metaType ==
21927
0
    XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21928
0
      {
21929
    /*
21930
    * If using @schemaLocation then tuples are expected.
21931
    * I.e. the namespace name *and* the document's URI.
21932
    */
21933
0
    xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21934
0
        iattr->node, NULL,
21935
0
        "The value must consist of tuples: the target namespace "
21936
0
        "name and the document's URI", NULL, NULL, NULL);
21937
0
      }
21938
0
      break;
21939
0
  }
21940
  /* TODO: Don't use the schema's dict. */
21941
0
  location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21942
0
  cur = end;
21943
0
  ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21944
0
      iattr->node, nsname, location);
21945
0
  if (ret == -1) {
21946
0
      VERROR_INT("xmlSchemaAssembleByXSI",
21947
0
    "assembling schemata");
21948
0
      return (-1);
21949
0
  }
21950
0
    } while (*cur != 0);
21951
0
    return (ret);
21952
0
}
21953
21954
static const xmlChar *
21955
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21956
       const xmlChar *prefix)
21957
0
{
21958
0
    if (vctxt->sax != NULL) {
21959
0
  int i, j;
21960
0
  xmlSchemaNodeInfoPtr inode;
21961
21962
0
  for (i = vctxt->depth; i >= 0; i--) {
21963
0
      if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21964
0
    inode = vctxt->elemInfos[i];
21965
0
    for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21966
0
        if (((prefix == NULL) &&
21967
0
          (inode->nsBindings[j] == NULL)) ||
21968
0
      ((prefix != NULL) && xmlStrEqual(prefix,
21969
0
          inode->nsBindings[j]))) {
21970
21971
      /*
21972
      * Note that the namespace bindings are already
21973
      * in a string dict.
21974
      */
21975
0
      return (inode->nsBindings[j+1]);
21976
0
        }
21977
0
    }
21978
0
      }
21979
0
  }
21980
0
  return (NULL);
21981
0
#ifdef LIBXML_READER_ENABLED
21982
0
    } else if (vctxt->reader != NULL) {
21983
0
  xmlChar *nsName;
21984
21985
0
  nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21986
0
  if (nsName != NULL) {
21987
0
      const xmlChar *ret;
21988
21989
0
      ret = xmlDictLookup(vctxt->dict, nsName, -1);
21990
0
      xmlFree(nsName);
21991
0
      return (ret);
21992
0
  } else
21993
0
      return (NULL);
21994
0
#endif
21995
0
    } else {
21996
0
  xmlNsPtr ns;
21997
21998
0
  if ((vctxt->inode->node == NULL) ||
21999
0
      (vctxt->inode->node->doc == NULL)) {
22000
0
      VERROR_INT("xmlSchemaLookupNamespace",
22001
0
    "no node or node's doc available");
22002
0
      return (NULL);
22003
0
  }
22004
0
  ns = xmlSearchNs(vctxt->inode->node->doc,
22005
0
      vctxt->inode->node, prefix);
22006
0
  if (ns != NULL)
22007
0
      return (ns->href);
22008
0
  return (NULL);
22009
0
    }
22010
0
}
22011
22012
/*
22013
* This one works on the schema of the validation context.
22014
*/
22015
static int
22016
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
22017
        xmlSchemaPtr schema,
22018
        xmlNodePtr node,
22019
        const xmlChar *value,
22020
        xmlSchemaValPtr *val,
22021
        int valNeeded)
22022
0
{
22023
0
    int ret;
22024
22025
0
    if (vctxt && (vctxt->schema == NULL)) {
22026
0
  VERROR_INT("xmlSchemaValidateNotation",
22027
0
      "a schema is needed on the validation context");
22028
0
  return (-1);
22029
0
    }
22030
0
    ret = xmlValidateQName(value, 1);
22031
0
    if (ret != 0)
22032
0
  return (ret);
22033
0
    {
22034
0
  xmlChar *localName = NULL;
22035
0
  xmlChar *prefix = NULL;
22036
22037
0
  localName = xmlSplitQName2(value, &prefix);
22038
0
  if (prefix != NULL) {
22039
0
      const xmlChar *nsName = NULL;
22040
22041
0
      if (vctxt != NULL)
22042
0
    nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
22043
0
      else if (node != NULL) {
22044
0
    xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
22045
0
    if (ns != NULL)
22046
0
        nsName = ns->href;
22047
0
      } else {
22048
0
    xmlFree(prefix);
22049
0
    xmlFree(localName);
22050
0
    return (1);
22051
0
      }
22052
0
      if (nsName == NULL) {
22053
0
    xmlFree(prefix);
22054
0
    xmlFree(localName);
22055
0
    return (1);
22056
0
      }
22057
0
      if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
22058
0
    if ((valNeeded) && (val != NULL)) {
22059
0
        (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
22060
0
                   xmlStrdup(nsName));
22061
0
        if (*val == NULL)
22062
0
      ret = -1;
22063
0
    }
22064
0
      } else
22065
0
    ret = 1;
22066
0
      xmlFree(prefix);
22067
0
      xmlFree(localName);
22068
0
  } else {
22069
0
      if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
22070
0
    if (valNeeded && (val != NULL)) {
22071
0
        (*val) = xmlSchemaNewNOTATIONValue(
22072
0
      BAD_CAST xmlStrdup(value), NULL);
22073
0
        if (*val == NULL)
22074
0
      ret = -1;
22075
0
    }
22076
0
      } else
22077
0
    return (1);
22078
0
  }
22079
0
    }
22080
0
    return (ret);
22081
0
}
22082
22083
static int
22084
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
22085
           const xmlChar* lname,
22086
           const xmlChar* nsname)
22087
0
{
22088
0
    int i;
22089
22090
0
    lname = xmlDictLookup(vctxt->dict, lname, -1);
22091
0
    if (lname == NULL)
22092
0
  return(-1);
22093
0
    if (nsname != NULL) {
22094
0
  nsname = xmlDictLookup(vctxt->dict, nsname, -1);
22095
0
  if (nsname == NULL)
22096
0
      return(-1);
22097
0
    }
22098
0
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
22099
0
  if ((vctxt->nodeQNames->items [i] == lname) &&
22100
0
      (vctxt->nodeQNames->items[i +1] == nsname))
22101
      /* Already there */
22102
0
      return(i);
22103
0
    }
22104
    /* Add new entry. */
22105
0
    i = vctxt->nodeQNames->nbItems;
22106
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
22107
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
22108
0
    return(i);
22109
0
}
22110
22111
/************************************************************************
22112
 *                  *
22113
 *  Validation of identity-constraints (IDC)                            *
22114
 *                  *
22115
 ************************************************************************/
22116
22117
/**
22118
 * xmlSchemaAugmentIDC:
22119
 * @idcDef: the IDC definition
22120
 *
22121
 * Creates an augmented IDC definition item.
22122
 *
22123
 * Returns the item, or NULL on internal errors.
22124
 */
22125
static void
22126
xmlSchemaAugmentIDC(void *payload, void *data,
22127
                    const xmlChar *name ATTRIBUTE_UNUSED)
22128
0
{
22129
0
    xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
22130
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
22131
0
    xmlSchemaIDCAugPtr aidc;
22132
22133
0
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
22134
0
    if (aidc == NULL) {
22135
0
  xmlSchemaVErrMemory(vctxt,
22136
0
      "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
22137
0
      NULL);
22138
0
  return;
22139
0
    }
22140
0
    aidc->keyrefDepth = -1;
22141
0
    aidc->def = idcDef;
22142
0
    aidc->next = NULL;
22143
0
    if (vctxt->aidcs == NULL)
22144
0
  vctxt->aidcs = aidc;
22145
0
    else {
22146
0
  aidc->next = vctxt->aidcs;
22147
0
  vctxt->aidcs = aidc;
22148
0
    }
22149
    /*
22150
    * Save if we have keyrefs at all.
22151
    */
22152
0
    if ((vctxt->hasKeyrefs == 0) &&
22153
0
  (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
22154
0
  vctxt->hasKeyrefs = 1;
22155
0
}
22156
22157
/**
22158
 * xmlSchemaAugmentImportedIDC:
22159
 * @imported: the imported schema
22160
 *
22161
 * Creates an augmented IDC definition for the imported schema.
22162
 */
22163
static void
22164
xmlSchemaAugmentImportedIDC(void *payload, void *data,
22165
0
                            const xmlChar *name ATTRIBUTE_UNUSED) {
22166
0
    xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
22167
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
22168
0
    if (imported->schema->idcDef != NULL) {
22169
0
      xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
22170
0
    }
22171
0
}
22172
22173
/**
22174
 * xmlSchemaIDCNewBinding:
22175
 * @idcDef: the IDC definition of this binding
22176
 *
22177
 * Creates a new IDC binding.
22178
 *
22179
 * Returns the new IDC binding, NULL on internal errors.
22180
 */
22181
static xmlSchemaPSVIIDCBindingPtr
22182
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22183
0
{
22184
0
    xmlSchemaPSVIIDCBindingPtr ret;
22185
22186
0
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22187
0
      sizeof(xmlSchemaPSVIIDCBinding));
22188
0
    if (ret == NULL) {
22189
0
  xmlSchemaVErrMemory(NULL,
22190
0
      "allocating a PSVI IDC binding item", NULL);
22191
0
  return (NULL);
22192
0
    }
22193
0
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22194
0
    ret->definition = idcDef;
22195
0
    return (ret);
22196
0
}
22197
22198
/**
22199
 * xmlSchemaIDCStoreNodeTableItem:
22200
 * @vctxt: the WXS validation context
22201
 * @item: the IDC node table item
22202
 *
22203
 * The validation context is used to store IDC node table items.
22204
 * They are stored to avoid copying them if IDC node-tables are merged
22205
 * with corresponding parent IDC node-tables (bubbling).
22206
 *
22207
 * Returns 0 if succeeded, -1 on internal errors.
22208
 */
22209
static int
22210
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22211
             xmlSchemaPSVIIDCNodePtr item)
22212
0
{
22213
    /*
22214
    * Add to global list.
22215
    */
22216
0
    if (vctxt->idcNodes == NULL) {
22217
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22218
0
      xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22219
0
  if (vctxt->idcNodes == NULL) {
22220
0
      xmlSchemaVErrMemory(vctxt,
22221
0
    "allocating the IDC node table item list", NULL);
22222
0
      return (-1);
22223
0
  }
22224
0
  vctxt->sizeIdcNodes = 20;
22225
0
    } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22226
0
  vctxt->sizeIdcNodes *= 2;
22227
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22228
0
      xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22229
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
22230
0
  if (vctxt->idcNodes == NULL) {
22231
0
      xmlSchemaVErrMemory(vctxt,
22232
0
    "re-allocating the IDC node table item list", NULL);
22233
0
      return (-1);
22234
0
  }
22235
0
    }
22236
0
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22237
22238
0
    return (0);
22239
0
}
22240
22241
/**
22242
 * xmlSchemaIDCStoreKey:
22243
 * @vctxt: the WXS validation context
22244
 * @item: the IDC key
22245
 *
22246
 * The validation context is used to store an IDC key.
22247
 *
22248
 * Returns 0 if succeeded, -1 on internal errors.
22249
 */
22250
static int
22251
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22252
         xmlSchemaPSVIIDCKeyPtr key)
22253
0
{
22254
    /*
22255
    * Add to global list.
22256
    */
22257
0
    if (vctxt->idcKeys == NULL) {
22258
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22259
0
      xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22260
0
  if (vctxt->idcKeys == NULL) {
22261
0
      xmlSchemaVErrMemory(vctxt,
22262
0
    "allocating the IDC key storage list", NULL);
22263
0
      return (-1);
22264
0
  }
22265
0
  vctxt->sizeIdcKeys = 40;
22266
0
    } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22267
0
  vctxt->sizeIdcKeys *= 2;
22268
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22269
0
      xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22270
0
      sizeof(xmlSchemaPSVIIDCKeyPtr));
22271
0
  if (vctxt->idcKeys == NULL) {
22272
0
      xmlSchemaVErrMemory(vctxt,
22273
0
    "re-allocating the IDC key storage list", NULL);
22274
0
      return (-1);
22275
0
  }
22276
0
    }
22277
0
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22278
22279
0
    return (0);
22280
0
}
22281
22282
/**
22283
 * xmlSchemaIDCAppendNodeTableItem:
22284
 * @bind: the IDC binding
22285
 * @ntItem: the node-table item
22286
 *
22287
 * Appends the IDC node-table item to the binding.
22288
 *
22289
 * Returns 0 on success and -1 on internal errors.
22290
 */
22291
static int
22292
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22293
        xmlSchemaPSVIIDCNodePtr ntItem)
22294
0
{
22295
0
    if (bind->nodeTable == NULL) {
22296
0
  bind->sizeNodes = 10;
22297
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22298
0
      xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22299
0
  if (bind->nodeTable == NULL) {
22300
0
      xmlSchemaVErrMemory(NULL,
22301
0
    "allocating an array of IDC node-table items", NULL);
22302
0
      return(-1);
22303
0
  }
22304
0
    } else if (bind->sizeNodes <= bind->nbNodes) {
22305
0
  bind->sizeNodes *= 2;
22306
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22307
0
      xmlRealloc(bind->nodeTable, bind->sizeNodes *
22308
0
    sizeof(xmlSchemaPSVIIDCNodePtr));
22309
0
  if (bind->nodeTable == NULL) {
22310
0
      xmlSchemaVErrMemory(NULL,
22311
0
    "re-allocating an array of IDC node-table items", NULL);
22312
0
      return(-1);
22313
0
  }
22314
0
    }
22315
0
    bind->nodeTable[bind->nbNodes++] = ntItem;
22316
0
    return(0);
22317
0
}
22318
22319
/**
22320
 * xmlSchemaIDCAcquireBinding:
22321
 * @vctxt: the WXS validation context
22322
 * @matcher: the IDC matcher
22323
 *
22324
 * Looks up an PSVI IDC binding, for the IDC definition and
22325
 * of the given matcher. If none found, a new one is created
22326
 * and added to the IDC table.
22327
 *
22328
 * Returns an IDC binding or NULL on internal errors.
22329
 */
22330
static xmlSchemaPSVIIDCBindingPtr
22331
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22332
        xmlSchemaIDCMatcherPtr matcher)
22333
0
{
22334
0
    xmlSchemaNodeInfoPtr ielem;
22335
22336
0
    ielem = vctxt->elemInfos[matcher->depth];
22337
22338
0
    if (ielem->idcTable == NULL) {
22339
0
  ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22340
0
  if (ielem->idcTable == NULL)
22341
0
      return (NULL);
22342
0
  return(ielem->idcTable);
22343
0
    } else {
22344
0
  xmlSchemaPSVIIDCBindingPtr bind = NULL;
22345
22346
0
  bind = ielem->idcTable;
22347
0
  do {
22348
0
      if (bind->definition == matcher->aidc->def)
22349
0
    return(bind);
22350
0
      if (bind->next == NULL) {
22351
0
    bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22352
0
    if (bind->next == NULL)
22353
0
        return (NULL);
22354
0
    return(bind->next);
22355
0
      }
22356
0
      bind = bind->next;
22357
0
  } while (bind != NULL);
22358
0
    }
22359
0
    return (NULL);
22360
0
}
22361
22362
static xmlSchemaItemListPtr
22363
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22364
           xmlSchemaIDCMatcherPtr matcher)
22365
0
{
22366
0
    if (matcher->targets == NULL)
22367
0
  matcher->targets = xmlSchemaItemListCreate();
22368
0
    return(matcher->targets);
22369
0
}
22370
22371
/**
22372
 * xmlSchemaIDCFreeKey:
22373
 * @key: the IDC key
22374
 *
22375
 * Frees an IDC key together with its compiled value.
22376
 */
22377
static void
22378
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22379
0
{
22380
0
    if (key->val != NULL)
22381
0
  xmlSchemaFreeValue(key->val);
22382
0
    xmlFree(key);
22383
0
}
22384
22385
/**
22386
 * xmlSchemaIDCFreeBinding:
22387
 *
22388
 * Frees an IDC binding. Note that the node table-items
22389
 * are not freed.
22390
 */
22391
static void
22392
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22393
0
{
22394
0
    if (bind->nodeTable != NULL)
22395
0
  xmlFree(bind->nodeTable);
22396
0
    if (bind->dupls != NULL)
22397
0
  xmlSchemaItemListFree(bind->dupls);
22398
0
    xmlFree(bind);
22399
0
}
22400
22401
/**
22402
 * xmlSchemaIDCFreeIDCTable:
22403
 * @bind: the first IDC binding in the list
22404
 *
22405
 * Frees an IDC table, i.e. all the IDC bindings in the list.
22406
 */
22407
static void
22408
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22409
0
{
22410
0
    xmlSchemaPSVIIDCBindingPtr prev;
22411
22412
0
    while (bind != NULL) {
22413
0
  prev = bind;
22414
0
  bind = bind->next;
22415
0
  xmlSchemaIDCFreeBinding(prev);
22416
0
    }
22417
0
}
22418
22419
static void
22420
xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
22421
0
{
22422
0
    xmlIDCHashEntryPtr e = payload, n;
22423
0
    while (e) {
22424
0
  n = e->next;
22425
0
  xmlFree(e);
22426
0
  e = n;
22427
0
    }
22428
0
}
22429
22430
/**
22431
 * xmlSchemaIDCFreeMatcherList:
22432
 * @matcher: the first IDC matcher in the list
22433
 *
22434
 * Frees a list of IDC matchers.
22435
 */
22436
static void
22437
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22438
0
{
22439
0
    xmlSchemaIDCMatcherPtr next;
22440
22441
0
    while (matcher != NULL) {
22442
0
  next = matcher->next;
22443
0
  if (matcher->keySeqs != NULL) {
22444
0
      int i;
22445
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22446
0
    if (matcher->keySeqs[i] != NULL)
22447
0
        xmlFree(matcher->keySeqs[i]);
22448
0
      xmlFree(matcher->keySeqs);
22449
0
  }
22450
0
  if (matcher->targets != NULL) {
22451
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22452
0
    int i;
22453
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22454
    /*
22455
    * Node-table items for keyrefs are not stored globally
22456
    * to the validation context, since they are not bubbled.
22457
    * We need to free them here.
22458
    */
22459
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22460
0
        idcNode =
22461
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22462
0
        xmlFree(idcNode->keys);
22463
0
        xmlFree(idcNode);
22464
0
    }
22465
0
      }
22466
0
      xmlSchemaItemListFree(matcher->targets);
22467
0
  }
22468
0
  if (matcher->htab != NULL)
22469
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22470
0
  xmlFree(matcher);
22471
0
  matcher = next;
22472
0
    }
22473
0
}
22474
22475
/**
22476
 * xmlSchemaIDCReleaseMatcherList:
22477
 * @vctxt: the WXS validation context
22478
 * @matcher: the first IDC matcher in the list
22479
 *
22480
 * Caches a list of IDC matchers for reuse.
22481
 */
22482
static void
22483
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22484
             xmlSchemaIDCMatcherPtr matcher)
22485
0
{
22486
0
    xmlSchemaIDCMatcherPtr next;
22487
22488
0
    while (matcher != NULL) {
22489
0
  next = matcher->next;
22490
0
  if (matcher->keySeqs != NULL) {
22491
0
      int i;
22492
      /*
22493
      * Don't free the array, but only the content.
22494
      */
22495
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22496
0
    if (matcher->keySeqs[i] != NULL) {
22497
0
        xmlFree(matcher->keySeqs[i]);
22498
0
        matcher->keySeqs[i] = NULL;
22499
0
    }
22500
0
  }
22501
0
  if (matcher->targets) {
22502
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22503
0
    int i;
22504
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22505
    /*
22506
    * Node-table items for keyrefs are not stored globally
22507
    * to the validation context, since they are not bubbled.
22508
    * We need to free them here.
22509
    */
22510
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22511
0
        idcNode =
22512
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22513
0
        xmlFree(idcNode->keys);
22514
0
        xmlFree(idcNode);
22515
0
    }
22516
0
      }
22517
0
      xmlSchemaItemListFree(matcher->targets);
22518
0
      matcher->targets = NULL;
22519
0
  }
22520
0
  if (matcher->htab != NULL) {
22521
0
      xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22522
0
      matcher->htab = NULL;
22523
0
  }
22524
0
  matcher->next = NULL;
22525
  /*
22526
  * Cache the matcher.
22527
  */
22528
0
  if (vctxt->idcMatcherCache != NULL)
22529
0
      matcher->nextCached = vctxt->idcMatcherCache;
22530
0
  vctxt->idcMatcherCache = matcher;
22531
22532
0
  matcher = next;
22533
0
    }
22534
0
}
22535
22536
/**
22537
 * xmlSchemaIDCAddStateObject:
22538
 * @vctxt: the WXS validation context
22539
 * @matcher: the IDC matcher
22540
 * @sel: the XPath information
22541
 * @parent: the parent "selector" state object if any
22542
 * @type: "selector" or "field"
22543
 *
22544
 * Creates/reuses and activates state objects for the given
22545
 * XPath information; if the XPath expression consists of unions,
22546
 * multiple state objects are created for every unioned expression.
22547
 *
22548
 * Returns 0 on success and -1 on internal errors.
22549
 */
22550
static int
22551
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22552
      xmlSchemaIDCMatcherPtr matcher,
22553
      xmlSchemaIDCSelectPtr sel,
22554
      int type)
22555
0
{
22556
0
    xmlSchemaIDCStateObjPtr sto;
22557
22558
    /*
22559
    * Reuse the state objects from the pool.
22560
    */
22561
0
    if (vctxt->xpathStatePool != NULL) {
22562
0
  sto = vctxt->xpathStatePool;
22563
0
  vctxt->xpathStatePool = sto->next;
22564
0
  sto->next = NULL;
22565
0
    } else {
22566
  /*
22567
  * Create a new state object.
22568
  */
22569
0
  sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22570
0
  if (sto == NULL) {
22571
0
      xmlSchemaVErrMemory(NULL,
22572
0
    "allocating an IDC state object", NULL);
22573
0
      return (-1);
22574
0
  }
22575
0
  memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22576
0
    }
22577
    /*
22578
    * Add to global list.
22579
    */
22580
0
    if (vctxt->xpathStates != NULL)
22581
0
  sto->next = vctxt->xpathStates;
22582
0
    vctxt->xpathStates = sto;
22583
22584
    /*
22585
    * Free the old xpath validation context.
22586
    */
22587
0
    if (sto->xpathCtxt != NULL)
22588
0
  xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22589
22590
    /*
22591
    * Create a new XPath (pattern) validation context.
22592
    */
22593
0
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22594
0
  (xmlPatternPtr) sel->xpathComp);
22595
0
    if (sto->xpathCtxt == NULL) {
22596
0
  VERROR_INT("xmlSchemaIDCAddStateObject",
22597
0
      "failed to create an XPath validation context");
22598
0
  return (-1);
22599
0
    }
22600
0
    sto->type = type;
22601
0
    sto->depth = vctxt->depth;
22602
0
    sto->matcher = matcher;
22603
0
    sto->sel = sel;
22604
0
    sto->nbHistory = 0;
22605
22606
#ifdef DEBUG_IDC
22607
    xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
22608
  sto->sel->xpath);
22609
#endif
22610
0
    return (0);
22611
0
}
22612
22613
/**
22614
 * xmlSchemaXPathEvaluate:
22615
 * @vctxt: the WXS validation context
22616
 * @nodeType: the nodeType of the current node
22617
 *
22618
 * Evaluates all active XPath state objects.
22619
 *
22620
 * Returns the number of IC "field" state objects which resolved to
22621
 * this node, 0 if none resolved and -1 on internal errors.
22622
 */
22623
static int
22624
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22625
           xmlElementType nodeType)
22626
0
{
22627
0
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22628
0
    int res, resolved = 0, depth = vctxt->depth;
22629
22630
0
    if (vctxt->xpathStates == NULL)
22631
0
  return (0);
22632
22633
0
    if (nodeType == XML_ATTRIBUTE_NODE)
22634
0
  depth++;
22635
#ifdef DEBUG_IDC
22636
    {
22637
  xmlChar *str = NULL;
22638
  xmlGenericError(xmlGenericErrorContext,
22639
      "IDC: EVAL on %s, depth %d, type %d\n",
22640
      xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22641
    vctxt->inode->localName), depth, nodeType);
22642
  FREE_AND_NULL(str)
22643
    }
22644
#endif
22645
    /*
22646
    * Process all active XPath state objects.
22647
    */
22648
0
    first = vctxt->xpathStates;
22649
0
    sto = first;
22650
0
    while (sto != head) {
22651
#ifdef DEBUG_IDC
22652
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22653
      xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
22654
    sto->matcher->aidc->def->name, sto->sel->xpath);
22655
  else
22656
      xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
22657
    sto->matcher->aidc->def->name, sto->sel->xpath);
22658
#endif
22659
0
  if (nodeType == XML_ELEMENT_NODE)
22660
0
      res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22661
0
    vctxt->inode->localName, vctxt->inode->nsName);
22662
0
  else
22663
0
      res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22664
0
    vctxt->inode->localName, vctxt->inode->nsName);
22665
22666
0
  if (res == -1) {
22667
0
      VERROR_INT("xmlSchemaXPathEvaluate",
22668
0
    "calling xmlStreamPush()");
22669
0
      return (-1);
22670
0
  }
22671
0
  if (res == 0)
22672
0
      goto next_sto;
22673
  /*
22674
  * Full match.
22675
  */
22676
#ifdef DEBUG_IDC
22677
  xmlGenericError(xmlGenericErrorContext, "IDC:     "
22678
      "MATCH\n");
22679
#endif
22680
  /*
22681
  * Register a match in the state object history.
22682
  */
22683
0
  if (sto->history == NULL) {
22684
0
      sto->history = (int *) xmlMalloc(5 * sizeof(int));
22685
0
      if (sto->history == NULL) {
22686
0
    xmlSchemaVErrMemory(NULL,
22687
0
        "allocating the state object history", NULL);
22688
0
    return(-1);
22689
0
      }
22690
0
      sto->sizeHistory = 5;
22691
0
  } else if (sto->sizeHistory <= sto->nbHistory) {
22692
0
      sto->sizeHistory *= 2;
22693
0
      sto->history = (int *) xmlRealloc(sto->history,
22694
0
    sto->sizeHistory * sizeof(int));
22695
0
      if (sto->history == NULL) {
22696
0
    xmlSchemaVErrMemory(NULL,
22697
0
        "re-allocating the state object history", NULL);
22698
0
    return(-1);
22699
0
      }
22700
0
  }
22701
0
  sto->history[sto->nbHistory++] = depth;
22702
22703
#ifdef DEBUG_IDC
22704
  xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
22705
      vctxt->depth);
22706
#endif
22707
22708
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22709
0
      xmlSchemaIDCSelectPtr sel;
22710
      /*
22711
      * Activate state objects for the IDC fields of
22712
      * the IDC selector.
22713
      */
22714
#ifdef DEBUG_IDC
22715
      xmlGenericError(xmlGenericErrorContext, "IDC:     "
22716
    "activating field states\n");
22717
#endif
22718
0
      sel = sto->matcher->aidc->def->fields;
22719
0
      while (sel != NULL) {
22720
0
    if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22721
0
        sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22722
0
        return (-1);
22723
0
    sel = sel->next;
22724
0
      }
22725
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22726
      /*
22727
      * An IDC key node was found by the IDC field.
22728
      */
22729
#ifdef DEBUG_IDC
22730
      xmlGenericError(xmlGenericErrorContext,
22731
    "IDC:     key found\n");
22732
#endif
22733
      /*
22734
      * Notify that the character value of this node is
22735
      * needed.
22736
      */
22737
0
      if (resolved == 0) {
22738
0
    if ((vctxt->inode->flags &
22739
0
        XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22740
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22741
0
      }
22742
0
      resolved++;
22743
0
  }
22744
0
next_sto:
22745
0
  if (sto->next == NULL) {
22746
      /*
22747
      * Evaluate field state objects created on this node as well.
22748
      */
22749
0
      head = first;
22750
0
      sto = vctxt->xpathStates;
22751
0
  } else
22752
0
      sto = sto->next;
22753
0
    }
22754
0
    return (resolved);
22755
0
}
22756
22757
static const xmlChar *
22758
xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22759
        xmlChar **buf,
22760
        xmlSchemaPSVIIDCKeyPtr *seq,
22761
        int count, int for_hash)
22762
0
{
22763
0
    int i, res;
22764
0
    xmlChar *value = NULL;
22765
22766
0
    *buf = xmlStrdup(BAD_CAST "[");
22767
0
    for (i = 0; i < count; i++) {
22768
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
22769
0
  if (!for_hash)
22770
0
      res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22771
0
        xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22772
0
        &value);
22773
0
  else {
22774
0
      res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22775
0
  }
22776
0
  if (res == 0)
22777
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
22778
0
  else {
22779
0
      VERROR_INT("xmlSchemaFormatIDCKeySequence",
22780
0
    "failed to compute a canonical value");
22781
0
      *buf = xmlStrcat(*buf, BAD_CAST "???");
22782
0
  }
22783
0
  if (i < count -1)
22784
0
      *buf = xmlStrcat(*buf, BAD_CAST "', ");
22785
0
  else
22786
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
22787
0
  if (value != NULL) {
22788
0
      xmlFree(value);
22789
0
      value = NULL;
22790
0
  }
22791
0
    }
22792
0
    *buf = xmlStrcat(*buf, BAD_CAST "]");
22793
22794
0
    return (BAD_CAST *buf);
22795
0
}
22796
22797
static const xmlChar *
22798
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22799
            xmlChar **buf,
22800
            xmlSchemaPSVIIDCKeyPtr *seq,
22801
            int count)
22802
0
{
22803
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22804
0
}
22805
22806
static const xmlChar *
22807
xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22808
       xmlChar **buf,
22809
       xmlSchemaPSVIIDCKeyPtr *seq,
22810
       int count)
22811
0
{
22812
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22813
0
}
22814
22815
/**
22816
 * xmlSchemaXPathPop:
22817
 * @vctxt: the WXS validation context
22818
 *
22819
 * Pops all XPath states.
22820
 *
22821
 * Returns 0 on success and -1 on internal errors.
22822
 */
22823
static int
22824
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22825
0
{
22826
0
    xmlSchemaIDCStateObjPtr sto;
22827
0
    int res;
22828
22829
0
    if (vctxt->xpathStates == NULL)
22830
0
  return(0);
22831
0
    sto = vctxt->xpathStates;
22832
0
    do {
22833
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22834
0
  if (res == -1)
22835
0
      return (-1);
22836
0
  sto = sto->next;
22837
0
    } while (sto != NULL);
22838
0
    return(0);
22839
0
}
22840
22841
/**
22842
 * xmlSchemaXPathProcessHistory:
22843
 * @vctxt: the WXS validation context
22844
 * @type: the simple/complex type of the current node if any at all
22845
 * @val: the precompiled value
22846
 *
22847
 * Processes and pops the history items of the IDC state objects.
22848
 * IDC key-sequences are validated/created on IDC bindings.
22849
 *
22850
 * Returns 0 on success and -1 on internal errors.
22851
 */
22852
static int
22853
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22854
           int depth)
22855
0
{
22856
0
    xmlSchemaIDCStateObjPtr sto, nextsto;
22857
0
    int res, matchDepth;
22858
0
    xmlSchemaPSVIIDCKeyPtr key = NULL;
22859
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22860
22861
0
    if (vctxt->xpathStates == NULL)
22862
0
  return (0);
22863
0
    sto = vctxt->xpathStates;
22864
22865
#ifdef DEBUG_IDC
22866
    {
22867
  xmlChar *str = NULL;
22868
  xmlGenericError(xmlGenericErrorContext,
22869
      "IDC: BACK on %s, depth %d\n",
22870
      xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22871
    vctxt->inode->localName), vctxt->depth);
22872
  FREE_AND_NULL(str)
22873
    }
22874
#endif
22875
    /*
22876
    * Evaluate the state objects.
22877
    */
22878
0
    while (sto != NULL) {
22879
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22880
0
  if (res == -1) {
22881
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22882
0
    "calling xmlStreamPop()");
22883
0
      return (-1);
22884
0
  }
22885
#ifdef DEBUG_IDC
22886
  xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
22887
      sto->sel->xpath);
22888
#endif
22889
0
  if (sto->nbHistory == 0)
22890
0
      goto deregister_check;
22891
22892
0
  matchDepth = sto->history[sto->nbHistory -1];
22893
22894
  /*
22895
  * Only matches at the current depth are of interest.
22896
  */
22897
0
  if (matchDepth != depth) {
22898
0
      sto = sto->next;
22899
0
      continue;
22900
0
  }
22901
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22902
      /*
22903
      * NOTE: According to
22904
      *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22905
      *   ... the simple-content of complex types is also allowed.
22906
      */
22907
22908
0
      if (WXS_IS_COMPLEX(type)) {
22909
0
    if (WXS_HAS_SIMPLE_CONTENT(type)) {
22910
        /*
22911
        * Sanity check for complex types with simple content.
22912
        */
22913
0
        simpleType = type->contentTypeDef;
22914
0
        if (simpleType == NULL) {
22915
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22916
0
          "field resolves to a CT with simple content "
22917
0
          "but the CT is missing the ST definition");
22918
0
      return (-1);
22919
0
        }
22920
0
    } else
22921
0
        simpleType = NULL;
22922
0
      } else
22923
0
    simpleType = type;
22924
0
      if (simpleType == NULL) {
22925
0
    xmlChar *str = NULL;
22926
22927
    /*
22928
    * Not qualified if the field resolves to a node of non
22929
    * simple type.
22930
    */
22931
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22932
0
        XML_SCHEMAV_CVC_IDC, NULL,
22933
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22934
0
        "The XPath '%s' of a field of %s does evaluate to a node of "
22935
0
        "non-simple type",
22936
0
        sto->sel->xpath,
22937
0
        xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22938
0
    FREE_AND_NULL(str);
22939
0
    sto->nbHistory--;
22940
0
    goto deregister_check;
22941
0
      }
22942
22943
0
      if ((key == NULL) && (vctxt->inode->val == NULL)) {
22944
    /*
22945
    * Failed to provide the normalized value; maybe
22946
    * the value was invalid.
22947
    */
22948
0
    VERROR(XML_SCHEMAV_CVC_IDC,
22949
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22950
0
        "Warning: No precomputed value available, the value "
22951
0
        "was either invalid or something strange happened");
22952
0
    sto->nbHistory--;
22953
0
    goto deregister_check;
22954
0
      } else {
22955
0
    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22956
0
    xmlSchemaPSVIIDCKeyPtr *keySeq;
22957
0
    int pos, idx;
22958
22959
    /*
22960
    * The key will be anchored on the matcher's list of
22961
    * key-sequences. The position in this list is determined
22962
    * by the target node's depth relative to the matcher's
22963
    * depth of creation (i.e. the depth of the scope element).
22964
    *
22965
    * Element        Depth    Pos   List-entries
22966
    * <scope>          0              NULL
22967
    *   <bar>          1              NULL
22968
    *     <target/>    2       2      target
22969
    *   <bar>
22970
                * </scope>
22971
    *
22972
    * The size of the list is only dependent on the depth of
22973
    * the tree.
22974
    * An entry will be NULLed in selector_leave, i.e. when
22975
    * we hit the target's
22976
    */
22977
0
    pos = sto->depth - matcher->depth;
22978
0
    idx = sto->sel->index;
22979
22980
    /*
22981
    * Create/grow the array of key-sequences.
22982
    */
22983
0
    if (matcher->keySeqs == NULL) {
22984
0
        if (pos > 9)
22985
0
      matcher->sizeKeySeqs = pos * 2;
22986
0
        else
22987
0
      matcher->sizeKeySeqs = 10;
22988
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22989
0
      xmlMalloc(matcher->sizeKeySeqs *
22990
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22991
0
        if (matcher->keySeqs == NULL) {
22992
0
      xmlSchemaVErrMemory(NULL,
22993
0
          "allocating an array of key-sequences",
22994
0
          NULL);
22995
0
      return(-1);
22996
0
        }
22997
0
        memset(matcher->keySeqs, 0,
22998
0
      matcher->sizeKeySeqs *
22999
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
23000
0
    } else if (pos >= matcher->sizeKeySeqs) {
23001
0
        int i = matcher->sizeKeySeqs;
23002
23003
0
        matcher->sizeKeySeqs *= 2;
23004
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
23005
0
      xmlRealloc(matcher->keySeqs,
23006
0
      matcher->sizeKeySeqs *
23007
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
23008
0
        if (matcher->keySeqs == NULL) {
23009
0
      xmlSchemaVErrMemory(NULL,
23010
0
          "reallocating an array of key-sequences",
23011
0
          NULL);
23012
0
      return (-1);
23013
0
        }
23014
        /*
23015
        * The array needs to be NULLed.
23016
        * TODO: Use memset?
23017
        */
23018
0
        for (; i < matcher->sizeKeySeqs; i++)
23019
0
      matcher->keySeqs[i] = NULL;
23020
0
    }
23021
23022
    /*
23023
    * Get/create the key-sequence.
23024
    */
23025
0
    keySeq = matcher->keySeqs[pos];
23026
0
    if (keySeq == NULL) {
23027
0
        goto create_sequence;
23028
0
    } else if (keySeq[idx] != NULL) {
23029
0
        xmlChar *str = NULL;
23030
        /*
23031
        * cvc-identity-constraint:
23032
        * 3 For each node in the `target node set` all
23033
        * of the {fields}, with that node as the context
23034
        * node, evaluate to either an empty node-set or
23035
        * a node-set with exactly one member, which must
23036
        * have a simple type.
23037
        *
23038
        * The key was already set; report an error.
23039
        */
23040
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
23041
0
      XML_SCHEMAV_CVC_IDC, NULL,
23042
0
      WXS_BASIC_CAST matcher->aidc->def,
23043
0
      "The XPath '%s' of a field of %s evaluates to a "
23044
0
      "node-set with more than one member",
23045
0
      sto->sel->xpath,
23046
0
      xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
23047
0
        FREE_AND_NULL(str);
23048
0
        sto->nbHistory--;
23049
0
        goto deregister_check;
23050
0
    } else
23051
0
        goto create_key;
23052
23053
0
create_sequence:
23054
    /*
23055
    * Create a key-sequence.
23056
    */
23057
0
    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
23058
0
        matcher->aidc->def->nbFields *
23059
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
23060
0
    if (keySeq == NULL) {
23061
0
        xmlSchemaVErrMemory(NULL,
23062
0
      "allocating an IDC key-sequence", NULL);
23063
0
        return(-1);
23064
0
    }
23065
0
    memset(keySeq, 0, matcher->aidc->def->nbFields *
23066
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
23067
0
    matcher->keySeqs[pos] = keySeq;
23068
0
create_key:
23069
    /*
23070
    * Create a key once per node only.
23071
    */
23072
0
    if (key == NULL) {
23073
0
        key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
23074
0
      sizeof(xmlSchemaPSVIIDCKey));
23075
0
        if (key == NULL) {
23076
0
      xmlSchemaVErrMemory(NULL,
23077
0
          "allocating a IDC key", NULL);
23078
0
      xmlFree(keySeq);
23079
0
      matcher->keySeqs[pos] = NULL;
23080
0
      return(-1);
23081
0
        }
23082
        /*
23083
        * Consume the compiled value.
23084
        */
23085
0
        key->type = simpleType;
23086
0
        key->val = vctxt->inode->val;
23087
0
        vctxt->inode->val = NULL;
23088
        /*
23089
        * Store the key in a global list.
23090
        */
23091
0
        if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
23092
0
      xmlSchemaIDCFreeKey(key);
23093
0
      return (-1);
23094
0
        }
23095
0
    }
23096
0
    keySeq[idx] = key;
23097
0
      }
23098
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
23099
23100
0
      xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
23101
      /* xmlSchemaPSVIIDCBindingPtr bind; */
23102
0
      xmlSchemaPSVIIDCNodePtr ntItem;
23103
0
      xmlSchemaIDCMatcherPtr matcher;
23104
0
      xmlSchemaIDCPtr idc;
23105
0
      xmlSchemaItemListPtr targets;
23106
0
      int pos, i, j, nbKeys;
23107
      /*
23108
      * Here we have the following scenario:
23109
      * An IDC 'selector' state object resolved to a target node,
23110
      * during the time this target node was in the
23111
      * ancestor-or-self axis, the 'field' state object(s) looked
23112
      * out for matching nodes to create a key-sequence for this
23113
      * target node. Now we are back to this target node and need
23114
      * to put the key-sequence, together with the target node
23115
      * itself, into the node-table of the corresponding IDC
23116
      * binding.
23117
      */
23118
0
      matcher = sto->matcher;
23119
0
      idc = matcher->aidc->def;
23120
0
      nbKeys = idc->nbFields;
23121
0
      pos = depth - matcher->depth;
23122
      /*
23123
      * Check if the matcher has any key-sequences at all, plus
23124
      * if it has a key-sequence for the current target node.
23125
      */
23126
0
      if ((matcher->keySeqs == NULL) ||
23127
0
    (matcher->sizeKeySeqs <= pos)) {
23128
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
23129
0
        goto selector_key_error;
23130
0
    else
23131
0
        goto selector_leave;
23132
0
      }
23133
23134
0
      keySeq = &(matcher->keySeqs[pos]);
23135
0
      if (*keySeq == NULL) {
23136
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
23137
0
        goto selector_key_error;
23138
0
    else
23139
0
        goto selector_leave;
23140
0
      }
23141
23142
0
      for (i = 0; i < nbKeys; i++) {
23143
0
    if ((*keySeq)[i] == NULL) {
23144
        /*
23145
        * Not qualified, if not all fields did resolve.
23146
        */
23147
0
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
23148
      /*
23149
      * All fields of a "key" IDC must resolve.
23150
      */
23151
0
      goto selector_key_error;
23152
0
        }
23153
0
        goto selector_leave;
23154
0
    }
23155
0
      }
23156
      /*
23157
      * All fields did resolve.
23158
      */
23159
23160
      /*
23161
      * 4.1 If the {identity-constraint category} is unique(/key),
23162
      * then no two members of the `qualified node set` have
23163
      * `key-sequences` whose members are pairwise equal, as
23164
      * defined by Equal in [XML Schemas: Datatypes].
23165
      *
23166
      * Get the IDC binding from the matcher and check for
23167
      * duplicate key-sequences.
23168
      */
23169
#if 0
23170
      bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23171
#endif
23172
0
      targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
23173
0
      if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
23174
0
    (targets->nbItems != 0)) {
23175
0
    xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
23176
0
    xmlIDCHashEntryPtr e;
23177
23178
0
    res = 0;
23179
23180
0
    if (!matcher->htab)
23181
0
        e = NULL;
23182
0
    else {
23183
0
        xmlChar *value = NULL;
23184
0
        xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
23185
0
        e = xmlHashLookup(matcher->htab, value);
23186
0
        FREE_AND_NULL(value);
23187
0
    }
23188
23189
    /*
23190
    * Compare the key-sequences, key by key.
23191
    */
23192
0
    for (;e; e = e->next) {
23193
0
        bkeySeq =
23194
0
      ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
23195
0
        for (j = 0; j < nbKeys; j++) {
23196
0
      ckey = (*keySeq)[j];
23197
0
      bkey = bkeySeq[j];
23198
0
      res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
23199
0
      if (res == -1) {
23200
0
          return (-1);
23201
0
      } else if (res == 0) {
23202
          /*
23203
          * One of the keys differs, so the key-sequence
23204
          * won't be equal; get out.
23205
          */
23206
0
          break;
23207
0
      }
23208
0
        }
23209
0
        if (res == 1) {
23210
      /*
23211
      * Duplicate key-sequence found.
23212
      */
23213
0
      break;
23214
0
        }
23215
0
    }
23216
0
    if (e) {
23217
0
        xmlChar *str = NULL, *strB = NULL;
23218
        /*
23219
        * TODO: Try to report the key-sequence.
23220
        */
23221
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
23222
0
      XML_SCHEMAV_CVC_IDC, NULL,
23223
0
      WXS_BASIC_CAST idc,
23224
0
      "Duplicate key-sequence %s in %s",
23225
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
23226
0
          (*keySeq), nbKeys),
23227
0
      xmlSchemaGetIDCDesignation(&strB, idc));
23228
0
        FREE_AND_NULL(str);
23229
0
        FREE_AND_NULL(strB);
23230
0
        goto selector_leave;
23231
0
    }
23232
0
      }
23233
      /*
23234
      * Add a node-table item to the IDC binding.
23235
      */
23236
0
      ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
23237
0
    sizeof(xmlSchemaPSVIIDCNode));
23238
0
      if (ntItem == NULL) {
23239
0
    xmlSchemaVErrMemory(NULL,
23240
0
        "allocating an IDC node-table item", NULL);
23241
0
    xmlFree(*keySeq);
23242
0
    *keySeq = NULL;
23243
0
    return(-1);
23244
0
      }
23245
0
      memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
23246
23247
      /*
23248
      * Store the node-table item in a global list.
23249
      */
23250
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23251
0
    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
23252
0
        xmlFree(ntItem);
23253
0
        xmlFree(*keySeq);
23254
0
        *keySeq = NULL;
23255
0
        return (-1);
23256
0
    }
23257
0
    ntItem->nodeQNameID = -1;
23258
0
      } else {
23259
    /*
23260
    * Save a cached QName for this node on the IDC node, to be
23261
    * able to report it, even if the node is not saved.
23262
    */
23263
0
    ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23264
0
        vctxt->inode->localName, vctxt->inode->nsName);
23265
0
    if (ntItem->nodeQNameID == -1) {
23266
0
        xmlFree(ntItem);
23267
0
        xmlFree(*keySeq);
23268
0
        *keySeq = NULL;
23269
0
        return (-1);
23270
0
    }
23271
0
      }
23272
      /*
23273
      * Init the node-table item: Save the node, position and
23274
      * consume the key-sequence.
23275
      */
23276
0
      ntItem->node = vctxt->node;
23277
0
      ntItem->nodeLine = vctxt->inode->nodeLine;
23278
0
      ntItem->keys = *keySeq;
23279
0
      *keySeq = NULL;
23280
#if 0
23281
      if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23282
#endif
23283
0
      if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23284
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23285
        /*
23286
        * Free the item, since keyref items won't be
23287
        * put on a global list.
23288
        */
23289
0
        xmlFree(ntItem->keys);
23290
0
        xmlFree(ntItem);
23291
0
    }
23292
0
    return (-1);
23293
0
      }
23294
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23295
0
    xmlChar *value = NULL;
23296
0
    xmlIDCHashEntryPtr r, e;
23297
0
    if (!matcher->htab)
23298
0
      matcher->htab = xmlHashCreate(4);
23299
0
    xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23300
0
    e = xmlMalloc(sizeof *e);
23301
0
    e->index = targets->nbItems - 1;
23302
0
    r = xmlHashLookup(matcher->htab, value);
23303
0
    if (r) {
23304
0
        e->next = r->next;
23305
0
        r->next = e;
23306
0
    } else {
23307
0
        e->next = NULL;
23308
0
        xmlHashAddEntry(matcher->htab, value, e);
23309
0
    }
23310
0
    FREE_AND_NULL(value);
23311
0
      }
23312
23313
0
      goto selector_leave;
23314
0
selector_key_error:
23315
0
      {
23316
0
    xmlChar *str = NULL;
23317
    /*
23318
    * 4.2.1 (KEY) The `target node set` and the
23319
    * `qualified node set` are equal, that is, every
23320
    * member of the `target node set` is also a member
23321
    * of the `qualified node set` and vice versa.
23322
    */
23323
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
23324
0
        XML_SCHEMAV_CVC_IDC, NULL,
23325
0
        WXS_BASIC_CAST idc,
23326
0
        "Not all fields of %s evaluate to a node",
23327
0
        xmlSchemaGetIDCDesignation(&str, idc), NULL);
23328
0
    FREE_AND_NULL(str);
23329
0
      }
23330
0
selector_leave:
23331
      /*
23332
      * Free the key-sequence if not added to the IDC table.
23333
      */
23334
0
      if ((keySeq != NULL) && (*keySeq != NULL)) {
23335
0
    xmlFree(*keySeq);
23336
0
    *keySeq = NULL;
23337
0
      }
23338
0
  } /* if selector */
23339
23340
0
  sto->nbHistory--;
23341
23342
0
deregister_check:
23343
  /*
23344
  * Deregister state objects if they reach the depth of creation.
23345
  */
23346
0
  if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23347
#ifdef DEBUG_IDC
23348
      xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
23349
    sto->sel->xpath);
23350
#endif
23351
0
      if (vctxt->xpathStates != sto) {
23352
0
    VERROR_INT("xmlSchemaXPathProcessHistory",
23353
0
        "The state object to be removed is not the first "
23354
0
        "in the list");
23355
0
      }
23356
0
      nextsto = sto->next;
23357
      /*
23358
      * Unlink from the list of active XPath state objects.
23359
      */
23360
0
      vctxt->xpathStates = sto->next;
23361
0
      sto->next = vctxt->xpathStatePool;
23362
      /*
23363
      * Link it to the pool of reusable state objects.
23364
      */
23365
0
      vctxt->xpathStatePool = sto;
23366
0
      sto = nextsto;
23367
0
  } else
23368
0
      sto = sto->next;
23369
0
    } /* while (sto != NULL) */
23370
0
    return (0);
23371
0
}
23372
23373
/**
23374
 * xmlSchemaIDCRegisterMatchers:
23375
 * @vctxt: the WXS validation context
23376
 * @elemDecl: the element declaration
23377
 *
23378
 * Creates helper objects to evaluate IDC selectors/fields
23379
 * successively.
23380
 *
23381
 * Returns 0 if OK and -1 on internal errors.
23382
 */
23383
static int
23384
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23385
           xmlSchemaElementPtr elemDecl)
23386
0
{
23387
0
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
23388
0
    xmlSchemaIDCPtr idc, refIdc;
23389
0
    xmlSchemaIDCAugPtr aidc;
23390
23391
0
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23392
0
    if (idc == NULL)
23393
0
  return (0);
23394
23395
#ifdef DEBUG_IDC
23396
    {
23397
  xmlChar *str = NULL;
23398
  xmlGenericError(xmlGenericErrorContext,
23399
      "IDC: REGISTER on %s, depth %d\n",
23400
      (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23401
    vctxt->inode->localName), vctxt->depth);
23402
  FREE_AND_NULL(str)
23403
    }
23404
#endif
23405
0
    if (vctxt->inode->idcMatchers != NULL) {
23406
0
  VERROR_INT("xmlSchemaIDCRegisterMatchers",
23407
0
      "The chain of IDC matchers is expected to be empty");
23408
0
  return (-1);
23409
0
    }
23410
0
    do {
23411
0
  if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23412
      /*
23413
      * Since IDCs bubbles are expensive we need to know the
23414
      * depth at which the bubbles should stop; this will be
23415
      * the depth of the top-most keyref IDC. If no keyref
23416
      * references a key/unique IDC, the keyrefDepth will
23417
      * be -1, indicating that no bubbles are needed.
23418
      */
23419
0
      refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23420
0
      if (refIdc != NULL) {
23421
    /*
23422
    * Remember that we have keyrefs on this node.
23423
    */
23424
0
    vctxt->inode->hasKeyrefs = 1;
23425
    /*
23426
    * Lookup the referenced augmented IDC info.
23427
    */
23428
0
    aidc = vctxt->aidcs;
23429
0
    while (aidc != NULL) {
23430
0
        if (aidc->def == refIdc)
23431
0
      break;
23432
0
        aidc = aidc->next;
23433
0
    }
23434
0
    if (aidc == NULL) {
23435
0
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
23436
0
      "Could not find an augmented IDC item for an IDC "
23437
0
      "definition");
23438
0
        return (-1);
23439
0
    }
23440
0
    if ((aidc->keyrefDepth == -1) ||
23441
0
        (vctxt->depth < aidc->keyrefDepth))
23442
0
        aidc->keyrefDepth = vctxt->depth;
23443
0
      }
23444
0
  }
23445
  /*
23446
  * Lookup the augmented IDC item for the IDC definition.
23447
  */
23448
0
  aidc = vctxt->aidcs;
23449
0
  while (aidc != NULL) {
23450
0
      if (aidc->def == idc)
23451
0
    break;
23452
0
      aidc = aidc->next;
23453
0
  }
23454
0
  if (aidc == NULL) {
23455
0
      VERROR_INT("xmlSchemaIDCRegisterMatchers",
23456
0
    "Could not find an augmented IDC item for an IDC definition");
23457
0
      return (-1);
23458
0
  }
23459
  /*
23460
  * Create an IDC matcher for every IDC definition.
23461
  */
23462
0
  if (vctxt->idcMatcherCache != NULL) {
23463
      /*
23464
      * Reuse a cached matcher.
23465
      */
23466
0
      matcher = vctxt->idcMatcherCache;
23467
0
      vctxt->idcMatcherCache = matcher->nextCached;
23468
0
      matcher->nextCached = NULL;
23469
0
  } else {
23470
0
      matcher = (xmlSchemaIDCMatcherPtr)
23471
0
    xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23472
0
      if (matcher == NULL) {
23473
0
    xmlSchemaVErrMemory(vctxt,
23474
0
        "allocating an IDC matcher", NULL);
23475
0
    return (-1);
23476
0
      }
23477
0
      memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23478
0
  }
23479
0
  if (last == NULL)
23480
0
      vctxt->inode->idcMatchers = matcher;
23481
0
  else
23482
0
      last->next = matcher;
23483
0
  last = matcher;
23484
23485
0
  matcher->type = IDC_MATCHER;
23486
0
  matcher->depth = vctxt->depth;
23487
0
  matcher->aidc = aidc;
23488
0
  matcher->idcType = aidc->def->type;
23489
#ifdef DEBUG_IDC
23490
  xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
23491
#endif
23492
  /*
23493
  * Init the automaton state object.
23494
  */
23495
0
  if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23496
0
      idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23497
0
      return (-1);
23498
23499
0
  idc = idc->next;
23500
0
    } while (idc != NULL);
23501
0
    return (0);
23502
0
}
23503
23504
static int
23505
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23506
         xmlSchemaNodeInfoPtr ielem)
23507
0
{
23508
0
    xmlSchemaPSVIIDCBindingPtr bind;
23509
0
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23510
0
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23511
0
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23512
23513
0
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23514
    /* vctxt->createIDCNodeTables */
23515
0
    while (matcher != NULL) {
23516
  /*
23517
  * Skip keyref IDCs and empty IDC target-lists.
23518
  */
23519
0
  if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23520
0
      WXS_ILIST_IS_EMPTY(matcher->targets))
23521
0
  {
23522
0
      matcher = matcher->next;
23523
0
      continue;
23524
0
  }
23525
  /*
23526
  * If we _want_ the IDC node-table to be created in any case
23527
  * then do so. Otherwise create them only if keyrefs need them.
23528
  */
23529
0
  if ((! vctxt->createIDCNodeTables) &&
23530
0
      ((matcher->aidc->keyrefDepth == -1) ||
23531
0
       (matcher->aidc->keyrefDepth > vctxt->depth)))
23532
0
  {
23533
0
      matcher = matcher->next;
23534
0
      continue;
23535
0
  }
23536
  /*
23537
  * Get/create the IDC binding on this element for the IDC definition.
23538
  */
23539
0
  bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23540
0
  if (bind == NULL)
23541
0
     goto internal_error;
23542
23543
0
  if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23544
0
      dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23545
0
      nbDupls = bind->dupls->nbItems;
23546
0
  } else {
23547
0
      dupls = NULL;
23548
0
      nbDupls = 0;
23549
0
  }
23550
0
  if (bind->nodeTable != NULL) {
23551
0
      nbNodeTable = bind->nbNodes;
23552
0
  } else {
23553
0
      nbNodeTable = 0;
23554
0
  }
23555
23556
0
  if ((nbNodeTable == 0) && (nbDupls == 0)) {
23557
      /*
23558
      * Transfer all IDC target-nodes to the IDC node-table.
23559
      */
23560
0
      bind->nodeTable =
23561
0
    (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23562
0
      bind->sizeNodes = matcher->targets->sizeItems;
23563
0
      bind->nbNodes = matcher->targets->nbItems;
23564
23565
0
      matcher->targets->items = NULL;
23566
0
      matcher->targets->sizeItems = 0;
23567
0
      matcher->targets->nbItems = 0;
23568
0
      if (matcher->htab) {
23569
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23570
0
    matcher->htab = NULL;
23571
0
      }
23572
0
  } else {
23573
      /*
23574
      * Compare the key-sequences and add to the IDC node-table.
23575
      */
23576
0
      nbTargets = matcher->targets->nbItems;
23577
0
      targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23578
0
      nbFields = matcher->aidc->def->nbFields;
23579
0
      i = 0;
23580
0
      do {
23581
0
    keys = targets[i]->keys;
23582
0
    if (nbDupls) {
23583
        /*
23584
        * Search in already found duplicates first.
23585
        */
23586
0
        j = 0;
23587
0
        do {
23588
0
      if (nbFields == 1) {
23589
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23590
0
        dupls[j]->keys[0]->val);
23591
0
          if (res == -1)
23592
0
        goto internal_error;
23593
0
          if (res == 1) {
23594
        /*
23595
        * Equal key-sequence.
23596
        */
23597
0
        goto next_target;
23598
0
          }
23599
0
      } else {
23600
0
          res = 0;
23601
0
          ntkeys = dupls[j]->keys;
23602
0
          for (k = 0; k < nbFields; k++) {
23603
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23604
0
            ntkeys[k]->val);
23605
0
        if (res == -1)
23606
0
            goto internal_error;
23607
0
        if (res == 0) {
23608
            /*
23609
            * One of the keys differs.
23610
            */
23611
0
            break;
23612
0
        }
23613
0
          }
23614
0
          if (res == 1) {
23615
        /*
23616
        * Equal key-sequence found.
23617
        */
23618
0
        goto next_target;
23619
0
          }
23620
0
      }
23621
0
      j++;
23622
0
        } while (j < nbDupls);
23623
0
    }
23624
0
    if (nbNodeTable) {
23625
0
        j = 0;
23626
0
        do {
23627
0
      if (nbFields == 1) {
23628
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23629
0
        bind->nodeTable[j]->keys[0]->val);
23630
0
          if (res == -1)
23631
0
        goto internal_error;
23632
0
          if (res == 0) {
23633
        /*
23634
        * The key-sequence differs.
23635
        */
23636
0
        goto next_node_table_entry;
23637
0
          }
23638
0
      } else {
23639
0
          res = 0;
23640
0
          ntkeys = bind->nodeTable[j]->keys;
23641
0
          for (k = 0; k < nbFields; k++) {
23642
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23643
0
            ntkeys[k]->val);
23644
0
        if (res == -1)
23645
0
            goto internal_error;
23646
0
        if (res == 0) {
23647
            /*
23648
            * One of the keys differs.
23649
            */
23650
0
            goto next_node_table_entry;
23651
0
        }
23652
0
          }
23653
0
      }
23654
      /*
23655
      * Add the duplicate to the list of duplicates.
23656
      */
23657
0
      if (bind->dupls == NULL) {
23658
0
          bind->dupls = xmlSchemaItemListCreate();
23659
0
          if (bind->dupls == NULL)
23660
0
        goto internal_error;
23661
0
      }
23662
0
      if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23663
0
          goto internal_error;
23664
      /*
23665
      * Remove the duplicate entry from the IDC node-table.
23666
      */
23667
0
      bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23668
0
      bind->nbNodes--;
23669
23670
0
      goto next_target;
23671
23672
0
next_node_table_entry:
23673
0
      j++;
23674
0
        } while (j < nbNodeTable);
23675
0
    }
23676
    /*
23677
    * If everything is fine, then add the IDC target-node to
23678
    * the IDC node-table.
23679
    */
23680
0
    if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23681
0
        goto internal_error;
23682
23683
0
next_target:
23684
0
    i++;
23685
0
      } while (i < nbTargets);
23686
0
  }
23687
0
  matcher = matcher->next;
23688
0
    }
23689
0
    return(0);
23690
23691
0
internal_error:
23692
0
    return(-1);
23693
0
}
23694
23695
/**
23696
 * xmlSchemaBubbleIDCNodeTables:
23697
 * @depth: the current tree depth
23698
 *
23699
 * Merges IDC bindings of an element at @depth into the corresponding IDC
23700
 * bindings of its parent element. If a duplicate note-table entry is found,
23701
 * both, the parent node-table entry and child entry are discarded from the
23702
 * node-table of the parent.
23703
 *
23704
 * Returns 0 if OK and -1 on internal errors.
23705
 */
23706
static int
23707
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23708
0
{
23709
0
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23710
0
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23711
0
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23712
0
    xmlSchemaIDCAugPtr aidc;
23713
0
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23714
23715
0
    bind = vctxt->inode->idcTable;
23716
0
    if (bind == NULL) {
23717
  /* Fine, no table, no bubbles. */
23718
0
  return (0);
23719
0
    }
23720
23721
0
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23722
    /*
23723
    * Walk all bindings; create new or add to existing bindings.
23724
    * Remove duplicate key-sequences.
23725
    */
23726
0
    while (bind != NULL) {
23727
23728
0
  if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23729
0
      goto next_binding;
23730
  /*
23731
  * Check if the key/unique IDC table needs to be bubbled.
23732
  */
23733
0
  if (! vctxt->createIDCNodeTables) {
23734
0
      aidc = vctxt->aidcs;
23735
0
      do {
23736
0
    if (aidc->def == bind->definition) {
23737
0
        if ((aidc->keyrefDepth == -1) ||
23738
0
      (aidc->keyrefDepth >= vctxt->depth)) {
23739
0
      goto next_binding;
23740
0
        }
23741
0
        break;
23742
0
    }
23743
0
    aidc = aidc->next;
23744
0
      } while (aidc != NULL);
23745
0
  }
23746
23747
0
  if (parTable != NULL)
23748
0
      parBind = *parTable;
23749
  /*
23750
  * Search a matching parent binding for the
23751
  * IDC definition.
23752
  */
23753
0
  while (parBind != NULL) {
23754
0
      if (parBind->definition == bind->definition)
23755
0
    break;
23756
0
      parBind = parBind->next;
23757
0
  }
23758
23759
0
  if (parBind != NULL) {
23760
      /*
23761
      * Compare every node-table entry of the child node,
23762
      * i.e. the key-sequence within, ...
23763
      */
23764
0
      oldNum = parBind->nbNodes; /* Skip newly added items. */
23765
23766
0
      if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23767
0
    oldDupls = parBind->dupls->nbItems;
23768
0
    dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23769
0
      } else {
23770
0
    dupls = NULL;
23771
0
    oldDupls = 0;
23772
0
      }
23773
23774
0
      parNodes = parBind->nodeTable;
23775
0
      nbFields = bind->definition->nbFields;
23776
23777
0
      for (i = 0; i < bind->nbNodes; i++) {
23778
0
    node = bind->nodeTable[i];
23779
0
    if (node == NULL)
23780
0
        continue;
23781
    /*
23782
    * ...with every key-sequence of the parent node, already
23783
    * evaluated to be a duplicate key-sequence.
23784
    */
23785
0
    if (oldDupls) {
23786
0
        j = 0;
23787
0
        while (j < oldDupls) {
23788
0
      if (nbFields == 1) {
23789
0
          ret = xmlSchemaAreValuesEqual(
23790
0
        node->keys[0]->val,
23791
0
        dupls[j]->keys[0]->val);
23792
0
          if (ret == -1)
23793
0
        goto internal_error;
23794
0
          if (ret == 0) {
23795
0
        j++;
23796
0
        continue;
23797
0
          }
23798
0
      } else {
23799
0
          parNode = dupls[j];
23800
0
          for (k = 0; k < nbFields; k++) {
23801
0
        ret = xmlSchemaAreValuesEqual(
23802
0
            node->keys[k]->val,
23803
0
            parNode->keys[k]->val);
23804
0
        if (ret == -1)
23805
0
            goto internal_error;
23806
0
        if (ret == 0)
23807
0
            break;
23808
0
          }
23809
0
      }
23810
0
      if (ret == 1)
23811
          /* Duplicate found. */
23812
0
          break;
23813
0
      j++;
23814
0
        }
23815
0
        if (j != oldDupls) {
23816
      /* Duplicate found. Skip this entry. */
23817
0
      continue;
23818
0
        }
23819
0
    }
23820
    /*
23821
    * ... and with every key-sequence of the parent node.
23822
    */
23823
0
    if (oldNum) {
23824
0
        j = 0;
23825
0
        while (j < oldNum) {
23826
0
      parNode = parNodes[j];
23827
0
      if (nbFields == 1) {
23828
0
          ret = xmlSchemaAreValuesEqual(
23829
0
        node->keys[0]->val,
23830
0
        parNode->keys[0]->val);
23831
0
          if (ret == -1)
23832
0
        goto internal_error;
23833
0
          if (ret == 0) {
23834
0
        j++;
23835
0
        continue;
23836
0
          }
23837
0
      } else {
23838
0
          for (k = 0; k < nbFields; k++) {
23839
0
        ret = xmlSchemaAreValuesEqual(
23840
0
            node->keys[k]->val,
23841
0
            parNode->keys[k]->val);
23842
0
        if (ret == -1)
23843
0
            goto internal_error;
23844
0
        if (ret == 0)
23845
0
            break;
23846
0
          }
23847
0
      }
23848
0
      if (ret == 1)
23849
          /* Duplicate found. */
23850
0
          break;
23851
0
      j++;
23852
0
        }
23853
0
        if (j != oldNum) {
23854
      /*
23855
      * Handle duplicates. Move the duplicate in
23856
      * the parent's node-table to the list of
23857
      * duplicates.
23858
      */
23859
0
      oldNum--;
23860
0
      parBind->nbNodes--;
23861
      /*
23862
      * Move last old item to pos of duplicate.
23863
      */
23864
0
      parNodes[j] = parNodes[oldNum];
23865
23866
0
      if (parBind->nbNodes != oldNum) {
23867
          /*
23868
          * If new items exist, move last new item to
23869
          * last of old items.
23870
          */
23871
0
          parNodes[oldNum] =
23872
0
        parNodes[parBind->nbNodes];
23873
0
      }
23874
0
      if (parBind->dupls == NULL) {
23875
0
          parBind->dupls = xmlSchemaItemListCreate();
23876
0
          if (parBind->dupls == NULL)
23877
0
        goto internal_error;
23878
0
      }
23879
0
      xmlSchemaItemListAdd(parBind->dupls, parNode);
23880
0
        } else {
23881
      /*
23882
      * Add the node-table entry (node and key-sequence) of
23883
      * the child node to the node table of the parent node.
23884
      */
23885
0
      if (parBind->nodeTable == NULL) {
23886
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23887
0
        xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23888
0
          if (parBind->nodeTable == NULL) {
23889
0
        xmlSchemaVErrMemory(NULL,
23890
0
            "allocating IDC list of node-table items", NULL);
23891
0
        goto internal_error;
23892
0
          }
23893
0
          parBind->sizeNodes = 1;
23894
0
      } else if (parBind->nbNodes >= parBind->sizeNodes) {
23895
0
          parBind->sizeNodes *= 2;
23896
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23897
0
        xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23898
0
        sizeof(xmlSchemaPSVIIDCNodePtr));
23899
0
          if (parBind->nodeTable == NULL) {
23900
0
        xmlSchemaVErrMemory(NULL,
23901
0
            "re-allocating IDC list of node-table items", NULL);
23902
0
        goto internal_error;
23903
0
          }
23904
0
      }
23905
0
      parNodes = parBind->nodeTable;
23906
      /*
23907
      * Append the new node-table entry to the 'new node-table
23908
      * entries' section.
23909
      */
23910
0
      parNodes[parBind->nbNodes++] = node;
23911
0
        }
23912
23913
0
    }
23914
23915
0
      }
23916
0
  } else {
23917
      /*
23918
      * No binding for the IDC was found: create a new one and
23919
      * copy all node-tables.
23920
      */
23921
0
      parBind = xmlSchemaIDCNewBinding(bind->definition);
23922
0
      if (parBind == NULL)
23923
0
    goto internal_error;
23924
23925
      /*
23926
      * TODO: Hmm, how to optimize the initial number of
23927
      * allocated entries?
23928
      */
23929
0
      if (bind->nbNodes != 0) {
23930
    /*
23931
    * Add all IDC node-table entries.
23932
    */
23933
0
    if (! vctxt->psviExposeIDCNodeTables) {
23934
        /*
23935
        * Just move the entries.
23936
        * NOTE: this is quite save here, since
23937
        * all the keyref lookups have already been
23938
        * performed.
23939
        */
23940
0
        parBind->nodeTable = bind->nodeTable;
23941
0
        bind->nodeTable = NULL;
23942
0
        parBind->sizeNodes = bind->sizeNodes;
23943
0
        bind->sizeNodes = 0;
23944
0
        parBind->nbNodes = bind->nbNodes;
23945
0
        bind->nbNodes = 0;
23946
0
    } else {
23947
        /*
23948
        * Copy the entries.
23949
        */
23950
0
        parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23951
0
      xmlMalloc(bind->nbNodes *
23952
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
23953
0
        if (parBind->nodeTable == NULL) {
23954
0
      xmlSchemaVErrMemory(NULL,
23955
0
          "allocating an array of IDC node-table "
23956
0
          "items", NULL);
23957
0
      xmlSchemaIDCFreeBinding(parBind);
23958
0
      goto internal_error;
23959
0
        }
23960
0
        parBind->sizeNodes = bind->nbNodes;
23961
0
        parBind->nbNodes = bind->nbNodes;
23962
0
        memcpy(parBind->nodeTable, bind->nodeTable,
23963
0
      bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23964
0
    }
23965
0
      }
23966
0
      if (bind->dupls) {
23967
    /*
23968
    * Move the duplicates.
23969
    */
23970
0
    if (parBind->dupls != NULL)
23971
0
        xmlSchemaItemListFree(parBind->dupls);
23972
0
    parBind->dupls = bind->dupls;
23973
0
    bind->dupls = NULL;
23974
0
      }
23975
0
            if (parTable != NULL) {
23976
0
                if (*parTable == NULL)
23977
0
                    *parTable = parBind;
23978
0
                else {
23979
0
                    parBind->next = *parTable;
23980
0
                    *parTable = parBind;
23981
0
                }
23982
0
            }
23983
0
  }
23984
23985
0
next_binding:
23986
0
  bind = bind->next;
23987
0
    }
23988
0
    return (0);
23989
23990
0
internal_error:
23991
0
    return(-1);
23992
0
}
23993
23994
/**
23995
 * xmlSchemaCheckCVCIDCKeyRef:
23996
 * @vctxt: the WXS validation context
23997
 * @elemDecl: the element declaration
23998
 *
23999
 * Check the cvc-idc-keyref constraints.
24000
 */
24001
static int
24002
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
24003
0
{
24004
0
    xmlSchemaIDCMatcherPtr matcher;
24005
0
    xmlSchemaPSVIIDCBindingPtr bind;
24006
24007
0
    matcher = vctxt->inode->idcMatchers;
24008
    /*
24009
    * Find a keyref.
24010
    */
24011
0
    while (matcher != NULL) {
24012
0
  if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
24013
0
      matcher->targets &&
24014
0
      matcher->targets->nbItems)
24015
0
  {
24016
0
      int i, j, k, res, nbFields, hasDupls;
24017
0
      xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
24018
0
      xmlSchemaPSVIIDCNodePtr refNode = NULL;
24019
0
      xmlHashTablePtr table = NULL;
24020
24021
0
      nbFields = matcher->aidc->def->nbFields;
24022
24023
      /*
24024
      * Find the IDC node-table for the referenced IDC key/unique.
24025
      */
24026
0
      bind = vctxt->inode->idcTable;
24027
0
      while (bind != NULL) {
24028
0
    if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
24029
0
        bind->definition)
24030
0
        break;
24031
0
    bind = bind->next;
24032
0
      }
24033
0
      hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
24034
      /*
24035
      * Search for a matching key-sequences.
24036
      */
24037
0
      if (bind) {
24038
0
    table = xmlHashCreate(bind->nbNodes * 2);
24039
0
    for (j = 0; j < bind->nbNodes; j++) {
24040
0
        xmlChar *value;
24041
0
        xmlIDCHashEntryPtr r, e;
24042
0
        keys = bind->nodeTable[j]->keys;
24043
0
        xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
24044
0
        e = xmlMalloc(sizeof *e);
24045
0
        e->index = j;
24046
0
        r = xmlHashLookup(table, value);
24047
0
        if (r) {
24048
0
      e->next = r->next;
24049
0
      r->next = e;
24050
0
        } else {
24051
0
      e->next = NULL;
24052
0
      xmlHashAddEntry(table, value, e);
24053
0
        }
24054
0
        FREE_AND_NULL(value);
24055
0
    }
24056
0
      }
24057
0
      for (i = 0; i < matcher->targets->nbItems; i++) {
24058
0
    res = 0;
24059
0
    refNode = matcher->targets->items[i];
24060
0
    if (bind != NULL) {
24061
0
        xmlChar *value;
24062
0
        xmlIDCHashEntryPtr e;
24063
0
        refKeys = refNode->keys;
24064
0
        xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
24065
0
        e = xmlHashLookup(table, value);
24066
0
        FREE_AND_NULL(value);
24067
0
        res = 0;
24068
0
        for (;e; e = e->next) {
24069
0
      keys = bind->nodeTable[e->index]->keys;
24070
0
      for (k = 0; k < nbFields; k++) {
24071
0
          res = xmlSchemaAreValuesEqual(keys[k]->val,
24072
0
                refKeys[k]->val);
24073
0
          if (res == 0)
24074
0
              break;
24075
0
          else if (res == -1) {
24076
0
        return (-1);
24077
0
          }
24078
0
      }
24079
0
      if (res == 1) {
24080
          /*
24081
           * Match found.
24082
           */
24083
0
          break;
24084
0
      }
24085
0
        }
24086
0
        if ((res == 0) && hasDupls) {
24087
      /*
24088
      * Search in duplicates
24089
      */
24090
0
      for (j = 0; j < bind->dupls->nbItems; j++) {
24091
0
          keys = ((xmlSchemaPSVIIDCNodePtr)
24092
0
        bind->dupls->items[j])->keys;
24093
0
          for (k = 0; k < nbFields; k++) {
24094
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
24095
0
            refKeys[k]->val);
24096
0
        if (res == 0)
24097
0
            break;
24098
0
        else if (res == -1) {
24099
0
            return (-1);
24100
0
        }
24101
0
          }
24102
0
          if (res == 1) {
24103
        /*
24104
        * Match in duplicates found.
24105
        */
24106
0
        xmlChar *str = NULL, *strB = NULL;
24107
0
        xmlSchemaKeyrefErr(vctxt,
24108
0
            XML_SCHEMAV_CVC_IDC, refNode,
24109
0
            (xmlSchemaTypePtr) matcher->aidc->def,
24110
0
            "More than one match found for "
24111
0
            "key-sequence %s of keyref '%s'",
24112
0
            xmlSchemaFormatIDCKeySequence(vctxt, &str,
24113
0
          refNode->keys, nbFields),
24114
0
            xmlSchemaGetComponentQName(&strB,
24115
0
          matcher->aidc->def));
24116
0
        FREE_AND_NULL(str);
24117
0
        FREE_AND_NULL(strB);
24118
0
        break;
24119
0
          }
24120
0
      }
24121
0
        }
24122
0
    }
24123
24124
0
    if (res == 0) {
24125
0
        xmlChar *str = NULL, *strB = NULL;
24126
0
        xmlSchemaKeyrefErr(vctxt,
24127
0
      XML_SCHEMAV_CVC_IDC, refNode,
24128
0
      (xmlSchemaTypePtr) matcher->aidc->def,
24129
0
      "No match found for key-sequence %s of keyref '%s'",
24130
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
24131
0
          refNode->keys, nbFields),
24132
0
      xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
24133
0
        FREE_AND_NULL(str);
24134
0
        FREE_AND_NULL(strB);
24135
0
    }
24136
0
      }
24137
0
      if (table) {
24138
0
    xmlHashFree(table, xmlFreeIDCHashEntry);
24139
0
      }
24140
0
  }
24141
0
  matcher = matcher->next;
24142
0
    }
24143
    /* TODO: Return an error if any error encountered. */
24144
0
    return (0);
24145
0
}
24146
24147
/************************************************************************
24148
 *                  *
24149
 *      XML Reader validation code                      *
24150
 *                  *
24151
 ************************************************************************/
24152
24153
static xmlSchemaAttrInfoPtr
24154
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
24155
0
{
24156
0
    xmlSchemaAttrInfoPtr iattr;
24157
    /*
24158
    * Grow/create list of attribute infos.
24159
    */
24160
0
    if (vctxt->attrInfos == NULL) {
24161
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
24162
0
      xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
24163
0
  vctxt->sizeAttrInfos = 1;
24164
0
  if (vctxt->attrInfos == NULL) {
24165
0
      xmlSchemaVErrMemory(vctxt,
24166
0
    "allocating attribute info list", NULL);
24167
0
      return (NULL);
24168
0
  }
24169
0
    } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
24170
0
  vctxt->sizeAttrInfos++;
24171
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
24172
0
      xmlRealloc(vctxt->attrInfos,
24173
0
    vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
24174
0
  if (vctxt->attrInfos == NULL) {
24175
0
      xmlSchemaVErrMemory(vctxt,
24176
0
    "re-allocating attribute info list", NULL);
24177
0
      return (NULL);
24178
0
  }
24179
0
    } else {
24180
0
  iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
24181
0
  if (iattr->localName != NULL) {
24182
0
      VERROR_INT("xmlSchemaGetFreshAttrInfo",
24183
0
    "attr info not cleared");
24184
0
      return (NULL);
24185
0
  }
24186
0
  iattr->nodeType = XML_ATTRIBUTE_NODE;
24187
0
  return (iattr);
24188
0
    }
24189
    /*
24190
    * Create an attribute info.
24191
    */
24192
0
    iattr = (xmlSchemaAttrInfoPtr)
24193
0
  xmlMalloc(sizeof(xmlSchemaAttrInfo));
24194
0
    if (iattr == NULL) {
24195
0
  xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
24196
0
  return (NULL);
24197
0
    }
24198
0
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
24199
0
    iattr->nodeType = XML_ATTRIBUTE_NODE;
24200
0
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
24201
24202
0
    return (iattr);
24203
0
}
24204
24205
static int
24206
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
24207
      xmlNodePtr attrNode,
24208
      int nodeLine,
24209
      const xmlChar *localName,
24210
      const xmlChar *nsName,
24211
      int ownedNames,
24212
      xmlChar *value,
24213
      int ownedValue)
24214
0
{
24215
0
    xmlSchemaAttrInfoPtr attr;
24216
24217
0
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
24218
0
    if (attr == NULL) {
24219
0
  VERROR_INT("xmlSchemaPushAttribute",
24220
0
      "calling xmlSchemaGetFreshAttrInfo()");
24221
0
  return (-1);
24222
0
    }
24223
0
    attr->node = attrNode;
24224
0
    attr->nodeLine = nodeLine;
24225
0
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
24226
0
    attr->localName = localName;
24227
0
    attr->nsName = nsName;
24228
0
    if (ownedNames)
24229
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
24230
    /*
24231
    * Evaluate if it's an XSI attribute.
24232
    */
24233
0
    if (nsName != NULL) {
24234
0
  if (xmlStrEqual(localName, BAD_CAST "nil")) {
24235
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24236
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
24237
0
      }
24238
0
  } else if (xmlStrEqual(localName, BAD_CAST "type")) {
24239
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24240
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
24241
0
      }
24242
0
  } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
24243
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24244
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
24245
0
      }
24246
0
  } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
24247
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24248
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
24249
0
      }
24250
0
  } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
24251
0
      attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
24252
0
  }
24253
0
    }
24254
0
    attr->value = value;
24255
0
    if (ownedValue)
24256
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
24257
0
    if (attr->metaType != 0)
24258
0
  attr->state = XML_SCHEMAS_ATTR_META;
24259
0
    return (0);
24260
0
}
24261
24262
/**
24263
 * xmlSchemaClearElemInfo:
24264
 * @vctxt: the WXS validation context
24265
 * @ielem: the element information item
24266
 */
24267
static void
24268
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
24269
           xmlSchemaNodeInfoPtr ielem)
24270
0
{
24271
0
    ielem->hasKeyrefs = 0;
24272
0
    ielem->appliedXPath = 0;
24273
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
24274
0
  FREE_AND_NULL(ielem->localName);
24275
0
  FREE_AND_NULL(ielem->nsName);
24276
0
    } else {
24277
0
  ielem->localName = NULL;
24278
0
  ielem->nsName = NULL;
24279
0
    }
24280
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24281
0
  FREE_AND_NULL(ielem->value);
24282
0
    } else {
24283
0
  ielem->value = NULL;
24284
0
    }
24285
0
    if (ielem->val != NULL) {
24286
  /*
24287
  * PSVI TODO: Be careful not to free it when the value is
24288
  * exposed via PSVI.
24289
  */
24290
0
  xmlSchemaFreeValue(ielem->val);
24291
0
  ielem->val = NULL;
24292
0
    }
24293
0
    if (ielem->idcMatchers != NULL) {
24294
  /*
24295
  * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24296
  *   Does it work?
24297
  */
24298
0
  xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24299
#if 0
24300
  xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24301
#endif
24302
0
  ielem->idcMatchers = NULL;
24303
0
    }
24304
0
    if (ielem->idcTable != NULL) {
24305
  /*
24306
  * OPTIMIZE TODO: Use a pool of IDC tables??.
24307
  */
24308
0
  xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24309
0
  ielem->idcTable = NULL;
24310
0
    }
24311
0
    if (ielem->regexCtxt != NULL) {
24312
0
  xmlRegFreeExecCtxt(ielem->regexCtxt);
24313
0
  ielem->regexCtxt = NULL;
24314
0
    }
24315
0
    if (ielem->nsBindings != NULL) {
24316
0
  xmlFree((xmlChar **)ielem->nsBindings);
24317
0
  ielem->nsBindings = NULL;
24318
0
  ielem->nbNsBindings = 0;
24319
0
  ielem->sizeNsBindings = 0;
24320
0
    }
24321
0
}
24322
24323
/**
24324
 * xmlSchemaGetFreshElemInfo:
24325
 * @vctxt: the schema validation context
24326
 *
24327
 * Creates/reuses and initializes the element info item for
24328
 * the current tree depth.
24329
 *
24330
 * Returns the element info item or NULL on API or internal errors.
24331
 */
24332
static xmlSchemaNodeInfoPtr
24333
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24334
0
{
24335
0
    xmlSchemaNodeInfoPtr info = NULL;
24336
24337
0
    if (vctxt->depth > vctxt->sizeElemInfos) {
24338
0
  VERROR_INT("xmlSchemaGetFreshElemInfo",
24339
0
      "inconsistent depth encountered");
24340
0
  return (NULL);
24341
0
    }
24342
0
    if (vctxt->elemInfos == NULL) {
24343
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24344
0
      xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24345
0
  if (vctxt->elemInfos == NULL) {
24346
0
      xmlSchemaVErrMemory(vctxt,
24347
0
    "allocating the element info array", NULL);
24348
0
      return (NULL);
24349
0
  }
24350
0
  memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24351
0
  vctxt->sizeElemInfos = 10;
24352
0
    } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24353
0
  int i = vctxt->sizeElemInfos;
24354
24355
0
  vctxt->sizeElemInfos *= 2;
24356
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24357
0
      xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24358
0
      sizeof(xmlSchemaNodeInfoPtr));
24359
0
  if (vctxt->elemInfos == NULL) {
24360
0
      xmlSchemaVErrMemory(vctxt,
24361
0
    "re-allocating the element info array", NULL);
24362
0
      return (NULL);
24363
0
  }
24364
  /*
24365
  * We need the new memory to be NULLed.
24366
  * TODO: Use memset instead?
24367
  */
24368
0
  for (; i < vctxt->sizeElemInfos; i++)
24369
0
      vctxt->elemInfos[i] = NULL;
24370
0
    } else
24371
0
  info = vctxt->elemInfos[vctxt->depth];
24372
24373
0
    if (info == NULL) {
24374
0
  info = (xmlSchemaNodeInfoPtr)
24375
0
      xmlMalloc(sizeof(xmlSchemaNodeInfo));
24376
0
  if (info == NULL) {
24377
0
      xmlSchemaVErrMemory(vctxt,
24378
0
    "allocating an element info", NULL);
24379
0
      return (NULL);
24380
0
  }
24381
0
  vctxt->elemInfos[vctxt->depth] = info;
24382
0
    } else {
24383
0
  if (info->localName != NULL) {
24384
0
      VERROR_INT("xmlSchemaGetFreshElemInfo",
24385
0
    "elem info has not been cleared");
24386
0
      return (NULL);
24387
0
  }
24388
0
    }
24389
0
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
24390
0
    info->nodeType = XML_ELEMENT_NODE;
24391
0
    info->depth = vctxt->depth;
24392
24393
0
    return (info);
24394
0
}
24395
24396
0
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24397
0
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24398
0
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24399
24400
static int
24401
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24402
      xmlNodePtr node,
24403
      xmlSchemaTypePtr type,
24404
      xmlSchemaValType valType,
24405
      const xmlChar * value,
24406
      xmlSchemaValPtr val,
24407
      unsigned long length,
24408
      int fireErrors)
24409
0
{
24410
0
    int ret, error = 0, found;
24411
24412
0
    xmlSchemaTypePtr tmpType;
24413
0
    xmlSchemaFacetLinkPtr facetLink;
24414
0
    xmlSchemaFacetPtr facet;
24415
0
    unsigned long len = 0;
24416
0
    xmlSchemaWhitespaceValueType ws;
24417
24418
    /*
24419
    * In Libxml2, derived built-in types have currently no explicit facets.
24420
    */
24421
0
    if (type->type == XML_SCHEMA_TYPE_BASIC)
24422
0
  return (0);
24423
24424
    /*
24425
    * NOTE: Do not jump away, if the facetSet of the given type is
24426
    * empty: until now, "pattern" and "enumeration" facets of the
24427
    * *base types* need to be checked as well.
24428
    */
24429
0
    if (type->facetSet == NULL)
24430
0
  goto pattern_and_enum;
24431
24432
0
    if (! WXS_IS_ATOMIC(type)) {
24433
0
  if (WXS_IS_LIST(type))
24434
0
      goto WXS_IS_LIST;
24435
0
  else
24436
0
      goto pattern_and_enum;
24437
0
    }
24438
24439
    /*
24440
    * Whitespace handling is only of importance for string-based
24441
    * types.
24442
    */
24443
0
    tmpType = xmlSchemaGetPrimitiveType(type);
24444
0
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24445
0
  WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24446
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24447
0
    } else
24448
0
  ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24449
24450
    /*
24451
    * If the value was not computed (for string or
24452
    * anySimpleType based types), then use the provided
24453
    * type.
24454
    */
24455
0
    if (val != NULL)
24456
0
  valType = xmlSchemaGetValType(val);
24457
24458
0
    ret = 0;
24459
0
    for (facetLink = type->facetSet; facetLink != NULL;
24460
0
  facetLink = facetLink->next) {
24461
  /*
24462
  * Skip the pattern "whiteSpace": it is used to
24463
  * format the character content beforehand.
24464
  */
24465
0
  switch (facetLink->facet->type) {
24466
0
      case XML_SCHEMA_FACET_WHITESPACE:
24467
0
      case XML_SCHEMA_FACET_PATTERN:
24468
0
      case XML_SCHEMA_FACET_ENUMERATION:
24469
0
    continue;
24470
0
      case XML_SCHEMA_FACET_LENGTH:
24471
0
      case XML_SCHEMA_FACET_MINLENGTH:
24472
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24473
0
    ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24474
0
        valType, value, val, &len, ws);
24475
0
    break;
24476
0
      default:
24477
0
    ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24478
0
        valType, value, val, ws);
24479
0
    break;
24480
0
  }
24481
0
  if (ret < 0) {
24482
0
      AERROR_INT("xmlSchemaValidateFacets",
24483
0
    "validating against a atomic type facet");
24484
0
      return (-1);
24485
0
  } else if (ret > 0) {
24486
0
      if (fireErrors)
24487
0
    xmlSchemaFacetErr(actxt, ret, node,
24488
0
    value, len, type, facetLink->facet, NULL, NULL, NULL);
24489
0
      else
24490
0
    return (ret);
24491
0
      if (error == 0)
24492
0
    error = ret;
24493
0
  }
24494
0
  ret = 0;
24495
0
    }
24496
24497
0
WXS_IS_LIST:
24498
0
    if (! WXS_IS_LIST(type))
24499
0
  goto pattern_and_enum;
24500
    /*
24501
    * "length", "minLength" and "maxLength" of list types.
24502
    */
24503
0
    ret = 0;
24504
0
    for (facetLink = type->facetSet; facetLink != NULL;
24505
0
  facetLink = facetLink->next) {
24506
24507
0
  switch (facetLink->facet->type) {
24508
0
      case XML_SCHEMA_FACET_LENGTH:
24509
0
      case XML_SCHEMA_FACET_MINLENGTH:
24510
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24511
0
    ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24512
0
        value, length, NULL);
24513
0
    break;
24514
0
      default:
24515
0
    continue;
24516
0
  }
24517
0
  if (ret < 0) {
24518
0
      AERROR_INT("xmlSchemaValidateFacets",
24519
0
    "validating against a list type facet");
24520
0
      return (-1);
24521
0
  } else if (ret > 0) {
24522
0
      if (fireErrors)
24523
0
    xmlSchemaFacetErr(actxt, ret, node,
24524
0
    value, length, type, facetLink->facet, NULL, NULL, NULL);
24525
0
      else
24526
0
    return (ret);
24527
0
      if (error == 0)
24528
0
    error = ret;
24529
0
  }
24530
0
  ret = 0;
24531
0
    }
24532
24533
0
pattern_and_enum:
24534
0
    found = 0;
24535
    /*
24536
    * Process enumerations. Facet values are in the value space
24537
    * of the defining type's base type. This seems to be a bug in the
24538
    * XML Schema 1.0 spec. Use the whitespace type of the base type.
24539
    * Only the first set of enumerations in the ancestor-or-self axis
24540
    * is used for validation.
24541
    */
24542
0
    ret = 0;
24543
0
    tmpType = type;
24544
0
    do {
24545
0
        for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24546
0
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24547
0
                continue;
24548
0
            found = 1;
24549
0
            ret = xmlSchemaAreValuesEqual(facet->val, val);
24550
0
            if (ret == 1)
24551
0
                break;
24552
0
            else if (ret < 0) {
24553
0
                AERROR_INT("xmlSchemaValidateFacets",
24554
0
                    "validating against an enumeration facet");
24555
0
                return (-1);
24556
0
            }
24557
0
        }
24558
0
        if (ret != 0)
24559
0
            break;
24560
        /*
24561
        * Break on the first set of enumerations. Any additional
24562
        *  enumerations which might be existent on the ancestors
24563
        *  of the current type are restricted by this set; thus
24564
        *  *must* *not* be taken into account.
24565
        */
24566
0
        if (found)
24567
0
            break;
24568
0
        tmpType = tmpType->baseType;
24569
0
    } while ((tmpType != NULL) &&
24570
0
        (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24571
0
    if (found && (ret == 0)) {
24572
0
        ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24573
0
        if (fireErrors) {
24574
0
            xmlSchemaFacetErr(actxt, ret, node,
24575
0
                value, 0, type, NULL, NULL, NULL, NULL);
24576
0
        } else
24577
0
            return (ret);
24578
0
        if (error == 0)
24579
0
            error = ret;
24580
0
    }
24581
24582
    /*
24583
    * Process patters. Pattern facets are ORed at type level
24584
    * and ANDed if derived. Walk the base type axis.
24585
    */
24586
0
    tmpType = type;
24587
0
    facet = NULL;
24588
0
    do {
24589
0
        found = 0;
24590
0
        for (facetLink = tmpType->facetSet; facetLink != NULL;
24591
0
            facetLink = facetLink->next) {
24592
0
            if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24593
0
                continue;
24594
0
            found = 1;
24595
            /*
24596
            * NOTE that for patterns, @value needs to be the
24597
            * normalized value.
24598
            */
24599
0
            ret = xmlRegexpExec(facetLink->facet->regexp, value);
24600
0
            if (ret == 1)
24601
0
                break;
24602
0
            else if (ret < 0) {
24603
0
                AERROR_INT("xmlSchemaValidateFacets",
24604
0
                    "validating against a pattern facet");
24605
0
                return (-1);
24606
0
            } else {
24607
                /*
24608
                * Save the last non-validating facet.
24609
                */
24610
0
                facet = facetLink->facet;
24611
0
            }
24612
0
        }
24613
0
        if (found && (ret != 1)) {
24614
0
            ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24615
0
            if (fireErrors) {
24616
0
                xmlSchemaFacetErr(actxt, ret, node,
24617
0
                    value, 0, type, facet, NULL, NULL, NULL);
24618
0
            } else
24619
0
                return (ret);
24620
0
            if (error == 0)
24621
0
                error = ret;
24622
0
            break;
24623
0
        }
24624
0
        tmpType = tmpType->baseType;
24625
0
    } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24626
24627
0
    return (error);
24628
0
}
24629
24630
static xmlChar *
24631
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24632
      const xmlChar *value)
24633
0
{
24634
0
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24635
0
  case XML_SCHEMA_WHITESPACE_COLLAPSE:
24636
0
      return (xmlSchemaCollapseString(value));
24637
0
  case XML_SCHEMA_WHITESPACE_REPLACE:
24638
0
      return (xmlSchemaWhiteSpaceReplace(value));
24639
0
  default:
24640
0
      return (NULL);
24641
0
    }
24642
0
}
24643
24644
static int
24645
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24646
           const xmlChar *value,
24647
           xmlSchemaValPtr *val,
24648
           int valNeeded)
24649
0
{
24650
0
    int ret;
24651
0
    xmlChar *stripped;
24652
0
    const xmlChar *nsName;
24653
0
    xmlChar *local, *prefix = NULL;
24654
24655
0
    ret = xmlValidateQName(value, 1);
24656
0
    if (ret != 0) {
24657
0
  if (ret == -1) {
24658
0
      VERROR_INT("xmlSchemaValidateQName",
24659
0
    "calling xmlValidateQName()");
24660
0
      return (-1);
24661
0
  }
24662
0
  return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24663
0
    }
24664
    /*
24665
    * NOTE: xmlSplitQName2 will always return a duplicated
24666
    * strings.
24667
    */
24668
    /* TODO: Export and use xmlSchemaStrip instead */
24669
0
    stripped = xmlSchemaCollapseString(value);
24670
0
    local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24671
0
    xmlFree(stripped);
24672
0
    if (local == NULL)
24673
0
  local = xmlStrdup(value);
24674
    /*
24675
    * OPTIMIZE TODO: Use flags for:
24676
    *  - is there any namespace binding?
24677
    *  - is there a default namespace?
24678
    */
24679
0
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24680
24681
0
    if (prefix != NULL) {
24682
0
  xmlFree(prefix);
24683
  /*
24684
  * A namespace must be found if the prefix is
24685
  * NOT NULL.
24686
  */
24687
0
  if (nsName == NULL) {
24688
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24689
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24690
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24691
0
    "The QName value '%s' has no "
24692
0
    "corresponding namespace declaration in "
24693
0
    "scope", value, NULL);
24694
0
      if (local != NULL)
24695
0
    xmlFree(local);
24696
0
      return (ret);
24697
0
  }
24698
0
    }
24699
0
    if (valNeeded && val) {
24700
0
  if (nsName != NULL)
24701
0
      *val = xmlSchemaNewQNameValue(
24702
0
    BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24703
0
  else
24704
0
      *val = xmlSchemaNewQNameValue(NULL,
24705
0
    BAD_CAST local);
24706
0
    } else
24707
0
  xmlFree(local);
24708
0
    return (0);
24709
0
}
24710
24711
/*
24712
* cvc-simple-type
24713
*/
24714
static int
24715
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24716
           xmlNodePtr node,
24717
           xmlSchemaTypePtr type,
24718
           const xmlChar *value,
24719
           xmlSchemaValPtr *retVal,
24720
           int fireErrors,
24721
           int normalize,
24722
           int isNormalized)
24723
0
{
24724
0
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
24725
0
    xmlSchemaValPtr val = NULL;
24726
    /* xmlSchemaWhitespaceValueType ws; */
24727
0
    xmlChar *normValue = NULL;
24728
24729
0
#define NORMALIZE(atype) \
24730
0
    if ((! isNormalized) && \
24731
0
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24732
0
  normValue = xmlSchemaNormalizeValue(atype, value); \
24733
0
  if (normValue != NULL) \
24734
0
      value = normValue; \
24735
0
  isNormalized = 1; \
24736
0
    }
24737
24738
0
    if ((retVal != NULL) && (*retVal != NULL)) {
24739
0
  xmlSchemaFreeValue(*retVal);
24740
0
  *retVal = NULL;
24741
0
    }
24742
    /*
24743
    * 3.14.4 Simple Type Definition Validation Rules
24744
    * Validation Rule: String Valid
24745
    */
24746
    /*
24747
    * 1 It is schema-valid with respect to that definition as defined
24748
    * by Datatype Valid in [XML Schemas: Datatypes].
24749
    */
24750
    /*
24751
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24752
    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24753
    * the string must be a `declared entity name`.
24754
    */
24755
    /*
24756
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24757
    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24758
    * then every whitespace-delimited substring of the string must be a `declared
24759
    * entity name`.
24760
    */
24761
    /*
24762
    * 2.3 otherwise no further condition applies.
24763
    */
24764
0
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24765
0
  valNeeded = 1;
24766
0
    if (value == NULL)
24767
0
  value = BAD_CAST "";
24768
0
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24769
0
  xmlSchemaTypePtr biType; /* The built-in type. */
24770
  /*
24771
  * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24772
  * a literal in the `lexical space` of {base type definition}"
24773
  */
24774
  /*
24775
  * Whitespace-normalize.
24776
  */
24777
0
  NORMALIZE(type);
24778
0
  if (type->type != XML_SCHEMA_TYPE_BASIC) {
24779
      /*
24780
      * Get the built-in type.
24781
      */
24782
0
      biType = type->baseType;
24783
0
      while ((biType != NULL) &&
24784
0
    (biType->type != XML_SCHEMA_TYPE_BASIC))
24785
0
    biType = biType->baseType;
24786
24787
0
      if (biType == NULL) {
24788
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24789
0
        "could not get the built-in type");
24790
0
    goto internal_error;
24791
0
      }
24792
0
  } else
24793
0
      biType = type;
24794
  /*
24795
  * NOTATIONs need to be processed here, since they need
24796
  * to lookup in the hashtable of NOTATION declarations of the schema.
24797
  */
24798
0
  if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24799
0
      switch (biType->builtInType) {
24800
0
    case XML_SCHEMAS_NOTATION:
24801
0
        ret = xmlSchemaValidateNotation(
24802
0
      (xmlSchemaValidCtxtPtr) actxt,
24803
0
      ((xmlSchemaValidCtxtPtr) actxt)->schema,
24804
0
      NULL, value, &val, valNeeded);
24805
0
        break;
24806
0
    case XML_SCHEMAS_QNAME:
24807
0
        ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24808
0
      value, &val, valNeeded);
24809
0
        break;
24810
0
    default:
24811
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24812
0
        if (valNeeded)
24813
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24814
0
          value, &val, node);
24815
0
        else
24816
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24817
0
          value, NULL, node);
24818
0
        break;
24819
0
      }
24820
0
  } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24821
0
      switch (biType->builtInType) {
24822
0
    case XML_SCHEMAS_NOTATION:
24823
0
        ret = xmlSchemaValidateNotation(NULL,
24824
0
      ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24825
0
      value, &val, valNeeded);
24826
0
        break;
24827
0
    default:
24828
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24829
0
        if (valNeeded)
24830
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24831
0
          value, &val, node);
24832
0
        else
24833
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24834
0
          value, NULL, node);
24835
0
        break;
24836
0
      }
24837
0
  } else {
24838
      /*
24839
      * Validation via a public API is not implemented yet.
24840
      */
24841
0
      TODO
24842
0
      goto internal_error;
24843
0
  }
24844
0
  if (ret != 0) {
24845
0
      if (ret < 0) {
24846
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24847
0
        "validating against a built-in type");
24848
0
    goto internal_error;
24849
0
      }
24850
0
      if (WXS_IS_LIST(type))
24851
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24852
0
      else
24853
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24854
0
  }
24855
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24856
      /*
24857
      * Check facets.
24858
      */
24859
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24860
0
    (xmlSchemaValType) biType->builtInType, value, val,
24861
0
    0, fireErrors);
24862
0
      if (ret != 0) {
24863
0
    if (ret < 0) {
24864
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24865
0
      "validating facets of atomic simple type");
24866
0
        goto internal_error;
24867
0
    }
24868
0
    if (WXS_IS_LIST(type))
24869
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24870
0
    else
24871
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24872
0
      }
24873
0
  }
24874
0
  else if (fireErrors && (ret > 0))
24875
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24876
0
    } else if (WXS_IS_LIST(type)) {
24877
24878
0
  xmlSchemaTypePtr itemType;
24879
0
  const xmlChar *cur, *end;
24880
0
  xmlChar *tmpValue = NULL;
24881
0
  unsigned long len = 0;
24882
0
  xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24883
  /* 1.2.2 if {variety} is `list` then the string must be a sequence
24884
  * of white space separated tokens, each of which `match`es a literal
24885
  * in the `lexical space` of {item type definition}
24886
  */
24887
  /*
24888
  * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24889
  * the list type has an enum or pattern facet.
24890
  */
24891
0
  NORMALIZE(type);
24892
  /*
24893
  * VAL TODO: Optimize validation of empty values.
24894
  * VAL TODO: We do not have computed values for lists.
24895
  */
24896
0
  itemType = WXS_LIST_ITEMTYPE(type);
24897
0
  cur = value;
24898
0
  do {
24899
0
      while (IS_BLANK_CH(*cur))
24900
0
    cur++;
24901
0
      end = cur;
24902
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24903
0
    end++;
24904
0
      if (end == cur)
24905
0
    break;
24906
0
      tmpValue = xmlStrndup(cur, end - cur);
24907
0
      len++;
24908
24909
0
      if (valNeeded)
24910
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24911
0
        tmpValue, &curVal, fireErrors, 0, 1);
24912
0
      else
24913
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24914
0
        tmpValue, NULL, fireErrors, 0, 1);
24915
0
      FREE_AND_NULL(tmpValue);
24916
0
      if (curVal != NULL) {
24917
    /*
24918
    * Add to list of computed values.
24919
    */
24920
0
    if (val == NULL)
24921
0
        val = curVal;
24922
0
    else
24923
0
        xmlSchemaValueAppend(prevVal, curVal);
24924
0
    prevVal = curVal;
24925
0
    curVal = NULL;
24926
0
      }
24927
0
      if (ret != 0) {
24928
0
    if (ret < 0) {
24929
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24930
0
      "validating an item of list simple type");
24931
0
        goto internal_error;
24932
0
    }
24933
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24934
0
    break;
24935
0
      }
24936
0
      cur = end;
24937
0
  } while (*cur != 0);
24938
0
  FREE_AND_NULL(tmpValue);
24939
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24940
      /*
24941
      * Apply facets (pattern, enumeration).
24942
      */
24943
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24944
0
    XML_SCHEMAS_UNKNOWN, value, val,
24945
0
    len, fireErrors);
24946
0
      if (ret != 0) {
24947
0
    if (ret < 0) {
24948
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24949
0
      "validating facets of list simple type");
24950
0
        goto internal_error;
24951
0
    }
24952
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24953
0
      }
24954
0
  }
24955
0
  if (fireErrors && (ret > 0)) {
24956
      /*
24957
      * Report the normalized value.
24958
      */
24959
0
      normalize = 1;
24960
0
      NORMALIZE(type);
24961
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24962
0
  }
24963
0
    } else if (WXS_IS_UNION(type)) {
24964
0
  xmlSchemaTypeLinkPtr memberLink;
24965
  /*
24966
  * TODO: For all datatypes `derived` by `union`  whiteSpace does
24967
  * not apply directly; however, the normalization behavior of `union`
24968
  * types is controlled by the value of whiteSpace on that one of the
24969
  * `memberTypes` against which the `union` is successfully validated.
24970
  *
24971
  * This means that the value is normalized by the first validating
24972
  * member type, then the facets of the union type are applied. This
24973
  * needs changing of the value!
24974
  */
24975
24976
  /*
24977
  * 1.2.3 if {variety} is `union` then the string must `match` a
24978
  * literal in the `lexical space` of at least one member of
24979
  * {member type definitions}
24980
  */
24981
0
  memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24982
0
  if (memberLink == NULL) {
24983
0
      AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24984
0
    "union simple type has no member types");
24985
0
      goto internal_error;
24986
0
  }
24987
  /*
24988
  * Always normalize union type values, since we currently
24989
  * cannot store the whitespace information with the value
24990
  * itself; otherwise a later value-comparison would be
24991
  * not possible.
24992
  */
24993
0
  while (memberLink != NULL) {
24994
0
      if (valNeeded)
24995
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24996
0
        memberLink->type, value, &val, 0, 1, 0);
24997
0
      else
24998
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24999
0
        memberLink->type, value, NULL, 0, 1, 0);
25000
0
      if (ret <= 0)
25001
0
    break;
25002
0
      memberLink = memberLink->next;
25003
0
  }
25004
0
  if (ret != 0) {
25005
0
      if (ret < 0) {
25006
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
25007
0
        "validating members of union simple type");
25008
0
    goto internal_error;
25009
0
      }
25010
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
25011
0
  }
25012
  /*
25013
  * Apply facets (pattern, enumeration).
25014
  */
25015
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
25016
      /*
25017
      * The normalization behavior of `union` types is controlled by
25018
      * the value of whiteSpace on that one of the `memberTypes`
25019
      * against which the `union` is successfully validated.
25020
      */
25021
0
      NORMALIZE(memberLink->type);
25022
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
25023
0
    XML_SCHEMAS_UNKNOWN, value, val,
25024
0
    0, fireErrors);
25025
0
      if (ret != 0) {
25026
0
    if (ret < 0) {
25027
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
25028
0
      "validating facets of union simple type");
25029
0
        goto internal_error;
25030
0
    }
25031
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
25032
0
      }
25033
0
  }
25034
0
  if (fireErrors && (ret > 0))
25035
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
25036
0
    }
25037
25038
0
    if (normValue != NULL)
25039
0
  xmlFree(normValue);
25040
0
    if (ret == 0) {
25041
0
  if (retVal != NULL)
25042
0
      *retVal = val;
25043
0
  else if (val != NULL)
25044
0
      xmlSchemaFreeValue(val);
25045
0
    } else if (val != NULL)
25046
0
  xmlSchemaFreeValue(val);
25047
0
    return (ret);
25048
0
internal_error:
25049
0
    if (normValue != NULL)
25050
0
  xmlFree(normValue);
25051
0
    if (val != NULL)
25052
0
  xmlSchemaFreeValue(val);
25053
0
    return (-1);
25054
0
}
25055
25056
static int
25057
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
25058
         const xmlChar *value,
25059
         const xmlChar **nsName,
25060
         const xmlChar **localName)
25061
0
{
25062
0
    int ret = 0;
25063
25064
0
    if ((nsName == NULL) || (localName == NULL))
25065
0
  return (-1);
25066
0
    *nsName = NULL;
25067
0
    *localName = NULL;
25068
25069
0
    ret = xmlValidateQName(value, 1);
25070
0
    if (ret == -1)
25071
0
  return (-1);
25072
0
    if (ret > 0) {
25073
0
  xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
25074
0
      XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
25075
0
      value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
25076
0
  return (1);
25077
0
    }
25078
0
    {
25079
0
  xmlChar *local = NULL;
25080
0
  xmlChar *prefix;
25081
25082
  /*
25083
  * NOTE: xmlSplitQName2 will return a duplicated
25084
  * string.
25085
  */
25086
0
  local = xmlSplitQName2(value, &prefix);
25087
0
  if (local == NULL)
25088
0
      *localName = xmlDictLookup(vctxt->dict, value, -1);
25089
0
  else {
25090
0
      *localName = xmlDictLookup(vctxt->dict, local, -1);
25091
0
      xmlFree(local);
25092
0
  }
25093
25094
0
  *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
25095
25096
0
  if (prefix != NULL) {
25097
0
      xmlFree(prefix);
25098
      /*
25099
      * A namespace must be found if the prefix is NOT NULL.
25100
      */
25101
0
      if (*nsName == NULL) {
25102
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25103
0
        XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
25104
0
        WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
25105
0
        "The QName value '%s' has no "
25106
0
        "corresponding namespace declaration in scope",
25107
0
        value, NULL);
25108
0
    return (2);
25109
0
      }
25110
0
  }
25111
0
    }
25112
0
    return (0);
25113
0
}
25114
25115
static int
25116
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
25117
      xmlSchemaAttrInfoPtr iattr,
25118
      xmlSchemaTypePtr *localType,
25119
      xmlSchemaElementPtr elemDecl)
25120
0
{
25121
0
    int ret = 0;
25122
    /*
25123
    * cvc-elt (3.3.4) : (4)
25124
    * AND
25125
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
25126
    *   (1.2.1.2.1) - (1.2.1.2.4)
25127
    * Handle 'xsi:type'.
25128
    */
25129
0
    if (localType == NULL)
25130
0
  return (-1);
25131
0
    *localType = NULL;
25132
0
    if (iattr == NULL)
25133
0
  return (0);
25134
0
    else {
25135
0
  const xmlChar *nsName = NULL, *local = NULL;
25136
  /*
25137
  * TODO: We should report a *warning* that the type was overridden
25138
  * by the instance.
25139
  */
25140
0
  ACTIVATE_ATTRIBUTE(iattr);
25141
  /*
25142
  * (cvc-elt) (3.3.4) : (4.1)
25143
  * (cvc-assess-elt) (1.2.1.2.2)
25144
  */
25145
0
  ret = xmlSchemaVExpandQName(vctxt, iattr->value,
25146
0
      &nsName, &local);
25147
0
  if (ret != 0) {
25148
0
      if (ret < 0) {
25149
0
    VERROR_INT("xmlSchemaValidateElementByDeclaration",
25150
0
        "calling xmlSchemaQNameExpand() to validate the "
25151
0
        "attribute 'xsi:type'");
25152
0
    goto internal_error;
25153
0
      }
25154
0
      goto exit;
25155
0
  }
25156
  /*
25157
  * (cvc-elt) (3.3.4) : (4.2)
25158
  * (cvc-assess-elt) (1.2.1.2.3)
25159
  */
25160
0
  *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
25161
0
  if (*localType == NULL) {
25162
0
      xmlChar *str = NULL;
25163
25164
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
25165
0
    XML_SCHEMAV_CVC_ELT_4_2, NULL,
25166
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
25167
0
    "The QName value '%s' of the xsi:type attribute does not "
25168
0
    "resolve to a type definition",
25169
0
    xmlSchemaFormatQName(&str, nsName, local), NULL);
25170
0
      FREE_AND_NULL(str);
25171
0
      ret = vctxt->err;
25172
0
      goto exit;
25173
0
  }
25174
0
  if (elemDecl != NULL) {
25175
0
      int set = 0;
25176
25177
      /*
25178
      * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
25179
      * "The `local type definition` must be validly
25180
      * derived from the {type definition} given the union of
25181
      * the {disallowed substitutions} and the {type definition}'s
25182
      * {prohibited substitutions}, as defined in
25183
      * Type Derivation OK (Complex) ($3.4.6)
25184
      * (if it is a complex type definition),
25185
      * or given {disallowed substitutions} as defined in Type
25186
      * Derivation OK (Simple) ($3.14.6) (if it is a simple type
25187
      * definition)."
25188
      *
25189
      * {disallowed substitutions}: the "block" on the element decl.
25190
      * {prohibited substitutions}: the "block" on the type def.
25191
      */
25192
      /*
25193
      * OPTIMIZE TODO: We could map types already evaluated
25194
      * to be validly derived from other types to avoid checking
25195
      * this over and over for the same types.
25196
      */
25197
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
25198
0
    (elemDecl->subtypes->flags &
25199
0
        XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
25200
0
    set |= SUBSET_EXTENSION;
25201
25202
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
25203
0
    (elemDecl->subtypes->flags &
25204
0
        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
25205
0
    set |= SUBSET_RESTRICTION;
25206
25207
      /*
25208
      * REMOVED and CHANGED since this produced a parser context
25209
      * which adds to the string dict of the schema. So this would
25210
      * change the schema and we don't want this. We don't need
25211
      * the parser context anymore.
25212
      *
25213
      * if ((vctxt->pctxt == NULL) &&
25214
      * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
25215
      *     return (-1);
25216
      */
25217
25218
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
25219
0
    elemDecl->subtypes, set) != 0) {
25220
0
    xmlChar *str = NULL;
25221
25222
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25223
0
        XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
25224
0
        "The type definition '%s', specified by xsi:type, is "
25225
0
        "blocked or not validly derived from the type definition "
25226
0
        "of the element declaration",
25227
0
        xmlSchemaFormatQName(&str,
25228
0
      (*localType)->targetNamespace,
25229
0
      (*localType)->name),
25230
0
        NULL);
25231
0
    FREE_AND_NULL(str);
25232
0
    ret = vctxt->err;
25233
0
    *localType = NULL;
25234
0
      }
25235
0
  }
25236
0
    }
25237
0
exit:
25238
0
    ACTIVATE_ELEM;
25239
0
    return (ret);
25240
0
internal_error:
25241
0
    ACTIVATE_ELEM;
25242
0
    return (-1);
25243
0
}
25244
25245
static int
25246
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
25247
0
{
25248
0
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
25249
0
    xmlSchemaTypePtr actualType;
25250
25251
    /*
25252
    * cvc-elt (3.3.4) : 1
25253
    */
25254
0
    if (elemDecl == NULL) {
25255
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
25256
0
      "No matching declaration available");
25257
0
        return (vctxt->err);
25258
0
    }
25259
0
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
25260
    /*
25261
    * cvc-elt (3.3.4) : 2
25262
    */
25263
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
25264
0
  VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
25265
0
      "The element declaration is abstract");
25266
0
        return (vctxt->err);
25267
0
    }
25268
0
    if (actualType == NULL) {
25269
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25270
0
      "The type definition is absent");
25271
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25272
0
    }
25273
0
    if (vctxt->nbAttrInfos != 0) {
25274
0
  int ret;
25275
0
  xmlSchemaAttrInfoPtr iattr;
25276
  /*
25277
  * cvc-elt (3.3.4) : 3
25278
  * Handle 'xsi:nil'.
25279
  */
25280
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25281
0
      XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25282
0
  if (iattr) {
25283
0
      ACTIVATE_ATTRIBUTE(iattr);
25284
      /*
25285
      * Validate the value.
25286
      */
25287
0
      ret = xmlSchemaVCheckCVCSimpleType(
25288
0
    ACTXT_CAST vctxt, NULL,
25289
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25290
0
    iattr->value, &(iattr->val), 1, 0, 0);
25291
0
      ACTIVATE_ELEM;
25292
0
      if (ret < 0) {
25293
0
    VERROR_INT("xmlSchemaValidateElemDecl",
25294
0
        "calling xmlSchemaVCheckCVCSimpleType() to "
25295
0
        "validate the attribute 'xsi:nil'");
25296
0
    return (-1);
25297
0
      }
25298
0
      if (ret == 0) {
25299
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25300
        /*
25301
        * cvc-elt (3.3.4) : 3.1
25302
        */
25303
0
        VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25304
0
      "The element is not 'nillable'");
25305
        /* Does not return an error on purpose. */
25306
0
    } else {
25307
0
        if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25308
      /*
25309
      * cvc-elt (3.3.4) : 3.2.2
25310
      */
25311
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25312
0
          (elemDecl->value != NULL)) {
25313
0
          VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25314
0
        "The element cannot be 'nilled' because "
25315
0
        "there is a fixed value constraint defined "
25316
0
        "for it");
25317
           /* Does not return an error on purpose. */
25318
0
      } else
25319
0
          vctxt->inode->flags |=
25320
0
        XML_SCHEMA_ELEM_INFO_NILLED;
25321
0
        }
25322
0
    }
25323
0
      }
25324
0
  }
25325
  /*
25326
  * cvc-elt (3.3.4) : 4
25327
  * Handle 'xsi:type'.
25328
  */
25329
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25330
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25331
0
  if (iattr) {
25332
0
      xmlSchemaTypePtr localType = NULL;
25333
25334
0
      ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25335
0
    elemDecl);
25336
0
      if (ret != 0) {
25337
0
    if (ret == -1) {
25338
0
        VERROR_INT("xmlSchemaValidateElemDecl",
25339
0
      "calling xmlSchemaProcessXSIType() to "
25340
0
      "process the attribute 'xsi:type'");
25341
0
        return (-1);
25342
0
    }
25343
    /* Does not return an error on purpose. */
25344
0
      }
25345
0
      if (localType != NULL) {
25346
0
    vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25347
0
    actualType = localType;
25348
0
      }
25349
0
  }
25350
0
    }
25351
    /*
25352
    * IDC: Register identity-constraint XPath matchers.
25353
    */
25354
0
    if ((elemDecl->idcs != NULL) &&
25355
0
  (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25356
0
      return (-1);
25357
    /*
25358
    * No actual type definition.
25359
    */
25360
0
    if (actualType == NULL) {
25361
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25362
0
      "The type definition is absent");
25363
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25364
0
    }
25365
    /*
25366
    * Remember the actual type definition.
25367
    */
25368
0
    vctxt->inode->typeDef = actualType;
25369
25370
0
    return (0);
25371
0
}
25372
25373
static int
25374
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25375
0
{
25376
0
    xmlSchemaAttrInfoPtr iattr;
25377
0
    int ret = 0, i;
25378
25379
    /*
25380
    * SPEC cvc-type (3.1.1)
25381
    * "The attributes of must be empty, excepting those whose namespace
25382
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25383
    * whose local name is one of type, nil, schemaLocation or
25384
    * noNamespaceSchemaLocation."
25385
    */
25386
0
    if (vctxt->nbAttrInfos == 0)
25387
0
  return (0);
25388
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25389
0
  iattr = vctxt->attrInfos[i];
25390
0
  if (! iattr->metaType) {
25391
0
      ACTIVATE_ATTRIBUTE(iattr)
25392
0
      xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25393
0
    XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25394
0
      ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25395
0
        }
25396
0
    }
25397
0
    ACTIVATE_ELEM
25398
0
    return (ret);
25399
0
}
25400
25401
/*
25402
* Cleanup currently used attribute infos.
25403
*/
25404
static void
25405
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25406
0
{
25407
0
    int i;
25408
0
    xmlSchemaAttrInfoPtr attr;
25409
25410
0
    if (vctxt->nbAttrInfos == 0)
25411
0
  return;
25412
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25413
0
  attr = vctxt->attrInfos[i];
25414
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25415
0
      if (attr->localName != NULL)
25416
0
    xmlFree((xmlChar *) attr->localName);
25417
0
      if (attr->nsName != NULL)
25418
0
    xmlFree((xmlChar *) attr->nsName);
25419
0
  }
25420
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25421
0
      if (attr->value != NULL)
25422
0
    xmlFree((xmlChar *) attr->value);
25423
0
  }
25424
0
  if (attr->val != NULL) {
25425
0
      xmlSchemaFreeValue(attr->val);
25426
0
      attr->val = NULL;
25427
0
  }
25428
0
  memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25429
0
    }
25430
0
    vctxt->nbAttrInfos = 0;
25431
0
}
25432
25433
/*
25434
* 3.4.4 Complex Type Definition Validation Rules
25435
*   Element Locally Valid (Complex Type) (cvc-complex-type)
25436
* 3.2.4 Attribute Declaration Validation Rules
25437
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
25438
*   Attribute Locally Valid (Use) (cvc-au)
25439
*
25440
* Only "assessed" attribute information items will be visible to
25441
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25442
*/
25443
static int
25444
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25445
0
{
25446
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef;
25447
0
    xmlSchemaItemListPtr attrUseList;
25448
0
    xmlSchemaAttributeUsePtr attrUse = NULL;
25449
0
    xmlSchemaAttributePtr attrDecl = NULL;
25450
0
    xmlSchemaAttrInfoPtr iattr, tmpiattr;
25451
0
    int i, j, found, nbAttrs, nbUses;
25452
0
    int xpathRes = 0, res, wildIDs = 0, fixed;
25453
0
    xmlNodePtr defAttrOwnerElem = NULL;
25454
25455
    /*
25456
    * SPEC (cvc-attribute)
25457
    * (1) "The declaration must not be `absent` (see Missing
25458
    * Sub-components ($5.3) for how this can fail to be
25459
    * the case)."
25460
    * (2) "Its {type definition} must not be absent."
25461
    *
25462
    * NOTE (1) + (2): This is not handled here, since we currently do not
25463
    * allow validation against schemas which have missing sub-components.
25464
    *
25465
    * SPEC (cvc-complex-type)
25466
    * (3) "For each attribute information item in the element information
25467
    * item's [attributes] excepting those whose [namespace name] is
25468
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25469
    * [local name] is one of type, nil, schemaLocation or
25470
    * noNamespaceSchemaLocation, the appropriate case among the following
25471
    * must be true:
25472
    *
25473
    */
25474
0
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25475
    /*
25476
    * @nbAttrs is the number of attributes present in the instance.
25477
    */
25478
0
    nbAttrs = vctxt->nbAttrInfos;
25479
0
    if (attrUseList != NULL)
25480
0
  nbUses = attrUseList->nbItems;
25481
0
    else
25482
0
  nbUses = 0;
25483
0
    for (i = 0; i < nbUses; i++) {
25484
0
        found = 0;
25485
0
  attrUse = attrUseList->items[i];
25486
0
  attrDecl = WXS_ATTRUSE_DECL(attrUse);
25487
0
        for (j = 0; j < nbAttrs; j++) {
25488
0
      iattr = vctxt->attrInfos[j];
25489
      /*
25490
      * SPEC (cvc-complex-type) (3)
25491
      * Skip meta attributes.
25492
      */
25493
0
      if (iattr->metaType)
25494
0
    continue;
25495
0
      if (iattr->localName[0] != attrDecl->name[0])
25496
0
    continue;
25497
0
      if (!xmlStrEqual(iattr->localName, attrDecl->name))
25498
0
    continue;
25499
0
      if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25500
0
    continue;
25501
0
      found = 1;
25502
      /*
25503
      * SPEC (cvc-complex-type)
25504
      * (3.1) "If there is among the {attribute uses} an attribute
25505
      * use with an {attribute declaration} whose {name} matches
25506
      * the attribute information item's [local name] and whose
25507
      * {target namespace} is identical to the attribute information
25508
      * item's [namespace name] (where an `absent` {target namespace}
25509
      * is taken to be identical to a [namespace name] with no value),
25510
      * then the attribute information must be `valid` with respect
25511
      * to that attribute use as per Attribute Locally Valid (Use)
25512
      * ($3.5.4). In this case the {attribute declaration} of that
25513
      * attribute use is the `context-determined declaration` for the
25514
      * attribute information item with respect to Schema-Validity
25515
      * Assessment (Attribute) ($3.2.4) and
25516
      * Assessment Outcome (Attribute) ($3.2.5).
25517
      */
25518
0
      iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25519
0
      iattr->use = attrUse;
25520
      /*
25521
      * Context-determined declaration.
25522
      */
25523
0
      iattr->decl = attrDecl;
25524
0
      iattr->typeDef = attrDecl->subtypes;
25525
0
      break;
25526
0
  }
25527
25528
0
  if (found)
25529
0
      continue;
25530
25531
0
  if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25532
      /*
25533
      * Handle non-existent, required attributes.
25534
      *
25535
      * SPEC (cvc-complex-type)
25536
      * (4) "The {attribute declaration} of each attribute use in
25537
      * the {attribute uses} whose {required} is true matches one
25538
      * of the attribute information items in the element information
25539
      * item's [attributes] as per clause 3.1 above."
25540
      */
25541
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25542
0
      if (tmpiattr == NULL) {
25543
0
    VERROR_INT(
25544
0
        "xmlSchemaVAttributesComplex",
25545
0
        "calling xmlSchemaGetFreshAttrInfo()");
25546
0
    return (-1);
25547
0
      }
25548
0
      tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25549
0
      tmpiattr->use = attrUse;
25550
0
      tmpiattr->decl = attrDecl;
25551
0
  } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25552
0
      ((attrUse->defValue != NULL) ||
25553
0
       (attrDecl->defValue != NULL))) {
25554
      /*
25555
      * Handle non-existent, optional, default/fixed attributes.
25556
      */
25557
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25558
0
      if (tmpiattr == NULL) {
25559
0
    VERROR_INT(
25560
0
        "xmlSchemaVAttributesComplex",
25561
0
        "calling xmlSchemaGetFreshAttrInfo()");
25562
0
    return (-1);
25563
0
      }
25564
0
      tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25565
0
      tmpiattr->use = attrUse;
25566
0
      tmpiattr->decl = attrDecl;
25567
0
      tmpiattr->typeDef = attrDecl->subtypes;
25568
0
      tmpiattr->localName = attrDecl->name;
25569
0
      tmpiattr->nsName = attrDecl->targetNamespace;
25570
0
  }
25571
0
    }
25572
25573
0
    if (vctxt->nbAttrInfos == 0)
25574
0
  return (0);
25575
    /*
25576
    * Validate against the wildcard.
25577
    */
25578
0
    if (type->attributeWildcard != NULL) {
25579
  /*
25580
  * SPEC (cvc-complex-type)
25581
  * (3.2.1) "There must be an {attribute wildcard}."
25582
  */
25583
0
  for (i = 0; i < nbAttrs; i++) {
25584
0
      iattr = vctxt->attrInfos[i];
25585
      /*
25586
      * SPEC (cvc-complex-type) (3)
25587
      * Skip meta attributes.
25588
      */
25589
0
      if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25590
0
    continue;
25591
      /*
25592
      * SPEC (cvc-complex-type)
25593
      * (3.2.2) "The attribute information item must be `valid` with
25594
      * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25595
      *
25596
      * SPEC Item Valid (Wildcard) (cvc-wildcard)
25597
      * "... its [namespace name] must be `valid` with respect to
25598
      * the wildcard constraint, as defined in Wildcard allows
25599
      * Namespace Name ($3.10.4)."
25600
      */
25601
0
      if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25602
0
        iattr->nsName) == 0) {
25603
    /*
25604
    * Handle processContents.
25605
    *
25606
    * SPEC (cvc-wildcard):
25607
    * processContents | context-determined declaration:
25608
    * "strict"          "mustFind"
25609
    * "lax"             "none"
25610
    * "skip"            "skip"
25611
    */
25612
0
    if (type->attributeWildcard->processContents ==
25613
0
        XML_SCHEMAS_ANY_SKIP) {
25614
         /*
25615
        * context-determined declaration = "skip"
25616
        *
25617
        * SPEC PSVI Assessment Outcome (Attribute)
25618
        * [validity] = "notKnown"
25619
        * [validation attempted] = "none"
25620
        */
25621
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25622
0
        continue;
25623
0
    }
25624
    /*
25625
    * Find an attribute declaration.
25626
    */
25627
0
    iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25628
0
        iattr->localName, iattr->nsName);
25629
0
    if (iattr->decl != NULL) {
25630
0
        iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25631
        /*
25632
        * SPEC (cvc-complex-type)
25633
        * (5) "Let [Definition:]  the wild IDs be the set of
25634
        * all attribute information item to which clause 3.2
25635
        * applied and whose `validation` resulted in a
25636
        * `context-determined declaration` of mustFind or no
25637
        * `context-determined declaration` at all, and whose
25638
        * [local name] and [namespace name] resolve (as
25639
        * defined by QName resolution (Instance) ($3.15.4)) to
25640
        * an attribute declaration whose {type definition} is
25641
        * or is derived from ID. Then all of the following
25642
        * must be true:"
25643
        */
25644
0
        iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25645
0
        if (xmlSchemaIsDerivedFromBuiltInType(
25646
0
      iattr->typeDef, XML_SCHEMAS_ID)) {
25647
      /*
25648
      * SPEC (5.1) "There must be no more than one
25649
      * item in `wild IDs`."
25650
      */
25651
0
      if (wildIDs != 0) {
25652
          /* VAL TODO */
25653
0
          iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25654
0
          TODO
25655
0
          continue;
25656
0
      }
25657
0
      wildIDs++;
25658
      /*
25659
      * SPEC (cvc-complex-type)
25660
      * (5.2) "If `wild IDs` is non-empty, there must not
25661
      * be any attribute uses among the {attribute uses}
25662
      * whose {attribute declaration}'s {type definition}
25663
      * is or is derived from ID."
25664
      */
25665
0
                        if (attrUseList != NULL) {
25666
0
                            for (j = 0; j < attrUseList->nbItems; j++) {
25667
0
                                if (xmlSchemaIsDerivedFromBuiltInType(
25668
0
                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25669
0
                                    XML_SCHEMAS_ID)) {
25670
                                    /* URGENT VAL TODO: implement */
25671
0
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25672
0
                                    TODO
25673
0
                                    break;
25674
0
                                }
25675
0
                            }
25676
0
                        }
25677
0
        }
25678
0
    } else if (type->attributeWildcard->processContents ==
25679
0
        XML_SCHEMAS_ANY_LAX) {
25680
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25681
        /*
25682
        * SPEC PSVI Assessment Outcome (Attribute)
25683
        * [validity] = "notKnown"
25684
        * [validation attempted] = "none"
25685
        */
25686
0
    } else {
25687
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25688
0
    }
25689
0
      }
25690
0
  }
25691
0
    }
25692
25693
0
    if (vctxt->nbAttrInfos == 0)
25694
0
  return (0);
25695
25696
    /*
25697
    * Get the owner element; needed for creation of default attributes.
25698
    * This fixes bug #341337, reported by David Grohmann.
25699
    */
25700
0
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25701
0
  xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25702
0
  if (ielem && ielem->node && ielem->node->doc)
25703
0
      defAttrOwnerElem = ielem->node;
25704
0
    }
25705
    /*
25706
    * Validate values, create default attributes, evaluate IDCs.
25707
    */
25708
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25709
0
  iattr = vctxt->attrInfos[i];
25710
  /*
25711
  * VAL TODO: Note that we won't try to resolve IDCs to
25712
  * "lax" and "skip" validated attributes. Check what to
25713
  * do in this case.
25714
  */
25715
0
  if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25716
0
      (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25717
0
      continue;
25718
  /*
25719
  * VAL TODO: What to do if the type definition is missing?
25720
  */
25721
0
  if (iattr->typeDef == NULL) {
25722
0
      iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25723
0
      continue;
25724
0
  }
25725
25726
0
  ACTIVATE_ATTRIBUTE(iattr);
25727
0
  fixed = 0;
25728
0
  xpathRes = 0;
25729
25730
0
  if (vctxt->xpathStates != NULL) {
25731
      /*
25732
      * Evaluate IDCs.
25733
      */
25734
0
      xpathRes = xmlSchemaXPathEvaluate(vctxt,
25735
0
    XML_ATTRIBUTE_NODE);
25736
0
      if (xpathRes == -1) {
25737
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25738
0
        "calling xmlSchemaXPathEvaluate()");
25739
0
    goto internal_error;
25740
0
      }
25741
0
  }
25742
25743
0
  if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25744
      /*
25745
      * Default/fixed attributes.
25746
      * We need the value only if we need to resolve IDCs or
25747
      * will create default attributes.
25748
      */
25749
0
      if ((xpathRes) || (defAttrOwnerElem)) {
25750
0
    if (iattr->use->defValue != NULL) {
25751
0
        iattr->value = (xmlChar *) iattr->use->defValue;
25752
0
        iattr->val = iattr->use->defVal;
25753
0
    } else {
25754
0
        iattr->value = (xmlChar *) iattr->decl->defValue;
25755
0
        iattr->val = iattr->decl->defVal;
25756
0
    }
25757
    /*
25758
    * IDCs will consume the precomputed default value,
25759
    * so we need to clone it.
25760
    */
25761
0
    if (iattr->val == NULL) {
25762
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25763
0
      "default/fixed value on an attribute use was "
25764
0
      "not precomputed");
25765
0
        goto internal_error;
25766
0
    }
25767
0
    iattr->val = xmlSchemaCopyValue(iattr->val);
25768
0
    if (iattr->val == NULL) {
25769
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25770
0
      "calling xmlSchemaCopyValue()");
25771
0
        goto internal_error;
25772
0
    }
25773
0
      }
25774
      /*
25775
      * PSVI: Add the default attribute to the current element.
25776
      * VAL TODO: Should we use the *normalized* value? This currently
25777
      *   uses the *initial* value.
25778
      */
25779
25780
0
      if (defAttrOwnerElem) {
25781
0
    xmlChar *normValue;
25782
0
    const xmlChar *value;
25783
25784
0
    value = iattr->value;
25785
    /*
25786
    * Normalize the value.
25787
    */
25788
0
    normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25789
0
        iattr->value);
25790
0
    if (normValue != NULL)
25791
0
        value = BAD_CAST normValue;
25792
25793
0
    if (iattr->nsName == NULL) {
25794
0
        if (xmlNewProp(defAttrOwnerElem,
25795
0
      iattr->localName, value) == NULL) {
25796
0
      VERROR_INT("xmlSchemaVAttributesComplex",
25797
0
          "calling xmlNewProp()");
25798
0
      if (normValue != NULL)
25799
0
          xmlFree(normValue);
25800
0
      goto internal_error;
25801
0
        }
25802
0
    } else {
25803
0
        xmlNsPtr ns;
25804
25805
0
        ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25806
0
      defAttrOwnerElem, iattr->nsName);
25807
0
        if (ns == NULL) {
25808
0
      xmlChar prefix[12];
25809
0
      int counter = 0;
25810
25811
      /*
25812
      * Create a namespace declaration on the validation
25813
      * root node if no namespace declaration is in scope.
25814
      */
25815
0
      do {
25816
0
          snprintf((char *) prefix, 12, "p%d", counter++);
25817
0
          ns = xmlSearchNs(defAttrOwnerElem->doc,
25818
0
        defAttrOwnerElem, BAD_CAST prefix);
25819
0
          if (counter > 1000) {
25820
0
        VERROR_INT(
25821
0
            "xmlSchemaVAttributesComplex",
25822
0
            "could not compute a ns prefix for a "
25823
0
            "default/fixed attribute");
25824
0
        if (normValue != NULL)
25825
0
            xmlFree(normValue);
25826
0
        goto internal_error;
25827
0
          }
25828
0
      } while (ns != NULL);
25829
0
      ns = xmlNewNs(vctxt->validationRoot,
25830
0
          iattr->nsName, BAD_CAST prefix);
25831
0
        }
25832
        /*
25833
        * TODO:
25834
        * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25835
        * If we have QNames: do we need to ensure there's a
25836
        * prefix defined for the QName?
25837
        */
25838
0
        xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25839
0
    }
25840
0
    if (normValue != NULL)
25841
0
        xmlFree(normValue);
25842
0
      }
25843
      /*
25844
      * Go directly to IDC evaluation.
25845
      */
25846
0
      goto eval_idcs;
25847
0
  }
25848
  /*
25849
  * Validate the value.
25850
  */
25851
0
  if (vctxt->value != NULL) {
25852
      /*
25853
      * Free last computed value; just for safety reasons.
25854
      */
25855
0
      xmlSchemaFreeValue(vctxt->value);
25856
0
      vctxt->value = NULL;
25857
0
  }
25858
  /*
25859
  * Note that the attribute *use* can be unavailable, if
25860
  * the attribute was a wild attribute.
25861
  */
25862
0
  if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25863
0
      ((iattr->use != NULL) &&
25864
0
       (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25865
0
      fixed = 1;
25866
0
  else
25867
0
      fixed = 0;
25868
  /*
25869
  * SPEC (cvc-attribute)
25870
  * (3) "The item's `normalized value` must be locally `valid`
25871
  * with respect to that {type definition} as per
25872
  * String Valid ($3.14.4)."
25873
  *
25874
  * VAL TODO: Do we already have the
25875
  * "normalized attribute value" here?
25876
  */
25877
0
  if (xpathRes || fixed) {
25878
0
      iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25879
      /*
25880
      * Request a computed value.
25881
      */
25882
0
      res = xmlSchemaVCheckCVCSimpleType(
25883
0
    ACTXT_CAST vctxt,
25884
0
    iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25885
0
    1, 1, 0);
25886
0
  } else {
25887
0
      res = xmlSchemaVCheckCVCSimpleType(
25888
0
    ACTXT_CAST vctxt,
25889
0
    iattr->node, iattr->typeDef, iattr->value, NULL,
25890
0
    1, 0, 0);
25891
0
  }
25892
25893
0
  if (res != 0) {
25894
0
      if (res == -1) {
25895
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25896
0
        "calling xmlSchemaStreamValidateSimpleTypeValue()");
25897
0
    goto internal_error;
25898
0
      }
25899
0
      iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25900
      /*
25901
      * SPEC PSVI Assessment Outcome (Attribute)
25902
      * [validity] = "invalid"
25903
      */
25904
0
      goto eval_idcs;
25905
0
  }
25906
25907
0
  if (fixed) {
25908
      /*
25909
      * SPEC Attribute Locally Valid (Use) (cvc-au)
25910
      * "For an attribute information item to be `valid`
25911
      * with respect to an attribute use its *normalized*
25912
      * value must match the *canonical* lexical
25913
      * representation of the attribute use's {value
25914
      * constraint}value, if it is present and fixed."
25915
      *
25916
      * VAL TODO: The requirement for the *canonical* value
25917
      * will be removed in XML Schema 1.1.
25918
      */
25919
      /*
25920
      * SPEC Attribute Locally Valid (cvc-attribute)
25921
      * (4) "The item's *actual* value must match the *value* of
25922
      * the {value constraint}, if it is present and fixed."
25923
      */
25924
0
      if (iattr->val == NULL) {
25925
    /* VAL TODO: A value was not precomputed. */
25926
0
    TODO
25927
0
    goto eval_idcs;
25928
0
      }
25929
0
      if ((iattr->use != NULL) &&
25930
0
    (iattr->use->defValue != NULL)) {
25931
0
    if (iattr->use->defVal == NULL) {
25932
        /* VAL TODO: A default value was not precomputed. */
25933
0
        TODO
25934
0
        goto eval_idcs;
25935
0
    }
25936
0
    iattr->vcValue = iattr->use->defValue;
25937
    /*
25938
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25939
        (xmlSchemaWhitespaceValueType) ws,
25940
        attr->use->defVal,
25941
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25942
    */
25943
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25944
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25945
0
      } else {
25946
0
    if (iattr->decl->defVal == NULL) {
25947
        /* VAL TODO: A default value was not precomputed. */
25948
0
        TODO
25949
0
        goto eval_idcs;
25950
0
    }
25951
0
    iattr->vcValue = iattr->decl->defValue;
25952
    /*
25953
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25954
        (xmlSchemaWhitespaceValueType) ws,
25955
        attrDecl->defVal,
25956
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25957
    */
25958
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25959
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25960
0
      }
25961
      /*
25962
      * [validity] = "valid"
25963
      */
25964
0
  }
25965
0
eval_idcs:
25966
  /*
25967
  * Evaluate IDCs.
25968
  */
25969
0
  if (xpathRes) {
25970
0
      if (xmlSchemaXPathProcessHistory(vctxt,
25971
0
    vctxt->depth +1) == -1) {
25972
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25973
0
        "calling xmlSchemaXPathEvaluate()");
25974
0
    goto internal_error;
25975
0
      }
25976
0
  } else if (vctxt->xpathStates != NULL)
25977
0
      xmlSchemaXPathPop(vctxt);
25978
0
    }
25979
25980
    /*
25981
    * Report errors.
25982
    */
25983
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25984
0
  iattr = vctxt->attrInfos[i];
25985
0
  if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25986
0
      (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25987
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25988
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25989
0
      continue;
25990
0
  ACTIVATE_ATTRIBUTE(iattr);
25991
0
  switch (iattr->state) {
25992
0
      case XML_SCHEMAS_ATTR_ERR_MISSING: {
25993
0
        xmlChar *str = NULL;
25994
0
        ACTIVATE_ELEM;
25995
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
25996
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25997
0
      "The attribute '%s' is required but missing",
25998
0
      xmlSchemaFormatQName(&str,
25999
0
          iattr->decl->targetNamespace,
26000
0
          iattr->decl->name),
26001
0
      NULL);
26002
0
        FREE_AND_NULL(str)
26003
0
        break;
26004
0
    }
26005
0
      case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
26006
0
    VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
26007
0
        "The type definition is absent");
26008
0
    break;
26009
0
      case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
26010
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
26011
0
        XML_SCHEMAV_CVC_AU, NULL, NULL,
26012
0
        "The value '%s' does not match the fixed "
26013
0
        "value constraint '%s'",
26014
0
        iattr->value, iattr->vcValue);
26015
0
    break;
26016
0
      case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
26017
0
    VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
26018
0
        "No matching global attribute declaration available, but "
26019
0
        "demanded by the strict wildcard");
26020
0
    break;
26021
0
      case XML_SCHEMAS_ATTR_UNKNOWN:
26022
0
    if (iattr->metaType)
26023
0
        break;
26024
    /*
26025
    * MAYBE VAL TODO: One might report different error messages
26026
    * for the following errors.
26027
    */
26028
0
    if (type->attributeWildcard == NULL) {
26029
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
26030
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
26031
0
    } else {
26032
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
26033
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
26034
0
    }
26035
0
    break;
26036
0
      default:
26037
0
    break;
26038
0
  }
26039
0
    }
26040
26041
0
    ACTIVATE_ELEM;
26042
0
    return (0);
26043
0
internal_error:
26044
0
    ACTIVATE_ELEM;
26045
0
    return (-1);
26046
0
}
26047
26048
static int
26049
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
26050
            int *skip)
26051
0
{
26052
0
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
26053
    /*
26054
    * The namespace of the element was already identified to be
26055
    * matching the wildcard.
26056
    */
26057
0
    if ((skip == NULL) || (wild == NULL) ||
26058
0
  (wild->type != XML_SCHEMA_TYPE_ANY)) {
26059
0
  VERROR_INT("xmlSchemaValidateElemWildcard",
26060
0
      "bad arguments");
26061
0
  return (-1);
26062
0
    }
26063
0
    *skip = 0;
26064
0
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
26065
  /*
26066
  * URGENT VAL TODO: Either we need to position the stream to the
26067
  * next sibling, or walk the whole subtree.
26068
  */
26069
0
  *skip = 1;
26070
0
  return (0);
26071
0
    }
26072
0
    {
26073
0
  xmlSchemaElementPtr decl = NULL;
26074
26075
0
  decl = xmlSchemaGetElem(vctxt->schema,
26076
0
      vctxt->inode->localName, vctxt->inode->nsName);
26077
0
  if (decl != NULL) {
26078
0
      vctxt->inode->decl = decl;
26079
0
      return (0);
26080
0
  }
26081
0
    }
26082
0
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
26083
  /* VAL TODO: Change to proper error code. */
26084
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
26085
0
      "No matching global element declaration available, but "
26086
0
      "demanded by the strict wildcard");
26087
0
  return (vctxt->err);
26088
0
    }
26089
0
    if (vctxt->nbAttrInfos != 0) {
26090
0
  xmlSchemaAttrInfoPtr iattr;
26091
  /*
26092
  * SPEC Validation Rule: Schema-Validity Assessment (Element)
26093
  * (1.2.1.2.1) - (1.2.1.2.3 )
26094
  *
26095
  * Use the xsi:type attribute for the type definition.
26096
  */
26097
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26098
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26099
0
  if (iattr != NULL) {
26100
0
      if (xmlSchemaProcessXSIType(vctxt, iattr,
26101
0
    &(vctxt->inode->typeDef), NULL) == -1) {
26102
0
    VERROR_INT("xmlSchemaValidateElemWildcard",
26103
0
        "calling xmlSchemaProcessXSIType() to "
26104
0
        "process the attribute 'xsi:nil'");
26105
0
    return (-1);
26106
0
      }
26107
      /*
26108
      * Don't return an error on purpose.
26109
      */
26110
0
      return (0);
26111
0
  }
26112
0
    }
26113
    /*
26114
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
26115
    *
26116
    * Fallback to "anyType".
26117
    */
26118
0
    vctxt->inode->typeDef =
26119
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26120
0
    return (0);
26121
0
}
26122
26123
/*
26124
* xmlSchemaCheckCOSValidDefault:
26125
*
26126
* This will be called if: not nilled, no content and a default/fixed
26127
* value is provided.
26128
*/
26129
26130
static int
26131
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
26132
            const xmlChar *value,
26133
            xmlSchemaValPtr *val)
26134
0
{
26135
0
    int ret = 0;
26136
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
26137
26138
    /*
26139
    * cos-valid-default:
26140
    * Schema Component Constraint: Element Default Valid (Immediate)
26141
    * For a string to be a valid default with respect to a type
26142
    * definition the appropriate case among the following must be true:
26143
    */
26144
0
    if WXS_IS_COMPLEX(inode->typeDef) {
26145
  /*
26146
  * Complex type.
26147
  *
26148
  * SPEC (2.1) "its {content type} must be a simple type definition
26149
  * or mixed."
26150
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
26151
  * type}'s particle must be `emptiable` as defined by
26152
  * Particle Emptiable ($3.9.6)."
26153
  */
26154
0
  if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
26155
0
      ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
26156
0
       (! WXS_EMPTIABLE(inode->typeDef)))) {
26157
0
      ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
26158
      /* NOTE that this covers (2.2.2) as well. */
26159
0
      VERROR(ret, NULL,
26160
0
    "For a string to be a valid default, the type definition "
26161
0
    "must be a simple type or a complex type with simple content "
26162
0
    "or mixed content and a particle emptiable");
26163
0
      return(ret);
26164
0
  }
26165
0
    }
26166
    /*
26167
    * 1 If the type definition is a simple type definition, then the string
26168
    * must be `valid` with respect to that definition as defined by String
26169
    * Valid ($3.14.4).
26170
    *
26171
    * AND
26172
    *
26173
    * 2.2.1 If the {content type} is a simple type definition, then the
26174
    * string must be `valid` with respect to that simple type definition
26175
    * as defined by String Valid ($3.14.4).
26176
    */
26177
0
    if (WXS_IS_SIMPLE(inode->typeDef)) {
26178
26179
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
26180
0
      NULL, inode->typeDef, value, val, 1, 1, 0);
26181
26182
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26183
26184
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
26185
0
      NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
26186
0
    }
26187
0
    if (ret < 0) {
26188
0
  VERROR_INT("xmlSchemaCheckCOSValidDefault",
26189
0
      "calling xmlSchemaVCheckCVCSimpleType()");
26190
0
    }
26191
0
    return (ret);
26192
0
}
26193
26194
static void
26195
xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
26196
             const xmlChar * name ATTRIBUTE_UNUSED,
26197
             void *transdata, void *inputdata)
26198
0
{
26199
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
26200
0
    xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
26201
0
    inode->decl = item;
26202
#ifdef DEBUG_CONTENT
26203
    {
26204
  xmlChar *str = NULL;
26205
26206
  if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
26207
      xmlGenericError(xmlGenericErrorContext,
26208
    "AUTOMATON callback for '%s' [declaration]\n",
26209
    xmlSchemaFormatQName(&str,
26210
    inode->localName, inode->nsName));
26211
  } else {
26212
      xmlGenericError(xmlGenericErrorContext,
26213
        "AUTOMATON callback for '%s' [wildcard]\n",
26214
        xmlSchemaFormatQName(&str,
26215
        inode->localName, inode->nsName));
26216
26217
  }
26218
  FREE_AND_NULL(str)
26219
    }
26220
#endif
26221
0
}
26222
26223
static int
26224
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
26225
0
{
26226
0
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
26227
0
    if (vctxt->inode == NULL) {
26228
0
  VERROR_INT("xmlSchemaValidatorPushElem",
26229
0
      "calling xmlSchemaGetFreshElemInfo()");
26230
0
  return (-1);
26231
0
    }
26232
0
    vctxt->nbAttrInfos = 0;
26233
0
    return (0);
26234
0
}
26235
26236
static int
26237
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
26238
           xmlSchemaNodeInfoPtr inode,
26239
           xmlSchemaTypePtr type,
26240
           const xmlChar *value)
26241
0
{
26242
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
26243
0
  return (xmlSchemaVCheckCVCSimpleType(
26244
0
      ACTXT_CAST vctxt, NULL,
26245
0
      type, value, &(inode->val), 1, 1, 0));
26246
0
    else
26247
0
  return (xmlSchemaVCheckCVCSimpleType(
26248
0
      ACTXT_CAST vctxt, NULL,
26249
0
      type, value, NULL, 1, 0, 0));
26250
0
}
26251
26252
26253
26254
/*
26255
* Process END of element.
26256
*/
26257
static int
26258
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
26259
0
{
26260
0
    int ret = 0;
26261
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
26262
26263
0
    if (vctxt->nbAttrInfos != 0)
26264
0
  xmlSchemaClearAttrInfos(vctxt);
26265
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
26266
  /*
26267
  * This element was not expected;
26268
  * we will not validate child elements of broken parents.
26269
  * Skip validation of all content of the parent.
26270
  */
26271
0
  vctxt->skipDepth = vctxt->depth -1;
26272
0
  goto end_elem;
26273
0
    }
26274
0
    if ((inode->typeDef == NULL) ||
26275
0
  (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
26276
  /*
26277
  * 1. the type definition might be missing if the element was
26278
  *    error prone
26279
  * 2. it might be abstract.
26280
  */
26281
0
  goto end_elem;
26282
0
    }
26283
    /*
26284
    * Check the content model.
26285
    */
26286
0
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
26287
0
  (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
26288
26289
  /*
26290
  * Workaround for "anyType".
26291
  */
26292
0
  if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26293
0
      goto character_content;
26294
26295
0
  if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
26296
0
      xmlChar *values[10];
26297
0
      int terminal, nbval = 10, nbneg;
26298
26299
0
      if (inode->regexCtxt == NULL) {
26300
    /*
26301
    * Create the regex context.
26302
    */
26303
0
    inode->regexCtxt =
26304
0
        xmlRegNewExecCtxt(inode->typeDef->contModel,
26305
0
        xmlSchemaVContentModelCallback, vctxt);
26306
0
    if (inode->regexCtxt == NULL) {
26307
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26308
0
      "failed to create a regex context");
26309
0
        goto internal_error;
26310
0
    }
26311
#ifdef DEBUG_AUTOMATA
26312
    xmlGenericError(xmlGenericErrorContext,
26313
        "AUTOMATON create on '%s'\n", inode->localName);
26314
#endif
26315
0
      }
26316
26317
      /*
26318
       * Do not check further content if the node has been nilled
26319
       */
26320
0
      if (INODE_NILLED(inode)) {
26321
0
    ret = 0;
26322
#ifdef DEBUG_AUTOMATA
26323
    xmlGenericError(xmlGenericErrorContext,
26324
        "AUTOMATON succeeded on nilled '%s'\n",
26325
        inode->localName);
26326
#endif
26327
0
                goto skip_nilled;
26328
0
      }
26329
26330
      /*
26331
      * Get hold of the still expected content, since a further
26332
      * call to xmlRegExecPushString() will lose this information.
26333
      */
26334
0
      xmlRegExecNextValues(inode->regexCtxt,
26335
0
    &nbval, &nbneg, &values[0], &terminal);
26336
0
      ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26337
0
      if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26338
    /*
26339
    * Still missing something.
26340
    */
26341
0
    ret = 1;
26342
0
    inode->flags |=
26343
0
        XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26344
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26345
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26346
0
        "Missing child element(s)",
26347
0
        nbval, nbneg, values);
26348
#ifdef DEBUG_AUTOMATA
26349
    xmlGenericError(xmlGenericErrorContext,
26350
        "AUTOMATON missing ERROR on '%s'\n",
26351
        inode->localName);
26352
#endif
26353
0
      } else {
26354
    /*
26355
    * Content model is satisfied.
26356
    */
26357
0
    ret = 0;
26358
#ifdef DEBUG_AUTOMATA
26359
    xmlGenericError(xmlGenericErrorContext,
26360
        "AUTOMATON succeeded on '%s'\n",
26361
        inode->localName);
26362
#endif
26363
0
      }
26364
26365
0
  }
26366
0
    }
26367
26368
0
skip_nilled:
26369
26370
0
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26371
0
  goto end_elem;
26372
26373
0
character_content:
26374
26375
0
    if (vctxt->value != NULL) {
26376
0
  xmlSchemaFreeValue(vctxt->value);
26377
0
  vctxt->value = NULL;
26378
0
    }
26379
    /*
26380
    * Check character content.
26381
    */
26382
0
    if (inode->decl == NULL) {
26383
  /*
26384
  * Speedup if no declaration exists.
26385
  */
26386
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26387
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26388
0
    inode, inode->typeDef, inode->value);
26389
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26390
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26391
0
    inode, inode->typeDef->contentTypeDef,
26392
0
    inode->value);
26393
0
  }
26394
0
  if (ret < 0) {
26395
0
      VERROR_INT("xmlSchemaValidatorPopElem",
26396
0
    "calling xmlSchemaVCheckCVCSimpleType()");
26397
0
      goto internal_error;
26398
0
  }
26399
0
  goto end_elem;
26400
0
    }
26401
    /*
26402
    * cvc-elt (3.3.4) : 5
26403
    * The appropriate case among the following must be true:
26404
    */
26405
    /*
26406
    * cvc-elt (3.3.4) : 5.1
26407
    * If the declaration has a {value constraint},
26408
    * the item has neither element nor character [children] and
26409
    * clause 3.2 has not applied, then all of the following must be true:
26410
    */
26411
0
    if ((inode->decl->value != NULL) &&
26412
0
  (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26413
0
  (! INODE_NILLED(inode))) {
26414
  /*
26415
  * cvc-elt (3.3.4) : 5.1.1
26416
  * If the `actual type definition` is a `local type definition`
26417
  * then the canonical lexical representation of the {value constraint}
26418
  * value must be a valid default for the `actual type definition` as
26419
  * defined in Element Default Valid (Immediate) ($3.3.6).
26420
  */
26421
  /*
26422
  * NOTE: 'local' above means types acquired by xsi:type.
26423
  * NOTE: Although the *canonical* value is stated, it is not
26424
  * relevant if canonical or not. Additionally XML Schema 1.1
26425
  * will removed this requirement as well.
26426
  */
26427
0
  if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26428
26429
0
      ret = xmlSchemaCheckCOSValidDefault(vctxt,
26430
0
    inode->decl->value, &(inode->val));
26431
0
      if (ret != 0) {
26432
0
    if (ret < 0) {
26433
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26434
0
      "calling xmlSchemaCheckCOSValidDefault()");
26435
0
        goto internal_error;
26436
0
    }
26437
0
    goto end_elem;
26438
0
      }
26439
      /*
26440
      * Stop here, to avoid redundant validation of the value
26441
      * (see following).
26442
      */
26443
0
      goto default_psvi;
26444
0
  }
26445
  /*
26446
  * cvc-elt (3.3.4) : 5.1.2
26447
  * The element information item with the canonical lexical
26448
  * representation of the {value constraint} value used as its
26449
  * `normalized value` must be `valid` with respect to the
26450
  * `actual type definition` as defined by Element Locally Valid (Type)
26451
  * ($3.3.4).
26452
  */
26453
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26454
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26455
0
    inode, inode->typeDef, inode->decl->value);
26456
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26457
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26458
0
    inode, inode->typeDef->contentTypeDef,
26459
0
    inode->decl->value);
26460
0
  }
26461
0
  if (ret != 0) {
26462
0
      if (ret < 0) {
26463
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26464
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26465
0
    goto internal_error;
26466
0
      }
26467
0
      goto end_elem;
26468
0
  }
26469
26470
0
default_psvi:
26471
  /*
26472
  * PSVI: Create a text node on the instance element.
26473
  */
26474
0
  if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26475
0
      (inode->node != NULL)) {
26476
0
      xmlNodePtr textChild;
26477
0
      xmlChar *normValue;
26478
      /*
26479
      * VAL TODO: Normalize the value.
26480
      */
26481
0
      normValue = xmlSchemaNormalizeValue(inode->typeDef,
26482
0
    inode->decl->value);
26483
0
      if (normValue != NULL) {
26484
0
    textChild = xmlNewDocText(inode->node->doc,
26485
0
                        BAD_CAST normValue);
26486
0
    xmlFree(normValue);
26487
0
      } else
26488
0
    textChild = xmlNewDocText(inode->node->doc,
26489
0
                        inode->decl->value);
26490
0
      if (textChild == NULL) {
26491
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26492
0
        "calling xmlNewDocText()");
26493
0
    goto internal_error;
26494
0
      } else
26495
0
    xmlAddChild(inode->node, textChild);
26496
0
  }
26497
26498
0
    } else if (! INODE_NILLED(inode)) {
26499
  /*
26500
  * 5.2.1 The element information item must be `valid` with respect
26501
  * to the `actual type definition` as defined by Element Locally
26502
  * Valid (Type) ($3.3.4).
26503
  */
26504
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26505
       /*
26506
      * SPEC (cvc-type) (3.1)
26507
      * "If the type definition is a simple type definition, ..."
26508
      * (3.1.3) "If clause 3.2 of Element Locally Valid
26509
      * (Element) ($3.3.4) did not apply, then the `normalized value`
26510
      * must be `valid` with respect to the type definition as defined
26511
      * by String Valid ($3.14.4).
26512
      */
26513
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26514
0
        inode, inode->typeDef, inode->value);
26515
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26516
      /*
26517
      * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26518
      * definition, then the element information item must be
26519
      * `valid` with respect to the type definition as per
26520
      * Element Locally Valid (Complex Type) ($3.4.4);"
26521
      *
26522
      * SPEC (cvc-complex-type) (2.2)
26523
      * "If the {content type} is a simple type definition, ...
26524
      * the `normalized value` of the element information item is
26525
      * `valid` with respect to that simple type definition as
26526
      * defined by String Valid ($3.14.4)."
26527
      */
26528
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26529
0
    inode, inode->typeDef->contentTypeDef, inode->value);
26530
0
  }
26531
0
  if (ret != 0) {
26532
0
      if (ret < 0) {
26533
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26534
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26535
0
    goto internal_error;
26536
0
      }
26537
0
      goto end_elem;
26538
0
  }
26539
  /*
26540
  * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26541
  * not applied, all of the following must be true:
26542
  */
26543
0
  if ((inode->decl->value != NULL) &&
26544
0
      (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26545
26546
      /*
26547
      * TODO: We will need a computed value, when comparison is
26548
      * done on computed values.
26549
      */
26550
      /*
26551
      * 5.2.2.1 The element information item must have no element
26552
      * information item [children].
26553
      */
26554
0
      if (inode->flags &
26555
0
        XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26556
0
    ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26557
0
    VERROR(ret, NULL,
26558
0
        "The content must not contain element nodes since "
26559
0
        "there is a fixed value constraint");
26560
0
    goto end_elem;
26561
0
      } else {
26562
    /*
26563
    * 5.2.2.2 The appropriate case among the following must
26564
    * be true:
26565
    */
26566
0
    if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26567
        /*
26568
        * 5.2.2.2.1 If the {content type} of the `actual type
26569
        * definition` is mixed, then the *initial value* of the
26570
        * item must match the canonical lexical representation
26571
        * of the {value constraint} value.
26572
        *
26573
        * ... the *initial value* of an element information
26574
        * item is the string composed of, in order, the
26575
        * [character code] of each character information item in
26576
        * the [children] of that element information item.
26577
        */
26578
0
        if (! xmlStrEqual(inode->value, inode->decl->value)){
26579
      /*
26580
      * VAL TODO: Report invalid & expected values as well.
26581
      * VAL TODO: Implement the canonical stuff.
26582
      */
26583
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26584
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26585
0
          ret, NULL, NULL,
26586
0
          "The initial value '%s' does not match the fixed "
26587
0
          "value constraint '%s'",
26588
0
          inode->value, inode->decl->value);
26589
0
      goto end_elem;
26590
0
        }
26591
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26592
        /*
26593
        * 5.2.2.2.2 If the {content type} of the `actual type
26594
        * definition` is a simple type definition, then the
26595
        * *actual value* of the item must match the canonical
26596
        * lexical representation of the {value constraint} value.
26597
        */
26598
        /*
26599
        * VAL TODO: *actual value* is the normalized value, impl.
26600
        *           this.
26601
        * VAL TODO: Report invalid & expected values as well.
26602
        * VAL TODO: Implement a comparison with the computed values.
26603
        */
26604
0
        if (! xmlStrEqual(inode->value,
26605
0
          inode->decl->value)) {
26606
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26607
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26608
0
          ret, NULL, NULL,
26609
0
          "The actual value '%s' does not match the fixed "
26610
0
          "value constraint '%s'",
26611
0
          inode->value,
26612
0
          inode->decl->value);
26613
0
      goto end_elem;
26614
0
        }
26615
0
    }
26616
0
      }
26617
0
  }
26618
0
    }
26619
26620
0
end_elem:
26621
0
    if (vctxt->depth < 0) {
26622
  /* TODO: raise error? */
26623
0
  return (0);
26624
0
    }
26625
0
    if (vctxt->depth == vctxt->skipDepth)
26626
0
  vctxt->skipDepth = -1;
26627
    /*
26628
    * Evaluate the history of XPath state objects.
26629
    */
26630
0
    if (inode->appliedXPath &&
26631
0
  (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26632
0
  goto internal_error;
26633
    /*
26634
    * MAYBE TODO:
26635
    * SPEC (6) "The element information item must be `valid` with
26636
    * respect to each of the {identity-constraint definitions} as per
26637
    * Identity-constraint Satisfied ($3.11.4)."
26638
    */
26639
    /*
26640
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26641
    *   need to be built in any case.
26642
    *   We will currently build IDC node-tables and bubble them only if
26643
    *   keyrefs do exist.
26644
    */
26645
26646
    /*
26647
    * Add the current IDC target-nodes to the IDC node-tables.
26648
    */
26649
0
    if ((inode->idcMatchers != NULL) &&
26650
0
  (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26651
0
    {
26652
0
  if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26653
0
      goto internal_error;
26654
0
    }
26655
    /*
26656
    * Validate IDC keyrefs.
26657
    */
26658
0
    if (vctxt->inode->hasKeyrefs)
26659
0
  if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26660
0
      goto internal_error;
26661
    /*
26662
    * Merge/free the IDC table.
26663
    */
26664
0
    if (inode->idcTable != NULL) {
26665
#ifdef DEBUG_IDC_NODE_TABLE
26666
  xmlSchemaDebugDumpIDCTable(stdout,
26667
      inode->nsName,
26668
      inode->localName,
26669
      inode->idcTable);
26670
#endif
26671
0
  if ((vctxt->depth > 0) &&
26672
0
      (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26673
0
  {
26674
      /*
26675
      * Merge the IDC node table with the table of the parent node.
26676
      */
26677
0
      if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26678
0
    goto internal_error;
26679
0
  }
26680
0
    }
26681
    /*
26682
    * Clear the current ielem.
26683
    * VAL TODO: Don't free the PSVI IDC tables if they are
26684
    * requested for the PSVI.
26685
    */
26686
0
    xmlSchemaClearElemInfo(vctxt, inode);
26687
    /*
26688
    * Skip further processing if we are on the validation root.
26689
    */
26690
0
    if (vctxt->depth == 0) {
26691
0
  vctxt->depth--;
26692
0
  vctxt->inode = NULL;
26693
0
  return (0);
26694
0
    }
26695
    /*
26696
    * Reset the keyrefDepth if needed.
26697
    */
26698
0
    if (vctxt->aidcs != NULL) {
26699
0
  xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26700
0
  do {
26701
0
      if (aidc->keyrefDepth == vctxt->depth) {
26702
    /*
26703
    * A 'keyrefDepth' of a key/unique IDC matches the current
26704
    * depth, this means that we are leaving the scope of the
26705
    * top-most keyref IDC which refers to this IDC.
26706
    */
26707
0
    aidc->keyrefDepth = -1;
26708
0
      }
26709
0
      aidc = aidc->next;
26710
0
  } while (aidc != NULL);
26711
0
    }
26712
0
    vctxt->depth--;
26713
0
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
26714
    /*
26715
    * VAL TODO: 7 If the element information item is the `validation root`, it must be
26716
    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26717
    */
26718
0
    return (ret);
26719
26720
0
internal_error:
26721
0
    vctxt->err = -1;
26722
0
    return (-1);
26723
0
}
26724
26725
/*
26726
* 3.4.4 Complex Type Definition Validation Rules
26727
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26728
*/
26729
static int
26730
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26731
0
{
26732
0
    xmlSchemaNodeInfoPtr pielem;
26733
0
    xmlSchemaTypePtr ptype;
26734
0
    int ret = 0;
26735
26736
0
    if (vctxt->depth <= 0) {
26737
0
  VERROR_INT("xmlSchemaValidateChildElem",
26738
0
      "not intended for the validation root");
26739
0
  return (-1);
26740
0
    }
26741
0
    pielem = vctxt->elemInfos[vctxt->depth -1];
26742
0
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26743
0
  pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26744
    /*
26745
    * Handle 'nilled' elements.
26746
    */
26747
0
    if (INODE_NILLED(pielem)) {
26748
  /*
26749
  * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26750
  */
26751
0
  ACTIVATE_PARENT_ELEM;
26752
0
  ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26753
0
  VERROR(ret, NULL,
26754
0
      "Neither character nor element content is allowed, "
26755
0
      "because the element was 'nilled'");
26756
0
  ACTIVATE_ELEM;
26757
0
  goto unexpected_elem;
26758
0
    }
26759
26760
0
    ptype = pielem->typeDef;
26761
26762
0
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26763
  /*
26764
  * Workaround for "anyType": we have currently no content model
26765
  * assigned for "anyType", so handle it explicitly.
26766
  * "anyType" has an unbounded, lax "any" wildcard.
26767
  */
26768
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26769
0
      vctxt->inode->localName,
26770
0
      vctxt->inode->nsName);
26771
26772
0
  if (vctxt->inode->decl == NULL) {
26773
0
      xmlSchemaAttrInfoPtr iattr;
26774
      /*
26775
      * Process "xsi:type".
26776
      * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26777
      */
26778
0
      iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26779
0
    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26780
0
      if (iattr != NULL) {
26781
0
    ret = xmlSchemaProcessXSIType(vctxt, iattr,
26782
0
        &(vctxt->inode->typeDef), NULL);
26783
0
    if (ret != 0) {
26784
0
        if (ret == -1) {
26785
0
      VERROR_INT("xmlSchemaValidateChildElem",
26786
0
          "calling xmlSchemaProcessXSIType() to "
26787
0
          "process the attribute 'xsi:nil'");
26788
0
      return (-1);
26789
0
        }
26790
0
        return (ret);
26791
0
    }
26792
0
      } else {
26793
     /*
26794
     * Fallback to "anyType".
26795
     *
26796
     * SPEC (cvc-assess-elt)
26797
     * "If the item cannot be `strictly assessed`, [...]
26798
     * an element information item's schema validity may be laxly
26799
     * assessed if its `context-determined declaration` is not
26800
     * skip by `validating` with respect to the `ur-type
26801
     * definition` as per Element Locally Valid (Type) ($3.3.4)."
26802
    */
26803
0
    vctxt->inode->typeDef =
26804
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26805
0
      }
26806
0
  }
26807
0
  return (0);
26808
0
    }
26809
26810
0
    switch (ptype->contentType) {
26811
0
  case XML_SCHEMA_CONTENT_EMPTY:
26812
      /*
26813
      * SPEC (2.1) "If the {content type} is empty, then the
26814
      * element information item has no character or element
26815
      * information item [children]."
26816
      */
26817
0
      ACTIVATE_PARENT_ELEM
26818
0
      ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26819
0
      VERROR(ret, NULL,
26820
0
    "Element content is not allowed, "
26821
0
    "because the content type is empty");
26822
0
      ACTIVATE_ELEM
26823
0
      goto unexpected_elem;
26824
0
      break;
26825
26826
0
  case XML_SCHEMA_CONTENT_MIXED:
26827
0
        case XML_SCHEMA_CONTENT_ELEMENTS: {
26828
0
      xmlRegExecCtxtPtr regexCtxt;
26829
0
      xmlChar *values[10];
26830
0
      int terminal, nbval = 10, nbneg;
26831
26832
      /* VAL TODO: Optimized "anyType" validation.*/
26833
26834
0
      if (ptype->contModel == NULL) {
26835
0
    VERROR_INT("xmlSchemaValidateChildElem",
26836
0
        "type has elem content but no content model");
26837
0
    return (-1);
26838
0
      }
26839
      /*
26840
      * Safety belt for evaluation if the cont. model was already
26841
      * examined to be invalid.
26842
      */
26843
0
      if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26844
0
    VERROR_INT("xmlSchemaValidateChildElem",
26845
0
        "validating elem, but elem content is already invalid");
26846
0
    return (-1);
26847
0
      }
26848
26849
0
      regexCtxt = pielem->regexCtxt;
26850
0
      if (regexCtxt == NULL) {
26851
    /*
26852
    * Create the regex context.
26853
    */
26854
0
    regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26855
0
        xmlSchemaVContentModelCallback, vctxt);
26856
0
    if (regexCtxt == NULL) {
26857
0
        VERROR_INT("xmlSchemaValidateChildElem",
26858
0
      "failed to create a regex context");
26859
0
        return (-1);
26860
0
    }
26861
0
    pielem->regexCtxt = regexCtxt;
26862
#ifdef DEBUG_AUTOMATA
26863
    xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26864
        pielem->localName);
26865
#endif
26866
0
      }
26867
26868
      /*
26869
      * SPEC (2.4) "If the {content type} is element-only or mixed,
26870
      * then the sequence of the element information item's
26871
      * element information item [children], if any, taken in
26872
      * order, is `valid` with respect to the {content type}'s
26873
      * particle, as defined in Element Sequence Locally Valid
26874
      * (Particle) ($3.9.4)."
26875
      */
26876
0
      ret = xmlRegExecPushString2(regexCtxt,
26877
0
    vctxt->inode->localName,
26878
0
    vctxt->inode->nsName,
26879
0
    vctxt->inode);
26880
#ifdef DEBUG_AUTOMATA
26881
      if (ret < 0)
26882
    xmlGenericError(xmlGenericErrorContext,
26883
    "AUTOMATON push ERROR for '%s' on '%s'\n",
26884
    vctxt->inode->localName, pielem->localName);
26885
      else
26886
    xmlGenericError(xmlGenericErrorContext,
26887
    "AUTOMATON push OK for '%s' on '%s'\n",
26888
    vctxt->inode->localName, pielem->localName);
26889
#endif
26890
0
      if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26891
0
    VERROR_INT("xmlSchemaValidateChildElem",
26892
0
        "calling xmlRegExecPushString2()");
26893
0
    return (-1);
26894
0
      }
26895
0
      if (ret < 0) {
26896
0
    xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26897
0
        &values[0], &terminal);
26898
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26899
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26900
0
        "This element is not expected",
26901
0
        nbval, nbneg, values);
26902
0
    ret = vctxt->err;
26903
0
    goto unexpected_elem;
26904
0
      } else
26905
0
    ret = 0;
26906
0
  }
26907
0
      break;
26908
0
  case XML_SCHEMA_CONTENT_SIMPLE:
26909
0
  case XML_SCHEMA_CONTENT_BASIC:
26910
0
      ACTIVATE_PARENT_ELEM
26911
0
      if (WXS_IS_COMPLEX(ptype)) {
26912
    /*
26913
    * SPEC (cvc-complex-type) (2.2)
26914
    * "If the {content type} is a simple type definition, then
26915
    * the element information item has no element information
26916
    * item [children], ..."
26917
    */
26918
0
    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26919
0
    VERROR(ret, NULL, "Element content is not allowed, "
26920
0
        "because the content type is a simple type definition");
26921
0
      } else {
26922
    /*
26923
    * SPEC (cvc-type) (3.1.2) "The element information item must
26924
    * have no element information item [children]."
26925
    */
26926
0
    ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26927
0
    VERROR(ret, NULL, "Element content is not allowed, "
26928
0
        "because the type definition is simple");
26929
0
      }
26930
0
      ACTIVATE_ELEM
26931
0
      ret = vctxt->err;
26932
0
      goto unexpected_elem;
26933
0
      break;
26934
26935
0
  default:
26936
0
      break;
26937
0
    }
26938
0
    return (ret);
26939
0
unexpected_elem:
26940
    /*
26941
    * Pop this element and set the skipDepth to skip
26942
    * all further content of the parent element.
26943
    */
26944
0
    vctxt->skipDepth = vctxt->depth;
26945
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26946
0
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26947
0
    return (ret);
26948
0
}
26949
26950
0
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26951
0
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26952
0
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26953
26954
static int
26955
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26956
      int nodeType, const xmlChar *value, int len,
26957
      int mode, int *consumed)
26958
0
{
26959
    /*
26960
    * Unfortunately we have to duplicate the text sometimes.
26961
    * OPTIMIZE: Maybe we could skip it, if:
26962
    *   1. content type is simple
26963
    *   2. whitespace is "collapse"
26964
    *   3. it consists of whitespace only
26965
    *
26966
    * Process character content.
26967
    */
26968
0
    if (consumed != NULL)
26969
0
  *consumed = 0;
26970
0
    if (INODE_NILLED(vctxt->inode)) {
26971
  /*
26972
  * SPEC cvc-elt (3.3.4 - 3.2.1)
26973
  * "The element information item must have no character or
26974
  * element information item [children]."
26975
  */
26976
0
  VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26977
0
      "Neither character nor element content is allowed "
26978
0
      "because the element is 'nilled'");
26979
0
  return (vctxt->err);
26980
0
    }
26981
    /*
26982
    * SPEC (2.1) "If the {content type} is empty, then the
26983
    * element information item has no character or element
26984
    * information item [children]."
26985
    */
26986
0
    if (vctxt->inode->typeDef->contentType ==
26987
0
      XML_SCHEMA_CONTENT_EMPTY) {
26988
0
  VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26989
0
      "Character content is not allowed, "
26990
0
      "because the content type is empty");
26991
0
  return (vctxt->err);
26992
0
    }
26993
26994
0
    if (vctxt->inode->typeDef->contentType ==
26995
0
      XML_SCHEMA_CONTENT_ELEMENTS) {
26996
0
  if ((nodeType != XML_TEXT_NODE) ||
26997
0
      (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26998
      /*
26999
      * SPEC cvc-complex-type (2.3)
27000
      * "If the {content type} is element-only, then the
27001
      * element information item has no character information
27002
      * item [children] other than those whose [character
27003
      * code] is defined as a white space in [XML 1.0 (Second
27004
      * Edition)]."
27005
      */
27006
0
      VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
27007
0
    "Character content other than whitespace is not allowed "
27008
0
    "because the content type is 'element-only'");
27009
0
      return (vctxt->err);
27010
0
  }
27011
0
  return (0);
27012
0
    }
27013
27014
0
    if ((value == NULL) || (value[0] == 0))
27015
0
  return (0);
27016
    /*
27017
    * Save the value.
27018
    * NOTE that even if the content type is *mixed*, we need the
27019
    * *initial value* for default/fixed value constraints.
27020
    */
27021
0
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
27022
0
  ((vctxt->inode->decl == NULL) ||
27023
0
  (vctxt->inode->decl->value == NULL)))
27024
0
  return (0);
27025
27026
0
    if (vctxt->inode->value == NULL) {
27027
  /*
27028
  * Set the value.
27029
  */
27030
0
  switch (mode) {
27031
0
      case XML_SCHEMA_PUSH_TEXT_PERSIST:
27032
    /*
27033
    * When working on a tree.
27034
    */
27035
0
    vctxt->inode->value = value;
27036
0
    break;
27037
0
      case XML_SCHEMA_PUSH_TEXT_CREATED:
27038
    /*
27039
    * When working with the reader.
27040
    * The value will be freed by the element info.
27041
    */
27042
0
    vctxt->inode->value = value;
27043
0
    if (consumed != NULL)
27044
0
        *consumed = 1;
27045
0
    vctxt->inode->flags |=
27046
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27047
0
    break;
27048
0
      case XML_SCHEMA_PUSH_TEXT_VOLATILE:
27049
    /*
27050
    * When working with SAX.
27051
    * The value will be freed by the element info.
27052
    */
27053
0
    if (len != -1)
27054
0
        vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
27055
0
    else
27056
0
        vctxt->inode->value = BAD_CAST xmlStrdup(value);
27057
0
    vctxt->inode->flags |=
27058
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27059
0
    break;
27060
0
      default:
27061
0
    break;
27062
0
  }
27063
0
    } else {
27064
0
  if (len < 0)
27065
0
      len = xmlStrlen(value);
27066
  /*
27067
  * Concat the value.
27068
  */
27069
0
  if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
27070
0
      vctxt->inode->value = BAD_CAST xmlStrncat(
27071
0
    (xmlChar *) vctxt->inode->value, value, len);
27072
0
  } else {
27073
0
      vctxt->inode->value =
27074
0
    BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
27075
0
      vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27076
0
  }
27077
0
    }
27078
27079
0
    return (0);
27080
0
}
27081
27082
static int
27083
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
27084
0
{
27085
0
    int ret = 0;
27086
27087
0
    if ((vctxt->skipDepth != -1) &&
27088
0
  (vctxt->depth >= vctxt->skipDepth)) {
27089
0
  VERROR_INT("xmlSchemaValidateElem",
27090
0
      "in skip-state");
27091
0
  goto internal_error;
27092
0
    }
27093
0
    if (vctxt->xsiAssemble) {
27094
  /*
27095
  * We will stop validation if there was an error during
27096
  * dynamic schema construction.
27097
  * Note that we simply set @skipDepth to 0, this could
27098
  * mean that a streaming document via SAX would be
27099
  * still read to the end but it won't be validated any more.
27100
  * TODO: If we are sure how to stop the validation at once
27101
  *   for all input scenarios, then this should be changed to
27102
  *   instantly stop the validation.
27103
  */
27104
0
  ret = xmlSchemaAssembleByXSI(vctxt);
27105
0
  if (ret != 0) {
27106
0
      if (ret == -1)
27107
0
    goto internal_error;
27108
0
      vctxt->skipDepth = 0;
27109
0
      return(ret);
27110
0
  }
27111
        /*
27112
         * Augment the IDC definitions for the main schema and all imported ones
27113
         * NOTE: main schema is the first in the imported list
27114
         */
27115
0
        xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
27116
0
                    vctxt);
27117
0
    }
27118
0
    if (vctxt->depth > 0) {
27119
  /*
27120
  * Validate this element against the content model
27121
  * of the parent.
27122
  */
27123
0
  ret = xmlSchemaValidateChildElem(vctxt);
27124
0
  if (ret != 0) {
27125
0
      if (ret < 0) {
27126
0
    VERROR_INT("xmlSchemaValidateElem",
27127
0
        "calling xmlSchemaStreamValidateChildElement()");
27128
0
    goto internal_error;
27129
0
      }
27130
0
      goto exit;
27131
0
  }
27132
0
  if (vctxt->depth == vctxt->skipDepth)
27133
0
      goto exit;
27134
0
  if ((vctxt->inode->decl == NULL) &&
27135
0
      (vctxt->inode->typeDef == NULL)) {
27136
0
      VERROR_INT("xmlSchemaValidateElem",
27137
0
    "the child element was valid but neither the "
27138
0
    "declaration nor the type was set");
27139
0
      goto internal_error;
27140
0
  }
27141
0
    } else {
27142
  /*
27143
  * Get the declaration of the validation root.
27144
  */
27145
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
27146
0
      vctxt->inode->localName,
27147
0
      vctxt->inode->nsName);
27148
0
  if (vctxt->inode->decl == NULL) {
27149
0
      ret = XML_SCHEMAV_CVC_ELT_1;
27150
0
      VERROR(ret, NULL,
27151
0
    "No matching global declaration available "
27152
0
    "for the validation root");
27153
0
      goto exit;
27154
0
  }
27155
0
    }
27156
27157
0
    if (vctxt->inode->decl == NULL)
27158
0
  goto type_validation;
27159
27160
0
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
27161
0
  int skip;
27162
  /*
27163
  * Wildcards.
27164
  */
27165
0
  ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
27166
0
  if (ret != 0) {
27167
0
      if (ret < 0) {
27168
0
    VERROR_INT("xmlSchemaValidateElem",
27169
0
        "calling xmlSchemaValidateElemWildcard()");
27170
0
    goto internal_error;
27171
0
      }
27172
0
      goto exit;
27173
0
  }
27174
0
  if (skip) {
27175
0
      vctxt->skipDepth = vctxt->depth;
27176
0
      goto exit;
27177
0
  }
27178
  /*
27179
  * The declaration might be set by the wildcard validation,
27180
  * when the processContents is "lax" or "strict".
27181
  */
27182
0
  if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
27183
      /*
27184
      * Clear the "decl" field to not confuse further processing.
27185
      */
27186
0
      vctxt->inode->decl = NULL;
27187
0
      goto type_validation;
27188
0
  }
27189
0
    }
27190
    /*
27191
    * Validate against the declaration.
27192
    */
27193
0
    ret = xmlSchemaValidateElemDecl(vctxt);
27194
0
    if (ret != 0) {
27195
0
  if (ret < 0) {
27196
0
      VERROR_INT("xmlSchemaValidateElem",
27197
0
    "calling xmlSchemaValidateElemDecl()");
27198
0
      goto internal_error;
27199
0
  }
27200
0
  goto exit;
27201
0
    }
27202
    /*
27203
    * Validate against the type definition.
27204
    */
27205
0
type_validation:
27206
27207
0
    if (vctxt->inode->typeDef == NULL) {
27208
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
27209
0
  ret = XML_SCHEMAV_CVC_TYPE_1;
27210
0
  VERROR(ret, NULL,
27211
0
      "The type definition is absent");
27212
0
  goto exit;
27213
0
    }
27214
0
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
27215
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
27216
0
  ret = XML_SCHEMAV_CVC_TYPE_2;
27217
0
      VERROR(ret, NULL,
27218
0
      "The type definition is abstract");
27219
0
  goto exit;
27220
0
    }
27221
    /*
27222
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
27223
    * during validation against the declaration. This must be done
27224
    * _before_ attribute validation.
27225
    */
27226
0
    if (vctxt->xpathStates != NULL) {
27227
0
  ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
27228
0
  vctxt->inode->appliedXPath = 1;
27229
0
  if (ret == -1) {
27230
0
      VERROR_INT("xmlSchemaValidateElem",
27231
0
    "calling xmlSchemaXPathEvaluate()");
27232
0
      goto internal_error;
27233
0
  }
27234
0
    }
27235
    /*
27236
    * Validate attributes.
27237
    */
27238
0
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
27239
0
  if ((vctxt->nbAttrInfos != 0) ||
27240
0
      (vctxt->inode->typeDef->attrUses != NULL)) {
27241
27242
0
      ret = xmlSchemaVAttributesComplex(vctxt);
27243
0
  }
27244
0
    } else if (vctxt->nbAttrInfos != 0) {
27245
27246
0
  ret = xmlSchemaVAttributesSimple(vctxt);
27247
0
    }
27248
    /*
27249
    * Clear registered attributes.
27250
    */
27251
0
    if (vctxt->nbAttrInfos != 0)
27252
0
  xmlSchemaClearAttrInfos(vctxt);
27253
0
    if (ret == -1) {
27254
0
  VERROR_INT("xmlSchemaValidateElem",
27255
0
      "calling attributes validation");
27256
0
  goto internal_error;
27257
0
    }
27258
    /*
27259
    * Don't return an error if attributes are invalid on purpose.
27260
    */
27261
0
    ret = 0;
27262
27263
0
exit:
27264
0
    if (ret != 0)
27265
0
  vctxt->skipDepth = vctxt->depth;
27266
0
    return (ret);
27267
0
internal_error:
27268
0
    return (-1);
27269
0
}
27270
27271
#ifdef XML_SCHEMA_READER_ENABLED
27272
static int
27273
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
27274
{
27275
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
27276
    int depth, nodeType, ret = 0, consumed;
27277
    xmlSchemaNodeInfoPtr ielem;
27278
27279
    vctxt->depth = -1;
27280
    ret = xmlTextReaderRead(vctxt->reader);
27281
    /*
27282
    * Move to the document element.
27283
    */
27284
    while (ret == 1) {
27285
  nodeType = xmlTextReaderNodeType(vctxt->reader);
27286
  if (nodeType == XML_ELEMENT_NODE)
27287
      goto root_found;
27288
  ret = xmlTextReaderRead(vctxt->reader);
27289
    }
27290
    goto exit;
27291
27292
root_found:
27293
27294
    do {
27295
  depth = xmlTextReaderDepth(vctxt->reader);
27296
  nodeType = xmlTextReaderNodeType(vctxt->reader);
27297
27298
  if (nodeType == XML_ELEMENT_NODE) {
27299
27300
      vctxt->depth++;
27301
      if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27302
    VERROR_INT("xmlSchemaVReaderWalk",
27303
        "calling xmlSchemaValidatorPushElem()");
27304
    goto internal_error;
27305
      }
27306
      ielem = vctxt->inode;
27307
      ielem->localName = xmlTextReaderLocalName(vctxt->reader);
27308
      ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
27309
      ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
27310
      /*
27311
      * Is the element empty?
27312
      */
27313
      ret = xmlTextReaderIsEmptyElement(vctxt->reader);
27314
      if (ret == -1) {
27315
    VERROR_INT("xmlSchemaVReaderWalk",
27316
        "calling xmlTextReaderIsEmptyElement()");
27317
    goto internal_error;
27318
      }
27319
      if (ret) {
27320
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27321
      }
27322
      /*
27323
      * Register attributes.
27324
      */
27325
      vctxt->nbAttrInfos = 0;
27326
      ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
27327
      if (ret == -1) {
27328
    VERROR_INT("xmlSchemaVReaderWalk",
27329
        "calling xmlTextReaderMoveToFirstAttribute()");
27330
    goto internal_error;
27331
      }
27332
      if (ret == 1) {
27333
    do {
27334
        /*
27335
        * VAL TODO: How do we know that the reader works on a
27336
        * node tree, to be able to pass a node here?
27337
        */
27338
        if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27339
      (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27340
      xmlTextReaderNamespaceUri(vctxt->reader), 1,
27341
      xmlTextReaderValue(vctxt->reader), 1) == -1) {
27342
27343
      VERROR_INT("xmlSchemaVReaderWalk",
27344
          "calling xmlSchemaValidatorPushAttribute()");
27345
      goto internal_error;
27346
        }
27347
        ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27348
        if (ret == -1) {
27349
      VERROR_INT("xmlSchemaVReaderWalk",
27350
          "calling xmlTextReaderMoveToFirstAttribute()");
27351
      goto internal_error;
27352
        }
27353
    } while (ret == 1);
27354
    /*
27355
    * Back to element position.
27356
    */
27357
    ret = xmlTextReaderMoveToElement(vctxt->reader);
27358
    if (ret == -1) {
27359
        VERROR_INT("xmlSchemaVReaderWalk",
27360
      "calling xmlTextReaderMoveToElement()");
27361
        goto internal_error;
27362
    }
27363
      }
27364
      /*
27365
      * Validate the element.
27366
      */
27367
      ret= xmlSchemaValidateElem(vctxt);
27368
      if (ret != 0) {
27369
    if (ret == -1) {
27370
        VERROR_INT("xmlSchemaVReaderWalk",
27371
      "calling xmlSchemaValidateElem()");
27372
        goto internal_error;
27373
    }
27374
    goto exit;
27375
      }
27376
      if (vctxt->depth == vctxt->skipDepth) {
27377
    int curDepth;
27378
    /*
27379
    * Skip all content.
27380
    */
27381
    if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27382
        ret = xmlTextReaderRead(vctxt->reader);
27383
        curDepth = xmlTextReaderDepth(vctxt->reader);
27384
        while ((ret == 1) && (curDepth != depth)) {
27385
      ret = xmlTextReaderRead(vctxt->reader);
27386
      curDepth = xmlTextReaderDepth(vctxt->reader);
27387
        }
27388
        if (ret < 0) {
27389
      /*
27390
      * VAL TODO: A reader error occurred; what to do here?
27391
      */
27392
      ret = 1;
27393
      goto exit;
27394
        }
27395
    }
27396
    goto leave_elem;
27397
      }
27398
      /*
27399
      * READER VAL TODO: Is an END_ELEM really never called
27400
      * if the elem is empty?
27401
      */
27402
      if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27403
    goto leave_elem;
27404
  } else if (nodeType == END_ELEM) {
27405
      /*
27406
      * Process END of element.
27407
      */
27408
leave_elem:
27409
      ret = xmlSchemaValidatorPopElem(vctxt);
27410
      if (ret != 0) {
27411
    if (ret < 0) {
27412
        VERROR_INT("xmlSchemaVReaderWalk",
27413
      "calling xmlSchemaValidatorPopElem()");
27414
        goto internal_error;
27415
    }
27416
    goto exit;
27417
      }
27418
      if (vctxt->depth >= 0)
27419
    ielem = vctxt->inode;
27420
      else
27421
    ielem = NULL;
27422
  } else if ((nodeType == XML_TEXT_NODE) ||
27423
      (nodeType == XML_CDATA_SECTION_NODE) ||
27424
      (nodeType == WHTSP) ||
27425
      (nodeType == SIGN_WHTSP)) {
27426
      /*
27427
      * Process character content.
27428
      */
27429
      xmlChar *value;
27430
27431
      if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27432
    nodeType = XML_TEXT_NODE;
27433
27434
      value = xmlTextReaderValue(vctxt->reader);
27435
      ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27436
    -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27437
      if (! consumed)
27438
    xmlFree(value);
27439
      if (ret == -1) {
27440
    VERROR_INT("xmlSchemaVReaderWalk",
27441
        "calling xmlSchemaVPushText()");
27442
    goto internal_error;
27443
      }
27444
  } else if ((nodeType == XML_ENTITY_NODE) ||
27445
      (nodeType == XML_ENTITY_REF_NODE)) {
27446
      /*
27447
      * VAL TODO: What to do with entities?
27448
      */
27449
      TODO
27450
  }
27451
  /*
27452
  * Read next node.
27453
  */
27454
  ret = xmlTextReaderRead(vctxt->reader);
27455
    } while (ret == 1);
27456
27457
exit:
27458
    return (ret);
27459
internal_error:
27460
    return (-1);
27461
}
27462
#endif
27463
27464
/************************************************************************
27465
 *                  *
27466
 *      SAX validation handlers       *
27467
 *                  *
27468
 ************************************************************************/
27469
27470
/*
27471
* Process text content.
27472
*/
27473
static void
27474
xmlSchemaSAXHandleText(void *ctx,
27475
           const xmlChar * ch,
27476
           int len)
27477
0
{
27478
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27479
27480
0
    if (vctxt->depth < 0)
27481
0
  return;
27482
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27483
0
  return;
27484
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27485
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27486
0
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27487
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27488
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27489
0
      "calling xmlSchemaVPushText()");
27490
0
  vctxt->err = -1;
27491
0
  xmlStopParser(vctxt->parserCtxt);
27492
0
    }
27493
0
}
27494
27495
/*
27496
* Process CDATA content.
27497
*/
27498
static void
27499
xmlSchemaSAXHandleCDataSection(void *ctx,
27500
           const xmlChar * ch,
27501
           int len)
27502
0
{
27503
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27504
27505
0
    if (vctxt->depth < 0)
27506
0
  return;
27507
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27508
0
  return;
27509
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27510
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27511
0
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27512
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27513
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27514
0
      "calling xmlSchemaVPushText()");
27515
0
  vctxt->err = -1;
27516
0
  xmlStopParser(vctxt->parserCtxt);
27517
0
    }
27518
0
}
27519
27520
static void
27521
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27522
          const xmlChar * name ATTRIBUTE_UNUSED)
27523
0
{
27524
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27525
27526
0
    if (vctxt->depth < 0)
27527
0
  return;
27528
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27529
0
  return;
27530
    /* SAX VAL TODO: What to do here? */
27531
0
    TODO
27532
0
}
27533
27534
static void
27535
xmlSchemaSAXHandleStartElementNs(void *ctx,
27536
         const xmlChar * localname,
27537
         const xmlChar * prefix ATTRIBUTE_UNUSED,
27538
         const xmlChar * URI,
27539
         int nb_namespaces,
27540
         const xmlChar ** namespaces,
27541
         int nb_attributes,
27542
         int nb_defaulted ATTRIBUTE_UNUSED,
27543
         const xmlChar ** attributes)
27544
0
{
27545
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27546
0
    int ret;
27547
0
    xmlSchemaNodeInfoPtr ielem;
27548
0
    int i, j;
27549
27550
    /*
27551
    * SAX VAL TODO: What to do with nb_defaulted?
27552
    */
27553
    /*
27554
    * Skip elements if inside a "skip" wildcard or invalid.
27555
    */
27556
0
    vctxt->depth++;
27557
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27558
0
  return;
27559
    /*
27560
    * Push the element.
27561
    */
27562
0
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27563
0
  VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27564
0
      "calling xmlSchemaValidatorPushElem()");
27565
0
  goto internal_error;
27566
0
    }
27567
0
    ielem = vctxt->inode;
27568
    /*
27569
    * TODO: Is this OK?
27570
    */
27571
0
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27572
0
    ielem->localName = localname;
27573
0
    ielem->nsName = URI;
27574
0
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27575
    /*
27576
    * Register namespaces on the elem info.
27577
    */
27578
0
    if (nb_namespaces != 0) {
27579
  /*
27580
  * Although the parser builds its own namespace list,
27581
  * we have no access to it, so we'll use an own one.
27582
  */
27583
0
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27584
      /*
27585
      * Store prefix and namespace name.
27586
      */
27587
0
      if (ielem->nsBindings == NULL) {
27588
0
    ielem->nsBindings =
27589
0
        (const xmlChar **) xmlMalloc(10 *
27590
0
      sizeof(const xmlChar *));
27591
0
    if (ielem->nsBindings == NULL) {
27592
0
        xmlSchemaVErrMemory(vctxt,
27593
0
      "allocating namespace bindings for SAX validation",
27594
0
      NULL);
27595
0
        goto internal_error;
27596
0
    }
27597
0
    ielem->nbNsBindings = 0;
27598
0
    ielem->sizeNsBindings = 5;
27599
0
      } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27600
0
    ielem->sizeNsBindings *= 2;
27601
0
    ielem->nsBindings =
27602
0
        (const xmlChar **) xmlRealloc(
27603
0
      (void *) ielem->nsBindings,
27604
0
      ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27605
0
    if (ielem->nsBindings == NULL) {
27606
0
        xmlSchemaVErrMemory(vctxt,
27607
0
      "re-allocating namespace bindings for SAX validation",
27608
0
      NULL);
27609
0
        goto internal_error;
27610
0
    }
27611
0
      }
27612
27613
0
      ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27614
0
      if (namespaces[j+1][0] == 0) {
27615
    /*
27616
    * Handle xmlns="".
27617
    */
27618
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27619
0
      } else
27620
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27621
0
        namespaces[j+1];
27622
0
      ielem->nbNsBindings++;
27623
0
  }
27624
0
    }
27625
    /*
27626
    * Register attributes.
27627
    * SAX VAL TODO: We are not adding namespace declaration
27628
    * attributes yet.
27629
    */
27630
0
    if (nb_attributes != 0) {
27631
0
  int valueLen, k, l;
27632
0
  xmlChar *value;
27633
27634
0
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27635
      /*
27636
      * Duplicate the value, changing any &#38; to a literal ampersand.
27637
      *
27638
      * libxml2 differs from normal SAX here in that it escapes all ampersands
27639
      * as &#38; instead of delivering the raw converted string. Changing the
27640
      * behavior at this point would break applications that use this API, so
27641
      * we are forced to work around it.
27642
      */
27643
0
      valueLen = attributes[j+4] - attributes[j+3];
27644
0
      value = xmlMallocAtomic(valueLen + 1);
27645
0
      if (value == NULL) {
27646
0
    xmlSchemaVErrMemory(vctxt,
27647
0
        "allocating string for decoded attribute",
27648
0
        NULL);
27649
0
    goto internal_error;
27650
0
      }
27651
0
      for (k = 0, l = 0; k < valueLen; l++) {
27652
0
    if (k < valueLen - 4 &&
27653
0
        attributes[j+3][k+0] == '&' &&
27654
0
        attributes[j+3][k+1] == '#' &&
27655
0
        attributes[j+3][k+2] == '3' &&
27656
0
        attributes[j+3][k+3] == '8' &&
27657
0
        attributes[j+3][k+4] == ';') {
27658
0
        value[l] = '&';
27659
0
        k += 5;
27660
0
    } else {
27661
0
        value[l] = attributes[j+3][k];
27662
0
        k++;
27663
0
    }
27664
0
      }
27665
0
      value[l] = '\0';
27666
      /*
27667
      * TODO: Set the node line.
27668
      */
27669
0
      ret = xmlSchemaValidatorPushAttribute(vctxt,
27670
0
    NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27671
0
    value, 1);
27672
0
      if (ret == -1) {
27673
0
    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27674
0
        "calling xmlSchemaValidatorPushAttribute()");
27675
0
    goto internal_error;
27676
0
      }
27677
0
  }
27678
0
    }
27679
    /*
27680
    * Validate the element.
27681
    */
27682
0
    ret = xmlSchemaValidateElem(vctxt);
27683
0
    if (ret != 0) {
27684
0
  if (ret == -1) {
27685
0
      VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27686
0
    "calling xmlSchemaValidateElem()");
27687
0
      goto internal_error;
27688
0
  }
27689
0
  goto exit;
27690
0
    }
27691
27692
0
exit:
27693
0
    return;
27694
0
internal_error:
27695
0
    vctxt->err = -1;
27696
0
    xmlStopParser(vctxt->parserCtxt);
27697
0
    return;
27698
0
}
27699
27700
static void
27701
xmlSchemaSAXHandleEndElementNs(void *ctx,
27702
             const xmlChar * localname ATTRIBUTE_UNUSED,
27703
             const xmlChar * prefix ATTRIBUTE_UNUSED,
27704
             const xmlChar * URI ATTRIBUTE_UNUSED)
27705
0
{
27706
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27707
0
    int res;
27708
27709
    /*
27710
    * Skip elements if inside a "skip" wildcard or if invalid.
27711
    */
27712
0
    if (vctxt->skipDepth != -1) {
27713
0
  if (vctxt->depth > vctxt->skipDepth) {
27714
0
      vctxt->depth--;
27715
0
      return;
27716
0
  } else
27717
0
      vctxt->skipDepth = -1;
27718
0
    }
27719
    /*
27720
    * SAX VAL TODO: Just a temporary check.
27721
    */
27722
0
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27723
0
  (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27724
0
  VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27725
0
      "elem pop mismatch");
27726
0
    }
27727
0
    res = xmlSchemaValidatorPopElem(vctxt);
27728
0
    if (res != 0) {
27729
0
  if (res < 0) {
27730
0
      VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27731
0
    "calling xmlSchemaValidatorPopElem()");
27732
0
      goto internal_error;
27733
0
  }
27734
0
  goto exit;
27735
0
    }
27736
0
exit:
27737
0
    return;
27738
0
internal_error:
27739
0
    vctxt->err = -1;
27740
0
    xmlStopParser(vctxt->parserCtxt);
27741
0
    return;
27742
0
}
27743
27744
/************************************************************************
27745
 *                  *
27746
 *      Validation interfaces       *
27747
 *                  *
27748
 ************************************************************************/
27749
27750
/**
27751
 * xmlSchemaNewValidCtxt:
27752
 * @schema:  a precompiled XML Schemas
27753
 *
27754
 * Create an XML Schemas validation context based on the given schema.
27755
 *
27756
 * Returns the validation context or NULL in case of error
27757
 */
27758
xmlSchemaValidCtxtPtr
27759
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27760
0
{
27761
0
    xmlSchemaValidCtxtPtr ret;
27762
27763
0
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27764
0
    if (ret == NULL) {
27765
0
        xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27766
0
        return (NULL);
27767
0
    }
27768
0
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27769
0
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27770
0
    ret->dict = xmlDictCreate();
27771
0
    ret->nodeQNames = xmlSchemaItemListCreate();
27772
0
    ret->schema = schema;
27773
0
    return (ret);
27774
0
}
27775
27776
/**
27777
 * xmlSchemaValidateSetFilename:
27778
 * @vctxt: the schema validation context
27779
 * @filename: the file name
27780
 *
27781
 * Workaround to provide file error reporting information when this is
27782
 * not provided by current APIs
27783
 */
27784
void
27785
0
xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27786
0
    if (vctxt == NULL)
27787
0
        return;
27788
0
    if (vctxt->filename != NULL)
27789
0
        xmlFree(vctxt->filename);
27790
0
    if (filename != NULL)
27791
0
        vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27792
0
    else
27793
0
        vctxt->filename = NULL;
27794
0
}
27795
27796
/**
27797
 * xmlSchemaClearValidCtxt:
27798
 * @vctxt: the schema validation context
27799
 *
27800
 * Free the resources associated to the schema validation context;
27801
 * leaves some fields alive intended for reuse of the context.
27802
 */
27803
static void
27804
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27805
0
{
27806
0
    if (vctxt == NULL)
27807
0
        return;
27808
27809
    /*
27810
    * TODO: Should we clear the flags?
27811
    *   Might be problematic if one reuses the context
27812
    *   and assumes that the options remain the same.
27813
    */
27814
0
    vctxt->flags = 0;
27815
0
    vctxt->validationRoot = NULL;
27816
0
    vctxt->doc = NULL;
27817
0
#ifdef LIBXML_READER_ENABLED
27818
0
    vctxt->reader = NULL;
27819
0
#endif
27820
0
    vctxt->hasKeyrefs = 0;
27821
27822
0
    if (vctxt->value != NULL) {
27823
0
        xmlSchemaFreeValue(vctxt->value);
27824
0
  vctxt->value = NULL;
27825
0
    }
27826
    /*
27827
    * Augmented IDC information.
27828
    */
27829
0
    if (vctxt->aidcs != NULL) {
27830
0
  xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27831
0
  do {
27832
0
      next = cur->next;
27833
0
      xmlFree(cur);
27834
0
      cur = next;
27835
0
  } while (cur != NULL);
27836
0
  vctxt->aidcs = NULL;
27837
0
    }
27838
27839
0
    if (vctxt->idcNodes != NULL) {
27840
0
  int i;
27841
0
  xmlSchemaPSVIIDCNodePtr item;
27842
27843
0
  for (i = 0; i < vctxt->nbIdcNodes; i++) {
27844
0
      item = vctxt->idcNodes[i];
27845
0
      xmlFree(item->keys);
27846
0
      xmlFree(item);
27847
0
  }
27848
0
  xmlFree(vctxt->idcNodes);
27849
0
  vctxt->idcNodes = NULL;
27850
0
  vctxt->nbIdcNodes = 0;
27851
0
  vctxt->sizeIdcNodes = 0;
27852
0
    }
27853
27854
0
    if (vctxt->idcKeys != NULL) {
27855
0
  int i;
27856
0
  for (i = 0; i < vctxt->nbIdcKeys; i++)
27857
0
      xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27858
0
  xmlFree(vctxt->idcKeys);
27859
0
  vctxt->idcKeys = NULL;
27860
0
  vctxt->nbIdcKeys = 0;
27861
0
  vctxt->sizeIdcKeys = 0;
27862
0
    }
27863
27864
    /*
27865
    * Note that we won't delete the XPath state pool here.
27866
    */
27867
0
    if (vctxt->xpathStates != NULL) {
27868
0
  xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27869
0
  vctxt->xpathStates = NULL;
27870
0
    }
27871
    /*
27872
    * Attribute info.
27873
    */
27874
0
    if (vctxt->nbAttrInfos != 0) {
27875
0
  xmlSchemaClearAttrInfos(vctxt);
27876
0
    }
27877
    /*
27878
    * Element info.
27879
    */
27880
0
    if (vctxt->elemInfos != NULL) {
27881
0
  int i;
27882
0
  xmlSchemaNodeInfoPtr ei;
27883
27884
0
  for (i = 0; i < vctxt->sizeElemInfos; i++) {
27885
0
      ei = vctxt->elemInfos[i];
27886
0
      if (ei == NULL)
27887
0
    break;
27888
0
      xmlSchemaClearElemInfo(vctxt, ei);
27889
0
  }
27890
0
    }
27891
0
    xmlSchemaItemListClear(vctxt->nodeQNames);
27892
    /* Recreate the dict. */
27893
0
    xmlDictFree(vctxt->dict);
27894
    /*
27895
    * TODO: Is is save to recreate it? Do we have a scenario
27896
    * where the user provides the dict?
27897
    */
27898
0
    vctxt->dict = xmlDictCreate();
27899
27900
0
    if (vctxt->filename != NULL) {
27901
0
        xmlFree(vctxt->filename);
27902
0
  vctxt->filename = NULL;
27903
0
    }
27904
27905
    /*
27906
     * Note that some cleanup functions can move items to the cache,
27907
     * so the cache shouldn't be freed too early.
27908
     */
27909
0
    if (vctxt->idcMatcherCache != NULL) {
27910
0
  xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27911
27912
0
  while (matcher) {
27913
0
      tmp = matcher;
27914
0
      matcher = matcher->nextCached;
27915
0
      xmlSchemaIDCFreeMatcherList(tmp);
27916
0
  }
27917
0
  vctxt->idcMatcherCache = NULL;
27918
0
    }
27919
0
}
27920
27921
/**
27922
 * xmlSchemaFreeValidCtxt:
27923
 * @ctxt:  the schema validation context
27924
 *
27925
 * Free the resources associated to the schema validation context
27926
 */
27927
void
27928
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27929
0
{
27930
0
    if (ctxt == NULL)
27931
0
        return;
27932
0
    if (ctxt->value != NULL)
27933
0
        xmlSchemaFreeValue(ctxt->value);
27934
0
    if (ctxt->pctxt != NULL)
27935
0
  xmlSchemaFreeParserCtxt(ctxt->pctxt);
27936
0
    if (ctxt->idcNodes != NULL) {
27937
0
  int i;
27938
0
  xmlSchemaPSVIIDCNodePtr item;
27939
27940
0
  for (i = 0; i < ctxt->nbIdcNodes; i++) {
27941
0
      item = ctxt->idcNodes[i];
27942
0
      xmlFree(item->keys);
27943
0
      xmlFree(item);
27944
0
  }
27945
0
  xmlFree(ctxt->idcNodes);
27946
0
    }
27947
0
    if (ctxt->idcKeys != NULL) {
27948
0
  int i;
27949
0
  for (i = 0; i < ctxt->nbIdcKeys; i++)
27950
0
      xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27951
0
  xmlFree(ctxt->idcKeys);
27952
0
    }
27953
27954
0
    if (ctxt->xpathStates != NULL) {
27955
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27956
0
  ctxt->xpathStates = NULL;
27957
0
    }
27958
0
    if (ctxt->xpathStatePool != NULL) {
27959
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27960
0
  ctxt->xpathStatePool = NULL;
27961
0
    }
27962
27963
    /*
27964
    * Augmented IDC information.
27965
    */
27966
0
    if (ctxt->aidcs != NULL) {
27967
0
  xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27968
0
  do {
27969
0
      next = cur->next;
27970
0
      xmlFree(cur);
27971
0
      cur = next;
27972
0
  } while (cur != NULL);
27973
0
    }
27974
0
    if (ctxt->attrInfos != NULL) {
27975
0
  int i;
27976
0
  xmlSchemaAttrInfoPtr attr;
27977
27978
  /* Just a paranoid call to the cleanup. */
27979
0
  if (ctxt->nbAttrInfos != 0)
27980
0
      xmlSchemaClearAttrInfos(ctxt);
27981
0
  for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27982
0
      attr = ctxt->attrInfos[i];
27983
0
      xmlFree(attr);
27984
0
  }
27985
0
  xmlFree(ctxt->attrInfos);
27986
0
    }
27987
0
    if (ctxt->elemInfos != NULL) {
27988
0
  int i;
27989
0
  xmlSchemaNodeInfoPtr ei;
27990
27991
0
  for (i = 0; i < ctxt->sizeElemInfos; i++) {
27992
0
      ei = ctxt->elemInfos[i];
27993
0
      if (ei == NULL)
27994
0
    break;
27995
0
      xmlSchemaClearElemInfo(ctxt, ei);
27996
0
      xmlFree(ei);
27997
0
  }
27998
0
  xmlFree(ctxt->elemInfos);
27999
0
    }
28000
0
    if (ctxt->nodeQNames != NULL)
28001
0
  xmlSchemaItemListFree(ctxt->nodeQNames);
28002
0
    if (ctxt->dict != NULL)
28003
0
  xmlDictFree(ctxt->dict);
28004
0
    if (ctxt->filename != NULL)
28005
0
  xmlFree(ctxt->filename);
28006
0
    xmlFree(ctxt);
28007
0
}
28008
28009
/**
28010
 * xmlSchemaIsValid:
28011
 * @ctxt: the schema validation context
28012
 *
28013
 * Check if any error was detected during validation.
28014
 *
28015
 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
28016
 *         of internal error.
28017
 */
28018
int
28019
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
28020
0
{
28021
0
    if (ctxt == NULL)
28022
0
        return(-1);
28023
0
    return(ctxt->err == 0);
28024
0
}
28025
28026
/**
28027
 * xmlSchemaSetValidErrors:
28028
 * @ctxt:  a schema validation context
28029
 * @err:  the error function
28030
 * @warn: the warning function
28031
 * @ctx: the functions context
28032
 *
28033
 * Set the error and warning callback information
28034
 */
28035
void
28036
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
28037
                        xmlSchemaValidityErrorFunc err,
28038
                        xmlSchemaValidityWarningFunc warn, void *ctx)
28039
0
{
28040
0
    if (ctxt == NULL)
28041
0
        return;
28042
0
    ctxt->error = err;
28043
0
    ctxt->warning = warn;
28044
0
    ctxt->errCtxt = ctx;
28045
0
    if (ctxt->pctxt != NULL)
28046
0
  xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
28047
0
}
28048
28049
/**
28050
 * xmlSchemaSetValidStructuredErrors:
28051
 * @ctxt:  a schema validation context
28052
 * @serror:  the structured error function
28053
 * @ctx: the functions context
28054
 *
28055
 * Set the structured error callback
28056
 */
28057
void
28058
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
28059
          xmlStructuredErrorFunc serror, void *ctx)
28060
0
{
28061
0
    if (ctxt == NULL)
28062
0
        return;
28063
0
    ctxt->serror = serror;
28064
0
    ctxt->error = NULL;
28065
0
    ctxt->warning = NULL;
28066
0
    ctxt->errCtxt = ctx;
28067
0
    if (ctxt->pctxt != NULL)
28068
0
  xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
28069
0
}
28070
28071
/**
28072
 * xmlSchemaGetValidErrors:
28073
 * @ctxt: a XML-Schema validation context
28074
 * @err: the error function result
28075
 * @warn: the warning function result
28076
 * @ctx: the functions context result
28077
 *
28078
 * Get the error and warning callback information
28079
 *
28080
 * Returns -1 in case of error and 0 otherwise
28081
 */
28082
int
28083
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
28084
      xmlSchemaValidityErrorFunc * err,
28085
      xmlSchemaValidityWarningFunc * warn, void **ctx)
28086
0
{
28087
0
  if (ctxt == NULL)
28088
0
    return (-1);
28089
0
  if (err != NULL)
28090
0
    *err = ctxt->error;
28091
0
  if (warn != NULL)
28092
0
    *warn = ctxt->warning;
28093
0
  if (ctx != NULL)
28094
0
    *ctx = ctxt->errCtxt;
28095
0
  return (0);
28096
0
}
28097
28098
28099
/**
28100
 * xmlSchemaSetValidOptions:
28101
 * @ctxt: a schema validation context
28102
 * @options: a combination of xmlSchemaValidOption
28103
 *
28104
 * Sets the options to be used during the validation.
28105
 *
28106
 * Returns 0 in case of success, -1 in case of an
28107
 * API error.
28108
 */
28109
int
28110
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
28111
       int options)
28112
28113
0
{
28114
0
    int i;
28115
28116
0
    if (ctxt == NULL)
28117
0
  return (-1);
28118
    /*
28119
    * WARNING: Change the start value if adding to the
28120
    * xmlSchemaValidOption.
28121
    * TODO: Is there an other, more easy to maintain,
28122
    * way?
28123
    */
28124
0
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
28125
0
        if (options & 1<<i)
28126
0
      return (-1);
28127
0
    }
28128
0
    ctxt->options = options;
28129
0
    return (0);
28130
0
}
28131
28132
/**
28133
 * xmlSchemaValidCtxtGetOptions:
28134
 * @ctxt: a schema validation context
28135
 *
28136
 * Get the validation context options.
28137
 *
28138
 * Returns the option combination or -1 on error.
28139
 */
28140
int
28141
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
28142
28143
0
{
28144
0
    if (ctxt == NULL)
28145
0
  return (-1);
28146
0
    else
28147
0
  return (ctxt->options);
28148
0
}
28149
28150
static int
28151
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
28152
0
{
28153
0
    xmlAttrPtr attr;
28154
0
    int ret = 0;
28155
0
    xmlSchemaNodeInfoPtr ielem = NULL;
28156
0
    xmlNodePtr node, valRoot;
28157
0
    const xmlChar *nsName;
28158
28159
    /* DOC VAL TODO: Move this to the start function. */
28160
0
    if (vctxt->validationRoot != NULL)
28161
0
        valRoot = vctxt->validationRoot;
28162
0
    else
28163
0
  valRoot = xmlDocGetRootElement(vctxt->doc);
28164
0
    if (valRoot == NULL) {
28165
  /* VAL TODO: Error code? */
28166
0
  VERROR(1, NULL, "The document has no document element");
28167
0
  return (1);
28168
0
    }
28169
0
    vctxt->depth = -1;
28170
0
    vctxt->validationRoot = valRoot;
28171
0
    node = valRoot;
28172
0
    while (node != NULL) {
28173
0
  if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
28174
0
      goto next_sibling;
28175
0
  if (node->type == XML_ELEMENT_NODE) {
28176
28177
      /*
28178
      * Init the node-info.
28179
      */
28180
0
      vctxt->depth++;
28181
0
      if (xmlSchemaValidatorPushElem(vctxt) == -1)
28182
0
    goto internal_error;
28183
0
      ielem = vctxt->inode;
28184
0
      ielem->node = node;
28185
0
      ielem->nodeLine = node->line;
28186
0
      ielem->localName = node->name;
28187
0
      if (node->ns != NULL)
28188
0
    ielem->nsName = node->ns->href;
28189
0
      ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
28190
      /*
28191
      * Register attributes.
28192
      * DOC VAL TODO: We do not register namespace declaration
28193
      * attributes yet.
28194
      */
28195
0
      vctxt->nbAttrInfos = 0;
28196
0
      if (node->properties != NULL) {
28197
0
    attr = node->properties;
28198
0
    do {
28199
0
        if (attr->ns != NULL)
28200
0
      nsName = attr->ns->href;
28201
0
        else
28202
0
      nsName = NULL;
28203
0
        ret = xmlSchemaValidatorPushAttribute(vctxt,
28204
0
      (xmlNodePtr) attr,
28205
      /*
28206
      * Note that we give it the line number of the
28207
      * parent element.
28208
      */
28209
0
      ielem->nodeLine,
28210
0
      attr->name, nsName, 0,
28211
0
      xmlNodeListGetString(attr->doc, attr->children, 1), 1);
28212
0
        if (ret == -1) {
28213
0
      VERROR_INT("xmlSchemaDocWalk",
28214
0
          "calling xmlSchemaValidatorPushAttribute()");
28215
0
      goto internal_error;
28216
0
        }
28217
0
        attr = attr->next;
28218
0
    } while (attr);
28219
0
      }
28220
      /*
28221
      * Validate the element.
28222
      */
28223
0
      ret = xmlSchemaValidateElem(vctxt);
28224
0
      if (ret != 0) {
28225
0
    if (ret == -1) {
28226
0
        VERROR_INT("xmlSchemaDocWalk",
28227
0
      "calling xmlSchemaValidateElem()");
28228
0
        goto internal_error;
28229
0
    }
28230
    /*
28231
    * Don't stop validation; just skip the content
28232
    * of this element.
28233
    */
28234
0
    goto leave_node;
28235
0
      }
28236
0
      if ((vctxt->skipDepth != -1) &&
28237
0
    (vctxt->depth >= vctxt->skipDepth))
28238
0
    goto leave_node;
28239
0
  } else if ((node->type == XML_TEXT_NODE) ||
28240
0
      (node->type == XML_CDATA_SECTION_NODE)) {
28241
      /*
28242
      * Process character content.
28243
      */
28244
0
      if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
28245
0
    ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
28246
0
      ret = xmlSchemaVPushText(vctxt, node->type, node->content,
28247
0
    -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
28248
0
      if (ret < 0) {
28249
0
    VERROR_INT("xmlSchemaVDocWalk",
28250
0
        "calling xmlSchemaVPushText()");
28251
0
    goto internal_error;
28252
0
      }
28253
      /*
28254
      * DOC VAL TODO: Should we skip further validation of the
28255
      * element content here?
28256
      */
28257
0
  } else if ((node->type == XML_ENTITY_NODE) ||
28258
0
      (node->type == XML_ENTITY_REF_NODE)) {
28259
      /*
28260
      * DOC VAL TODO: What to do with entities?
28261
      */
28262
0
      VERROR_INT("xmlSchemaVDocWalk",
28263
0
    "there is at least one entity reference in the node-tree "
28264
0
    "currently being validated. Processing of entities with "
28265
0
    "this XML Schema processor is not supported (yet). Please "
28266
0
    "substitute entities before validation.");
28267
0
      goto internal_error;
28268
0
  } else {
28269
0
      goto leave_node;
28270
      /*
28271
      * DOC VAL TODO: XInclude nodes, etc.
28272
      */
28273
0
  }
28274
  /*
28275
  * Walk the doc.
28276
  */
28277
0
  if (node->children != NULL) {
28278
0
      node = node->children;
28279
0
      continue;
28280
0
  }
28281
0
leave_node:
28282
0
  if (node->type == XML_ELEMENT_NODE) {
28283
      /*
28284
      * Leaving the scope of an element.
28285
      */
28286
0
      if (node != vctxt->inode->node) {
28287
0
    VERROR_INT("xmlSchemaVDocWalk",
28288
0
        "element position mismatch");
28289
0
    goto internal_error;
28290
0
      }
28291
0
      ret = xmlSchemaValidatorPopElem(vctxt);
28292
0
      if (ret != 0) {
28293
0
    if (ret < 0) {
28294
0
        VERROR_INT("xmlSchemaVDocWalk",
28295
0
      "calling xmlSchemaValidatorPopElem()");
28296
0
        goto internal_error;
28297
0
    }
28298
0
      }
28299
0
      if (node == valRoot)
28300
0
    goto exit;
28301
0
  }
28302
0
next_sibling:
28303
0
  if (node->next != NULL)
28304
0
      node = node->next;
28305
0
  else {
28306
0
      node = node->parent;
28307
0
      goto leave_node;
28308
0
  }
28309
0
    }
28310
28311
0
exit:
28312
0
    return (ret);
28313
0
internal_error:
28314
0
    return (-1);
28315
0
}
28316
28317
static int
28318
0
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
28319
    /*
28320
    * Some initialization.
28321
    */
28322
0
    vctxt->err = 0;
28323
0
    vctxt->nberrors = 0;
28324
0
    vctxt->depth = -1;
28325
0
    vctxt->skipDepth = -1;
28326
0
    vctxt->hasKeyrefs = 0;
28327
#ifdef ENABLE_IDC_NODE_TABLES_TEST
28328
    vctxt->createIDCNodeTables = 1;
28329
#else
28330
0
    vctxt->createIDCNodeTables = 0;
28331
0
#endif
28332
    /*
28333
    * Create a schema + parser if necessary.
28334
    */
28335
0
    if (vctxt->schema == NULL) {
28336
0
  xmlSchemaParserCtxtPtr pctxt;
28337
28338
0
  vctxt->xsiAssemble = 1;
28339
  /*
28340
  * If not schema was given then we will create a schema
28341
  * dynamically using XSI schema locations.
28342
  *
28343
  * Create the schema parser context.
28344
  */
28345
0
  if ((vctxt->pctxt == NULL) &&
28346
0
     (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
28347
0
     return (-1);
28348
0
  pctxt = vctxt->pctxt;
28349
0
  pctxt->xsiAssemble = 1;
28350
  /*
28351
  * Create the schema.
28352
  */
28353
0
  vctxt->schema = xmlSchemaNewSchema(pctxt);
28354
0
  if (vctxt->schema == NULL)
28355
0
      return (-1);
28356
  /*
28357
  * Create the schema construction context.
28358
  */
28359
0
  pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
28360
0
  if (pctxt->constructor == NULL)
28361
0
      return(-1);
28362
0
  pctxt->constructor->mainSchema = vctxt->schema;
28363
  /*
28364
  * Take ownership of the constructor to be able to free it.
28365
  */
28366
0
  pctxt->ownsConstructor = 1;
28367
0
    }
28368
    /*
28369
    * Augment the IDC definitions for the main schema and all imported ones
28370
    * NOTE: main schema if the first in the imported list
28371
    */
28372
0
    xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
28373
0
                vctxt);
28374
28375
0
    return(0);
28376
0
}
28377
28378
static void
28379
0
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28380
0
    if (vctxt->xsiAssemble) {
28381
0
  if (vctxt->schema != NULL) {
28382
0
      xmlSchemaFree(vctxt->schema);
28383
0
      vctxt->schema = NULL;
28384
0
  }
28385
0
    }
28386
0
    xmlSchemaClearValidCtxt(vctxt);
28387
0
}
28388
28389
static int
28390
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28391
0
{
28392
0
    int ret = 0;
28393
28394
0
    if (xmlSchemaPreRun(vctxt) < 0)
28395
0
        return(-1);
28396
28397
0
    if (vctxt->doc != NULL) {
28398
  /*
28399
   * Tree validation.
28400
   */
28401
0
  ret = xmlSchemaVDocWalk(vctxt);
28402
0
#ifdef LIBXML_READER_ENABLED
28403
0
    } else if (vctxt->reader != NULL) {
28404
  /*
28405
   * XML Reader validation.
28406
   */
28407
#ifdef XML_SCHEMA_READER_ENABLED
28408
  ret = xmlSchemaVReaderWalk(vctxt);
28409
#endif
28410
0
#endif
28411
0
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28412
  /*
28413
   * SAX validation.
28414
   */
28415
0
  ret = xmlParseDocument(vctxt->parserCtxt);
28416
0
    } else {
28417
0
  VERROR_INT("xmlSchemaVStart",
28418
0
      "no instance to validate");
28419
0
  ret = -1;
28420
0
    }
28421
28422
0
    xmlSchemaPostRun(vctxt);
28423
0
    if (ret == 0)
28424
0
  ret = vctxt->err;
28425
0
    return (ret);
28426
0
}
28427
28428
/**
28429
 * xmlSchemaValidateOneElement:
28430
 * @ctxt:  a schema validation context
28431
 * @elem:  an element node
28432
 *
28433
 * Validate a branch of a tree, starting with the given @elem.
28434
 *
28435
 * Returns 0 if the element and its subtree is valid, a positive error
28436
 * code number otherwise and -1 in case of an internal or API error.
28437
 */
28438
int
28439
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28440
0
{
28441
0
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28442
0
  return (-1);
28443
28444
0
    if (ctxt->schema == NULL)
28445
0
  return (-1);
28446
28447
0
    ctxt->doc = elem->doc;
28448
0
    ctxt->node = elem;
28449
0
    ctxt->validationRoot = elem;
28450
0
    return(xmlSchemaVStart(ctxt));
28451
0
}
28452
28453
/**
28454
 * xmlSchemaValidateDoc:
28455
 * @ctxt:  a schema validation context
28456
 * @doc:  a parsed document tree
28457
 *
28458
 * Validate a document tree in memory.
28459
 *
28460
 * Returns 0 if the document is schemas valid, a positive error code
28461
 *     number otherwise and -1 in case of internal or API error.
28462
 */
28463
int
28464
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28465
0
{
28466
0
    if ((ctxt == NULL) || (doc == NULL))
28467
0
        return (-1);
28468
28469
0
    ctxt->doc = doc;
28470
0
    ctxt->node = xmlDocGetRootElement(doc);
28471
0
    if (ctxt->node == NULL) {
28472
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
28473
0
      XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28474
0
      (xmlNodePtr) doc, NULL,
28475
0
      "The document has no document element", NULL, NULL);
28476
0
        return (ctxt->err);
28477
0
    }
28478
0
    ctxt->validationRoot = ctxt->node;
28479
0
    return (xmlSchemaVStart(ctxt));
28480
0
}
28481
28482
28483
/************************************************************************
28484
 *                  *
28485
 *    Function and data for SAX streaming API     *
28486
 *                  *
28487
 ************************************************************************/
28488
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28489
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28490
28491
struct _xmlSchemaSplitSAXData {
28492
    xmlSAXHandlerPtr      user_sax;
28493
    void                 *user_data;
28494
    xmlSchemaValidCtxtPtr ctxt;
28495
    xmlSAXHandlerPtr      schemas_sax;
28496
};
28497
28498
0
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28499
28500
struct _xmlSchemaSAXPlug {
28501
    unsigned int magic;
28502
28503
    /* the original callbacks information */
28504
    xmlSAXHandlerPtr     *user_sax_ptr;
28505
    xmlSAXHandlerPtr      user_sax;
28506
    void                **user_data_ptr;
28507
    void                 *user_data;
28508
28509
    /* the block plugged back and validation information */
28510
    xmlSAXHandler         schemas_sax;
28511
    xmlSchemaValidCtxtPtr ctxt;
28512
};
28513
28514
/* All those functions just bounces to the user provided SAX handlers */
28515
static void
28516
internalSubsetSplit(void *ctx, const xmlChar *name,
28517
         const xmlChar *ExternalID, const xmlChar *SystemID)
28518
0
{
28519
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28520
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28521
0
        (ctxt->user_sax->internalSubset != NULL))
28522
0
  ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28523
0
                                 SystemID);
28524
0
}
28525
28526
static int
28527
isStandaloneSplit(void *ctx)
28528
0
{
28529
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28530
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28531
0
        (ctxt->user_sax->isStandalone != NULL))
28532
0
  return(ctxt->user_sax->isStandalone(ctxt->user_data));
28533
0
    return(0);
28534
0
}
28535
28536
static int
28537
hasInternalSubsetSplit(void *ctx)
28538
0
{
28539
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28540
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28541
0
        (ctxt->user_sax->hasInternalSubset != NULL))
28542
0
  return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28543
0
    return(0);
28544
0
}
28545
28546
static int
28547
hasExternalSubsetSplit(void *ctx)
28548
0
{
28549
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28550
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28551
0
        (ctxt->user_sax->hasExternalSubset != NULL))
28552
0
  return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28553
0
    return(0);
28554
0
}
28555
28556
static void
28557
externalSubsetSplit(void *ctx, const xmlChar *name,
28558
         const xmlChar *ExternalID, const xmlChar *SystemID)
28559
0
{
28560
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28561
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28562
0
        (ctxt->user_sax->externalSubset != NULL))
28563
0
  ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28564
0
                                 SystemID);
28565
0
}
28566
28567
static xmlParserInputPtr
28568
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28569
0
{
28570
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28571
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28572
0
        (ctxt->user_sax->resolveEntity != NULL))
28573
0
  return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28574
0
                                       systemId));
28575
0
    return(NULL);
28576
0
}
28577
28578
static xmlEntityPtr
28579
getEntitySplit(void *ctx, const xmlChar *name)
28580
0
{
28581
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28582
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28583
0
        (ctxt->user_sax->getEntity != NULL))
28584
0
  return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28585
0
    return(NULL);
28586
0
}
28587
28588
static xmlEntityPtr
28589
getParameterEntitySplit(void *ctx, const xmlChar *name)
28590
0
{
28591
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28592
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28593
0
        (ctxt->user_sax->getParameterEntity != NULL))
28594
0
  return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28595
0
    return(NULL);
28596
0
}
28597
28598
28599
static void
28600
entityDeclSplit(void *ctx, const xmlChar *name, int type,
28601
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28602
0
{
28603
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28604
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28605
0
        (ctxt->user_sax->entityDecl != NULL))
28606
0
  ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28607
0
                             systemId, content);
28608
0
}
28609
28610
static void
28611
attributeDeclSplit(void *ctx, const xmlChar * elem,
28612
                   const xmlChar * name, int type, int def,
28613
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
28614
0
{
28615
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28616
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28617
0
        (ctxt->user_sax->attributeDecl != NULL)) {
28618
0
  ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28619
0
                                def, defaultValue, tree);
28620
0
    } else {
28621
0
  xmlFreeEnumeration(tree);
28622
0
    }
28623
0
}
28624
28625
static void
28626
elementDeclSplit(void *ctx, const xmlChar *name, int type,
28627
      xmlElementContentPtr content)
28628
0
{
28629
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28630
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28631
0
        (ctxt->user_sax->elementDecl != NULL))
28632
0
  ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28633
0
}
28634
28635
static void
28636
notationDeclSplit(void *ctx, const xmlChar *name,
28637
       const xmlChar *publicId, const xmlChar *systemId)
28638
0
{
28639
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28640
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28641
0
        (ctxt->user_sax->notationDecl != NULL))
28642
0
  ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28643
0
                               systemId);
28644
0
}
28645
28646
static void
28647
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28648
       const xmlChar *publicId, const xmlChar *systemId,
28649
       const xmlChar *notationName)
28650
0
{
28651
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28652
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28653
0
        (ctxt->user_sax->unparsedEntityDecl != NULL))
28654
0
  ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28655
0
                                     systemId, notationName);
28656
0
}
28657
28658
static void
28659
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28660
0
{
28661
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28662
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28663
0
        (ctxt->user_sax->setDocumentLocator != NULL))
28664
0
  ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28665
0
}
28666
28667
static void
28668
startDocumentSplit(void *ctx)
28669
0
{
28670
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28671
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28672
0
        (ctxt->user_sax->startDocument != NULL))
28673
0
  ctxt->user_sax->startDocument(ctxt->user_data);
28674
0
}
28675
28676
static void
28677
endDocumentSplit(void *ctx)
28678
0
{
28679
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28680
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28681
0
        (ctxt->user_sax->endDocument != NULL))
28682
0
  ctxt->user_sax->endDocument(ctxt->user_data);
28683
0
}
28684
28685
static void
28686
processingInstructionSplit(void *ctx, const xmlChar *target,
28687
                      const xmlChar *data)
28688
0
{
28689
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28690
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28691
0
        (ctxt->user_sax->processingInstruction != NULL))
28692
0
  ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28693
0
}
28694
28695
static void
28696
commentSplit(void *ctx, const xmlChar *value)
28697
0
{
28698
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28699
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28700
0
        (ctxt->user_sax->comment != NULL))
28701
0
  ctxt->user_sax->comment(ctxt->user_data, value);
28702
0
}
28703
28704
/*
28705
 * Varargs error callbacks to the user application, harder ...
28706
 */
28707
28708
static void
28709
0
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28710
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28711
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28712
0
        (ctxt->user_sax->warning != NULL)) {
28713
0
  TODO
28714
0
    }
28715
0
}
28716
static void
28717
0
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28718
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28719
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28720
0
        (ctxt->user_sax->error != NULL)) {
28721
0
  TODO
28722
0
    }
28723
0
}
28724
static void
28725
0
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28726
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28727
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28728
0
        (ctxt->user_sax->fatalError != NULL)) {
28729
0
  TODO
28730
0
    }
28731
0
}
28732
28733
/*
28734
 * Those are function where both the user handler and the schemas handler
28735
 * need to be called.
28736
 */
28737
static void
28738
charactersSplit(void *ctx, const xmlChar *ch, int len)
28739
0
{
28740
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28741
0
    if (ctxt == NULL)
28742
0
        return;
28743
0
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28744
0
  ctxt->user_sax->characters(ctxt->user_data, ch, len);
28745
0
    if (ctxt->ctxt != NULL)
28746
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28747
0
}
28748
28749
static void
28750
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28751
0
{
28752
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28753
0
    if (ctxt == NULL)
28754
0
        return;
28755
0
    if ((ctxt->user_sax != NULL) &&
28756
0
        (ctxt->user_sax->ignorableWhitespace != NULL))
28757
0
  ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28758
0
    if (ctxt->ctxt != NULL)
28759
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28760
0
}
28761
28762
static void
28763
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28764
0
{
28765
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28766
0
    if (ctxt == NULL)
28767
0
        return;
28768
0
    if ((ctxt->user_sax != NULL) &&
28769
0
        (ctxt->user_sax->cdataBlock != NULL))
28770
0
  ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28771
0
    if (ctxt->ctxt != NULL)
28772
0
  xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28773
0
}
28774
28775
static void
28776
referenceSplit(void *ctx, const xmlChar *name)
28777
0
{
28778
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28779
0
    if (ctxt == NULL)
28780
0
        return;
28781
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28782
0
        (ctxt->user_sax->reference != NULL))
28783
0
  ctxt->user_sax->reference(ctxt->user_data, name);
28784
0
    if (ctxt->ctxt != NULL)
28785
0
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
28786
0
}
28787
28788
static void
28789
startElementNsSplit(void *ctx, const xmlChar * localname,
28790
        const xmlChar * prefix, const xmlChar * URI,
28791
        int nb_namespaces, const xmlChar ** namespaces,
28792
        int nb_attributes, int nb_defaulted,
28793
0
        const xmlChar ** attributes) {
28794
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28795
0
    if (ctxt == NULL)
28796
0
        return;
28797
0
    if ((ctxt->user_sax != NULL) &&
28798
0
        (ctxt->user_sax->startElementNs != NULL))
28799
0
  ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28800
0
                                 URI, nb_namespaces, namespaces,
28801
0
               nb_attributes, nb_defaulted,
28802
0
               attributes);
28803
0
    if (ctxt->ctxt != NULL)
28804
0
  xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28805
0
                                   URI, nb_namespaces, namespaces,
28806
0
           nb_attributes, nb_defaulted,
28807
0
           attributes);
28808
0
}
28809
28810
static void
28811
endElementNsSplit(void *ctx, const xmlChar * localname,
28812
0
        const xmlChar * prefix, const xmlChar * URI) {
28813
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28814
0
    if (ctxt == NULL)
28815
0
        return;
28816
0
    if ((ctxt->user_sax != NULL) &&
28817
0
        (ctxt->user_sax->endElementNs != NULL))
28818
0
  ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28819
0
    if (ctxt->ctxt != NULL)
28820
0
  xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28821
0
}
28822
28823
/**
28824
 * xmlSchemaSAXPlug:
28825
 * @ctxt:  a schema validation context
28826
 * @sax:  a pointer to the original xmlSAXHandlerPtr
28827
 * @user_data:  a pointer to the original SAX user data pointer
28828
 *
28829
 * Plug a SAX based validation layer in a SAX parsing event flow.
28830
 * The original @saxptr and @dataptr data are replaced by new pointers
28831
 * but the calls to the original will be maintained.
28832
 *
28833
 * Returns a pointer to a data structure needed to unplug the validation layer
28834
 *         or NULL in case of errors.
28835
 */
28836
xmlSchemaSAXPlugPtr
28837
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28838
     xmlSAXHandlerPtr *sax, void **user_data)
28839
0
{
28840
0
    xmlSchemaSAXPlugPtr ret;
28841
0
    xmlSAXHandlerPtr old_sax;
28842
28843
0
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28844
0
        return(NULL);
28845
28846
    /*
28847
     * We only allow to plug into SAX2 event streams
28848
     */
28849
0
    old_sax = *sax;
28850
0
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28851
0
        return(NULL);
28852
0
    if ((old_sax != NULL) &&
28853
0
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28854
0
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28855
0
        return(NULL);
28856
28857
    /*
28858
     * everything seems right allocate the local data needed for that layer
28859
     */
28860
0
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28861
0
    if (ret == NULL) {
28862
0
        return(NULL);
28863
0
    }
28864
0
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28865
0
    ret->magic = XML_SAX_PLUG_MAGIC;
28866
0
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28867
0
    ret->ctxt = ctxt;
28868
0
    ret->user_sax_ptr = sax;
28869
0
    ret->user_sax = old_sax;
28870
0
    if (old_sax == NULL) {
28871
        /*
28872
   * go direct, no need for the split block and functions.
28873
   */
28874
0
  ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28875
0
  ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28876
  /*
28877
   * Note that we use the same text-function for both, to prevent
28878
   * the parser from testing for ignorable whitespace.
28879
   */
28880
0
  ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28881
0
  ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28882
28883
0
  ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28884
0
  ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28885
28886
0
  ret->user_data = ctxt;
28887
0
  *user_data = ctxt;
28888
0
    } else {
28889
       /*
28890
        * for each callback unused by Schemas initialize it to the Split
28891
  * routine only if non NULL in the user block, this can speed up
28892
  * things at the SAX level.
28893
  */
28894
0
        if (old_sax->internalSubset != NULL)
28895
0
            ret->schemas_sax.internalSubset = internalSubsetSplit;
28896
0
        if (old_sax->isStandalone != NULL)
28897
0
            ret->schemas_sax.isStandalone = isStandaloneSplit;
28898
0
        if (old_sax->hasInternalSubset != NULL)
28899
0
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28900
0
        if (old_sax->hasExternalSubset != NULL)
28901
0
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28902
0
        if (old_sax->resolveEntity != NULL)
28903
0
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
28904
0
        if (old_sax->getEntity != NULL)
28905
0
            ret->schemas_sax.getEntity = getEntitySplit;
28906
0
        if (old_sax->entityDecl != NULL)
28907
0
            ret->schemas_sax.entityDecl = entityDeclSplit;
28908
0
        if (old_sax->notationDecl != NULL)
28909
0
            ret->schemas_sax.notationDecl = notationDeclSplit;
28910
0
        if (old_sax->attributeDecl != NULL)
28911
0
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
28912
0
        if (old_sax->elementDecl != NULL)
28913
0
            ret->schemas_sax.elementDecl = elementDeclSplit;
28914
0
        if (old_sax->unparsedEntityDecl != NULL)
28915
0
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28916
0
        if (old_sax->setDocumentLocator != NULL)
28917
0
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28918
0
        if (old_sax->startDocument != NULL)
28919
0
            ret->schemas_sax.startDocument = startDocumentSplit;
28920
0
        if (old_sax->endDocument != NULL)
28921
0
            ret->schemas_sax.endDocument = endDocumentSplit;
28922
0
        if (old_sax->processingInstruction != NULL)
28923
0
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
28924
0
        if (old_sax->comment != NULL)
28925
0
            ret->schemas_sax.comment = commentSplit;
28926
0
        if (old_sax->warning != NULL)
28927
0
            ret->schemas_sax.warning = warningSplit;
28928
0
        if (old_sax->error != NULL)
28929
0
            ret->schemas_sax.error = errorSplit;
28930
0
        if (old_sax->fatalError != NULL)
28931
0
            ret->schemas_sax.fatalError = fatalErrorSplit;
28932
0
        if (old_sax->getParameterEntity != NULL)
28933
0
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28934
0
        if (old_sax->externalSubset != NULL)
28935
0
            ret->schemas_sax.externalSubset = externalSubsetSplit;
28936
28937
  /*
28938
   * the 6 schemas callback have to go to the splitter functions
28939
   * Note that we use the same text-function for ignorableWhitespace
28940
   * if possible, to prevent the parser from testing for ignorable
28941
   * whitespace.
28942
   */
28943
0
        ret->schemas_sax.characters = charactersSplit;
28944
0
  if ((old_sax->ignorableWhitespace != NULL) &&
28945
0
      (old_sax->ignorableWhitespace != old_sax->characters))
28946
0
      ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28947
0
  else
28948
0
      ret->schemas_sax.ignorableWhitespace = charactersSplit;
28949
0
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
28950
0
        ret->schemas_sax.reference = referenceSplit;
28951
0
        ret->schemas_sax.startElementNs = startElementNsSplit;
28952
0
        ret->schemas_sax.endElementNs = endElementNsSplit;
28953
28954
0
  ret->user_data_ptr = user_data;
28955
0
  ret->user_data = *user_data;
28956
0
  *user_data = ret;
28957
0
    }
28958
28959
    /*
28960
     * plug the pointers back.
28961
     */
28962
0
    *sax = &(ret->schemas_sax);
28963
0
    ctxt->sax = *sax;
28964
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28965
0
    xmlSchemaPreRun(ctxt);
28966
0
    return(ret);
28967
0
}
28968
28969
/**
28970
 * xmlSchemaSAXUnplug:
28971
 * @plug:  a data structure returned by xmlSchemaSAXPlug
28972
 *
28973
 * Unplug a SAX based validation layer in a SAX parsing event flow.
28974
 * The original pointers used in the call are restored.
28975
 *
28976
 * Returns 0 in case of success and -1 in case of failure.
28977
 */
28978
int
28979
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28980
0
{
28981
0
    xmlSAXHandlerPtr *sax;
28982
0
    void **user_data;
28983
28984
0
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28985
0
        return(-1);
28986
0
    plug->magic = 0;
28987
28988
0
    xmlSchemaPostRun(plug->ctxt);
28989
    /* restore the data */
28990
0
    sax = plug->user_sax_ptr;
28991
0
    *sax = plug->user_sax;
28992
0
    if (plug->user_sax != NULL) {
28993
0
  user_data = plug->user_data_ptr;
28994
0
  *user_data = plug->user_data;
28995
0
    }
28996
28997
    /* free and return */
28998
0
    xmlFree(plug);
28999
0
    return(0);
29000
0
}
29001
29002
/**
29003
 * xmlSchemaValidateSetLocator:
29004
 * @vctxt: a schema validation context
29005
 * @f: the locator function pointer
29006
 * @ctxt: the locator context
29007
 *
29008
 * Allows to set a locator function to the validation context,
29009
 * which will be used to provide file and line information since
29010
 * those are not provided as part of the SAX validation flow
29011
 * Setting @f to NULL disable the locator.
29012
 */
29013
29014
void
29015
xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
29016
                            xmlSchemaValidityLocatorFunc f,
29017
          void *ctxt)
29018
0
{
29019
0
    if (vctxt == NULL) return;
29020
0
    vctxt->locFunc = f;
29021
0
    vctxt->locCtxt = ctxt;
29022
0
}
29023
29024
/**
29025
 * xmlSchemaValidateStreamLocator:
29026
 * @ctx: the xmlTextReaderPtr used
29027
 * @file: returned file information
29028
 * @line: returned line information
29029
 *
29030
 * Internal locator function for the readers
29031
 *
29032
 * Returns 0 in case the Schema validation could be (de)activated and
29033
 *         -1 in case of error.
29034
 */
29035
static int
29036
xmlSchemaValidateStreamLocator(void *ctx, const char **file,
29037
0
                               unsigned long *line) {
29038
0
    xmlParserCtxtPtr ctxt;
29039
29040
0
    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
29041
0
        return(-1);
29042
29043
0
    if (file != NULL)
29044
0
        *file = NULL;
29045
0
    if (line != NULL)
29046
0
        *line = 0;
29047
29048
0
    ctxt = (xmlParserCtxtPtr) ctx;
29049
0
    if (ctxt->input != NULL) {
29050
0
       if (file != NULL)
29051
0
           *file = ctxt->input->filename;
29052
0
       if (line != NULL)
29053
0
           *line = ctxt->input->line;
29054
0
       return(0);
29055
0
    }
29056
0
    return(-1);
29057
0
}
29058
29059
/**
29060
 * xmlSchemaValidateStream:
29061
 * @ctxt:  a schema validation context
29062
 * @input:  the input to use for reading the data
29063
 * @enc:  an optional encoding information
29064
 * @sax:  a SAX handler for the resulting events
29065
 * @user_data:  the context to provide to the SAX handler.
29066
 *
29067
 * Validate an input based on a flow of SAX event from the parser
29068
 * and forward the events to the @sax handler with the provided @user_data
29069
 * the user provided @sax handler must be a SAX2 one.
29070
 *
29071
 * Returns 0 if the document is schemas valid, a positive error code
29072
 *     number otherwise and -1 in case of internal or API error.
29073
 */
29074
int
29075
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
29076
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
29077
                        xmlSAXHandlerPtr sax, void *user_data)
29078
0
{
29079
0
    xmlSchemaSAXPlugPtr plug = NULL;
29080
0
    xmlParserCtxtPtr pctxt = NULL;
29081
0
    xmlParserInputPtr inputStream = NULL;
29082
0
    int ret;
29083
29084
0
    if ((ctxt == NULL) || (input == NULL))
29085
0
        return (-1);
29086
29087
    /*
29088
     * prepare the parser
29089
     */
29090
0
    pctxt = xmlNewSAXParserCtxt(sax, user_data);
29091
0
    if (pctxt == NULL)
29092
0
        return (-1);
29093
#if 0
29094
    if (options)
29095
        xmlCtxtUseOptions(pctxt, options);
29096
#endif
29097
0
    pctxt->linenumbers = 1;
29098
0
    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
29099
29100
0
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
29101
0
    if (inputStream == NULL) {
29102
0
        ret = -1;
29103
0
  goto done;
29104
0
    }
29105
0
    inputPush(pctxt, inputStream);
29106
0
    ctxt->parserCtxt = pctxt;
29107
0
    ctxt->input = input;
29108
29109
    /*
29110
     * Plug the validation and launch the parsing
29111
     */
29112
0
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
29113
0
    if (plug == NULL) {
29114
0
        ret = -1;
29115
0
  goto done;
29116
0
    }
29117
0
    ctxt->input = input;
29118
0
    ctxt->enc = enc;
29119
0
    ctxt->sax = pctxt->sax;
29120
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
29121
0
    ret = xmlSchemaVStart(ctxt);
29122
29123
0
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
29124
0
  ret = ctxt->parserCtxt->errNo;
29125
0
  if (ret == 0)
29126
0
      ret = 1;
29127
0
    }
29128
29129
0
done:
29130
0
    ctxt->parserCtxt = NULL;
29131
0
    ctxt->sax = NULL;
29132
0
    ctxt->input = NULL;
29133
0
    if (plug != NULL) {
29134
0
        xmlSchemaSAXUnplug(plug);
29135
0
    }
29136
    /* cleanup */
29137
0
    if (pctxt != NULL) {
29138
0
  xmlFreeParserCtxt(pctxt);
29139
0
    }
29140
0
    return (ret);
29141
0
}
29142
29143
/**
29144
 * xmlSchemaValidateFile:
29145
 * @ctxt: a schema validation context
29146
 * @filename: the URI of the instance
29147
 * @options: a future set of options, currently unused
29148
 *
29149
 * Do a schemas validation of the given resource, it will use the
29150
 * SAX streamable validation internally.
29151
 *
29152
 * Returns 0 if the document is valid, a positive error code
29153
 *     number otherwise and -1 in case of an internal or API error.
29154
 */
29155
int
29156
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
29157
                      const char * filename,
29158
          int options ATTRIBUTE_UNUSED)
29159
0
{
29160
0
    int ret;
29161
0
    xmlParserInputBufferPtr input;
29162
29163
0
    if ((ctxt == NULL) || (filename == NULL))
29164
0
        return (-1);
29165
29166
0
    input = xmlParserInputBufferCreateFilename(filename,
29167
0
  XML_CHAR_ENCODING_NONE);
29168
0
    if (input == NULL)
29169
0
  return (-1);
29170
0
    ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
29171
0
  NULL, NULL);
29172
0
    return (ret);
29173
0
}
29174
29175
/**
29176
 * xmlSchemaValidCtxtGetParserCtxt:
29177
 * @ctxt: a schema validation context
29178
 *
29179
 * allow access to the parser context of the schema validation context
29180
 *
29181
 * Returns the parser context of the schema validation context or NULL
29182
 *         in case of error.
29183
 */
29184
xmlParserCtxtPtr
29185
xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
29186
0
{
29187
0
    if (ctxt == NULL)
29188
0
        return(NULL);
29189
0
    return (ctxt->parserCtxt);
29190
0
}
29191
29192
#endif /* LIBXML_SCHEMAS_ENABLED */