Coverage Report

Created: 2023-06-07 06:05

/src/libxml2-2.10.3/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
/* #define DEBUG 1 */
80
81
/* #define DEBUG_CONTENT 1 */
82
83
/* #define DEBUG_TYPE 1 */
84
85
/* #define DEBUG_CONTENT_REGEXP 1 */
86
87
/* #define DEBUG_AUTOMATA 1 */
88
89
/* #define DEBUG_IDC */
90
91
/* #define DEBUG_IDC_NODE_TABLE */
92
93
/* #define WXS_ELEM_DECL_CONS_ENABLED */
94
95
#ifdef DEBUG_IDC
96
 #ifndef DEBUG_IDC_NODE_TABLE
97
  #define DEBUG_IDC_NODE_TABLE
98
 #endif
99
#endif
100
101
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
102
103
#define ENABLE_REDEFINE
104
105
/* #define ENABLE_NAMED_LOCALS */
106
107
/* #define ENABLE_IDC_NODE_TABLES_TEST */
108
109
#define DUMP_CONTENT_MODEL
110
111
#ifdef LIBXML_READER_ENABLED
112
/* #define XML_SCHEMA_READER_ENABLED */
113
#endif
114
115
0
#define UNBOUNDED (1 << 30)
116
#define TODO                \
117
0
    xmlGenericError(xmlGenericErrorContext,       \
118
0
      "Unimplemented block at %s:%d\n",       \
119
0
            __FILE__, __LINE__);
120
121
0
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
122
123
/*
124
 * The XML Schemas namespaces
125
 */
126
static const xmlChar *xmlSchemaNs = (const xmlChar *)
127
    "http://www.w3.org/2001/XMLSchema";
128
129
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
130
    "http://www.w3.org/2001/XMLSchema-instance";
131
132
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
133
    "http://www.w3.org/2000/xmlns/";
134
135
/*
136
* Come casting macros.
137
*/
138
0
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
139
0
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
140
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
141
0
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
142
0
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
143
0
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
144
0
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
145
0
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
146
0
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
147
0
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
148
0
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
149
0
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
150
0
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
151
0
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
152
0
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
153
0
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
154
0
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
155
156
/*
157
* Macros to query common properties of components.
158
*/
159
0
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
160
161
0
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
162
/*
163
* Macros for element declarations.
164
*/
165
0
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
166
167
0
#define WXS_SUBST_HEAD(item) (item)->refDecl
168
/*
169
* Macros for attribute declarations.
170
*/
171
0
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
172
/*
173
* Macros for attribute uses.
174
*/
175
0
#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
176
177
0
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
178
179
0
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
180
181
0
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
182
/*
183
* Macros for attribute groups.
184
*/
185
0
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
186
0
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
187
/*
188
* Macros for particles.
189
*/
190
0
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
191
192
0
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
193
194
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
195
196
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
197
/*
198
* Macros for model groups definitions.
199
*/
200
0
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
201
/*
202
* Macros for model groups.
203
*/
204
#define WXS_IS_MODEL_GROUP(i) \
205
0
    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
206
0
     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
207
0
     ((i)->type == XML_SCHEMA_TYPE_ALL))
208
209
0
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
210
/*
211
* Macros for schema buckets.
212
*/
213
0
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
214
0
    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
215
216
0
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
217
0
    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
218
219
0
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
220
221
0
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
222
/*
223
* Macros for complex/simple types.
224
*/
225
#define WXS_IS_ANYTYPE(i) \
226
0
     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
227
0
      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
228
229
#define WXS_IS_COMPLEX(i) \
230
0
    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
231
0
     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
232
233
#define WXS_IS_SIMPLE(item) \
234
0
    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
235
0
     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
236
0
      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
237
238
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
239
0
    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
240
0
      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
241
242
#define WXS_IS_RESTRICTION(t) \
243
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
244
245
#define WXS_IS_EXTENSION(t) \
246
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
247
248
#define WXS_IS_TYPE_NOT_FIXED(i) \
249
0
    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
250
0
     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
251
252
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
253
0
    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
254
0
     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
255
256
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
257
258
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
259
/*
260
* Macros for exclusively for complex types.
261
*/
262
#define WXS_HAS_COMPLEX_CONTENT(item) \
263
    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
264
     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
265
     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
266
267
#define WXS_HAS_SIMPLE_CONTENT(item) \
268
0
    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
269
0
     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
270
271
#define WXS_HAS_MIXED_CONTENT(item) \
272
0
    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
273
274
#define WXS_EMPTIABLE(t) \
275
0
    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
276
277
0
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
278
279
0
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
280
281
0
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
282
/*
283
* Macros for exclusively for simple types.
284
*/
285
0
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
286
287
0
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
288
289
0
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
290
291
0
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
292
/*
293
* Misc parser context macros.
294
*/
295
0
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
296
297
0
#define WXS_HAS_BUCKETS(ctx) \
298
0
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
299
0
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
300
301
0
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
302
303
0
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
304
305
#define WXS_SCHEMA(ctx) (ctx)->schema
306
307
#define WXS_ADD_LOCAL(ctx, item) \
308
0
    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
309
310
#define WXS_ADD_GLOBAL(ctx, item) \
311
0
    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
312
313
#define WXS_ADD_PENDING(ctx, item) \
314
0
    xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
315
/*
316
* xmlSchemaItemList macros.
317
*/
318
0
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
319
/*
320
* Misc macros.
321
*/
322
#define IS_SCHEMA(node, type) \
323
0
   ((node != NULL) && (node->ns != NULL) && \
324
0
    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
325
0
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
326
327
0
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
328
329
/*
330
* Since we put the default/fixed values into the dict, we can
331
* use pointer comparison for those values.
332
* REMOVED: (xmlStrEqual((v1), (v2)))
333
*/
334
0
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
335
336
0
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
337
338
0
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
339
340
0
#define HFAILURE if (res == -1) goto exit_failure;
341
342
0
#define HERROR if (res != 0) goto exit_error;
343
344
0
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
345
/*
346
* Some flags used for various schema constraints.
347
*/
348
0
#define SUBSET_RESTRICTION  1<<0
349
0
#define SUBSET_EXTENSION    1<<1
350
#define SUBSET_SUBSTITUTION 1<<2
351
#define SUBSET_LIST         1<<3
352
#define SUBSET_UNION        1<<4
353
354
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
355
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
356
357
typedef struct _xmlSchemaItemList xmlSchemaItemList;
358
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
359
struct _xmlSchemaItemList {
360
    void **items;  /* used for dynamic addition of schemata */
361
    int nbItems; /* used for dynamic addition of schemata */
362
    int sizeItems; /* used for dynamic addition of schemata */
363
};
364
365
0
#define XML_SCHEMA_CTXT_PARSER 1
366
0
#define XML_SCHEMA_CTXT_VALIDATOR 2
367
368
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
369
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
370
struct _xmlSchemaAbstractCtxt {
371
    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
372
    void *dummy; /* Fix alignment issues */
373
};
374
375
typedef struct _xmlSchemaBucket xmlSchemaBucket;
376
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
377
378
0
#define XML_SCHEMA_SCHEMA_MAIN 0
379
0
#define XML_SCHEMA_SCHEMA_IMPORT 1
380
0
#define XML_SCHEMA_SCHEMA_INCLUDE 2
381
0
#define XML_SCHEMA_SCHEMA_REDEFINE 3
382
383
/**
384
 * xmlSchemaSchemaRelation:
385
 *
386
 * Used to create a graph of schema relationships.
387
 */
388
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
389
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
390
struct _xmlSchemaSchemaRelation {
391
    xmlSchemaSchemaRelationPtr next;
392
    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
393
    const xmlChar *importNamespace;
394
    xmlSchemaBucketPtr bucket;
395
};
396
397
0
#define XML_SCHEMA_BUCKET_MARKED 1<<0
398
0
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
399
400
struct _xmlSchemaBucket {
401
    int type;
402
    int flags;
403
    const xmlChar *schemaLocation;
404
    const xmlChar *origTargetNamespace;
405
    const xmlChar *targetNamespace;
406
    xmlDocPtr doc;
407
    xmlSchemaSchemaRelationPtr relations;
408
    int located;
409
    int parsed;
410
    int imported;
411
    int preserveDoc;
412
    xmlSchemaItemListPtr globals; /* Global components. */
413
    xmlSchemaItemListPtr locals; /* Local components. */
414
};
415
416
/**
417
 * xmlSchemaImport:
418
 * (extends xmlSchemaBucket)
419
 *
420
 * Reflects a schema. Holds some information
421
 * about the schema and its toplevel components. Duplicate
422
 * toplevel components are not checked at this level.
423
 */
424
typedef struct _xmlSchemaImport xmlSchemaImport;
425
typedef xmlSchemaImport *xmlSchemaImportPtr;
426
struct _xmlSchemaImport {
427
    int type; /* Main OR import OR include. */
428
    int flags;
429
    const xmlChar *schemaLocation; /* The URI of the schema document. */
430
    /* For chameleon includes, @origTargetNamespace will be NULL */
431
    const xmlChar *origTargetNamespace;
432
    /*
433
    * For chameleon includes, @targetNamespace will be the
434
    * targetNamespace of the including schema.
435
    */
436
    const xmlChar *targetNamespace;
437
    xmlDocPtr doc; /* The schema node-tree. */
438
    /* @relations will hold any included/imported/redefined schemas. */
439
    xmlSchemaSchemaRelationPtr relations;
440
    int located;
441
    int parsed;
442
    int imported;
443
    int preserveDoc;
444
    xmlSchemaItemListPtr globals;
445
    xmlSchemaItemListPtr locals;
446
    /* The imported schema. */
447
    xmlSchemaPtr schema;
448
};
449
450
/*
451
* (extends xmlSchemaBucket)
452
*/
453
typedef struct _xmlSchemaInclude xmlSchemaInclude;
454
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
455
struct _xmlSchemaInclude {
456
    int type;
457
    int flags;
458
    const xmlChar *schemaLocation;
459
    const xmlChar *origTargetNamespace;
460
    const xmlChar *targetNamespace;
461
    xmlDocPtr doc;
462
    xmlSchemaSchemaRelationPtr relations;
463
    int located;
464
    int parsed;
465
    int imported;
466
    int preserveDoc;
467
    xmlSchemaItemListPtr globals; /* Global components. */
468
    xmlSchemaItemListPtr locals; /* Local components. */
469
470
    /* The owning main or import schema bucket. */
471
    xmlSchemaImportPtr ownerImport;
472
};
473
474
/**
475
 * xmlSchemaBasicItem:
476
 *
477
 * The abstract base type for schema components.
478
 */
479
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
480
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
481
struct _xmlSchemaBasicItem {
482
    xmlSchemaTypeType type;
483
    void *dummy; /* Fix alignment issues */
484
};
485
486
/**
487
 * xmlSchemaAnnotItem:
488
 *
489
 * The abstract base type for annotated schema components.
490
 * (Extends xmlSchemaBasicItem)
491
 */
492
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
493
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
494
struct _xmlSchemaAnnotItem {
495
    xmlSchemaTypeType type;
496
    xmlSchemaAnnotPtr annot;
497
};
498
499
/**
500
 * xmlSchemaTreeItem:
501
 *
502
 * The abstract base type for tree-like structured schema components.
503
 * (Extends xmlSchemaAnnotItem)
504
 */
505
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
506
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
507
struct _xmlSchemaTreeItem {
508
    xmlSchemaTypeType type;
509
    xmlSchemaAnnotPtr annot;
510
    xmlSchemaTreeItemPtr next;
511
    xmlSchemaTreeItemPtr children;
512
};
513
514
515
0
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
516
/**
517
 * xmlSchemaAttributeUsePtr:
518
 *
519
 * The abstract base type for tree-like structured schema components.
520
 * (Extends xmlSchemaTreeItem)
521
 */
522
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
523
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
524
struct _xmlSchemaAttributeUse {
525
    xmlSchemaTypeType type;
526
    xmlSchemaAnnotPtr annot;
527
    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
528
    /*
529
    * The attr. decl. OR a QName-ref. to an attr. decl. OR
530
    * a QName-ref. to an attribute group definition.
531
    */
532
    xmlSchemaAttributePtr attrDecl;
533
534
    int flags;
535
    xmlNodePtr node;
536
    int occurs; /* required, optional */
537
    const xmlChar * defValue;
538
    xmlSchemaValPtr defVal;
539
};
540
541
/**
542
 * xmlSchemaAttributeUseProhibPtr:
543
 *
544
 * A helper component to reflect attribute prohibitions.
545
 * (Extends xmlSchemaBasicItem)
546
 */
547
typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
548
typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
549
struct _xmlSchemaAttributeUseProhib {
550
    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
551
    xmlNodePtr node;
552
    const xmlChar *name;
553
    const xmlChar *targetNamespace;
554
    int isRef;
555
};
556
557
/**
558
 * xmlSchemaRedef:
559
 */
560
typedef struct _xmlSchemaRedef xmlSchemaRedef;
561
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
562
struct _xmlSchemaRedef {
563
    xmlSchemaRedefPtr next;
564
    xmlSchemaBasicItemPtr item; /* The redefining component. */
565
    xmlSchemaBasicItemPtr reference; /* The referencing component. */
566
    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
567
    const xmlChar *refName; /* The name of the to-be-redefined component. */
568
    const xmlChar *refTargetNs; /* The target namespace of the
569
                                   to-be-redefined comp. */
570
    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
571
};
572
573
/**
574
 * xmlSchemaConstructionCtxt:
575
 */
576
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
577
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
578
struct _xmlSchemaConstructionCtxt {
579
    xmlSchemaPtr mainSchema; /* The main schema. */
580
    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
581
    xmlDictPtr dict;
582
    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
583
    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
584
    xmlSchemaBucketPtr bucket; /* The current schema bucket */
585
    xmlSchemaItemListPtr pending; /* All Components of all schemas that
586
                                     need to be fixed. */
587
    xmlHashTablePtr substGroups;
588
    xmlSchemaRedefPtr redefs;
589
    xmlSchemaRedefPtr lastRedef;
590
};
591
592
#define XML_SCHEMAS_PARSE_ERROR   1
593
0
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
594
595
struct _xmlSchemaParserCtxt {
596
    int type;
597
    void *errCtxt;             /* user specific error context */
598
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
599
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
600
    int err;
601
    int nberrors;
602
    xmlStructuredErrorFunc serror;
603
604
    xmlSchemaConstructionCtxtPtr constructor;
605
    int ownsConstructor; /* TODO: Move this to parser *flags*. */
606
607
    /* xmlSchemaPtr topschema;  */
608
    /* xmlHashTablePtr namespaces;  */
609
610
    xmlSchemaPtr schema;        /* The main schema in use */
611
    int counter;
612
613
    const xmlChar *URL;
614
    xmlDocPtr doc;
615
    int preserve;   /* Whether the doc should be freed  */
616
617
    const char *buffer;
618
    int size;
619
620
    /*
621
     * Used to build complex element content models
622
     */
623
    xmlAutomataPtr am;
624
    xmlAutomataStatePtr start;
625
    xmlAutomataStatePtr end;
626
    xmlAutomataStatePtr state;
627
628
    xmlDictPtr dict;    /* dictionary for interned string names */
629
    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
630
    int options;
631
    xmlSchemaValidCtxtPtr vctxt;
632
    int isS4S;
633
    int isRedefine;
634
    int xsiAssemble;
635
    int stop; /* If the parser should stop; i.e. a critical error. */
636
    const xmlChar *targetNamespace;
637
    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
638
639
    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
640
    int redefCounter; /* Used for redefinitions. */
641
    xmlSchemaItemListPtr attrProhibs;
642
};
643
644
/**
645
 * xmlSchemaQNameRef:
646
 *
647
 * A component reference item (not a schema component)
648
 * (Extends xmlSchemaBasicItem)
649
 */
650
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
651
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
652
struct _xmlSchemaQNameRef {
653
    xmlSchemaTypeType type;
654
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
655
    xmlSchemaTypeType itemType;
656
    const xmlChar *name;
657
    const xmlChar *targetNamespace;
658
    xmlNodePtr node;
659
};
660
661
/**
662
 * xmlSchemaParticle:
663
 *
664
 * A particle component.
665
 * (Extends xmlSchemaTreeItem)
666
 */
667
typedef struct _xmlSchemaParticle xmlSchemaParticle;
668
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
669
struct _xmlSchemaParticle {
670
    xmlSchemaTypeType type;
671
    xmlSchemaAnnotPtr annot;
672
    xmlSchemaTreeItemPtr next; /* next particle */
673
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
674
  a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
675
        etc.) */
676
    int minOccurs;
677
    int maxOccurs;
678
    xmlNodePtr node;
679
};
680
681
/**
682
 * xmlSchemaModelGroup:
683
 *
684
 * A model group component.
685
 * (Extends xmlSchemaTreeItem)
686
 */
687
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
688
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
689
struct _xmlSchemaModelGroup {
690
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
691
    xmlSchemaAnnotPtr annot;
692
    xmlSchemaTreeItemPtr next; /* not used */
693
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
694
    xmlNodePtr node;
695
};
696
697
0
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
698
0
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
699
/**
700
 * xmlSchemaModelGroupDef:
701
 *
702
 * A model group definition component.
703
 * (Extends xmlSchemaTreeItem)
704
 */
705
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
706
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
707
struct _xmlSchemaModelGroupDef {
708
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
709
    xmlSchemaAnnotPtr annot;
710
    xmlSchemaTreeItemPtr next; /* not used */
711
    xmlSchemaTreeItemPtr children; /* the "model group" */
712
    const xmlChar *name;
713
    const xmlChar *targetNamespace;
714
    xmlNodePtr node;
715
    int flags;
716
};
717
718
typedef struct _xmlSchemaIDC xmlSchemaIDC;
719
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
720
721
/**
722
 * xmlSchemaIDCSelect:
723
 *
724
 * The identity-constraint "field" and "selector" item, holding the
725
 * XPath expression.
726
 */
727
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
728
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
729
struct _xmlSchemaIDCSelect {
730
    xmlSchemaIDCSelectPtr next;
731
    xmlSchemaIDCPtr idc;
732
    int index; /* an index position if significant for IDC key-sequences */
733
    const xmlChar *xpath; /* the XPath expression */
734
    void *xpathComp; /* the compiled XPath expression */
735
};
736
737
/**
738
 * xmlSchemaIDC:
739
 *
740
 * The identity-constraint definition component.
741
 * (Extends xmlSchemaAnnotItem)
742
 */
743
744
struct _xmlSchemaIDC {
745
    xmlSchemaTypeType type;
746
    xmlSchemaAnnotPtr annot;
747
    xmlSchemaIDCPtr next;
748
    xmlNodePtr node;
749
    const xmlChar *name;
750
    const xmlChar *targetNamespace;
751
    xmlSchemaIDCSelectPtr selector;
752
    xmlSchemaIDCSelectPtr fields;
753
    int nbFields;
754
    xmlSchemaQNameRefPtr ref;
755
};
756
757
/**
758
 * xmlSchemaIDCAug:
759
 *
760
 * The augmented IDC information used for validation.
761
 */
762
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
763
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
764
struct _xmlSchemaIDCAug {
765
    xmlSchemaIDCAugPtr next; /* next in a list */
766
    xmlSchemaIDCPtr def; /* the IDC definition */
767
    int keyrefDepth; /* the lowest tree level to which IDC
768
                        tables need to be bubbled upwards */
769
};
770
771
/**
772
 * xmlSchemaPSVIIDCKeySequence:
773
 *
774
 * The key sequence of a node table item.
775
 */
776
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
777
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
778
struct _xmlSchemaPSVIIDCKey {
779
    xmlSchemaTypePtr type;
780
    xmlSchemaValPtr val;
781
};
782
783
/**
784
 * xmlSchemaPSVIIDCNode:
785
 *
786
 * The node table item of a node table.
787
 */
788
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
789
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
790
struct _xmlSchemaPSVIIDCNode {
791
    xmlNodePtr node;
792
    xmlSchemaPSVIIDCKeyPtr *keys;
793
    int nodeLine;
794
    int nodeQNameID;
795
796
};
797
798
/**
799
 * xmlSchemaPSVIIDCBinding:
800
 *
801
 * The identity-constraint binding item of the [identity-constraint table].
802
 */
803
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
804
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
805
struct _xmlSchemaPSVIIDCBinding {
806
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
807
    xmlSchemaIDCPtr definition; /* the IDC definition */
808
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
809
    int nbNodes; /* number of entries in the node table */
810
    int sizeNodes; /* size of the node table */
811
    xmlSchemaItemListPtr dupls;
812
};
813
814
815
0
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
816
0
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
817
818
#define XPATH_STATE_OBJ_MATCHES -2
819
#define XPATH_STATE_OBJ_BLOCKED -3
820
821
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
822
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
823
824
/**
825
 * xmlSchemaIDCStateObj:
826
 *
827
 * The state object used to evaluate XPath expressions.
828
 */
829
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
830
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
831
struct _xmlSchemaIDCStateObj {
832
    int type;
833
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
834
    int depth; /* depth of creation */
835
    int *history; /* list of (depth, state-id) tuples */
836
    int nbHistory;
837
    int sizeHistory;
838
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
839
                                       matcher */
840
    xmlSchemaIDCSelectPtr sel;
841
    void *xpathCtxt;
842
};
843
844
0
#define IDC_MATCHER 0
845
846
/**
847
 * xmlSchemaIDCMatcher:
848
 *
849
 * Used to evaluate IDC selectors (and fields).
850
 */
851
struct _xmlSchemaIDCMatcher {
852
    int type;
853
    int depth; /* the tree depth at creation time */
854
    xmlSchemaIDCMatcherPtr next; /* next in the list */
855
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
856
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
857
    int idcType;
858
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
859
                                         elements */
860
    int sizeKeySeqs;
861
    xmlSchemaItemListPtr targets; /* list of target-node
862
                                     (xmlSchemaPSVIIDCNodePtr) entries */
863
    xmlHashTablePtr htab;
864
};
865
866
/*
867
* Element info flags.
868
*/
869
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
870
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
871
0
#define XML_SCHEMA_ELEM_INFO_NILLED        1<<2
872
0
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        1<<3
873
874
0
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
875
0
#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
876
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
877
878
0
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
879
0
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
880
0
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
881
0
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
882
883
/**
884
 * xmlSchemaNodeInfo:
885
 *
886
 * Holds information of an element node.
887
 */
888
struct _xmlSchemaNodeInfo {
889
    int nodeType;
890
    xmlNodePtr node;
891
    int nodeLine;
892
    const xmlChar *localName;
893
    const xmlChar *nsName;
894
    const xmlChar *value;
895
    xmlSchemaValPtr val; /* the pre-computed value if any */
896
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
897
898
    int flags; /* combination of node info flags */
899
900
    int valNeeded;
901
    int normVal;
902
903
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
904
    int depth;
905
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
906
                                            for the scope element*/
907
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
908
                                           element */
909
    xmlRegExecCtxtPtr regexCtxt;
910
911
    const xmlChar **nsBindings; /* Namespace bindings on this element */
912
    int nbNsBindings;
913
    int sizeNsBindings;
914
915
    int hasKeyrefs;
916
    int appliedXPath; /* Indicates that an XPath has been applied. */
917
};
918
919
0
#define XML_SCHEMAS_ATTR_UNKNOWN 1
920
0
#define XML_SCHEMAS_ATTR_ASSESSED 2
921
#define XML_SCHEMAS_ATTR_PROHIBITED 3
922
0
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
923
0
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
924
0
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
925
0
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
926
0
#define XML_SCHEMAS_ATTR_DEFAULT 8
927
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
928
0
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
929
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
930
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
931
0
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
932
0
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
933
0
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
934
0
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
935
0
#define XML_SCHEMAS_ATTR_META 17
936
/*
937
* @metaType values of xmlSchemaAttrInfo.
938
*/
939
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
940
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
941
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
942
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
943
0
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
944
945
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
946
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
947
struct _xmlSchemaAttrInfo {
948
    int nodeType;
949
    xmlNodePtr node;
950
    int nodeLine;
951
    const xmlChar *localName;
952
    const xmlChar *nsName;
953
    const xmlChar *value;
954
    xmlSchemaValPtr val; /* the pre-computed value if any */
955
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
956
    int flags; /* combination of node info flags */
957
958
    xmlSchemaAttributePtr decl; /* the attribute declaration */
959
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
960
    int state;
961
    int metaType;
962
    const xmlChar *vcValue; /* the value constraint value */
963
    xmlSchemaNodeInfoPtr parent;
964
};
965
966
967
0
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
968
/**
969
 * xmlSchemaValidCtxt:
970
 *
971
 * A Schemas validation context
972
 */
973
struct _xmlSchemaValidCtxt {
974
    int type;
975
    void *errCtxt;             /* user specific data block */
976
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
977
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
978
    xmlStructuredErrorFunc serror;
979
980
    xmlSchemaPtr schema;        /* The schema in use */
981
    xmlDocPtr doc;
982
    xmlParserInputBufferPtr input;
983
    xmlCharEncoding enc;
984
    xmlSAXHandlerPtr sax;
985
    xmlParserCtxtPtr parserCtxt;
986
    void *user_data; /* TODO: What is this for? */
987
    char *filename;
988
989
    int err;
990
    int nberrors;
991
992
    xmlNodePtr node;
993
    xmlNodePtr cur;
994
    /* xmlSchemaTypePtr type; */
995
996
    xmlRegExecCtxtPtr regexp;
997
    xmlSchemaValPtr value;
998
999
    int valueWS;
1000
    int options;
1001
    xmlNodePtr validationRoot;
1002
    xmlSchemaParserCtxtPtr pctxt;
1003
    int xsiAssemble;
1004
1005
    int depth;
1006
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
1007
    int sizeElemInfos;
1008
    xmlSchemaNodeInfoPtr inode; /* the current element information */
1009
1010
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1011
1012
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1013
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1014
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1015
1016
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1017
    int nbIdcNodes;
1018
    int sizeIdcNodes;
1019
1020
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1021
    int nbIdcKeys;
1022
    int sizeIdcKeys;
1023
1024
    int flags;
1025
1026
    xmlDictPtr dict;
1027
1028
#ifdef LIBXML_READER_ENABLED
1029
    xmlTextReaderPtr reader;
1030
#endif
1031
1032
    xmlSchemaAttrInfoPtr *attrInfos;
1033
    int nbAttrInfos;
1034
    int sizeAttrInfos;
1035
1036
    int skipDepth;
1037
    xmlSchemaItemListPtr nodeQNames;
1038
    int hasKeyrefs;
1039
    int createIDCNodeTables;
1040
    int psviExposeIDCNodeTables;
1041
1042
    /* Locator for error reporting in streaming mode */
1043
    xmlSchemaValidityLocatorFunc locFunc;
1044
    void *locCtxt;
1045
};
1046
1047
/**
1048
 * xmlSchemaSubstGroup:
1049
 *
1050
 *
1051
 */
1052
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1053
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1054
struct _xmlSchemaSubstGroup {
1055
    xmlSchemaElementPtr head;
1056
    xmlSchemaItemListPtr members;
1057
};
1058
1059
/**
1060
 * xmlIDCHashEntry:
1061
 *
1062
 * an entry in hash tables to quickly look up keys/uniques
1063
 */
1064
typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1065
typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1066
struct _xmlIDCHashEntry {
1067
    xmlIDCHashEntryPtr next; /* next item with same hash */
1068
    int index;               /* index into associated item list */
1069
};
1070
1071
/************************************************************************
1072
 *                  *
1073
 *      Some predeclarations        *
1074
 *                  *
1075
 ************************************************************************/
1076
1077
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1078
                                 xmlSchemaPtr schema,
1079
                                 xmlNodePtr node);
1080
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1081
                                 xmlSchemaPtr schema,
1082
                                 xmlNodePtr node);
1083
static int
1084
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1085
                   xmlSchemaAbstractCtxtPtr ctxt);
1086
static const xmlChar *
1087
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1088
static int
1089
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1090
                     xmlNodePtr node);
1091
static int
1092
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1093
                       xmlSchemaParserCtxtPtr ctxt);
1094
static void
1095
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1096
static xmlSchemaWhitespaceValueType
1097
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1098
static xmlSchemaTreeItemPtr
1099
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1100
       xmlNodePtr node, xmlSchemaTypeType type,
1101
       int withParticle);
1102
static const xmlChar *
1103
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1104
static xmlSchemaTypeLinkPtr
1105
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1106
static void
1107
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1108
         const char *funcName,
1109
         const char *message) LIBXML_ATTR_FORMAT(3,0);
1110
static int
1111
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1112
           xmlSchemaTypePtr type,
1113
           xmlSchemaTypePtr baseType,
1114
           int subset);
1115
static void
1116
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1117
           xmlSchemaParserCtxtPtr ctxt);
1118
static void
1119
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1120
static xmlSchemaQNameRefPtr
1121
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1122
        xmlSchemaPtr schema,
1123
        xmlNodePtr node);
1124
1125
/************************************************************************
1126
 *                  *
1127
 *      Helper functions              *
1128
 *                  *
1129
 ************************************************************************/
1130
1131
/**
1132
 * xmlSchemaItemTypeToStr:
1133
 * @type: the type of the schema item
1134
 *
1135
 * Returns the component name of a schema item.
1136
 */
1137
static const xmlChar *
1138
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1139
0
{
1140
0
    switch (type) {
1141
0
  case XML_SCHEMA_TYPE_BASIC:
1142
0
      return(BAD_CAST "simple type definition");
1143
0
  case XML_SCHEMA_TYPE_SIMPLE:
1144
0
      return(BAD_CAST "simple type definition");
1145
0
  case XML_SCHEMA_TYPE_COMPLEX:
1146
0
      return(BAD_CAST "complex type definition");
1147
0
  case XML_SCHEMA_TYPE_ELEMENT:
1148
0
      return(BAD_CAST "element declaration");
1149
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1150
0
      return(BAD_CAST "attribute use");
1151
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1152
0
      return(BAD_CAST "attribute declaration");
1153
0
  case XML_SCHEMA_TYPE_GROUP:
1154
0
      return(BAD_CAST "model group definition");
1155
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1156
0
      return(BAD_CAST "attribute group definition");
1157
0
  case XML_SCHEMA_TYPE_NOTATION:
1158
0
      return(BAD_CAST "notation declaration");
1159
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1160
0
      return(BAD_CAST "model group (sequence)");
1161
0
  case XML_SCHEMA_TYPE_CHOICE:
1162
0
      return(BAD_CAST "model group (choice)");
1163
0
  case XML_SCHEMA_TYPE_ALL:
1164
0
      return(BAD_CAST "model group (all)");
1165
0
  case XML_SCHEMA_TYPE_PARTICLE:
1166
0
      return(BAD_CAST "particle");
1167
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1168
0
      return(BAD_CAST "unique identity-constraint");
1169
      /* return(BAD_CAST "IDC (unique)"); */
1170
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1171
0
      return(BAD_CAST "key identity-constraint");
1172
      /* return(BAD_CAST "IDC (key)"); */
1173
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1174
0
      return(BAD_CAST "keyref identity-constraint");
1175
      /* return(BAD_CAST "IDC (keyref)"); */
1176
0
  case XML_SCHEMA_TYPE_ANY:
1177
0
      return(BAD_CAST "wildcard (any)");
1178
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1179
0
      return(BAD_CAST "[helper component] QName reference");
1180
0
  case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1181
0
      return(BAD_CAST "[helper component] attribute use prohibition");
1182
0
  default:
1183
0
      return(BAD_CAST "Not a schema component");
1184
0
    }
1185
0
}
1186
1187
/**
1188
 * xmlSchemaGetComponentTypeStr:
1189
 * @type: the type of the schema item
1190
 *
1191
 * Returns the component name of a schema item.
1192
 */
1193
static const xmlChar *
1194
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1195
0
{
1196
0
    switch (item->type) {
1197
0
  case XML_SCHEMA_TYPE_BASIC:
1198
0
      if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1199
0
    return(BAD_CAST "complex type definition");
1200
0
      else
1201
0
    return(BAD_CAST "simple type definition");
1202
0
  default:
1203
0
      return(xmlSchemaItemTypeToStr(item->type));
1204
0
    }
1205
0
}
1206
1207
/**
1208
 * xmlSchemaGetComponentNode:
1209
 * @item: a schema component
1210
 *
1211
 * Returns node associated with the schema component.
1212
 * NOTE that such a node need not be available; plus, a component's
1213
 * node need not to reflect the component directly, since there is no
1214
 * one-to-one relationship between the XML Schema representation and
1215
 * the component representation.
1216
 */
1217
static xmlNodePtr
1218
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1219
0
{
1220
0
    switch (item->type) {
1221
0
  case XML_SCHEMA_TYPE_ELEMENT:
1222
0
      return (((xmlSchemaElementPtr) item)->node);
1223
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1224
0
      return (((xmlSchemaAttributePtr) item)->node);
1225
0
  case XML_SCHEMA_TYPE_COMPLEX:
1226
0
  case XML_SCHEMA_TYPE_SIMPLE:
1227
0
      return (((xmlSchemaTypePtr) item)->node);
1228
0
  case XML_SCHEMA_TYPE_ANY:
1229
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1230
0
      return (((xmlSchemaWildcardPtr) item)->node);
1231
0
  case XML_SCHEMA_TYPE_PARTICLE:
1232
0
      return (((xmlSchemaParticlePtr) item)->node);
1233
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1234
0
  case XML_SCHEMA_TYPE_CHOICE:
1235
0
  case XML_SCHEMA_TYPE_ALL:
1236
0
      return (((xmlSchemaModelGroupPtr) item)->node);
1237
0
  case XML_SCHEMA_TYPE_GROUP:
1238
0
      return (((xmlSchemaModelGroupDefPtr) item)->node);
1239
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1240
0
      return (((xmlSchemaAttributeGroupPtr) item)->node);
1241
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1242
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1243
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1244
0
      return (((xmlSchemaIDCPtr) item)->node);
1245
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1246
0
      return(((xmlSchemaQNameRefPtr) item)->node);
1247
  /* TODO: What to do with NOTATIONs?
1248
  case XML_SCHEMA_TYPE_NOTATION:
1249
      return (((xmlSchemaNotationPtr) item)->node);
1250
  */
1251
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1252
0
      return (((xmlSchemaAttributeUsePtr) item)->node);
1253
0
  default:
1254
0
      return (NULL);
1255
0
    }
1256
0
}
1257
1258
#if 0
1259
/**
1260
 * xmlSchemaGetNextComponent:
1261
 * @item: a schema component
1262
 *
1263
 * Returns the next sibling of the schema component.
1264
 */
1265
static xmlSchemaBasicItemPtr
1266
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1267
{
1268
    switch (item->type) {
1269
  case XML_SCHEMA_TYPE_ELEMENT:
1270
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1271
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1272
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1273
  case XML_SCHEMA_TYPE_COMPLEX:
1274
  case XML_SCHEMA_TYPE_SIMPLE:
1275
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1276
  case XML_SCHEMA_TYPE_ANY:
1277
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1278
      return (NULL);
1279
  case XML_SCHEMA_TYPE_PARTICLE:
1280
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1281
  case XML_SCHEMA_TYPE_SEQUENCE:
1282
  case XML_SCHEMA_TYPE_CHOICE:
1283
  case XML_SCHEMA_TYPE_ALL:
1284
      return (NULL);
1285
  case XML_SCHEMA_TYPE_GROUP:
1286
      return (NULL);
1287
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1288
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1289
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1290
  case XML_SCHEMA_TYPE_IDC_KEY:
1291
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1292
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1293
  default:
1294
      return (NULL);
1295
    }
1296
}
1297
#endif
1298
1299
1300
/**
1301
 * xmlSchemaFormatQName:
1302
 * @buf: the string buffer
1303
 * @namespaceName:  the namespace name
1304
 * @localName: the local name
1305
 *
1306
 * Returns the given QName in the format "{namespaceName}localName" or
1307
 * just "localName" if @namespaceName is NULL.
1308
 *
1309
 * Returns the localName if @namespaceName is NULL, a formatted
1310
 * string otherwise.
1311
 */
1312
static const xmlChar*
1313
xmlSchemaFormatQName(xmlChar **buf,
1314
         const xmlChar *namespaceName,
1315
         const xmlChar *localName)
1316
0
{
1317
0
    FREE_AND_NULL(*buf)
1318
0
    if (namespaceName != NULL) {
1319
0
  *buf = xmlStrdup(BAD_CAST "{");
1320
0
  *buf = xmlStrcat(*buf, namespaceName);
1321
0
  *buf = xmlStrcat(*buf, BAD_CAST "}");
1322
0
    }
1323
0
    if (localName != NULL) {
1324
0
  if (namespaceName == NULL)
1325
0
      return(localName);
1326
0
  *buf = xmlStrcat(*buf, localName);
1327
0
    } else {
1328
0
  *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1329
0
    }
1330
0
    return ((const xmlChar *) *buf);
1331
0
}
1332
1333
static const xmlChar*
1334
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1335
0
{
1336
0
    if (ns != NULL)
1337
0
  return (xmlSchemaFormatQName(buf, ns->href, localName));
1338
0
    else
1339
0
  return (xmlSchemaFormatQName(buf, NULL, localName));
1340
0
}
1341
1342
static const xmlChar *
1343
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1344
0
{
1345
0
    if (item == NULL) {
1346
0
        return (NULL);
1347
0
    }
1348
0
    switch (item->type) {
1349
0
  case XML_SCHEMA_TYPE_ELEMENT:
1350
0
      return (((xmlSchemaElementPtr) item)->name);
1351
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1352
0
      return (((xmlSchemaAttributePtr) item)->name);
1353
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1354
0
      return (((xmlSchemaAttributeGroupPtr) item)->name);
1355
0
  case XML_SCHEMA_TYPE_BASIC:
1356
0
  case XML_SCHEMA_TYPE_SIMPLE:
1357
0
  case XML_SCHEMA_TYPE_COMPLEX:
1358
0
      return (((xmlSchemaTypePtr) item)->name);
1359
0
  case XML_SCHEMA_TYPE_GROUP:
1360
0
      return (((xmlSchemaModelGroupDefPtr) item)->name);
1361
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1362
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1363
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1364
0
      return (((xmlSchemaIDCPtr) item)->name);
1365
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1366
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1367
0
    return(xmlSchemaGetComponentName(
1368
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1369
0
      } else
1370
0
    return(NULL);
1371
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1372
0
      return (((xmlSchemaQNameRefPtr) item)->name);
1373
0
  case XML_SCHEMA_TYPE_NOTATION:
1374
0
      return (((xmlSchemaNotationPtr) item)->name);
1375
0
  default:
1376
      /*
1377
      * Other components cannot have names.
1378
      */
1379
0
      break;
1380
0
    }
1381
0
    return (NULL);
1382
0
}
1383
1384
0
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1385
0
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1386
/*
1387
static const xmlChar *
1388
xmlSchemaGetQNameRefName(void *ref)
1389
{
1390
    return(((xmlSchemaQNameRefPtr) ref)->name);
1391
}
1392
1393
static const xmlChar *
1394
xmlSchemaGetQNameRefTargetNs(void *ref)
1395
{
1396
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1397
}
1398
*/
1399
1400
static const xmlChar *
1401
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1402
0
{
1403
0
    if (item == NULL) {
1404
0
        return (NULL);
1405
0
    }
1406
0
    switch (item->type) {
1407
0
  case XML_SCHEMA_TYPE_ELEMENT:
1408
0
      return (((xmlSchemaElementPtr) item)->targetNamespace);
1409
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1410
0
      return (((xmlSchemaAttributePtr) item)->targetNamespace);
1411
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1412
0
      return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1413
0
  case XML_SCHEMA_TYPE_BASIC:
1414
0
      return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1415
0
  case XML_SCHEMA_TYPE_SIMPLE:
1416
0
  case XML_SCHEMA_TYPE_COMPLEX:
1417
0
      return (((xmlSchemaTypePtr) item)->targetNamespace);
1418
0
  case XML_SCHEMA_TYPE_GROUP:
1419
0
      return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1420
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1421
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1422
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1423
0
      return (((xmlSchemaIDCPtr) item)->targetNamespace);
1424
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1425
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1426
0
    return(xmlSchemaGetComponentTargetNs(
1427
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1428
0
      }
1429
      /* TODO: Will returning NULL break something? */
1430
0
      break;
1431
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1432
0
      return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1433
0
  case XML_SCHEMA_TYPE_NOTATION:
1434
0
      return (((xmlSchemaNotationPtr) item)->targetNamespace);
1435
0
  default:
1436
      /*
1437
      * Other components cannot have names.
1438
      */
1439
0
      break;
1440
0
    }
1441
0
    return (NULL);
1442
0
}
1443
1444
static const xmlChar*
1445
xmlSchemaGetComponentQName(xmlChar **buf,
1446
         void *item)
1447
0
{
1448
0
    return (xmlSchemaFormatQName(buf,
1449
0
  xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1450
0
  xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1451
0
}
1452
1453
static const xmlChar*
1454
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1455
0
{
1456
0
    xmlChar *str = NULL;
1457
1458
0
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1459
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1460
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1461
0
  (xmlSchemaBasicItemPtr) item));
1462
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1463
0
    FREE_AND_NULL(str);
1464
0
    return(*buf);
1465
0
}
1466
1467
static const xmlChar*
1468
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1469
0
{
1470
0
    return(xmlSchemaGetComponentDesignation(buf, idc));
1471
0
}
1472
1473
/**
1474
 * xmlSchemaWildcardPCToString:
1475
 * @pc: the type of processContents
1476
 *
1477
 * Returns a string representation of the type of
1478
 * processContents.
1479
 */
1480
static const xmlChar *
1481
xmlSchemaWildcardPCToString(int pc)
1482
0
{
1483
0
    switch (pc) {
1484
0
  case XML_SCHEMAS_ANY_SKIP:
1485
0
      return (BAD_CAST "skip");
1486
0
  case XML_SCHEMAS_ANY_LAX:
1487
0
      return (BAD_CAST "lax");
1488
0
  case XML_SCHEMAS_ANY_STRICT:
1489
0
      return (BAD_CAST "strict");
1490
0
  default:
1491
0
      return (BAD_CAST "invalid process contents");
1492
0
    }
1493
0
}
1494
1495
/**
1496
 * xmlSchemaGetCanonValueWhtspExt:
1497
 * @val: the precomputed value
1498
 * @retValue: the returned value
1499
 * @ws: the whitespace type of the value
1500
 * @for_hash: non-zero if this is supposed to generate a string for hashing
1501
 *
1502
 * Get a the canonical representation of the value.
1503
 * The caller has to free the returned retValue.
1504
 *
1505
 * Returns 0 if the value could be built and -1 in case of
1506
 *         API errors or if the value type is not supported yet.
1507
 */
1508
static int
1509
xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1510
               xmlSchemaWhitespaceValueType ws,
1511
               xmlChar **retValue,
1512
         int for_hash)
1513
0
{
1514
0
    int list;
1515
0
    xmlSchemaValType valType;
1516
0
    const xmlChar *value, *value2 = NULL;
1517
1518
1519
0
    if ((retValue == NULL) || (val == NULL))
1520
0
  return (-1);
1521
0
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1522
0
    *retValue = NULL;
1523
0
    do {
1524
0
  value = NULL;
1525
0
  valType = xmlSchemaGetValType(val);
1526
0
  switch (valType) {
1527
0
      case XML_SCHEMAS_STRING:
1528
0
      case XML_SCHEMAS_NORMSTRING:
1529
0
      case XML_SCHEMAS_ANYSIMPLETYPE:
1530
0
    value = xmlSchemaValueGetAsString(val);
1531
0
    if (value != NULL) {
1532
0
        if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1533
0
      value2 = xmlSchemaCollapseString(value);
1534
0
        else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1535
0
      value2 = xmlSchemaWhiteSpaceReplace(value);
1536
0
        if (value2 != NULL)
1537
0
      value = value2;
1538
0
    }
1539
0
    break;
1540
0
      default:
1541
0
    if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1542
0
        if (value2 != NULL)
1543
0
      xmlFree((xmlChar *) value2);
1544
0
        goto internal_error;
1545
0
    }
1546
0
    if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1547
        /* We can mostly use the canonical value for hashing,
1548
           except in the case of decimal.  There the canonical
1549
           representation requires a trailing '.0' even for
1550
           non-fractional numbers, but for the derived integer
1551
           types it forbids any decimal point.  Nevertheless they
1552
           compare equal if the value is equal.  We need to generate
1553
           the same hash value for this to work, and it's easiest
1554
           to just cut off the useless '.0' suffix for the
1555
           decimal type.  */
1556
0
        int len = xmlStrlen(value2);
1557
0
        if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1558
0
          ((xmlChar*)value2)[len-2] = 0;
1559
0
    }
1560
0
    value = value2;
1561
0
  }
1562
0
  if (*retValue == NULL)
1563
0
      if (value == NULL) {
1564
0
    if (! list)
1565
0
        *retValue = xmlStrdup(BAD_CAST "");
1566
0
      } else
1567
0
    *retValue = xmlStrdup(value);
1568
0
  else if (value != NULL) {
1569
      /* List. */
1570
0
      *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1571
0
      *retValue = xmlStrcat((xmlChar *) *retValue, value);
1572
0
  }
1573
0
  FREE_AND_NULL(value2)
1574
0
  val = xmlSchemaValueGetNext(val);
1575
0
    } while (val != NULL);
1576
1577
0
    return (0);
1578
0
internal_error:
1579
0
    if (*retValue != NULL)
1580
0
  xmlFree((xmlChar *) (*retValue));
1581
0
    if (value2 != NULL)
1582
0
  xmlFree((xmlChar *) value2);
1583
0
    return (-1);
1584
0
}
1585
1586
static int
1587
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1588
             xmlSchemaWhitespaceValueType ws,
1589
             xmlChar **retValue)
1590
0
{
1591
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1592
0
}
1593
1594
static int
1595
xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1596
         xmlChar **retValue)
1597
0
{
1598
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1599
0
              retValue, 1);
1600
0
}
1601
1602
/**
1603
 * xmlSchemaFormatItemForReport:
1604
 * @buf: the string buffer
1605
 * @itemDes: the designation of the item
1606
 * @itemName: the name of the item
1607
 * @item: the item as an object
1608
 * @itemNode: the node of the item
1609
 * @local: the local name
1610
 * @parsing: if the function is used during the parse
1611
 *
1612
 * Returns a representation of the given item used
1613
 * for error reports.
1614
 *
1615
 * The following order is used to build the resulting
1616
 * designation if the arguments are not NULL:
1617
 * 1a. If itemDes not NULL -> itemDes
1618
 * 1b. If (itemDes not NULL) and (itemName not NULL)
1619
 *     -> itemDes + itemName
1620
 * 2. If the preceding was NULL and (item not NULL) -> item
1621
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1622
 *
1623
 * If the itemNode is an attribute node, the name of the attribute
1624
 * will be appended to the result.
1625
 *
1626
 * Returns the formatted string and sets @buf to the resulting value.
1627
 */
1628
static xmlChar*
1629
xmlSchemaFormatItemForReport(xmlChar **buf,
1630
         const xmlChar *itemDes,
1631
         xmlSchemaBasicItemPtr item,
1632
         xmlNodePtr itemNode)
1633
0
{
1634
0
    xmlChar *str = NULL;
1635
0
    int named = 1;
1636
1637
0
    if (*buf != NULL) {
1638
0
  xmlFree(*buf);
1639
0
  *buf = NULL;
1640
0
    }
1641
1642
0
    if (itemDes != NULL) {
1643
0
  *buf = xmlStrdup(itemDes);
1644
0
    } else if (item != NULL) {
1645
0
  switch (item->type) {
1646
0
  case XML_SCHEMA_TYPE_BASIC: {
1647
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1648
1649
0
      if (WXS_IS_ATOMIC(type))
1650
0
    *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1651
0
      else if (WXS_IS_LIST(type))
1652
0
    *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1653
0
      else if (WXS_IS_UNION(type))
1654
0
    *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1655
0
      else
1656
0
    *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1657
0
      *buf = xmlStrcat(*buf, type->name);
1658
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1659
0
      }
1660
0
      break;
1661
0
  case XML_SCHEMA_TYPE_SIMPLE: {
1662
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1663
1664
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1665
0
    *buf = xmlStrdup(BAD_CAST"");
1666
0
      } else {
1667
0
    *buf = xmlStrdup(BAD_CAST "local ");
1668
0
      }
1669
0
      if (WXS_IS_ATOMIC(type))
1670
0
    *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1671
0
      else if (WXS_IS_LIST(type))
1672
0
    *buf = xmlStrcat(*buf, BAD_CAST "list type");
1673
0
      else if (WXS_IS_UNION(type))
1674
0
    *buf = xmlStrcat(*buf, BAD_CAST "union type");
1675
0
      else
1676
0
    *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1677
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1678
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1679
0
    *buf = xmlStrcat(*buf, type->name);
1680
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1681
0
      }
1682
0
      }
1683
0
      break;
1684
0
  case XML_SCHEMA_TYPE_COMPLEX: {
1685
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1686
1687
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1688
0
    *buf = xmlStrdup(BAD_CAST "");
1689
0
      else
1690
0
    *buf = xmlStrdup(BAD_CAST "local ");
1691
0
      *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1692
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1693
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1694
0
    *buf = xmlStrcat(*buf, type->name);
1695
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1696
0
      }
1697
0
      }
1698
0
      break;
1699
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1700
0
    xmlSchemaAttributeUsePtr ause;
1701
1702
0
    ause = WXS_ATTR_USE_CAST item;
1703
0
    *buf = xmlStrdup(BAD_CAST "attribute use ");
1704
0
    if (WXS_ATTRUSE_DECL(ause) != NULL) {
1705
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1706
0
        *buf = xmlStrcat(*buf,
1707
0
      xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1708
0
        FREE_AND_NULL(str)
1709
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1710
0
    } else {
1711
0
        *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1712
0
    }
1713
0
      }
1714
0
      break;
1715
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
1716
0
    xmlSchemaAttributePtr attr;
1717
1718
0
    attr = (xmlSchemaAttributePtr) item;
1719
0
    *buf = xmlStrdup(BAD_CAST "attribute decl.");
1720
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1721
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1722
0
        attr->targetNamespace, attr->name));
1723
0
    FREE_AND_NULL(str)
1724
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1725
0
      }
1726
0
      break;
1727
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1728
0
      xmlSchemaGetComponentDesignation(buf, item);
1729
0
      break;
1730
0
  case XML_SCHEMA_TYPE_ELEMENT: {
1731
0
    xmlSchemaElementPtr elem;
1732
1733
0
    elem = (xmlSchemaElementPtr) item;
1734
0
    *buf = xmlStrdup(BAD_CAST "element decl.");
1735
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1736
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1737
0
        elem->targetNamespace, elem->name));
1738
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1739
0
      }
1740
0
      break;
1741
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1742
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1743
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1744
0
      if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1745
0
    *buf = xmlStrdup(BAD_CAST "unique '");
1746
0
      else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1747
0
    *buf = xmlStrdup(BAD_CAST "key '");
1748
0
      else
1749
0
    *buf = xmlStrdup(BAD_CAST "keyRef '");
1750
0
      *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1751
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1752
0
      break;
1753
0
  case XML_SCHEMA_TYPE_ANY:
1754
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1755
0
      *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1756
0
        ((xmlSchemaWildcardPtr) item)->processContents));
1757
0
      *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1758
0
      break;
1759
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
1760
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
1761
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
1762
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1763
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
1764
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
1765
0
  case XML_SCHEMA_FACET_PATTERN:
1766
0
  case XML_SCHEMA_FACET_ENUMERATION:
1767
0
  case XML_SCHEMA_FACET_WHITESPACE:
1768
0
  case XML_SCHEMA_FACET_LENGTH:
1769
0
  case XML_SCHEMA_FACET_MAXLENGTH:
1770
0
  case XML_SCHEMA_FACET_MINLENGTH:
1771
0
      *buf = xmlStrdup(BAD_CAST "facet '");
1772
0
      *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1773
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1774
0
      break;
1775
0
  case XML_SCHEMA_TYPE_GROUP: {
1776
0
    *buf = xmlStrdup(BAD_CAST "model group def.");
1777
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1778
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1779
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1780
0
    FREE_AND_NULL(str)
1781
0
      }
1782
0
      break;
1783
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1784
0
  case XML_SCHEMA_TYPE_CHOICE:
1785
0
  case XML_SCHEMA_TYPE_ALL:
1786
0
  case XML_SCHEMA_TYPE_PARTICLE:
1787
0
      *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1788
0
      break;
1789
0
  case XML_SCHEMA_TYPE_NOTATION: {
1790
0
    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1791
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1792
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1793
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1794
0
    FREE_AND_NULL(str);
1795
0
      }
1796
            /* Falls through. */
1797
0
  default:
1798
0
      named = 0;
1799
0
  }
1800
0
    } else
1801
0
  named = 0;
1802
1803
0
    if ((named == 0) && (itemNode != NULL)) {
1804
0
  xmlNodePtr elem;
1805
1806
0
  if (itemNode->type == XML_ATTRIBUTE_NODE)
1807
0
      elem = itemNode->parent;
1808
0
  else
1809
0
      elem = itemNode;
1810
0
  *buf = xmlStrdup(BAD_CAST "Element '");
1811
0
  if (elem->ns != NULL) {
1812
0
      *buf = xmlStrcat(*buf,
1813
0
    xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1814
0
      FREE_AND_NULL(str)
1815
0
  } else
1816
0
      *buf = xmlStrcat(*buf, elem->name);
1817
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1818
1819
0
    }
1820
0
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1821
0
  *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1822
0
  if (itemNode->ns != NULL) {
1823
0
      *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1824
0
    itemNode->ns->href, itemNode->name));
1825
0
      FREE_AND_NULL(str)
1826
0
  } else
1827
0
      *buf = xmlStrcat(*buf, itemNode->name);
1828
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1829
0
    }
1830
0
    FREE_AND_NULL(str)
1831
1832
0
    return (xmlEscapeFormatString(buf));
1833
0
}
1834
1835
/**
1836
 * xmlSchemaFormatFacetEnumSet:
1837
 * @buf: the string buffer
1838
 * @type: the type holding the enumeration facets
1839
 *
1840
 * Builds a string consisting of all enumeration elements.
1841
 *
1842
 * Returns a string of all enumeration elements.
1843
 */
1844
static const xmlChar *
1845
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1846
          xmlChar **buf, xmlSchemaTypePtr type)
1847
0
{
1848
0
    xmlSchemaFacetPtr facet;
1849
0
    xmlSchemaWhitespaceValueType ws;
1850
0
    xmlChar *value = NULL;
1851
0
    int res, found = 0;
1852
1853
0
    if (*buf != NULL)
1854
0
  xmlFree(*buf);
1855
0
    *buf = NULL;
1856
1857
0
    do {
1858
  /*
1859
  * Use the whitespace type of the base type.
1860
  */
1861
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1862
0
  for (facet = type->facets; facet != NULL; facet = facet->next) {
1863
0
      if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1864
0
    continue;
1865
0
      found = 1;
1866
0
      res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1867
0
    ws, &value);
1868
0
      if (res == -1) {
1869
0
    xmlSchemaInternalErr(actxt,
1870
0
        "xmlSchemaFormatFacetEnumSet",
1871
0
        "compute the canonical lexical representation");
1872
0
    if (*buf != NULL)
1873
0
        xmlFree(*buf);
1874
0
    *buf = NULL;
1875
0
    return (NULL);
1876
0
      }
1877
0
      if (*buf == NULL)
1878
0
    *buf = xmlStrdup(BAD_CAST "'");
1879
0
      else
1880
0
    *buf = xmlStrcat(*buf, BAD_CAST ", '");
1881
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
1882
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1883
0
      if (value != NULL) {
1884
0
    xmlFree((xmlChar *)value);
1885
0
    value = NULL;
1886
0
      }
1887
0
  }
1888
  /*
1889
  * The enumeration facet of a type restricts the enumeration
1890
  * facet of the ancestor type; i.e., such restricted enumerations
1891
  * do not belong to the set of the given type. Thus we break
1892
  * on the first found enumeration.
1893
  */
1894
0
  if (found)
1895
0
      break;
1896
0
  type = type->baseType;
1897
0
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1898
1899
0
    return ((const xmlChar *) *buf);
1900
0
}
1901
1902
/************************************************************************
1903
 *                  *
1904
 *      Error functions               *
1905
 *                  *
1906
 ************************************************************************/
1907
1908
#if 0
1909
static void
1910
xmlSchemaErrMemory(const char *msg)
1911
{
1912
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1913
                     msg);
1914
}
1915
#endif
1916
1917
static void
1918
xmlSchemaPSimpleErr(const char *msg)
1919
0
{
1920
0
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1921
0
                     msg);
1922
0
}
1923
1924
/**
1925
 * xmlSchemaPErrMemory:
1926
 * @node: a context node
1927
 * @extra:  extra information
1928
 *
1929
 * Handle an out of memory condition
1930
 */
1931
static void
1932
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1933
                    const char *extra, xmlNodePtr node)
1934
0
{
1935
0
    if (ctxt != NULL)
1936
0
        ctxt->nberrors++;
1937
0
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
1938
0
                     extra);
1939
0
}
1940
1941
/**
1942
 * xmlSchemaPErr:
1943
 * @ctxt: the parsing context
1944
 * @node: the context node
1945
 * @error: the error code
1946
 * @msg: the error message
1947
 * @str1: extra data
1948
 * @str2: extra data
1949
 *
1950
 * Handle a parser error
1951
 */
1952
static void LIBXML_ATTR_FORMAT(4,0)
1953
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1954
              const char *msg, const xmlChar * str1, const xmlChar * str2)
1955
0
{
1956
0
    xmlGenericErrorFunc channel = NULL;
1957
0
    xmlStructuredErrorFunc schannel = NULL;
1958
0
    void *data = NULL;
1959
1960
0
    if (ctxt != NULL) {
1961
0
        ctxt->nberrors++;
1962
0
  ctxt->err = error;
1963
0
        channel = ctxt->error;
1964
0
        data = ctxt->errCtxt;
1965
0
  schannel = ctxt->serror;
1966
0
    }
1967
0
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1968
0
                    error, XML_ERR_ERROR, NULL, 0,
1969
0
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
1970
0
                    msg, str1, str2);
1971
0
}
1972
1973
/**
1974
 * xmlSchemaPErr2:
1975
 * @ctxt: the parsing context
1976
 * @node: the context node
1977
 * @node: the current child
1978
 * @error: the error code
1979
 * @msg: the error message
1980
 * @str1: extra data
1981
 * @str2: extra data
1982
 *
1983
 * Handle a parser error
1984
 */
1985
static void LIBXML_ATTR_FORMAT(5,0)
1986
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1987
               xmlNodePtr child, int error,
1988
               const char *msg, const xmlChar * str1, const xmlChar * str2)
1989
0
{
1990
0
    if (child != NULL)
1991
0
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1992
0
    else
1993
0
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1994
0
}
1995
1996
1997
/**
1998
 * xmlSchemaPErrExt:
1999
 * @ctxt: the parsing context
2000
 * @node: the context node
2001
 * @error: the error code
2002
 * @strData1: extra data
2003
 * @strData2: extra data
2004
 * @strData3: extra data
2005
 * @msg: the message
2006
 * @str1:  extra parameter for the message display
2007
 * @str2:  extra parameter for the message display
2008
 * @str3:  extra parameter for the message display
2009
 * @str4:  extra parameter for the message display
2010
 * @str5:  extra parameter for the message display
2011
 *
2012
 * Handle a parser error
2013
 */
2014
static void LIBXML_ATTR_FORMAT(7,0)
2015
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
2016
    const xmlChar * strData1, const xmlChar * strData2,
2017
    const xmlChar * strData3, const char *msg, const xmlChar * str1,
2018
    const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2019
    const xmlChar * str5)
2020
0
{
2021
2022
0
    xmlGenericErrorFunc channel = NULL;
2023
0
    xmlStructuredErrorFunc schannel = NULL;
2024
0
    void *data = NULL;
2025
2026
0
    if (ctxt != NULL) {
2027
0
        ctxt->nberrors++;
2028
0
  ctxt->err = error;
2029
0
        channel = ctxt->error;
2030
0
        data = ctxt->errCtxt;
2031
0
  schannel = ctxt->serror;
2032
0
    }
2033
0
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
2034
0
                    error, XML_ERR_ERROR, NULL, 0,
2035
0
                    (const char *) strData1, (const char *) strData2,
2036
0
        (const char *) strData3, 0, 0, msg, str1, str2,
2037
0
        str3, str4, str5);
2038
0
}
2039
2040
/************************************************************************
2041
 *                  *
2042
 *      Allround error functions      *
2043
 *                  *
2044
 ************************************************************************/
2045
2046
/**
2047
 * xmlSchemaVTypeErrMemory:
2048
 * @node: a context node
2049
 * @extra:  extra information
2050
 *
2051
 * Handle an out of memory condition
2052
 */
2053
static void
2054
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
2055
                    const char *extra, xmlNodePtr node)
2056
0
{
2057
0
    if (ctxt != NULL) {
2058
0
        ctxt->nberrors++;
2059
0
        ctxt->err = XML_SCHEMAV_INTERNAL;
2060
0
    }
2061
0
    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
2062
0
                     extra);
2063
0
}
2064
2065
static void LIBXML_ATTR_FORMAT(2,0)
2066
xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2067
          const char *msg, const xmlChar *str)
2068
0
{
2069
0
     __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2070
0
   msg, (const char *) str);
2071
0
}
2072
2073
#define WXS_ERROR_TYPE_ERROR 1
2074
#define WXS_ERROR_TYPE_WARNING 2
2075
/**
2076
 * xmlSchemaErr4Line:
2077
 * @ctxt: the validation context
2078
 * @errorLevel: the error level
2079
 * @error: the error code
2080
 * @node: the context node
2081
 * @line: the line number
2082
 * @msg: the error message
2083
 * @str1: extra data
2084
 * @str2: extra data
2085
 * @str3: extra data
2086
 * @str4: extra data
2087
 *
2088
 * Handle a validation error
2089
 */
2090
static void LIBXML_ATTR_FORMAT(6,0)
2091
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2092
      xmlErrorLevel errorLevel,
2093
      int error, xmlNodePtr node, int line, const char *msg,
2094
      const xmlChar *str1, const xmlChar *str2,
2095
      const xmlChar *str3, const xmlChar *str4)
2096
0
{
2097
0
    xmlStructuredErrorFunc schannel = NULL;
2098
0
    xmlGenericErrorFunc channel = NULL;
2099
0
    void *data = NULL;
2100
2101
0
    if (ctxt != NULL) {
2102
0
  if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2103
0
      xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2104
0
      const char *file = NULL;
2105
0
      int col = 0;
2106
0
      if (errorLevel != XML_ERR_WARNING) {
2107
0
    vctxt->nberrors++;
2108
0
    vctxt->err = error;
2109
0
    channel = vctxt->error;
2110
0
      } else {
2111
0
    channel = vctxt->warning;
2112
0
      }
2113
0
      schannel = vctxt->serror;
2114
0
      data = vctxt->errCtxt;
2115
2116
      /*
2117
      * Error node. If we specify a line number, then
2118
      * do not channel any node to the error function.
2119
      */
2120
0
      if (line == 0) {
2121
0
    if ((node == NULL) &&
2122
0
        (vctxt->depth >= 0) &&
2123
0
        (vctxt->inode != NULL)) {
2124
0
        node = vctxt->inode->node;
2125
0
    }
2126
    /*
2127
    * Get filename and line if no node-tree.
2128
    */
2129
0
    if ((node == NULL) &&
2130
0
        (vctxt->parserCtxt != NULL) &&
2131
0
        (vctxt->parserCtxt->input != NULL)) {
2132
0
        file = vctxt->parserCtxt->input->filename;
2133
0
        line = vctxt->parserCtxt->input->line;
2134
0
        col = vctxt->parserCtxt->input->col;
2135
0
    }
2136
0
      } else {
2137
    /*
2138
    * Override the given node's (if any) position
2139
    * and channel only the given line number.
2140
    */
2141
0
    node = NULL;
2142
    /*
2143
    * Get filename.
2144
    */
2145
0
    if (vctxt->doc != NULL)
2146
0
        file = (const char *) vctxt->doc->URL;
2147
0
    else if ((vctxt->parserCtxt != NULL) &&
2148
0
        (vctxt->parserCtxt->input != NULL))
2149
0
        file = vctxt->parserCtxt->input->filename;
2150
0
      }
2151
0
      if (vctxt->locFunc != NULL) {
2152
0
          if ((file == NULL) || (line == 0)) {
2153
0
        unsigned long l;
2154
0
        const char *f;
2155
0
        vctxt->locFunc(vctxt->locCtxt, &f, &l);
2156
0
        if (file == NULL)
2157
0
            file = f;
2158
0
        if (line == 0)
2159
0
            line = (int) l;
2160
0
    }
2161
0
      }
2162
0
      if ((file == NULL) && (vctxt->filename != NULL))
2163
0
          file = vctxt->filename;
2164
2165
0
      __xmlRaiseError(schannel, channel, data, ctxt,
2166
0
    node, XML_FROM_SCHEMASV,
2167
0
    error, errorLevel, file, line,
2168
0
    (const char *) str1, (const char *) str2,
2169
0
    (const char *) str3, 0, col, msg, str1, str2, str3, str4);
2170
2171
0
  } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2172
0
      xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2173
0
      if (errorLevel != XML_ERR_WARNING) {
2174
0
    pctxt->nberrors++;
2175
0
    pctxt->err = error;
2176
0
    channel = pctxt->error;
2177
0
      } else {
2178
0
    channel = pctxt->warning;
2179
0
      }
2180
0
      schannel = pctxt->serror;
2181
0
      data = pctxt->errCtxt;
2182
0
      __xmlRaiseError(schannel, channel, data, ctxt,
2183
0
    node, XML_FROM_SCHEMASP, error,
2184
0
    errorLevel, NULL, 0,
2185
0
    (const char *) str1, (const char *) str2,
2186
0
    (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2187
0
  } else {
2188
0
      TODO
2189
0
  }
2190
0
    }
2191
0
}
2192
2193
/**
2194
 * xmlSchemaErr3:
2195
 * @ctxt: the validation context
2196
 * @node: the context node
2197
 * @error: the error code
2198
 * @msg: the error message
2199
 * @str1: extra data
2200
 * @str2: extra data
2201
 * @str3: extra data
2202
 *
2203
 * Handle a validation error
2204
 */
2205
static void LIBXML_ATTR_FORMAT(4,0)
2206
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2207
        int error, xmlNodePtr node, const char *msg,
2208
        const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2209
0
{
2210
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2211
0
  msg, str1, str2, str3, NULL);
2212
0
}
2213
2214
static void LIBXML_ATTR_FORMAT(4,0)
2215
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2216
        int error, xmlNodePtr node, const char *msg,
2217
        const xmlChar *str1, const xmlChar *str2,
2218
        const xmlChar *str3, const xmlChar *str4)
2219
0
{
2220
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2221
0
  msg, str1, str2, str3, str4);
2222
0
}
2223
2224
static void LIBXML_ATTR_FORMAT(4,0)
2225
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2226
       int error, xmlNodePtr node, const char *msg,
2227
       const xmlChar *str1, const xmlChar *str2)
2228
0
{
2229
0
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2230
0
}
2231
2232
static xmlChar *
2233
xmlSchemaFormatNodeForError(xmlChar ** msg,
2234
          xmlSchemaAbstractCtxtPtr actxt,
2235
          xmlNodePtr node)
2236
0
{
2237
0
    xmlChar *str = NULL;
2238
2239
0
    *msg = NULL;
2240
0
    if ((node != NULL) &&
2241
0
  (node->type != XML_ELEMENT_NODE) &&
2242
0
  (node->type != XML_ATTRIBUTE_NODE))
2243
0
    {
2244
  /*
2245
  * Don't try to format other nodes than element and
2246
  * attribute nodes.
2247
  * Play safe and return an empty string.
2248
  */
2249
0
  *msg = xmlStrdup(BAD_CAST "");
2250
0
  return(*msg);
2251
0
    }
2252
0
    if (node != NULL) {
2253
  /*
2254
  * Work on tree nodes.
2255
  */
2256
0
  if (node->type == XML_ATTRIBUTE_NODE) {
2257
0
      xmlNodePtr elem = node->parent;
2258
2259
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2260
0
      if (elem->ns != NULL)
2261
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2262
0
        elem->ns->href, elem->name));
2263
0
      else
2264
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2265
0
        NULL, elem->name));
2266
0
      FREE_AND_NULL(str);
2267
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2268
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2269
0
  } else {
2270
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2271
0
  }
2272
0
  if (node->ns != NULL)
2273
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2274
0
      node->ns->href, node->name));
2275
0
  else
2276
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2277
0
      NULL, node->name));
2278
0
  FREE_AND_NULL(str);
2279
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2280
0
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2281
0
  xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2282
  /*
2283
  * Work on node infos.
2284
  */
2285
0
  if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2286
0
      xmlSchemaNodeInfoPtr ielem =
2287
0
    vctxt->elemInfos[vctxt->depth];
2288
2289
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2290
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2291
0
    ielem->nsName, ielem->localName));
2292
0
      FREE_AND_NULL(str);
2293
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2294
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2295
0
  } else {
2296
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2297
0
  }
2298
0
  *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2299
0
      vctxt->inode->nsName, vctxt->inode->localName));
2300
0
  FREE_AND_NULL(str);
2301
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2302
0
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2303
  /*
2304
  * Hmm, no node while parsing?
2305
  * Return an empty string, in case NULL will break something.
2306
  */
2307
0
  *msg = xmlStrdup(BAD_CAST "");
2308
0
    } else {
2309
0
  TODO
2310
0
  return (NULL);
2311
0
    }
2312
2313
    /*
2314
     * xmlSchemaFormatItemForReport() also returns an escaped format
2315
     * string, so do this before calling it below (in the future).
2316
     */
2317
0
    xmlEscapeFormatString(msg);
2318
2319
    /*
2320
    * VAL TODO: The output of the given schema component is currently
2321
    * disabled.
2322
    */
2323
#if 0
2324
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2325
  *msg = xmlStrcat(*msg, BAD_CAST " [");
2326
  *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2327
      NULL, type, NULL, 0));
2328
  FREE_AND_NULL(str)
2329
  *msg = xmlStrcat(*msg, BAD_CAST "]");
2330
    }
2331
#endif
2332
0
    return (*msg);
2333
0
}
2334
2335
static void LIBXML_ATTR_FORMAT(3,0)
2336
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2337
         const char *funcName,
2338
         const char *message,
2339
         const xmlChar *str1,
2340
         const xmlChar *str2)
2341
0
{
2342
0
    xmlChar *msg = NULL;
2343
2344
0
    if (actxt == NULL)
2345
0
        return;
2346
0
    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2347
0
    msg = xmlStrcat(msg, BAD_CAST message);
2348
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2349
2350
0
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2351
0
  xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2352
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2353
0
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2354
0
  xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2355
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2356
2357
0
    FREE_AND_NULL(msg)
2358
0
}
2359
2360
static void LIBXML_ATTR_FORMAT(3,0)
2361
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2362
         const char *funcName,
2363
         const char *message)
2364
0
{
2365
0
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2366
0
}
2367
2368
#if 0
2369
static void LIBXML_ATTR_FORMAT(3,0)
2370
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2371
         const char *funcName,
2372
         const char *message,
2373
         const xmlChar *str1,
2374
         const xmlChar *str2)
2375
{
2376
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2377
  str1, str2);
2378
}
2379
#endif
2380
2381
static void LIBXML_ATTR_FORMAT(5,0)
2382
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2383
       xmlParserErrors error,
2384
       xmlNodePtr node,
2385
       xmlSchemaBasicItemPtr item,
2386
       const char *message,
2387
       const xmlChar *str1, const xmlChar *str2,
2388
       const xmlChar *str3, const xmlChar *str4)
2389
0
{
2390
0
    xmlChar *msg = NULL;
2391
2392
0
    if ((node == NULL) && (item != NULL) &&
2393
0
  (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2394
0
  node = WXS_ITEM_NODE(item);
2395
0
  xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2396
0
  msg = xmlStrcat(msg, BAD_CAST ": ");
2397
0
    } else
2398
0
  xmlSchemaFormatNodeForError(&msg, actxt, node);
2399
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2400
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2401
0
    xmlSchemaErr4(actxt, error, node,
2402
0
  (const char *) msg, str1, str2, str3, str4);
2403
0
    FREE_AND_NULL(msg)
2404
0
}
2405
2406
static void LIBXML_ATTR_FORMAT(5,0)
2407
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2408
       xmlParserErrors error,
2409
       xmlNodePtr node,
2410
       xmlSchemaBasicItemPtr item,
2411
       const char *message,
2412
       const xmlChar *str1,
2413
       const xmlChar *str2)
2414
0
{
2415
0
    xmlSchemaCustomErr4(actxt, error, node, item,
2416
0
  message, str1, str2, NULL, NULL);
2417
0
}
2418
2419
2420
2421
static void LIBXML_ATTR_FORMAT(5,0)
2422
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2423
       xmlParserErrors error,
2424
       xmlNodePtr node,
2425
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2426
       const char *message,
2427
       const xmlChar *str1,
2428
       const xmlChar *str2,
2429
       const xmlChar *str3)
2430
0
{
2431
0
    xmlChar *msg = NULL;
2432
2433
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2434
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2435
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2436
2437
    /* URGENT TODO: Set the error code to something sane. */
2438
0
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2439
0
  (const char *) msg, str1, str2, str3, NULL);
2440
2441
0
    FREE_AND_NULL(msg)
2442
0
}
2443
2444
2445
2446
static void LIBXML_ATTR_FORMAT(5,0)
2447
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2448
       xmlParserErrors error,
2449
       xmlSchemaPSVIIDCNodePtr idcNode,
2450
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2451
       const char *message,
2452
       const xmlChar *str1,
2453
       const xmlChar *str2)
2454
0
{
2455
0
    xmlChar *msg = NULL, *qname = NULL;
2456
2457
0
    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2458
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2459
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2460
0
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2461
0
  error, NULL, idcNode->nodeLine, (const char *) msg,
2462
0
  xmlSchemaFormatQName(&qname,
2463
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2464
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2465
0
  str1, str2, NULL);
2466
0
    FREE_AND_NULL(qname);
2467
0
    FREE_AND_NULL(msg);
2468
0
}
2469
2470
static int
2471
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2472
         xmlNodePtr node)
2473
0
{
2474
0
    if (node != NULL)
2475
0
  return (node->type);
2476
0
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2477
0
  (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2478
0
  return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2479
0
    return (-1);
2480
0
}
2481
2482
static int
2483
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2484
0
{
2485
0
    switch (item->type) {
2486
0
  case XML_SCHEMA_TYPE_COMPLEX:
2487
0
  case XML_SCHEMA_TYPE_SIMPLE:
2488
0
      if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2489
0
    return(1);
2490
0
      break;
2491
0
  case XML_SCHEMA_TYPE_GROUP:
2492
0
      return (1);
2493
0
  case XML_SCHEMA_TYPE_ELEMENT:
2494
0
      if ( ((xmlSchemaElementPtr) item)->flags &
2495
0
    XML_SCHEMAS_ELEM_GLOBAL)
2496
0
    return(1);
2497
0
      break;
2498
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
2499
0
      if ( ((xmlSchemaAttributePtr) item)->flags &
2500
0
    XML_SCHEMAS_ATTR_GLOBAL)
2501
0
    return(1);
2502
0
      break;
2503
  /* Note that attribute groups are always global. */
2504
0
  default:
2505
0
      return(1);
2506
0
    }
2507
0
    return (0);
2508
0
}
2509
2510
static void
2511
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2512
           xmlParserErrors error,
2513
           xmlNodePtr node,
2514
           const xmlChar *value,
2515
           xmlSchemaTypePtr type,
2516
           int displayValue)
2517
0
{
2518
0
    xmlChar *msg = NULL;
2519
2520
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2521
2522
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2523
0
      XML_ATTRIBUTE_NODE))
2524
0
  msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2525
0
    else
2526
0
  msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2527
0
      "value of ");
2528
2529
0
    if (! xmlSchemaIsGlobalItem(type))
2530
0
  msg = xmlStrcat(msg, BAD_CAST "the local ");
2531
0
    else
2532
0
  msg = xmlStrcat(msg, BAD_CAST "the ");
2533
2534
0
    if (WXS_IS_ATOMIC(type))
2535
0
  msg = xmlStrcat(msg, BAD_CAST "atomic type");
2536
0
    else if (WXS_IS_LIST(type))
2537
0
  msg = xmlStrcat(msg, BAD_CAST "list type");
2538
0
    else if (WXS_IS_UNION(type))
2539
0
  msg = xmlStrcat(msg, BAD_CAST "union type");
2540
2541
0
    if (xmlSchemaIsGlobalItem(type)) {
2542
0
  xmlChar *str = NULL;
2543
0
  msg = xmlStrcat(msg, BAD_CAST " '");
2544
0
  if (type->builtInType != 0) {
2545
0
      msg = xmlStrcat(msg, BAD_CAST "xs:");
2546
0
      str = xmlStrdup(type->name);
2547
0
  } else {
2548
0
      const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2549
0
      if (!str)
2550
0
    str = xmlStrdup(qName);
2551
0
  }
2552
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2553
0
  msg = xmlStrcat(msg, BAD_CAST "'");
2554
0
  FREE_AND_NULL(str);
2555
0
    }
2556
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2557
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2558
0
      XML_ATTRIBUTE_NODE))
2559
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2560
0
    else
2561
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2562
0
    FREE_AND_NULL(msg)
2563
0
}
2564
2565
static const xmlChar *
2566
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2567
            xmlSchemaNodeInfoPtr ni,
2568
            xmlNodePtr node)
2569
0
{
2570
0
    if (node != NULL) {
2571
0
  if (node->ns != NULL)
2572
0
      return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2573
0
  else
2574
0
      return (xmlSchemaFormatQName(str, NULL, node->name));
2575
0
    } else if (ni != NULL)
2576
0
  return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2577
0
    return (NULL);
2578
0
}
2579
2580
static void
2581
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2582
      xmlParserErrors error,
2583
      xmlSchemaAttrInfoPtr ni,
2584
      xmlNodePtr node)
2585
0
{
2586
0
    xmlChar *msg = NULL, *str = NULL;
2587
2588
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2589
0
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2590
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2591
0
  xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2592
0
  NULL);
2593
0
    FREE_AND_NULL(str)
2594
0
    FREE_AND_NULL(msg)
2595
0
}
2596
2597
static void LIBXML_ATTR_FORMAT(5,0)
2598
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2599
            xmlParserErrors error,
2600
            xmlNodePtr node,
2601
      xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2602
      const char *message,
2603
      int nbval,
2604
      int nbneg,
2605
      xmlChar **values)
2606
0
{
2607
0
    xmlChar *str = NULL, *msg = NULL;
2608
0
    xmlChar *localName, *nsName;
2609
0
    const xmlChar *cur, *end;
2610
0
    int i;
2611
2612
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2613
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2614
0
    msg = xmlStrcat(msg, BAD_CAST ".");
2615
    /*
2616
    * Note that is does not make sense to report that we have a
2617
    * wildcard here, since the wildcard might be unfolded into
2618
    * multiple transitions.
2619
    */
2620
0
    if (nbval + nbneg > 0) {
2621
0
  if (nbval + nbneg > 1) {
2622
0
      str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2623
0
  } else
2624
0
      str = xmlStrdup(BAD_CAST " Expected is ( ");
2625
0
  nsName = NULL;
2626
2627
0
  for (i = 0; i < nbval + nbneg; i++) {
2628
0
      cur = values[i];
2629
0
      if (cur == NULL)
2630
0
          continue;
2631
0
      if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2632
0
          (cur[3] == ' ')) {
2633
0
    cur += 4;
2634
0
    str = xmlStrcat(str, BAD_CAST "##other");
2635
0
      }
2636
      /*
2637
      * Get the local name.
2638
      */
2639
0
      localName = NULL;
2640
2641
0
      end = cur;
2642
0
      if (*end == '*') {
2643
0
    localName = xmlStrdup(BAD_CAST "*");
2644
0
    end++;
2645
0
      } else {
2646
0
    while ((*end != 0) && (*end != '|'))
2647
0
        end++;
2648
0
    localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2649
0
      }
2650
0
      if (*end != 0) {
2651
0
    end++;
2652
    /*
2653
    * Skip "*|*" if they come with negated expressions, since
2654
    * they represent the same negated wildcard.
2655
    */
2656
0
    if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2657
        /*
2658
        * Get the namespace name.
2659
        */
2660
0
        cur = end;
2661
0
        if (*end == '*') {
2662
0
      nsName = xmlStrdup(BAD_CAST "{*}");
2663
0
        } else {
2664
0
      while (*end != 0)
2665
0
          end++;
2666
2667
0
      if (i >= nbval)
2668
0
          nsName = xmlStrdup(BAD_CAST "{##other:");
2669
0
      else
2670
0
          nsName = xmlStrdup(BAD_CAST "{");
2671
2672
0
      nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2673
0
      nsName = xmlStrcat(nsName, BAD_CAST "}");
2674
0
        }
2675
0
        str = xmlStrcat(str, BAD_CAST nsName);
2676
0
        FREE_AND_NULL(nsName)
2677
0
    } else {
2678
0
        FREE_AND_NULL(localName);
2679
0
        continue;
2680
0
    }
2681
0
      }
2682
0
      str = xmlStrcat(str, BAD_CAST localName);
2683
0
      FREE_AND_NULL(localName);
2684
2685
0
      if (i < nbval + nbneg -1)
2686
0
    str = xmlStrcat(str, BAD_CAST ", ");
2687
0
  }
2688
0
  str = xmlStrcat(str, BAD_CAST " ).\n");
2689
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2690
0
  FREE_AND_NULL(str)
2691
0
    } else
2692
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
2693
0
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2694
0
    xmlFree(msg);
2695
0
}
2696
2697
static void LIBXML_ATTR_FORMAT(8,0)
2698
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2699
      xmlParserErrors error,
2700
      xmlNodePtr node,
2701
      const xmlChar *value,
2702
      unsigned long length,
2703
      xmlSchemaTypePtr type,
2704
      xmlSchemaFacetPtr facet,
2705
      const char *message,
2706
      const xmlChar *str1,
2707
      const xmlChar *str2)
2708
0
{
2709
0
    xmlChar *str = NULL, *msg = NULL;
2710
0
    xmlSchemaTypeType facetType;
2711
0
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2712
2713
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2714
0
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2715
0
  facetType = XML_SCHEMA_FACET_ENUMERATION;
2716
  /*
2717
  * If enumerations are validated, one must not expect the
2718
  * facet to be given.
2719
  */
2720
0
    } else
2721
0
  facetType = facet->type;
2722
0
    msg = xmlStrcat(msg, BAD_CAST "[");
2723
0
    msg = xmlStrcat(msg, BAD_CAST "facet '");
2724
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2725
0
    msg = xmlStrcat(msg, BAD_CAST "'] ");
2726
0
    if (message == NULL) {
2727
  /*
2728
  * Use a default message.
2729
  */
2730
0
  if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2731
0
      (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2732
0
      (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2733
2734
0
      char len[25], actLen[25];
2735
2736
      /* FIXME, TODO: What is the max expected string length of the
2737
      * this value?
2738
      */
2739
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2740
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2741
0
      else
2742
0
    msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2743
2744
0
      snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2745
0
      snprintf(actLen, 24, "%lu", length);
2746
2747
0
      if (facetType == XML_SCHEMA_FACET_LENGTH)
2748
0
    msg = xmlStrcat(msg,
2749
0
    BAD_CAST "this differs from the allowed length of '%s'.\n");
2750
0
      else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2751
0
    msg = xmlStrcat(msg,
2752
0
    BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2753
0
      else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2754
0
    msg = xmlStrcat(msg,
2755
0
    BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2756
2757
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2758
0
    xmlSchemaErr3(actxt, error, node, (const char *) msg,
2759
0
        value, (const xmlChar *) actLen, (const xmlChar *) len);
2760
0
      else
2761
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2762
0
        (const xmlChar *) actLen, (const xmlChar *) len);
2763
2764
0
  } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2765
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2766
0
    "of the set {%s}.\n");
2767
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2768
0
    xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2769
0
  } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2770
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2771
0
    "by the pattern '%s'.\n");
2772
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2773
0
    facet->value);
2774
0
  } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2775
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2776
0
    "minimum value allowed ('%s').\n");
2777
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2778
0
    facet->value);
2779
0
  } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2780
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2781
0
    "maximum value allowed ('%s').\n");
2782
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2783
0
    facet->value);
2784
0
  } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2785
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2786
0
    "'%s'.\n");
2787
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2788
0
    facet->value);
2789
0
  } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2790
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2791
0
    "'%s'.\n");
2792
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2793
0
    facet->value);
2794
0
  } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2795
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2796
0
    "digits than are allowed ('%s').\n");
2797
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2798
0
    facet->value);
2799
0
  } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2800
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2801
0
    "digits than are allowed ('%s').\n");
2802
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2803
0
    facet->value);
2804
0
  } else if (nodeType == XML_ATTRIBUTE_NODE) {
2805
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2806
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2807
0
  } else {
2808
0
      msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2809
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2810
0
  }
2811
0
    } else {
2812
0
  msg = xmlStrcat(msg, (const xmlChar *) message);
2813
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
2814
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2815
0
    }
2816
0
    FREE_AND_NULL(str)
2817
0
    xmlFree(msg);
2818
0
}
2819
2820
#define VERROR(err, type, msg) \
2821
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2822
2823
0
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2824
2825
0
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2826
0
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2827
2828
0
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2829
2830
2831
/**
2832
 * xmlSchemaPMissingAttrErr:
2833
 * @ctxt: the schema validation context
2834
 * @ownerItem: the owner as a schema object
2835
 * @ownerElem: the owner as an element node
2836
 * @node: the parent element node of the missing attribute node
2837
 * @type: the corresponding type of the attribute node
2838
 *
2839
 * Reports an illegal attribute.
2840
 */
2841
static void
2842
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2843
       xmlParserErrors error,
2844
       xmlSchemaBasicItemPtr ownerItem,
2845
       xmlNodePtr ownerElem,
2846
       const char *name,
2847
       const char *message)
2848
0
{
2849
0
    xmlChar *des = NULL;
2850
2851
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2852
2853
0
    if (message != NULL)
2854
0
  xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2855
0
    else
2856
0
  xmlSchemaPErr(ctxt, ownerElem, error,
2857
0
      "%s: The attribute '%s' is required but missing.\n",
2858
0
      BAD_CAST des, BAD_CAST name);
2859
0
    FREE_AND_NULL(des);
2860
0
}
2861
2862
2863
/**
2864
 * xmlSchemaPResCompAttrErr:
2865
 * @ctxt: the schema validation context
2866
 * @error: the error code
2867
 * @ownerItem: the owner as a schema object
2868
 * @ownerElem: the owner as an element node
2869
 * @name: the name of the attribute holding the QName
2870
 * @refName: the referenced local name
2871
 * @refURI: the referenced namespace URI
2872
 * @message: optional message
2873
 *
2874
 * Used to report QName attribute values that failed to resolve
2875
 * to schema components.
2876
 */
2877
static void
2878
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2879
       xmlParserErrors error,
2880
       xmlSchemaBasicItemPtr ownerItem,
2881
       xmlNodePtr ownerElem,
2882
       const char *name,
2883
       const xmlChar *refName,
2884
       const xmlChar *refURI,
2885
       xmlSchemaTypeType refType,
2886
       const char *refTypeStr)
2887
0
{
2888
0
    xmlChar *des = NULL, *strA = NULL;
2889
2890
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2891
0
    if (refTypeStr == NULL)
2892
0
  refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2893
0
    xmlSchemaPErrExt(ctxt, ownerElem, error,
2894
0
      NULL, NULL, NULL,
2895
0
      "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2896
0
      "%s.\n", BAD_CAST des, BAD_CAST name,
2897
0
      xmlSchemaFormatQName(&strA, refURI, refName),
2898
0
      BAD_CAST refTypeStr, NULL);
2899
0
    FREE_AND_NULL(des)
2900
0
    FREE_AND_NULL(strA)
2901
0
}
2902
2903
/**
2904
 * xmlSchemaPCustomAttrErr:
2905
 * @ctxt: the schema parser context
2906
 * @error: the error code
2907
 * @ownerDes: the designation of the owner
2908
 * @ownerItem: the owner as a schema object
2909
 * @attr: the illegal attribute node
2910
 *
2911
 * Reports an illegal attribute during the parse.
2912
 */
2913
static void
2914
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2915
      xmlParserErrors error,
2916
      xmlChar **ownerDes,
2917
      xmlSchemaBasicItemPtr ownerItem,
2918
      xmlAttrPtr attr,
2919
      const char *msg)
2920
0
{
2921
0
    xmlChar *des = NULL;
2922
2923
0
    if (ownerDes == NULL)
2924
0
  xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2925
0
    else if (*ownerDes == NULL) {
2926
0
  xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2927
0
  des = *ownerDes;
2928
0
    } else
2929
0
  des = *ownerDes;
2930
0
    if (attr == NULL) {
2931
0
  xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2932
0
      "%s, attribute '%s': %s.\n",
2933
0
      BAD_CAST des, (const xmlChar *) "Unknown",
2934
0
      (const xmlChar *) msg, NULL, NULL);
2935
0
    } else {
2936
0
  xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2937
0
      "%s, attribute '%s': %s.\n",
2938
0
      BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2939
0
    }
2940
0
    if (ownerDes == NULL)
2941
0
  FREE_AND_NULL(des);
2942
0
}
2943
2944
/**
2945
 * xmlSchemaPIllegalAttrErr:
2946
 * @ctxt: the schema parser context
2947
 * @error: the error code
2948
 * @ownerItem: the attribute's owner item
2949
 * @attr: the illegal attribute node
2950
 *
2951
 * Reports an illegal attribute during the parse.
2952
 */
2953
static void
2954
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2955
       xmlParserErrors error,
2956
       xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2957
       xmlAttrPtr attr)
2958
0
{
2959
0
    xmlChar *strA = NULL, *strB = NULL;
2960
2961
0
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2962
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2963
0
  "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2964
0
  xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2965
0
  NULL, NULL);
2966
0
    FREE_AND_NULL(strA);
2967
0
    FREE_AND_NULL(strB);
2968
0
}
2969
2970
/**
2971
 * xmlSchemaPCustomErr:
2972
 * @ctxt: the schema parser context
2973
 * @error: the error code
2974
 * @itemDes: the designation of the schema item
2975
 * @item: the schema item
2976
 * @itemElem: the node of the schema item
2977
 * @message: the error message
2978
 * @str1: an optional param for the error message
2979
 * @str2: an optional param for the error message
2980
 * @str3: an optional param for the error message
2981
 *
2982
 * Reports an error during parsing.
2983
 */
2984
static void LIBXML_ATTR_FORMAT(5,0)
2985
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2986
        xmlParserErrors error,
2987
        xmlSchemaBasicItemPtr item,
2988
        xmlNodePtr itemElem,
2989
        const char *message,
2990
        const xmlChar *str1,
2991
        const xmlChar *str2,
2992
        const xmlChar *str3)
2993
0
{
2994
0
    xmlChar *des = NULL, *msg = NULL;
2995
2996
0
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
2997
0
    msg = xmlStrdup(BAD_CAST "%s: ");
2998
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2999
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3000
0
    if ((itemElem == NULL) && (item != NULL))
3001
0
  itemElem = WXS_ITEM_NODE(item);
3002
0
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3003
0
  (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3004
0
    FREE_AND_NULL(des);
3005
0
    FREE_AND_NULL(msg);
3006
0
}
3007
3008
/**
3009
 * xmlSchemaPCustomErr:
3010
 * @ctxt: the schema parser context
3011
 * @error: the error code
3012
 * @itemDes: the designation of the schema item
3013
 * @item: the schema item
3014
 * @itemElem: the node of the schema item
3015
 * @message: the error message
3016
 * @str1: the optional param for the error message
3017
 *
3018
 * Reports an error during parsing.
3019
 */
3020
static void LIBXML_ATTR_FORMAT(5,0)
3021
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3022
        xmlParserErrors error,
3023
        xmlSchemaBasicItemPtr item,
3024
        xmlNodePtr itemElem,
3025
        const char *message,
3026
        const xmlChar *str1)
3027
0
{
3028
0
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3029
0
  str1, NULL, NULL);
3030
0
}
3031
3032
/**
3033
 * xmlSchemaPAttrUseErr:
3034
 * @ctxt: the schema parser context
3035
 * @error: the error code
3036
 * @itemDes: the designation of the schema type
3037
 * @item: the schema type
3038
 * @itemElem: the node of the schema type
3039
 * @attr: the invalid schema attribute
3040
 * @message: the error message
3041
 * @str1: the optional param for the error message
3042
 *
3043
 * Reports an attribute use error during parsing.
3044
 */
3045
static void LIBXML_ATTR_FORMAT(6,0)
3046
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3047
        xmlParserErrors error,
3048
        xmlNodePtr node,
3049
        xmlSchemaBasicItemPtr ownerItem,
3050
        const xmlSchemaAttributeUsePtr attruse,
3051
        const char *message,
3052
        const xmlChar *str1, const xmlChar *str2,
3053
        const xmlChar *str3,const xmlChar *str4)
3054
0
{
3055
0
    xmlChar *str = NULL, *msg = NULL;
3056
3057
0
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3058
0
    msg = xmlStrcat(msg, BAD_CAST ", ");
3059
0
    msg = xmlStrcat(msg,
3060
0
  BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3061
0
  WXS_BASIC_CAST attruse, NULL));
3062
0
    FREE_AND_NULL(str);
3063
0
    msg = xmlStrcat(msg, BAD_CAST ": ");
3064
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3065
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3066
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3067
0
  (const char *) msg, str1, str2, str3, str4);
3068
0
    xmlFree(msg);
3069
0
}
3070
3071
/**
3072
 * xmlSchemaPIllegalFacetAtomicErr:
3073
 * @ctxt: the schema parser context
3074
 * @error: the error code
3075
 * @type: the schema type
3076
 * @baseType: the base type of type
3077
 * @facet: the illegal facet
3078
 *
3079
 * Reports an illegal facet for atomic simple types.
3080
 */
3081
static void
3082
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3083
        xmlParserErrors error,
3084
        xmlSchemaTypePtr type,
3085
        xmlSchemaTypePtr baseType,
3086
        xmlSchemaFacetPtr facet)
3087
0
{
3088
0
    xmlChar *des = NULL, *strT = NULL;
3089
3090
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3091
0
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3092
0
  "%s: The facet '%s' is not allowed on types derived from the "
3093
0
  "type %s.\n",
3094
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3095
0
  xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3096
0
  NULL, NULL);
3097
0
    FREE_AND_NULL(des);
3098
0
    FREE_AND_NULL(strT);
3099
0
}
3100
3101
/**
3102
 * xmlSchemaPIllegalFacetListUnionErr:
3103
 * @ctxt: the schema parser context
3104
 * @error: the error code
3105
 * @itemDes: the designation of the schema item involved
3106
 * @item: the schema item involved
3107
 * @facet: the illegal facet
3108
 *
3109
 * Reports an illegal facet for <list> and <union>.
3110
 */
3111
static void
3112
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3113
        xmlParserErrors error,
3114
        xmlSchemaTypePtr type,
3115
        xmlSchemaFacetPtr facet)
3116
0
{
3117
0
    xmlChar *des = NULL;
3118
3119
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3120
0
  type->node);
3121
0
    xmlSchemaPErr(ctxt, type->node, error,
3122
0
  "%s: The facet '%s' is not allowed.\n",
3123
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3124
0
    FREE_AND_NULL(des);
3125
0
}
3126
3127
/**
3128
 * xmlSchemaPMutualExclAttrErr:
3129
 * @ctxt: the schema validation context
3130
 * @error: the error code
3131
 * @elemDes: the designation of the parent element node
3132
 * @attr: the bad attribute node
3133
 * @type: the corresponding type of the attribute node
3134
 *
3135
 * Reports an illegal attribute.
3136
 */
3137
static void
3138
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3139
       xmlParserErrors error,
3140
       xmlSchemaBasicItemPtr ownerItem,
3141
       xmlAttrPtr attr,
3142
       const char *name1,
3143
       const char *name2)
3144
0
{
3145
0
    xmlChar *des = NULL;
3146
3147
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3148
0
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3149
0
  "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3150
0
  BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3151
0
    FREE_AND_NULL(des);
3152
0
}
3153
3154
/**
3155
 * xmlSchemaPSimpleTypeErr:
3156
 * @ctxt:  the schema validation context
3157
 * @error: the error code
3158
 * @type: the type specifier
3159
 * @ownerItem: the schema object if existent
3160
 * @node: the validated node
3161
 * @value: the validated value
3162
 *
3163
 * Reports a simple type validation error.
3164
 * TODO: Should this report the value of an element as well?
3165
 */
3166
static void LIBXML_ATTR_FORMAT(8,0)
3167
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3168
      xmlParserErrors error,
3169
      xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3170
      xmlNodePtr node,
3171
      xmlSchemaTypePtr type,
3172
      const char *expected,
3173
      const xmlChar *value,
3174
      const char *message,
3175
      const xmlChar *str1,
3176
      const xmlChar *str2)
3177
0
{
3178
0
    xmlChar *msg = NULL;
3179
3180
0
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3181
0
    if (message == NULL) {
3182
  /*
3183
  * Use default messages.
3184
  */
3185
0
  if (type != NULL) {
3186
0
      if (node->type == XML_ATTRIBUTE_NODE)
3187
0
    msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3188
0
      else
3189
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3190
0
    "valid value of ");
3191
0
      if (! xmlSchemaIsGlobalItem(type))
3192
0
    msg = xmlStrcat(msg, BAD_CAST "the local ");
3193
0
      else
3194
0
    msg = xmlStrcat(msg, BAD_CAST "the ");
3195
3196
0
      if (WXS_IS_ATOMIC(type))
3197
0
    msg = xmlStrcat(msg, BAD_CAST "atomic type");
3198
0
      else if (WXS_IS_LIST(type))
3199
0
    msg = xmlStrcat(msg, BAD_CAST "list type");
3200
0
      else if (WXS_IS_UNION(type))
3201
0
    msg = xmlStrcat(msg, BAD_CAST "union type");
3202
3203
0
      if (xmlSchemaIsGlobalItem(type)) {
3204
0
    xmlChar *str = NULL;
3205
0
    msg = xmlStrcat(msg, BAD_CAST " '");
3206
0
    if (type->builtInType != 0) {
3207
0
        msg = xmlStrcat(msg, BAD_CAST "xs:");
3208
0
        str = xmlStrdup(type->name);
3209
0
    } else {
3210
0
        const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3211
0
        if (!str)
3212
0
      str = xmlStrdup(qName);
3213
0
    }
3214
0
    msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3215
0
    msg = xmlStrcat(msg, BAD_CAST "'.");
3216
0
    FREE_AND_NULL(str);
3217
0
      }
3218
0
  } else {
3219
0
      if (node->type == XML_ATTRIBUTE_NODE)
3220
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3221
0
      else
3222
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3223
0
    "valid.");
3224
0
  }
3225
0
  if (expected) {
3226
0
      xmlChar *expectedEscaped = xmlCharStrdup(expected);
3227
0
      msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3228
0
      msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3229
0
      FREE_AND_NULL(expectedEscaped);
3230
0
      msg = xmlStrcat(msg, BAD_CAST "'.\n");
3231
0
  } else
3232
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
3233
0
  if (node->type == XML_ATTRIBUTE_NODE)
3234
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3235
0
  else
3236
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3237
0
    } else {
3238
0
  msg = xmlStrcat(msg, BAD_CAST message);
3239
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
3240
0
  xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3241
0
       (const char*) msg, str1, str2, NULL, NULL, NULL);
3242
0
    }
3243
    /* Cleanup. */
3244
0
    FREE_AND_NULL(msg)
3245
0
}
3246
3247
/**
3248
 * xmlSchemaPContentErr:
3249
 * @ctxt: the schema parser context
3250
 * @error: the error code
3251
 * @ownerItem: the owner item of the holder of the content
3252
 * @ownerElem: the node of the holder of the content
3253
 * @child: the invalid child node
3254
 * @message: the optional error message
3255
 * @content: the optional string describing the correct content
3256
 *
3257
 * Reports an error concerning the content of a schema element.
3258
 */
3259
static void
3260
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3261
         xmlParserErrors error,
3262
         xmlSchemaBasicItemPtr ownerItem,
3263
         xmlNodePtr ownerElem,
3264
         xmlNodePtr child,
3265
         const char *message,
3266
         const char *content)
3267
0
{
3268
0
    xmlChar *des = NULL;
3269
3270
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3271
0
    if (message != NULL)
3272
0
  xmlSchemaPErr2(ctxt, ownerElem, child, error,
3273
0
      "%s: %s.\n",
3274
0
      BAD_CAST des, BAD_CAST message);
3275
0
    else {
3276
0
  if (content != NULL) {
3277
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3278
0
    "%s: The content is not valid. Expected is %s.\n",
3279
0
    BAD_CAST des, BAD_CAST content);
3280
0
  } else {
3281
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3282
0
    "%s: The content is not valid.\n",
3283
0
    BAD_CAST des, NULL);
3284
0
  }
3285
0
    }
3286
0
    FREE_AND_NULL(des)
3287
0
}
3288
3289
/************************************************************************
3290
 *                  *
3291
 *      Streamable error functions                      *
3292
 *                  *
3293
 ************************************************************************/
3294
3295
3296
3297
3298
/************************************************************************
3299
 *                  *
3300
 *      Validation helper functions     *
3301
 *                  *
3302
 ************************************************************************/
3303
3304
3305
/************************************************************************
3306
 *                  *
3307
 *      Allocation functions        *
3308
 *                  *
3309
 ************************************************************************/
3310
3311
/**
3312
 * xmlSchemaNewSchemaForParserCtxt:
3313
 * @ctxt:  a schema validation context
3314
 *
3315
 * Allocate a new Schema structure.
3316
 *
3317
 * Returns the newly allocated structure or NULL in case or error
3318
 */
3319
static xmlSchemaPtr
3320
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3321
0
{
3322
0
    xmlSchemaPtr ret;
3323
3324
0
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3325
0
    if (ret == NULL) {
3326
0
        xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
3327
0
        return (NULL);
3328
0
    }
3329
0
    memset(ret, 0, sizeof(xmlSchema));
3330
0
    ret->dict = ctxt->dict;
3331
0
    xmlDictReference(ret->dict);
3332
3333
0
    return (ret);
3334
0
}
3335
3336
/**
3337
 * xmlSchemaNewFacet:
3338
 *
3339
 * Allocate a new Facet structure.
3340
 *
3341
 * Returns the newly allocated structure or NULL in case or error
3342
 */
3343
xmlSchemaFacetPtr
3344
xmlSchemaNewFacet(void)
3345
0
{
3346
0
    xmlSchemaFacetPtr ret;
3347
3348
0
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3349
0
    if (ret == NULL) {
3350
0
        return (NULL);
3351
0
    }
3352
0
    memset(ret, 0, sizeof(xmlSchemaFacet));
3353
3354
0
    return (ret);
3355
0
}
3356
3357
/**
3358
 * xmlSchemaNewAnnot:
3359
 * @ctxt:  a schema validation context
3360
 * @node:  a node
3361
 *
3362
 * Allocate a new annotation structure.
3363
 *
3364
 * Returns the newly allocated structure or NULL in case or error
3365
 */
3366
static xmlSchemaAnnotPtr
3367
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3368
0
{
3369
0
    xmlSchemaAnnotPtr ret;
3370
3371
0
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3372
0
    if (ret == NULL) {
3373
0
        xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3374
0
        return (NULL);
3375
0
    }
3376
0
    memset(ret, 0, sizeof(xmlSchemaAnnot));
3377
0
    ret->content = node;
3378
0
    return (ret);
3379
0
}
3380
3381
static xmlSchemaItemListPtr
3382
xmlSchemaItemListCreate(void)
3383
0
{
3384
0
    xmlSchemaItemListPtr ret;
3385
3386
0
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3387
0
    if (ret == NULL) {
3388
0
  xmlSchemaPErrMemory(NULL,
3389
0
      "allocating an item list structure", NULL);
3390
0
  return (NULL);
3391
0
    }
3392
0
    memset(ret, 0, sizeof(xmlSchemaItemList));
3393
0
    return (ret);
3394
0
}
3395
3396
static void
3397
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3398
0
{
3399
0
    if (list->items != NULL) {
3400
0
  xmlFree(list->items);
3401
0
  list->items = NULL;
3402
0
    }
3403
0
    list->nbItems = 0;
3404
0
    list->sizeItems = 0;
3405
0
}
3406
3407
static int
3408
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3409
0
{
3410
0
    if (list->items == NULL) {
3411
0
  list->items = (void **) xmlMalloc(
3412
0
      20 * sizeof(void *));
3413
0
  if (list->items == NULL) {
3414
0
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3415
0
      return(-1);
3416
0
  }
3417
0
  list->sizeItems = 20;
3418
0
    } else if (list->sizeItems <= list->nbItems) {
3419
0
  list->sizeItems *= 2;
3420
0
  list->items = (void **) xmlRealloc(list->items,
3421
0
      list->sizeItems * sizeof(void *));
3422
0
  if (list->items == NULL) {
3423
0
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3424
0
      list->sizeItems = 0;
3425
0
      return(-1);
3426
0
  }
3427
0
    }
3428
0
    list->items[list->nbItems++] = item;
3429
0
    return(0);
3430
0
}
3431
3432
static int
3433
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3434
       int initialSize,
3435
       void *item)
3436
0
{
3437
0
    if (list->items == NULL) {
3438
0
  if (initialSize <= 0)
3439
0
      initialSize = 1;
3440
0
  list->items = (void **) xmlMalloc(
3441
0
      initialSize * sizeof(void *));
3442
0
  if (list->items == NULL) {
3443
0
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3444
0
      return(-1);
3445
0
  }
3446
0
  list->sizeItems = initialSize;
3447
0
    } else if (list->sizeItems <= list->nbItems) {
3448
0
  list->sizeItems *= 2;
3449
0
  list->items = (void **) xmlRealloc(list->items,
3450
0
      list->sizeItems * sizeof(void *));
3451
0
  if (list->items == NULL) {
3452
0
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3453
0
      list->sizeItems = 0;
3454
0
      return(-1);
3455
0
  }
3456
0
    }
3457
0
    list->items[list->nbItems++] = item;
3458
0
    return(0);
3459
0
}
3460
3461
static int
3462
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3463
0
{
3464
0
    if (list->items == NULL) {
3465
0
  list->items = (void **) xmlMalloc(
3466
0
      20 * sizeof(void *));
3467
0
  if (list->items == NULL) {
3468
0
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3469
0
      return(-1);
3470
0
  }
3471
0
  list->sizeItems = 20;
3472
0
    } else if (list->sizeItems <= list->nbItems) {
3473
0
  list->sizeItems *= 2;
3474
0
  list->items = (void **) xmlRealloc(list->items,
3475
0
      list->sizeItems * sizeof(void *));
3476
0
  if (list->items == NULL) {
3477
0
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3478
0
      list->sizeItems = 0;
3479
0
      return(-1);
3480
0
  }
3481
0
    }
3482
    /*
3483
    * Just append if the index is greater/equal than the item count.
3484
    */
3485
0
    if (idx >= list->nbItems) {
3486
0
  list->items[list->nbItems++] = item;
3487
0
    } else {
3488
0
  int i;
3489
0
  for (i = list->nbItems; i > idx; i--)
3490
0
      list->items[i] = list->items[i-1];
3491
0
  list->items[idx] = item;
3492
0
  list->nbItems++;
3493
0
    }
3494
0
    return(0);
3495
0
}
3496
3497
#if 0 /* enable if ever needed */
3498
static int
3499
xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3500
          int initialSize,
3501
          void *item,
3502
          int idx)
3503
{
3504
    if (list->items == NULL) {
3505
  if (initialSize <= 0)
3506
      initialSize = 1;
3507
  list->items = (void **) xmlMalloc(
3508
      initialSize * sizeof(void *));
3509
  if (list->items == NULL) {
3510
      xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3511
      return(-1);
3512
  }
3513
  list->sizeItems = initialSize;
3514
    } else if (list->sizeItems <= list->nbItems) {
3515
  list->sizeItems *= 2;
3516
  list->items = (void **) xmlRealloc(list->items,
3517
      list->sizeItems * sizeof(void *));
3518
  if (list->items == NULL) {
3519
      xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3520
      list->sizeItems = 0;
3521
      return(-1);
3522
  }
3523
    }
3524
    /*
3525
    * Just append if the index is greater/equal than the item count.
3526
    */
3527
    if (idx >= list->nbItems) {
3528
  list->items[list->nbItems++] = item;
3529
    } else {
3530
  int i;
3531
  for (i = list->nbItems; i > idx; i--)
3532
      list->items[i] = list->items[i-1];
3533
  list->items[idx] = item;
3534
  list->nbItems++;
3535
    }
3536
    return(0);
3537
}
3538
#endif
3539
3540
static int
3541
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3542
0
{
3543
0
    int i;
3544
0
    if ((list->items == NULL) || (idx >= list->nbItems)) {
3545
0
  xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3546
0
      "index error.\n");
3547
0
  return(-1);
3548
0
    }
3549
3550
0
    if (list->nbItems == 1) {
3551
  /* TODO: Really free the list? */
3552
0
  xmlFree(list->items);
3553
0
  list->items = NULL;
3554
0
  list->nbItems = 0;
3555
0
  list->sizeItems = 0;
3556
0
    } else if (list->nbItems -1 == idx) {
3557
0
  list->nbItems--;
3558
0
    } else {
3559
0
  for (i = idx; i < list->nbItems -1; i++)
3560
0
      list->items[i] = list->items[i+1];
3561
0
  list->nbItems--;
3562
0
    }
3563
0
    return(0);
3564
0
}
3565
3566
/**
3567
 * xmlSchemaItemListFree:
3568
 * @annot:  a schema type structure
3569
 *
3570
 * Deallocate a annotation structure
3571
 */
3572
static void
3573
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3574
0
{
3575
0
    if (list == NULL)
3576
0
  return;
3577
0
    if (list->items != NULL)
3578
0
  xmlFree(list->items);
3579
0
    xmlFree(list);
3580
0
}
3581
3582
static void
3583
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3584
0
{
3585
0
    if (bucket == NULL)
3586
0
  return;
3587
0
    if (bucket->globals != NULL) {
3588
0
  xmlSchemaComponentListFree(bucket->globals);
3589
0
  xmlSchemaItemListFree(bucket->globals);
3590
0
    }
3591
0
    if (bucket->locals != NULL) {
3592
0
  xmlSchemaComponentListFree(bucket->locals);
3593
0
  xmlSchemaItemListFree(bucket->locals);
3594
0
    }
3595
0
    if (bucket->relations != NULL) {
3596
0
  xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3597
0
  do {
3598
0
      prev = cur;
3599
0
      cur = cur->next;
3600
0
      xmlFree(prev);
3601
0
  } while (cur != NULL);
3602
0
    }
3603
0
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3604
0
  xmlFreeDoc(bucket->doc);
3605
0
    }
3606
0
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3607
0
  if (WXS_IMPBUCKET(bucket)->schema != NULL)
3608
0
      xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3609
0
    }
3610
0
    xmlFree(bucket);
3611
0
}
3612
3613
static void
3614
xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3615
0
{
3616
0
    xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3617
0
}
3618
3619
static xmlSchemaBucketPtr
3620
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3621
       int type, const xmlChar *targetNamespace)
3622
0
{
3623
0
    xmlSchemaBucketPtr ret;
3624
0
    int size;
3625
0
    xmlSchemaPtr mainSchema;
3626
3627
0
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3628
0
  PERROR_INT("xmlSchemaBucketCreate",
3629
0
      "no main schema on constructor");
3630
0
  return(NULL);
3631
0
    }
3632
0
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3633
    /* Create the schema bucket. */
3634
0
    if (WXS_IS_BUCKET_INCREDEF(type))
3635
0
  size = sizeof(xmlSchemaInclude);
3636
0
    else
3637
0
  size = sizeof(xmlSchemaImport);
3638
0
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3639
0
    if (ret == NULL) {
3640
0
  xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
3641
0
  return(NULL);
3642
0
    }
3643
0
    memset(ret, 0, size);
3644
0
    ret->targetNamespace = targetNamespace;
3645
0
    ret->type = type;
3646
0
    ret->globals = xmlSchemaItemListCreate();
3647
0
    if (ret->globals == NULL) {
3648
0
  xmlFree(ret);
3649
0
  return(NULL);
3650
0
    }
3651
0
    ret->locals = xmlSchemaItemListCreate();
3652
0
    if (ret->locals == NULL) {
3653
0
  xmlFree(ret);
3654
0
  return(NULL);
3655
0
    }
3656
    /*
3657
    * The following will assure that only the first bucket is marked as
3658
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3659
    * For each following import buckets an xmlSchema will be created.
3660
    * An xmlSchema will be created for every distinct targetNamespace.
3661
    * We assign the targetNamespace to the schemata here.
3662
    */
3663
0
    if (! WXS_HAS_BUCKETS(pctxt)) {
3664
0
  if (WXS_IS_BUCKET_INCREDEF(type)) {
3665
0
      PERROR_INT("xmlSchemaBucketCreate",
3666
0
    "first bucket but it's an include or redefine");
3667
0
      xmlSchemaBucketFree(ret);
3668
0
      return(NULL);
3669
0
  }
3670
  /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3671
0
  ret->type = XML_SCHEMA_SCHEMA_MAIN;
3672
  /* Point to the *main* schema. */
3673
0
  WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3674
0
  WXS_IMPBUCKET(ret)->schema = mainSchema;
3675
  /*
3676
  * Ensure that the main schema gets a targetNamespace.
3677
  */
3678
0
  mainSchema->targetNamespace = targetNamespace;
3679
0
    } else {
3680
0
  if (type == XML_SCHEMA_SCHEMA_MAIN) {
3681
0
      PERROR_INT("xmlSchemaBucketCreate",
3682
0
    "main bucket but it's not the first one");
3683
0
      xmlSchemaBucketFree(ret);
3684
0
      return(NULL);
3685
0
  } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3686
      /*
3687
      * Create a schema for imports and assign the
3688
      * targetNamespace.
3689
      */
3690
0
      WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3691
0
      if (WXS_IMPBUCKET(ret)->schema == NULL) {
3692
0
    xmlSchemaBucketFree(ret);
3693
0
    return(NULL);
3694
0
      }
3695
0
      WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3696
0
  }
3697
0
    }
3698
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3699
0
  int res;
3700
  /*
3701
  * Imports go into the "schemasImports" slot of the main *schema*.
3702
  * Note that we create an import entry for the main schema as well; i.e.,
3703
  * even if there's only one schema, we'll get an import.
3704
  */
3705
0
  if (mainSchema->schemasImports == NULL) {
3706
0
      mainSchema->schemasImports = xmlHashCreateDict(5,
3707
0
    WXS_CONSTRUCTOR(pctxt)->dict);
3708
0
      if (mainSchema->schemasImports == NULL) {
3709
0
    xmlSchemaBucketFree(ret);
3710
0
    return(NULL);
3711
0
      }
3712
0
  }
3713
0
  if (targetNamespace == NULL)
3714
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3715
0
    XML_SCHEMAS_NO_NAMESPACE, ret);
3716
0
  else
3717
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3718
0
    targetNamespace, ret);
3719
0
  if (res != 0) {
3720
0
      PERROR_INT("xmlSchemaBucketCreate",
3721
0
    "failed to add the schema bucket to the hash");
3722
0
      xmlSchemaBucketFree(ret);
3723
0
      return(NULL);
3724
0
  }
3725
0
    } else {
3726
  /* Set the @ownerImport of an include bucket. */
3727
0
  if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3728
0
      WXS_INCBUCKET(ret)->ownerImport =
3729
0
    WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3730
0
  else
3731
0
      WXS_INCBUCKET(ret)->ownerImport =
3732
0
    WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3733
3734
  /* Includes got into the "includes" slot of the *main* schema. */
3735
0
  if (mainSchema->includes == NULL) {
3736
0
      mainSchema->includes = xmlSchemaItemListCreate();
3737
0
      if (mainSchema->includes == NULL) {
3738
0
    xmlSchemaBucketFree(ret);
3739
0
    return(NULL);
3740
0
      }
3741
0
  }
3742
0
  xmlSchemaItemListAdd(mainSchema->includes, ret);
3743
0
    }
3744
    /*
3745
    * Add to list of all buckets; this is used for lookup
3746
    * during schema construction time only.
3747
    */
3748
0
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3749
0
  return(NULL);
3750
0
    return(ret);
3751
0
}
3752
3753
static int
3754
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3755
0
{
3756
0
    if (*list == NULL) {
3757
0
  *list = xmlSchemaItemListCreate();
3758
0
  if (*list == NULL)
3759
0
      return(-1);
3760
0
    }
3761
0
    xmlSchemaItemListAddSize(*list, initialSize, item);
3762
0
    return(0);
3763
0
}
3764
3765
/**
3766
 * xmlSchemaFreeAnnot:
3767
 * @annot:  a schema type structure
3768
 *
3769
 * Deallocate a annotation structure
3770
 */
3771
static void
3772
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3773
0
{
3774
0
    if (annot == NULL)
3775
0
        return;
3776
0
    if (annot->next == NULL) {
3777
0
  xmlFree(annot);
3778
0
    } else {
3779
0
  xmlSchemaAnnotPtr prev;
3780
3781
0
  do {
3782
0
      prev = annot;
3783
0
      annot = annot->next;
3784
0
      xmlFree(prev);
3785
0
  } while (annot != NULL);
3786
0
    }
3787
0
}
3788
3789
/**
3790
 * xmlSchemaFreeNotation:
3791
 * @schema:  a schema notation structure
3792
 *
3793
 * Deallocate a Schema Notation structure.
3794
 */
3795
static void
3796
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3797
0
{
3798
0
    if (nota == NULL)
3799
0
        return;
3800
0
    xmlFree(nota);
3801
0
}
3802
3803
/**
3804
 * xmlSchemaFreeAttribute:
3805
 * @attr:  an attribute declaration
3806
 *
3807
 * Deallocates an attribute declaration structure.
3808
 */
3809
static void
3810
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3811
0
{
3812
0
    if (attr == NULL)
3813
0
        return;
3814
0
    if (attr->annot != NULL)
3815
0
  xmlSchemaFreeAnnot(attr->annot);
3816
0
    if (attr->defVal != NULL)
3817
0
  xmlSchemaFreeValue(attr->defVal);
3818
0
    xmlFree(attr);
3819
0
}
3820
3821
/**
3822
 * xmlSchemaFreeAttributeUse:
3823
 * @use:  an attribute use
3824
 *
3825
 * Deallocates an attribute use structure.
3826
 */
3827
static void
3828
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3829
0
{
3830
0
    if (use == NULL)
3831
0
        return;
3832
0
    if (use->annot != NULL)
3833
0
  xmlSchemaFreeAnnot(use->annot);
3834
0
    if (use->defVal != NULL)
3835
0
  xmlSchemaFreeValue(use->defVal);
3836
0
    xmlFree(use);
3837
0
}
3838
3839
/**
3840
 * xmlSchemaFreeAttributeUseProhib:
3841
 * @prohib:  an attribute use prohibition
3842
 *
3843
 * Deallocates an attribute use structure.
3844
 */
3845
static void
3846
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3847
0
{
3848
0
    if (prohib == NULL)
3849
0
        return;
3850
0
    xmlFree(prohib);
3851
0
}
3852
3853
/**
3854
 * xmlSchemaFreeWildcardNsSet:
3855
 * set:  a schema wildcard namespace
3856
 *
3857
 * Deallocates a list of wildcard constraint structures.
3858
 */
3859
static void
3860
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3861
0
{
3862
0
    xmlSchemaWildcardNsPtr next;
3863
3864
0
    while (set != NULL) {
3865
0
  next = set->next;
3866
0
  xmlFree(set);
3867
0
  set = next;
3868
0
    }
3869
0
}
3870
3871
/**
3872
 * xmlSchemaFreeWildcard:
3873
 * @wildcard:  a wildcard structure
3874
 *
3875
 * Deallocates a wildcard structure.
3876
 */
3877
void
3878
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3879
0
{
3880
0
    if (wildcard == NULL)
3881
0
        return;
3882
0
    if (wildcard->annot != NULL)
3883
0
        xmlSchemaFreeAnnot(wildcard->annot);
3884
0
    if (wildcard->nsSet != NULL)
3885
0
  xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3886
0
    if (wildcard->negNsSet != NULL)
3887
0
  xmlFree(wildcard->negNsSet);
3888
0
    xmlFree(wildcard);
3889
0
}
3890
3891
/**
3892
 * xmlSchemaFreeAttributeGroup:
3893
 * @schema:  a schema attribute group structure
3894
 *
3895
 * Deallocate a Schema Attribute Group structure.
3896
 */
3897
static void
3898
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3899
0
{
3900
0
    if (attrGr == NULL)
3901
0
        return;
3902
0
    if (attrGr->annot != NULL)
3903
0
        xmlSchemaFreeAnnot(attrGr->annot);
3904
0
    if (attrGr->attrUses != NULL)
3905
0
  xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3906
0
    xmlFree(attrGr);
3907
0
}
3908
3909
/**
3910
 * xmlSchemaFreeQNameRef:
3911
 * @item: a QName reference structure
3912
 *
3913
 * Deallocatea a QName reference structure.
3914
 */
3915
static void
3916
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3917
0
{
3918
0
    xmlFree(item);
3919
0
}
3920
3921
/**
3922
 * xmlSchemaFreeTypeLinkList:
3923
 * @alink: a type link
3924
 *
3925
 * Deallocate a list of types.
3926
 */
3927
static void
3928
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3929
0
{
3930
0
    xmlSchemaTypeLinkPtr next;
3931
3932
0
    while (link != NULL) {
3933
0
  next = link->next;
3934
0
  xmlFree(link);
3935
0
  link = next;
3936
0
    }
3937
0
}
3938
3939
static void
3940
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3941
0
{
3942
0
    xmlSchemaIDCStateObjPtr next;
3943
0
    while (sto != NULL) {
3944
0
  next = sto->next;
3945
0
  if (sto->history != NULL)
3946
0
      xmlFree(sto->history);
3947
0
  if (sto->xpathCtxt != NULL)
3948
0
      xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3949
0
  xmlFree(sto);
3950
0
  sto = next;
3951
0
    }
3952
0
}
3953
3954
/**
3955
 * xmlSchemaFreeIDC:
3956
 * @idc: a identity-constraint definition
3957
 *
3958
 * Deallocates an identity-constraint definition.
3959
 */
3960
static void
3961
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3962
0
{
3963
0
    xmlSchemaIDCSelectPtr cur, prev;
3964
3965
0
    if (idcDef == NULL)
3966
0
  return;
3967
0
    if (idcDef->annot != NULL)
3968
0
        xmlSchemaFreeAnnot(idcDef->annot);
3969
    /* Selector */
3970
0
    if (idcDef->selector != NULL) {
3971
0
  if (idcDef->selector->xpathComp != NULL)
3972
0
      xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3973
0
  xmlFree(idcDef->selector);
3974
0
    }
3975
    /* Fields */
3976
0
    if (idcDef->fields != NULL) {
3977
0
  cur = idcDef->fields;
3978
0
  do {
3979
0
      prev = cur;
3980
0
      cur = cur->next;
3981
0
      if (prev->xpathComp != NULL)
3982
0
    xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3983
0
      xmlFree(prev);
3984
0
  } while (cur != NULL);
3985
0
    }
3986
0
    xmlFree(idcDef);
3987
0
}
3988
3989
/**
3990
 * xmlSchemaFreeElement:
3991
 * @schema:  a schema element structure
3992
 *
3993
 * Deallocate a Schema Element structure.
3994
 */
3995
static void
3996
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3997
0
{
3998
0
    if (elem == NULL)
3999
0
        return;
4000
0
    if (elem->annot != NULL)
4001
0
        xmlSchemaFreeAnnot(elem->annot);
4002
0
    if (elem->contModel != NULL)
4003
0
        xmlRegFreeRegexp(elem->contModel);
4004
0
    if (elem->defVal != NULL)
4005
0
  xmlSchemaFreeValue(elem->defVal);
4006
0
    xmlFree(elem);
4007
0
}
4008
4009
/**
4010
 * xmlSchemaFreeFacet:
4011
 * @facet:  a schema facet structure
4012
 *
4013
 * Deallocate a Schema Facet structure.
4014
 */
4015
void
4016
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4017
0
{
4018
0
    if (facet == NULL)
4019
0
        return;
4020
0
    if (facet->val != NULL)
4021
0
        xmlSchemaFreeValue(facet->val);
4022
0
    if (facet->regexp != NULL)
4023
0
        xmlRegFreeRegexp(facet->regexp);
4024
0
    if (facet->annot != NULL)
4025
0
        xmlSchemaFreeAnnot(facet->annot);
4026
0
    xmlFree(facet);
4027
0
}
4028
4029
/**
4030
 * xmlSchemaFreeType:
4031
 * @type:  a schema type structure
4032
 *
4033
 * Deallocate a Schema Type structure.
4034
 */
4035
void
4036
xmlSchemaFreeType(xmlSchemaTypePtr type)
4037
0
{
4038
0
    if (type == NULL)
4039
0
        return;
4040
0
    if (type->annot != NULL)
4041
0
        xmlSchemaFreeAnnot(type->annot);
4042
0
    if (type->facets != NULL) {
4043
0
        xmlSchemaFacetPtr facet, next;
4044
4045
0
        facet = type->facets;
4046
0
        while (facet != NULL) {
4047
0
            next = facet->next;
4048
0
            xmlSchemaFreeFacet(facet);
4049
0
            facet = next;
4050
0
        }
4051
0
    }
4052
0
    if (type->attrUses != NULL)
4053
0
  xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4054
0
    if (type->memberTypes != NULL)
4055
0
  xmlSchemaFreeTypeLinkList(type->memberTypes);
4056
0
    if (type->facetSet != NULL) {
4057
0
  xmlSchemaFacetLinkPtr next, link;
4058
4059
0
  link = type->facetSet;
4060
0
  do {
4061
0
      next = link->next;
4062
0
      xmlFree(link);
4063
0
      link = next;
4064
0
  } while (link != NULL);
4065
0
    }
4066
0
    if (type->contModel != NULL)
4067
0
        xmlRegFreeRegexp(type->contModel);
4068
0
    xmlFree(type);
4069
0
}
4070
4071
/**
4072
 * xmlSchemaFreeModelGroupDef:
4073
 * @item:  a schema model group definition
4074
 *
4075
 * Deallocates a schema model group definition.
4076
 */
4077
static void
4078
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4079
0
{
4080
0
    if (item->annot != NULL)
4081
0
  xmlSchemaFreeAnnot(item->annot);
4082
0
    xmlFree(item);
4083
0
}
4084
4085
/**
4086
 * xmlSchemaFreeModelGroup:
4087
 * @item:  a schema model group
4088
 *
4089
 * Deallocates a schema model group structure.
4090
 */
4091
static void
4092
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4093
0
{
4094
0
    if (item->annot != NULL)
4095
0
  xmlSchemaFreeAnnot(item->annot);
4096
0
    xmlFree(item);
4097
0
}
4098
4099
static void
4100
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4101
0
{
4102
0
    if ((list == NULL) || (list->nbItems == 0))
4103
0
  return;
4104
0
    {
4105
0
  xmlSchemaTreeItemPtr item;
4106
0
  xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4107
0
  int i;
4108
4109
0
  for (i = 0; i < list->nbItems; i++) {
4110
0
      item = items[i];
4111
0
      if (item == NULL)
4112
0
    continue;
4113
0
      switch (item->type) {
4114
0
    case XML_SCHEMA_TYPE_SIMPLE:
4115
0
    case XML_SCHEMA_TYPE_COMPLEX:
4116
0
        xmlSchemaFreeType((xmlSchemaTypePtr) item);
4117
0
        break;
4118
0
    case XML_SCHEMA_TYPE_ATTRIBUTE:
4119
0
        xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4120
0
        break;
4121
0
    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4122
0
        xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4123
0
        break;
4124
0
    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4125
0
        xmlSchemaFreeAttributeUseProhib(
4126
0
      (xmlSchemaAttributeUseProhibPtr) item);
4127
0
        break;
4128
0
    case XML_SCHEMA_TYPE_ELEMENT:
4129
0
        xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4130
0
        break;
4131
0
    case XML_SCHEMA_TYPE_PARTICLE:
4132
0
        if (item->annot != NULL)
4133
0
      xmlSchemaFreeAnnot(item->annot);
4134
0
        xmlFree(item);
4135
0
        break;
4136
0
    case XML_SCHEMA_TYPE_SEQUENCE:
4137
0
    case XML_SCHEMA_TYPE_CHOICE:
4138
0
    case XML_SCHEMA_TYPE_ALL:
4139
0
        xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4140
0
        break;
4141
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4142
0
        xmlSchemaFreeAttributeGroup(
4143
0
      (xmlSchemaAttributeGroupPtr) item);
4144
0
        break;
4145
0
    case XML_SCHEMA_TYPE_GROUP:
4146
0
        xmlSchemaFreeModelGroupDef(
4147
0
      (xmlSchemaModelGroupDefPtr) item);
4148
0
        break;
4149
0
    case XML_SCHEMA_TYPE_ANY:
4150
0
    case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4151
0
        xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4152
0
        break;
4153
0
    case XML_SCHEMA_TYPE_IDC_KEY:
4154
0
    case XML_SCHEMA_TYPE_IDC_UNIQUE:
4155
0
    case XML_SCHEMA_TYPE_IDC_KEYREF:
4156
0
        xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4157
0
        break;
4158
0
    case XML_SCHEMA_TYPE_NOTATION:
4159
0
        xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4160
0
        break;
4161
0
    case XML_SCHEMA_EXTRA_QNAMEREF:
4162
0
        xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4163
0
        break;
4164
0
    default: {
4165
        /* TODO: This should never be hit. */
4166
0
        xmlSchemaPSimpleInternalErr(NULL,
4167
0
      "Internal error: xmlSchemaComponentListFree, "
4168
0
      "unexpected component type '%s'\n",
4169
0
      (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
4170
0
       }
4171
0
        break;
4172
0
      }
4173
0
  }
4174
0
  list->nbItems = 0;
4175
0
    }
4176
0
}
4177
4178
/**
4179
 * xmlSchemaFree:
4180
 * @schema:  a schema structure
4181
 *
4182
 * Deallocate a Schema structure.
4183
 */
4184
void
4185
xmlSchemaFree(xmlSchemaPtr schema)
4186
0
{
4187
0
    if (schema == NULL)
4188
0
        return;
4189
    /* @volatiles is not used anymore :-/ */
4190
0
    if (schema->volatiles != NULL)
4191
0
  TODO
4192
    /*
4193
    * Note that those slots are not responsible for freeing
4194
    * schema components anymore; this will now be done by
4195
    * the schema buckets.
4196
    */
4197
0
    if (schema->notaDecl != NULL)
4198
0
        xmlHashFree(schema->notaDecl, NULL);
4199
0
    if (schema->attrDecl != NULL)
4200
0
        xmlHashFree(schema->attrDecl, NULL);
4201
0
    if (schema->attrgrpDecl != NULL)
4202
0
        xmlHashFree(schema->attrgrpDecl, NULL);
4203
0
    if (schema->elemDecl != NULL)
4204
0
        xmlHashFree(schema->elemDecl, NULL);
4205
0
    if (schema->typeDecl != NULL)
4206
0
        xmlHashFree(schema->typeDecl, NULL);
4207
0
    if (schema->groupDecl != NULL)
4208
0
        xmlHashFree(schema->groupDecl, NULL);
4209
0
    if (schema->idcDef != NULL)
4210
0
        xmlHashFree(schema->idcDef, NULL);
4211
4212
0
    if (schema->schemasImports != NULL)
4213
0
  xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4214
0
    if (schema->includes != NULL) {
4215
0
  xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4216
0
  int i;
4217
0
  for (i = 0; i < list->nbItems; i++) {
4218
0
      xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4219
0
  }
4220
0
  xmlSchemaItemListFree(list);
4221
0
    }
4222
0
    if (schema->annot != NULL)
4223
0
        xmlSchemaFreeAnnot(schema->annot);
4224
    /* Never free the doc here, since this will be done by the buckets. */
4225
4226
0
    xmlDictFree(schema->dict);
4227
0
    xmlFree(schema);
4228
0
}
4229
4230
/************************************************************************
4231
 *                  *
4232
 *      Debug functions         *
4233
 *                  *
4234
 ************************************************************************/
4235
4236
#ifdef LIBXML_OUTPUT_ENABLED
4237
4238
static void
4239
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4240
4241
/**
4242
 * xmlSchemaElementDump:
4243
 * @elem:  an element
4244
 * @output:  the file output
4245
 *
4246
 * Dump the element
4247
 */
4248
static void
4249
xmlSchemaElementDump(void *payload, void *data,
4250
                     const xmlChar * name ATTRIBUTE_UNUSED,
4251
         const xmlChar * namespace ATTRIBUTE_UNUSED,
4252
                     const xmlChar * context ATTRIBUTE_UNUSED)
4253
0
{
4254
0
    xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4255
0
    FILE *output = (FILE *) data;
4256
0
    if (elem == NULL)
4257
0
        return;
4258
4259
4260
0
    fprintf(output, "Element");
4261
0
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4262
0
  fprintf(output, " (global)");
4263
0
    fprintf(output, ": '%s' ", elem->name);
4264
0
    if (namespace != NULL)
4265
0
  fprintf(output, "ns '%s'", namespace);
4266
0
    fprintf(output, "\n");
4267
#if 0
4268
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4269
  fprintf(output, "  min %d ", elem->minOccurs);
4270
        if (elem->maxOccurs >= UNBOUNDED)
4271
            fprintf(output, "max: unbounded\n");
4272
        else if (elem->maxOccurs != 1)
4273
            fprintf(output, "max: %d\n", elem->maxOccurs);
4274
        else
4275
            fprintf(output, "\n");
4276
    }
4277
#endif
4278
    /*
4279
    * Misc other properties.
4280
    */
4281
0
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4282
0
  (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4283
0
  (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4284
0
  (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4285
0
  fprintf(output, "  props: ");
4286
0
  if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4287
0
      fprintf(output, "[fixed] ");
4288
0
  if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4289
0
      fprintf(output, "[default] ");
4290
0
  if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4291
0
      fprintf(output, "[abstract] ");
4292
0
  if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4293
0
      fprintf(output, "[nillable] ");
4294
0
  fprintf(output, "\n");
4295
0
    }
4296
    /*
4297
    * Default/fixed value.
4298
    */
4299
0
    if (elem->value != NULL)
4300
0
  fprintf(output, "  value: '%s'\n", elem->value);
4301
    /*
4302
    * Type.
4303
    */
4304
0
    if (elem->namedType != NULL) {
4305
0
  fprintf(output, "  type: '%s' ", elem->namedType);
4306
0
  if (elem->namedTypeNs != NULL)
4307
0
      fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4308
0
  else
4309
0
      fprintf(output, "\n");
4310
0
    } else if (elem->subtypes != NULL) {
4311
  /*
4312
  * Dump local types.
4313
  */
4314
0
  xmlSchemaTypeDump(elem->subtypes, output);
4315
0
    }
4316
    /*
4317
    * Substitution group.
4318
    */
4319
0
    if (elem->substGroup != NULL) {
4320
0
  fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4321
0
  if (elem->substGroupNs != NULL)
4322
0
      fprintf(output, "ns '%s'\n", elem->substGroupNs);
4323
0
  else
4324
0
      fprintf(output, "\n");
4325
0
    }
4326
0
}
4327
4328
/**
4329
 * xmlSchemaAnnotDump:
4330
 * @output:  the file output
4331
 * @annot:  a annotation
4332
 *
4333
 * Dump the annotation
4334
 */
4335
static void
4336
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4337
0
{
4338
0
    xmlChar *content;
4339
4340
0
    if (annot == NULL)
4341
0
        return;
4342
4343
0
    content = xmlNodeGetContent(annot->content);
4344
0
    if (content != NULL) {
4345
0
        fprintf(output, "  Annot: %s\n", content);
4346
0
        xmlFree(content);
4347
0
    } else
4348
0
        fprintf(output, "  Annot: empty\n");
4349
0
}
4350
4351
/**
4352
 * xmlSchemaContentModelDump:
4353
 * @particle: the schema particle
4354
 * @output: the file output
4355
 * @depth: the depth used for indentation
4356
 *
4357
 * Dump a SchemaType structure
4358
 */
4359
static void
4360
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4361
0
{
4362
0
    xmlChar *str = NULL;
4363
0
    xmlSchemaTreeItemPtr term;
4364
0
    char shift[100];
4365
0
    int i;
4366
4367
0
    if (particle == NULL)
4368
0
  return;
4369
0
    for (i = 0;((i < depth) && (i < 25));i++)
4370
0
        shift[2 * i] = shift[2 * i + 1] = ' ';
4371
0
    shift[2 * i] = shift[2 * i + 1] = 0;
4372
0
    fprintf(output, "%s", shift);
4373
0
    if (particle->children == NULL) {
4374
0
  fprintf(output, "MISSING particle term\n");
4375
0
  return;
4376
0
    }
4377
0
    term = particle->children;
4378
0
    if (term == NULL) {
4379
0
  fprintf(output, "(NULL)");
4380
0
    } else {
4381
0
  switch (term->type) {
4382
0
      case XML_SCHEMA_TYPE_ELEMENT:
4383
0
    fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4384
0
        ((xmlSchemaElementPtr)term)->targetNamespace,
4385
0
        ((xmlSchemaElementPtr)term)->name));
4386
0
    FREE_AND_NULL(str);
4387
0
    break;
4388
0
      case XML_SCHEMA_TYPE_SEQUENCE:
4389
0
    fprintf(output, "SEQUENCE");
4390
0
    break;
4391
0
      case XML_SCHEMA_TYPE_CHOICE:
4392
0
    fprintf(output, "CHOICE");
4393
0
    break;
4394
0
      case XML_SCHEMA_TYPE_ALL:
4395
0
    fprintf(output, "ALL");
4396
0
    break;
4397
0
      case XML_SCHEMA_TYPE_ANY:
4398
0
    fprintf(output, "ANY");
4399
0
    break;
4400
0
      default:
4401
0
    fprintf(output, "UNKNOWN\n");
4402
0
    return;
4403
0
  }
4404
0
    }
4405
0
    if (particle->minOccurs != 1)
4406
0
  fprintf(output, " min: %d", particle->minOccurs);
4407
0
    if (particle->maxOccurs >= UNBOUNDED)
4408
0
  fprintf(output, " max: unbounded");
4409
0
    else if (particle->maxOccurs != 1)
4410
0
  fprintf(output, " max: %d", particle->maxOccurs);
4411
0
    fprintf(output, "\n");
4412
0
    if (term &&
4413
0
  ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4414
0
   (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4415
0
   (term->type == XML_SCHEMA_TYPE_ALL)) &&
4416
0
   (term->children != NULL)) {
4417
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4418
0
      output, depth +1);
4419
0
    }
4420
0
    if (particle->next != NULL)
4421
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4422
0
    output, depth);
4423
0
}
4424
4425
/**
4426
 * xmlSchemaAttrUsesDump:
4427
 * @uses:  attribute uses list
4428
 * @output:  the file output
4429
 *
4430
 * Dumps a list of attribute use components.
4431
 */
4432
static void
4433
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4434
0
{
4435
0
    xmlSchemaAttributeUsePtr use;
4436
0
    xmlSchemaAttributeUseProhibPtr prohib;
4437
0
    xmlSchemaQNameRefPtr ref;
4438
0
    const xmlChar *name, *tns;
4439
0
    xmlChar *str = NULL;
4440
0
    int i;
4441
4442
0
    if ((uses == NULL) || (uses->nbItems == 0))
4443
0
        return;
4444
4445
0
    fprintf(output, "  attributes:\n");
4446
0
    for (i = 0; i < uses->nbItems; i++) {
4447
0
  use = uses->items[i];
4448
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4449
0
      fprintf(output, "  [prohibition] ");
4450
0
      prohib = (xmlSchemaAttributeUseProhibPtr) use;
4451
0
      name = prohib->name;
4452
0
      tns = prohib->targetNamespace;
4453
0
  } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4454
0
      fprintf(output, "  [reference] ");
4455
0
      ref = (xmlSchemaQNameRefPtr) use;
4456
0
      name = ref->name;
4457
0
      tns = ref->targetNamespace;
4458
0
  } else {
4459
0
      fprintf(output, "  [use] ");
4460
0
      name = WXS_ATTRUSE_DECL_NAME(use);
4461
0
      tns = WXS_ATTRUSE_DECL_TNS(use);
4462
0
  }
4463
0
  fprintf(output, "'%s'\n",
4464
0
      (const char *) xmlSchemaFormatQName(&str, tns, name));
4465
0
  FREE_AND_NULL(str);
4466
0
    }
4467
0
}
4468
4469
/**
4470
 * xmlSchemaTypeDump:
4471
 * @output:  the file output
4472
 * @type:  a type structure
4473
 *
4474
 * Dump a SchemaType structure
4475
 */
4476
static void
4477
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4478
0
{
4479
0
    if (type == NULL) {
4480
0
        fprintf(output, "Type: NULL\n");
4481
0
        return;
4482
0
    }
4483
0
    fprintf(output, "Type: ");
4484
0
    if (type->name != NULL)
4485
0
        fprintf(output, "'%s' ", type->name);
4486
0
    else
4487
0
        fprintf(output, "(no name) ");
4488
0
    if (type->targetNamespace != NULL)
4489
0
  fprintf(output, "ns '%s' ", type->targetNamespace);
4490
0
    switch (type->type) {
4491
0
        case XML_SCHEMA_TYPE_BASIC:
4492
0
            fprintf(output, "[basic] ");
4493
0
            break;
4494
0
        case XML_SCHEMA_TYPE_SIMPLE:
4495
0
            fprintf(output, "[simple] ");
4496
0
            break;
4497
0
        case XML_SCHEMA_TYPE_COMPLEX:
4498
0
            fprintf(output, "[complex] ");
4499
0
            break;
4500
0
        case XML_SCHEMA_TYPE_SEQUENCE:
4501
0
            fprintf(output, "[sequence] ");
4502
0
            break;
4503
0
        case XML_SCHEMA_TYPE_CHOICE:
4504
0
            fprintf(output, "[choice] ");
4505
0
            break;
4506
0
        case XML_SCHEMA_TYPE_ALL:
4507
0
            fprintf(output, "[all] ");
4508
0
            break;
4509
0
        case XML_SCHEMA_TYPE_UR:
4510
0
            fprintf(output, "[ur] ");
4511
0
            break;
4512
0
        case XML_SCHEMA_TYPE_RESTRICTION:
4513
0
            fprintf(output, "[restriction] ");
4514
0
            break;
4515
0
        case XML_SCHEMA_TYPE_EXTENSION:
4516
0
            fprintf(output, "[extension] ");
4517
0
            break;
4518
0
        default:
4519
0
            fprintf(output, "[unknown type %d] ", type->type);
4520
0
            break;
4521
0
    }
4522
0
    fprintf(output, "content: ");
4523
0
    switch (type->contentType) {
4524
0
        case XML_SCHEMA_CONTENT_UNKNOWN:
4525
0
            fprintf(output, "[unknown] ");
4526
0
            break;
4527
0
        case XML_SCHEMA_CONTENT_EMPTY:
4528
0
            fprintf(output, "[empty] ");
4529
0
            break;
4530
0
        case XML_SCHEMA_CONTENT_ELEMENTS:
4531
0
            fprintf(output, "[element] ");
4532
0
            break;
4533
0
        case XML_SCHEMA_CONTENT_MIXED:
4534
0
            fprintf(output, "[mixed] ");
4535
0
            break;
4536
0
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4537
  /* not used. */
4538
0
            break;
4539
0
        case XML_SCHEMA_CONTENT_BASIC:
4540
0
            fprintf(output, "[basic] ");
4541
0
            break;
4542
0
        case XML_SCHEMA_CONTENT_SIMPLE:
4543
0
            fprintf(output, "[simple] ");
4544
0
            break;
4545
0
        case XML_SCHEMA_CONTENT_ANY:
4546
0
            fprintf(output, "[any] ");
4547
0
            break;
4548
0
    }
4549
0
    fprintf(output, "\n");
4550
0
    if (type->base != NULL) {
4551
0
        fprintf(output, "  base type: '%s'", type->base);
4552
0
  if (type->baseNs != NULL)
4553
0
      fprintf(output, " ns '%s'\n", type->baseNs);
4554
0
  else
4555
0
      fprintf(output, "\n");
4556
0
    }
4557
0
    if (type->attrUses != NULL)
4558
0
  xmlSchemaAttrUsesDump(type->attrUses, output);
4559
0
    if (type->annot != NULL)
4560
0
        xmlSchemaAnnotDump(output, type->annot);
4561
0
#ifdef DUMP_CONTENT_MODEL
4562
0
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4563
0
  (type->subtypes != NULL)) {
4564
0
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4565
0
      output, 1);
4566
0
    }
4567
0
#endif
4568
0
}
4569
4570
static void
4571
xmlSchemaTypeDumpEntry(void *type, void *output,
4572
                       const xmlChar *name ATTRIBUTE_UNUSED)
4573
0
{
4574
0
    xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4575
0
}
4576
4577
/**
4578
 * xmlSchemaDump:
4579
 * @output:  the file output
4580
 * @schema:  a schema structure
4581
 *
4582
 * Dump a Schema structure.
4583
 */
4584
void
4585
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4586
0
{
4587
0
    if (output == NULL)
4588
0
        return;
4589
0
    if (schema == NULL) {
4590
0
        fprintf(output, "Schemas: NULL\n");
4591
0
        return;
4592
0
    }
4593
0
    fprintf(output, "Schemas: ");
4594
0
    if (schema->name != NULL)
4595
0
        fprintf(output, "%s, ", schema->name);
4596
0
    else
4597
0
        fprintf(output, "no name, ");
4598
0
    if (schema->targetNamespace != NULL)
4599
0
        fprintf(output, "%s", (const char *) schema->targetNamespace);
4600
0
    else
4601
0
        fprintf(output, "no target namespace");
4602
0
    fprintf(output, "\n");
4603
0
    if (schema->annot != NULL)
4604
0
        xmlSchemaAnnotDump(output, schema->annot);
4605
0
    xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4606
0
    xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4607
0
}
4608
4609
#ifdef DEBUG_IDC_NODE_TABLE
4610
/**
4611
 * xmlSchemaDebugDumpIDCTable:
4612
 * @vctxt: the WXS validation context
4613
 *
4614
 * Displays the current IDC table for debug purposes.
4615
 */
4616
static void
4617
xmlSchemaDebugDumpIDCTable(FILE * output,
4618
         const xmlChar *namespaceName,
4619
         const xmlChar *localName,
4620
         xmlSchemaPSVIIDCBindingPtr bind)
4621
{
4622
    xmlChar *str = NULL;
4623
    const xmlChar *value;
4624
    xmlSchemaPSVIIDCNodePtr tab;
4625
    xmlSchemaPSVIIDCKeyPtr key;
4626
    int i, j, res;
4627
4628
    fprintf(output, "IDC: TABLES on '%s'\n",
4629
  xmlSchemaFormatQName(&str, namespaceName, localName));
4630
    FREE_AND_NULL(str)
4631
4632
    if (bind == NULL)
4633
  return;
4634
    do {
4635
  fprintf(output, "IDC:   BINDING '%s' (%d)\n",
4636
      xmlSchemaGetComponentQName(&str,
4637
    bind->definition), bind->nbNodes);
4638
  FREE_AND_NULL(str)
4639
  for (i = 0; i < bind->nbNodes; i++) {
4640
      tab = bind->nodeTable[i];
4641
      fprintf(output, "         ( ");
4642
      for (j = 0; j < bind->definition->nbFields; j++) {
4643
    key = tab->keys[j];
4644
    if ((key != NULL) && (key->val != NULL)) {
4645
        res = xmlSchemaGetCanonValue(key->val, &value);
4646
        if (res >= 0)
4647
      fprintf(output, "'%s' ", value);
4648
        else
4649
      fprintf(output, "CANON-VALUE-FAILED ");
4650
        if (res == 0)
4651
      FREE_AND_NULL(value)
4652
    } else if (key != NULL)
4653
        fprintf(output, "(no val), ");
4654
    else
4655
        fprintf(output, "(key missing), ");
4656
      }
4657
      fprintf(output, ")\n");
4658
  }
4659
  if (bind->dupls && bind->dupls->nbItems) {
4660
      fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
4661
      for (i = 0; i < bind->dupls->nbItems; i++) {
4662
    tab = bind->dupls->items[i];
4663
    fprintf(output, "         ( ");
4664
    for (j = 0; j < bind->definition->nbFields; j++) {
4665
        key = tab->keys[j];
4666
        if ((key != NULL) && (key->val != NULL)) {
4667
      res = xmlSchemaGetCanonValue(key->val, &value);
4668
      if (res >= 0)
4669
          fprintf(output, "'%s' ", value);
4670
      else
4671
          fprintf(output, "CANON-VALUE-FAILED ");
4672
      if (res == 0)
4673
          FREE_AND_NULL(value)
4674
        } else if (key != NULL)
4675
        fprintf(output, "(no val), ");
4676
      else
4677
          fprintf(output, "(key missing), ");
4678
    }
4679
    fprintf(output, ")\n");
4680
      }
4681
  }
4682
  bind = bind->next;
4683
    } while (bind != NULL);
4684
}
4685
#endif /* DEBUG_IDC */
4686
#endif /* LIBXML_OUTPUT_ENABLED */
4687
4688
/************************************************************************
4689
 *                  *
4690
 *      Utilities         *
4691
 *                  *
4692
 ************************************************************************/
4693
4694
/**
4695
 * xmlSchemaGetPropNode:
4696
 * @node: the element node
4697
 * @name: the name of the attribute
4698
 *
4699
 * Seeks an attribute with a name of @name in
4700
 * no namespace.
4701
 *
4702
 * Returns the attribute or NULL if not present.
4703
 */
4704
static xmlAttrPtr
4705
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4706
0
{
4707
0
    xmlAttrPtr prop;
4708
4709
0
    if ((node == NULL) || (name == NULL))
4710
0
  return(NULL);
4711
0
    prop = node->properties;
4712
0
    while (prop != NULL) {
4713
0
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4714
0
      return(prop);
4715
0
  prop = prop->next;
4716
0
    }
4717
0
    return (NULL);
4718
0
}
4719
4720
/**
4721
 * xmlSchemaGetPropNodeNs:
4722
 * @node: the element node
4723
 * @uri: the uri
4724
 * @name: the name of the attribute
4725
 *
4726
 * Seeks an attribute with a local name of @name and
4727
 * a namespace URI of @uri.
4728
 *
4729
 * Returns the attribute or NULL if not present.
4730
 */
4731
static xmlAttrPtr
4732
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4733
0
{
4734
0
    xmlAttrPtr prop;
4735
4736
0
    if ((node == NULL) || (name == NULL))
4737
0
  return(NULL);
4738
0
    prop = node->properties;
4739
0
    while (prop != NULL) {
4740
0
  if ((prop->ns != NULL) &&
4741
0
      xmlStrEqual(prop->name, BAD_CAST name) &&
4742
0
      xmlStrEqual(prop->ns->href, BAD_CAST uri))
4743
0
      return(prop);
4744
0
  prop = prop->next;
4745
0
    }
4746
0
    return (NULL);
4747
0
}
4748
4749
static const xmlChar *
4750
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4751
0
{
4752
0
    xmlChar *val;
4753
0
    const xmlChar *ret;
4754
4755
0
    val = xmlNodeGetContent(node);
4756
0
    if (val == NULL)
4757
0
  val = xmlStrdup((xmlChar *)"");
4758
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4759
0
    xmlFree(val);
4760
0
    return(ret);
4761
0
}
4762
4763
static const xmlChar *
4764
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4765
0
{
4766
0
    return((const xmlChar*) xmlNodeGetContent(node));
4767
0
}
4768
4769
/**
4770
 * xmlSchemaGetProp:
4771
 * @ctxt: the parser context
4772
 * @node: the node
4773
 * @name: the property name
4774
 *
4775
 * Read a attribute value and internalize the string
4776
 *
4777
 * Returns the string or NULL if not present.
4778
 */
4779
static const xmlChar *
4780
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4781
                 const char *name)
4782
0
{
4783
0
    xmlChar *val;
4784
0
    const xmlChar *ret;
4785
4786
0
    val = xmlGetNoNsProp(node, BAD_CAST name);
4787
0
    if (val == NULL)
4788
0
        return(NULL);
4789
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4790
0
    xmlFree(val);
4791
0
    return(ret);
4792
0
}
4793
4794
/************************************************************************
4795
 *                  *
4796
 *      Parsing functions       *
4797
 *                  *
4798
 ************************************************************************/
4799
4800
#define WXS_FIND_GLOBAL_ITEM(slot)      \
4801
0
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4802
0
  ret = xmlHashLookup(schema->slot, name); \
4803
0
  if (ret != NULL) goto exit; \
4804
0
    } \
4805
0
    if (xmlHashSize(schema->schemasImports) > 1) { \
4806
0
  xmlSchemaImportPtr import; \
4807
0
  if (nsName == NULL) \
4808
0
      import = xmlHashLookup(schema->schemasImports, \
4809
0
    XML_SCHEMAS_NO_NAMESPACE); \
4810
0
  else \
4811
0
      import = xmlHashLookup(schema->schemasImports, nsName); \
4812
0
  if (import == NULL) \
4813
0
      goto exit; \
4814
0
  ret = xmlHashLookup(import->schema->slot, name); \
4815
0
    }
4816
4817
/**
4818
 * xmlSchemaGetElem:
4819
 * @schema:  the schema context
4820
 * @name:  the element name
4821
 * @ns:  the element namespace
4822
 *
4823
 * Lookup a global element declaration in the schema.
4824
 *
4825
 * Returns the element declaration or NULL if not found.
4826
 */
4827
static xmlSchemaElementPtr
4828
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4829
                 const xmlChar * nsName)
4830
0
{
4831
0
    xmlSchemaElementPtr ret = NULL;
4832
4833
0
    if ((name == NULL) || (schema == NULL))
4834
0
        return(NULL);
4835
0
    if (schema != NULL) {
4836
0
  WXS_FIND_GLOBAL_ITEM(elemDecl)
4837
0
    }
4838
0
exit:
4839
#ifdef DEBUG
4840
    if (ret == NULL) {
4841
        if (nsName == NULL)
4842
            fprintf(stderr, "Unable to lookup element decl. %s", name);
4843
        else
4844
            fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
4845
                    nsName);
4846
    }
4847
#endif
4848
0
    return (ret);
4849
0
}
4850
4851
/**
4852
 * xmlSchemaGetType:
4853
 * @schema:  the main schema
4854
 * @name:  the type's name
4855
 * nsName:  the type's namespace
4856
 *
4857
 * Lookup a type in the schemas or the predefined types
4858
 *
4859
 * Returns the group definition or NULL if not found.
4860
 */
4861
static xmlSchemaTypePtr
4862
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4863
                 const xmlChar * nsName)
4864
0
{
4865
0
    xmlSchemaTypePtr ret = NULL;
4866
4867
0
    if (name == NULL)
4868
0
        return (NULL);
4869
    /* First try the built-in types. */
4870
0
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4871
0
  ret = xmlSchemaGetPredefinedType(name, nsName);
4872
0
  if (ret != NULL)
4873
0
      goto exit;
4874
  /*
4875
  * Note that we try the parsed schemas as well here
4876
  * since one might have parsed the S4S, which contain more
4877
  * than the built-in types.
4878
  * TODO: Can we optimize this?
4879
  */
4880
0
    }
4881
0
    if (schema != NULL) {
4882
0
  WXS_FIND_GLOBAL_ITEM(typeDecl)
4883
0
    }
4884
0
exit:
4885
4886
#ifdef DEBUG
4887
    if (ret == NULL) {
4888
        if (nsName == NULL)
4889
            fprintf(stderr, "Unable to lookup type %s", name);
4890
        else
4891
            fprintf(stderr, "Unable to lookup type %s:%s", name,
4892
                    nsName);
4893
    }
4894
#endif
4895
0
    return (ret);
4896
0
}
4897
4898
/**
4899
 * xmlSchemaGetAttributeDecl:
4900
 * @schema:  the context of the schema
4901
 * @name:  the name of the attribute
4902
 * @ns:  the target namespace of the attribute
4903
 *
4904
 * Lookup a an attribute in the schema or imported schemas
4905
 *
4906
 * Returns the attribute declaration or NULL if not found.
4907
 */
4908
static xmlSchemaAttributePtr
4909
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4910
                 const xmlChar * nsName)
4911
0
{
4912
0
    xmlSchemaAttributePtr ret = NULL;
4913
4914
0
    if ((name == NULL) || (schema == NULL))
4915
0
        return (NULL);
4916
0
    if (schema != NULL) {
4917
0
  WXS_FIND_GLOBAL_ITEM(attrDecl)
4918
0
    }
4919
0
exit:
4920
#ifdef DEBUG
4921
    if (ret == NULL) {
4922
        if (nsName == NULL)
4923
            fprintf(stderr, "Unable to lookup attribute %s", name);
4924
        else
4925
            fprintf(stderr, "Unable to lookup attribute %s:%s", name,
4926
                    nsName);
4927
    }
4928
#endif
4929
0
    return (ret);
4930
0
}
4931
4932
/**
4933
 * xmlSchemaGetAttributeGroup:
4934
 * @schema:  the context of the schema
4935
 * @name:  the name of the attribute group
4936
 * @ns:  the target namespace of the attribute group
4937
 *
4938
 * Lookup a an attribute group in the schema or imported schemas
4939
 *
4940
 * Returns the attribute group definition or NULL if not found.
4941
 */
4942
static xmlSchemaAttributeGroupPtr
4943
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4944
                 const xmlChar * nsName)
4945
0
{
4946
0
    xmlSchemaAttributeGroupPtr ret = NULL;
4947
4948
0
    if ((name == NULL) || (schema == NULL))
4949
0
        return (NULL);
4950
0
    if (schema != NULL) {
4951
0
  WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4952
0
    }
4953
0
exit:
4954
    /* TODO:
4955
    if ((ret != NULL) && (ret->redef != NULL)) {
4956
  * Return the last redefinition. *
4957
  ret = ret->redef;
4958
    }
4959
    */
4960
#ifdef DEBUG
4961
    if (ret == NULL) {
4962
        if (nsName == NULL)
4963
            fprintf(stderr, "Unable to lookup attribute group %s", name);
4964
        else
4965
            fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
4966
                    nsName);
4967
    }
4968
#endif
4969
0
    return (ret);
4970
0
}
4971
4972
/**
4973
 * xmlSchemaGetGroup:
4974
 * @schema:  the context of the schema
4975
 * @name:  the name of the group
4976
 * @ns:  the target namespace of the group
4977
 *
4978
 * Lookup a group in the schema or imported schemas
4979
 *
4980
 * Returns the group definition or NULL if not found.
4981
 */
4982
static xmlSchemaModelGroupDefPtr
4983
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4984
                 const xmlChar * nsName)
4985
0
{
4986
0
    xmlSchemaModelGroupDefPtr ret = NULL;
4987
4988
0
    if ((name == NULL) || (schema == NULL))
4989
0
        return (NULL);
4990
0
    if (schema != NULL) {
4991
0
  WXS_FIND_GLOBAL_ITEM(groupDecl)
4992
0
    }
4993
0
exit:
4994
4995
#ifdef DEBUG
4996
    if (ret == NULL) {
4997
        if (nsName == NULL)
4998
            fprintf(stderr, "Unable to lookup group %s", name);
4999
        else
5000
            fprintf(stderr, "Unable to lookup group %s:%s", name,
5001
                    nsName);
5002
    }
5003
#endif
5004
0
    return (ret);
5005
0
}
5006
5007
static xmlSchemaNotationPtr
5008
xmlSchemaGetNotation(xmlSchemaPtr schema,
5009
         const xmlChar *name,
5010
         const xmlChar *nsName)
5011
0
{
5012
0
    xmlSchemaNotationPtr ret = NULL;
5013
5014
0
    if ((name == NULL) || (schema == NULL))
5015
0
        return (NULL);
5016
0
    if (schema != NULL) {
5017
0
  WXS_FIND_GLOBAL_ITEM(notaDecl)
5018
0
    }
5019
0
exit:
5020
0
    return (ret);
5021
0
}
5022
5023
static xmlSchemaIDCPtr
5024
xmlSchemaGetIDC(xmlSchemaPtr schema,
5025
    const xmlChar *name,
5026
    const xmlChar *nsName)
5027
0
{
5028
0
    xmlSchemaIDCPtr ret = NULL;
5029
5030
0
    if ((name == NULL) || (schema == NULL))
5031
0
        return (NULL);
5032
0
    if (schema != NULL) {
5033
0
  WXS_FIND_GLOBAL_ITEM(idcDef)
5034
0
    }
5035
0
exit:
5036
0
    return (ret);
5037
0
}
5038
5039
/**
5040
 * xmlSchemaGetNamedComponent:
5041
 * @schema:  the schema
5042
 * @name:  the name of the group
5043
 * @ns:  the target namespace of the group
5044
 *
5045
 * Lookup a group in the schema or imported schemas
5046
 *
5047
 * Returns the group definition or NULL if not found.
5048
 */
5049
static xmlSchemaBasicItemPtr
5050
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
5051
         xmlSchemaTypeType itemType,
5052
         const xmlChar *name,
5053
         const xmlChar *targetNs)
5054
0
{
5055
0
    switch (itemType) {
5056
0
  case XML_SCHEMA_TYPE_GROUP:
5057
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
5058
0
    name, targetNs));
5059
0
  case XML_SCHEMA_TYPE_ELEMENT:
5060
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
5061
0
    name, targetNs));
5062
0
  default:
5063
0
      TODO
5064
0
      return (NULL);
5065
0
    }
5066
0
}
5067
5068
/************************************************************************
5069
 *                  *
5070
 *      Parsing functions       *
5071
 *                  *
5072
 ************************************************************************/
5073
5074
#define IS_BLANK_NODE(n)            \
5075
0
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
5076
5077
/**
5078
 * xmlSchemaIsBlank:
5079
 * @str:  a string
5080
 * @len: the length of the string or -1
5081
 *
5082
 * Check if a string is ignorable
5083
 *
5084
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
5085
 */
5086
static int
5087
xmlSchemaIsBlank(xmlChar * str, int len)
5088
0
{
5089
0
    if (str == NULL)
5090
0
        return (1);
5091
0
    if (len < 0) {
5092
0
  while (*str != 0) {
5093
0
      if (!(IS_BLANK_CH(*str)))
5094
0
    return (0);
5095
0
      str++;
5096
0
  }
5097
0
    } else while ((*str != 0) && (len != 0)) {
5098
0
  if (!(IS_BLANK_CH(*str)))
5099
0
      return (0);
5100
0
  str++;
5101
0
  len--;
5102
0
    }
5103
5104
0
    return (1);
5105
0
}
5106
5107
0
#define WXS_COMP_NAME(c, t) ((t) (c))->name
5108
0
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5109
/*
5110
* xmlSchemaFindRedefCompInGraph:
5111
* ATTENTION TODO: This uses pointer comp. for strings.
5112
*/
5113
static xmlSchemaBasicItemPtr
5114
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5115
            xmlSchemaTypeType type,
5116
            const xmlChar *name,
5117
            const xmlChar *nsName)
5118
0
{
5119
0
    xmlSchemaBasicItemPtr ret;
5120
0
    int i;
5121
5122
0
    if ((bucket == NULL) || (name == NULL))
5123
0
  return(NULL);
5124
0
    if ((bucket->globals == NULL) ||
5125
0
  (bucket->globals->nbItems == 0))
5126
0
  goto subschemas;
5127
    /*
5128
    * Search in global components.
5129
    */
5130
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
5131
0
  ret = bucket->globals->items[i];
5132
0
  if (ret->type == type) {
5133
0
      switch (type) {
5134
0
    case XML_SCHEMA_TYPE_COMPLEX:
5135
0
    case XML_SCHEMA_TYPE_SIMPLE:
5136
0
        if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5137
0
      (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5138
0
      nsName))
5139
0
        {
5140
0
      return(ret);
5141
0
        }
5142
0
        break;
5143
0
    case XML_SCHEMA_TYPE_GROUP:
5144
0
        if ((WXS_COMP_NAME(ret,
5145
0
          xmlSchemaModelGroupDefPtr) == name) &&
5146
0
      (WXS_COMP_TNS(ret,
5147
0
          xmlSchemaModelGroupDefPtr) == nsName))
5148
0
        {
5149
0
      return(ret);
5150
0
        }
5151
0
        break;
5152
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5153
0
        if ((WXS_COMP_NAME(ret,
5154
0
          xmlSchemaAttributeGroupPtr) == name) &&
5155
0
      (WXS_COMP_TNS(ret,
5156
0
          xmlSchemaAttributeGroupPtr) == nsName))
5157
0
        {
5158
0
      return(ret);
5159
0
        }
5160
0
        break;
5161
0
    default:
5162
        /* Should not be hit. */
5163
0
        return(NULL);
5164
0
      }
5165
0
  }
5166
0
    }
5167
0
subschemas:
5168
    /*
5169
    * Process imported/included schemas.
5170
    */
5171
0
    if (bucket->relations != NULL) {
5172
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
5173
5174
  /*
5175
  * TODO: Marking the bucket will not avoid multiple searches
5176
  * in the same schema, but avoids at least circularity.
5177
  */
5178
0
  bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5179
0
  do {
5180
0
      if ((rel->bucket != NULL) &&
5181
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5182
0
    ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5183
0
        type, name, nsName);
5184
0
    if (ret != NULL)
5185
0
        return(ret);
5186
0
      }
5187
0
      rel = rel->next;
5188
0
  } while (rel != NULL);
5189
0
   bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5190
0
    }
5191
0
    return(NULL);
5192
0
}
5193
5194
/**
5195
 * xmlSchemaAddNotation:
5196
 * @ctxt:  a schema parser context
5197
 * @schema:  the schema being built
5198
 * @name:  the item name
5199
 *
5200
 * Add an XML schema annotation declaration
5201
 * *WARNING* this interface is highly subject to change
5202
 *
5203
 * Returns the new structure or NULL in case of error
5204
 */
5205
static xmlSchemaNotationPtr
5206
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5207
                     const xmlChar *name, const xmlChar *nsName,
5208
         xmlNodePtr node ATTRIBUTE_UNUSED)
5209
0
{
5210
0
    xmlSchemaNotationPtr ret = NULL;
5211
5212
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5213
0
        return (NULL);
5214
5215
0
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5216
0
    if (ret == NULL) {
5217
0
        xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
5218
0
        return (NULL);
5219
0
    }
5220
0
    memset(ret, 0, sizeof(xmlSchemaNotation));
5221
0
    ret->type = XML_SCHEMA_TYPE_NOTATION;
5222
0
    ret->name = name;
5223
0
    ret->targetNamespace = nsName;
5224
    /* TODO: do we need the node to be set?
5225
    * ret->node = node;*/
5226
0
    WXS_ADD_GLOBAL(ctxt, ret);
5227
0
    return (ret);
5228
0
}
5229
5230
/**
5231
 * xmlSchemaAddAttribute:
5232
 * @ctxt:  a schema parser context
5233
 * @schema:  the schema being built
5234
 * @name:  the item name
5235
 * @namespace:  the namespace
5236
 *
5237
 * Add an XML schema Attribute declaration
5238
 * *WARNING* this interface is highly subject to change
5239
 *
5240
 * Returns the new structure or NULL in case of error
5241
 */
5242
static xmlSchemaAttributePtr
5243
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5244
                      const xmlChar * name, const xmlChar * nsName,
5245
          xmlNodePtr node, int topLevel)
5246
0
{
5247
0
    xmlSchemaAttributePtr ret = NULL;
5248
5249
0
    if ((ctxt == NULL) || (schema == NULL))
5250
0
        return (NULL);
5251
5252
0
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5253
0
    if (ret == NULL) {
5254
0
        xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
5255
0
        return (NULL);
5256
0
    }
5257
0
    memset(ret, 0, sizeof(xmlSchemaAttribute));
5258
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5259
0
    ret->node = node;
5260
0
    ret->name = name;
5261
0
    ret->targetNamespace = nsName;
5262
5263
0
    if (topLevel)
5264
0
  WXS_ADD_GLOBAL(ctxt, ret);
5265
0
    else
5266
0
  WXS_ADD_LOCAL(ctxt, ret);
5267
0
    WXS_ADD_PENDING(ctxt, ret);
5268
0
    return (ret);
5269
0
}
5270
5271
/**
5272
 * xmlSchemaAddAttributeUse:
5273
 * @ctxt:  a schema parser context
5274
 * @schema:  the schema being built
5275
 * @name:  the item name
5276
 * @namespace:  the namespace
5277
 *
5278
 * Add an XML schema Attribute declaration
5279
 * *WARNING* this interface is highly subject to change
5280
 *
5281
 * Returns the new structure or NULL in case of error
5282
 */
5283
static xmlSchemaAttributeUsePtr
5284
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5285
       xmlNodePtr node)
5286
0
{
5287
0
    xmlSchemaAttributeUsePtr ret = NULL;
5288
5289
0
    if (pctxt == NULL)
5290
0
        return (NULL);
5291
5292
0
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5293
0
    if (ret == NULL) {
5294
0
        xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
5295
0
        return (NULL);
5296
0
    }
5297
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5298
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5299
0
    ret->node = node;
5300
5301
0
    WXS_ADD_LOCAL(pctxt, ret);
5302
0
    return (ret);
5303
0
}
5304
5305
/*
5306
* xmlSchemaAddRedef:
5307
*
5308
* Adds a redefinition information. This is used at a later stage to:
5309
* resolve references to the redefined components and to check constraints.
5310
*/
5311
static xmlSchemaRedefPtr
5312
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5313
      xmlSchemaBucketPtr targetBucket,
5314
      void *item,
5315
      const xmlChar *refName,
5316
      const xmlChar *refTargetNs)
5317
0
{
5318
0
    xmlSchemaRedefPtr ret;
5319
5320
0
    ret = (xmlSchemaRedefPtr)
5321
0
  xmlMalloc(sizeof(xmlSchemaRedef));
5322
0
    if (ret == NULL) {
5323
0
  xmlSchemaPErrMemory(pctxt,
5324
0
      "allocating redefinition info", NULL);
5325
0
  return (NULL);
5326
0
    }
5327
0
    memset(ret, 0, sizeof(xmlSchemaRedef));
5328
0
    ret->item = item;
5329
0
    ret->targetBucket = targetBucket;
5330
0
    ret->refName = refName;
5331
0
    ret->refTargetNs = refTargetNs;
5332
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5333
0
  WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5334
0
    else
5335
0
  WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5336
0
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5337
5338
0
    return (ret);
5339
0
}
5340
5341
/**
5342
 * xmlSchemaAddAttributeGroupDefinition:
5343
 * @ctxt:  a schema parser context
5344
 * @schema:  the schema being built
5345
 * @name:  the item name
5346
 * @nsName:  the target namespace
5347
 * @node: the corresponding node
5348
 *
5349
 * Add an XML schema Attribute Group definition.
5350
 *
5351
 * Returns the new structure or NULL in case of error
5352
 */
5353
static xmlSchemaAttributeGroupPtr
5354
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5355
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5356
         const xmlChar *name,
5357
         const xmlChar *nsName,
5358
         xmlNodePtr node)
5359
0
{
5360
0
    xmlSchemaAttributeGroupPtr ret = NULL;
5361
5362
0
    if ((pctxt == NULL) || (name == NULL))
5363
0
        return (NULL);
5364
5365
0
    ret = (xmlSchemaAttributeGroupPtr)
5366
0
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5367
0
    if (ret == NULL) {
5368
0
  xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
5369
0
  return (NULL);
5370
0
    }
5371
0
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5372
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5373
0
    ret->name = name;
5374
0
    ret->targetNamespace = nsName;
5375
0
    ret->node = node;
5376
5377
    /* TODO: Remove the flag. */
5378
0
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5379
0
    if (pctxt->isRedefine) {
5380
0
  pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5381
0
      ret, name, nsName);
5382
0
  if (pctxt->redef == NULL) {
5383
0
      xmlFree(ret);
5384
0
      return(NULL);
5385
0
  }
5386
0
  pctxt->redefCounter = 0;
5387
0
    }
5388
0
    WXS_ADD_GLOBAL(pctxt, ret);
5389
0
    WXS_ADD_PENDING(pctxt, ret);
5390
0
    return (ret);
5391
0
}
5392
5393
/**
5394
 * xmlSchemaAddElement:
5395
 * @ctxt:  a schema parser context
5396
 * @schema:  the schema being built
5397
 * @name:  the type name
5398
 * @namespace:  the type namespace
5399
 *
5400
 * Add an XML schema Element declaration
5401
 * *WARNING* this interface is highly subject to change
5402
 *
5403
 * Returns the new structure or NULL in case of error
5404
 */
5405
static xmlSchemaElementPtr
5406
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5407
                    const xmlChar * name, const xmlChar * nsName,
5408
        xmlNodePtr node, int topLevel)
5409
0
{
5410
0
    xmlSchemaElementPtr ret = NULL;
5411
5412
0
    if ((ctxt == NULL) || (name == NULL))
5413
0
        return (NULL);
5414
5415
0
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5416
0
    if (ret == NULL) {
5417
0
        xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
5418
0
        return (NULL);
5419
0
    }
5420
0
    memset(ret, 0, sizeof(xmlSchemaElement));
5421
0
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5422
0
    ret->name = name;
5423
0
    ret->targetNamespace = nsName;
5424
0
    ret->node = node;
5425
5426
0
    if (topLevel)
5427
0
  WXS_ADD_GLOBAL(ctxt, ret);
5428
0
    else
5429
0
  WXS_ADD_LOCAL(ctxt, ret);
5430
0
    WXS_ADD_PENDING(ctxt, ret);
5431
0
    return (ret);
5432
0
}
5433
5434
/**
5435
 * xmlSchemaAddType:
5436
 * @ctxt:  a schema parser context
5437
 * @schema:  the schema being built
5438
 * @name:  the item name
5439
 * @namespace:  the namespace
5440
 *
5441
 * Add an XML schema item
5442
 * *WARNING* this interface is highly subject to change
5443
 *
5444
 * Returns the new structure or NULL in case of error
5445
 */
5446
static xmlSchemaTypePtr
5447
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5448
     xmlSchemaTypeType type,
5449
                 const xmlChar * name, const xmlChar * nsName,
5450
     xmlNodePtr node, int topLevel)
5451
0
{
5452
0
    xmlSchemaTypePtr ret = NULL;
5453
5454
0
    if ((ctxt == NULL) || (schema == NULL))
5455
0
        return (NULL);
5456
5457
0
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5458
0
    if (ret == NULL) {
5459
0
        xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
5460
0
        return (NULL);
5461
0
    }
5462
0
    memset(ret, 0, sizeof(xmlSchemaType));
5463
0
    ret->type = type;
5464
0
    ret->name = name;
5465
0
    ret->targetNamespace = nsName;
5466
0
    ret->node = node;
5467
0
    if (topLevel) {
5468
0
  if (ctxt->isRedefine) {
5469
0
      ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5470
0
    ret, name, nsName);
5471
0
      if (ctxt->redef == NULL) {
5472
0
    xmlFree(ret);
5473
0
    return(NULL);
5474
0
      }
5475
0
      ctxt->redefCounter = 0;
5476
0
  }
5477
0
  WXS_ADD_GLOBAL(ctxt, ret);
5478
0
    } else
5479
0
  WXS_ADD_LOCAL(ctxt, ret);
5480
0
    WXS_ADD_PENDING(ctxt, ret);
5481
0
    return (ret);
5482
0
}
5483
5484
static xmlSchemaQNameRefPtr
5485
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5486
         xmlSchemaTypeType refType,
5487
         const xmlChar *refName,
5488
         const xmlChar *refNs)
5489
0
{
5490
0
    xmlSchemaQNameRefPtr ret;
5491
5492
0
    ret = (xmlSchemaQNameRefPtr)
5493
0
  xmlMalloc(sizeof(xmlSchemaQNameRef));
5494
0
    if (ret == NULL) {
5495
0
  xmlSchemaPErrMemory(pctxt,
5496
0
      "allocating QName reference item", NULL);
5497
0
  return (NULL);
5498
0
    }
5499
0
    ret->node = NULL;
5500
0
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5501
0
    ret->name = refName;
5502
0
    ret->targetNamespace = refNs;
5503
0
    ret->item = NULL;
5504
0
    ret->itemType = refType;
5505
    /*
5506
    * Store the reference item in the schema.
5507
    */
5508
0
    WXS_ADD_LOCAL(pctxt, ret);
5509
0
    return (ret);
5510
0
}
5511
5512
static xmlSchemaAttributeUseProhibPtr
5513
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5514
0
{
5515
0
    xmlSchemaAttributeUseProhibPtr ret;
5516
5517
0
    ret = (xmlSchemaAttributeUseProhibPtr)
5518
0
  xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5519
0
    if (ret == NULL) {
5520
0
  xmlSchemaPErrMemory(pctxt,
5521
0
      "allocating attribute use prohibition", NULL);
5522
0
  return (NULL);
5523
0
    }
5524
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5525
0
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5526
0
    WXS_ADD_LOCAL(pctxt, ret);
5527
0
    return (ret);
5528
0
}
5529
5530
5531
/**
5532
 * xmlSchemaAddModelGroup:
5533
 * @ctxt:  a schema parser context
5534
 * @schema:  the schema being built
5535
 * @type: the "compositor" type of the model group
5536
 * @node: the node in the schema doc
5537
 *
5538
 * Adds a schema model group
5539
 * *WARNING* this interface is highly subject to change
5540
 *
5541
 * Returns the new structure or NULL in case of error
5542
 */
5543
static xmlSchemaModelGroupPtr
5544
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5545
           xmlSchemaPtr schema,
5546
           xmlSchemaTypeType type,
5547
           xmlNodePtr node)
5548
0
{
5549
0
    xmlSchemaModelGroupPtr ret = NULL;
5550
5551
0
    if ((ctxt == NULL) || (schema == NULL))
5552
0
        return (NULL);
5553
5554
0
    ret = (xmlSchemaModelGroupPtr)
5555
0
  xmlMalloc(sizeof(xmlSchemaModelGroup));
5556
0
    if (ret == NULL) {
5557
0
  xmlSchemaPErrMemory(ctxt, "allocating model group component",
5558
0
      NULL);
5559
0
  return (NULL);
5560
0
    }
5561
0
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5562
0
    ret->type = type;
5563
0
    ret->node = node;
5564
0
    WXS_ADD_LOCAL(ctxt, ret);
5565
0
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5566
0
  (type == XML_SCHEMA_TYPE_CHOICE))
5567
0
  WXS_ADD_PENDING(ctxt, ret);
5568
0
    return (ret);
5569
0
}
5570
5571
5572
/**
5573
 * xmlSchemaAddParticle:
5574
 * @ctxt:  a schema parser context
5575
 * @schema:  the schema being built
5576
 * @node: the corresponding node in the schema doc
5577
 * @min: the minOccurs
5578
 * @max: the maxOccurs
5579
 *
5580
 * Adds an XML schema particle component.
5581
 * *WARNING* this interface is highly subject to change
5582
 *
5583
 * Returns the new structure or NULL in case of error
5584
 */
5585
static xmlSchemaParticlePtr
5586
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5587
         xmlNodePtr node, int min, int max)
5588
0
{
5589
0
    xmlSchemaParticlePtr ret = NULL;
5590
0
    if (ctxt == NULL)
5591
0
        return (NULL);
5592
5593
#ifdef DEBUG
5594
    fprintf(stderr, "Adding particle component\n");
5595
#endif
5596
0
    ret = (xmlSchemaParticlePtr)
5597
0
  xmlMalloc(sizeof(xmlSchemaParticle));
5598
0
    if (ret == NULL) {
5599
0
  xmlSchemaPErrMemory(ctxt, "allocating particle component",
5600
0
      NULL);
5601
0
  return (NULL);
5602
0
    }
5603
0
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5604
0
    ret->annot = NULL;
5605
0
    ret->node = node;
5606
0
    ret->minOccurs = min;
5607
0
    ret->maxOccurs = max;
5608
0
    ret->next = NULL;
5609
0
    ret->children = NULL;
5610
5611
0
    WXS_ADD_LOCAL(ctxt, ret);
5612
    /*
5613
    * Note that addition to pending components will be done locally
5614
    * to the specific parsing function, since the most particles
5615
    * need not to be fixed up (i.e. the reference to be resolved).
5616
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5617
    */
5618
0
    return (ret);
5619
0
}
5620
5621
/**
5622
 * xmlSchemaAddModelGroupDefinition:
5623
 * @ctxt:  a schema validation context
5624
 * @schema:  the schema being built
5625
 * @name:  the group name
5626
 *
5627
 * Add an XML schema Group definition
5628
 *
5629
 * Returns the new structure or NULL in case of error
5630
 */
5631
static xmlSchemaModelGroupDefPtr
5632
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5633
         xmlSchemaPtr schema,
5634
         const xmlChar *name,
5635
         const xmlChar *nsName,
5636
         xmlNodePtr node)
5637
0
{
5638
0
    xmlSchemaModelGroupDefPtr ret = NULL;
5639
5640
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5641
0
        return (NULL);
5642
5643
0
    ret = (xmlSchemaModelGroupDefPtr)
5644
0
  xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5645
0
    if (ret == NULL) {
5646
0
        xmlSchemaPErrMemory(ctxt, "adding group", NULL);
5647
0
        return (NULL);
5648
0
    }
5649
0
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5650
0
    ret->name = name;
5651
0
    ret->type = XML_SCHEMA_TYPE_GROUP;
5652
0
    ret->node = node;
5653
0
    ret->targetNamespace = nsName;
5654
5655
0
    if (ctxt->isRedefine) {
5656
0
  ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5657
0
      ret, name, nsName);
5658
0
  if (ctxt->redef == NULL) {
5659
0
      xmlFree(ret);
5660
0
      return(NULL);
5661
0
  }
5662
0
  ctxt->redefCounter = 0;
5663
0
    }
5664
0
    WXS_ADD_GLOBAL(ctxt, ret);
5665
0
    WXS_ADD_PENDING(ctxt, ret);
5666
0
    return (ret);
5667
0
}
5668
5669
/**
5670
 * xmlSchemaNewWildcardNs:
5671
 * @ctxt:  a schema validation context
5672
 *
5673
 * Creates a new wildcard namespace constraint.
5674
 *
5675
 * Returns the new structure or NULL in case of error
5676
 */
5677
static xmlSchemaWildcardNsPtr
5678
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5679
0
{
5680
0
    xmlSchemaWildcardNsPtr ret;
5681
5682
0
    ret = (xmlSchemaWildcardNsPtr)
5683
0
  xmlMalloc(sizeof(xmlSchemaWildcardNs));
5684
0
    if (ret == NULL) {
5685
0
  xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
5686
0
  return (NULL);
5687
0
    }
5688
0
    ret->value = NULL;
5689
0
    ret->next = NULL;
5690
0
    return (ret);
5691
0
}
5692
5693
static xmlSchemaIDCPtr
5694
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5695
                  const xmlChar *name, const xmlChar *nsName,
5696
      int category, xmlNodePtr node)
5697
0
{
5698
0
    xmlSchemaIDCPtr ret = NULL;
5699
5700
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5701
0
        return (NULL);
5702
5703
0
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5704
0
    if (ret == NULL) {
5705
0
        xmlSchemaPErrMemory(ctxt,
5706
0
      "allocating an identity-constraint definition", NULL);
5707
0
        return (NULL);
5708
0
    }
5709
0
    memset(ret, 0, sizeof(xmlSchemaIDC));
5710
    /* The target namespace of the parent element declaration. */
5711
0
    ret->targetNamespace = nsName;
5712
0
    ret->name = name;
5713
0
    ret->type = category;
5714
0
    ret->node = node;
5715
5716
0
    WXS_ADD_GLOBAL(ctxt, ret);
5717
    /*
5718
    * Only keyrefs need to be fixup up.
5719
    */
5720
0
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5721
0
  WXS_ADD_PENDING(ctxt, ret);
5722
0
    return (ret);
5723
0
}
5724
5725
/**
5726
 * xmlSchemaAddWildcard:
5727
 * @ctxt:  a schema validation context
5728
 * @schema: a schema
5729
 *
5730
 * Adds a wildcard.
5731
 * It corresponds to a xsd:anyAttribute and xsd:any.
5732
 *
5733
 * Returns the new structure or NULL in case of error
5734
 */
5735
static xmlSchemaWildcardPtr
5736
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5737
         xmlSchemaTypeType type, xmlNodePtr node)
5738
0
{
5739
0
    xmlSchemaWildcardPtr ret = NULL;
5740
5741
0
    if ((ctxt == NULL) || (schema == NULL))
5742
0
        return (NULL);
5743
5744
0
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5745
0
    if (ret == NULL) {
5746
0
        xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
5747
0
        return (NULL);
5748
0
    }
5749
0
    memset(ret, 0, sizeof(xmlSchemaWildcard));
5750
0
    ret->type = type;
5751
0
    ret->node = node;
5752
0
    WXS_ADD_LOCAL(ctxt, ret);
5753
0
    return (ret);
5754
0
}
5755
5756
static void
5757
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5758
0
{
5759
0
    if (group == NULL)
5760
0
  return;
5761
0
    if (group->members != NULL)
5762
0
  xmlSchemaItemListFree(group->members);
5763
0
    xmlFree(group);
5764
0
}
5765
5766
static void
5767
xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5768
0
{
5769
0
    xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5770
0
}
5771
5772
static xmlSchemaSubstGroupPtr
5773
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5774
           xmlSchemaElementPtr head)
5775
0
{
5776
0
    xmlSchemaSubstGroupPtr ret;
5777
5778
    /* Init subst group hash. */
5779
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5780
0
  WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5781
0
  if (WXS_SUBST_GROUPS(pctxt) == NULL)
5782
0
      return(NULL);
5783
0
    }
5784
    /* Create a new substitution group. */
5785
0
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5786
0
    if (ret == NULL) {
5787
0
  xmlSchemaPErrMemory(NULL,
5788
0
      "allocating a substitution group container", NULL);
5789
0
  return(NULL);
5790
0
    }
5791
0
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5792
0
    ret->head = head;
5793
    /* Create list of members. */
5794
0
    ret->members = xmlSchemaItemListCreate();
5795
0
    if (ret->members == NULL) {
5796
0
  xmlSchemaSubstGroupFree(ret);
5797
0
  return(NULL);
5798
0
    }
5799
    /* Add subst group to hash. */
5800
0
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5801
0
  head->name, head->targetNamespace, ret) != 0) {
5802
0
  PERROR_INT("xmlSchemaSubstGroupAdd",
5803
0
      "failed to add a new substitution container");
5804
0
  xmlSchemaSubstGroupFree(ret);
5805
0
  return(NULL);
5806
0
    }
5807
0
    return(ret);
5808
0
}
5809
5810
static xmlSchemaSubstGroupPtr
5811
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5812
           xmlSchemaElementPtr head)
5813
0
{
5814
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5815
0
  return(NULL);
5816
0
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5817
0
  head->name, head->targetNamespace));
5818
5819
0
}
5820
5821
/**
5822
 * xmlSchemaAddElementSubstitutionMember:
5823
 * @pctxt:  a schema parser context
5824
 * @head:  the head of the substitution group
5825
 * @member: the new member of the substitution group
5826
 *
5827
 * Allocate a new annotation structure.
5828
 *
5829
 * Returns the newly allocated structure or NULL in case or error
5830
 */
5831
static int
5832
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5833
              xmlSchemaElementPtr head,
5834
              xmlSchemaElementPtr member)
5835
0
{
5836
0
    xmlSchemaSubstGroupPtr substGroup = NULL;
5837
5838
0
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5839
0
  return (-1);
5840
5841
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5842
0
    if (substGroup == NULL)
5843
0
  substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5844
0
    if (substGroup == NULL)
5845
0
  return(-1);
5846
0
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5847
0
  return(-1);
5848
0
    return(0);
5849
0
}
5850
5851
/************************************************************************
5852
 *                  *
5853
 *    Utilities for parsing         *
5854
 *                  *
5855
 ************************************************************************/
5856
5857
/**
5858
 * xmlSchemaPValAttrNodeQNameValue:
5859
 * @ctxt:  a schema parser context
5860
 * @schema: the schema context
5861
 * @ownerItem: the parent as a schema object
5862
 * @value:  the QName value
5863
 * @uri:  the resulting namespace URI if found
5864
 * @local: the resulting local part if found, the attribute value otherwise
5865
 *
5866
 * Extracts the local name and the URI of a QName value and validates it.
5867
 * This one is intended to be used on attribute values that
5868
 * should resolve to schema components.
5869
 *
5870
 * Returns 0, in case the QName is valid, a positive error code
5871
 * if not valid and -1 if an internal error occurs.
5872
 */
5873
static int
5874
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5875
               xmlSchemaPtr schema,
5876
               xmlSchemaBasicItemPtr ownerItem,
5877
               xmlAttrPtr attr,
5878
               const xmlChar *value,
5879
               const xmlChar **uri,
5880
               const xmlChar **local)
5881
0
{
5882
0
    const xmlChar *pref;
5883
0
    xmlNsPtr ns;
5884
0
    int len, ret;
5885
5886
0
    *uri = NULL;
5887
0
    *local = NULL;
5888
0
    ret = xmlValidateQName(value, 1);
5889
0
    if (ret > 0) {
5890
0
  xmlSchemaPSimpleTypeErr(ctxt,
5891
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5892
0
      ownerItem, (xmlNodePtr) attr,
5893
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5894
0
      NULL, value, NULL, NULL, NULL);
5895
0
  *local = value;
5896
0
  return (ctxt->err);
5897
0
    } else if (ret < 0)
5898
0
  return (-1);
5899
5900
0
    if (!strchr((char *) value, ':')) {
5901
0
  ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5902
0
  if (ns && ns->href && ns->href[0])
5903
0
      *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5904
0
  else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5905
      /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5906
      * parser context. */
5907
      /*
5908
      * This one takes care of included schemas with no
5909
      * target namespace.
5910
      */
5911
0
      *uri = ctxt->targetNamespace;
5912
0
  }
5913
0
  *local = xmlDictLookup(ctxt->dict, value, -1);
5914
0
  return (0);
5915
0
    }
5916
    /*
5917
    * At this point xmlSplitQName3 has to return a local name.
5918
    */
5919
0
    *local = xmlSplitQName3(value, &len);
5920
0
    *local = xmlDictLookup(ctxt->dict, *local, -1);
5921
0
    pref = xmlDictLookup(ctxt->dict, value, len);
5922
0
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5923
0
    if (ns == NULL) {
5924
0
  xmlSchemaPSimpleTypeErr(ctxt,
5925
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5926
0
      ownerItem, (xmlNodePtr) attr,
5927
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5928
0
      "The value '%s' of simple type 'xs:QName' has no "
5929
0
      "corresponding namespace declaration in scope", value, NULL);
5930
0
  return (ctxt->err);
5931
0
    } else {
5932
0
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5933
0
    }
5934
0
    return (0);
5935
0
}
5936
5937
/**
5938
 * xmlSchemaPValAttrNodeQName:
5939
 * @ctxt:  a schema parser context
5940
 * @schema: the schema context
5941
 * @ownerItem: the owner as a schema object
5942
 * @attr:  the attribute node
5943
 * @uri:  the resulting namespace URI if found
5944
 * @local: the resulting local part if found, the attribute value otherwise
5945
 *
5946
 * Extracts and validates the QName of an attribute value.
5947
 * This one is intended to be used on attribute values that
5948
 * should resolve to schema components.
5949
 *
5950
 * Returns 0, in case the QName is valid, a positive error code
5951
 * if not valid and -1 if an internal error occurs.
5952
 */
5953
static int
5954
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5955
               xmlSchemaPtr schema,
5956
               xmlSchemaBasicItemPtr ownerItem,
5957
               xmlAttrPtr attr,
5958
               const xmlChar **uri,
5959
               const xmlChar **local)
5960
0
{
5961
0
    const xmlChar *value;
5962
5963
0
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5964
0
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5965
0
  ownerItem, attr, value, uri, local));
5966
0
}
5967
5968
/**
5969
 * xmlSchemaPValAttrQName:
5970
 * @ctxt:  a schema parser context
5971
 * @schema: the schema context
5972
 * @ownerItem: the owner as a schema object
5973
 * @ownerElem:  the parent node of the attribute
5974
 * @name:  the name of the attribute
5975
 * @uri:  the resulting namespace URI if found
5976
 * @local: the resulting local part if found, the attribute value otherwise
5977
 *
5978
 * Extracts and validates the QName of an attribute value.
5979
 *
5980
 * Returns 0, in case the QName is valid, a positive error code
5981
 * if not valid and -1 if an internal error occurs.
5982
 */
5983
static int
5984
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5985
           xmlSchemaPtr schema,
5986
           xmlSchemaBasicItemPtr ownerItem,
5987
           xmlNodePtr ownerElem,
5988
           const char *name,
5989
           const xmlChar **uri,
5990
           const xmlChar **local)
5991
0
{
5992
0
    xmlAttrPtr attr;
5993
5994
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
5995
0
    if (attr == NULL) {
5996
0
  *local = NULL;
5997
0
  *uri = NULL;
5998
0
  return (0);
5999
0
    }
6000
0
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
6001
0
  ownerItem, attr, uri, local));
6002
0
}
6003
6004
/**
6005
 * xmlSchemaPValAttrID:
6006
 * @ctxt:  a schema parser context
6007
 *
6008
 * Extracts and validates the ID of an attribute value.
6009
 *
6010
 * Returns 0, in case the ID is valid, a positive error code
6011
 * if not valid and -1 if an internal error occurs.
6012
 */
6013
static int
6014
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
6015
0
{
6016
0
    int ret;
6017
0
    const xmlChar *value;
6018
6019
0
    if (attr == NULL)
6020
0
  return(0);
6021
0
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
6022
0
    ret = xmlValidateNCName(value, 1);
6023
0
    if (ret == 0) {
6024
  /*
6025
  * NOTE: the IDness might have already be declared in the DTD
6026
  */
6027
0
  if (attr->atype != XML_ATTRIBUTE_ID) {
6028
0
      xmlIDPtr res;
6029
0
      xmlChar *strip;
6030
6031
      /*
6032
      * TODO: Use xmlSchemaStrip here; it's not exported at this
6033
      * moment.
6034
      */
6035
0
      strip = xmlSchemaCollapseString(value);
6036
0
      if (strip != NULL) {
6037
0
    xmlFree((xmlChar *) value);
6038
0
    value = strip;
6039
0
      }
6040
0
      res = xmlAddID(NULL, attr->doc, value, attr);
6041
0
      if (res == NULL) {
6042
0
    ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6043
0
    xmlSchemaPSimpleTypeErr(ctxt,
6044
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6045
0
        NULL, (xmlNodePtr) attr,
6046
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
6047
0
        NULL, NULL, "Duplicate value '%s' of simple "
6048
0
        "type 'xs:ID'", value, NULL);
6049
0
      } else
6050
0
    attr->atype = XML_ATTRIBUTE_ID;
6051
0
  }
6052
0
    } else if (ret > 0) {
6053
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6054
0
  xmlSchemaPSimpleTypeErr(ctxt,
6055
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6056
0
      NULL, (xmlNodePtr) attr,
6057
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
6058
0
      NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
6059
0
      "not a valid 'xs:NCName'",
6060
0
      value, NULL);
6061
0
    }
6062
0
    if (value != NULL)
6063
0
  xmlFree((xmlChar *)value);
6064
6065
0
    return (ret);
6066
0
}
6067
6068
static int
6069
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
6070
        xmlNodePtr ownerElem,
6071
        const xmlChar *name)
6072
0
{
6073
0
    xmlAttrPtr attr;
6074
6075
0
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
6076
0
    if (attr == NULL)
6077
0
  return(0);
6078
0
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
6079
6080
0
}
6081
6082
/**
6083
 * xmlGetMaxOccurs:
6084
 * @ctxt:  a schema validation context
6085
 * @node:  a subtree containing XML Schema information
6086
 *
6087
 * Get the maxOccurs property
6088
 *
6089
 * Returns the default if not found, or the value
6090
 */
6091
static int
6092
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6093
    int min, int max, int def, const char *expected)
6094
0
{
6095
0
    const xmlChar *val, *cur;
6096
0
    int ret = 0;
6097
0
    xmlAttrPtr attr;
6098
6099
0
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
6100
0
    if (attr == NULL)
6101
0
  return (def);
6102
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6103
6104
0
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
6105
0
  if (max != UNBOUNDED) {
6106
0
      xmlSchemaPSimpleTypeErr(ctxt,
6107
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6108
    /* XML_SCHEMAP_INVALID_MINOCCURS, */
6109
0
    NULL, (xmlNodePtr) attr, NULL, expected,
6110
0
    val, NULL, NULL, NULL);
6111
0
      return (def);
6112
0
  } else
6113
0
      return (UNBOUNDED);  /* encoding it with -1 might be another option */
6114
0
    }
6115
6116
0
    cur = val;
6117
0
    while (IS_BLANK_CH(*cur))
6118
0
        cur++;
6119
0
    if (*cur == 0) {
6120
0
        xmlSchemaPSimpleTypeErr(ctxt,
6121
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6122
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6123
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6124
0
      val, NULL, NULL, NULL);
6125
0
  return (def);
6126
0
    }
6127
0
    while ((*cur >= '0') && (*cur <= '9')) {
6128
0
        if (ret > INT_MAX / 10) {
6129
0
            ret = INT_MAX;
6130
0
        } else {
6131
0
            int digit = *cur - '0';
6132
0
            ret *= 10;
6133
0
            if (ret > INT_MAX - digit)
6134
0
                ret = INT_MAX;
6135
0
            else
6136
0
                ret += digit;
6137
0
        }
6138
0
        cur++;
6139
0
    }
6140
0
    while (IS_BLANK_CH(*cur))
6141
0
        cur++;
6142
    /*
6143
    * TODO: Restrict the maximal value to Integer.
6144
    */
6145
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6146
0
  xmlSchemaPSimpleTypeErr(ctxt,
6147
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6148
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6149
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6150
0
      val, NULL, NULL, NULL);
6151
0
        return (def);
6152
0
    }
6153
0
    return (ret);
6154
0
}
6155
6156
/**
6157
 * xmlGetMinOccurs:
6158
 * @ctxt:  a schema validation context
6159
 * @node:  a subtree containing XML Schema information
6160
 *
6161
 * Get the minOccurs property
6162
 *
6163
 * Returns the default if not found, or the value
6164
 */
6165
static int
6166
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6167
    int min, int max, int def, const char *expected)
6168
0
{
6169
0
    const xmlChar *val, *cur;
6170
0
    int ret = 0;
6171
0
    xmlAttrPtr attr;
6172
6173
0
    attr = xmlSchemaGetPropNode(node, "minOccurs");
6174
0
    if (attr == NULL)
6175
0
  return (def);
6176
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6177
0
    cur = val;
6178
0
    while (IS_BLANK_CH(*cur))
6179
0
        cur++;
6180
0
    if (*cur == 0) {
6181
0
        xmlSchemaPSimpleTypeErr(ctxt,
6182
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6183
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6184
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6185
0
      val, NULL, NULL, NULL);
6186
0
        return (def);
6187
0
    }
6188
0
    while ((*cur >= '0') && (*cur <= '9')) {
6189
0
        if (ret > INT_MAX / 10) {
6190
0
            ret = INT_MAX;
6191
0
        } else {
6192
0
            int digit = *cur - '0';
6193
0
            ret *= 10;
6194
0
            if (ret > INT_MAX - digit)
6195
0
                ret = INT_MAX;
6196
0
            else
6197
0
                ret += digit;
6198
0
        }
6199
0
        cur++;
6200
0
    }
6201
0
    while (IS_BLANK_CH(*cur))
6202
0
        cur++;
6203
    /*
6204
    * TODO: Restrict the maximal value to Integer.
6205
    */
6206
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6207
0
  xmlSchemaPSimpleTypeErr(ctxt,
6208
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6209
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6210
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6211
0
      val, NULL, NULL, NULL);
6212
0
        return (def);
6213
0
    }
6214
0
    return (ret);
6215
0
}
6216
6217
/**
6218
 * xmlSchemaPGetBoolNodeValue:
6219
 * @ctxt:  a schema validation context
6220
 * @ownerItem:  the owner as a schema item
6221
 * @node: the node holding the value
6222
 *
6223
 * Converts a boolean string value into 1 or 0.
6224
 *
6225
 * Returns 0 or 1.
6226
 */
6227
static int
6228
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6229
         xmlSchemaBasicItemPtr ownerItem,
6230
         xmlNodePtr node)
6231
0
{
6232
0
    xmlChar *value = NULL;
6233
0
    int res = 0;
6234
6235
0
    value = xmlNodeGetContent(node);
6236
    /*
6237
    * 3.2.2.1 Lexical representation
6238
    * An instance of a datatype that is defined as `boolean`
6239
    * can have the following legal literals {true, false, 1, 0}.
6240
    */
6241
0
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6242
0
        res = 1;
6243
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6244
0
        res = 0;
6245
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6246
0
  res = 1;
6247
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6248
0
        res = 0;
6249
0
    else {
6250
0
        xmlSchemaPSimpleTypeErr(ctxt,
6251
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6252
0
      ownerItem, node,
6253
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6254
0
      NULL, BAD_CAST value,
6255
0
      NULL, NULL, NULL);
6256
0
    }
6257
0
    if (value != NULL)
6258
0
  xmlFree(value);
6259
0
    return (res);
6260
0
}
6261
6262
/**
6263
 * xmlGetBooleanProp:
6264
 * @ctxt:  a schema validation context
6265
 * @node:  a subtree containing XML Schema information
6266
 * @name:  the attribute name
6267
 * @def:  the default value
6268
 *
6269
 * Evaluate if a boolean property is set
6270
 *
6271
 * Returns the default if not found, 0 if found to be false,
6272
 * 1 if found to be true
6273
 */
6274
static int
6275
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6276
      xmlNodePtr node,
6277
                  const char *name, int def)
6278
0
{
6279
0
    const xmlChar *val;
6280
6281
0
    val = xmlSchemaGetProp(ctxt, node, name);
6282
0
    if (val == NULL)
6283
0
        return (def);
6284
    /*
6285
    * 3.2.2.1 Lexical representation
6286
    * An instance of a datatype that is defined as `boolean`
6287
    * can have the following legal literals {true, false, 1, 0}.
6288
    */
6289
0
    if (xmlStrEqual(val, BAD_CAST "true"))
6290
0
        def = 1;
6291
0
    else if (xmlStrEqual(val, BAD_CAST "false"))
6292
0
        def = 0;
6293
0
    else if (xmlStrEqual(val, BAD_CAST "1"))
6294
0
  def = 1;
6295
0
    else if (xmlStrEqual(val, BAD_CAST "0"))
6296
0
        def = 0;
6297
0
    else {
6298
0
        xmlSchemaPSimpleTypeErr(ctxt,
6299
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6300
0
      NULL,
6301
0
      (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6302
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6303
0
      NULL, val, NULL, NULL, NULL);
6304
0
    }
6305
0
    return (def);
6306
0
}
6307
6308
/************************************************************************
6309
 *                  *
6310
 *    Schema extraction from an Infoset     *
6311
 *                  *
6312
 ************************************************************************/
6313
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6314
                                                 ctxt, xmlSchemaPtr schema,
6315
                                                 xmlNodePtr node,
6316
             int topLevel);
6317
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6318
                                                  ctxt,
6319
                                                  xmlSchemaPtr schema,
6320
                                                  xmlNodePtr node,
6321
              int topLevel);
6322
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6323
                                                  ctxt,
6324
                                                  xmlSchemaPtr schema,
6325
                                                  xmlNodePtr node,
6326
              xmlSchemaTypeType parentType);
6327
static xmlSchemaBasicItemPtr
6328
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6329
           xmlSchemaPtr schema,
6330
           xmlNodePtr node,
6331
           xmlSchemaItemListPtr uses,
6332
           int parentType);
6333
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6334
                                           xmlSchemaPtr schema,
6335
                                           xmlNodePtr node);
6336
static xmlSchemaWildcardPtr
6337
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6338
                           xmlSchemaPtr schema, xmlNodePtr node);
6339
6340
/**
6341
 * xmlSchemaPValAttrNodeValue:
6342
 *
6343
 * @pctxt:  a schema parser context
6344
 * @ownerItem: the schema object owner if existent
6345
 * @attr:  the schema attribute node being validated
6346
 * @value: the value
6347
 * @type: the built-in type to be validated against
6348
 *
6349
 * Validates a value against the given built-in type.
6350
 * This one is intended to be used internally for validation
6351
 * of schema attribute values during parsing of the schema.
6352
 *
6353
 * Returns 0 if the value is valid, a positive error code
6354
 * number otherwise and -1 in case of an internal or API error.
6355
 */
6356
static int
6357
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6358
         xmlSchemaBasicItemPtr ownerItem,
6359
         xmlAttrPtr attr,
6360
         const xmlChar *value,
6361
         xmlSchemaTypePtr type)
6362
0
{
6363
6364
0
    int ret = 0;
6365
6366
    /*
6367
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6368
    * one is really meant to be used internally, so better not.
6369
    */
6370
0
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6371
0
  return (-1);
6372
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6373
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6374
0
      "the given type is not a built-in type");
6375
0
  return (-1);
6376
0
    }
6377
0
    switch (type->builtInType) {
6378
0
  case XML_SCHEMAS_NCNAME:
6379
0
  case XML_SCHEMAS_QNAME:
6380
0
  case XML_SCHEMAS_ANYURI:
6381
0
  case XML_SCHEMAS_TOKEN:
6382
0
  case XML_SCHEMAS_LANGUAGE:
6383
0
      ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6384
0
    (xmlNodePtr) attr);
6385
0
      break;
6386
0
  default: {
6387
0
      PERROR_INT("xmlSchemaPValAttrNodeValue",
6388
0
    "validation using the given type is not supported while "
6389
0
    "parsing a schema");
6390
0
      return (-1);
6391
0
  }
6392
0
    }
6393
    /*
6394
    * TODO: Should we use the S4S error codes instead?
6395
    */
6396
0
    if (ret < 0) {
6397
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6398
0
      "failed to validate a schema attribute value");
6399
0
  return (-1);
6400
0
    } else if (ret > 0) {
6401
0
  if (WXS_IS_LIST(type))
6402
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6403
0
  else
6404
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6405
0
  xmlSchemaPSimpleTypeErr(pctxt,
6406
0
      ret, ownerItem, (xmlNodePtr) attr,
6407
0
      type, NULL, value, NULL, NULL, NULL);
6408
0
    }
6409
0
    return (ret);
6410
0
}
6411
6412
/**
6413
 * xmlSchemaPValAttrNode:
6414
 *
6415
 * @ctxt:  a schema parser context
6416
 * @ownerItem: the schema object owner if existent
6417
 * @attr:  the schema attribute node being validated
6418
 * @type: the built-in type to be validated against
6419
 * @value: the resulting value if any
6420
 *
6421
 * Extracts and validates a value against the given built-in type.
6422
 * This one is intended to be used internally for validation
6423
 * of schema attribute values during parsing of the schema.
6424
 *
6425
 * Returns 0 if the value is valid, a positive error code
6426
 * number otherwise and -1 in case of an internal or API error.
6427
 */
6428
static int
6429
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6430
         xmlSchemaBasicItemPtr ownerItem,
6431
         xmlAttrPtr attr,
6432
         xmlSchemaTypePtr type,
6433
         const xmlChar **value)
6434
0
{
6435
0
    const xmlChar *val;
6436
6437
0
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6438
0
  return (-1);
6439
6440
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6441
0
    if (value != NULL)
6442
0
  *value = val;
6443
6444
0
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6445
0
  val, type));
6446
0
}
6447
6448
/**
6449
 * xmlSchemaPValAttr:
6450
 *
6451
 * @ctxt:  a schema parser context
6452
 * @node: the element node of the attribute
6453
 * @ownerItem: the schema object owner if existent
6454
 * @ownerElem: the owner element node
6455
 * @name:  the name of the schema attribute node
6456
 * @type: the built-in type to be validated against
6457
 * @value: the resulting value if any
6458
 *
6459
 * Extracts and validates a value against the given built-in type.
6460
 * This one is intended to be used internally for validation
6461
 * of schema attribute values during parsing of the schema.
6462
 *
6463
 * Returns 0 if the value is valid, a positive error code
6464
 * number otherwise and -1 in case of an internal or API error.
6465
 */
6466
static int
6467
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6468
           xmlSchemaBasicItemPtr ownerItem,
6469
           xmlNodePtr ownerElem,
6470
           const char *name,
6471
           xmlSchemaTypePtr type,
6472
           const xmlChar **value)
6473
0
{
6474
0
    xmlAttrPtr attr;
6475
6476
0
    if ((ctxt == NULL) || (type == NULL)) {
6477
0
  if (value != NULL)
6478
0
      *value = NULL;
6479
0
  return (-1);
6480
0
    }
6481
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6482
0
  if (value != NULL)
6483
0
      *value = NULL;
6484
0
  xmlSchemaPErr(ctxt, ownerElem,
6485
0
      XML_SCHEMAP_INTERNAL,
6486
0
      "Internal error: xmlSchemaPValAttr, the given "
6487
0
      "type '%s' is not a built-in type.\n",
6488
0
      type->name, NULL);
6489
0
  return (-1);
6490
0
    }
6491
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
6492
0
    if (attr == NULL) {
6493
0
  if (value != NULL)
6494
0
      *value = NULL;
6495
0
  return (0);
6496
0
    }
6497
0
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6498
0
  type, value));
6499
0
}
6500
6501
static int
6502
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6503
      xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6504
      xmlNodePtr node,
6505
      xmlAttrPtr attr,
6506
      const xmlChar *namespaceName)
6507
0
{
6508
    /* TODO: Pointer comparison instead? */
6509
0
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6510
0
  return (0);
6511
0
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
6512
0
  return (0);
6513
    /*
6514
    * Check if the referenced namespace was <import>ed.
6515
    */
6516
0
    if (WXS_BUCKET(pctxt)->relations != NULL) {
6517
0
  xmlSchemaSchemaRelationPtr rel;
6518
6519
0
  rel = WXS_BUCKET(pctxt)->relations;
6520
0
  do {
6521
0
      if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6522
0
    xmlStrEqual(namespaceName, rel->importNamespace))
6523
0
    return (0);
6524
0
      rel = rel->next;
6525
0
  } while (rel != NULL);
6526
0
    }
6527
    /*
6528
    * No matching <import>ed namespace found.
6529
    */
6530
0
    {
6531
0
  xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6532
6533
0
  if (namespaceName == NULL)
6534
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6535
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6536
0
    "References from this schema to components in no "
6537
0
    "namespace are not allowed, since not indicated by an "
6538
0
    "import statement", NULL, NULL);
6539
0
  else
6540
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6541
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6542
0
    "References from this schema to components in the "
6543
0
    "namespace '%s' are not allowed, since not indicated by an "
6544
0
    "import statement", namespaceName, NULL);
6545
0
    }
6546
0
    return (XML_SCHEMAP_SRC_RESOLVE);
6547
0
}
6548
6549
/**
6550
 * xmlSchemaParseLocalAttributes:
6551
 * @ctxt:  a schema validation context
6552
 * @schema:  the schema being built
6553
 * @node:  a subtree containing XML Schema information
6554
 * @type:  the hosting type where the attributes will be anchored
6555
 *
6556
 * Parses attribute uses and attribute declarations and
6557
 * attribute group references.
6558
 */
6559
static int
6560
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6561
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
6562
      int parentType, int *hasRefs)
6563
0
{
6564
0
    void *item;
6565
6566
0
    while ((IS_SCHEMA((*child), "attribute")) ||
6567
0
           (IS_SCHEMA((*child), "attributeGroup"))) {
6568
0
        if (IS_SCHEMA((*child), "attribute")) {
6569
0
      item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6570
0
    *list, parentType);
6571
0
        } else {
6572
0
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6573
0
      if ((item != NULL) && (hasRefs != NULL))
6574
0
    *hasRefs = 1;
6575
0
        }
6576
0
  if (item != NULL) {
6577
0
      if (*list == NULL) {
6578
    /* TODO: Customize grow factor. */
6579
0
    *list = xmlSchemaItemListCreate();
6580
0
    if (*list == NULL)
6581
0
        return(-1);
6582
0
      }
6583
0
      if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6584
0
    return(-1);
6585
0
  }
6586
0
        *child = (*child)->next;
6587
0
    }
6588
0
    return (0);
6589
0
}
6590
6591
/**
6592
 * xmlSchemaParseAnnotation:
6593
 * @ctxt:  a schema validation context
6594
 * @schema:  the schema being built
6595
 * @node:  a subtree containing XML Schema information
6596
 *
6597
 * parse a XML schema Attribute declaration
6598
 * *WARNING* this interface is highly subject to change
6599
 *
6600
 * Returns -1 in case of error, 0 if the declaration is improper and
6601
 *         1 in case of success.
6602
 */
6603
static xmlSchemaAnnotPtr
6604
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6605
0
{
6606
0
    xmlSchemaAnnotPtr ret;
6607
0
    xmlNodePtr child = NULL;
6608
0
    xmlAttrPtr attr;
6609
0
    int barked = 0;
6610
6611
    /*
6612
    * INFO: S4S completed.
6613
    */
6614
    /*
6615
    * id = ID
6616
    * {any attributes with non-schema namespace . . .}>
6617
    * Content: (appinfo | documentation)*
6618
    */
6619
0
    if ((ctxt == NULL) || (node == NULL))
6620
0
        return (NULL);
6621
0
    if (needed)
6622
0
  ret = xmlSchemaNewAnnot(ctxt, node);
6623
0
    else
6624
0
  ret = NULL;
6625
0
    attr = node->properties;
6626
0
    while (attr != NULL) {
6627
0
  if (((attr->ns == NULL) &&
6628
0
      (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6629
0
      ((attr->ns != NULL) &&
6630
0
      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6631
6632
0
      xmlSchemaPIllegalAttrErr(ctxt,
6633
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6634
0
  }
6635
0
  attr = attr->next;
6636
0
    }
6637
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6638
    /*
6639
    * And now for the children...
6640
    */
6641
0
    child = node->children;
6642
0
    while (child != NULL) {
6643
0
  if (IS_SCHEMA(child, "appinfo")) {
6644
      /* TODO: make available the content of "appinfo". */
6645
      /*
6646
      * source = anyURI
6647
      * {any attributes with non-schema namespace . . .}>
6648
      * Content: ({any})*
6649
      */
6650
0
      attr = child->properties;
6651
0
      while (attr != NULL) {
6652
0
    if (((attr->ns == NULL) &&
6653
0
         (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6654
0
         ((attr->ns != NULL) &&
6655
0
          xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6656
6657
0
        xmlSchemaPIllegalAttrErr(ctxt,
6658
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6659
0
    }
6660
0
    attr = attr->next;
6661
0
      }
6662
0
      xmlSchemaPValAttr(ctxt, NULL, child, "source",
6663
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6664
0
      child = child->next;
6665
0
  } else if (IS_SCHEMA(child, "documentation")) {
6666
      /* TODO: make available the content of "documentation". */
6667
      /*
6668
      * source = anyURI
6669
      * {any attributes with non-schema namespace . . .}>
6670
      * Content: ({any})*
6671
      */
6672
0
      attr = child->properties;
6673
0
      while (attr != NULL) {
6674
0
    if (attr->ns == NULL) {
6675
0
        if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6676
0
      xmlSchemaPIllegalAttrErr(ctxt,
6677
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6678
0
        }
6679
0
    } else {
6680
0
        if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6681
0
      (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6682
0
      (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6683
6684
0
      xmlSchemaPIllegalAttrErr(ctxt,
6685
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6686
0
        }
6687
0
    }
6688
0
    attr = attr->next;
6689
0
      }
6690
      /*
6691
      * Attribute "xml:lang".
6692
      */
6693
0
      attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6694
0
      if (attr != NULL)
6695
0
    xmlSchemaPValAttrNode(ctxt, NULL, attr,
6696
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6697
0
      child = child->next;
6698
0
  } else {
6699
0
      if (!barked)
6700
0
    xmlSchemaPContentErr(ctxt,
6701
0
        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6702
0
        NULL, node, child, NULL, "(appinfo | documentation)*");
6703
0
      barked = 1;
6704
0
      child = child->next;
6705
0
  }
6706
0
    }
6707
6708
0
    return (ret);
6709
0
}
6710
6711
/**
6712
 * xmlSchemaParseFacet:
6713
 * @ctxt:  a schema validation context
6714
 * @schema:  the schema being built
6715
 * @node:  a subtree containing XML Schema information
6716
 *
6717
 * parse a XML schema Facet declaration
6718
 * *WARNING* this interface is highly subject to change
6719
 *
6720
 * Returns the new type structure or NULL in case of error
6721
 */
6722
static xmlSchemaFacetPtr
6723
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6724
                    xmlNodePtr node)
6725
0
{
6726
0
    xmlSchemaFacetPtr facet;
6727
0
    xmlNodePtr child = NULL;
6728
0
    const xmlChar *value;
6729
6730
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6731
0
        return (NULL);
6732
6733
0
    facet = xmlSchemaNewFacet();
6734
0
    if (facet == NULL) {
6735
0
        xmlSchemaPErrMemory(ctxt, "allocating facet", node);
6736
0
        return (NULL);
6737
0
    }
6738
0
    facet->node = node;
6739
0
    value = xmlSchemaGetProp(ctxt, node, "value");
6740
0
    if (value == NULL) {
6741
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6742
0
                       "Facet %s has no value\n", node->name, NULL);
6743
0
        xmlSchemaFreeFacet(facet);
6744
0
        return (NULL);
6745
0
    }
6746
0
    if (IS_SCHEMA(node, "minInclusive")) {
6747
0
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6748
0
    } else if (IS_SCHEMA(node, "minExclusive")) {
6749
0
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6750
0
    } else if (IS_SCHEMA(node, "maxInclusive")) {
6751
0
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6752
0
    } else if (IS_SCHEMA(node, "maxExclusive")) {
6753
0
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6754
0
    } else if (IS_SCHEMA(node, "totalDigits")) {
6755
0
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6756
0
    } else if (IS_SCHEMA(node, "fractionDigits")) {
6757
0
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6758
0
    } else if (IS_SCHEMA(node, "pattern")) {
6759
0
        facet->type = XML_SCHEMA_FACET_PATTERN;
6760
0
    } else if (IS_SCHEMA(node, "enumeration")) {
6761
0
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
6762
0
    } else if (IS_SCHEMA(node, "whiteSpace")) {
6763
0
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
6764
0
    } else if (IS_SCHEMA(node, "length")) {
6765
0
        facet->type = XML_SCHEMA_FACET_LENGTH;
6766
0
    } else if (IS_SCHEMA(node, "maxLength")) {
6767
0
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6768
0
    } else if (IS_SCHEMA(node, "minLength")) {
6769
0
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
6770
0
    } else {
6771
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6772
0
                       "Unknown facet type %s\n", node->name, NULL);
6773
0
        xmlSchemaFreeFacet(facet);
6774
0
        return (NULL);
6775
0
    }
6776
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6777
0
    facet->value = value;
6778
0
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6779
0
  (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6780
0
  const xmlChar *fixed;
6781
6782
0
  fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6783
0
  if (fixed != NULL) {
6784
0
      if (xmlStrEqual(fixed, BAD_CAST "true"))
6785
0
    facet->fixed = 1;
6786
0
  }
6787
0
    }
6788
0
    child = node->children;
6789
6790
0
    if (IS_SCHEMA(child, "annotation")) {
6791
0
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6792
0
        child = child->next;
6793
0
    }
6794
0
    if (child != NULL) {
6795
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6796
0
                       "Facet %s has unexpected child content\n",
6797
0
                       node->name, NULL);
6798
0
    }
6799
0
    return (facet);
6800
0
}
6801
6802
/**
6803
 * xmlSchemaParseWildcardNs:
6804
 * @ctxt:  a schema parser context
6805
 * @wildc:  the wildcard, already created
6806
 * @node:  a subtree containing XML Schema information
6807
 *
6808
 * Parses the attribute "processContents" and "namespace"
6809
 * of a xsd:anyAttribute and xsd:any.
6810
 * *WARNING* this interface is highly subject to change
6811
 *
6812
 * Returns 0 if everything goes fine, a positive error code
6813
 * if something is not valid and -1 if an internal error occurs.
6814
 */
6815
static int
6816
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6817
       xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6818
       xmlSchemaWildcardPtr wildc,
6819
       xmlNodePtr node)
6820
0
{
6821
0
    const xmlChar *pc, *ns, *dictnsItem;
6822
0
    int ret = 0;
6823
0
    xmlChar *nsItem;
6824
0
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6825
0
    xmlAttrPtr attr;
6826
6827
0
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
6828
0
    if ((pc == NULL)
6829
0
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6830
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6831
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6832
0
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6833
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6834
0
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
6835
0
    } else {
6836
0
        xmlSchemaPSimpleTypeErr(ctxt,
6837
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6838
0
      NULL, node,
6839
0
      NULL, "(strict | skip | lax)", pc,
6840
0
      NULL, NULL, NULL);
6841
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6842
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6843
0
    }
6844
    /*
6845
     * Build the namespace constraints.
6846
     */
6847
0
    attr = xmlSchemaGetPropNode(node, "namespace");
6848
0
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6849
0
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6850
0
  wildc->any = 1;
6851
0
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6852
0
  wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6853
0
  if (wildc->negNsSet == NULL) {
6854
0
      return (-1);
6855
0
  }
6856
0
  wildc->negNsSet->value = ctxt->targetNamespace;
6857
0
    } else {
6858
0
  const xmlChar *end, *cur;
6859
6860
0
  cur = ns;
6861
0
  do {
6862
0
      while (IS_BLANK_CH(*cur))
6863
0
    cur++;
6864
0
      end = cur;
6865
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6866
0
    end++;
6867
0
      if (end == cur)
6868
0
    break;
6869
0
      nsItem = xmlStrndup(cur, end - cur);
6870
0
      if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6871
0
        (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6872
0
    xmlSchemaPSimpleTypeErr(ctxt,
6873
0
        XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6874
0
        NULL, (xmlNodePtr) attr,
6875
0
        NULL,
6876
0
        "((##any | ##other) | List of (xs:anyURI | "
6877
0
        "(##targetNamespace | ##local)))",
6878
0
        nsItem, NULL, NULL, NULL);
6879
0
    ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6880
0
      } else {
6881
0
    if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6882
0
        dictnsItem = ctxt->targetNamespace;
6883
0
    } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6884
0
        dictnsItem = NULL;
6885
0
    } else {
6886
        /*
6887
        * Validate the item (anyURI).
6888
        */
6889
0
        xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6890
0
      nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6891
0
        dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6892
0
    }
6893
    /*
6894
    * Avoid duplicate namespaces.
6895
    */
6896
0
    tmp = wildc->nsSet;
6897
0
    while (tmp != NULL) {
6898
0
        if (dictnsItem == tmp->value)
6899
0
      break;
6900
0
        tmp = tmp->next;
6901
0
    }
6902
0
    if (tmp == NULL) {
6903
0
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6904
0
        if (tmp == NULL) {
6905
0
      xmlFree(nsItem);
6906
0
      return (-1);
6907
0
        }
6908
0
        tmp->value = dictnsItem;
6909
0
        tmp->next = NULL;
6910
0
        if (wildc->nsSet == NULL)
6911
0
      wildc->nsSet = tmp;
6912
0
        else if (lastNs != NULL)
6913
0
      lastNs->next = tmp;
6914
0
        lastNs = tmp;
6915
0
    }
6916
6917
0
      }
6918
0
      xmlFree(nsItem);
6919
0
      cur = end;
6920
0
  } while (*cur != 0);
6921
0
    }
6922
0
    return (ret);
6923
0
}
6924
6925
static int
6926
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6927
         xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6928
         xmlNodePtr node,
6929
         int minOccurs,
6930
0
         int maxOccurs) {
6931
6932
0
    if ((maxOccurs == 0) && ( minOccurs == 0))
6933
0
  return (0);
6934
0
    if (maxOccurs != UNBOUNDED) {
6935
  /*
6936
  * TODO: Maybe we should better not create the particle,
6937
  * if min/max is invalid, since it could confuse the build of the
6938
  * content model.
6939
  */
6940
  /*
6941
  * 3.9.6 Schema Component Constraint: Particle Correct
6942
  *
6943
  */
6944
0
  if (maxOccurs < 1) {
6945
      /*
6946
      * 2.2 {max occurs} must be greater than or equal to 1.
6947
      */
6948
0
      xmlSchemaPCustomAttrErr(ctxt,
6949
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6950
0
    NULL, NULL,
6951
0
    xmlSchemaGetPropNode(node, "maxOccurs"),
6952
0
    "The value must be greater than or equal to 1");
6953
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6954
0
  } else if (minOccurs > maxOccurs) {
6955
      /*
6956
      * 2.1 {min occurs} must not be greater than {max occurs}.
6957
      */
6958
0
      xmlSchemaPCustomAttrErr(ctxt,
6959
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6960
0
    NULL, NULL,
6961
0
    xmlSchemaGetPropNode(node, "minOccurs"),
6962
0
    "The value must not be greater than the value of 'maxOccurs'");
6963
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6964
0
  }
6965
0
    }
6966
0
    return (0);
6967
0
}
6968
6969
/**
6970
 * xmlSchemaParseAny:
6971
 * @ctxt:  a schema validation context
6972
 * @schema:  the schema being built
6973
 * @node:  a subtree containing XML Schema information
6974
 *
6975
 * Parsea a XML schema <any> element. A particle and wildcard
6976
 * will be created (except if minOccurs==maxOccurs==0, in this case
6977
 * nothing will be created).
6978
 * *WARNING* this interface is highly subject to change
6979
 *
6980
 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6981
 */
6982
static xmlSchemaParticlePtr
6983
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6984
                  xmlNodePtr node)
6985
0
{
6986
0
    xmlSchemaParticlePtr particle;
6987
0
    xmlNodePtr child = NULL;
6988
0
    xmlSchemaWildcardPtr wild;
6989
0
    int min, max;
6990
0
    xmlAttrPtr attr;
6991
0
    xmlSchemaAnnotPtr annot = NULL;
6992
6993
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6994
0
        return (NULL);
6995
    /*
6996
    * Check for illegal attributes.
6997
    */
6998
0
    attr = node->properties;
6999
0
    while (attr != NULL) {
7000
0
  if (attr->ns == NULL) {
7001
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7002
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
7003
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
7004
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7005
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7006
0
    xmlSchemaPIllegalAttrErr(ctxt,
7007
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7008
0
      }
7009
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7010
0
      xmlSchemaPIllegalAttrErr(ctxt,
7011
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7012
0
  }
7013
0
  attr = attr->next;
7014
0
    }
7015
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7016
    /*
7017
    * minOccurs/maxOccurs.
7018
    */
7019
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
7020
0
  "(xs:nonNegativeInteger | unbounded)");
7021
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
7022
0
  "xs:nonNegativeInteger");
7023
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
7024
    /*
7025
    * Create & parse the wildcard.
7026
    */
7027
0
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
7028
0
    if (wild == NULL)
7029
0
  return (NULL);
7030
0
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
7031
    /*
7032
    * And now for the children...
7033
    */
7034
0
    child = node->children;
7035
0
    if (IS_SCHEMA(child, "annotation")) {
7036
0
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7037
0
        child = child->next;
7038
0
    }
7039
0
    if (child != NULL) {
7040
0
  xmlSchemaPContentErr(ctxt,
7041
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7042
0
      NULL, node, child,
7043
0
      NULL, "(annotation?)");
7044
0
    }
7045
    /*
7046
    * No component if minOccurs==maxOccurs==0.
7047
    */
7048
0
    if ((min == 0) && (max == 0)) {
7049
  /* Don't free the wildcard, since it's already on the list. */
7050
0
  return (NULL);
7051
0
    }
7052
    /*
7053
    * Create the particle.
7054
    */
7055
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
7056
0
    if (particle == NULL)
7057
0
        return (NULL);
7058
0
    particle->annot = annot;
7059
0
    particle->children = (xmlSchemaTreeItemPtr) wild;
7060
7061
0
    return (particle);
7062
0
}
7063
7064
/**
7065
 * xmlSchemaParseNotation:
7066
 * @ctxt:  a schema validation context
7067
 * @schema:  the schema being built
7068
 * @node:  a subtree containing XML Schema information
7069
 *
7070
 * parse a XML schema Notation declaration
7071
 *
7072
 * Returns the new structure or NULL in case of error
7073
 */
7074
static xmlSchemaNotationPtr
7075
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
7076
                       xmlNodePtr node)
7077
0
{
7078
0
    const xmlChar *name;
7079
0
    xmlSchemaNotationPtr ret;
7080
0
    xmlNodePtr child = NULL;
7081
7082
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7083
0
        return (NULL);
7084
0
    name = xmlSchemaGetProp(ctxt, node, "name");
7085
0
    if (name == NULL) {
7086
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
7087
0
                       "Notation has no name\n", NULL, NULL);
7088
0
        return (NULL);
7089
0
    }
7090
0
    ret = xmlSchemaAddNotation(ctxt, schema, name,
7091
0
  ctxt->targetNamespace, node);
7092
0
    if (ret == NULL)
7093
0
        return (NULL);
7094
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7095
7096
0
    child = node->children;
7097
0
    if (IS_SCHEMA(child, "annotation")) {
7098
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7099
0
        child = child->next;
7100
0
    }
7101
0
    if (child != NULL) {
7102
0
  xmlSchemaPContentErr(ctxt,
7103
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7104
0
      NULL, node, child,
7105
0
      NULL, "(annotation?)");
7106
0
    }
7107
7108
0
    return (ret);
7109
0
}
7110
7111
/**
7112
 * xmlSchemaParseAnyAttribute:
7113
 * @ctxt:  a schema validation context
7114
 * @schema:  the schema being built
7115
 * @node:  a subtree containing XML Schema information
7116
 *
7117
 * parse a XML schema AnyAttribute declaration
7118
 * *WARNING* this interface is highly subject to change
7119
 *
7120
 * Returns a wildcard or NULL.
7121
 */
7122
static xmlSchemaWildcardPtr
7123
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7124
                           xmlSchemaPtr schema, xmlNodePtr node)
7125
0
{
7126
0
    xmlSchemaWildcardPtr ret;
7127
0
    xmlNodePtr child = NULL;
7128
0
    xmlAttrPtr attr;
7129
7130
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7131
0
        return (NULL);
7132
7133
0
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7134
0
  node);
7135
0
    if (ret == NULL) {
7136
0
        return (NULL);
7137
0
    }
7138
    /*
7139
    * Check for illegal attributes.
7140
    */
7141
0
    attr = node->properties;
7142
0
    while (attr != NULL) {
7143
0
  if (attr->ns == NULL) {
7144
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7145
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7146
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7147
0
    xmlSchemaPIllegalAttrErr(ctxt,
7148
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7149
0
      }
7150
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7151
0
      xmlSchemaPIllegalAttrErr(ctxt,
7152
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7153
0
  }
7154
0
  attr = attr->next;
7155
0
    }
7156
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7157
    /*
7158
    * Parse the namespace list.
7159
    */
7160
0
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7161
0
  return (NULL);
7162
    /*
7163
    * And now for the children...
7164
    */
7165
0
    child = node->children;
7166
0
    if (IS_SCHEMA(child, "annotation")) {
7167
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7168
0
        child = child->next;
7169
0
    }
7170
0
    if (child != NULL) {
7171
0
  xmlSchemaPContentErr(ctxt,
7172
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7173
0
      NULL, node, child,
7174
0
      NULL, "(annotation?)");
7175
0
    }
7176
7177
0
    return (ret);
7178
0
}
7179
7180
7181
/**
7182
 * xmlSchemaParseAttribute:
7183
 * @ctxt:  a schema validation context
7184
 * @schema:  the schema being built
7185
 * @node:  a subtree containing XML Schema information
7186
 *
7187
 * parse a XML schema Attribute declaration
7188
 * *WARNING* this interface is highly subject to change
7189
 *
7190
 * Returns the attribute declaration.
7191
 */
7192
static xmlSchemaBasicItemPtr
7193
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7194
           xmlSchemaPtr schema,
7195
           xmlNodePtr node,
7196
           xmlSchemaItemListPtr uses,
7197
           int parentType)
7198
0
{
7199
0
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
7200
0
    xmlSchemaAttributeUsePtr use = NULL;
7201
0
    xmlNodePtr child = NULL;
7202
0
    xmlAttrPtr attr;
7203
0
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7204
0
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7205
0
    int nberrors, hasForm = 0, defValueType = 0;
7206
7207
0
#define WXS_ATTR_DEF_VAL_DEFAULT 1
7208
0
#define WXS_ATTR_DEF_VAL_FIXED 2
7209
7210
    /*
7211
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7212
     */
7213
7214
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7215
0
        return (NULL);
7216
0
    attr = xmlSchemaGetPropNode(node, "ref");
7217
0
    if (attr != NULL) {
7218
0
  if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7219
0
      NULL, attr, &tmpNs, &tmpName) != 0) {
7220
0
      return (NULL);
7221
0
  }
7222
0
  if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7223
0
      return(NULL);
7224
0
  isRef = 1;
7225
0
    }
7226
0
    nberrors = pctxt->nberrors;
7227
    /*
7228
    * Check for illegal attributes.
7229
    */
7230
0
    attr = node->properties;
7231
0
    while (attr != NULL) {
7232
0
  if (attr->ns == NULL) {
7233
0
      if (isRef) {
7234
0
    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7235
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7236
0
        goto attr_next;
7237
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7238
0
        goto attr_next;
7239
0
    }
7240
0
      } else {
7241
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7242
0
        goto attr_next;
7243
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7244
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7245
0
        goto attr_next;
7246
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7247
0
        xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7248
0
      attr, &tmpNs, &tmpName);
7249
0
        goto attr_next;
7250
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7251
        /*
7252
        * Evaluate the target namespace
7253
        */
7254
0
        hasForm = 1;
7255
0
        attrValue = xmlSchemaGetNodeContent(pctxt,
7256
0
      (xmlNodePtr) attr);
7257
0
        if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7258
0
      ns = pctxt->targetNamespace;
7259
0
        } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7260
0
        {
7261
0
      xmlSchemaPSimpleTypeErr(pctxt,
7262
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7263
0
          NULL, (xmlNodePtr) attr,
7264
0
          NULL, "(qualified | unqualified)",
7265
0
          attrValue, NULL, NULL, NULL);
7266
0
        }
7267
0
        goto attr_next;
7268
0
    }
7269
0
      }
7270
0
      if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7271
7272
0
    attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7273
    /* TODO: Maybe we need to normalize the value beforehand. */
7274
0
    if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7275
0
        occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7276
0
    else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7277
0
        occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7278
0
    else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7279
0
        occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7280
0
    else {
7281
0
        xmlSchemaPSimpleTypeErr(pctxt,
7282
0
      XML_SCHEMAP_INVALID_ATTR_USE,
7283
0
      NULL, (xmlNodePtr) attr,
7284
0
      NULL, "(optional | prohibited | required)",
7285
0
      attrValue, NULL, NULL, NULL);
7286
0
    }
7287
0
    goto attr_next;
7288
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7289
    /*
7290
    * 3.2.3 : 1
7291
    * default and fixed must not both be present.
7292
    */
7293
0
    if (defValue) {
7294
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7295
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7296
0
      NULL, attr, "default", "fixed");
7297
0
    } else {
7298
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7299
0
        defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7300
0
    }
7301
0
    goto attr_next;
7302
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7303
    /*
7304
    * 3.2.3 : 1
7305
    * default and fixed must not both be present.
7306
    */
7307
0
    if (defValue) {
7308
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7309
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7310
0
      NULL, attr, "default", "fixed");
7311
0
    } else {
7312
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7313
0
        defValueType = WXS_ATTR_DEF_VAL_FIXED;
7314
0
    }
7315
0
    goto attr_next;
7316
0
      }
7317
0
  } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7318
0
      goto attr_next;
7319
7320
0
  xmlSchemaPIllegalAttrErr(pctxt,
7321
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7322
7323
0
attr_next:
7324
0
  attr = attr->next;
7325
0
    }
7326
    /*
7327
    * 3.2.3 : 2
7328
    * If default and use are both present, use must have
7329
    * the actual value optional.
7330
    */
7331
0
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7332
0
  (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7333
0
  xmlSchemaPSimpleTypeErr(pctxt,
7334
0
      XML_SCHEMAP_SRC_ATTRIBUTE_2,
7335
0
      NULL, node, NULL,
7336
0
      "(optional | prohibited | required)", NULL,
7337
0
      "The value of the attribute 'use' must be 'optional' "
7338
0
      "if the attribute 'default' is present",
7339
0
      NULL, NULL);
7340
0
    }
7341
    /*
7342
    * We want correct attributes.
7343
    */
7344
0
    if (nberrors != pctxt->nberrors)
7345
0
  return(NULL);
7346
0
    if (! isRef) {
7347
0
  xmlSchemaAttributePtr attrDecl;
7348
7349
  /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7350
0
  if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7351
0
      ns = pctxt->targetNamespace;
7352
  /*
7353
  * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7354
  * TODO: Move this to the component layer.
7355
  */
7356
0
  if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7357
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7358
0
    XML_SCHEMAP_NO_XSI,
7359
0
    node, NULL,
7360
0
    "The target namespace must not match '%s'",
7361
0
    xmlSchemaInstanceNs, NULL);
7362
0
  }
7363
0
  attr = xmlSchemaGetPropNode(node, "name");
7364
0
  if (attr == NULL) {
7365
0
      xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7366
0
    NULL, node, "name", NULL);
7367
0
      return (NULL);
7368
0
  }
7369
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7370
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7371
0
      return (NULL);
7372
0
  }
7373
  /*
7374
  * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7375
  * TODO: Move this to the component layer.
7376
  */
7377
0
  if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7378
0
      xmlSchemaPSimpleTypeErr(pctxt,
7379
0
    XML_SCHEMAP_NO_XMLNS,
7380
0
    NULL, (xmlNodePtr) attr,
7381
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7382
0
    "The value of the attribute must not match 'xmlns'",
7383
0
    NULL, NULL);
7384
0
      return (NULL);
7385
0
  }
7386
0
  if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7387
0
      goto check_children;
7388
  /*
7389
  * Create the attribute use component.
7390
  */
7391
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7392
0
  if (use == NULL)
7393
0
      return(NULL);
7394
0
  use->occurs = occurs;
7395
  /*
7396
  * Create the attribute declaration.
7397
  */
7398
0
  attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7399
0
  if (attrDecl == NULL)
7400
0
      return (NULL);
7401
0
  if (tmpName != NULL) {
7402
0
      attrDecl->typeName = tmpName;
7403
0
      attrDecl->typeNs = tmpNs;
7404
0
  }
7405
0
  use->attrDecl = attrDecl;
7406
  /*
7407
  * Value constraint.
7408
  */
7409
0
  if (defValue != NULL) {
7410
0
      attrDecl->defValue = defValue;
7411
0
      if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7412
0
    attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7413
0
  }
7414
0
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7415
0
  xmlSchemaQNameRefPtr ref;
7416
7417
  /*
7418
  * Create the attribute use component.
7419
  */
7420
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7421
0
  if (use == NULL)
7422
0
      return(NULL);
7423
  /*
7424
  * We need to resolve the reference at later stage.
7425
  */
7426
0
  WXS_ADD_PENDING(pctxt, use);
7427
0
  use->occurs = occurs;
7428
  /*
7429
  * Create a QName reference to the attribute declaration.
7430
  */
7431
0
  ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7432
0
      tmpName, tmpNs);
7433
0
  if (ref == NULL)
7434
0
      return(NULL);
7435
  /*
7436
  * Assign the reference. This will be substituted for the
7437
  * referenced attribute declaration when the QName is resolved.
7438
  */
7439
0
  use->attrDecl = WXS_ATTR_CAST ref;
7440
  /*
7441
  * Value constraint.
7442
  */
7443
0
  if (defValue != NULL)
7444
0
      use->defValue = defValue;
7445
0
  if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7446
0
      use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7447
0
    }
7448
7449
0
check_children:
7450
    /*
7451
    * And now for the children...
7452
    */
7453
0
    child = node->children;
7454
0
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7455
0
  xmlSchemaAttributeUseProhibPtr prohib;
7456
7457
0
  if (IS_SCHEMA(child, "annotation")) {
7458
0
      xmlSchemaParseAnnotation(pctxt, child, 0);
7459
0
      child = child->next;
7460
0
  }
7461
0
  if (child != NULL) {
7462
0
      xmlSchemaPContentErr(pctxt,
7463
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7464
0
    NULL, node, child, NULL,
7465
0
    "(annotation?)");
7466
0
  }
7467
  /*
7468
  * Check for pointlessness of attribute prohibitions.
7469
  */
7470
0
  if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7471
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7472
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7473
0
    node, NULL,
7474
0
    "Skipping attribute use prohibition, since it is "
7475
0
    "pointless inside an <attributeGroup>",
7476
0
    NULL, NULL, NULL);
7477
0
      return(NULL);
7478
0
  } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7479
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7480
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7481
0
    node, NULL,
7482
0
    "Skipping attribute use prohibition, since it is "
7483
0
    "pointless when extending a type",
7484
0
    NULL, NULL, NULL);
7485
0
      return(NULL);
7486
0
  }
7487
0
  if (! isRef) {
7488
0
      tmpName = name;
7489
0
      tmpNs = ns;
7490
0
  }
7491
  /*
7492
  * Check for duplicate attribute prohibitions.
7493
  */
7494
0
  if (uses) {
7495
0
      int i;
7496
7497
0
      for (i = 0; i < uses->nbItems; i++) {
7498
0
    use = uses->items[i];
7499
0
    if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7500
0
        (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7501
0
        (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7502
0
    {
7503
0
        xmlChar *str = NULL;
7504
7505
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7506
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7507
0
      node, NULL,
7508
0
      "Skipping duplicate attribute use prohibition '%s'",
7509
0
      xmlSchemaFormatQName(&str, tmpNs, tmpName),
7510
0
      NULL, NULL);
7511
0
        FREE_AND_NULL(str)
7512
0
        return(NULL);
7513
0
    }
7514
0
      }
7515
0
  }
7516
  /*
7517
  * Create the attribute prohibition helper component.
7518
  */
7519
0
  prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7520
0
  if (prohib == NULL)
7521
0
      return(NULL);
7522
0
  prohib->node = node;
7523
0
  prohib->name = tmpName;
7524
0
  prohib->targetNamespace = tmpNs;
7525
0
  if (isRef) {
7526
      /*
7527
      * We need at least to resolve to the attribute declaration.
7528
      */
7529
0
      WXS_ADD_PENDING(pctxt, prohib);
7530
0
  }
7531
0
  return(WXS_BASIC_CAST prohib);
7532
0
    } else {
7533
0
  if (IS_SCHEMA(child, "annotation")) {
7534
      /*
7535
      * TODO: Should this go into the attr decl?
7536
      */
7537
0
      use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7538
0
      child = child->next;
7539
0
  }
7540
0
  if (isRef) {
7541
0
      if (child != NULL) {
7542
0
    if (IS_SCHEMA(child, "simpleType"))
7543
        /*
7544
        * 3.2.3 : 3.2
7545
        * If ref is present, then all of <simpleType>,
7546
        * form and type must be absent.
7547
        */
7548
0
        xmlSchemaPContentErr(pctxt,
7549
0
      XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7550
0
      NULL, node, child, NULL,
7551
0
      "(annotation?)");
7552
0
    else
7553
0
        xmlSchemaPContentErr(pctxt,
7554
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7555
0
      NULL, node, child, NULL,
7556
0
      "(annotation?)");
7557
0
      }
7558
0
  } else {
7559
0
      if (IS_SCHEMA(child, "simpleType")) {
7560
0
    if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7561
        /*
7562
        * 3.2.3 : 4
7563
        * type and <simpleType> must not both be present.
7564
        */
7565
0
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7566
0
      NULL, node, child,
7567
0
      "The attribute 'type' and the <simpleType> child "
7568
0
      "are mutually exclusive", NULL);
7569
0
    } else
7570
0
        WXS_ATTRUSE_TYPEDEF(use) =
7571
0
      xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7572
0
    child = child->next;
7573
0
      }
7574
0
      if (child != NULL)
7575
0
    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7576
0
    NULL, node, child, NULL,
7577
0
    "(annotation?, simpleType?)");
7578
0
  }
7579
0
    }
7580
0
    return (WXS_BASIC_CAST use);
7581
0
}
7582
7583
7584
static xmlSchemaAttributePtr
7585
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7586
            xmlSchemaPtr schema,
7587
            xmlNodePtr node)
7588
0
{
7589
0
    const xmlChar *attrValue;
7590
0
    xmlSchemaAttributePtr ret;
7591
0
    xmlNodePtr child = NULL;
7592
0
    xmlAttrPtr attr;
7593
7594
    /*
7595
     * Note that the w3c spec assumes the schema to be validated with schema
7596
     * for schemas beforehand.
7597
     *
7598
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7599
     */
7600
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7601
0
        return (NULL);
7602
    /*
7603
    * 3.2.3 : 3.1
7604
    * One of ref or name must be present, but not both
7605
    */
7606
0
    attr = xmlSchemaGetPropNode(node, "name");
7607
0
    if (attr == NULL) {
7608
0
  xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7609
0
      NULL, node, "name", NULL);
7610
0
  return (NULL);
7611
0
    }
7612
0
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7613
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7614
0
  return (NULL);
7615
0
    }
7616
    /*
7617
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7618
    * TODO: Move this to the component layer.
7619
    */
7620
0
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7621
0
  xmlSchemaPSimpleTypeErr(pctxt,
7622
0
      XML_SCHEMAP_NO_XMLNS,
7623
0
      NULL, (xmlNodePtr) attr,
7624
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7625
0
      "The value of the attribute must not match 'xmlns'",
7626
0
      NULL, NULL);
7627
0
  return (NULL);
7628
0
    }
7629
    /*
7630
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7631
    * TODO: Move this to the component layer.
7632
    *       Or better leave it here and add it to the component layer
7633
    *       if we have a schema construction API.
7634
    */
7635
0
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7636
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
7637
0
      XML_SCHEMAP_NO_XSI, node, NULL,
7638
0
      "The target namespace must not match '%s'",
7639
0
      xmlSchemaInstanceNs, NULL);
7640
0
    }
7641
7642
0
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7643
0
  pctxt->targetNamespace, node, 1);
7644
0
    if (ret == NULL)
7645
0
  return (NULL);
7646
0
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7647
7648
    /*
7649
    * Check for illegal attributes.
7650
    */
7651
0
    attr = node->properties;
7652
0
    while (attr != NULL) {
7653
0
  if (attr->ns == NULL) {
7654
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7655
0
    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7656
0
    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7657
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7658
0
    (!xmlStrEqual(attr->name, BAD_CAST "type")))
7659
0
      {
7660
0
    xmlSchemaPIllegalAttrErr(pctxt,
7661
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7662
0
      }
7663
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7664
0
      xmlSchemaPIllegalAttrErr(pctxt,
7665
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7666
0
  }
7667
0
  attr = attr->next;
7668
0
    }
7669
0
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
7670
0
  node, "type", &ret->typeNs, &ret->typeName);
7671
7672
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7673
    /*
7674
    * Attribute "fixed".
7675
    */
7676
0
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7677
0
    if (ret->defValue != NULL)
7678
0
  ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7679
    /*
7680
    * Attribute "default".
7681
    */
7682
0
    attr = xmlSchemaGetPropNode(node, "default");
7683
0
    if (attr != NULL) {
7684
  /*
7685
  * 3.2.3 : 1
7686
  * default and fixed must not both be present.
7687
  */
7688
0
  if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7689
0
      xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7690
0
    WXS_BASIC_CAST ret, attr, "default", "fixed");
7691
0
  } else
7692
0
      ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7693
0
    }
7694
    /*
7695
    * And now for the children...
7696
    */
7697
0
    child = node->children;
7698
0
    if (IS_SCHEMA(child, "annotation")) {
7699
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7700
0
        child = child->next;
7701
0
    }
7702
0
    if (IS_SCHEMA(child, "simpleType")) {
7703
0
  if (ret->typeName != NULL) {
7704
      /*
7705
      * 3.2.3 : 4
7706
      * type and <simpleType> must not both be present.
7707
      */
7708
0
      xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7709
0
    NULL, node, child,
7710
0
    "The attribute 'type' and the <simpleType> child "
7711
0
    "are mutually exclusive", NULL);
7712
0
  } else
7713
0
      ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7714
0
  child = child->next;
7715
0
    }
7716
0
    if (child != NULL)
7717
0
  xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7718
0
      NULL, node, child, NULL,
7719
0
      "(annotation?, simpleType?)");
7720
7721
0
    return (ret);
7722
0
}
7723
7724
/**
7725
 * xmlSchemaParseAttributeGroupRef:
7726
 * @ctxt:  a schema validation context
7727
 * @schema:  the schema being built
7728
 * @node:  a subtree containing XML Schema information
7729
 *
7730
 * Parse an attribute group definition reference.
7731
 * Note that a reference to an attribute group does not
7732
 * correspond to any component at all.
7733
 * *WARNING* this interface is highly subject to change
7734
 *
7735
 * Returns the attribute group or NULL in case of error.
7736
 */
7737
static xmlSchemaQNameRefPtr
7738
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7739
        xmlSchemaPtr schema,
7740
        xmlNodePtr node)
7741
0
{
7742
0
    xmlSchemaQNameRefPtr ret;
7743
0
    xmlNodePtr child = NULL;
7744
0
    xmlAttrPtr attr;
7745
0
    const xmlChar *refNs = NULL, *ref = NULL;
7746
7747
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7748
0
        return (NULL);
7749
7750
0
    attr = xmlSchemaGetPropNode(node, "ref");
7751
0
    if (attr == NULL) {
7752
0
  xmlSchemaPMissingAttrErr(pctxt,
7753
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7754
0
      NULL, node, "ref", NULL);
7755
0
  return (NULL);
7756
0
    }
7757
0
    xmlSchemaPValAttrNodeQName(pctxt, schema,
7758
0
  NULL, attr, &refNs, &ref);
7759
0
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7760
0
  return(NULL);
7761
7762
    /*
7763
    * Check for illegal attributes.
7764
    */
7765
0
    attr = node->properties;
7766
0
    while (attr != NULL) {
7767
0
  if (attr->ns == NULL) {
7768
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7769
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7770
0
      {
7771
0
    xmlSchemaPIllegalAttrErr(pctxt,
7772
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7773
0
      }
7774
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7775
0
      xmlSchemaPIllegalAttrErr(pctxt,
7776
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7777
0
  }
7778
0
  attr = attr->next;
7779
0
    }
7780
    /* Attribute ID */
7781
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7782
7783
    /*
7784
    * And now for the children...
7785
    */
7786
0
    child = node->children;
7787
0
    if (IS_SCHEMA(child, "annotation")) {
7788
  /*
7789
  * TODO: We do not have a place to store the annotation, do we?
7790
  */
7791
0
        xmlSchemaParseAnnotation(pctxt, child, 0);
7792
0
        child = child->next;
7793
0
    }
7794
0
    if (child != NULL) {
7795
0
  xmlSchemaPContentErr(pctxt,
7796
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7797
0
      NULL, node, child, NULL,
7798
0
      "(annotation?)");
7799
0
    }
7800
7801
    /*
7802
    * Handle attribute group redefinitions.
7803
    */
7804
0
    if (pctxt->isRedefine && pctxt->redef &&
7805
0
  (pctxt->redef->item->type ==
7806
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7807
0
  (ref == pctxt->redef->refName) &&
7808
0
  (refNs == pctxt->redef->refTargetNs))
7809
0
    {
7810
  /*
7811
  * SPEC src-redefine:
7812
  * (7.1) "If it has an <attributeGroup> among its contents
7813
  * the `actual value` of whose ref [attribute] is the same
7814
  * as the `actual value` of its own name attribute plus
7815
  * target namespace, then it must have exactly one such group."
7816
  */
7817
0
  if (pctxt->redefCounter != 0) {
7818
0
      xmlChar *str = NULL;
7819
7820
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7821
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7822
0
    "The redefining attribute group definition "
7823
0
    "'%s' must not contain more than one "
7824
0
    "reference to the redefined definition",
7825
0
    xmlSchemaFormatQName(&str, refNs, ref), NULL);
7826
0
      FREE_AND_NULL(str);
7827
0
      return(NULL);
7828
0
  }
7829
0
  pctxt->redefCounter++;
7830
  /*
7831
  * URGENT TODO: How to ensure that the reference will not be
7832
  * handled by the normal component resolution mechanism?
7833
  */
7834
0
  ret = xmlSchemaNewQNameRef(pctxt,
7835
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7836
0
  if (ret == NULL)
7837
0
      return(NULL);
7838
0
  ret->node = node;
7839
0
  pctxt->redef->reference = WXS_BASIC_CAST ret;
7840
0
    } else {
7841
  /*
7842
  * Create a QName-reference helper component. We will substitute this
7843
  * component for the attribute uses of the referenced attribute group
7844
  * definition.
7845
  */
7846
0
  ret = xmlSchemaNewQNameRef(pctxt,
7847
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7848
0
  if (ret == NULL)
7849
0
      return(NULL);
7850
0
  ret->node = node;
7851
  /* Add to pending items, to be able to resolve the reference. */
7852
0
  WXS_ADD_PENDING(pctxt, ret);
7853
0
    }
7854
0
    return (ret);
7855
0
}
7856
7857
/**
7858
 * xmlSchemaParseAttributeGroupDefinition:
7859
 * @pctxt:  a schema validation context
7860
 * @schema:  the schema being built
7861
 * @node:  a subtree containing XML Schema information
7862
 *
7863
 * parse a XML schema Attribute Group declaration
7864
 * *WARNING* this interface is highly subject to change
7865
 *
7866
 * Returns the attribute group definition or NULL in case of error.
7867
 */
7868
static xmlSchemaAttributeGroupPtr
7869
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7870
               xmlSchemaPtr schema,
7871
               xmlNodePtr node)
7872
0
{
7873
0
    const xmlChar *name;
7874
0
    xmlSchemaAttributeGroupPtr ret;
7875
0
    xmlNodePtr child = NULL;
7876
0
    xmlAttrPtr attr;
7877
0
    int hasRefs = 0;
7878
7879
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7880
0
        return (NULL);
7881
7882
0
    attr = xmlSchemaGetPropNode(node, "name");
7883
0
    if (attr == NULL) {
7884
0
  xmlSchemaPMissingAttrErr(pctxt,
7885
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7886
0
      NULL, node, "name", NULL);
7887
0
  return (NULL);
7888
0
    }
7889
    /*
7890
    * The name is crucial, exit if invalid.
7891
    */
7892
0
    if (xmlSchemaPValAttrNode(pctxt,
7893
0
  NULL, attr,
7894
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7895
0
  return (NULL);
7896
0
    }
7897
0
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7898
0
  name, pctxt->targetNamespace, node);
7899
0
    if (ret == NULL)
7900
0
  return (NULL);
7901
    /*
7902
    * Check for illegal attributes.
7903
    */
7904
0
    attr = node->properties;
7905
0
    while (attr != NULL) {
7906
0
  if (attr->ns == NULL) {
7907
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7908
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7909
0
      {
7910
0
    xmlSchemaPIllegalAttrErr(pctxt,
7911
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7912
0
      }
7913
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7914
0
      xmlSchemaPIllegalAttrErr(pctxt,
7915
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7916
0
  }
7917
0
  attr = attr->next;
7918
0
    }
7919
    /* Attribute ID */
7920
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7921
    /*
7922
    * And now for the children...
7923
    */
7924
0
    child = node->children;
7925
0
    if (IS_SCHEMA(child, "annotation")) {
7926
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7927
0
        child = child->next;
7928
0
    }
7929
    /*
7930
    * Parse contained attribute decls/refs.
7931
    */
7932
0
    if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7933
0
  (xmlSchemaItemListPtr *) &(ret->attrUses),
7934
0
  XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7935
0
  return(NULL);
7936
0
    if (hasRefs)
7937
0
  ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7938
    /*
7939
    * Parse the attribute wildcard.
7940
    */
7941
0
    if (IS_SCHEMA(child, "anyAttribute")) {
7942
0
  ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7943
0
      schema, child);
7944
0
  child = child->next;
7945
0
    }
7946
0
    if (child != NULL) {
7947
0
  xmlSchemaPContentErr(pctxt,
7948
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7949
0
      NULL, node, child, NULL,
7950
0
      "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7951
0
    }
7952
0
    return (ret);
7953
0
}
7954
7955
/**
7956
 * xmlSchemaPValAttrFormDefault:
7957
 * @value:  the value
7958
 * @flags: the flags to be modified
7959
 * @flagQualified: the specific flag for "qualified"
7960
 *
7961
 * Returns 0 if the value is valid, 1 otherwise.
7962
 */
7963
static int
7964
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7965
           int *flags,
7966
           int flagQualified)
7967
0
{
7968
0
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
7969
0
  if  ((*flags & flagQualified) == 0)
7970
0
      *flags |= flagQualified;
7971
0
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7972
0
  return (1);
7973
7974
0
    return (0);
7975
0
}
7976
7977
/**
7978
 * xmlSchemaPValAttrBlockFinal:
7979
 * @value:  the value
7980
 * @flags: the flags to be modified
7981
 * @flagAll: the specific flag for "#all"
7982
 * @flagExtension: the specific flag for "extension"
7983
 * @flagRestriction: the specific flag for "restriction"
7984
 * @flagSubstitution: the specific flag for "substitution"
7985
 * @flagList: the specific flag for "list"
7986
 * @flagUnion: the specific flag for "union"
7987
 *
7988
 * Validates the value of the attribute "final" and "block". The value
7989
 * is converted into the specified flag values and returned in @flags.
7990
 *
7991
 * Returns 0 if the value is valid, 1 otherwise.
7992
 */
7993
7994
static int
7995
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7996
          int *flags,
7997
          int flagAll,
7998
          int flagExtension,
7999
          int flagRestriction,
8000
          int flagSubstitution,
8001
          int flagList,
8002
          int flagUnion)
8003
0
{
8004
0
    int ret = 0;
8005
8006
    /*
8007
    * TODO: This does not check for duplicate entries.
8008
    */
8009
0
    if ((flags == NULL) || (value == NULL))
8010
0
  return (-1);
8011
0
    if (value[0] == 0)
8012
0
  return (0);
8013
0
    if (xmlStrEqual(value, BAD_CAST "#all")) {
8014
0
  if (flagAll != -1)
8015
0
      *flags |= flagAll;
8016
0
  else {
8017
0
      if (flagExtension != -1)
8018
0
    *flags |= flagExtension;
8019
0
      if (flagRestriction != -1)
8020
0
    *flags |= flagRestriction;
8021
0
      if (flagSubstitution != -1)
8022
0
    *flags |= flagSubstitution;
8023
0
      if (flagList != -1)
8024
0
    *flags |= flagList;
8025
0
      if (flagUnion != -1)
8026
0
    *flags |= flagUnion;
8027
0
  }
8028
0
    } else {
8029
0
  const xmlChar *end, *cur = value;
8030
0
  xmlChar *item;
8031
8032
0
  do {
8033
0
      while (IS_BLANK_CH(*cur))
8034
0
    cur++;
8035
0
      end = cur;
8036
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8037
0
    end++;
8038
0
      if (end == cur)
8039
0
    break;
8040
0
      item = xmlStrndup(cur, end - cur);
8041
0
      if (xmlStrEqual(item, BAD_CAST "extension")) {
8042
0
    if (flagExtension != -1) {
8043
0
        if ((*flags & flagExtension) == 0)
8044
0
      *flags |= flagExtension;
8045
0
    } else
8046
0
        ret = 1;
8047
0
      } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
8048
0
    if (flagRestriction != -1) {
8049
0
        if ((*flags & flagRestriction) == 0)
8050
0
      *flags |= flagRestriction;
8051
0
    } else
8052
0
        ret = 1;
8053
0
      } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
8054
0
    if (flagSubstitution != -1) {
8055
0
        if ((*flags & flagSubstitution) == 0)
8056
0
      *flags |= flagSubstitution;
8057
0
    } else
8058
0
        ret = 1;
8059
0
      } else if (xmlStrEqual(item, BAD_CAST "list")) {
8060
0
    if (flagList != -1) {
8061
0
        if ((*flags & flagList) == 0)
8062
0
      *flags |= flagList;
8063
0
    } else
8064
0
        ret = 1;
8065
0
      } else if (xmlStrEqual(item, BAD_CAST "union")) {
8066
0
    if (flagUnion != -1) {
8067
0
        if ((*flags & flagUnion) == 0)
8068
0
      *flags |= flagUnion;
8069
0
    } else
8070
0
        ret = 1;
8071
0
      } else
8072
0
    ret = 1;
8073
0
      if (item != NULL)
8074
0
    xmlFree(item);
8075
0
      cur = end;
8076
0
  } while ((ret == 0) && (*cur != 0));
8077
0
    }
8078
8079
0
    return (ret);
8080
0
}
8081
8082
static int
8083
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
8084
           xmlSchemaIDCPtr idc,
8085
           xmlSchemaIDCSelectPtr selector,
8086
           xmlAttrPtr attr,
8087
           int isField)
8088
0
{
8089
0
    xmlNodePtr node;
8090
8091
    /*
8092
    * c-selector-xpath:
8093
    * Schema Component Constraint: Selector Value OK
8094
    *
8095
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
8096
    * in [XPath].
8097
    */
8098
0
    if (selector == NULL) {
8099
0
  xmlSchemaPErr(ctxt, idc->node,
8100
0
      XML_SCHEMAP_INTERNAL,
8101
0
      "Internal error: xmlSchemaCheckCSelectorXPath, "
8102
0
      "the selector is not specified.\n", NULL, NULL);
8103
0
  return (-1);
8104
0
    }
8105
0
    if (attr == NULL)
8106
0
  node = idc->node;
8107
0
    else
8108
0
  node = (xmlNodePtr) attr;
8109
0
    if (selector->xpath == NULL) {
8110
0
  xmlSchemaPCustomErr(ctxt,
8111
      /* TODO: Adjust error code. */
8112
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8113
0
      NULL, node,
8114
0
      "The XPath expression of the selector is not valid", NULL);
8115
0
  return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8116
0
    } else {
8117
0
  const xmlChar **nsArray = NULL;
8118
0
  xmlNsPtr *nsList = NULL;
8119
  /*
8120
  * Compile the XPath expression.
8121
  */
8122
  /*
8123
  * TODO: We need the array of in-scope namespaces for compilation.
8124
  * TODO: Call xmlPatterncompile with different options for selector/
8125
  * field.
8126
  */
8127
0
  if (attr == NULL)
8128
0
      nsList = NULL;
8129
0
  else
8130
0
      nsList = xmlGetNsList(attr->doc, attr->parent);
8131
  /*
8132
  * Build an array of prefixes and namespaces.
8133
  */
8134
0
  if (nsList != NULL) {
8135
0
      int i, count = 0;
8136
8137
0
      for (i = 0; nsList[i] != NULL; i++)
8138
0
    count++;
8139
8140
0
      nsArray = (const xmlChar **) xmlMalloc(
8141
0
    (count * 2 + 1) * sizeof(const xmlChar *));
8142
0
      if (nsArray == NULL) {
8143
0
    xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
8144
0
        NULL);
8145
0
    xmlFree(nsList);
8146
0
    return (-1);
8147
0
      }
8148
0
      for (i = 0; i < count; i++) {
8149
0
    nsArray[2 * i] = nsList[i]->href;
8150
0
    nsArray[2 * i + 1] = nsList[i]->prefix;
8151
0
      }
8152
0
      nsArray[count * 2] = NULL;
8153
0
      xmlFree(nsList);
8154
0
  }
8155
  /*
8156
  * TODO: Differentiate between "selector" and "field".
8157
  */
8158
0
  if (isField)
8159
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8160
0
    NULL, XML_PATTERN_XSFIELD, nsArray);
8161
0
  else
8162
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8163
0
    NULL, XML_PATTERN_XSSEL, nsArray);
8164
0
  if (nsArray != NULL)
8165
0
      xmlFree((xmlChar **) nsArray);
8166
8167
0
  if (selector->xpathComp == NULL) {
8168
0
      xmlSchemaPCustomErr(ctxt,
8169
    /* TODO: Adjust error code? */
8170
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8171
0
    NULL, node,
8172
0
    "The XPath expression '%s' could not be "
8173
0
    "compiled", selector->xpath);
8174
0
      return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8175
0
  }
8176
0
    }
8177
0
    return (0);
8178
0
}
8179
8180
#define ADD_ANNOTATION(annot)   \
8181
0
    xmlSchemaAnnotPtr cur = item->annot; \
8182
0
    if (item->annot == NULL) {  \
8183
0
  item->annot = annot;    \
8184
0
  return (annot);         \
8185
0
    }                           \
8186
0
    cur = item->annot;          \
8187
0
    if (cur->next != NULL) {    \
8188
0
  cur = cur->next;  \
8189
0
    }                           \
8190
0
    cur->next = annot;
8191
8192
/**
8193
 * xmlSchemaAssignAnnotation:
8194
 * @item: the schema component
8195
 * @annot: the annotation
8196
 *
8197
 * Adds the annotation to the given schema component.
8198
 *
8199
 * Returns the given annotation.
8200
 */
8201
static xmlSchemaAnnotPtr
8202
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8203
           xmlSchemaAnnotPtr annot)
8204
0
{
8205
0
    if ((annItem == NULL) || (annot == NULL))
8206
0
  return (NULL);
8207
0
    switch (annItem->type) {
8208
0
  case XML_SCHEMA_TYPE_ELEMENT: {
8209
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8210
0
    ADD_ANNOTATION(annot)
8211
0
      }
8212
0
      break;
8213
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
8214
0
    xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8215
0
    ADD_ANNOTATION(annot)
8216
0
      }
8217
0
      break;
8218
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8219
0
  case XML_SCHEMA_TYPE_ANY: {
8220
0
    xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8221
0
    ADD_ANNOTATION(annot)
8222
0
      }
8223
0
      break;
8224
0
  case XML_SCHEMA_TYPE_PARTICLE:
8225
0
  case XML_SCHEMA_TYPE_IDC_KEY:
8226
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
8227
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8228
0
    xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8229
0
    ADD_ANNOTATION(annot)
8230
0
      }
8231
0
      break;
8232
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8233
0
    xmlSchemaAttributeGroupPtr item =
8234
0
        (xmlSchemaAttributeGroupPtr) annItem;
8235
0
    ADD_ANNOTATION(annot)
8236
0
      }
8237
0
      break;
8238
0
  case XML_SCHEMA_TYPE_NOTATION: {
8239
0
    xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8240
0
    ADD_ANNOTATION(annot)
8241
0
      }
8242
0
      break;
8243
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
8244
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
8245
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
8246
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8247
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
8248
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
8249
0
  case XML_SCHEMA_FACET_PATTERN:
8250
0
  case XML_SCHEMA_FACET_ENUMERATION:
8251
0
  case XML_SCHEMA_FACET_WHITESPACE:
8252
0
  case XML_SCHEMA_FACET_LENGTH:
8253
0
  case XML_SCHEMA_FACET_MAXLENGTH:
8254
0
  case XML_SCHEMA_FACET_MINLENGTH: {
8255
0
    xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8256
0
    ADD_ANNOTATION(annot)
8257
0
      }
8258
0
      break;
8259
0
  case XML_SCHEMA_TYPE_SIMPLE:
8260
0
  case XML_SCHEMA_TYPE_COMPLEX: {
8261
0
    xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8262
0
    ADD_ANNOTATION(annot)
8263
0
      }
8264
0
      break;
8265
0
  case XML_SCHEMA_TYPE_GROUP: {
8266
0
    xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8267
0
    ADD_ANNOTATION(annot)
8268
0
      }
8269
0
      break;
8270
0
  case XML_SCHEMA_TYPE_SEQUENCE:
8271
0
  case XML_SCHEMA_TYPE_CHOICE:
8272
0
  case XML_SCHEMA_TYPE_ALL: {
8273
0
    xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8274
0
    ADD_ANNOTATION(annot)
8275
0
      }
8276
0
      break;
8277
0
  default:
8278
0
       xmlSchemaPCustomErr(NULL,
8279
0
    XML_SCHEMAP_INTERNAL,
8280
0
    NULL, NULL,
8281
0
    "Internal error: xmlSchemaAddAnnotation, "
8282
0
    "The item is not a annotated schema component", NULL);
8283
0
       break;
8284
0
    }
8285
0
    return (annot);
8286
0
}
8287
8288
/**
8289
 * xmlSchemaParseIDCSelectorAndField:
8290
 * @ctxt:  a schema validation context
8291
 * @schema:  the schema being built
8292
 * @node:  a subtree containing XML Schema information
8293
 *
8294
 * Parses a XML Schema identity-constraint definition's
8295
 * <selector> and <field> elements.
8296
 *
8297
 * Returns the parsed identity-constraint definition.
8298
 */
8299
static xmlSchemaIDCSelectPtr
8300
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8301
        xmlSchemaIDCPtr idc,
8302
        xmlNodePtr node,
8303
        int isField)
8304
0
{
8305
0
    xmlSchemaIDCSelectPtr item;
8306
0
    xmlNodePtr child = NULL;
8307
0
    xmlAttrPtr attr;
8308
8309
    /*
8310
    * Check for illegal attributes.
8311
    */
8312
0
    attr = node->properties;
8313
0
    while (attr != NULL) {
8314
0
  if (attr->ns == NULL) {
8315
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8316
0
    (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8317
0
    xmlSchemaPIllegalAttrErr(ctxt,
8318
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8319
0
      }
8320
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8321
0
      xmlSchemaPIllegalAttrErr(ctxt,
8322
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8323
0
  }
8324
0
  attr = attr->next;
8325
0
    }
8326
    /*
8327
    * Create the item.
8328
    */
8329
0
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8330
0
    if (item == NULL) {
8331
0
        xmlSchemaPErrMemory(ctxt,
8332
0
      "allocating a 'selector' of an identity-constraint definition",
8333
0
      NULL);
8334
0
        return (NULL);
8335
0
    }
8336
0
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
8337
    /*
8338
    * Attribute "xpath" (mandatory).
8339
    */
8340
0
    attr = xmlSchemaGetPropNode(node, "xpath");
8341
0
    if (attr == NULL) {
8342
0
  xmlSchemaPMissingAttrErr(ctxt,
8343
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8344
0
      NULL, node,
8345
0
      "name", NULL);
8346
0
    } else {
8347
0
  item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8348
  /*
8349
  * URGENT TODO: "field"s have an other syntax than "selector"s.
8350
  */
8351
8352
0
  if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8353
0
      isField) == -1) {
8354
0
      xmlSchemaPErr(ctxt,
8355
0
    (xmlNodePtr) attr,
8356
0
    XML_SCHEMAP_INTERNAL,
8357
0
    "Internal error: xmlSchemaParseIDCSelectorAndField, "
8358
0
    "validating the XPath expression of a IDC selector.\n",
8359
0
    NULL, NULL);
8360
0
  }
8361
8362
0
    }
8363
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8364
    /*
8365
    * And now for the children...
8366
    */
8367
0
    child = node->children;
8368
0
    if (IS_SCHEMA(child, "annotation")) {
8369
  /*
8370
  * Add the annotation to the parent IDC.
8371
  */
8372
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8373
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8374
0
  child = child->next;
8375
0
    }
8376
0
    if (child != NULL) {
8377
0
  xmlSchemaPContentErr(ctxt,
8378
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8379
0
      NULL, node, child,
8380
0
      NULL, "(annotation?)");
8381
0
    }
8382
8383
0
    return (item);
8384
0
}
8385
8386
/**
8387
 * xmlSchemaParseIDC:
8388
 * @ctxt:  a schema validation context
8389
 * @schema:  the schema being built
8390
 * @node:  a subtree containing XML Schema information
8391
 *
8392
 * Parses a XML Schema identity-constraint definition.
8393
 *
8394
 * Returns the parsed identity-constraint definition.
8395
 */
8396
static xmlSchemaIDCPtr
8397
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8398
      xmlSchemaPtr schema,
8399
      xmlNodePtr node,
8400
      xmlSchemaTypeType idcCategory,
8401
      const xmlChar *targetNamespace)
8402
0
{
8403
0
    xmlSchemaIDCPtr item = NULL;
8404
0
    xmlNodePtr child = NULL;
8405
0
    xmlAttrPtr attr;
8406
0
    const xmlChar *name = NULL;
8407
0
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8408
8409
    /*
8410
    * Check for illegal attributes.
8411
    */
8412
0
    attr = node->properties;
8413
0
    while (attr != NULL) {
8414
0
  if (attr->ns == NULL) {
8415
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8416
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8417
0
    ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8418
0
     (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8419
0
    xmlSchemaPIllegalAttrErr(ctxt,
8420
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8421
0
      }
8422
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8423
0
      xmlSchemaPIllegalAttrErr(ctxt,
8424
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8425
0
  }
8426
0
  attr = attr->next;
8427
0
    }
8428
    /*
8429
    * Attribute "name" (mandatory).
8430
    */
8431
0
    attr = xmlSchemaGetPropNode(node, "name");
8432
0
    if (attr == NULL) {
8433
0
  xmlSchemaPMissingAttrErr(ctxt,
8434
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8435
0
      NULL, node,
8436
0
      "name", NULL);
8437
0
  return (NULL);
8438
0
    } else if (xmlSchemaPValAttrNode(ctxt,
8439
0
  NULL, attr,
8440
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8441
0
  return (NULL);
8442
0
    }
8443
    /* Create the component. */
8444
0
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8445
0
  idcCategory, node);
8446
0
    if (item == NULL)
8447
0
  return(NULL);
8448
8449
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8450
0
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8451
  /*
8452
  * Attribute "refer" (mandatory).
8453
  */
8454
0
  attr = xmlSchemaGetPropNode(node, "refer");
8455
0
  if (attr == NULL) {
8456
0
      xmlSchemaPMissingAttrErr(ctxt,
8457
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8458
0
    NULL, node,
8459
0
    "refer", NULL);
8460
0
  } else {
8461
      /*
8462
      * Create a reference item.
8463
      */
8464
0
      item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8465
0
    NULL, NULL);
8466
0
      if (item->ref == NULL)
8467
0
    return (NULL);
8468
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8469
0
    NULL, attr,
8470
0
    &(item->ref->targetNamespace),
8471
0
    &(item->ref->name));
8472
0
      xmlSchemaCheckReference(ctxt, schema, node, attr,
8473
0
    item->ref->targetNamespace);
8474
0
  }
8475
0
    }
8476
    /*
8477
    * And now for the children...
8478
    */
8479
0
    child = node->children;
8480
0
    if (IS_SCHEMA(child, "annotation")) {
8481
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8482
0
  child = child->next;
8483
0
    }
8484
0
    if (child == NULL) {
8485
0
  xmlSchemaPContentErr(ctxt,
8486
0
    XML_SCHEMAP_S4S_ELEM_MISSING,
8487
0
    NULL, node, child,
8488
0
    "A child element is missing",
8489
0
    "(annotation?, (selector, field+))");
8490
0
    }
8491
    /*
8492
    * Child element <selector>.
8493
    */
8494
0
    if (IS_SCHEMA(child, "selector")) {
8495
0
  item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8496
0
      item, child, 0);
8497
0
  child = child->next;
8498
  /*
8499
  * Child elements <field>.
8500
  */
8501
0
  if (IS_SCHEMA(child, "field")) {
8502
0
      do {
8503
0
    field = xmlSchemaParseIDCSelectorAndField(ctxt,
8504
0
        item, child, 1);
8505
0
    if (field != NULL) {
8506
0
        field->index = item->nbFields;
8507
0
        item->nbFields++;
8508
0
        if (lastField != NULL)
8509
0
      lastField->next = field;
8510
0
        else
8511
0
      item->fields = field;
8512
0
        lastField = field;
8513
0
    }
8514
0
    child = child->next;
8515
0
      } while (IS_SCHEMA(child, "field"));
8516
0
  } else {
8517
0
      xmlSchemaPContentErr(ctxt,
8518
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8519
0
    NULL, node, child,
8520
0
    NULL, "(annotation?, (selector, field+))");
8521
0
  }
8522
0
    }
8523
0
    if (child != NULL) {
8524
0
  xmlSchemaPContentErr(ctxt,
8525
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8526
0
      NULL, node, child,
8527
0
      NULL, "(annotation?, (selector, field+))");
8528
0
    }
8529
8530
0
    return (item);
8531
0
}
8532
8533
/**
8534
 * xmlSchemaParseElement:
8535
 * @ctxt:  a schema validation context
8536
 * @schema:  the schema being built
8537
 * @node:  a subtree containing XML Schema information
8538
 * @topLevel: indicates if this is global declaration
8539
 *
8540
 * Parses a XML schema element declaration.
8541
 * *WARNING* this interface is highly subject to change
8542
 *
8543
 * Returns the element declaration or a particle; NULL in case
8544
 * of an error or if the particle has minOccurs==maxOccurs==0.
8545
 */
8546
static xmlSchemaBasicItemPtr
8547
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8548
                      xmlNodePtr node, int *isElemRef, int topLevel)
8549
0
{
8550
0
    xmlSchemaElementPtr decl = NULL;
8551
0
    xmlSchemaParticlePtr particle = NULL;
8552
0
    xmlSchemaAnnotPtr annot = NULL;
8553
0
    xmlNodePtr child = NULL;
8554
0
    xmlAttrPtr attr, nameAttr;
8555
0
    int min, max, isRef = 0;
8556
0
    xmlChar *des = NULL;
8557
8558
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
8559
    /* TODO: Complete implementation of 3.3.6 */
8560
8561
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8562
0
        return (NULL);
8563
8564
0
    if (isElemRef != NULL)
8565
0
  *isElemRef = 0;
8566
    /*
8567
    * If we get a "ref" attribute on a local <element> we will assume it's
8568
    * a reference - even if there's a "name" attribute; this seems to be more
8569
    * robust.
8570
    */
8571
0
    nameAttr = xmlSchemaGetPropNode(node, "name");
8572
0
    attr = xmlSchemaGetPropNode(node, "ref");
8573
0
    if ((topLevel) || (attr == NULL)) {
8574
0
  if (nameAttr == NULL) {
8575
0
      xmlSchemaPMissingAttrErr(ctxt,
8576
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8577
0
    NULL, node, "name", NULL);
8578
0
      return (NULL);
8579
0
  }
8580
0
    } else
8581
0
  isRef = 1;
8582
8583
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8584
0
    child = node->children;
8585
0
    if (IS_SCHEMA(child, "annotation")) {
8586
0
  annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8587
0
  child = child->next;
8588
0
    }
8589
    /*
8590
    * Skip particle part if a global declaration.
8591
    */
8592
0
    if (topLevel)
8593
0
  goto declaration_part;
8594
    /*
8595
    * The particle part ==================================================
8596
    */
8597
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8598
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8599
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8600
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
8601
0
    if (particle == NULL)
8602
0
  goto return_null;
8603
8604
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8605
8606
0
    if (isRef) {
8607
0
  const xmlChar *refNs = NULL, *ref = NULL;
8608
0
  xmlSchemaQNameRefPtr refer = NULL;
8609
  /*
8610
  * The reference part =============================================
8611
  */
8612
0
  if (isElemRef != NULL)
8613
0
      *isElemRef = 1;
8614
8615
0
  xmlSchemaPValAttrNodeQName(ctxt, schema,
8616
0
      NULL, attr, &refNs, &ref);
8617
0
  xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8618
  /*
8619
  * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8620
  */
8621
0
  if (nameAttr != NULL) {
8622
0
      xmlSchemaPMutualExclAttrErr(ctxt,
8623
0
    XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8624
0
  }
8625
  /*
8626
  * Check for illegal attributes.
8627
  */
8628
0
  attr = node->properties;
8629
0
  while (attr != NULL) {
8630
0
      if (attr->ns == NULL) {
8631
0
    if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8632
0
        xmlStrEqual(attr->name, BAD_CAST "name") ||
8633
0
        xmlStrEqual(attr->name, BAD_CAST "id") ||
8634
0
        xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8635
0
        xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8636
0
    {
8637
0
        attr = attr->next;
8638
0
        continue;
8639
0
    } else {
8640
        /* SPEC (3.3.3 : 2.2) */
8641
0
        xmlSchemaPCustomAttrErr(ctxt,
8642
0
      XML_SCHEMAP_SRC_ELEMENT_2_2,
8643
0
      NULL, NULL, attr,
8644
0
      "Only the attributes 'minOccurs', 'maxOccurs' and "
8645
0
      "'id' are allowed in addition to 'ref'");
8646
0
        break;
8647
0
    }
8648
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8649
0
    xmlSchemaPIllegalAttrErr(ctxt,
8650
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8651
0
      }
8652
0
      attr = attr->next;
8653
0
  }
8654
  /*
8655
  * No children except <annotation> expected.
8656
  */
8657
0
  if (child != NULL) {
8658
0
      xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8659
0
    NULL, node, child, NULL, "(annotation?)");
8660
0
  }
8661
0
  if ((min == 0) && (max == 0))
8662
0
      goto return_null;
8663
  /*
8664
  * Create the reference item and attach it to the particle.
8665
  */
8666
0
  refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8667
0
      ref, refNs);
8668
0
  if (refer == NULL)
8669
0
      goto return_null;
8670
0
  particle->children = (xmlSchemaTreeItemPtr) refer;
8671
0
  particle->annot = annot;
8672
  /*
8673
  * Add the particle to pending components, since the reference
8674
  * need to be resolved.
8675
  */
8676
0
  WXS_ADD_PENDING(ctxt, particle);
8677
0
  return ((xmlSchemaBasicItemPtr) particle);
8678
0
    }
8679
    /*
8680
    * The declaration part ===============================================
8681
    */
8682
0
declaration_part:
8683
0
    {
8684
0
  const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8685
0
  xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8686
8687
0
  if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8688
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8689
0
      goto return_null;
8690
  /*
8691
  * Evaluate the target namespace.
8692
  */
8693
0
  if (topLevel) {
8694
0
      ns = ctxt->targetNamespace;
8695
0
  } else {
8696
0
      attr = xmlSchemaGetPropNode(node, "form");
8697
0
      if (attr != NULL) {
8698
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8699
0
    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8700
0
        ns = ctxt->targetNamespace;
8701
0
    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8702
0
        xmlSchemaPSimpleTypeErr(ctxt,
8703
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8704
0
      NULL, (xmlNodePtr) attr,
8705
0
      NULL, "(qualified | unqualified)",
8706
0
      attrValue, NULL, NULL, NULL);
8707
0
    }
8708
0
      } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8709
0
    ns = ctxt->targetNamespace;
8710
0
  }
8711
0
  decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8712
0
  if (decl == NULL) {
8713
0
      goto return_null;
8714
0
  }
8715
  /*
8716
  * Check for illegal attributes.
8717
  */
8718
0
  attr = node->properties;
8719
0
  while (attr != NULL) {
8720
0
      if (attr->ns == NULL) {
8721
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8722
0
        (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8723
0
        (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8724
0
        (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8725
0
        (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8726
0
        (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8727
0
        (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8728
0
    {
8729
0
        if (topLevel == 0) {
8730
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8731
0
          (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8732
0
          (!xmlStrEqual(attr->name, BAD_CAST "form")))
8733
0
      {
8734
0
          xmlSchemaPIllegalAttrErr(ctxt,
8735
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8736
0
      }
8737
0
        } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8738
0
      (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8739
0
      (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8740
8741
0
      xmlSchemaPIllegalAttrErr(ctxt,
8742
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8743
0
        }
8744
0
    }
8745
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8746
8747
0
    xmlSchemaPIllegalAttrErr(ctxt,
8748
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8749
0
      }
8750
0
      attr = attr->next;
8751
0
  }
8752
  /*
8753
  * Extract/validate attributes.
8754
  */
8755
0
  if (topLevel) {
8756
      /*
8757
      * Process top attributes of global element declarations here.
8758
      */
8759
0
      decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8760
0
      decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8761
0
      xmlSchemaPValAttrQName(ctxt, schema,
8762
0
    NULL, node, "substitutionGroup",
8763
0
    &(decl->substGroupNs), &(decl->substGroup));
8764
0
      if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8765
0
    decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8766
      /*
8767
      * Attribute "final".
8768
      */
8769
0
      attr = xmlSchemaGetPropNode(node, "final");
8770
0
      if (attr == NULL) {
8771
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8772
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8773
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8774
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8775
0
      } else {
8776
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8777
0
    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8778
0
        -1,
8779
0
        XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8780
0
        XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8781
0
        xmlSchemaPSimpleTypeErr(ctxt,
8782
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8783
0
      NULL, (xmlNodePtr) attr,
8784
0
      NULL, "(#all | List of (extension | restriction))",
8785
0
      attrValue, NULL, NULL, NULL);
8786
0
    }
8787
0
      }
8788
0
  }
8789
  /*
8790
  * Attribute "block".
8791
  */
8792
0
  attr = xmlSchemaGetPropNode(node, "block");
8793
0
  if (attr == NULL) {
8794
      /*
8795
      * Apply default "block" values.
8796
      */
8797
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8798
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8799
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8800
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8801
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8802
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8803
0
  } else {
8804
0
      attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8805
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8806
0
    -1,
8807
0
    XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8808
0
    XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8809
0
    XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8810
0
    xmlSchemaPSimpleTypeErr(ctxt,
8811
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8812
0
        NULL, (xmlNodePtr) attr,
8813
0
        NULL, "(#all | List of (extension | "
8814
0
        "restriction | substitution))", attrValue,
8815
0
        NULL, NULL, NULL);
8816
0
      }
8817
0
  }
8818
0
  if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8819
0
      decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8820
8821
0
  attr = xmlSchemaGetPropNode(node, "type");
8822
0
  if (attr != NULL) {
8823
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8824
0
    NULL, attr,
8825
0
    &(decl->namedTypeNs), &(decl->namedType));
8826
0
      xmlSchemaCheckReference(ctxt, schema, node,
8827
0
    attr, decl->namedTypeNs);
8828
0
  }
8829
0
  decl->value = xmlSchemaGetProp(ctxt, node, "default");
8830
0
  attr = xmlSchemaGetPropNode(node, "fixed");
8831
0
  if (attr != NULL) {
8832
0
      fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8833
0
      if (decl->value != NULL) {
8834
    /*
8835
    * 3.3.3 : 1
8836
    * default and fixed must not both be present.
8837
    */
8838
0
    xmlSchemaPMutualExclAttrErr(ctxt,
8839
0
        XML_SCHEMAP_SRC_ELEMENT_1,
8840
0
        NULL, attr, "default", "fixed");
8841
0
      } else {
8842
0
    decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8843
0
    decl->value = fixed;
8844
0
      }
8845
0
  }
8846
  /*
8847
  * And now for the children...
8848
  */
8849
0
  if (IS_SCHEMA(child, "complexType")) {
8850
      /*
8851
      * 3.3.3 : 3
8852
      * "type" and either <simpleType> or <complexType> are mutually
8853
      * exclusive
8854
      */
8855
0
      if (decl->namedType != NULL) {
8856
0
    xmlSchemaPContentErr(ctxt,
8857
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8858
0
        NULL, node, child,
8859
0
        "The attribute 'type' and the <complexType> child are "
8860
0
        "mutually exclusive", NULL);
8861
0
      } else
8862
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8863
0
      child = child->next;
8864
0
  } else if (IS_SCHEMA(child, "simpleType")) {
8865
      /*
8866
      * 3.3.3 : 3
8867
      * "type" and either <simpleType> or <complexType> are
8868
      * mutually exclusive
8869
      */
8870
0
      if (decl->namedType != NULL) {
8871
0
    xmlSchemaPContentErr(ctxt,
8872
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8873
0
        NULL, node, child,
8874
0
        "The attribute 'type' and the <simpleType> child are "
8875
0
        "mutually exclusive", NULL);
8876
0
      } else
8877
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8878
0
      child = child->next;
8879
0
  }
8880
0
  while ((IS_SCHEMA(child, "unique")) ||
8881
0
      (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8882
0
      if (IS_SCHEMA(child, "unique")) {
8883
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8884
0
        XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8885
0
      } else if (IS_SCHEMA(child, "key")) {
8886
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8887
0
        XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8888
0
      } else if (IS_SCHEMA(child, "keyref")) {
8889
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8890
0
        XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8891
0
      }
8892
0
      if (lastIDC != NULL)
8893
0
    lastIDC->next = curIDC;
8894
0
      else
8895
0
    decl->idcs = (void *) curIDC;
8896
0
      lastIDC = curIDC;
8897
0
      child = child->next;
8898
0
  }
8899
0
  if (child != NULL) {
8900
0
      xmlSchemaPContentErr(ctxt,
8901
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8902
0
    NULL, node, child,
8903
0
    NULL, "(annotation?, ((simpleType | complexType)?, "
8904
0
    "(unique | key | keyref)*))");
8905
0
  }
8906
0
  decl->annot = annot;
8907
0
    }
8908
    /*
8909
    * NOTE: Element Declaration Representation OK 4. will be checked at a
8910
    * different layer.
8911
    */
8912
0
    FREE_AND_NULL(des)
8913
0
    if (topLevel)
8914
0
  return ((xmlSchemaBasicItemPtr) decl);
8915
0
    else {
8916
0
  particle->children = (xmlSchemaTreeItemPtr) decl;
8917
0
  return ((xmlSchemaBasicItemPtr) particle);
8918
0
    }
8919
8920
0
return_null:
8921
0
    FREE_AND_NULL(des);
8922
0
    if (annot != NULL) {
8923
0
  if (particle != NULL)
8924
0
      particle->annot = NULL;
8925
0
  if (decl != NULL)
8926
0
      decl->annot = NULL;
8927
0
  xmlSchemaFreeAnnot(annot);
8928
0
    }
8929
0
    return (NULL);
8930
0
}
8931
8932
/**
8933
 * xmlSchemaParseUnion:
8934
 * @ctxt:  a schema validation context
8935
 * @schema:  the schema being built
8936
 * @node:  a subtree containing XML Schema information
8937
 *
8938
 * parse a XML schema Union definition
8939
 * *WARNING* this interface is highly subject to change
8940
 *
8941
 * Returns -1 in case of internal error, 0 in case of success and a positive
8942
 * error code otherwise.
8943
 */
8944
static int
8945
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8946
                    xmlNodePtr node)
8947
0
{
8948
0
    xmlSchemaTypePtr type;
8949
0
    xmlNodePtr child = NULL;
8950
0
    xmlAttrPtr attr;
8951
0
    const xmlChar *cur = NULL;
8952
8953
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8954
0
        return (-1);
8955
    /* Not a component, don't create it. */
8956
0
    type = ctxt->ctxtType;
8957
    /*
8958
    * Mark the simple type as being of variety "union".
8959
    */
8960
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8961
    /*
8962
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8963
    * then the `simple ur-type definition`."
8964
    */
8965
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8966
    /*
8967
    * Check for illegal attributes.
8968
    */
8969
0
    attr = node->properties;
8970
0
    while (attr != NULL) {
8971
0
  if (attr->ns == NULL) {
8972
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8973
0
    (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8974
0
    xmlSchemaPIllegalAttrErr(ctxt,
8975
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8976
0
      }
8977
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8978
0
      xmlSchemaPIllegalAttrErr(ctxt,
8979
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8980
0
  }
8981
0
  attr = attr->next;
8982
0
    }
8983
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8984
    /*
8985
    * Attribute "memberTypes". This is a list of QNames.
8986
    * TODO: Check the value to contain anything.
8987
    */
8988
0
    attr = xmlSchemaGetPropNode(node, "memberTypes");
8989
0
    if (attr != NULL) {
8990
0
  const xmlChar *end;
8991
0
  xmlChar *tmp;
8992
0
  const xmlChar *localName, *nsName;
8993
0
  xmlSchemaTypeLinkPtr link, lastLink = NULL;
8994
0
  xmlSchemaQNameRefPtr ref;
8995
8996
0
  cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8997
0
  type->base = cur;
8998
0
  do {
8999
0
      while (IS_BLANK_CH(*cur))
9000
0
    cur++;
9001
0
      end = cur;
9002
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
9003
0
    end++;
9004
0
      if (end == cur)
9005
0
    break;
9006
0
      tmp = xmlStrndup(cur, end - cur);
9007
0
      if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
9008
0
    NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
9009
    /*
9010
    * Create the member type link.
9011
    */
9012
0
    link = (xmlSchemaTypeLinkPtr)
9013
0
        xmlMalloc(sizeof(xmlSchemaTypeLink));
9014
0
    if (link == NULL) {
9015
0
        xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
9016
0
      "allocating a type link", NULL);
9017
0
        return (-1);
9018
0
    }
9019
0
    link->type = NULL;
9020
0
    link->next = NULL;
9021
0
    if (lastLink == NULL)
9022
0
        type->memberTypes = link;
9023
0
    else
9024
0
        lastLink->next = link;
9025
0
    lastLink = link;
9026
    /*
9027
    * Create a reference item.
9028
    */
9029
0
    ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
9030
0
        localName, nsName);
9031
0
    if (ref == NULL) {
9032
0
        FREE_AND_NULL(tmp)
9033
0
        return (-1);
9034
0
    }
9035
    /*
9036
    * Assign the reference to the link, it will be resolved
9037
    * later during fixup of the union simple type.
9038
    */
9039
0
    link->type = (xmlSchemaTypePtr) ref;
9040
0
      }
9041
0
      FREE_AND_NULL(tmp)
9042
0
      cur = end;
9043
0
  } while (*cur != 0);
9044
9045
0
    }
9046
    /*
9047
    * And now for the children...
9048
    */
9049
0
    child = node->children;
9050
0
    if (IS_SCHEMA(child, "annotation")) {
9051
  /*
9052
  * Add the annotation to the simple type ancestor.
9053
  */
9054
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9055
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
9056
0
        child = child->next;
9057
0
    }
9058
0
    if (IS_SCHEMA(child, "simpleType")) {
9059
0
  xmlSchemaTypePtr subtype, last = NULL;
9060
9061
  /*
9062
  * Anchor the member types in the "subtypes" field of the
9063
  * simple type.
9064
  */
9065
0
  while (IS_SCHEMA(child, "simpleType")) {
9066
0
      subtype = (xmlSchemaTypePtr)
9067
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9068
0
      if (subtype != NULL) {
9069
0
    if (last == NULL) {
9070
0
        type->subtypes = subtype;
9071
0
        last = subtype;
9072
0
    } else {
9073
0
        last->next = subtype;
9074
0
        last = subtype;
9075
0
    }
9076
0
    last->next = NULL;
9077
0
      }
9078
0
      child = child->next;
9079
0
  }
9080
0
    }
9081
0
    if (child != NULL) {
9082
0
  xmlSchemaPContentErr(ctxt,
9083
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9084
0
      NULL, node, child, NULL, "(annotation?, simpleType*)");
9085
0
    }
9086
0
    if ((attr == NULL) && (type->subtypes == NULL)) {
9087
   /*
9088
  * src-union-memberTypes-or-simpleTypes
9089
  * Either the memberTypes [attribute] of the <union> element must
9090
  * be non-empty or there must be at least one simpleType [child].
9091
  */
9092
0
  xmlSchemaPCustomErr(ctxt,
9093
0
      XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
9094
0
      NULL, node,
9095
0
      "Either the attribute 'memberTypes' or "
9096
0
      "at least one <simpleType> child must be present", NULL);
9097
0
    }
9098
0
    return (0);
9099
0
}
9100
9101
/**
9102
 * xmlSchemaParseList:
9103
 * @ctxt:  a schema validation context
9104
 * @schema:  the schema being built
9105
 * @node:  a subtree containing XML Schema information
9106
 *
9107
 * parse a XML schema List definition
9108
 * *WARNING* this interface is highly subject to change
9109
 *
9110
 * Returns -1 in case of error, 0 if the declaration is improper and
9111
 *         1 in case of success.
9112
 */
9113
static xmlSchemaTypePtr
9114
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9115
                   xmlNodePtr node)
9116
0
{
9117
0
    xmlSchemaTypePtr type;
9118
0
    xmlNodePtr child = NULL;
9119
0
    xmlAttrPtr attr;
9120
9121
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9122
0
        return (NULL);
9123
    /* Not a component, don't create it. */
9124
0
    type = ctxt->ctxtType;
9125
    /*
9126
    * Mark the type as being of variety "list".
9127
    */
9128
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9129
    /*
9130
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9131
    * then the `simple ur-type definition`."
9132
    */
9133
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9134
    /*
9135
    * Check for illegal attributes.
9136
    */
9137
0
    attr = node->properties;
9138
0
    while (attr != NULL) {
9139
0
  if (attr->ns == NULL) {
9140
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9141
0
    (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
9142
0
    xmlSchemaPIllegalAttrErr(ctxt,
9143
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9144
0
      }
9145
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9146
0
      xmlSchemaPIllegalAttrErr(ctxt,
9147
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9148
0
  }
9149
0
  attr = attr->next;
9150
0
    }
9151
9152
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9153
9154
    /*
9155
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9156
    * fields for holding the reference to the itemType.
9157
    *
9158
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9159
    * the "ref" fields.
9160
    */
9161
0
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
9162
0
  node, "itemType", &(type->baseNs), &(type->base));
9163
    /*
9164
    * And now for the children...
9165
    */
9166
0
    child = node->children;
9167
0
    if (IS_SCHEMA(child, "annotation")) {
9168
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9169
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
9170
0
        child = child->next;
9171
0
    }
9172
0
    if (IS_SCHEMA(child, "simpleType")) {
9173
  /*
9174
  * src-list-itemType-or-simpleType
9175
  * Either the itemType [attribute] or the <simpleType> [child] of
9176
  * the <list> element must be present, but not both.
9177
  */
9178
0
  if (type->base != NULL) {
9179
0
      xmlSchemaPCustomErr(ctxt,
9180
0
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9181
0
    NULL, node,
9182
0
    "The attribute 'itemType' and the <simpleType> child "
9183
0
    "are mutually exclusive", NULL);
9184
0
  } else {
9185
0
      type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9186
0
  }
9187
0
        child = child->next;
9188
0
    } else if (type->base == NULL) {
9189
0
  xmlSchemaPCustomErr(ctxt,
9190
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9191
0
      NULL, node,
9192
0
      "Either the attribute 'itemType' or the <simpleType> child "
9193
0
      "must be present", NULL);
9194
0
    }
9195
0
    if (child != NULL) {
9196
0
  xmlSchemaPContentErr(ctxt,
9197
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9198
0
      NULL, node, child, NULL, "(annotation?, simpleType?)");
9199
0
    }
9200
0
    if ((type->base == NULL) &&
9201
0
  (type->subtypes == NULL) &&
9202
0
  (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9203
0
  xmlSchemaPCustomErr(ctxt,
9204
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9205
0
      NULL, node,
9206
0
      "Either the attribute 'itemType' or the <simpleType> child "
9207
0
      "must be present", NULL);
9208
0
    }
9209
0
    return (NULL);
9210
0
}
9211
9212
/**
9213
 * xmlSchemaParseSimpleType:
9214
 * @ctxt:  a schema validation context
9215
 * @schema:  the schema being built
9216
 * @node:  a subtree containing XML Schema information
9217
 *
9218
 * parse a XML schema Simple Type definition
9219
 * *WARNING* this interface is highly subject to change
9220
 *
9221
 * Returns -1 in case of error, 0 if the declaration is improper and
9222
 * 1 in case of success.
9223
 */
9224
static xmlSchemaTypePtr
9225
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9226
                         xmlNodePtr node, int topLevel)
9227
0
{
9228
0
    xmlSchemaTypePtr type, oldCtxtType;
9229
0
    xmlNodePtr child = NULL;
9230
0
    const xmlChar *attrValue = NULL;
9231
0
    xmlAttrPtr attr;
9232
0
    int hasRestriction = 0;
9233
9234
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9235
0
        return (NULL);
9236
9237
0
    if (topLevel) {
9238
0
  attr = xmlSchemaGetPropNode(node, "name");
9239
0
  if (attr == NULL) {
9240
0
      xmlSchemaPMissingAttrErr(ctxt,
9241
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
9242
0
    NULL, node,
9243
0
    "name", NULL);
9244
0
      return (NULL);
9245
0
  } else {
9246
0
      if (xmlSchemaPValAttrNode(ctxt,
9247
0
    NULL, attr,
9248
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9249
0
    return (NULL);
9250
      /*
9251
      * Skip built-in types.
9252
      */
9253
0
      if (ctxt->isS4S) {
9254
0
    xmlSchemaTypePtr biType;
9255
9256
0
    if (ctxt->isRedefine) {
9257
        /*
9258
        * REDEFINE: Disallow redefinition of built-in-types.
9259
        * TODO: It seems that the spec does not say anything
9260
        * about this case.
9261
        */
9262
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9263
0
      NULL, node,
9264
0
      "Redefinition of built-in simple types is not "
9265
0
      "supported", NULL);
9266
0
        return(NULL);
9267
0
    }
9268
0
    biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9269
0
    if (biType != NULL)
9270
0
        return (biType);
9271
0
      }
9272
0
  }
9273
0
    }
9274
    /*
9275
    * TargetNamespace:
9276
    * SPEC "The `actual value` of the targetNamespace [attribute]
9277
    * of the <schema> ancestor element information item if present,
9278
    * otherwise `absent`.
9279
    */
9280
0
    if (topLevel == 0) {
9281
#ifdef ENABLE_NAMED_LOCALS
9282
        char buf[40];
9283
#endif
9284
  /*
9285
  * Parse as local simple type definition.
9286
  */
9287
#ifdef ENABLE_NAMED_LOCALS
9288
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9289
  type = xmlSchemaAddType(ctxt, schema,
9290
      XML_SCHEMA_TYPE_SIMPLE,
9291
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9292
      ctxt->targetNamespace, node, 0);
9293
#else
9294
0
  type = xmlSchemaAddType(ctxt, schema,
9295
0
      XML_SCHEMA_TYPE_SIMPLE,
9296
0
      NULL, ctxt->targetNamespace, node, 0);
9297
0
#endif
9298
0
  if (type == NULL)
9299
0
      return (NULL);
9300
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9301
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9302
  /*
9303
  * Check for illegal attributes.
9304
  */
9305
0
  attr = node->properties;
9306
0
  while (attr != NULL) {
9307
0
      if (attr->ns == NULL) {
9308
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9309
0
        xmlSchemaPIllegalAttrErr(ctxt,
9310
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9311
0
    }
9312
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9313
0
        xmlSchemaPIllegalAttrErr(ctxt,
9314
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9315
0
      }
9316
0
      attr = attr->next;
9317
0
  }
9318
0
    } else {
9319
  /*
9320
  * Parse as global simple type definition.
9321
  *
9322
  * Note that attrValue is the value of the attribute "name" here.
9323
  */
9324
0
  type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9325
0
      attrValue, ctxt->targetNamespace, node, 1);
9326
0
  if (type == NULL)
9327
0
      return (NULL);
9328
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9329
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9330
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9331
  /*
9332
  * Check for illegal attributes.
9333
  */
9334
0
  attr = node->properties;
9335
0
  while (attr != NULL) {
9336
0
      if (attr->ns == NULL) {
9337
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9338
0
        (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9339
0
        (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9340
0
        xmlSchemaPIllegalAttrErr(ctxt,
9341
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9342
0
    }
9343
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9344
0
    xmlSchemaPIllegalAttrErr(ctxt,
9345
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9346
0
      }
9347
0
      attr = attr->next;
9348
0
  }
9349
  /*
9350
  * Attribute "final".
9351
  */
9352
0
  attr = xmlSchemaGetPropNode(node, "final");
9353
0
  if (attr == NULL) {
9354
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9355
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9356
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9357
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9358
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9359
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9360
0
  } else {
9361
0
      attrValue = xmlSchemaGetProp(ctxt, node, "final");
9362
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9363
0
    -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9364
0
    XML_SCHEMAS_TYPE_FINAL_LIST,
9365
0
    XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9366
9367
0
    xmlSchemaPSimpleTypeErr(ctxt,
9368
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9369
0
        WXS_BASIC_CAST type, (xmlNodePtr) attr,
9370
0
        NULL, "(#all | List of (list | union | restriction)",
9371
0
        attrValue, NULL, NULL, NULL);
9372
0
      }
9373
0
  }
9374
0
    }
9375
0
    type->targetNamespace = ctxt->targetNamespace;
9376
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9377
    /*
9378
    * And now for the children...
9379
    */
9380
0
    oldCtxtType = ctxt->ctxtType;
9381
9382
0
    ctxt->ctxtType = type;
9383
9384
0
    child = node->children;
9385
0
    if (IS_SCHEMA(child, "annotation")) {
9386
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9387
0
        child = child->next;
9388
0
    }
9389
0
    if (child == NULL) {
9390
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9391
0
      NULL, node, child, NULL,
9392
0
      "(annotation?, (restriction | list | union))");
9393
0
    } else if (IS_SCHEMA(child, "restriction")) {
9394
0
        xmlSchemaParseRestriction(ctxt, schema, child,
9395
0
      XML_SCHEMA_TYPE_SIMPLE);
9396
0
  hasRestriction = 1;
9397
0
        child = child->next;
9398
0
    } else if (IS_SCHEMA(child, "list")) {
9399
0
        xmlSchemaParseList(ctxt, schema, child);
9400
0
        child = child->next;
9401
0
    } else if (IS_SCHEMA(child, "union")) {
9402
0
        xmlSchemaParseUnion(ctxt, schema, child);
9403
0
        child = child->next;
9404
0
    }
9405
0
    if (child != NULL) {
9406
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9407
0
      NULL, node, child, NULL,
9408
0
      "(annotation?, (restriction | list | union))");
9409
0
    }
9410
    /*
9411
    * REDEFINE: SPEC src-redefine (5)
9412
    * "Within the [children], each <simpleType> must have a
9413
    * <restriction> among its [children] ... the `actual value` of whose
9414
    * base [attribute] must be the same as the `actual value` of its own
9415
    * name attribute plus target namespace;"
9416
    */
9417
0
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9418
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9419
0
      NULL, node, "This is a redefinition, thus the "
9420
0
      "<simpleType> must have a <restriction> child", NULL);
9421
0
    }
9422
9423
0
    ctxt->ctxtType = oldCtxtType;
9424
0
    return (type);
9425
0
}
9426
9427
/**
9428
 * xmlSchemaParseModelGroupDefRef:
9429
 * @ctxt:  the parser context
9430
 * @schema: the schema being built
9431
 * @node:  the node
9432
 *
9433
 * Parses a reference to a model group definition.
9434
 *
9435
 * We will return a particle component with a qname-component or
9436
 * NULL in case of an error.
9437
 */
9438
static xmlSchemaTreeItemPtr
9439
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9440
             xmlSchemaPtr schema,
9441
             xmlNodePtr node)
9442
0
{
9443
0
    xmlSchemaParticlePtr item;
9444
0
    xmlNodePtr child = NULL;
9445
0
    xmlAttrPtr attr;
9446
0
    const xmlChar *ref = NULL, *refNs = NULL;
9447
0
    int min, max;
9448
9449
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9450
0
        return (NULL);
9451
9452
0
    attr = xmlSchemaGetPropNode(node, "ref");
9453
0
    if (attr == NULL) {
9454
0
  xmlSchemaPMissingAttrErr(ctxt,
9455
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9456
0
      NULL, node, "ref", NULL);
9457
0
  return (NULL);
9458
0
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9459
0
  attr, &refNs, &ref) != 0) {
9460
0
  return (NULL);
9461
0
    }
9462
0
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9463
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9464
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9465
0
  "(xs:nonNegativeInteger | unbounded)");
9466
    /*
9467
    * Check for illegal attributes.
9468
    */
9469
0
    attr = node->properties;
9470
0
    while (attr != NULL) {
9471
0
  if (attr->ns == NULL) {
9472
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9473
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9474
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9475
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9476
0
    xmlSchemaPIllegalAttrErr(ctxt,
9477
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9478
0
      }
9479
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9480
0
      xmlSchemaPIllegalAttrErr(ctxt,
9481
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9482
0
  }
9483
0
  attr = attr->next;
9484
0
    }
9485
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9486
0
    item = xmlSchemaAddParticle(ctxt, node, min, max);
9487
0
    if (item == NULL)
9488
0
  return (NULL);
9489
    /*
9490
    * Create a qname-reference and set as the term; it will be substituted
9491
    * for the model group after the reference has been resolved.
9492
    */
9493
0
    item->children = (xmlSchemaTreeItemPtr)
9494
0
  xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9495
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9496
    /*
9497
    * And now for the children...
9498
    */
9499
0
    child = node->children;
9500
    /* TODO: Is annotation even allowed for a model group reference? */
9501
0
    if (IS_SCHEMA(child, "annotation")) {
9502
  /*
9503
  * TODO: What to do exactly with the annotation?
9504
  */
9505
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9506
0
  child = child->next;
9507
0
    }
9508
0
    if (child != NULL) {
9509
0
  xmlSchemaPContentErr(ctxt,
9510
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9511
0
      NULL, node, child, NULL,
9512
0
      "(annotation?)");
9513
0
    }
9514
    /*
9515
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
9516
    */
9517
0
    if ((min == 0) && (max == 0))
9518
0
  return (NULL);
9519
9520
0
    return ((xmlSchemaTreeItemPtr) item);
9521
0
}
9522
9523
/**
9524
 * xmlSchemaParseModelGroupDefinition:
9525
 * @ctxt:  a schema validation context
9526
 * @schema:  the schema being built
9527
 * @node:  a subtree containing XML Schema information
9528
 *
9529
 * Parses a XML schema model group definition.
9530
 *
9531
 * Note that the constraint src-redefine (6.2) can't be applied until
9532
 * references have been resolved. So we will do this at the
9533
 * component fixup level.
9534
 *
9535
 * *WARNING* this interface is highly subject to change
9536
 *
9537
 * Returns -1 in case of error, 0 if the declaration is improper and
9538
 *         1 in case of success.
9539
 */
9540
static xmlSchemaModelGroupDefPtr
9541
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9542
           xmlSchemaPtr schema,
9543
           xmlNodePtr node)
9544
0
{
9545
0
    xmlSchemaModelGroupDefPtr item;
9546
0
    xmlNodePtr child = NULL;
9547
0
    xmlAttrPtr attr;
9548
0
    const xmlChar *name;
9549
9550
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9551
0
        return (NULL);
9552
9553
0
    attr = xmlSchemaGetPropNode(node, "name");
9554
0
    if (attr == NULL) {
9555
0
  xmlSchemaPMissingAttrErr(ctxt,
9556
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9557
0
      NULL, node,
9558
0
      "name", NULL);
9559
0
  return (NULL);
9560
0
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9561
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9562
0
  return (NULL);
9563
0
    }
9564
0
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9565
0
  ctxt->targetNamespace, node);
9566
0
    if (item == NULL)
9567
0
  return (NULL);
9568
    /*
9569
    * Check for illegal attributes.
9570
    */
9571
0
    attr = node->properties;
9572
0
    while (attr != NULL) {
9573
0
  if (attr->ns == NULL) {
9574
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9575
0
    (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9576
0
    xmlSchemaPIllegalAttrErr(ctxt,
9577
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9578
0
      }
9579
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9580
0
      xmlSchemaPIllegalAttrErr(ctxt,
9581
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9582
0
  }
9583
0
  attr = attr->next;
9584
0
    }
9585
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9586
    /*
9587
    * And now for the children...
9588
    */
9589
0
    child = node->children;
9590
0
    if (IS_SCHEMA(child, "annotation")) {
9591
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9592
0
  child = child->next;
9593
0
    }
9594
0
    if (IS_SCHEMA(child, "all")) {
9595
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9596
0
      XML_SCHEMA_TYPE_ALL, 0);
9597
0
  child = child->next;
9598
0
    } else if (IS_SCHEMA(child, "choice")) {
9599
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9600
0
      XML_SCHEMA_TYPE_CHOICE, 0);
9601
0
  child = child->next;
9602
0
    } else if (IS_SCHEMA(child, "sequence")) {
9603
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9604
0
      XML_SCHEMA_TYPE_SEQUENCE, 0);
9605
0
  child = child->next;
9606
0
    }
9607
9608
9609
9610
0
    if (child != NULL) {
9611
0
  xmlSchemaPContentErr(ctxt,
9612
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9613
0
      NULL, node, child, NULL,
9614
0
      "(annotation?, (all | choice | sequence)?)");
9615
0
    }
9616
0
    return (item);
9617
0
}
9618
9619
/**
9620
 * xmlSchemaCleanupDoc:
9621
 * @ctxt:  a schema validation context
9622
 * @node:  the root of the document.
9623
 *
9624
 * removes unwanted nodes in a schemas document tree
9625
 */
9626
static void
9627
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9628
0
{
9629
0
    xmlNodePtr delete, cur;
9630
9631
0
    if ((ctxt == NULL) || (root == NULL)) return;
9632
9633
    /*
9634
     * Remove all the blank text nodes
9635
     */
9636
0
    delete = NULL;
9637
0
    cur = root;
9638
0
    while (cur != NULL) {
9639
0
        if (delete != NULL) {
9640
0
            xmlUnlinkNode(delete);
9641
0
            xmlFreeNode(delete);
9642
0
            delete = NULL;
9643
0
        }
9644
0
        if (cur->type == XML_TEXT_NODE) {
9645
0
            if (IS_BLANK_NODE(cur)) {
9646
0
                if (xmlNodeGetSpacePreserve(cur) != 1) {
9647
0
                    delete = cur;
9648
0
                }
9649
0
            }
9650
0
        } else if ((cur->type != XML_ELEMENT_NODE) &&
9651
0
                   (cur->type != XML_CDATA_SECTION_NODE)) {
9652
0
            delete = cur;
9653
0
            goto skip_children;
9654
0
        }
9655
9656
        /*
9657
         * Skip to next node
9658
         */
9659
0
        if (cur->children != NULL) {
9660
0
            if ((cur->children->type != XML_ENTITY_DECL) &&
9661
0
                (cur->children->type != XML_ENTITY_REF_NODE) &&
9662
0
                (cur->children->type != XML_ENTITY_NODE)) {
9663
0
                cur = cur->children;
9664
0
                continue;
9665
0
            }
9666
0
        }
9667
0
      skip_children:
9668
0
        if (cur->next != NULL) {
9669
0
            cur = cur->next;
9670
0
            continue;
9671
0
        }
9672
9673
0
        do {
9674
0
            cur = cur->parent;
9675
0
            if (cur == NULL)
9676
0
                break;
9677
0
            if (cur == root) {
9678
0
                cur = NULL;
9679
0
                break;
9680
0
            }
9681
0
            if (cur->next != NULL) {
9682
0
                cur = cur->next;
9683
0
                break;
9684
0
            }
9685
0
        } while (cur != NULL);
9686
0
    }
9687
0
    if (delete != NULL) {
9688
0
        xmlUnlinkNode(delete);
9689
0
        xmlFreeNode(delete);
9690
0
        delete = NULL;
9691
0
    }
9692
0
}
9693
9694
9695
static void
9696
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9697
0
{
9698
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9699
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9700
9701
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9702
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9703
9704
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9705
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9706
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9707
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9708
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9709
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9710
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9711
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9712
9713
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9714
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9715
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9716
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9717
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9718
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9719
0
}
9720
9721
static int
9722
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9723
           xmlSchemaPtr schema,
9724
           xmlNodePtr node)
9725
0
{
9726
0
    xmlAttrPtr attr;
9727
0
    const xmlChar *val;
9728
0
    int res = 0, oldErrs = ctxt->nberrors;
9729
9730
    /*
9731
    * Those flags should be moved to the parser context flags,
9732
    * since they are not visible at the component level. I.e.
9733
    * they are used if processing schema *documents* only.
9734
    */
9735
0
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9736
0
    HFAILURE;
9737
9738
    /*
9739
    * Since the version is of type xs:token, we won't bother to
9740
    * check it.
9741
    */
9742
    /* REMOVED:
9743
    attr = xmlSchemaGetPropNode(node, "version");
9744
    if (attr != NULL) {
9745
  res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9746
      xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9747
  HFAILURE;
9748
    }
9749
    */
9750
0
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
9751
0
    if (attr != NULL) {
9752
0
  res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9753
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9754
0
  HFAILURE;
9755
0
  if (res != 0) {
9756
0
      ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9757
0
      goto exit;
9758
0
  }
9759
0
    }
9760
0
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9761
0
    if (attr != NULL) {
9762
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9763
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9764
0
      XML_SCHEMAS_QUALIF_ELEM);
9765
0
  HFAILURE;
9766
0
  if (res != 0) {
9767
0
      xmlSchemaPSimpleTypeErr(ctxt,
9768
0
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9769
0
    NULL, (xmlNodePtr) attr, NULL,
9770
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9771
0
  }
9772
0
    }
9773
0
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9774
0
    if (attr != NULL) {
9775
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9776
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9777
0
      XML_SCHEMAS_QUALIF_ATTR);
9778
0
  HFAILURE;
9779
0
  if (res != 0) {
9780
0
      xmlSchemaPSimpleTypeErr(ctxt,
9781
0
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9782
0
    NULL, (xmlNodePtr) attr, NULL,
9783
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9784
0
  }
9785
0
    }
9786
0
    attr = xmlSchemaGetPropNode(node, "finalDefault");
9787
0
    if (attr != NULL) {
9788
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9789
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9790
0
      XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9791
0
      XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9792
0
      -1,
9793
0
      XML_SCHEMAS_FINAL_DEFAULT_LIST,
9794
0
      XML_SCHEMAS_FINAL_DEFAULT_UNION);
9795
0
  HFAILURE;
9796
0
  if (res != 0) {
9797
0
      xmlSchemaPSimpleTypeErr(ctxt,
9798
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9799
0
    NULL, (xmlNodePtr) attr, NULL,
9800
0
    "(#all | List of (extension | restriction | list | union))",
9801
0
    val, NULL, NULL, NULL);
9802
0
  }
9803
0
    }
9804
0
    attr = xmlSchemaGetPropNode(node, "blockDefault");
9805
0
    if (attr != NULL) {
9806
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9807
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9808
0
      XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9809
0
      XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9810
0
      XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9811
0
  HFAILURE;
9812
0
  if (res != 0) {
9813
0
      xmlSchemaPSimpleTypeErr(ctxt,
9814
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9815
0
    NULL, (xmlNodePtr) attr, NULL,
9816
0
    "(#all | List of (extension | restriction | substitution))",
9817
0
    val, NULL, NULL, NULL);
9818
0
  }
9819
0
    }
9820
9821
0
exit:
9822
0
    if (oldErrs != ctxt->nberrors)
9823
0
  res = ctxt->err;
9824
0
    return(res);
9825
0
exit_failure:
9826
0
    return(-1);
9827
0
}
9828
9829
/**
9830
 * xmlSchemaParseSchemaTopLevel:
9831
 * @ctxt:  a schema validation context
9832
 * @schema:  the schemas
9833
 * @nodes:  the list of top level nodes
9834
 *
9835
 * Returns the internal XML Schema structure built from the resource or
9836
 *         NULL in case of error
9837
 */
9838
static int
9839
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9840
                             xmlSchemaPtr schema, xmlNodePtr nodes)
9841
0
{
9842
0
    xmlNodePtr child;
9843
0
    xmlSchemaAnnotPtr annot;
9844
0
    int res = 0, oldErrs, tmpOldErrs;
9845
9846
0
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9847
0
        return(-1);
9848
9849
0
    oldErrs = ctxt->nberrors;
9850
0
    child = nodes;
9851
0
    while ((IS_SCHEMA(child, "include")) ||
9852
0
     (IS_SCHEMA(child, "import")) ||
9853
0
     (IS_SCHEMA(child, "redefine")) ||
9854
0
     (IS_SCHEMA(child, "annotation"))) {
9855
0
  if (IS_SCHEMA(child, "annotation")) {
9856
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9857
0
      if (schema->annot == NULL)
9858
0
    schema->annot = annot;
9859
0
      else
9860
0
    xmlSchemaFreeAnnot(annot);
9861
0
  } else if (IS_SCHEMA(child, "import")) {
9862
0
      tmpOldErrs = ctxt->nberrors;
9863
0
      res = xmlSchemaParseImport(ctxt, schema, child);
9864
0
      HFAILURE;
9865
0
      HSTOP(ctxt);
9866
0
      if (tmpOldErrs != ctxt->nberrors)
9867
0
    goto exit;
9868
0
  } else if (IS_SCHEMA(child, "include")) {
9869
0
      tmpOldErrs = ctxt->nberrors;
9870
0
      res = xmlSchemaParseInclude(ctxt, schema, child);
9871
0
      HFAILURE;
9872
0
      HSTOP(ctxt);
9873
0
      if (tmpOldErrs != ctxt->nberrors)
9874
0
    goto exit;
9875
0
  } else if (IS_SCHEMA(child, "redefine")) {
9876
0
      tmpOldErrs = ctxt->nberrors;
9877
0
      res = xmlSchemaParseRedefine(ctxt, schema, child);
9878
0
      HFAILURE;
9879
0
      HSTOP(ctxt);
9880
0
      if (tmpOldErrs != ctxt->nberrors)
9881
0
    goto exit;
9882
0
  }
9883
0
  child = child->next;
9884
0
    }
9885
    /*
9886
    * URGENT TODO: Change the functions to return int results.
9887
    * We need especially to catch internal errors.
9888
    */
9889
0
    while (child != NULL) {
9890
0
  if (IS_SCHEMA(child, "complexType")) {
9891
0
      xmlSchemaParseComplexType(ctxt, schema, child, 1);
9892
0
      child = child->next;
9893
0
  } else if (IS_SCHEMA(child, "simpleType")) {
9894
0
      xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9895
0
      child = child->next;
9896
0
  } else if (IS_SCHEMA(child, "element")) {
9897
0
      xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9898
0
      child = child->next;
9899
0
  } else if (IS_SCHEMA(child, "attribute")) {
9900
0
      xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9901
0
      child = child->next;
9902
0
  } else if (IS_SCHEMA(child, "attributeGroup")) {
9903
0
      xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9904
0
      child = child->next;
9905
0
  } else if (IS_SCHEMA(child, "group")) {
9906
0
      xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9907
0
      child = child->next;
9908
0
  } else if (IS_SCHEMA(child, "notation")) {
9909
0
      xmlSchemaParseNotation(ctxt, schema, child);
9910
0
      child = child->next;
9911
0
  } else {
9912
0
      xmlSchemaPContentErr(ctxt,
9913
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9914
0
    NULL, child->parent, child,
9915
0
    NULL, "((include | import | redefine | annotation)*, "
9916
0
    "(((simpleType | complexType | group | attributeGroup) "
9917
0
    "| element | attribute | notation), annotation*)*)");
9918
0
      child = child->next;
9919
0
  }
9920
0
  while (IS_SCHEMA(child, "annotation")) {
9921
      /*
9922
      * TODO: We should add all annotations.
9923
      */
9924
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9925
0
      if (schema->annot == NULL)
9926
0
    schema->annot = annot;
9927
0
      else
9928
0
    xmlSchemaFreeAnnot(annot);
9929
0
      child = child->next;
9930
0
  }
9931
0
    }
9932
0
exit:
9933
0
    ctxt->ctxtType = NULL;
9934
0
    if (oldErrs != ctxt->nberrors)
9935
0
  res = ctxt->err;
9936
0
    return(res);
9937
0
exit_failure:
9938
0
    return(-1);
9939
0
}
9940
9941
static xmlSchemaSchemaRelationPtr
9942
xmlSchemaSchemaRelationCreate(void)
9943
0
{
9944
0
    xmlSchemaSchemaRelationPtr ret;
9945
9946
0
    ret = (xmlSchemaSchemaRelationPtr)
9947
0
  xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9948
0
    if (ret == NULL) {
9949
0
  xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
9950
0
  return(NULL);
9951
0
    }
9952
0
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9953
0
    return(ret);
9954
0
}
9955
9956
#if 0
9957
static void
9958
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9959
{
9960
    xmlFree(rel);
9961
}
9962
#endif
9963
9964
static void
9965
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9966
0
{
9967
0
    xmlSchemaRedefPtr prev;
9968
9969
0
    while (redef != NULL) {
9970
0
  prev = redef;
9971
0
  redef = redef->next;
9972
0
  xmlFree(prev);
9973
0
    }
9974
0
}
9975
9976
static void
9977
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9978
0
{
9979
    /*
9980
    * After the construction context has been freed, there will be
9981
    * no schema graph available any more. Only the schema buckets
9982
    * will stay alive, which are put into the "schemasImports" and
9983
    * "includes" slots of the xmlSchema.
9984
    */
9985
0
    if (con->buckets != NULL)
9986
0
  xmlSchemaItemListFree(con->buckets);
9987
0
    if (con->pending != NULL)
9988
0
  xmlSchemaItemListFree(con->pending);
9989
0
    if (con->substGroups != NULL)
9990
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9991
0
    if (con->redefs != NULL)
9992
0
  xmlSchemaRedefListFree(con->redefs);
9993
0
    if (con->dict != NULL)
9994
0
  xmlDictFree(con->dict);
9995
0
    xmlFree(con);
9996
0
}
9997
9998
static xmlSchemaConstructionCtxtPtr
9999
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
10000
0
{
10001
0
    xmlSchemaConstructionCtxtPtr ret;
10002
10003
0
    ret = (xmlSchemaConstructionCtxtPtr)
10004
0
  xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
10005
0
    if (ret == NULL) {
10006
0
        xmlSchemaPErrMemory(NULL,
10007
0
      "allocating schema construction context", NULL);
10008
0
        return (NULL);
10009
0
    }
10010
0
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
10011
10012
0
    ret->buckets = xmlSchemaItemListCreate();
10013
0
    if (ret->buckets == NULL) {
10014
0
  xmlSchemaPErrMemory(NULL,
10015
0
      "allocating list of schema buckets", NULL);
10016
0
  xmlFree(ret);
10017
0
        return (NULL);
10018
0
    }
10019
0
    ret->pending = xmlSchemaItemListCreate();
10020
0
    if (ret->pending == NULL) {
10021
0
  xmlSchemaPErrMemory(NULL,
10022
0
      "allocating list of pending global components", NULL);
10023
0
  xmlSchemaConstructionCtxtFree(ret);
10024
0
        return (NULL);
10025
0
    }
10026
0
    ret->dict = dict;
10027
0
    xmlDictReference(dict);
10028
0
    return(ret);
10029
0
}
10030
10031
static xmlSchemaParserCtxtPtr
10032
xmlSchemaParserCtxtCreate(void)
10033
0
{
10034
0
    xmlSchemaParserCtxtPtr ret;
10035
10036
0
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
10037
0
    if (ret == NULL) {
10038
0
        xmlSchemaPErrMemory(NULL, "allocating schema parser context",
10039
0
                            NULL);
10040
0
        return (NULL);
10041
0
    }
10042
0
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
10043
0
    ret->type = XML_SCHEMA_CTXT_PARSER;
10044
0
    ret->attrProhibs = xmlSchemaItemListCreate();
10045
0
    if (ret->attrProhibs == NULL) {
10046
0
  xmlFree(ret);
10047
0
  return(NULL);
10048
0
    }
10049
0
    return(ret);
10050
0
}
10051
10052
/**
10053
 * xmlSchemaNewParserCtxtUseDict:
10054
 * @URL:  the location of the schema
10055
 * @dict: the dictionary to be used
10056
 *
10057
 * Create an XML Schemas parse context for that file/resource expected
10058
 * to contain an XML Schemas file.
10059
 *
10060
 * Returns the parser context or NULL in case of error
10061
 */
10062
static xmlSchemaParserCtxtPtr
10063
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
10064
0
{
10065
0
    xmlSchemaParserCtxtPtr ret;
10066
10067
0
    ret = xmlSchemaParserCtxtCreate();
10068
0
    if (ret == NULL)
10069
0
        return (NULL);
10070
0
    ret->dict = dict;
10071
0
    xmlDictReference(dict);
10072
0
    if (URL != NULL)
10073
0
  ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
10074
0
    return (ret);
10075
0
}
10076
10077
static int
10078
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
10079
0
{
10080
0
    if (vctxt->pctxt == NULL) {
10081
0
        if (vctxt->schema != NULL)
10082
0
      vctxt->pctxt =
10083
0
    xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
10084
0
  else
10085
0
      vctxt->pctxt = xmlSchemaNewParserCtxt("*");
10086
0
  if (vctxt->pctxt == NULL) {
10087
0
      VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
10088
0
    "failed to create a temp. parser context");
10089
0
      return (-1);
10090
0
  }
10091
  /* TODO: Pass user data. */
10092
0
  xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
10093
0
      vctxt->warning, vctxt->errCtxt);
10094
0
  xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
10095
0
      vctxt->errCtxt);
10096
0
    }
10097
0
    return (0);
10098
0
}
10099
10100
/**
10101
 * xmlSchemaGetSchemaBucket:
10102
 * @pctxt: the schema parser context
10103
 * @schemaLocation: the URI of the schema document
10104
 *
10105
 * Returns a schema bucket if it was already parsed.
10106
 *
10107
 * Returns a schema bucket if it was already parsed from
10108
 *         @schemaLocation, NULL otherwise.
10109
 */
10110
static xmlSchemaBucketPtr
10111
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10112
          const xmlChar *schemaLocation)
10113
0
{
10114
0
    xmlSchemaBucketPtr cur;
10115
0
    xmlSchemaItemListPtr list;
10116
10117
0
    list = pctxt->constructor->buckets;
10118
0
    if (list->nbItems == 0)
10119
0
  return(NULL);
10120
0
    else {
10121
0
  int i;
10122
0
  for (i = 0; i < list->nbItems; i++) {
10123
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10124
      /* Pointer comparison! */
10125
0
      if (cur->schemaLocation == schemaLocation)
10126
0
    return(cur);
10127
0
  }
10128
0
    }
10129
0
    return(NULL);
10130
0
}
10131
10132
static xmlSchemaBucketPtr
10133
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10134
             const xmlChar *schemaLocation,
10135
             const xmlChar *targetNamespace)
10136
0
{
10137
0
    xmlSchemaBucketPtr cur;
10138
0
    xmlSchemaItemListPtr list;
10139
10140
0
    list = pctxt->constructor->buckets;
10141
0
    if (list->nbItems == 0)
10142
0
  return(NULL);
10143
0
    else {
10144
0
  int i;
10145
0
  for (i = 0; i < list->nbItems; i++) {
10146
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10147
      /* Pointer comparison! */
10148
0
      if ((cur->origTargetNamespace == NULL) &&
10149
0
    (cur->schemaLocation == schemaLocation) &&
10150
0
    (cur->targetNamespace == targetNamespace))
10151
0
    return(cur);
10152
0
  }
10153
0
    }
10154
0
    return(NULL);
10155
0
}
10156
10157
10158
#define IS_BAD_SCHEMA_DOC(b) \
10159
0
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10160
10161
static xmlSchemaBucketPtr
10162
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10163
         const xmlChar *targetNamespace,
10164
         int imported)
10165
0
{
10166
0
    xmlSchemaBucketPtr cur;
10167
0
    xmlSchemaItemListPtr list;
10168
10169
0
    list = pctxt->constructor->buckets;
10170
0
    if (list->nbItems == 0)
10171
0
  return(NULL);
10172
0
    else {
10173
0
  int i;
10174
0
  for (i = 0; i < list->nbItems; i++) {
10175
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10176
0
      if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10177
0
    (cur->origTargetNamespace == targetNamespace) &&
10178
0
    ((imported && cur->imported) ||
10179
0
     ((!imported) && (!cur->imported))))
10180
0
    return(cur);
10181
0
  }
10182
0
    }
10183
0
    return(NULL);
10184
0
}
10185
10186
static int
10187
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10188
         xmlSchemaPtr schema,
10189
         xmlSchemaBucketPtr bucket)
10190
0
{
10191
0
    int oldFlags;
10192
0
    xmlDocPtr oldDoc;
10193
0
    xmlNodePtr node;
10194
0
    int ret, oldErrs;
10195
0
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10196
10197
    /*
10198
    * Save old values; reset the *main* schema.
10199
    * URGENT TODO: This is not good; move the per-document information
10200
    * to the parser. Get rid of passing the main schema to the
10201
    * parsing functions.
10202
    */
10203
0
    oldFlags = schema->flags;
10204
0
    oldDoc = schema->doc;
10205
0
    if (schema->flags != 0)
10206
0
  xmlSchemaClearSchemaDefaults(schema);
10207
0
    schema->doc = bucket->doc;
10208
0
    pctxt->schema = schema;
10209
    /*
10210
    * Keep the current target namespace on the parser *not* on the
10211
    * main schema.
10212
    */
10213
0
    pctxt->targetNamespace = bucket->targetNamespace;
10214
0
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10215
10216
0
    if ((bucket->targetNamespace != NULL) &&
10217
0
  xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10218
  /*
10219
  * We are parsing the schema for schemas!
10220
  */
10221
0
  pctxt->isS4S = 1;
10222
0
    }
10223
    /* Mark it as parsed, even if parsing fails. */
10224
0
    bucket->parsed++;
10225
    /* Compile the schema doc. */
10226
0
    node = xmlDocGetRootElement(bucket->doc);
10227
0
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10228
0
    if (ret != 0)
10229
0
  goto exit;
10230
    /* An empty schema; just get out. */
10231
0
    if (node->children == NULL)
10232
0
  goto exit;
10233
0
    oldErrs = pctxt->nberrors;
10234
0
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10235
0
    if (ret != 0)
10236
0
  goto exit;
10237
    /*
10238
    * TODO: Not nice, but I'm not 100% sure we will get always an error
10239
    * as a result of the above functions; so better rely on pctxt->err
10240
    * as well.
10241
    */
10242
0
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10243
0
  ret = pctxt->err;
10244
0
  goto exit;
10245
0
    }
10246
10247
0
exit:
10248
0
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10249
    /* Restore schema values. */
10250
0
    schema->doc = oldDoc;
10251
0
    schema->flags = oldFlags;
10252
0
    return(ret);
10253
0
}
10254
10255
static int
10256
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10257
         xmlSchemaPtr schema,
10258
         xmlSchemaBucketPtr bucket)
10259
0
{
10260
0
    xmlSchemaParserCtxtPtr newpctxt;
10261
0
    int res = 0;
10262
10263
0
    if (bucket == NULL)
10264
0
  return(0);
10265
0
    if (bucket->parsed) {
10266
0
  PERROR_INT("xmlSchemaParseNewDoc",
10267
0
      "reparsing a schema doc");
10268
0
  return(-1);
10269
0
    }
10270
0
    if (bucket->doc == NULL) {
10271
0
  PERROR_INT("xmlSchemaParseNewDoc",
10272
0
      "parsing a schema doc, but there's no doc");
10273
0
  return(-1);
10274
0
    }
10275
0
    if (pctxt->constructor == NULL) {
10276
0
  PERROR_INT("xmlSchemaParseNewDoc",
10277
0
      "no constructor");
10278
0
  return(-1);
10279
0
    }
10280
    /* Create and init the temporary parser context. */
10281
0
    newpctxt = xmlSchemaNewParserCtxtUseDict(
10282
0
  (const char *) bucket->schemaLocation, pctxt->dict);
10283
0
    if (newpctxt == NULL)
10284
0
  return(-1);
10285
0
    newpctxt->constructor = pctxt->constructor;
10286
    /*
10287
    * TODO: Can we avoid that the parser knows about the main schema?
10288
    * It would be better if he knows about the current schema bucket
10289
    * only.
10290
    */
10291
0
    newpctxt->schema = schema;
10292
0
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10293
0
  pctxt->errCtxt);
10294
0
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10295
0
  pctxt->errCtxt);
10296
0
    newpctxt->counter = pctxt->counter;
10297
10298
10299
0
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10300
10301
    /* Channel back errors and cleanup the temporary parser context. */
10302
0
    if (res != 0)
10303
0
  pctxt->err = res;
10304
0
    pctxt->nberrors += newpctxt->nberrors;
10305
0
    pctxt->counter = newpctxt->counter;
10306
0
    newpctxt->constructor = NULL;
10307
    /* Free the parser context. */
10308
0
    xmlSchemaFreeParserCtxt(newpctxt);
10309
0
    return(res);
10310
0
}
10311
10312
static void
10313
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10314
        xmlSchemaSchemaRelationPtr rel)
10315
0
{
10316
0
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
10317
10318
0
    if (cur == NULL) {
10319
0
  bucket->relations = rel;
10320
0
  return;
10321
0
    }
10322
0
    while (cur->next != NULL)
10323
0
  cur = cur->next;
10324
0
    cur->next = rel;
10325
0
}
10326
10327
10328
static const xmlChar *
10329
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10330
        xmlNodePtr ctxtNode)
10331
0
{
10332
    /*
10333
    * Build an absolute location URI.
10334
    */
10335
0
    if (location != NULL) {
10336
0
  if (ctxtNode == NULL)
10337
0
      return(location);
10338
0
  else {
10339
0
      xmlChar *base, *URI;
10340
0
      const xmlChar *ret = NULL;
10341
10342
0
      base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10343
0
      if (base == NULL) {
10344
0
    URI = xmlBuildURI(location, ctxtNode->doc->URL);
10345
0
      } else {
10346
0
    URI = xmlBuildURI(location, base);
10347
0
    xmlFree(base);
10348
0
      }
10349
0
      if (URI != NULL) {
10350
0
    ret = xmlDictLookup(dict, URI, -1);
10351
0
    xmlFree(URI);
10352
0
    return(ret);
10353
0
      }
10354
0
  }
10355
0
    }
10356
0
    return(NULL);
10357
0
}
10358
10359
10360
10361
/**
10362
 * xmlSchemaAddSchemaDoc:
10363
 * @pctxt:  a schema validation context
10364
 * @schema:  the schema being built
10365
 * @node:  a subtree containing XML Schema information
10366
 *
10367
 * Parse an included (and to-be-redefined) XML schema document.
10368
 *
10369
 * Returns 0 on success, a positive error code on errors and
10370
 *         -1 in case of an internal or API error.
10371
 */
10372
10373
static int
10374
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10375
    int type, /* import or include or redefine */
10376
    const xmlChar *schemaLocation,
10377
    xmlDocPtr schemaDoc,
10378
    const char *schemaBuffer,
10379
    int schemaBufferLen,
10380
    xmlNodePtr invokingNode,
10381
    const xmlChar *sourceTargetNamespace,
10382
    const xmlChar *importNamespace,
10383
    xmlSchemaBucketPtr *bucket)
10384
0
{
10385
0
    const xmlChar *targetNamespace = NULL;
10386
0
    xmlSchemaSchemaRelationPtr relation = NULL;
10387
0
    xmlDocPtr doc = NULL;
10388
0
    int res = 0, err = 0, located = 0, preserveDoc = 0;
10389
0
    xmlSchemaBucketPtr bkt = NULL;
10390
10391
0
    if (bucket != NULL)
10392
0
  *bucket = NULL;
10393
10394
0
    switch (type) {
10395
0
  case XML_SCHEMA_SCHEMA_IMPORT:
10396
0
  case XML_SCHEMA_SCHEMA_MAIN:
10397
0
      err = XML_SCHEMAP_SRC_IMPORT;
10398
0
      break;
10399
0
  case XML_SCHEMA_SCHEMA_INCLUDE:
10400
0
      err = XML_SCHEMAP_SRC_INCLUDE;
10401
0
      break;
10402
0
  case XML_SCHEMA_SCHEMA_REDEFINE:
10403
0
      err = XML_SCHEMAP_SRC_REDEFINE;
10404
0
      break;
10405
0
    }
10406
10407
10408
    /* Special handling for the main schema:
10409
    * skip the location and relation logic and just parse the doc.
10410
    * We need just a bucket to be returned in this case.
10411
    */
10412
0
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10413
0
  goto doc_load;
10414
10415
    /* Note that we expect the location to be an absolute URI. */
10416
0
    if (schemaLocation != NULL) {
10417
0
  bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10418
0
  if ((bkt != NULL) &&
10419
0
      (pctxt->constructor->bucket == bkt)) {
10420
      /* Report self-imports/inclusions/redefinitions. */
10421
10422
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10423
0
    invokingNode, NULL,
10424
0
    "The schema must not import/include/redefine itself",
10425
0
    NULL, NULL);
10426
0
      goto exit;
10427
0
  }
10428
0
    }
10429
    /*
10430
    * Create a relation for the graph of schemas.
10431
    */
10432
0
    relation = xmlSchemaSchemaRelationCreate();
10433
0
    if (relation == NULL)
10434
0
  return(-1);
10435
0
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10436
0
  relation);
10437
0
    relation->type = type;
10438
10439
    /*
10440
    * Save the namespace import information.
10441
    */
10442
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10443
0
  relation->importNamespace = importNamespace;
10444
0
  if (schemaLocation == NULL) {
10445
      /*
10446
      * No location; this is just an import of the namespace.
10447
      * Note that we don't assign a bucket to the relation
10448
      * in this case.
10449
      */
10450
0
      goto exit;
10451
0
  }
10452
0
  targetNamespace = importNamespace;
10453
0
    }
10454
10455
    /* Did we already fetch the doc? */
10456
0
    if (bkt != NULL) {
10457
0
  if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10458
      /*
10459
      * We included/redefined and then try to import a schema,
10460
      * but the new location provided for import was different.
10461
      */
10462
0
      if (schemaLocation == NULL)
10463
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10464
0
      if (!xmlStrEqual(schemaLocation,
10465
0
    bkt->schemaLocation)) {
10466
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10467
0
        invokingNode, NULL,
10468
0
        "The schema document '%s' cannot be imported, since "
10469
0
        "it was already included or redefined",
10470
0
        schemaLocation, NULL);
10471
0
    goto exit;
10472
0
      }
10473
0
  } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10474
      /*
10475
      * We imported and then try to include/redefine a schema,
10476
      * but the new location provided for the include/redefine
10477
      * was different.
10478
      */
10479
0
      if (schemaLocation == NULL)
10480
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10481
0
      if (!xmlStrEqual(schemaLocation,
10482
0
    bkt->schemaLocation)) {
10483
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10484
0
        invokingNode, NULL,
10485
0
        "The schema document '%s' cannot be included or "
10486
0
        "redefined, since it was already imported",
10487
0
        schemaLocation, NULL);
10488
0
    goto exit;
10489
0
      }
10490
0
  }
10491
0
    }
10492
10493
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10494
  /*
10495
  * Given that the schemaLocation [attribute] is only a hint, it is open
10496
  * to applications to ignore all but the first <import> for a given
10497
  * namespace, regardless of the `actual value` of schemaLocation, but
10498
  * such a strategy risks missing useful information when new
10499
  * schemaLocations are offered.
10500
  *
10501
  * We will use the first <import> that comes with a location.
10502
  * Further <import>s *with* a location, will result in an error.
10503
  * TODO: Better would be to just report a warning here, but
10504
  * we'll try it this way until someone complains.
10505
  *
10506
  * Schema Document Location Strategy:
10507
  * 3 Based on the namespace name, identify an existing schema document,
10508
  * either as a resource which is an XML document or a <schema> element
10509
  * information item, in some local schema repository;
10510
  * 5 Attempt to resolve the namespace name to locate such a resource.
10511
  *
10512
  * NOTE: (3) and (5) are not supported.
10513
  */
10514
0
  if (bkt != NULL) {
10515
0
      relation->bucket = bkt;
10516
0
      goto exit;
10517
0
  }
10518
0
  bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10519
0
      importNamespace, 1);
10520
10521
0
  if (bkt != NULL) {
10522
0
      relation->bucket = bkt;
10523
0
      if (bkt->schemaLocation == NULL) {
10524
    /* First given location of the schema; load the doc. */
10525
0
    bkt->schemaLocation = schemaLocation;
10526
0
      } else {
10527
0
    if (!xmlStrEqual(schemaLocation,
10528
0
        bkt->schemaLocation)) {
10529
        /*
10530
        * Additional location given; just skip it.
10531
        * URGENT TODO: We should report a warning here.
10532
        * res = XML_SCHEMAP_SRC_IMPORT;
10533
        */
10534
0
        if (schemaLocation == NULL)
10535
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10536
10537
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10538
0
      XML_SCHEMAP_WARN_SKIP_SCHEMA,
10539
0
      invokingNode, NULL,
10540
0
      "Skipping import of schema located at '%s' for the "
10541
0
      "namespace '%s', since this namespace was already "
10542
0
      "imported with the schema located at '%s'",
10543
0
      schemaLocation, importNamespace, bkt->schemaLocation);
10544
0
    }
10545
0
    goto exit;
10546
0
      }
10547
0
  }
10548
  /*
10549
  * No bucket + first location: load the doc and create a
10550
  * bucket.
10551
  */
10552
0
    } else {
10553
  /* <include> and <redefine> */
10554
0
  if (bkt != NULL) {
10555
10556
0
      if ((bkt->origTargetNamespace == NULL) &&
10557
0
    (bkt->targetNamespace != sourceTargetNamespace)) {
10558
0
    xmlSchemaBucketPtr chamel;
10559
10560
    /*
10561
    * Chameleon include/redefine: skip loading only if it was
10562
    * already build for the targetNamespace of the including
10563
    * schema.
10564
    */
10565
    /*
10566
    * URGENT TODO: If the schema is a chameleon-include then copy
10567
    * the components into the including schema and modify the
10568
    * targetNamespace of those components, do nothing otherwise.
10569
    * NOTE: This is currently worked-around by compiling the
10570
    * chameleon for every distinct including targetNamespace; thus
10571
    * not performant at the moment.
10572
    * TODO: Check when the namespace in wildcards for chameleons
10573
    * needs to be converted: before we built wildcard intersections
10574
    * or after.
10575
    *   Answer: after!
10576
    */
10577
0
    chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10578
0
        schemaLocation, sourceTargetNamespace);
10579
0
    if (chamel != NULL) {
10580
        /* A fitting chameleon was already parsed; NOP. */
10581
0
        relation->bucket = chamel;
10582
0
        goto exit;
10583
0
    }
10584
    /*
10585
    * We need to parse the chameleon again for a different
10586
    * targetNamespace.
10587
    * CHAMELEON TODO: Optimize this by only parsing the
10588
    * chameleon once, and then copying the components to
10589
    * the new targetNamespace.
10590
    */
10591
0
    bkt = NULL;
10592
0
      } else {
10593
0
    relation->bucket = bkt;
10594
0
    goto exit;
10595
0
      }
10596
0
  }
10597
0
    }
10598
0
    if ((bkt != NULL) && (bkt->doc != NULL)) {
10599
0
  PERROR_INT("xmlSchemaAddSchemaDoc",
10600
0
      "trying to load a schema doc, but a doc is already "
10601
0
      "assigned to the schema bucket");
10602
0
  goto exit_failure;
10603
0
    }
10604
10605
0
doc_load:
10606
    /*
10607
    * Load the document.
10608
    */
10609
0
    if (schemaDoc != NULL) {
10610
0
  doc = schemaDoc;
10611
  /* Don' free this one, since it was provided by the caller. */
10612
0
  preserveDoc = 1;
10613
  /* TODO: Does the context or the doc hold the location? */
10614
0
  if (schemaDoc->URL != NULL)
10615
0
      schemaLocation = xmlDictLookup(pctxt->dict,
10616
0
    schemaDoc->URL, -1);
10617
0
        else
10618
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10619
0
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10620
0
  xmlParserCtxtPtr parserCtxt;
10621
10622
0
  parserCtxt = xmlNewParserCtxt();
10623
0
  if (parserCtxt == NULL) {
10624
0
      xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10625
0
    "allocating a parser context", NULL);
10626
0
      goto exit_failure;
10627
0
  }
10628
0
  if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10629
      /*
10630
      * TODO: Do we have to burden the schema parser dict with all
10631
      * the content of the schema doc?
10632
      */
10633
0
      xmlDictFree(parserCtxt->dict);
10634
0
      parserCtxt->dict = pctxt->dict;
10635
0
      xmlDictReference(parserCtxt->dict);
10636
0
  }
10637
0
  if (schemaLocation != NULL) {
10638
      /* Parse from file. */
10639
0
      doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10640
0
    NULL, SCHEMAS_PARSE_OPTIONS);
10641
0
  } else if (schemaBuffer != NULL) {
10642
      /* Parse from memory buffer. */
10643
0
      doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10644
0
    NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10645
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10646
0
      if (doc != NULL)
10647
0
    doc->URL = xmlStrdup(schemaLocation);
10648
0
  }
10649
  /*
10650
  * For <import>:
10651
  * 2.1 The referent is (a fragment of) a resource which is an
10652
  * XML document (see clause 1.1), which in turn corresponds to
10653
  * a <schema> element information item in a well-formed information
10654
  * set, which in turn corresponds to a valid schema.
10655
  * TODO: (2.1) fragments of XML documents are not supported.
10656
  *
10657
  * 2.2 The referent is a <schema> element information item in
10658
  * a well-formed information set, which in turn corresponds
10659
  * to a valid schema.
10660
  * TODO: (2.2) is not supported.
10661
  */
10662
0
  if (doc == NULL) {
10663
0
      xmlErrorPtr lerr;
10664
0
      lerr = xmlGetLastError();
10665
      /*
10666
      * Check if this a parser error, or if the document could
10667
      * just not be located.
10668
      * TODO: Try to find specific error codes to react only on
10669
      * localisation failures.
10670
      */
10671
0
      if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10672
    /*
10673
    * We assume a parser error here.
10674
    */
10675
0
    located = 1;
10676
    /* TODO: Error code ?? */
10677
0
    res = XML_SCHEMAP_SRC_IMPORT_2_1;
10678
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10679
0
        invokingNode, NULL,
10680
0
        "Failed to parse the XML resource '%s'",
10681
0
        schemaLocation, NULL);
10682
0
      }
10683
0
  }
10684
0
  xmlFreeParserCtxt(parserCtxt);
10685
0
  if ((doc == NULL) && located)
10686
0
      goto exit_error;
10687
0
    } else {
10688
0
  xmlSchemaPErr(pctxt, NULL,
10689
0
      XML_SCHEMAP_NOTHING_TO_PARSE,
10690
0
      "No information for parsing was provided with the "
10691
0
      "given schema parser context.\n",
10692
0
      NULL, NULL);
10693
0
  goto exit_failure;
10694
0
    }
10695
    /*
10696
    * Preprocess the document.
10697
    */
10698
0
    if (doc != NULL) {
10699
0
  xmlNodePtr docElem = NULL;
10700
10701
0
  located = 1;
10702
0
  docElem = xmlDocGetRootElement(doc);
10703
0
  if (docElem == NULL) {
10704
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10705
0
    invokingNode, NULL,
10706
0
    "The document '%s' has no document element",
10707
0
    schemaLocation, NULL);
10708
0
      goto exit_error;
10709
0
  }
10710
  /*
10711
  * Remove all the blank text nodes.
10712
  */
10713
0
  xmlSchemaCleanupDoc(pctxt, docElem);
10714
  /*
10715
  * Check the schema's top level element.
10716
  */
10717
0
  if (!IS_SCHEMA(docElem, "schema")) {
10718
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10719
0
    invokingNode, NULL,
10720
0
    "The XML document '%s' is not a schema document",
10721
0
    schemaLocation, NULL);
10722
0
      goto exit_error;
10723
0
  }
10724
  /*
10725
  * Note that we don't apply a type check for the
10726
  * targetNamespace value here.
10727
  */
10728
0
  targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10729
0
      "targetNamespace");
10730
0
    }
10731
10732
/* after_doc_loading: */
10733
0
    if ((bkt == NULL) && located) {
10734
  /* Only create a bucket if the schema was located. */
10735
0
        bkt = xmlSchemaBucketCreate(pctxt, type,
10736
0
      targetNamespace);
10737
0
  if (bkt == NULL)
10738
0
      goto exit_failure;
10739
0
    }
10740
0
    if (bkt != NULL) {
10741
0
  bkt->schemaLocation = schemaLocation;
10742
0
  bkt->located = located;
10743
0
  if (doc != NULL) {
10744
0
      bkt->doc = doc;
10745
0
      bkt->targetNamespace = targetNamespace;
10746
0
      bkt->origTargetNamespace = targetNamespace;
10747
0
      if (preserveDoc)
10748
0
    bkt->preserveDoc = 1;
10749
0
  }
10750
0
  if (WXS_IS_BUCKET_IMPMAIN(type))
10751
0
      bkt->imported++;
10752
      /*
10753
      * Add it to the graph of schemas.
10754
      */
10755
0
  if (relation != NULL)
10756
0
      relation->bucket = bkt;
10757
0
    }
10758
10759
0
exit:
10760
    /*
10761
    * Return the bucket explicitly; this is needed for the
10762
    * main schema.
10763
    */
10764
0
    if (bucket != NULL)
10765
0
  *bucket = bkt;
10766
0
    return (0);
10767
10768
0
exit_error:
10769
0
    if ((doc != NULL) && (! preserveDoc)) {
10770
0
  xmlFreeDoc(doc);
10771
0
  if (bkt != NULL)
10772
0
      bkt->doc = NULL;
10773
0
    }
10774
0
    return(pctxt->err);
10775
10776
0
exit_failure:
10777
0
    if ((doc != NULL) && (! preserveDoc)) {
10778
0
  xmlFreeDoc(doc);
10779
0
  if (bkt != NULL)
10780
0
      bkt->doc = NULL;
10781
0
    }
10782
0
    return (-1);
10783
0
}
10784
10785
/**
10786
 * xmlSchemaParseImport:
10787
 * @ctxt:  a schema validation context
10788
 * @schema:  the schema being built
10789
 * @node:  a subtree containing XML Schema information
10790
 *
10791
 * parse a XML schema Import definition
10792
 * *WARNING* this interface is highly subject to change
10793
 *
10794
 * Returns 0 in case of success, a positive error code if
10795
 * not valid and -1 in case of an internal error.
10796
 */
10797
static int
10798
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10799
                     xmlNodePtr node)
10800
0
{
10801
0
    xmlNodePtr child;
10802
0
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10803
0
    const xmlChar *thisTargetNamespace;
10804
0
    xmlAttrPtr attr;
10805
0
    int ret = 0;
10806
0
    xmlSchemaBucketPtr bucket = NULL;
10807
10808
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10809
0
        return (-1);
10810
10811
    /*
10812
    * Check for illegal attributes.
10813
    */
10814
0
    attr = node->properties;
10815
0
    while (attr != NULL) {
10816
0
  if (attr->ns == NULL) {
10817
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10818
0
    (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10819
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10820
0
    xmlSchemaPIllegalAttrErr(pctxt,
10821
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10822
0
      }
10823
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10824
0
      xmlSchemaPIllegalAttrErr(pctxt,
10825
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10826
0
  }
10827
0
  attr = attr->next;
10828
0
    }
10829
    /*
10830
    * Extract and validate attributes.
10831
    */
10832
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10833
0
  "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10834
0
  &namespaceName) != 0) {
10835
0
  xmlSchemaPSimpleTypeErr(pctxt,
10836
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10837
0
      NULL, node,
10838
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10839
0
      NULL, namespaceName, NULL, NULL, NULL);
10840
0
  return (pctxt->err);
10841
0
    }
10842
10843
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10844
0
  "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10845
0
  &schemaLocation) != 0) {
10846
0
  xmlSchemaPSimpleTypeErr(pctxt,
10847
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10848
0
      NULL, node,
10849
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10850
0
      NULL, schemaLocation, NULL, NULL, NULL);
10851
0
  return (pctxt->err);
10852
0
    }
10853
    /*
10854
    * And now for the children...
10855
    */
10856
0
    child = node->children;
10857
0
    if (IS_SCHEMA(child, "annotation")) {
10858
        /*
10859
         * the annotation here is simply discarded ...
10860
   * TODO: really?
10861
         */
10862
0
        child = child->next;
10863
0
    }
10864
0
    if (child != NULL) {
10865
0
  xmlSchemaPContentErr(pctxt,
10866
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10867
0
      NULL, node, child, NULL,
10868
0
      "(annotation?)");
10869
0
    }
10870
    /*
10871
    * Apply additional constraints.
10872
    *
10873
    * Note that it is important to use the original @targetNamespace
10874
    * (or none at all), to rule out imports of schemas _with_ a
10875
    * @targetNamespace if the importing schema is a chameleon schema
10876
    * (with no @targetNamespace).
10877
    */
10878
0
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10879
0
    if (namespaceName != NULL) {
10880
  /*
10881
  * 1.1 If the namespace [attribute] is present, then its `actual value`
10882
  * must not match the `actual value` of the enclosing <schema>'s
10883
  * targetNamespace [attribute].
10884
  */
10885
0
  if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10886
0
      xmlSchemaPCustomErr(pctxt,
10887
0
    XML_SCHEMAP_SRC_IMPORT_1_1,
10888
0
    NULL, node,
10889
0
    "The value of the attribute 'namespace' must not match "
10890
0
    "the target namespace '%s' of the importing schema",
10891
0
    thisTargetNamespace);
10892
0
      return (pctxt->err);
10893
0
  }
10894
0
    } else {
10895
  /*
10896
  * 1.2 If the namespace [attribute] is not present, then the enclosing
10897
  * <schema> must have a targetNamespace [attribute].
10898
  */
10899
0
  if (thisTargetNamespace == NULL) {
10900
0
      xmlSchemaPCustomErr(pctxt,
10901
0
    XML_SCHEMAP_SRC_IMPORT_1_2,
10902
0
    NULL, node,
10903
0
    "The attribute 'namespace' must be existent if "
10904
0
    "the importing schema has no target namespace",
10905
0
    NULL);
10906
0
      return (pctxt->err);
10907
0
  }
10908
0
    }
10909
    /*
10910
    * Locate and acquire the schema document.
10911
    */
10912
0
    if (schemaLocation != NULL)
10913
0
  schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10914
0
      schemaLocation, node);
10915
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10916
0
  schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10917
0
  namespaceName, &bucket);
10918
10919
0
    if (ret != 0)
10920
0
  return(ret);
10921
10922
    /*
10923
    * For <import>: "It is *not* an error for the application
10924
    * schema reference strategy to fail."
10925
    * So just don't parse if no schema document was found.
10926
    * Note that we will get no bucket if the schema could not be
10927
    * located or if there was no schemaLocation.
10928
    */
10929
0
    if ((bucket == NULL) && (schemaLocation != NULL)) {
10930
0
  xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10931
0
      XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10932
0
      node, NULL,
10933
0
      "Failed to locate a schema at location '%s'. "
10934
0
      "Skipping the import", schemaLocation, NULL, NULL);
10935
0
    }
10936
10937
0
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10938
0
  ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10939
0
    }
10940
10941
0
    return (ret);
10942
0
}
10943
10944
static int
10945
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10946
             xmlSchemaPtr schema,
10947
             xmlNodePtr node,
10948
             xmlChar **schemaLocation,
10949
             int type)
10950
0
{
10951
0
    xmlAttrPtr attr;
10952
10953
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10954
0
  (schemaLocation == NULL))
10955
0
        return (-1);
10956
10957
0
    *schemaLocation = NULL;
10958
    /*
10959
    * Check for illegal attributes.
10960
    * Applies for both <include> and <redefine>.
10961
    */
10962
0
    attr = node->properties;
10963
0
    while (attr != NULL) {
10964
0
  if (attr->ns == NULL) {
10965
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10966
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10967
0
    xmlSchemaPIllegalAttrErr(pctxt,
10968
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10969
0
      }
10970
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10971
0
      xmlSchemaPIllegalAttrErr(pctxt,
10972
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10973
0
  }
10974
0
  attr = attr->next;
10975
0
    }
10976
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10977
    /*
10978
    * Preliminary step, extract the URI-Reference and make an URI
10979
    * from the base.
10980
    */
10981
    /*
10982
    * Attribute "schemaLocation" is mandatory.
10983
    */
10984
0
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
10985
0
    if (attr != NULL) {
10986
0
        xmlChar *base = NULL;
10987
0
        xmlChar *uri = NULL;
10988
10989
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10990
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10991
0
      (const xmlChar **) schemaLocation) != 0)
10992
0
      goto exit_error;
10993
0
  base = xmlNodeGetBase(node->doc, node);
10994
0
  if (base == NULL) {
10995
0
      uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10996
0
  } else {
10997
0
      uri = xmlBuildURI(*schemaLocation, base);
10998
0
      xmlFree(base);
10999
0
  }
11000
0
  if (uri == NULL) {
11001
0
      PERROR_INT("xmlSchemaParseIncludeOrRedefine",
11002
0
    "could not build an URI from the schemaLocation")
11003
0
      goto exit_failure;
11004
0
  }
11005
0
  (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
11006
0
  xmlFree(uri);
11007
0
    } else {
11008
0
  xmlSchemaPMissingAttrErr(pctxt,
11009
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11010
0
      NULL, node, "schemaLocation", NULL);
11011
0
  goto exit_error;
11012
0
    }
11013
    /*
11014
    * Report self-inclusion and self-redefinition.
11015
    */
11016
0
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
11017
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11018
0
      xmlSchemaPCustomErr(pctxt,
11019
0
    XML_SCHEMAP_SRC_REDEFINE,
11020
0
    NULL, node,
11021
0
    "The schema document '%s' cannot redefine itself.",
11022
0
    *schemaLocation);
11023
0
  } else {
11024
0
      xmlSchemaPCustomErr(pctxt,
11025
0
    XML_SCHEMAP_SRC_INCLUDE,
11026
0
    NULL, node,
11027
0
    "The schema document '%s' cannot include itself.",
11028
0
    *schemaLocation);
11029
0
  }
11030
0
  goto exit_error;
11031
0
    }
11032
11033
0
    return(0);
11034
0
exit_error:
11035
0
    return(pctxt->err);
11036
0
exit_failure:
11037
0
    return(-1);
11038
0
}
11039
11040
static int
11041
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
11042
        xmlSchemaPtr schema,
11043
        xmlNodePtr node,
11044
        int type)
11045
0
{
11046
0
    xmlNodePtr child = NULL;
11047
0
    const xmlChar *schemaLocation = NULL;
11048
0
    int res = 0; /* hasRedefinitions = 0 */
11049
0
    int isChameleon = 0, wasChameleon = 0;
11050
0
    xmlSchemaBucketPtr bucket = NULL;
11051
11052
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
11053
0
        return (-1);
11054
11055
    /*
11056
    * Parse attributes. Note that the returned schemaLocation will
11057
    * be already converted to an absolute URI.
11058
    */
11059
0
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
11060
0
  node, (xmlChar **) (&schemaLocation), type);
11061
0
    if (res != 0)
11062
0
  return(res);
11063
    /*
11064
    * Load and add the schema document.
11065
    */
11066
0
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
11067
0
  NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
11068
0
    if (res != 0)
11069
0
  return(res);
11070
    /*
11071
    * If we get no schema bucket back, then this means that the schema
11072
    * document could not be located or was broken XML or was not
11073
    * a schema document.
11074
    */
11075
0
    if ((bucket == NULL) || (bucket->doc == NULL)) {
11076
0
  if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
11077
      /*
11078
      * WARNING for <include>:
11079
      * We will raise an error if the schema cannot be located
11080
      * for inclusions, since the that was the feedback from the
11081
      * schema people. I.e. the following spec piece will *not* be
11082
      * satisfied:
11083
      * SPEC src-include: "It is not an error for the `actual value` of the
11084
      * schemaLocation [attribute] to fail to resolve it all, in which
11085
      * case no corresponding inclusion is performed.
11086
      * So do we need a warning report here?"
11087
      */
11088
0
      res = XML_SCHEMAP_SRC_INCLUDE;
11089
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
11090
0
    node, NULL,
11091
0
    "Failed to load the document '%s' for inclusion",
11092
0
    schemaLocation, NULL);
11093
0
  } else {
11094
      /*
11095
      * NOTE: This was changed to raise an error even if no redefinitions
11096
      * are specified.
11097
      *
11098
      * SPEC src-redefine (1)
11099
      * "If there are any element information items among the [children]
11100
      * other than <annotation> then the `actual value` of the
11101
      * schemaLocation [attribute] must successfully resolve."
11102
      * TODO: Ask the WG if a the location has always to resolve
11103
      * here as well!
11104
      */
11105
0
      res = XML_SCHEMAP_SRC_REDEFINE;
11106
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
11107
0
    node, NULL,
11108
0
    "Failed to load the document '%s' for redefinition",
11109
0
    schemaLocation, NULL);
11110
0
  }
11111
0
    } else {
11112
  /*
11113
  * Check targetNamespace sanity before parsing the new schema.
11114
  * TODO: Note that we won't check further content if the
11115
  * targetNamespace was bad.
11116
  */
11117
0
  if (bucket->origTargetNamespace != NULL) {
11118
      /*
11119
      * SPEC src-include (2.1)
11120
      * "SII has a targetNamespace [attribute], and its `actual
11121
      * value` is identical to the `actual value` of the targetNamespace
11122
      * [attribute] of SII' (which must have such an [attribute])."
11123
      */
11124
0
      if (pctxt->targetNamespace == NULL) {
11125
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
11126
0
        XML_SCHEMAP_SRC_INCLUDE,
11127
0
        node, NULL,
11128
0
        "The target namespace of the included/redefined schema "
11129
0
        "'%s' has to be absent, since the including/redefining "
11130
0
        "schema has no target namespace",
11131
0
        schemaLocation, NULL);
11132
0
    goto exit_error;
11133
0
      } else if (!xmlStrEqual(bucket->origTargetNamespace,
11134
0
    pctxt->targetNamespace)) {
11135
    /* TODO: Change error function. */
11136
0
    xmlSchemaPCustomErrExt(pctxt,
11137
0
        XML_SCHEMAP_SRC_INCLUDE,
11138
0
        NULL, node,
11139
0
        "The target namespace '%s' of the included/redefined "
11140
0
        "schema '%s' differs from '%s' of the "
11141
0
        "including/redefining schema",
11142
0
        bucket->origTargetNamespace, schemaLocation,
11143
0
        pctxt->targetNamespace);
11144
0
    goto exit_error;
11145
0
      }
11146
0
  } else if (pctxt->targetNamespace != NULL) {
11147
      /*
11148
      * Chameleons: the original target namespace will
11149
      * differ from the resulting namespace.
11150
      */
11151
0
      isChameleon = 1;
11152
0
      if (bucket->parsed &&
11153
0
    bucket->origTargetNamespace != NULL) {
11154
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
11155
0
        XML_SCHEMAP_SRC_INCLUDE,
11156
0
        node, NULL,
11157
0
        "The target namespace of the included/redefined schema "
11158
0
        "'%s' has to be absent or the same as the "
11159
0
        "including/redefining schema's target namespace",
11160
0
        schemaLocation, NULL);
11161
0
    goto exit_error;
11162
0
      }
11163
0
      bucket->targetNamespace = pctxt->targetNamespace;
11164
0
  }
11165
0
    }
11166
    /*
11167
    * Parse the schema.
11168
    */
11169
0
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11170
0
  if (isChameleon) {
11171
      /* TODO: Get rid of this flag on the schema itself. */
11172
0
      if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11173
0
    schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11174
0
      } else
11175
0
    wasChameleon = 1;
11176
0
  }
11177
0
  xmlSchemaParseNewDoc(pctxt, schema, bucket);
11178
  /* Restore chameleon flag. */
11179
0
  if (isChameleon && (!wasChameleon))
11180
0
      schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11181
0
    }
11182
    /*
11183
    * And now for the children...
11184
    */
11185
0
    child = node->children;
11186
0
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11187
  /*
11188
  * Parse (simpleType | complexType | group | attributeGroup))*
11189
  */
11190
0
  pctxt->redefined = bucket;
11191
  /*
11192
  * How to proceed if the redefined schema was not located?
11193
  */
11194
0
  pctxt->isRedefine = 1;
11195
0
  while (IS_SCHEMA(child, "annotation") ||
11196
0
      IS_SCHEMA(child, "simpleType") ||
11197
0
      IS_SCHEMA(child, "complexType") ||
11198
0
      IS_SCHEMA(child, "group") ||
11199
0
      IS_SCHEMA(child, "attributeGroup")) {
11200
0
      if (IS_SCHEMA(child, "annotation")) {
11201
    /*
11202
    * TODO: discard or not?
11203
    */
11204
0
      } else if (IS_SCHEMA(child, "simpleType")) {
11205
0
    xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11206
0
      } else if (IS_SCHEMA(child, "complexType")) {
11207
0
    xmlSchemaParseComplexType(pctxt, schema, child, 1);
11208
    /* hasRedefinitions = 1; */
11209
0
      } else if (IS_SCHEMA(child, "group")) {
11210
    /* hasRedefinitions = 1; */
11211
0
    xmlSchemaParseModelGroupDefinition(pctxt,
11212
0
        schema, child);
11213
0
      } else if (IS_SCHEMA(child, "attributeGroup")) {
11214
    /* hasRedefinitions = 1; */
11215
0
    xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11216
0
        child);
11217
0
      }
11218
0
      child = child->next;
11219
0
  }
11220
0
  pctxt->redefined = NULL;
11221
0
  pctxt->isRedefine = 0;
11222
0
    } else {
11223
0
  if (IS_SCHEMA(child, "annotation")) {
11224
      /*
11225
      * TODO: discard or not?
11226
      */
11227
0
      child = child->next;
11228
0
  }
11229
0
    }
11230
0
    if (child != NULL) {
11231
0
  res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11232
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11233
0
      xmlSchemaPContentErr(pctxt, res,
11234
0
    NULL, node, child, NULL,
11235
0
    "(annotation | (simpleType | complexType | group | attributeGroup))*");
11236
0
  } else {
11237
0
       xmlSchemaPContentErr(pctxt, res,
11238
0
    NULL, node, child, NULL,
11239
0
    "(annotation?)");
11240
0
  }
11241
0
    }
11242
0
    return(res);
11243
11244
0
exit_error:
11245
0
    return(pctxt->err);
11246
0
}
11247
11248
static int
11249
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11250
                       xmlNodePtr node)
11251
0
{
11252
0
    int res;
11253
#ifndef ENABLE_REDEFINE
11254
    TODO
11255
    return(0);
11256
#endif
11257
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11258
0
  XML_SCHEMA_SCHEMA_REDEFINE);
11259
0
    if (res != 0)
11260
0
  return(res);
11261
0
    return(0);
11262
0
}
11263
11264
static int
11265
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11266
                       xmlNodePtr node)
11267
0
{
11268
0
    int res;
11269
11270
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11271
0
  XML_SCHEMA_SCHEMA_INCLUDE);
11272
0
    if (res != 0)
11273
0
  return(res);
11274
0
    return(0);
11275
0
}
11276
11277
/**
11278
 * xmlSchemaParseModelGroup:
11279
 * @ctxt:  a schema validation context
11280
 * @schema:  the schema being built
11281
 * @node:  a subtree containing XML Schema information
11282
 * @type: the "compositor" type
11283
 * @particleNeeded: if a a model group with a particle
11284
 *
11285
 * parse a XML schema Sequence definition.
11286
 * Applies parts of:
11287
 *   Schema Representation Constraint:
11288
 *     Redefinition Constraints and Semantics (src-redefine)
11289
 *     (6.1), (6.1.1), (6.1.2)
11290
 *
11291
 *   Schema Component Constraint:
11292
 *     All Group Limited (cos-all-limited) (2)
11293
 *     TODO: Actually this should go to component-level checks,
11294
 *     but is done here due to performance. Move it to an other layer
11295
 *     is schema construction via an API is implemented.
11296
 *
11297
 * *WARNING* this interface is highly subject to change
11298
 *
11299
 * Returns -1 in case of error, 0 if the declaration is improper and
11300
 *         1 in case of success.
11301
 */
11302
static xmlSchemaTreeItemPtr
11303
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11304
       xmlNodePtr node, xmlSchemaTypeType type,
11305
       int withParticle)
11306
0
{
11307
0
    xmlSchemaModelGroupPtr item;
11308
0
    xmlSchemaParticlePtr particle = NULL;
11309
0
    xmlNodePtr child = NULL;
11310
0
    xmlAttrPtr attr;
11311
0
    int min = 1, max = 1, isElemRef, hasRefs = 0;
11312
11313
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11314
0
        return (NULL);
11315
    /*
11316
    * Create a model group with the given compositor.
11317
    */
11318
0
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11319
0
    if (item == NULL)
11320
0
  return (NULL);
11321
11322
0
    if (withParticle) {
11323
0
  if (type == XML_SCHEMA_TYPE_ALL) {
11324
0
      min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11325
0
      max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11326
0
  } else {
11327
      /* choice + sequence */
11328
0
      min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11329
0
      max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11330
0
    "(xs:nonNegativeInteger | unbounded)");
11331
0
  }
11332
0
  xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11333
  /*
11334
  * Create a particle
11335
  */
11336
0
  particle = xmlSchemaAddParticle(ctxt, node, min, max);
11337
0
  if (particle == NULL)
11338
0
      return (NULL);
11339
0
  particle->children = (xmlSchemaTreeItemPtr) item;
11340
  /*
11341
  * Check for illegal attributes.
11342
  */
11343
0
  attr = node->properties;
11344
0
  while (attr != NULL) {
11345
0
      if (attr->ns == NULL) {
11346
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11347
0
        (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11348
0
        (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11349
0
        xmlSchemaPIllegalAttrErr(ctxt,
11350
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11351
0
    }
11352
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11353
0
    xmlSchemaPIllegalAttrErr(ctxt,
11354
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11355
0
      }
11356
0
      attr = attr->next;
11357
0
  }
11358
0
    } else {
11359
  /*
11360
  * Check for illegal attributes.
11361
  */
11362
0
  attr = node->properties;
11363
0
  while (attr != NULL) {
11364
0
      if (attr->ns == NULL) {
11365
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11366
0
        xmlSchemaPIllegalAttrErr(ctxt,
11367
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11368
0
    }
11369
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11370
0
    xmlSchemaPIllegalAttrErr(ctxt,
11371
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11372
0
      }
11373
0
      attr = attr->next;
11374
0
  }
11375
0
    }
11376
11377
    /*
11378
    * Extract and validate attributes.
11379
    */
11380
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11381
    /*
11382
    * And now for the children...
11383
    */
11384
0
    child = node->children;
11385
0
    if (IS_SCHEMA(child, "annotation")) {
11386
0
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11387
0
        child = child->next;
11388
0
    }
11389
0
    if (type == XML_SCHEMA_TYPE_ALL) {
11390
0
  xmlSchemaParticlePtr part, last = NULL;
11391
11392
0
  while (IS_SCHEMA(child, "element")) {
11393
0
      part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11394
0
    schema, child, &isElemRef, 0);
11395
      /*
11396
      * SPEC cos-all-limited (2)
11397
      * "The {max occurs} of all the particles in the {particles}
11398
      * of the ('all') group must be 0 or 1.
11399
      */
11400
0
      if (part != NULL) {
11401
0
    if (isElemRef)
11402
0
        hasRefs++;
11403
0
    if (part->minOccurs > 1) {
11404
0
        xmlSchemaPCustomErr(ctxt,
11405
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11406
0
      NULL, child,
11407
0
      "Invalid value for minOccurs (must be 0 or 1)",
11408
0
      NULL);
11409
        /* Reset to 1. */
11410
0
        part->minOccurs = 1;
11411
0
    }
11412
0
    if (part->maxOccurs > 1) {
11413
0
        xmlSchemaPCustomErr(ctxt,
11414
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11415
0
      NULL, child,
11416
0
      "Invalid value for maxOccurs (must be 0 or 1)",
11417
0
      NULL);
11418
        /* Reset to 1. */
11419
0
        part->maxOccurs = 1;
11420
0
    }
11421
0
    if (last == NULL)
11422
0
        item->children = (xmlSchemaTreeItemPtr) part;
11423
0
    else
11424
0
        last->next = (xmlSchemaTreeItemPtr) part;
11425
0
    last = part;
11426
0
      }
11427
0
      child = child->next;
11428
0
  }
11429
0
  if (child != NULL) {
11430
0
      xmlSchemaPContentErr(ctxt,
11431
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11432
0
    NULL, node, child, NULL,
11433
0
    "(annotation?, (annotation?, element*)");
11434
0
  }
11435
0
    } else {
11436
  /* choice + sequence */
11437
0
  xmlSchemaTreeItemPtr part = NULL, last = NULL;
11438
11439
0
  while ((IS_SCHEMA(child, "element")) ||
11440
0
      (IS_SCHEMA(child, "group")) ||
11441
0
      (IS_SCHEMA(child, "any")) ||
11442
0
      (IS_SCHEMA(child, "choice")) ||
11443
0
      (IS_SCHEMA(child, "sequence"))) {
11444
11445
0
      if (IS_SCHEMA(child, "element")) {
11446
0
    part = (xmlSchemaTreeItemPtr)
11447
0
        xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11448
0
    if (part && isElemRef)
11449
0
        hasRefs++;
11450
0
      } else if (IS_SCHEMA(child, "group")) {
11451
0
    part =
11452
0
        xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11453
0
    if (part != NULL)
11454
0
        hasRefs++;
11455
    /*
11456
    * Handle redefinitions.
11457
    */
11458
0
    if (ctxt->isRedefine && ctxt->redef &&
11459
0
        (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11460
0
        part && part->children)
11461
0
    {
11462
0
        if ((xmlSchemaGetQNameRefName(part->children) ==
11463
0
          ctxt->redef->refName) &&
11464
0
      (xmlSchemaGetQNameRefTargetNs(part->children) ==
11465
0
          ctxt->redef->refTargetNs))
11466
0
        {
11467
      /*
11468
      * SPEC src-redefine:
11469
      * (6.1) "If it has a <group> among its contents at
11470
      * some level the `actual value` of whose ref
11471
      * [attribute] is the same as the `actual value` of
11472
      * its own name attribute plus target namespace, then
11473
      * all of the following must be true:"
11474
      * (6.1.1) "It must have exactly one such group."
11475
      */
11476
0
      if (ctxt->redefCounter != 0) {
11477
0
          xmlChar *str = NULL;
11478
11479
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11480
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11481
0
        "The redefining model group definition "
11482
0
        "'%s' must not contain more than one "
11483
0
        "reference to the redefined definition",
11484
0
        xmlSchemaFormatQName(&str,
11485
0
            ctxt->redef->refTargetNs,
11486
0
            ctxt->redef->refName),
11487
0
        NULL);
11488
0
          FREE_AND_NULL(str)
11489
0
          part = NULL;
11490
0
      } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11491
0
          ((WXS_PARTICLE(part))->maxOccurs != 1))
11492
0
      {
11493
0
          xmlChar *str = NULL;
11494
          /*
11495
          * SPEC src-redefine:
11496
          * (6.1.2) "The `actual value` of both that
11497
          * group's minOccurs and maxOccurs [attribute]
11498
          * must be 1 (or `absent`).
11499
          */
11500
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11501
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11502
0
        "The redefining model group definition "
11503
0
        "'%s' must not contain a reference to the "
11504
0
        "redefined definition with a "
11505
0
        "maxOccurs/minOccurs other than 1",
11506
0
        xmlSchemaFormatQName(&str,
11507
0
            ctxt->redef->refTargetNs,
11508
0
            ctxt->redef->refName),
11509
0
        NULL);
11510
0
          FREE_AND_NULL(str)
11511
0
          part = NULL;
11512
0
      }
11513
0
      ctxt->redef->reference = WXS_BASIC_CAST part;
11514
0
      ctxt->redefCounter++;
11515
0
        }
11516
0
    }
11517
0
      } else if (IS_SCHEMA(child, "any")) {
11518
0
    part = (xmlSchemaTreeItemPtr)
11519
0
        xmlSchemaParseAny(ctxt, schema, child);
11520
0
      } else if (IS_SCHEMA(child, "choice")) {
11521
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11522
0
        XML_SCHEMA_TYPE_CHOICE, 1);
11523
0
      } else if (IS_SCHEMA(child, "sequence")) {
11524
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11525
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11526
0
      }
11527
0
      if (part != NULL) {
11528
0
    if (last == NULL)
11529
0
        item->children = part;
11530
0
    else
11531
0
        last->next = part;
11532
0
    last = part;
11533
0
      }
11534
0
      child = child->next;
11535
0
  }
11536
0
  if (child != NULL) {
11537
0
      xmlSchemaPContentErr(ctxt,
11538
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11539
0
    NULL, node, child, NULL,
11540
0
    "(annotation?, (element | group | choice | sequence | any)*)");
11541
0
  }
11542
0
    }
11543
0
    if ((max == 0) && (min == 0))
11544
0
  return (NULL);
11545
0
    if (hasRefs) {
11546
  /*
11547
  * We need to resolve references.
11548
  */
11549
0
  WXS_ADD_PENDING(ctxt, item);
11550
0
    }
11551
0
    if (withParticle)
11552
0
  return ((xmlSchemaTreeItemPtr) particle);
11553
0
    else
11554
0
  return ((xmlSchemaTreeItemPtr) item);
11555
0
}
11556
11557
/**
11558
 * xmlSchemaParseRestriction:
11559
 * @ctxt:  a schema validation context
11560
 * @schema:  the schema being built
11561
 * @node:  a subtree containing XML Schema information
11562
 *
11563
 * parse a XML schema Restriction definition
11564
 * *WARNING* this interface is highly subject to change
11565
 *
11566
 * Returns the type definition or NULL in case of error
11567
 */
11568
static xmlSchemaTypePtr
11569
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11570
                          xmlNodePtr node, xmlSchemaTypeType parentType)
11571
0
{
11572
0
    xmlSchemaTypePtr type;
11573
0
    xmlNodePtr child = NULL;
11574
0
    xmlAttrPtr attr;
11575
11576
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11577
0
        return (NULL);
11578
    /* Not a component, don't create it. */
11579
0
    type = ctxt->ctxtType;
11580
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11581
11582
    /*
11583
    * Check for illegal attributes.
11584
    */
11585
0
    attr = node->properties;
11586
0
    while (attr != NULL) {
11587
0
  if (attr->ns == NULL) {
11588
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11589
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11590
0
    xmlSchemaPIllegalAttrErr(ctxt,
11591
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11592
0
      }
11593
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11594
0
      xmlSchemaPIllegalAttrErr(ctxt,
11595
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11596
0
  }
11597
0
  attr = attr->next;
11598
0
    }
11599
    /*
11600
    * Extract and validate attributes.
11601
    */
11602
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11603
    /*
11604
    * Attribute
11605
    */
11606
    /*
11607
    * Extract the base type. The "base" attribute is mandatory if inside
11608
    * a complex type or if redefining.
11609
    *
11610
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11611
    * among its [children]), the simple type definition which is
11612
    * the {content type} of the type definition `resolved` to by
11613
    * the `actual value` of the base [attribute]"
11614
    */
11615
0
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11616
0
  &(type->baseNs), &(type->base)) == 0)
11617
0
    {
11618
0
  if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11619
0
      xmlSchemaPMissingAttrErr(ctxt,
11620
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
11621
0
    NULL, node, "base", NULL);
11622
0
  } else if ((ctxt->isRedefine) &&
11623
0
      (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11624
0
  {
11625
0
      if (type->base == NULL) {
11626
0
    xmlSchemaPMissingAttrErr(ctxt,
11627
0
        XML_SCHEMAP_S4S_ATTR_MISSING,
11628
0
        NULL, node, "base", NULL);
11629
0
      } else if ((! xmlStrEqual(type->base, type->name)) ||
11630
0
    (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11631
0
      {
11632
0
    xmlChar *str1 = NULL, *str2 = NULL;
11633
    /*
11634
    * REDEFINE: SPEC src-redefine (5)
11635
    * "Within the [children], each <simpleType> must have a
11636
    * <restriction> among its [children] ... the `actual value` of
11637
    * whose base [attribute] must be the same as the `actual value`
11638
    * of its own name attribute plus target namespace;"
11639
    */
11640
0
    xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11641
0
        NULL, node, "This is a redefinition, but the QName "
11642
0
        "value '%s' of the 'base' attribute does not match the "
11643
0
        "type's designation '%s'",
11644
0
        xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11645
0
        xmlSchemaFormatQName(&str2, type->targetNamespace,
11646
0
      type->name), NULL);
11647
0
    FREE_AND_NULL(str1);
11648
0
    FREE_AND_NULL(str2);
11649
    /* Avoid confusion and erase the values. */
11650
0
    type->base = NULL;
11651
0
    type->baseNs = NULL;
11652
0
      }
11653
0
  }
11654
0
    }
11655
    /*
11656
    * And now for the children...
11657
    */
11658
0
    child = node->children;
11659
0
    if (IS_SCHEMA(child, "annotation")) {
11660
  /*
11661
  * Add the annotation to the simple type ancestor.
11662
  */
11663
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11664
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11665
0
        child = child->next;
11666
0
    }
11667
0
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11668
  /*
11669
  * Corresponds to <simpleType><restriction><simpleType>.
11670
  */
11671
0
  if (IS_SCHEMA(child, "simpleType")) {
11672
0
      if (type->base != NULL) {
11673
    /*
11674
    * src-restriction-base-or-simpleType
11675
    * Either the base [attribute] or the simpleType [child] of the
11676
    * <restriction> element must be present, but not both.
11677
    */
11678
0
    xmlSchemaPContentErr(ctxt,
11679
0
        XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11680
0
        NULL, node, child,
11681
0
        "The attribute 'base' and the <simpleType> child are "
11682
0
        "mutually exclusive", NULL);
11683
0
      } else {
11684
0
    type->baseType = (xmlSchemaTypePtr)
11685
0
        xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11686
0
      }
11687
0
      child = child->next;
11688
0
  } else if (type->base == NULL) {
11689
0
      xmlSchemaPContentErr(ctxt,
11690
0
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11691
0
    NULL, node, child,
11692
0
    "Either the attribute 'base' or a <simpleType> child "
11693
0
    "must be present", NULL);
11694
0
  }
11695
0
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11696
  /*
11697
  * Corresponds to <complexType><complexContent><restriction>...
11698
  * followed by:
11699
  *
11700
  * Model groups <all>, <choice> and <sequence>.
11701
  */
11702
0
  if (IS_SCHEMA(child, "all")) {
11703
0
      type->subtypes = (xmlSchemaTypePtr)
11704
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11705
0
        XML_SCHEMA_TYPE_ALL, 1);
11706
0
      child = child->next;
11707
0
  } else if (IS_SCHEMA(child, "choice")) {
11708
0
      type->subtypes = (xmlSchemaTypePtr)
11709
0
    xmlSchemaParseModelGroup(ctxt,
11710
0
        schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11711
0
      child = child->next;
11712
0
  } else if (IS_SCHEMA(child, "sequence")) {
11713
0
      type->subtypes = (xmlSchemaTypePtr)
11714
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11715
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11716
0
      child = child->next;
11717
  /*
11718
  * Model group reference <group>.
11719
  */
11720
0
  } else if (IS_SCHEMA(child, "group")) {
11721
0
      type->subtypes = (xmlSchemaTypePtr)
11722
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11723
      /*
11724
      * Note that the reference will be resolved in
11725
      * xmlSchemaResolveTypeReferences();
11726
      */
11727
0
      child = child->next;
11728
0
  }
11729
0
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11730
  /*
11731
  * Corresponds to <complexType><simpleContent><restriction>...
11732
  *
11733
  * "1.1 the simple type definition corresponding to the <simpleType>
11734
  * among the [children] of <restriction> if there is one;"
11735
  */
11736
0
  if (IS_SCHEMA(child, "simpleType")) {
11737
      /*
11738
      * We will store the to-be-restricted simple type in
11739
      * type->contentTypeDef *temporarily*.
11740
      */
11741
0
      type->contentTypeDef = (xmlSchemaTypePtr)
11742
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11743
0
      if ( type->contentTypeDef == NULL)
11744
0
    return (NULL);
11745
0
      child = child->next;
11746
0
  }
11747
0
    }
11748
11749
0
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11750
0
  (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11751
0
  xmlSchemaFacetPtr facet, lastfacet = NULL;
11752
  /*
11753
  * Corresponds to <complexType><simpleContent><restriction>...
11754
  * <simpleType><restriction>...
11755
  */
11756
11757
  /*
11758
  * Add the facets to the simple type ancestor.
11759
  */
11760
  /*
11761
  * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11762
  * Simple Type Definition Schema Representation Constraint:
11763
  * *Single Facet Value*
11764
  */
11765
0
  while ((IS_SCHEMA(child, "minInclusive")) ||
11766
0
      (IS_SCHEMA(child, "minExclusive")) ||
11767
0
      (IS_SCHEMA(child, "maxInclusive")) ||
11768
0
      (IS_SCHEMA(child, "maxExclusive")) ||
11769
0
      (IS_SCHEMA(child, "totalDigits")) ||
11770
0
      (IS_SCHEMA(child, "fractionDigits")) ||
11771
0
      (IS_SCHEMA(child, "pattern")) ||
11772
0
      (IS_SCHEMA(child, "enumeration")) ||
11773
0
      (IS_SCHEMA(child, "whiteSpace")) ||
11774
0
      (IS_SCHEMA(child, "length")) ||
11775
0
      (IS_SCHEMA(child, "maxLength")) ||
11776
0
      (IS_SCHEMA(child, "minLength"))) {
11777
0
      facet = xmlSchemaParseFacet(ctxt, schema, child);
11778
0
      if (facet != NULL) {
11779
0
    if (lastfacet == NULL)
11780
0
        type->facets = facet;
11781
0
    else
11782
0
        lastfacet->next = facet;
11783
0
    lastfacet = facet;
11784
0
    lastfacet->next = NULL;
11785
0
      }
11786
0
      child = child->next;
11787
0
  }
11788
  /*
11789
  * Create links for derivation and validation.
11790
  */
11791
0
  if (type->facets != NULL) {
11792
0
      xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11793
11794
0
      facet = type->facets;
11795
0
      do {
11796
0
    facetLink = (xmlSchemaFacetLinkPtr)
11797
0
        xmlMalloc(sizeof(xmlSchemaFacetLink));
11798
0
    if (facetLink == NULL) {
11799
0
        xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11800
0
        xmlFree(facetLink);
11801
0
        return (NULL);
11802
0
    }
11803
0
    facetLink->facet = facet;
11804
0
    facetLink->next = NULL;
11805
0
    if (lastFacetLink == NULL)
11806
0
        type->facetSet = facetLink;
11807
0
    else
11808
0
        lastFacetLink->next = facetLink;
11809
0
    lastFacetLink = facetLink;
11810
0
    facet = facet->next;
11811
0
      } while (facet != NULL);
11812
0
  }
11813
0
    }
11814
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11815
  /*
11816
  * Attribute uses/declarations.
11817
  */
11818
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11819
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11820
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11821
0
      return(NULL);
11822
  /*
11823
  * Attribute wildcard.
11824
  */
11825
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11826
0
      type->attributeWildcard =
11827
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11828
0
      child = child->next;
11829
0
  }
11830
0
    }
11831
0
    if (child != NULL) {
11832
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11833
0
      xmlSchemaPContentErr(ctxt,
11834
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11835
0
    NULL, node, child, NULL,
11836
0
    "annotation?, (group | all | choice | sequence)?, "
11837
0
    "((attribute | attributeGroup)*, anyAttribute?))");
11838
0
  } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11839
0
       xmlSchemaPContentErr(ctxt,
11840
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11841
0
    NULL, node, child, NULL,
11842
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11843
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11844
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11845
0
    "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11846
0
  } else {
11847
      /* Simple type */
11848
0
      xmlSchemaPContentErr(ctxt,
11849
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11850
0
    NULL, node, child, NULL,
11851
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11852
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11853
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11854
0
    "pattern)*))");
11855
0
  }
11856
0
    }
11857
0
    return (NULL);
11858
0
}
11859
11860
/**
11861
 * xmlSchemaParseExtension:
11862
 * @ctxt:  a schema validation context
11863
 * @schema:  the schema being built
11864
 * @node:  a subtree containing XML Schema information
11865
 *
11866
 * Parses an <extension>, which is found inside a
11867
 * <simpleContent> or <complexContent>.
11868
 * *WARNING* this interface is highly subject to change.
11869
 *
11870
 * TODO: Returns the type definition or NULL in case of error
11871
 */
11872
static xmlSchemaTypePtr
11873
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11874
                        xmlNodePtr node, xmlSchemaTypeType parentType)
11875
0
{
11876
0
    xmlSchemaTypePtr type;
11877
0
    xmlNodePtr child = NULL;
11878
0
    xmlAttrPtr attr;
11879
11880
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11881
0
        return (NULL);
11882
    /* Not a component, don't create it. */
11883
0
    type = ctxt->ctxtType;
11884
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11885
11886
    /*
11887
    * Check for illegal attributes.
11888
    */
11889
0
    attr = node->properties;
11890
0
    while (attr != NULL) {
11891
0
  if (attr->ns == NULL) {
11892
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11893
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11894
0
    xmlSchemaPIllegalAttrErr(ctxt,
11895
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11896
0
      }
11897
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11898
0
      xmlSchemaPIllegalAttrErr(ctxt,
11899
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11900
0
  }
11901
0
  attr = attr->next;
11902
0
    }
11903
11904
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11905
11906
    /*
11907
    * Attribute "base" - mandatory.
11908
    */
11909
0
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11910
0
  "base", &(type->baseNs), &(type->base)) == 0) &&
11911
0
  (type->base == NULL)) {
11912
0
  xmlSchemaPMissingAttrErr(ctxt,
11913
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11914
0
      NULL, node, "base", NULL);
11915
0
    }
11916
    /*
11917
    * And now for the children...
11918
    */
11919
0
    child = node->children;
11920
0
    if (IS_SCHEMA(child, "annotation")) {
11921
  /*
11922
  * Add the annotation to the type ancestor.
11923
  */
11924
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11925
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11926
0
        child = child->next;
11927
0
    }
11928
0
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11929
  /*
11930
  * Corresponds to <complexType><complexContent><extension>... and:
11931
  *
11932
  * Model groups <all>, <choice>, <sequence> and <group>.
11933
  */
11934
0
  if (IS_SCHEMA(child, "all")) {
11935
0
      type->subtypes = (xmlSchemaTypePtr)
11936
0
    xmlSchemaParseModelGroup(ctxt, schema,
11937
0
        child, XML_SCHEMA_TYPE_ALL, 1);
11938
0
      child = child->next;
11939
0
  } else if (IS_SCHEMA(child, "choice")) {
11940
0
      type->subtypes = (xmlSchemaTypePtr)
11941
0
    xmlSchemaParseModelGroup(ctxt, schema,
11942
0
        child, XML_SCHEMA_TYPE_CHOICE, 1);
11943
0
      child = child->next;
11944
0
  } else if (IS_SCHEMA(child, "sequence")) {
11945
0
      type->subtypes = (xmlSchemaTypePtr)
11946
0
    xmlSchemaParseModelGroup(ctxt, schema,
11947
0
    child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11948
0
      child = child->next;
11949
0
  } else if (IS_SCHEMA(child, "group")) {
11950
0
      type->subtypes = (xmlSchemaTypePtr)
11951
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11952
      /*
11953
      * Note that the reference will be resolved in
11954
      * xmlSchemaResolveTypeReferences();
11955
      */
11956
0
      child = child->next;
11957
0
  }
11958
0
    }
11959
0
    if (child != NULL) {
11960
  /*
11961
  * Attribute uses/declarations.
11962
  */
11963
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11964
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11965
0
      XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11966
0
      return(NULL);
11967
  /*
11968
  * Attribute wildcard.
11969
  */
11970
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11971
0
      ctxt->ctxtType->attributeWildcard =
11972
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11973
0
      child = child->next;
11974
0
  }
11975
0
    }
11976
0
    if (child != NULL) {
11977
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11978
      /* Complex content extension. */
11979
0
      xmlSchemaPContentErr(ctxt,
11980
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11981
0
    NULL, node, child, NULL,
11982
0
    "(annotation?, ((group | all | choice | sequence)?, "
11983
0
    "((attribute | attributeGroup)*, anyAttribute?)))");
11984
0
  } else {
11985
      /* Simple content extension. */
11986
0
      xmlSchemaPContentErr(ctxt,
11987
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11988
0
    NULL, node, child, NULL,
11989
0
    "(annotation?, ((attribute | attributeGroup)*, "
11990
0
    "anyAttribute?))");
11991
0
  }
11992
0
    }
11993
0
    return (NULL);
11994
0
}
11995
11996
/**
11997
 * xmlSchemaParseSimpleContent:
11998
 * @ctxt:  a schema validation context
11999
 * @schema:  the schema being built
12000
 * @node:  a subtree containing XML Schema information
12001
 *
12002
 * parse a XML schema SimpleContent definition
12003
 * *WARNING* this interface is highly subject to change
12004
 *
12005
 * Returns the type definition or NULL in case of error
12006
 */
12007
static int
12008
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
12009
                            xmlSchemaPtr schema, xmlNodePtr node,
12010
          int *hasRestrictionOrExtension)
12011
0
{
12012
0
    xmlSchemaTypePtr type;
12013
0
    xmlNodePtr child = NULL;
12014
0
    xmlAttrPtr attr;
12015
12016
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
12017
0
  (hasRestrictionOrExtension == NULL))
12018
0
        return (-1);
12019
0
    *hasRestrictionOrExtension = 0;
12020
    /* Not a component, don't create it. */
12021
0
    type = ctxt->ctxtType;
12022
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
12023
    /*
12024
    * Check for illegal attributes.
12025
    */
12026
0
    attr = node->properties;
12027
0
    while (attr != NULL) {
12028
0
  if (attr->ns == NULL) {
12029
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
12030
0
    xmlSchemaPIllegalAttrErr(ctxt,
12031
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12032
0
      }
12033
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12034
0
      xmlSchemaPIllegalAttrErr(ctxt,
12035
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12036
0
  }
12037
0
  attr = attr->next;
12038
0
    }
12039
12040
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12041
12042
    /*
12043
    * And now for the children...
12044
    */
12045
0
    child = node->children;
12046
0
    if (IS_SCHEMA(child, "annotation")) {
12047
  /*
12048
  * Add the annotation to the complex type ancestor.
12049
  */
12050
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12051
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
12052
0
        child = child->next;
12053
0
    }
12054
0
    if (child == NULL) {
12055
0
  xmlSchemaPContentErr(ctxt,
12056
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12057
0
      NULL, node, NULL, NULL,
12058
0
      "(annotation?, (restriction | extension))");
12059
0
    }
12060
0
    if (child == NULL) {
12061
0
  xmlSchemaPContentErr(ctxt,
12062
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12063
0
      NULL, node, NULL, NULL,
12064
0
      "(annotation?, (restriction | extension))");
12065
0
    }
12066
0
    if (IS_SCHEMA(child, "restriction")) {
12067
0
        xmlSchemaParseRestriction(ctxt, schema, child,
12068
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
12069
0
  (*hasRestrictionOrExtension) = 1;
12070
0
        child = child->next;
12071
0
    } else if (IS_SCHEMA(child, "extension")) {
12072
0
        xmlSchemaParseExtension(ctxt, schema, child,
12073
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
12074
0
  (*hasRestrictionOrExtension) = 1;
12075
0
        child = child->next;
12076
0
    }
12077
0
    if (child != NULL) {
12078
0
  xmlSchemaPContentErr(ctxt,
12079
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12080
0
      NULL, node, child, NULL,
12081
0
      "(annotation?, (restriction | extension))");
12082
0
    }
12083
0
    return (0);
12084
0
}
12085
12086
/**
12087
 * xmlSchemaParseComplexContent:
12088
 * @ctxt:  a schema validation context
12089
 * @schema:  the schema being built
12090
 * @node:  a subtree containing XML Schema information
12091
 *
12092
 * parse a XML schema ComplexContent definition
12093
 * *WARNING* this interface is highly subject to change
12094
 *
12095
 * Returns the type definition or NULL in case of error
12096
 */
12097
static int
12098
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
12099
                             xmlSchemaPtr schema, xmlNodePtr node,
12100
           int *hasRestrictionOrExtension)
12101
0
{
12102
0
    xmlSchemaTypePtr type;
12103
0
    xmlNodePtr child = NULL;
12104
0
    xmlAttrPtr attr;
12105
12106
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
12107
0
  (hasRestrictionOrExtension == NULL))
12108
0
        return (-1);
12109
0
    *hasRestrictionOrExtension = 0;
12110
    /* Not a component, don't create it. */
12111
0
    type = ctxt->ctxtType;
12112
    /*
12113
    * Check for illegal attributes.
12114
    */
12115
0
    attr = node->properties;
12116
0
    while (attr != NULL) {
12117
0
  if (attr->ns == NULL) {
12118
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
12119
0
    (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
12120
0
      {
12121
0
    xmlSchemaPIllegalAttrErr(ctxt,
12122
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12123
0
      }
12124
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12125
0
      xmlSchemaPIllegalAttrErr(ctxt,
12126
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12127
0
  }
12128
0
  attr = attr->next;
12129
0
    }
12130
12131
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12132
12133
    /*
12134
    * Set the 'mixed' on the complex type ancestor.
12135
    */
12136
0
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12137
0
  if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12138
0
      type->flags |= XML_SCHEMAS_TYPE_MIXED;
12139
0
    }
12140
0
    child = node->children;
12141
0
    if (IS_SCHEMA(child, "annotation")) {
12142
  /*
12143
  * Add the annotation to the complex type ancestor.
12144
  */
12145
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12146
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
12147
0
        child = child->next;
12148
0
    }
12149
0
    if (child == NULL) {
12150
0
  xmlSchemaPContentErr(ctxt,
12151
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12152
0
      NULL, node, NULL,
12153
0
      NULL, "(annotation?, (restriction | extension))");
12154
0
    }
12155
0
    if (child == NULL) {
12156
0
  xmlSchemaPContentErr(ctxt,
12157
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
12158
0
      NULL, node, NULL,
12159
0
      NULL, "(annotation?, (restriction | extension))");
12160
0
    }
12161
0
    if (IS_SCHEMA(child, "restriction")) {
12162
0
        xmlSchemaParseRestriction(ctxt, schema, child,
12163
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12164
0
  (*hasRestrictionOrExtension) = 1;
12165
0
        child = child->next;
12166
0
    } else if (IS_SCHEMA(child, "extension")) {
12167
0
        xmlSchemaParseExtension(ctxt, schema, child,
12168
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12169
0
  (*hasRestrictionOrExtension) = 1;
12170
0
        child = child->next;
12171
0
    }
12172
0
    if (child != NULL) {
12173
0
  xmlSchemaPContentErr(ctxt,
12174
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12175
0
      NULL, node, child,
12176
0
      NULL, "(annotation?, (restriction | extension))");
12177
0
    }
12178
0
    return (0);
12179
0
}
12180
12181
/**
12182
 * xmlSchemaParseComplexType:
12183
 * @ctxt:  a schema validation context
12184
 * @schema:  the schema being built
12185
 * @node:  a subtree containing XML Schema information
12186
 *
12187
 * parse a XML schema Complex Type definition
12188
 * *WARNING* this interface is highly subject to change
12189
 *
12190
 * Returns the type definition or NULL in case of error
12191
 */
12192
static xmlSchemaTypePtr
12193
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12194
                          xmlNodePtr node, int topLevel)
12195
0
{
12196
0
    xmlSchemaTypePtr type, ctxtType;
12197
0
    xmlNodePtr child = NULL;
12198
0
    const xmlChar *name = NULL;
12199
0
    xmlAttrPtr attr;
12200
0
    const xmlChar *attrValue;
12201
#ifdef ENABLE_NAMED_LOCALS
12202
    char buf[40];
12203
#endif
12204
0
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
12205
12206
12207
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12208
0
        return (NULL);
12209
12210
0
    ctxtType = ctxt->ctxtType;
12211
12212
0
    if (topLevel) {
12213
0
  attr = xmlSchemaGetPropNode(node, "name");
12214
0
  if (attr == NULL) {
12215
0
      xmlSchemaPMissingAttrErr(ctxt,
12216
0
    XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12217
0
      return (NULL);
12218
0
  } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12219
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12220
0
      return (NULL);
12221
0
  }
12222
0
    }
12223
12224
0
    if (topLevel == 0) {
12225
  /*
12226
  * Parse as local complex type definition.
12227
  */
12228
#ifdef ENABLE_NAMED_LOCALS
12229
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12230
  type = xmlSchemaAddType(ctxt, schema,
12231
      XML_SCHEMA_TYPE_COMPLEX,
12232
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12233
      ctxt->targetNamespace, node, 0);
12234
#else
12235
0
  type = xmlSchemaAddType(ctxt, schema,
12236
0
      XML_SCHEMA_TYPE_COMPLEX,
12237
0
      NULL, ctxt->targetNamespace, node, 0);
12238
0
#endif
12239
0
  if (type == NULL)
12240
0
      return (NULL);
12241
0
  name = type->name;
12242
0
  type->node = node;
12243
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12244
  /*
12245
  * TODO: We need the target namespace.
12246
  */
12247
0
    } else {
12248
  /*
12249
  * Parse as global complex type definition.
12250
  */
12251
0
  type = xmlSchemaAddType(ctxt, schema,
12252
0
      XML_SCHEMA_TYPE_COMPLEX,
12253
0
      name, ctxt->targetNamespace, node, 1);
12254
0
  if (type == NULL)
12255
0
      return (NULL);
12256
0
  type->node = node;
12257
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12258
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12259
0
    }
12260
0
    type->targetNamespace = ctxt->targetNamespace;
12261
    /*
12262
    * Handle attributes.
12263
    */
12264
0
    attr = node->properties;
12265
0
    while (attr != NULL) {
12266
0
  if (attr->ns == NULL) {
12267
0
      if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12268
    /*
12269
    * Attribute "id".
12270
    */
12271
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12272
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12273
    /*
12274
    * Attribute "mixed".
12275
    */
12276
0
    if (xmlSchemaPGetBoolNodeValue(ctxt,
12277
0
      NULL, (xmlNodePtr) attr))
12278
0
        type->flags |= XML_SCHEMAS_TYPE_MIXED;
12279
0
      } else if (topLevel) {
12280
    /*
12281
    * Attributes of global complex type definitions.
12282
    */
12283
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12284
        /* Pass. */
12285
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12286
        /*
12287
        * Attribute "abstract".
12288
        */
12289
0
        if (xmlSchemaPGetBoolNodeValue(ctxt,
12290
0
          NULL, (xmlNodePtr) attr))
12291
0
      type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12292
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12293
        /*
12294
        * Attribute "final".
12295
        */
12296
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12297
0
      (xmlNodePtr) attr);
12298
0
        if (xmlSchemaPValAttrBlockFinal(attrValue,
12299
0
      &(type->flags),
12300
0
      -1,
12301
0
      XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12302
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12303
0
      -1, -1, -1) != 0)
12304
0
        {
12305
0
      xmlSchemaPSimpleTypeErr(ctxt,
12306
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12307
0
          NULL, (xmlNodePtr) attr, NULL,
12308
0
          "(#all | List of (extension | restriction))",
12309
0
          attrValue, NULL, NULL, NULL);
12310
0
        } else
12311
0
      final = 1;
12312
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12313
        /*
12314
        * Attribute "block".
12315
        */
12316
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12317
0
      (xmlNodePtr) attr);
12318
0
        if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12319
0
      -1,
12320
0
      XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12321
0
      XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12322
0
      -1, -1, -1) != 0) {
12323
0
      xmlSchemaPSimpleTypeErr(ctxt,
12324
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12325
0
          NULL, (xmlNodePtr) attr, NULL,
12326
0
          "(#all | List of (extension | restriction)) ",
12327
0
          attrValue, NULL, NULL, NULL);
12328
0
        } else
12329
0
      block = 1;
12330
0
    } else {
12331
0
      xmlSchemaPIllegalAttrErr(ctxt,
12332
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12333
0
    }
12334
0
      } else {
12335
0
    xmlSchemaPIllegalAttrErr(ctxt,
12336
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12337
0
      }
12338
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12339
0
      xmlSchemaPIllegalAttrErr(ctxt,
12340
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12341
0
  }
12342
0
  attr = attr->next;
12343
0
    }
12344
0
    if (! block) {
12345
  /*
12346
  * Apply default "block" values.
12347
  */
12348
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12349
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12350
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12351
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12352
0
    }
12353
0
    if (! final) {
12354
  /*
12355
  * Apply default "block" values.
12356
  */
12357
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12358
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12359
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12360
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12361
0
    }
12362
    /*
12363
    * And now for the children...
12364
    */
12365
0
    child = node->children;
12366
0
    if (IS_SCHEMA(child, "annotation")) {
12367
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12368
0
        child = child->next;
12369
0
    }
12370
0
    ctxt->ctxtType = type;
12371
0
    if (IS_SCHEMA(child, "simpleContent")) {
12372
  /*
12373
  * <complexType><simpleContent>...
12374
  * 3.4.3 : 2.2
12375
  * Specifying mixed='true' when the <simpleContent>
12376
  * alternative is chosen has no effect
12377
  */
12378
0
  if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12379
0
      type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12380
0
        xmlSchemaParseSimpleContent(ctxt, schema, child,
12381
0
      &hasRestrictionOrExtension);
12382
0
        child = child->next;
12383
0
    } else if (IS_SCHEMA(child, "complexContent")) {
12384
  /*
12385
  * <complexType><complexContent>...
12386
  */
12387
0
  type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12388
0
        xmlSchemaParseComplexContent(ctxt, schema, child,
12389
0
      &hasRestrictionOrExtension);
12390
0
        child = child->next;
12391
0
    } else {
12392
  /*
12393
  * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12394
  *
12395
  * SPEC
12396
  * "...the third alternative (neither <simpleContent> nor
12397
  * <complexContent>) is chosen. This case is understood as shorthand
12398
  * for complex content restricting the `ur-type definition`, and the
12399
  * details of the mappings should be modified as necessary.
12400
  */
12401
0
  type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12402
0
  type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12403
  /*
12404
  * Parse model groups.
12405
  */
12406
0
        if (IS_SCHEMA(child, "all")) {
12407
0
            type->subtypes = (xmlSchemaTypePtr)
12408
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12409
0
        XML_SCHEMA_TYPE_ALL, 1);
12410
0
            child = child->next;
12411
0
        } else if (IS_SCHEMA(child, "choice")) {
12412
0
            type->subtypes = (xmlSchemaTypePtr)
12413
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12414
0
        XML_SCHEMA_TYPE_CHOICE, 1);
12415
0
            child = child->next;
12416
0
        } else if (IS_SCHEMA(child, "sequence")) {
12417
0
            type->subtypes = (xmlSchemaTypePtr)
12418
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12419
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
12420
0
            child = child->next;
12421
0
        } else if (IS_SCHEMA(child, "group")) {
12422
0
            type->subtypes = (xmlSchemaTypePtr)
12423
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12424
      /*
12425
      * Note that the reference will be resolved in
12426
      * xmlSchemaResolveTypeReferences();
12427
      */
12428
0
            child = child->next;
12429
0
        }
12430
  /*
12431
  * Parse attribute decls/refs.
12432
  */
12433
0
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12434
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
12435
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12436
0
      return(NULL);
12437
  /*
12438
  * Parse attribute wildcard.
12439
  */
12440
0
  if (IS_SCHEMA(child, "anyAttribute")) {
12441
0
      type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12442
0
      child = child->next;
12443
0
  }
12444
0
    }
12445
0
    if (child != NULL) {
12446
0
  xmlSchemaPContentErr(ctxt,
12447
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12448
0
      NULL, node, child,
12449
0
      NULL, "(annotation?, (simpleContent | complexContent | "
12450
0
      "((group | all | choice | sequence)?, ((attribute | "
12451
0
      "attributeGroup)*, anyAttribute?))))");
12452
0
    }
12453
    /*
12454
    * REDEFINE: SPEC src-redefine (5)
12455
    */
12456
0
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12457
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12458
0
      NULL, node, "This is a redefinition, thus the "
12459
0
      "<complexType> must have a <restriction> or <extension> "
12460
0
      "grand-child", NULL);
12461
0
    }
12462
0
    ctxt->ctxtType = ctxtType;
12463
0
    return (type);
12464
0
}
12465
12466
/************************************************************************
12467
 *                  *
12468
 *      Validating using Schemas      *
12469
 *                  *
12470
 ************************************************************************/
12471
12472
/************************************************************************
12473
 *                  *
12474
 *      Reading/Writing Schemas       *
12475
 *                  *
12476
 ************************************************************************/
12477
12478
#if 0 /* Will be enabled if it is clear what options are needed. */
12479
/**
12480
 * xmlSchemaParserCtxtSetOptions:
12481
 * @ctxt: a schema parser context
12482
 * @options: a combination of xmlSchemaParserOption
12483
 *
12484
 * Sets the options to be used during the parse.
12485
 *
12486
 * Returns 0 in case of success, -1 in case of an
12487
 * API error.
12488
 */
12489
static int
12490
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12491
            int options)
12492
12493
{
12494
    int i;
12495
12496
    if (ctxt == NULL)
12497
  return (-1);
12498
    /*
12499
    * WARNING: Change the start value if adding to the
12500
    * xmlSchemaParseOption.
12501
    */
12502
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
12503
        if (options & 1<<i) {
12504
      return (-1);
12505
        }
12506
    }
12507
    ctxt->options = options;
12508
    return (0);
12509
}
12510
12511
/**
12512
 * xmlSchemaValidCtxtGetOptions:
12513
 * @ctxt: a schema parser context
12514
 *
12515
 * Returns the option combination of the parser context.
12516
 */
12517
static int
12518
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12519
12520
{
12521
    if (ctxt == NULL)
12522
  return (-1);
12523
    else
12524
  return (ctxt->options);
12525
}
12526
#endif
12527
12528
/**
12529
 * xmlSchemaNewParserCtxt:
12530
 * @URL:  the location of the schema
12531
 *
12532
 * Create an XML Schemas parse context for that file/resource expected
12533
 * to contain an XML Schemas file.
12534
 *
12535
 * Returns the parser context or NULL in case of error
12536
 */
12537
xmlSchemaParserCtxtPtr
12538
xmlSchemaNewParserCtxt(const char *URL)
12539
0
{
12540
0
    xmlSchemaParserCtxtPtr ret;
12541
12542
0
    if (URL == NULL)
12543
0
        return (NULL);
12544
12545
0
    ret = xmlSchemaParserCtxtCreate();
12546
0
    if (ret == NULL)
12547
0
  return(NULL);
12548
0
    ret->dict = xmlDictCreate();
12549
0
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12550
0
    return (ret);
12551
0
}
12552
12553
/**
12554
 * xmlSchemaNewMemParserCtxt:
12555
 * @buffer:  a pointer to a char array containing the schemas
12556
 * @size:  the size of the array
12557
 *
12558
 * Create an XML Schemas parse context for that memory buffer expected
12559
 * to contain an XML Schemas file.
12560
 *
12561
 * Returns the parser context or NULL in case of error
12562
 */
12563
xmlSchemaParserCtxtPtr
12564
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12565
0
{
12566
0
    xmlSchemaParserCtxtPtr ret;
12567
12568
0
    if ((buffer == NULL) || (size <= 0))
12569
0
        return (NULL);
12570
0
    ret = xmlSchemaParserCtxtCreate();
12571
0
    if (ret == NULL)
12572
0
  return(NULL);
12573
0
    ret->buffer = buffer;
12574
0
    ret->size = size;
12575
0
    ret->dict = xmlDictCreate();
12576
0
    return (ret);
12577
0
}
12578
12579
/**
12580
 * xmlSchemaNewDocParserCtxt:
12581
 * @doc:  a preparsed document tree
12582
 *
12583
 * Create an XML Schemas parse context for that document.
12584
 * NB. The document may be modified during the parsing process.
12585
 *
12586
 * Returns the parser context or NULL in case of error
12587
 */
12588
xmlSchemaParserCtxtPtr
12589
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12590
0
{
12591
0
    xmlSchemaParserCtxtPtr ret;
12592
12593
0
    if (doc == NULL)
12594
0
      return (NULL);
12595
0
    ret = xmlSchemaParserCtxtCreate();
12596
0
    if (ret == NULL)
12597
0
  return(NULL);
12598
0
    ret->doc = doc;
12599
0
    ret->dict = xmlDictCreate();
12600
    /* The application has responsibility for the document */
12601
0
    ret->preserve = 1;
12602
12603
0
    return (ret);
12604
0
}
12605
12606
/**
12607
 * xmlSchemaFreeParserCtxt:
12608
 * @ctxt:  the schema parser context
12609
 *
12610
 * Free the resources associated to the schema parser context
12611
 */
12612
void
12613
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12614
0
{
12615
0
    if (ctxt == NULL)
12616
0
        return;
12617
0
    if (ctxt->doc != NULL && !ctxt->preserve)
12618
0
        xmlFreeDoc(ctxt->doc);
12619
0
    if (ctxt->vctxt != NULL) {
12620
0
  xmlSchemaFreeValidCtxt(ctxt->vctxt);
12621
0
    }
12622
0
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12623
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
12624
0
  ctxt->constructor = NULL;
12625
0
  ctxt->ownsConstructor = 0;
12626
0
    }
12627
0
    if (ctxt->attrProhibs != NULL)
12628
0
  xmlSchemaItemListFree(ctxt->attrProhibs);
12629
0
    xmlDictFree(ctxt->dict);
12630
0
    xmlFree(ctxt);
12631
0
}
12632
12633
/************************************************************************
12634
 *                  *
12635
 *      Building the content models     *
12636
 *                  *
12637
 ************************************************************************/
12638
12639
/**
12640
 * xmlSchemaBuildContentModelForSubstGroup:
12641
 *
12642
 * Returns 1 if nillable, 0 otherwise
12643
 */
12644
static int
12645
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12646
  xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12647
0
{
12648
0
    xmlAutomataStatePtr start, tmp;
12649
0
    xmlSchemaElementPtr elemDecl, member;
12650
0
    xmlSchemaSubstGroupPtr substGroup;
12651
0
    int i;
12652
0
    int ret = 0;
12653
12654
0
    elemDecl = (xmlSchemaElementPtr) particle->children;
12655
    /*
12656
    * Wrap the substitution group with a CHOICE.
12657
    */
12658
0
    start = pctxt->state;
12659
0
    if (end == NULL)
12660
0
  end = xmlAutomataNewState(pctxt->am);
12661
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12662
0
    if (substGroup == NULL) {
12663
0
  xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12664
0
      XML_SCHEMAP_INTERNAL,
12665
0
      "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12666
0
      "declaration is marked having a subst. group but none "
12667
0
      "available.\n", elemDecl->name, NULL);
12668
0
  return(0);
12669
0
    }
12670
0
    if (counter >= 0) {
12671
  /*
12672
  * NOTE that we put the declaration in, even if it's abstract.
12673
  * However, an error will be raised during *validation* if an element
12674
  * information item shall be validated against an abstract element
12675
  * declaration.
12676
  */
12677
0
  tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12678
0
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
12679
0
              elemDecl->name, elemDecl->targetNamespace, elemDecl);
12680
  /*
12681
  * Add subst. group members.
12682
  */
12683
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12684
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12685
0
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
12686
0
                   member->name, member->targetNamespace, member);
12687
0
  }
12688
0
    } else if (particle->maxOccurs == 1) {
12689
  /*
12690
  * NOTE that we put the declaration in, even if it's abstract,
12691
  */
12692
0
  xmlAutomataNewEpsilon(pctxt->am,
12693
0
      xmlAutomataNewTransition2(pctxt->am,
12694
0
      start, NULL,
12695
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12696
  /*
12697
  * Add subst. group members.
12698
  */
12699
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12700
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12701
      /*
12702
      * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12703
      *  was incorrectly used instead of xmlAutomataNewTransition2()
12704
      *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12705
      *  section in xmlSchemaBuildAContentModel() ).
12706
      * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12707
      *  intended for the above "counter" section originally. I.e.,
12708
      *  check xs:all with subst-groups.
12709
      *
12710
      * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12711
      *                member->name, member->targetNamespace,
12712
      *          1, 1, member);
12713
      */
12714
0
      tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12715
0
    member->name, member->targetNamespace, member);
12716
0
      xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12717
0
  }
12718
0
    } else {
12719
0
  xmlAutomataStatePtr hop;
12720
0
  int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12721
0
      UNBOUNDED : particle->maxOccurs - 1;
12722
0
  int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12723
12724
0
  counter =
12725
0
      xmlAutomataNewCounter(pctxt->am, minOccurs,
12726
0
      maxOccurs);
12727
0
  hop = xmlAutomataNewState(pctxt->am);
12728
12729
0
  xmlAutomataNewEpsilon(pctxt->am,
12730
0
      xmlAutomataNewTransition2(pctxt->am,
12731
0
      start, NULL,
12732
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl),
12733
0
      hop);
12734
  /*
12735
   * Add subst. group members.
12736
   */
12737
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12738
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12739
0
      xmlAutomataNewEpsilon(pctxt->am,
12740
0
    xmlAutomataNewTransition2(pctxt->am,
12741
0
    start, NULL,
12742
0
    member->name, member->targetNamespace, member),
12743
0
    hop);
12744
0
  }
12745
0
  xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12746
0
  xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12747
0
    }
12748
0
    if (particle->minOccurs == 0) {
12749
0
  xmlAutomataNewEpsilon(pctxt->am, start, end);
12750
0
        ret = 1;
12751
0
    }
12752
0
    pctxt->state = end;
12753
0
    return(ret);
12754
0
}
12755
12756
/**
12757
 * xmlSchemaBuildContentModelForElement:
12758
 *
12759
 * Returns 1 if nillable, 0 otherwise
12760
 */
12761
static int
12762
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12763
             xmlSchemaParticlePtr particle)
12764
0
{
12765
0
    int ret = 0;
12766
12767
0
    if (((xmlSchemaElementPtr) particle->children)->flags &
12768
0
  XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12769
  /*
12770
  * Substitution groups.
12771
  */
12772
0
  ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12773
0
    } else {
12774
0
  xmlSchemaElementPtr elemDecl;
12775
0
  xmlAutomataStatePtr start;
12776
12777
0
  elemDecl = (xmlSchemaElementPtr) particle->children;
12778
12779
0
  if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12780
0
      return(0);
12781
0
  if (particle->maxOccurs == 1) {
12782
0
      start = ctxt->state;
12783
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12784
0
        elemDecl->name, elemDecl->targetNamespace, elemDecl);
12785
0
  } else if ((particle->maxOccurs >= UNBOUNDED) &&
12786
0
             (particle->minOccurs < 2)) {
12787
      /* Special case. */
12788
0
      start = ctxt->state;
12789
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12790
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12791
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12792
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12793
0
  } else {
12794
0
      int counter;
12795
0
      int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12796
0
          UNBOUNDED : particle->maxOccurs - 1;
12797
0
      int minOccurs = particle->minOccurs < 1 ?
12798
0
          0 : particle->minOccurs - 1;
12799
12800
0
      start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12801
0
      counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12802
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12803
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12804
0
      xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12805
0
      ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12806
0
    NULL, counter);
12807
0
  }
12808
0
  if (particle->minOccurs == 0) {
12809
0
      xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12810
0
            ret = 1;
12811
0
        }
12812
0
    }
12813
0
    return(ret);
12814
0
}
12815
12816
/**
12817
 * xmlSchemaBuildAContentModel:
12818
 * @ctxt:  the schema parser context
12819
 * @particle:  the particle component
12820
 * @name:  the complex type's name whose content is being built
12821
 *
12822
 * Create the automaton for the {content type} of a complex type.
12823
 *
12824
 * Returns 1 if the content is nillable, 0 otherwise
12825
 */
12826
static int
12827
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12828
          xmlSchemaParticlePtr particle)
12829
0
{
12830
0
    int ret = 0, tmp2;
12831
12832
0
    if (particle == NULL) {
12833
0
  PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12834
0
  return(1);
12835
0
    }
12836
0
    if (particle->children == NULL) {
12837
  /*
12838
  * Just return in this case. A missing "term" of the particle
12839
  * might arise due to an invalid "term" component.
12840
  */
12841
0
  return(1);
12842
0
    }
12843
12844
0
    switch (particle->children->type) {
12845
0
  case XML_SCHEMA_TYPE_ANY: {
12846
0
      xmlAutomataStatePtr start, end;
12847
0
      xmlSchemaWildcardPtr wild;
12848
0
      xmlSchemaWildcardNsPtr ns;
12849
12850
0
      wild = (xmlSchemaWildcardPtr) particle->children;
12851
12852
0
      start = pctxt->state;
12853
0
      end = xmlAutomataNewState(pctxt->am);
12854
12855
0
      if (particle->maxOccurs == 1) {
12856
0
    if (wild->any == 1) {
12857
        /*
12858
        * We need to add both transitions:
12859
        *
12860
        * 1. the {"*", "*"} for elements in a namespace.
12861
        */
12862
0
        pctxt->state =
12863
0
      xmlAutomataNewTransition2(pctxt->am,
12864
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12865
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12866
        /*
12867
        * 2. the {"*"} for elements in no namespace.
12868
        */
12869
0
        pctxt->state =
12870
0
      xmlAutomataNewTransition2(pctxt->am,
12871
0
      start, NULL, BAD_CAST "*", NULL, wild);
12872
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12873
12874
0
    } else if (wild->nsSet != NULL) {
12875
0
        ns = wild->nsSet;
12876
0
        do {
12877
0
      pctxt->state = start;
12878
0
      pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12879
0
          pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12880
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12881
0
      ns = ns->next;
12882
0
        } while (ns != NULL);
12883
12884
0
    } else if (wild->negNsSet != NULL) {
12885
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12886
0
      start, end, BAD_CAST "*", wild->negNsSet->value,
12887
0
      wild);
12888
0
    }
12889
0
      } else {
12890
0
    int counter;
12891
0
    xmlAutomataStatePtr hop;
12892
0
    int maxOccurs =
12893
0
        particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12894
0
                                           particle->maxOccurs - 1;
12895
0
    int minOccurs =
12896
0
        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12897
12898
0
    counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12899
0
    hop = xmlAutomataNewState(pctxt->am);
12900
0
    if (wild->any == 1) {
12901
0
        pctxt->state =
12902
0
      xmlAutomataNewTransition2(pctxt->am,
12903
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12904
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12905
0
        pctxt->state =
12906
0
      xmlAutomataNewTransition2(pctxt->am,
12907
0
      start, NULL, BAD_CAST "*", NULL, wild);
12908
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12909
0
    } else if (wild->nsSet != NULL) {
12910
0
        ns = wild->nsSet;
12911
0
        do {
12912
0
      pctxt->state =
12913
0
          xmlAutomataNewTransition2(pctxt->am,
12914
0
        start, NULL, BAD_CAST "*", ns->value, wild);
12915
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12916
0
      ns = ns->next;
12917
0
        } while (ns != NULL);
12918
12919
0
    } else if (wild->negNsSet != NULL) {
12920
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12921
0
      start, hop, BAD_CAST "*", wild->negNsSet->value,
12922
0
      wild);
12923
0
    }
12924
0
    xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12925
0
    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12926
0
      }
12927
0
      if (particle->minOccurs == 0) {
12928
0
    xmlAutomataNewEpsilon(pctxt->am, start, end);
12929
0
                ret = 1;
12930
0
      }
12931
0
      pctxt->state = end;
12932
0
            break;
12933
0
  }
12934
0
        case XML_SCHEMA_TYPE_ELEMENT:
12935
0
      ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12936
0
      break;
12937
0
        case XML_SCHEMA_TYPE_SEQUENCE:{
12938
0
            xmlSchemaTreeItemPtr sub;
12939
12940
0
            ret = 1;
12941
            /*
12942
             * If max and min occurrences are default (1) then
12943
             * simply iterate over the particles of the <sequence>.
12944
             */
12945
0
            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12946
0
                sub = particle->children->children;
12947
12948
0
                while (sub != NULL) {
12949
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12950
0
                                        (xmlSchemaParticlePtr) sub);
12951
0
                    if (tmp2 != 1) ret = 0;
12952
0
                    sub = sub->next;
12953
0
                }
12954
0
            } else {
12955
0
                xmlAutomataStatePtr oldstate = pctxt->state;
12956
12957
0
                if (particle->maxOccurs >= UNBOUNDED) {
12958
0
                    if (particle->minOccurs > 1) {
12959
0
                        xmlAutomataStatePtr tmp;
12960
0
                        int counter;
12961
12962
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12963
0
                            oldstate, NULL);
12964
0
                        oldstate = pctxt->state;
12965
12966
0
                        counter = xmlAutomataNewCounter(pctxt->am,
12967
0
                            particle->minOccurs - 1, UNBOUNDED);
12968
12969
0
                        sub = particle->children->children;
12970
0
                        while (sub != NULL) {
12971
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12972
0
                                            (xmlSchemaParticlePtr) sub);
12973
0
                            if (tmp2 != 1) ret = 0;
12974
0
                            sub = sub->next;
12975
0
                        }
12976
0
                        tmp = pctxt->state;
12977
0
                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
12978
0
                                                   oldstate, counter);
12979
0
                        pctxt->state =
12980
0
                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
12981
0
                                                       NULL, counter);
12982
0
                        if (ret == 1)
12983
0
                            xmlAutomataNewEpsilon(pctxt->am,
12984
0
                                                oldstate, pctxt->state);
12985
12986
0
                    } else {
12987
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12988
0
                            oldstate, NULL);
12989
0
                        oldstate = pctxt->state;
12990
12991
0
                        sub = particle->children->children;
12992
0
                        while (sub != NULL) {
12993
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12994
0
                                        (xmlSchemaParticlePtr) sub);
12995
0
                            if (tmp2 != 1) ret = 0;
12996
0
                            sub = sub->next;
12997
0
                        }
12998
0
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12999
0
                                              oldstate);
13000
                        /*
13001
                         * epsilon needed to block previous trans from
13002
                         * being allowed to enter back from another
13003
                         * construct
13004
                         */
13005
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13006
0
                                            pctxt->state, NULL);
13007
0
                        if (particle->minOccurs == 0) {
13008
0
                            xmlAutomataNewEpsilon(pctxt->am,
13009
0
                                oldstate, pctxt->state);
13010
0
                            ret = 1;
13011
0
                        }
13012
0
                    }
13013
0
                } else if ((particle->maxOccurs > 1)
13014
0
                           || (particle->minOccurs > 1)) {
13015
0
                    xmlAutomataStatePtr tmp;
13016
0
                    int counter;
13017
13018
0
                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13019
0
                        oldstate, NULL);
13020
0
                    oldstate = pctxt->state;
13021
13022
0
                    counter = xmlAutomataNewCounter(pctxt->am,
13023
0
                        particle->minOccurs - 1,
13024
0
                        particle->maxOccurs - 1);
13025
13026
0
                    sub = particle->children->children;
13027
0
                    while (sub != NULL) {
13028
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
13029
0
                                        (xmlSchemaParticlePtr) sub);
13030
0
                        if (tmp2 != 1) ret = 0;
13031
0
                        sub = sub->next;
13032
0
                    }
13033
0
                    tmp = pctxt->state;
13034
0
                    xmlAutomataNewCountedTrans(pctxt->am,
13035
0
                        tmp, oldstate, counter);
13036
0
                    pctxt->state =
13037
0
                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
13038
0
                                                   counter);
13039
0
                    if ((particle->minOccurs == 0) || (ret == 1)) {
13040
0
                        xmlAutomataNewEpsilon(pctxt->am,
13041
0
                                            oldstate, pctxt->state);
13042
0
                        ret = 1;
13043
0
                    }
13044
0
                } else {
13045
0
                    sub = particle->children->children;
13046
0
                    while (sub != NULL) {
13047
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
13048
0
                                        (xmlSchemaParticlePtr) sub);
13049
0
                        if (tmp2 != 1) ret = 0;
13050
0
                        sub = sub->next;
13051
0
                    }
13052
13053
        /*
13054
         * epsilon needed to block previous trans from
13055
         * being allowed to enter back from another
13056
         * construct
13057
         */
13058
0
        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
13059
0
          pctxt->state, NULL);
13060
13061
0
                    if (particle->minOccurs == 0) {
13062
0
                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
13063
0
                                              pctxt->state);
13064
0
                        ret = 1;
13065
0
                    }
13066
0
                }
13067
0
            }
13068
0
            break;
13069
0
        }
13070
0
        case XML_SCHEMA_TYPE_CHOICE:{
13071
0
            xmlSchemaTreeItemPtr sub;
13072
0
            xmlAutomataStatePtr start, end;
13073
13074
0
            ret = 0;
13075
0
            start = pctxt->state;
13076
0
            end = xmlAutomataNewState(pctxt->am);
13077
13078
            /*
13079
             * iterate over the subtypes and remerge the end with an
13080
             * epsilon transition
13081
             */
13082
0
            if (particle->maxOccurs == 1) {
13083
0
                sub = particle->children->children;
13084
0
                while (sub != NULL) {
13085
0
                    pctxt->state = start;
13086
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
13087
0
                                        (xmlSchemaParticlePtr) sub);
13088
0
                    if (tmp2 == 1) ret = 1;
13089
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
13090
0
                    sub = sub->next;
13091
0
                }
13092
0
            } else {
13093
0
                int counter;
13094
0
                xmlAutomataStatePtr hop, base;
13095
0
                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
13096
0
                    UNBOUNDED : particle->maxOccurs - 1;
13097
0
                int minOccurs =
13098
0
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
13099
13100
                /*
13101
                 * use a counter to keep track of the number of transitions
13102
                 * which went through the choice.
13103
                 */
13104
0
                counter =
13105
0
                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
13106
0
                hop = xmlAutomataNewState(pctxt->am);
13107
0
                base = xmlAutomataNewState(pctxt->am);
13108
13109
0
                sub = particle->children->children;
13110
0
                while (sub != NULL) {
13111
0
                    pctxt->state = base;
13112
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
13113
0
                                        (xmlSchemaParticlePtr) sub);
13114
0
                    if (tmp2 == 1) ret = 1;
13115
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
13116
0
                    sub = sub->next;
13117
0
                }
13118
0
                xmlAutomataNewEpsilon(pctxt->am, start, base);
13119
0
                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
13120
0
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
13121
0
                if (ret == 1)
13122
0
                    xmlAutomataNewEpsilon(pctxt->am, base, end);
13123
0
            }
13124
0
            if (particle->minOccurs == 0) {
13125
0
                xmlAutomataNewEpsilon(pctxt->am, start, end);
13126
0
                ret = 1;
13127
0
            }
13128
0
            pctxt->state = end;
13129
0
            break;
13130
0
        }
13131
0
        case XML_SCHEMA_TYPE_ALL:{
13132
0
            xmlAutomataStatePtr start, tmp;
13133
0
            xmlSchemaParticlePtr sub;
13134
0
            xmlSchemaElementPtr elemDecl;
13135
13136
0
            ret = 1;
13137
13138
0
            sub = (xmlSchemaParticlePtr) particle->children->children;
13139
0
            if (sub == NULL)
13140
0
                break;
13141
13142
0
            ret = 0;
13143
13144
0
            start = pctxt->state;
13145
0
            tmp = xmlAutomataNewState(pctxt->am);
13146
0
            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13147
0
            pctxt->state = tmp;
13148
0
            while (sub != NULL) {
13149
0
                pctxt->state = tmp;
13150
13151
0
                elemDecl = (xmlSchemaElementPtr) sub->children;
13152
0
                if (elemDecl == NULL) {
13153
0
                    PERROR_INT("xmlSchemaBuildAContentModel",
13154
0
                        "<element> particle has no term");
13155
0
                    return(ret);
13156
0
                };
13157
                /*
13158
                * NOTE: The {max occurs} of all the particles in the
13159
                * {particles} of the group must be 0 or 1; this is
13160
                * already ensured during the parse of the content of
13161
                * <all>.
13162
                */
13163
0
                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13164
0
                    int counter;
13165
13166
                    /*
13167
                     * This is an abstract group, we need to share
13168
                     * the same counter for all the element transitions
13169
                     * derived from the group
13170
                     */
13171
0
                    counter = xmlAutomataNewCounter(pctxt->am,
13172
0
                                       sub->minOccurs, sub->maxOccurs);
13173
0
                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
13174
0
                                       sub, counter, pctxt->state);
13175
0
                } else {
13176
0
                    if ((sub->minOccurs == 1) &&
13177
0
                        (sub->maxOccurs == 1)) {
13178
0
                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13179
0
                                                pctxt->state,
13180
0
                                                elemDecl->name,
13181
0
                                                elemDecl->targetNamespace,
13182
0
                                                1, 1, elemDecl);
13183
0
                    } else if ((sub->minOccurs == 0) &&
13184
0
                        (sub->maxOccurs == 1)) {
13185
13186
0
                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13187
0
                                                 pctxt->state,
13188
0
                                                 elemDecl->name,
13189
0
                                                 elemDecl->targetNamespace,
13190
0
                                                 0,
13191
0
                                                 1,
13192
0
                                                 elemDecl);
13193
0
                    }
13194
0
                }
13195
0
                sub = (xmlSchemaParticlePtr) sub->next;
13196
0
            }
13197
0
            pctxt->state =
13198
0
                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13199
0
            if (particle->minOccurs == 0) {
13200
0
                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13201
0
                ret = 1;
13202
0
            }
13203
0
            break;
13204
0
        }
13205
0
  case XML_SCHEMA_TYPE_GROUP:
13206
      /*
13207
      * If we hit a model group definition, then this means that
13208
      * it was empty, thus was not substituted for the containing
13209
      * model group. Just do nothing in this case.
13210
      * TODO: But the group should be substituted and not occur at
13211
      * all in the content model at this point. Fix this.
13212
      */
13213
0
            ret = 1;
13214
0
      break;
13215
0
        default:
13216
0
      xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13217
0
    "xmlSchemaBuildAContentModel",
13218
0
    "found unexpected term of type '%s' in content model",
13219
0
    WXS_ITEM_TYPE_NAME(particle->children), NULL);
13220
0
            return(ret);
13221
0
    }
13222
0
    return(ret);
13223
0
}
13224
13225
/**
13226
 * xmlSchemaBuildContentModel:
13227
 * @ctxt:  the schema parser context
13228
 * @type:  the complex type definition
13229
 * @name:  the element name
13230
 *
13231
 * Builds the content model of the complex type.
13232
 */
13233
static void
13234
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13235
         xmlSchemaParserCtxtPtr ctxt)
13236
0
{
13237
0
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13238
0
  (type->contModel != NULL) ||
13239
0
  ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13240
0
  (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13241
0
  return;
13242
13243
#ifdef DEBUG_CONTENT
13244
    xmlGenericError(xmlGenericErrorContext,
13245
                    "Building content model for %s\n", name);
13246
#endif
13247
0
    ctxt->am = NULL;
13248
0
    ctxt->am = xmlNewAutomata();
13249
0
    if (ctxt->am == NULL) {
13250
0
        xmlGenericError(xmlGenericErrorContext,
13251
0
      "Cannot create automata for complex type %s\n", type->name);
13252
0
        return;
13253
0
    }
13254
0
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
13255
    /*
13256
    * Build the automaton.
13257
    */
13258
0
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13259
0
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13260
0
    type->contModel = xmlAutomataCompile(ctxt->am);
13261
0
    if (type->contModel == NULL) {
13262
0
        xmlSchemaPCustomErr(ctxt,
13263
0
      XML_SCHEMAP_INTERNAL,
13264
0
      WXS_BASIC_CAST type, type->node,
13265
0
      "Failed to compile the content model", NULL);
13266
0
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13267
0
        xmlSchemaPCustomErr(ctxt,
13268
0
      XML_SCHEMAP_NOT_DETERMINISTIC,
13269
      /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13270
0
      WXS_BASIC_CAST type, type->node,
13271
0
      "The content model is not determinist", NULL);
13272
0
    } else {
13273
#ifdef DEBUG_CONTENT_REGEXP
13274
        xmlGenericError(xmlGenericErrorContext,
13275
                        "Content model of %s:\n", type->name);
13276
        xmlRegexpPrint(stderr, type->contModel);
13277
#endif
13278
0
    }
13279
0
    ctxt->state = NULL;
13280
0
    xmlFreeAutomata(ctxt->am);
13281
0
    ctxt->am = NULL;
13282
0
}
13283
13284
/**
13285
 * xmlSchemaResolveElementReferences:
13286
 * @elem:  the schema element context
13287
 * @ctxt:  the schema parser context
13288
 *
13289
 * Resolves the references of an element declaration
13290
 * or particle, which has an element declaration as it's
13291
 * term.
13292
 */
13293
static void
13294
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13295
          xmlSchemaParserCtxtPtr ctxt)
13296
0
{
13297
0
    if ((ctxt == NULL) || (elemDecl == NULL) ||
13298
0
  ((elemDecl != NULL) &&
13299
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13300
0
        return;
13301
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13302
13303
0
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13304
0
  xmlSchemaTypePtr type;
13305
13306
  /* (type definition) ... otherwise the type definition `resolved`
13307
  * to by the `actual value` of the type [attribute] ...
13308
  */
13309
0
  type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13310
0
      elemDecl->namedTypeNs);
13311
0
  if (type == NULL) {
13312
0
      xmlSchemaPResCompAttrErr(ctxt,
13313
0
    XML_SCHEMAP_SRC_RESOLVE,
13314
0
    WXS_BASIC_CAST elemDecl, elemDecl->node,
13315
0
    "type", elemDecl->namedType, elemDecl->namedTypeNs,
13316
0
    XML_SCHEMA_TYPE_BASIC, "type definition");
13317
0
  } else
13318
0
      elemDecl->subtypes = type;
13319
0
    }
13320
0
    if (elemDecl->substGroup != NULL) {
13321
0
  xmlSchemaElementPtr substHead;
13322
13323
  /*
13324
  * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13325
  * substitutionGroup?
13326
  */
13327
0
  substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13328
0
      elemDecl->substGroupNs);
13329
0
  if (substHead == NULL) {
13330
0
      xmlSchemaPResCompAttrErr(ctxt,
13331
0
    XML_SCHEMAP_SRC_RESOLVE,
13332
0
    WXS_BASIC_CAST elemDecl, NULL,
13333
0
    "substitutionGroup", elemDecl->substGroup,
13334
0
    elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13335
0
  } else {
13336
0
      xmlSchemaResolveElementReferences(substHead, ctxt);
13337
      /*
13338
      * Set the "substitution group affiliation".
13339
      * NOTE that now we use the "refDecl" field for this.
13340
      */
13341
0
      WXS_SUBST_HEAD(elemDecl) = substHead;
13342
      /*
13343
      * The type definitions is set to:
13344
      * SPEC "...the {type definition} of the element
13345
      * declaration `resolved` to by the `actual value`
13346
      * of the substitutionGroup [attribute], if present"
13347
      */
13348
0
      if (elemDecl->subtypes == NULL)
13349
0
    elemDecl->subtypes = substHead->subtypes;
13350
0
  }
13351
0
    }
13352
    /*
13353
    * SPEC "The definition of anyType serves as the default type definition
13354
    * for element declarations whose XML representation does not specify one."
13355
    */
13356
0
    if ((elemDecl->subtypes == NULL) &&
13357
0
  (elemDecl->namedType == NULL) &&
13358
0
  (elemDecl->substGroup == NULL))
13359
0
  elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13360
0
}
13361
13362
/**
13363
 * xmlSchemaResolveUnionMemberTypes:
13364
 * @ctxt:  the schema parser context
13365
 * @type:  the schema simple type definition
13366
 *
13367
 * Checks and builds the "member type definitions" property of the union
13368
 * simple type. This handles part (1), part (2) is done in
13369
 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13370
 *
13371
 * Returns -1 in case of an internal error, 0 otherwise.
13372
 */
13373
static int
13374
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13375
         xmlSchemaTypePtr type)
13376
0
{
13377
13378
0
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
13379
0
    xmlSchemaTypePtr memberType;
13380
13381
    /*
13382
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13383
    * define the explicit members as the type definitions `resolved`
13384
    * to by the items in the `actual value` of the memberTypes [attribute],
13385
    * if any, followed by the type definitions corresponding to the
13386
    * <simpleType>s among the [children] of <union>, if any."
13387
    */
13388
    /*
13389
    * Resolve references.
13390
    */
13391
0
    link = type->memberTypes;
13392
0
    lastLink = NULL;
13393
0
    while (link != NULL) {
13394
0
  const xmlChar *name, *nsName;
13395
13396
0
  name = ((xmlSchemaQNameRefPtr) link->type)->name;
13397
0
  nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13398
13399
0
  memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13400
0
  if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13401
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13402
0
    WXS_BASIC_CAST type, type->node, "memberTypes",
13403
0
    name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13404
      /*
13405
      * Remove the member type link.
13406
      */
13407
0
      if (lastLink == NULL)
13408
0
    type->memberTypes = link->next;
13409
0
      else
13410
0
    lastLink->next = link->next;
13411
0
      newLink = link;
13412
0
      link = link->next;
13413
0
      xmlFree(newLink);
13414
0
  } else {
13415
0
      link->type = memberType;
13416
0
      lastLink = link;
13417
0
      link = link->next;
13418
0
  }
13419
0
    }
13420
    /*
13421
    * Add local simple types,
13422
    */
13423
0
    memberType = type->subtypes;
13424
0
    while (memberType != NULL) {
13425
0
  link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13426
0
  if (link == NULL) {
13427
0
      xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
13428
0
      return (-1);
13429
0
  }
13430
0
  link->type = memberType;
13431
0
  link->next = NULL;
13432
0
  if (lastLink == NULL)
13433
0
      type->memberTypes = link;
13434
0
  else
13435
0
      lastLink->next = link;
13436
0
  lastLink = link;
13437
0
  memberType = memberType->next;
13438
0
    }
13439
0
    return (0);
13440
0
}
13441
13442
/**
13443
 * xmlSchemaIsDerivedFromBuiltInType:
13444
 * @ctxt:  the schema parser context
13445
 * @type:  the type definition
13446
 * @valType: the value type
13447
 *
13448
 *
13449
 * Returns 1 if the type has the given value type, or
13450
 * is derived from such a type.
13451
 */
13452
static int
13453
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13454
0
{
13455
0
    if (type == NULL)
13456
0
  return (0);
13457
0
    if (WXS_IS_COMPLEX(type))
13458
0
  return (0);
13459
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13460
0
  if (type->builtInType == valType)
13461
0
      return(1);
13462
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13463
0
      (type->builtInType == XML_SCHEMAS_ANYTYPE))
13464
0
      return (0);
13465
0
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13466
0
    }
13467
0
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13468
0
}
13469
13470
#if 0
13471
/**
13472
 * xmlSchemaIsDerivedFromBuiltInType:
13473
 * @ctxt:  the schema parser context
13474
 * @type:  the type definition
13475
 * @valType: the value type
13476
 *
13477
 *
13478
 * Returns 1 if the type has the given value type, or
13479
 * is derived from such a type.
13480
 */
13481
static int
13482
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13483
{
13484
    if (type == NULL)
13485
  return (0);
13486
    if (WXS_IS_COMPLEX(type))
13487
  return (0);
13488
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13489
  if (type->builtInType == valType)
13490
      return(1);
13491
  return (0);
13492
    } else
13493
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13494
13495
    return (0);
13496
}
13497
13498
static xmlSchemaTypePtr
13499
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13500
{
13501
    if (type == NULL)
13502
  return (NULL);
13503
    if (WXS_IS_COMPLEX(type))
13504
  return (NULL);
13505
    if (type->type == XML_SCHEMA_TYPE_BASIC)
13506
  return(type);
13507
    return(xmlSchemaQueryBuiltInType(type->subtypes));
13508
}
13509
#endif
13510
13511
/**
13512
 * xmlSchemaGetPrimitiveType:
13513
 * @type:  the simpleType definition
13514
 *
13515
 * Returns the primitive type of the given type or
13516
 * NULL in case of error.
13517
 */
13518
static xmlSchemaTypePtr
13519
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13520
0
{
13521
13522
0
    while (type != NULL) {
13523
  /*
13524
  * Note that anySimpleType is actually not a primitive type
13525
  * but we need that here.
13526
  */
13527
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13528
0
     (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13529
0
      return (type);
13530
0
  type = type->baseType;
13531
0
    }
13532
13533
0
    return (NULL);
13534
0
}
13535
13536
#if 0
13537
/**
13538
 * xmlSchemaGetBuiltInTypeAncestor:
13539
 * @type:  the simpleType definition
13540
 *
13541
 * Returns the primitive type of the given type or
13542
 * NULL in case of error.
13543
 */
13544
static xmlSchemaTypePtr
13545
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13546
{
13547
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13548
  return (0);
13549
    while (type != NULL) {
13550
  if (type->type == XML_SCHEMA_TYPE_BASIC)
13551
      return (type);
13552
  type = type->baseType;
13553
    }
13554
13555
    return (NULL);
13556
}
13557
#endif
13558
13559
/**
13560
 * xmlSchemaCloneWildcardNsConstraints:
13561
 * @ctxt:  the schema parser context
13562
 * @dest:  the destination wildcard
13563
 * @source: the source wildcard
13564
 *
13565
 * Clones the namespace constraints of source
13566
 * and assigns them to dest.
13567
 * Returns -1 on internal error, 0 otherwise.
13568
 */
13569
static int
13570
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13571
            xmlSchemaWildcardPtr dest,
13572
            xmlSchemaWildcardPtr source)
13573
0
{
13574
0
    xmlSchemaWildcardNsPtr cur, tmp, last;
13575
13576
0
    if ((source == NULL) || (dest == NULL))
13577
0
  return(-1);
13578
0
    dest->any = source->any;
13579
0
    cur = source->nsSet;
13580
0
    last = NULL;
13581
0
    while (cur != NULL) {
13582
0
  tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13583
0
  if (tmp == NULL)
13584
0
      return(-1);
13585
0
  tmp->value = cur->value;
13586
0
  if (last == NULL)
13587
0
      dest->nsSet = tmp;
13588
0
  else
13589
0
      last->next = tmp;
13590
0
  last = tmp;
13591
0
  cur = cur->next;
13592
0
    }
13593
0
    if (dest->negNsSet != NULL)
13594
0
  xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13595
0
    if (source->negNsSet != NULL) {
13596
0
  dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13597
0
  if (dest->negNsSet == NULL)
13598
0
      return(-1);
13599
0
  dest->negNsSet->value = source->negNsSet->value;
13600
0
    } else
13601
0
  dest->negNsSet = NULL;
13602
0
    return(0);
13603
0
}
13604
13605
/**
13606
 * xmlSchemaUnionWildcards:
13607
 * @ctxt:  the schema parser context
13608
 * @completeWild:  the first wildcard
13609
 * @curWild: the second wildcard
13610
 *
13611
 * Unions the namespace constraints of the given wildcards.
13612
 * @completeWild will hold the resulting union.
13613
 * Returns a positive error code on failure, -1 in case of an
13614
 * internal error, 0 otherwise.
13615
 */
13616
static int
13617
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13618
          xmlSchemaWildcardPtr completeWild,
13619
          xmlSchemaWildcardPtr curWild)
13620
0
{
13621
0
    xmlSchemaWildcardNsPtr cur, curB, tmp;
13622
13623
    /*
13624
    * 1 If O1 and O2 are the same value, then that value must be the
13625
    * value.
13626
    */
13627
0
    if ((completeWild->any == curWild->any) &&
13628
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13629
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13630
13631
0
  if ((completeWild->negNsSet == NULL) ||
13632
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13633
13634
0
      if (completeWild->nsSet != NULL) {
13635
0
    int found = 0;
13636
13637
    /*
13638
    * Check equality of sets.
13639
    */
13640
0
    cur = completeWild->nsSet;
13641
0
    while (cur != NULL) {
13642
0
        found = 0;
13643
0
        curB = curWild->nsSet;
13644
0
        while (curB != NULL) {
13645
0
      if (cur->value == curB->value) {
13646
0
          found = 1;
13647
0
          break;
13648
0
      }
13649
0
      curB = curB->next;
13650
0
        }
13651
0
        if (!found)
13652
0
      break;
13653
0
        cur = cur->next;
13654
0
    }
13655
0
    if (found)
13656
0
        return(0);
13657
0
      } else
13658
0
    return(0);
13659
0
  }
13660
0
    }
13661
    /*
13662
    * 2 If either O1 or O2 is any, then any must be the value
13663
    */
13664
0
    if (completeWild->any != curWild->any) {
13665
0
  if (completeWild->any == 0) {
13666
0
      completeWild->any = 1;
13667
0
      if (completeWild->nsSet != NULL) {
13668
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13669
0
    completeWild->nsSet = NULL;
13670
0
      }
13671
0
      if (completeWild->negNsSet != NULL) {
13672
0
    xmlFree(completeWild->negNsSet);
13673
0
    completeWild->negNsSet = NULL;
13674
0
      }
13675
0
  }
13676
0
  return (0);
13677
0
    }
13678
    /*
13679
    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13680
    * then the union of those sets must be the value.
13681
    */
13682
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13683
0
  int found;
13684
0
  xmlSchemaWildcardNsPtr start;
13685
13686
0
  cur = curWild->nsSet;
13687
0
  start = completeWild->nsSet;
13688
0
  while (cur != NULL) {
13689
0
      found = 0;
13690
0
      curB = start;
13691
0
      while (curB != NULL) {
13692
0
    if (cur->value == curB->value) {
13693
0
        found = 1;
13694
0
        break;
13695
0
    }
13696
0
    curB = curB->next;
13697
0
      }
13698
0
      if (!found) {
13699
0
    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13700
0
    if (tmp == NULL)
13701
0
        return (-1);
13702
0
    tmp->value = cur->value;
13703
0
    tmp->next = completeWild->nsSet;
13704
0
    completeWild->nsSet = tmp;
13705
0
      }
13706
0
      cur = cur->next;
13707
0
  }
13708
13709
0
  return(0);
13710
0
    }
13711
    /*
13712
    * 4 If the two are negations of different values (namespace names
13713
    * or `absent`), then a pair of not and `absent` must be the value.
13714
    */
13715
0
    if ((completeWild->negNsSet != NULL) &&
13716
0
  (curWild->negNsSet != NULL) &&
13717
0
  (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13718
0
  completeWild->negNsSet->value = NULL;
13719
13720
0
  return(0);
13721
0
    }
13722
    /*
13723
     * 5.
13724
     */
13725
0
    if (((completeWild->negNsSet != NULL) &&
13726
0
  (completeWild->negNsSet->value != NULL) &&
13727
0
  (curWild->nsSet != NULL)) ||
13728
0
  ((curWild->negNsSet != NULL) &&
13729
0
  (curWild->negNsSet->value != NULL) &&
13730
0
  (completeWild->nsSet != NULL))) {
13731
13732
0
  int nsFound, absentFound = 0;
13733
13734
0
  if (completeWild->nsSet != NULL) {
13735
0
      cur = completeWild->nsSet;
13736
0
      curB = curWild->negNsSet;
13737
0
  } else {
13738
0
      cur = curWild->nsSet;
13739
0
      curB = completeWild->negNsSet;
13740
0
  }
13741
0
  nsFound = 0;
13742
0
  while (cur != NULL) {
13743
0
      if (cur->value == NULL)
13744
0
    absentFound = 1;
13745
0
      else if (cur->value == curB->value)
13746
0
    nsFound = 1;
13747
0
      if (nsFound && absentFound)
13748
0
    break;
13749
0
      cur = cur->next;
13750
0
  }
13751
13752
0
  if (nsFound && absentFound) {
13753
      /*
13754
      * 5.1 If the set S includes both the negated namespace
13755
      * name and `absent`, then any must be the value.
13756
      */
13757
0
      completeWild->any = 1;
13758
0
      if (completeWild->nsSet != NULL) {
13759
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13760
0
    completeWild->nsSet = NULL;
13761
0
      }
13762
0
      if (completeWild->negNsSet != NULL) {
13763
0
    xmlFree(completeWild->negNsSet);
13764
0
    completeWild->negNsSet = NULL;
13765
0
      }
13766
0
  } else if (nsFound && (!absentFound)) {
13767
      /*
13768
      * 5.2 If the set S includes the negated namespace name
13769
      * but not `absent`, then a pair of not and `absent` must
13770
      * be the value.
13771
      */
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
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13778
0
    if (completeWild->negNsSet == NULL)
13779
0
        return (-1);
13780
0
      }
13781
0
      completeWild->negNsSet->value = NULL;
13782
0
  } else if ((!nsFound) && absentFound) {
13783
      /*
13784
      * 5.3 If the set S includes `absent` but not the negated
13785
      * namespace name, then the union is not expressible.
13786
      */
13787
0
      xmlSchemaPErr(ctxt, completeWild->node,
13788
0
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13789
0
    "The union of the wildcard is not expressible.\n",
13790
0
    NULL, NULL);
13791
0
      return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13792
0
  } else if ((!nsFound) && (!absentFound)) {
13793
      /*
13794
      * 5.4 If the set S does not include either the negated namespace
13795
      * name or `absent`, then whichever of O1 or O2 is a pair of not
13796
      * and a namespace name must be the value.
13797
      */
13798
0
      if (completeWild->negNsSet == NULL) {
13799
0
    if (completeWild->nsSet != NULL) {
13800
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13801
0
        completeWild->nsSet = NULL;
13802
0
    }
13803
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13804
0
    if (completeWild->negNsSet == NULL)
13805
0
        return (-1);
13806
0
    completeWild->negNsSet->value = curWild->negNsSet->value;
13807
0
      }
13808
0
  }
13809
0
  return (0);
13810
0
    }
13811
    /*
13812
     * 6.
13813
     */
13814
0
    if (((completeWild->negNsSet != NULL) &&
13815
0
  (completeWild->negNsSet->value == NULL) &&
13816
0
  (curWild->nsSet != NULL)) ||
13817
0
  ((curWild->negNsSet != NULL) &&
13818
0
  (curWild->negNsSet->value == NULL) &&
13819
0
  (completeWild->nsSet != NULL))) {
13820
13821
0
  if (completeWild->nsSet != NULL) {
13822
0
      cur = completeWild->nsSet;
13823
0
  } else {
13824
0
      cur = curWild->nsSet;
13825
0
  }
13826
0
  while (cur != NULL) {
13827
0
      if (cur->value == NULL) {
13828
    /*
13829
    * 6.1 If the set S includes `absent`, then any must be the
13830
    * value.
13831
    */
13832
0
    completeWild->any = 1;
13833
0
    if (completeWild->nsSet != NULL) {
13834
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13835
0
        completeWild->nsSet = NULL;
13836
0
    }
13837
0
    if (completeWild->negNsSet != NULL) {
13838
0
        xmlFree(completeWild->negNsSet);
13839
0
        completeWild->negNsSet = NULL;
13840
0
    }
13841
0
    return (0);
13842
0
      }
13843
0
      cur = cur->next;
13844
0
  }
13845
0
  if (completeWild->negNsSet == NULL) {
13846
      /*
13847
      * 6.2 If the set S does not include `absent`, then a pair of not
13848
      * and `absent` must be the value.
13849
      */
13850
0
      if (completeWild->nsSet != NULL) {
13851
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13852
0
    completeWild->nsSet = NULL;
13853
0
      }
13854
0
      completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13855
0
      if (completeWild->negNsSet == NULL)
13856
0
    return (-1);
13857
0
      completeWild->negNsSet->value = NULL;
13858
0
  }
13859
0
  return (0);
13860
0
    }
13861
0
    return (0);
13862
13863
0
}
13864
13865
/**
13866
 * xmlSchemaIntersectWildcards:
13867
 * @ctxt:  the schema parser context
13868
 * @completeWild:  the first wildcard
13869
 * @curWild: the second wildcard
13870
 *
13871
 * Intersects the namespace constraints of the given wildcards.
13872
 * @completeWild will hold the resulting intersection.
13873
 * Returns a positive error code on failure, -1 in case of an
13874
 * internal error, 0 otherwise.
13875
 */
13876
static int
13877
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13878
          xmlSchemaWildcardPtr completeWild,
13879
          xmlSchemaWildcardPtr curWild)
13880
0
{
13881
0
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13882
13883
    /*
13884
    * 1 If O1 and O2 are the same value, then that value must be the
13885
    * value.
13886
    */
13887
0
    if ((completeWild->any == curWild->any) &&
13888
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13889
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13890
13891
0
  if ((completeWild->negNsSet == NULL) ||
13892
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13893
13894
0
      if (completeWild->nsSet != NULL) {
13895
0
    int found = 0;
13896
13897
    /*
13898
    * Check equality of sets.
13899
    */
13900
0
    cur = completeWild->nsSet;
13901
0
    while (cur != NULL) {
13902
0
        found = 0;
13903
0
        curB = curWild->nsSet;
13904
0
        while (curB != NULL) {
13905
0
      if (cur->value == curB->value) {
13906
0
          found = 1;
13907
0
          break;
13908
0
      }
13909
0
      curB = curB->next;
13910
0
        }
13911
0
        if (!found)
13912
0
      break;
13913
0
        cur = cur->next;
13914
0
    }
13915
0
    if (found)
13916
0
        return(0);
13917
0
      } else
13918
0
    return(0);
13919
0
  }
13920
0
    }
13921
    /*
13922
    * 2 If either O1 or O2 is any, then the other must be the value.
13923
    */
13924
0
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
13925
0
  if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13926
0
      return(-1);
13927
0
  return(0);
13928
0
    }
13929
    /*
13930
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
13931
    * name or `absent`) and the other is a set of (namespace names or
13932
    * `absent`), then that set, minus the negated value if it was in
13933
    * the set, minus `absent` if it was in the set, must be the value.
13934
    */
13935
0
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13936
0
  ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13937
0
  const xmlChar *neg;
13938
13939
0
  if (completeWild->nsSet == NULL) {
13940
0
      neg = completeWild->negNsSet->value;
13941
0
      if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13942
0
    return(-1);
13943
0
  } else
13944
0
      neg = curWild->negNsSet->value;
13945
  /*
13946
  * Remove absent and negated.
13947
  */
13948
0
  prev = NULL;
13949
0
  cur = completeWild->nsSet;
13950
0
  while (cur != NULL) {
13951
0
      if (cur->value == NULL) {
13952
0
    if (prev == NULL)
13953
0
        completeWild->nsSet = cur->next;
13954
0
    else
13955
0
        prev->next = cur->next;
13956
0
    xmlFree(cur);
13957
0
    break;
13958
0
      }
13959
0
      prev = cur;
13960
0
      cur = cur->next;
13961
0
  }
13962
0
  if (neg != NULL) {
13963
0
      prev = NULL;
13964
0
      cur = completeWild->nsSet;
13965
0
      while (cur != NULL) {
13966
0
    if (cur->value == neg) {
13967
0
        if (prev == NULL)
13968
0
      completeWild->nsSet = cur->next;
13969
0
        else
13970
0
      prev->next = cur->next;
13971
0
        xmlFree(cur);
13972
0
        break;
13973
0
    }
13974
0
    prev = cur;
13975
0
    cur = cur->next;
13976
0
      }
13977
0
  }
13978
13979
0
  return(0);
13980
0
    }
13981
    /*
13982
    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13983
    * then the intersection of those sets must be the value.
13984
    */
13985
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13986
0
  int found;
13987
13988
0
  cur = completeWild->nsSet;
13989
0
  prev = NULL;
13990
0
  while (cur != NULL) {
13991
0
      found = 0;
13992
0
      curB = curWild->nsSet;
13993
0
      while (curB != NULL) {
13994
0
    if (cur->value == curB->value) {
13995
0
        found = 1;
13996
0
        break;
13997
0
    }
13998
0
    curB = curB->next;
13999
0
      }
14000
0
      if (!found) {
14001
0
    if (prev == NULL)
14002
0
        completeWild->nsSet = cur->next;
14003
0
    else
14004
0
        prev->next = cur->next;
14005
0
    tmp = cur->next;
14006
0
    xmlFree(cur);
14007
0
    cur = tmp;
14008
0
    continue;
14009
0
      }
14010
0
      prev = cur;
14011
0
      cur = cur->next;
14012
0
  }
14013
14014
0
  return(0);
14015
0
    }
14016
    /* 5 If the two are negations of different namespace names,
14017
    * then the intersection is not expressible
14018
    */
14019
0
    if ((completeWild->negNsSet != NULL) &&
14020
0
  (curWild->negNsSet != NULL) &&
14021
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
14022
0
  (completeWild->negNsSet->value != NULL) &&
14023
0
  (curWild->negNsSet->value != NULL)) {
14024
14025
0
  xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
14026
0
      "The intersection of the wildcard is not expressible.\n",
14027
0
      NULL, NULL);
14028
0
  return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
14029
0
    }
14030
    /*
14031
    * 6 If the one is a negation of a namespace name and the other
14032
    * is a negation of `absent`, then the one which is the negation
14033
    * of a namespace name must be the value.
14034
    */
14035
0
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
14036
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
14037
0
  (completeWild->negNsSet->value == NULL)) {
14038
0
  completeWild->negNsSet->value =  curWild->negNsSet->value;
14039
0
    }
14040
0
    return(0);
14041
0
}
14042
14043
/**
14044
 * xmlSchemaIsWildcardNsConstraintSubset:
14045
 * @ctxt:  the schema parser context
14046
 * @sub:  the first wildcard
14047
 * @super: the second wildcard
14048
 *
14049
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
14050
 *
14051
 * Returns 0 if the namespace constraint of @sub is an intensional
14052
 * subset of @super, 1 otherwise.
14053
 */
14054
static int
14055
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
14056
        xmlSchemaWildcardPtr super)
14057
0
{
14058
    /*
14059
    * 1 super must be any.
14060
    */
14061
0
    if (super->any)
14062
0
  return (0);
14063
    /*
14064
    * 2.1 sub must be a pair of not and a namespace name or `absent`.
14065
    * 2.2 super must be a pair of not and the same value.
14066
    */
14067
0
    if ((sub->negNsSet != NULL) &&
14068
0
  (super->negNsSet != NULL) &&
14069
0
  (sub->negNsSet->value == super->negNsSet->value))
14070
0
  return (0);
14071
    /*
14072
    * 3.1 sub must be a set whose members are either namespace names or `absent`.
14073
    */
14074
0
    if (sub->nsSet != NULL) {
14075
  /*
14076
  * 3.2.1 super must be the same set or a superset thereof.
14077
  */
14078
0
  if (super->nsSet != NULL) {
14079
0
      xmlSchemaWildcardNsPtr cur, curB;
14080
0
      int found = 0;
14081
14082
0
      cur = sub->nsSet;
14083
0
      while (cur != NULL) {
14084
0
    found = 0;
14085
0
    curB = super->nsSet;
14086
0
    while (curB != NULL) {
14087
0
        if (cur->value == curB->value) {
14088
0
      found = 1;
14089
0
      break;
14090
0
        }
14091
0
        curB = curB->next;
14092
0
    }
14093
0
    if (!found)
14094
0
        return (1);
14095
0
    cur = cur->next;
14096
0
      }
14097
0
      if (found)
14098
0
    return (0);
14099
0
  } else if (super->negNsSet != NULL) {
14100
0
      xmlSchemaWildcardNsPtr cur;
14101
      /*
14102
      * 3.2.2 super must be a pair of not and a namespace name or
14103
      * `absent` and that value must not be in sub's set.
14104
      */
14105
0
      cur = sub->nsSet;
14106
0
      while (cur != NULL) {
14107
0
    if (cur->value == super->negNsSet->value)
14108
0
        return (1);
14109
0
    cur = cur->next;
14110
0
      }
14111
0
      return (0);
14112
0
  }
14113
0
    }
14114
0
    return (1);
14115
0
}
14116
14117
static int
14118
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
14119
             int *fixed,
14120
             const xmlChar **value,
14121
             xmlSchemaValPtr *val)
14122
0
{
14123
0
    *fixed = 0;
14124
0
    *value = NULL;
14125
0
    if (val != 0)
14126
0
  *val = NULL;
14127
14128
0
    if (attruse->defValue != NULL) {
14129
0
  *value = attruse->defValue;
14130
0
  if (val != NULL)
14131
0
      *val = attruse->defVal;
14132
0
  if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14133
0
      *fixed = 1;
14134
0
  return(1);
14135
0
    } else if ((attruse->attrDecl != NULL) &&
14136
0
  (attruse->attrDecl->defValue != NULL)) {
14137
0
  *value = attruse->attrDecl->defValue;
14138
0
  if (val != NULL)
14139
0
      *val = attruse->attrDecl->defVal;
14140
0
  if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14141
0
      *fixed = 1;
14142
0
  return(1);
14143
0
    }
14144
0
    return(0);
14145
0
}
14146
/**
14147
 * xmlSchemaCheckCVCWildcardNamespace:
14148
 * @wild:  the wildcard
14149
 * @ns:  the namespace
14150
 *
14151
 * Validation Rule: Wildcard allows Namespace Name
14152
 * (cvc-wildcard-namespace)
14153
 *
14154
 * Returns 0 if the given namespace matches the wildcard,
14155
 * 1 otherwise and -1 on API errors.
14156
 */
14157
static int
14158
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14159
           const xmlChar* ns)
14160
0
{
14161
0
    if (wild == NULL)
14162
0
  return(-1);
14163
14164
0
    if (wild->any)
14165
0
  return(0);
14166
0
    else if (wild->nsSet != NULL) {
14167
0
  xmlSchemaWildcardNsPtr cur;
14168
14169
0
  cur = wild->nsSet;
14170
0
  while (cur != NULL) {
14171
0
      if (xmlStrEqual(cur->value, ns))
14172
0
    return(0);
14173
0
      cur = cur->next;
14174
0
  }
14175
0
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14176
0
  (!xmlStrEqual(wild->negNsSet->value, ns)))
14177
0
  return(0);
14178
14179
0
    return(1);
14180
0
}
14181
14182
0
#define XML_SCHEMA_ACTION_DERIVE 0
14183
0
#define XML_SCHEMA_ACTION_REDEFINE 1
14184
14185
0
#define WXS_ACTION_STR(a) \
14186
0
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14187
14188
/*
14189
* Schema Component Constraint:
14190
*   Derivation Valid (Restriction, Complex)
14191
*   derivation-ok-restriction (2) - (4)
14192
*
14193
* ATTENTION:
14194
* In XML Schema 1.1 this will be:
14195
* Validation Rule:
14196
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14197
*
14198
*/
14199
static int
14200
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14201
               int action,
14202
               xmlSchemaBasicItemPtr item,
14203
               xmlSchemaBasicItemPtr baseItem,
14204
               xmlSchemaItemListPtr uses,
14205
               xmlSchemaItemListPtr baseUses,
14206
               xmlSchemaWildcardPtr wild,
14207
               xmlSchemaWildcardPtr baseWild)
14208
0
{
14209
0
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
14210
0
    int i, j, found; /* err = 0; */
14211
0
    const xmlChar *bEffValue;
14212
0
    int effFixed;
14213
14214
0
    if (uses != NULL) {
14215
0
  for (i = 0; i < uses->nbItems; i++) {
14216
0
      cur = uses->items[i];
14217
0
      found = 0;
14218
0
      if (baseUses == NULL)
14219
0
    goto not_found;
14220
0
      for (j = 0; j < baseUses->nbItems; j++) {
14221
0
    bcur = baseUses->items[j];
14222
0
    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14223
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14224
0
        (WXS_ATTRUSE_DECL_TNS(cur) ==
14225
0
      WXS_ATTRUSE_DECL_TNS(bcur)))
14226
0
    {
14227
        /*
14228
        * (2.1) "If there is an attribute use in the {attribute
14229
        * uses} of the {base type definition} (call this B) whose
14230
        * {attribute declaration} has the same {name} and {target
14231
        * namespace}, then  all of the following must be true:"
14232
        */
14233
0
        found = 1;
14234
14235
0
        if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14236
0
      (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14237
0
        {
14238
0
      xmlChar *str = NULL;
14239
      /*
14240
      * (2.1.1) "one of the following must be true:"
14241
      * (2.1.1.1) "B's {required} is false."
14242
      * (2.1.1.2) "R's {required} is true."
14243
      */
14244
0
      xmlSchemaPAttrUseErr4(pctxt,
14245
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14246
0
          WXS_ITEM_NODE(item), item, cur,
14247
0
          "The 'optional' attribute use is inconsistent "
14248
0
          "with the corresponding 'required' attribute use of "
14249
0
          "the %s %s",
14250
0
          WXS_ACTION_STR(action),
14251
0
          xmlSchemaGetComponentDesignation(&str, baseItem),
14252
0
          NULL, NULL);
14253
0
      FREE_AND_NULL(str);
14254
      /* err = pctxt->err; */
14255
0
        } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14256
0
      WXS_ATTRUSE_TYPEDEF(cur),
14257
0
      WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14258
0
        {
14259
0
      xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14260
14261
      /*
14262
      * SPEC (2.1.2) "R's {attribute declaration}'s
14263
      * {type definition} must be validly derived from
14264
      * B's {type definition} given the empty set as
14265
      * defined in Type Derivation OK (Simple) ($3.14.6)."
14266
      */
14267
0
      xmlSchemaPAttrUseErr4(pctxt,
14268
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14269
0
          WXS_ITEM_NODE(item), item, cur,
14270
0
          "The attribute declaration's %s "
14271
0
          "is not validly derived from "
14272
0
          "the corresponding %s of the "
14273
0
          "attribute declaration in the %s %s",
14274
0
          xmlSchemaGetComponentDesignation(&strA,
14275
0
        WXS_ATTRUSE_TYPEDEF(cur)),
14276
0
          xmlSchemaGetComponentDesignation(&strB,
14277
0
        WXS_ATTRUSE_TYPEDEF(bcur)),
14278
0
          WXS_ACTION_STR(action),
14279
0
          xmlSchemaGetComponentDesignation(&strC, baseItem));
14280
          /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14281
0
      FREE_AND_NULL(strA);
14282
0
      FREE_AND_NULL(strB);
14283
0
      FREE_AND_NULL(strC);
14284
      /* err = pctxt->err; */
14285
0
        } else {
14286
      /*
14287
      * 2.1.3 [Definition:]  Let the effective value
14288
      * constraint of an attribute use be its {value
14289
      * constraint}, if present, otherwise its {attribute
14290
      * declaration}'s {value constraint} .
14291
      */
14292
0
      xmlSchemaGetEffectiveValueConstraint(bcur,
14293
0
          &effFixed, &bEffValue, NULL);
14294
      /*
14295
      * 2.1.3 ... one of the following must be true
14296
      *
14297
      * 2.1.3.1 B's `effective value constraint` is
14298
      * `absent` or default.
14299
      */
14300
0
      if ((bEffValue != NULL) &&
14301
0
          (effFixed == 1)) {
14302
0
          const xmlChar *rEffValue = NULL;
14303
14304
0
          xmlSchemaGetEffectiveValueConstraint(bcur,
14305
0
        &effFixed, &rEffValue, NULL);
14306
          /*
14307
          * 2.1.3.2 R's `effective value constraint` is
14308
          * fixed with the same string as B's.
14309
          * MAYBE TODO: Compare the computed values.
14310
          *       Hmm, it says "same string" so
14311
          *       string-equality might really be sufficient.
14312
          */
14313
0
          if ((effFixed == 0) ||
14314
0
        (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14315
0
          {
14316
0
        xmlChar *str = NULL;
14317
14318
0
        xmlSchemaPAttrUseErr4(pctxt,
14319
0
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14320
0
            WXS_ITEM_NODE(item), item, cur,
14321
0
            "The effective value constraint of the "
14322
0
            "attribute use is inconsistent with "
14323
0
            "its correspondent in the %s %s",
14324
0
            WXS_ACTION_STR(action),
14325
0
            xmlSchemaGetComponentDesignation(&str,
14326
0
          baseItem),
14327
0
            NULL, NULL);
14328
0
        FREE_AND_NULL(str);
14329
        /* err = pctxt->err; */
14330
0
          }
14331
0
      }
14332
0
        }
14333
0
        break;
14334
0
    }
14335
0
      }
14336
0
not_found:
14337
0
      if (!found) {
14338
    /*
14339
    * (2.2) "otherwise the {base type definition} must have an
14340
    * {attribute wildcard} and the {target namespace} of the
14341
    * R's {attribute declaration} must be `valid` with respect
14342
    * to that wildcard, as defined in Wildcard allows Namespace
14343
    * Name ($3.10.4)."
14344
    */
14345
0
    if ((baseWild == NULL) ||
14346
0
        (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14347
0
        (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14348
0
    {
14349
0
        xmlChar *str = NULL;
14350
14351
0
        xmlSchemaPAttrUseErr4(pctxt,
14352
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14353
0
      WXS_ITEM_NODE(item), item, cur,
14354
0
      "Neither a matching attribute use, "
14355
0
      "nor a matching wildcard exists in the %s %s",
14356
0
      WXS_ACTION_STR(action),
14357
0
      xmlSchemaGetComponentDesignation(&str, baseItem),
14358
0
      NULL, NULL);
14359
0
        FREE_AND_NULL(str);
14360
        /* err = pctxt->err; */
14361
0
    }
14362
0
      }
14363
0
  }
14364
0
    }
14365
    /*
14366
    * SPEC derivation-ok-restriction (3):
14367
    * (3) "For each attribute use in the {attribute uses} of the {base type
14368
    * definition} whose {required} is true, there must be an attribute
14369
    * use with an {attribute declaration} with the same {name} and
14370
    * {target namespace} as its {attribute declaration} in the {attribute
14371
    * uses} of the complex type definition itself whose {required} is true.
14372
    */
14373
0
    if (baseUses != NULL) {
14374
0
  for (j = 0; j < baseUses->nbItems; j++) {
14375
0
      bcur = baseUses->items[j];
14376
0
      if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14377
0
    continue;
14378
0
      found = 0;
14379
0
      if (uses != NULL) {
14380
0
    for (i = 0; i < uses->nbItems; i++) {
14381
0
        cur = uses->items[i];
14382
0
        if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14383
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14384
0
      (WXS_ATTRUSE_DECL_TNS(cur) ==
14385
0
      WXS_ATTRUSE_DECL_TNS(bcur))) {
14386
0
      found = 1;
14387
0
      break;
14388
0
        }
14389
0
    }
14390
0
      }
14391
0
      if (!found) {
14392
0
    xmlChar *strA = NULL, *strB = NULL;
14393
14394
0
    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14395
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14396
0
        NULL, item,
14397
0
        "A matching attribute use for the "
14398
0
        "'required' %s of the %s %s is missing",
14399
0
        xmlSchemaGetComponentDesignation(&strA, bcur),
14400
0
        WXS_ACTION_STR(action),
14401
0
        xmlSchemaGetComponentDesignation(&strB, baseItem),
14402
0
        NULL);
14403
0
    FREE_AND_NULL(strA);
14404
0
    FREE_AND_NULL(strB);
14405
0
      }
14406
0
  }
14407
0
    }
14408
    /*
14409
    * derivation-ok-restriction (4)
14410
    */
14411
0
    if (wild != NULL) {
14412
  /*
14413
  * (4) "If there is an {attribute wildcard}, all of the
14414
  * following must be true:"
14415
  */
14416
0
  if (baseWild == NULL) {
14417
0
      xmlChar *str = NULL;
14418
14419
      /*
14420
      * (4.1) "The {base type definition} must also have one."
14421
      */
14422
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14423
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14424
0
    NULL, item,
14425
0
    "The %s has an attribute wildcard, "
14426
0
    "but the %s %s '%s' does not have one",
14427
0
    WXS_ITEM_TYPE_NAME(item),
14428
0
    WXS_ACTION_STR(action),
14429
0
    WXS_ITEM_TYPE_NAME(baseItem),
14430
0
    xmlSchemaGetComponentQName(&str, baseItem));
14431
0
      FREE_AND_NULL(str);
14432
0
      return(pctxt->err);
14433
0
  } else if ((baseWild->any == 0) &&
14434
0
    xmlSchemaCheckCOSNSSubset(wild, baseWild))
14435
0
  {
14436
0
      xmlChar *str = NULL;
14437
      /*
14438
      * (4.2) "The complex type definition's {attribute wildcard}'s
14439
      * {namespace constraint} must be a subset of the {base type
14440
      * definition}'s {attribute wildcard}'s {namespace constraint},
14441
      * as defined by Wildcard Subset ($3.10.6)."
14442
      */
14443
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14444
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14445
0
    NULL, item,
14446
0
    "The attribute wildcard is not a valid "
14447
0
    "subset of the wildcard in the %s %s '%s'",
14448
0
    WXS_ACTION_STR(action),
14449
0
    WXS_ITEM_TYPE_NAME(baseItem),
14450
0
    xmlSchemaGetComponentQName(&str, baseItem),
14451
0
    NULL);
14452
0
      FREE_AND_NULL(str);
14453
0
      return(pctxt->err);
14454
0
  }
14455
  /* 4.3 Unless the {base type definition} is the `ur-type
14456
  * definition`, the complex type definition's {attribute
14457
  * wildcard}'s {process contents} must be identical to or
14458
  * stronger than the {base type definition}'s {attribute
14459
  * wildcard}'s {process contents}, where strict is stronger
14460
  * than lax is stronger than skip.
14461
  */
14462
0
  if ((! WXS_IS_ANYTYPE(baseItem)) &&
14463
0
      (wild->processContents < baseWild->processContents)) {
14464
0
      xmlChar *str = NULL;
14465
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14466
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14467
0
    NULL, baseItem,
14468
0
    "The {process contents} of the attribute wildcard is "
14469
0
    "weaker than the one in the %s %s '%s'",
14470
0
    WXS_ACTION_STR(action),
14471
0
    WXS_ITEM_TYPE_NAME(baseItem),
14472
0
    xmlSchemaGetComponentQName(&str, baseItem),
14473
0
    NULL);
14474
0
      FREE_AND_NULL(str)
14475
0
    return(pctxt->err);
14476
0
  }
14477
0
    }
14478
0
    return(0);
14479
0
}
14480
14481
14482
static int
14483
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14484
          xmlSchemaBasicItemPtr item,
14485
          xmlSchemaWildcardPtr *completeWild,
14486
          xmlSchemaItemListPtr list,
14487
          xmlSchemaItemListPtr prohibs);
14488
/**
14489
 * xmlSchemaFixupTypeAttributeUses:
14490
 * @ctxt:  the schema parser context
14491
 * @type:  the complex type definition
14492
 *
14493
 *
14494
 * Builds the wildcard and the attribute uses on the given complex type.
14495
 * Returns -1 if an internal error occurs, 0 otherwise.
14496
 *
14497
 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14498
 * strings, so recheck this if we start to hardcode some schemata, since
14499
 * they might not be in the same dict.
14500
 * NOTE: It is allowed to "extend" the xs:anyType type.
14501
 */
14502
static int
14503
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14504
          xmlSchemaTypePtr type)
14505
0
{
14506
0
    xmlSchemaTypePtr baseType = NULL;
14507
0
    xmlSchemaAttributeUsePtr use;
14508
0
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14509
14510
0
    if (type->baseType == NULL) {
14511
0
  PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14512
0
      "no base type");
14513
0
        return (-1);
14514
0
    }
14515
0
    baseType = type->baseType;
14516
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14517
0
  if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14518
0
      return(-1);
14519
14520
0
    uses = type->attrUses;
14521
0
    baseUses = baseType->attrUses;
14522
    /*
14523
    * Expand attribute group references. And build the 'complete'
14524
    * wildcard, i.e. intersect multiple wildcards.
14525
    * Move attribute prohibitions into a separate list.
14526
    */
14527
0
    if (uses != NULL) {
14528
0
  if (WXS_IS_RESTRICTION(type)) {
14529
      /*
14530
      * This one will transfer all attr. prohibitions
14531
      * into pctxt->attrProhibs.
14532
      */
14533
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14534
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14535
0
    pctxt->attrProhibs) == -1)
14536
0
      {
14537
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14538
0
    "failed to expand attributes");
14539
0
      }
14540
0
      if (pctxt->attrProhibs->nbItems != 0)
14541
0
    prohibs = pctxt->attrProhibs;
14542
0
  } else {
14543
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14544
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14545
0
    NULL) == -1)
14546
0
      {
14547
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14548
0
    "failed to expand attributes");
14549
0
      }
14550
0
  }
14551
0
    }
14552
    /*
14553
    * Inherit the attribute uses of the base type.
14554
    */
14555
0
    if (baseUses != NULL) {
14556
0
  int i, j;
14557
0
  xmlSchemaAttributeUseProhibPtr pro;
14558
14559
0
  if (WXS_IS_RESTRICTION(type)) {
14560
0
      int usesCount;
14561
0
      xmlSchemaAttributeUsePtr tmp;
14562
14563
0
      if (uses != NULL)
14564
0
    usesCount = uses->nbItems;
14565
0
      else
14566
0
    usesCount = 0;
14567
14568
      /* Restriction. */
14569
0
      for (i = 0; i < baseUses->nbItems; i++) {
14570
0
    use = baseUses->items[i];
14571
0
    if (prohibs) {
14572
        /*
14573
        * Filter out prohibited uses.
14574
        */
14575
0
        for (j = 0; j < prohibs->nbItems; j++) {
14576
0
      pro = prohibs->items[j];
14577
0
      if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14578
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14579
0
        pro->targetNamespace))
14580
0
      {
14581
0
          goto inherit_next;
14582
0
      }
14583
0
        }
14584
0
    }
14585
0
    if (usesCount) {
14586
        /*
14587
        * Filter out existing uses.
14588
        */
14589
0
        for (j = 0; j < usesCount; j++) {
14590
0
      tmp = uses->items[j];
14591
0
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
14592
0
        WXS_ATTRUSE_DECL_NAME(tmp)) &&
14593
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14594
0
        WXS_ATTRUSE_DECL_TNS(tmp)))
14595
0
      {
14596
0
          goto inherit_next;
14597
0
      }
14598
0
        }
14599
0
    }
14600
0
    if (uses == NULL) {
14601
0
        type->attrUses = xmlSchemaItemListCreate();
14602
0
        if (type->attrUses == NULL)
14603
0
      goto exit_failure;
14604
0
        uses = type->attrUses;
14605
0
    }
14606
0
    xmlSchemaItemListAddSize(uses, 2, use);
14607
0
inherit_next: {}
14608
0
      }
14609
0
  } else {
14610
      /* Extension. */
14611
0
      for (i = 0; i < baseUses->nbItems; i++) {
14612
0
    use = baseUses->items[i];
14613
0
    if (uses == NULL) {
14614
0
        type->attrUses = xmlSchemaItemListCreate();
14615
0
        if (type->attrUses == NULL)
14616
0
      goto exit_failure;
14617
0
        uses = type->attrUses;
14618
0
    }
14619
0
    xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14620
0
      }
14621
0
  }
14622
0
    }
14623
    /*
14624
    * Shrink attr. uses.
14625
    */
14626
0
    if (uses) {
14627
0
  if (uses->nbItems == 0) {
14628
0
      xmlSchemaItemListFree(uses);
14629
0
      type->attrUses = NULL;
14630
0
  }
14631
  /*
14632
  * TODO: We could shrink the size of the array
14633
  * to fit the actual number of items.
14634
  */
14635
0
    }
14636
    /*
14637
    * Compute the complete wildcard.
14638
    */
14639
0
    if (WXS_IS_EXTENSION(type)) {
14640
0
  if (baseType->attributeWildcard != NULL) {
14641
      /*
14642
      * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14643
      * the appropriate case among the following:"
14644
      */
14645
0
      if (type->attributeWildcard != NULL) {
14646
    /*
14647
    * Union the complete wildcard with the base wildcard.
14648
    * SPEC {attribute wildcard}
14649
    * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14650
    * and {annotation} are those of the `complete wildcard`,
14651
    * and whose {namespace constraint} is the intensional union
14652
    * of the {namespace constraint} of the `complete wildcard`
14653
    * and of the `base wildcard`, as defined in Attribute
14654
    * Wildcard Union ($3.10.6)."
14655
    */
14656
0
    if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14657
0
        baseType->attributeWildcard) == -1)
14658
0
        goto exit_failure;
14659
0
      } else {
14660
    /*
14661
    * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14662
    * then the `base wildcard`."
14663
    */
14664
0
    type->attributeWildcard = baseType->attributeWildcard;
14665
0
      }
14666
0
  } else {
14667
      /*
14668
      * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14669
      * `complete wildcard`"
14670
      * NOOP
14671
      */
14672
0
  }
14673
0
    } else {
14674
  /*
14675
  * SPEC {attribute wildcard}
14676
  * (3.1) "If the <restriction> alternative is chosen, then the
14677
  * `complete wildcard`;"
14678
  * NOOP
14679
  */
14680
0
    }
14681
14682
0
    return (0);
14683
14684
0
exit_failure:
14685
0
    return(-1);
14686
0
}
14687
14688
/**
14689
 * xmlSchemaTypeFinalContains:
14690
 * @schema:  the schema
14691
 * @type:  the type definition
14692
 * @final: the final
14693
 *
14694
 * Evaluates if a type definition contains the given "final".
14695
 * This does take "finalDefault" into account as well.
14696
 *
14697
 * Returns 1 if the type does contain the given "final",
14698
 * 0 otherwise.
14699
 */
14700
static int
14701
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14702
0
{
14703
0
    if (type == NULL)
14704
0
  return (0);
14705
0
    if (type->flags & final)
14706
0
  return (1);
14707
0
    else
14708
0
  return (0);
14709
0
}
14710
14711
/**
14712
 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14713
 * @type:  the Union Simple Type
14714
 *
14715
 * Returns a list of member types of @type if existing,
14716
 * returns NULL otherwise.
14717
 */
14718
static xmlSchemaTypeLinkPtr
14719
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14720
0
{
14721
0
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14722
0
  if (type->memberTypes != NULL)
14723
0
      return (type->memberTypes);
14724
0
  else
14725
0
      type = type->baseType;
14726
0
    }
14727
0
    return (NULL);
14728
0
}
14729
14730
#if 0
14731
/**
14732
 * xmlSchemaGetParticleTotalRangeMin:
14733
 * @particle: the particle
14734
 *
14735
 * Schema Component Constraint: Effective Total Range
14736
 * (all and sequence) + (choice)
14737
 *
14738
 * Returns the minimum Effective Total Range.
14739
 */
14740
static int
14741
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14742
{
14743
    if ((particle->children == NULL) ||
14744
  (particle->minOccurs == 0))
14745
  return (0);
14746
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14747
  int min = -1, cur;
14748
  xmlSchemaParticlePtr part =
14749
      (xmlSchemaParticlePtr) particle->children->children;
14750
14751
  if (part == NULL)
14752
      return (0);
14753
  while (part != NULL) {
14754
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14755
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14756
    cur = part->minOccurs;
14757
      else
14758
    cur = xmlSchemaGetParticleTotalRangeMin(part);
14759
      if (cur == 0)
14760
    return (0);
14761
      if ((min > cur) || (min == -1))
14762
    min = cur;
14763
      part = (xmlSchemaParticlePtr) part->next;
14764
  }
14765
  return (particle->minOccurs * min);
14766
    } else {
14767
  /* <all> and <sequence> */
14768
  int sum = 0;
14769
  xmlSchemaParticlePtr part =
14770
      (xmlSchemaParticlePtr) particle->children->children;
14771
14772
  if (part == NULL)
14773
      return (0);
14774
  do {
14775
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14776
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14777
    sum += part->minOccurs;
14778
      else
14779
    sum += xmlSchemaGetParticleTotalRangeMin(part);
14780
      part = (xmlSchemaParticlePtr) part->next;
14781
  } while (part != NULL);
14782
  return (particle->minOccurs * sum);
14783
    }
14784
}
14785
14786
/**
14787
 * xmlSchemaGetParticleTotalRangeMax:
14788
 * @particle: the particle
14789
 *
14790
 * Schema Component Constraint: Effective Total Range
14791
 * (all and sequence) + (choice)
14792
 *
14793
 * Returns the maximum Effective Total Range.
14794
 */
14795
static int
14796
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14797
{
14798
    if ((particle->children == NULL) ||
14799
  (particle->children->children == NULL))
14800
  return (0);
14801
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14802
  int max = -1, cur;
14803
  xmlSchemaParticlePtr part =
14804
      (xmlSchemaParticlePtr) particle->children->children;
14805
14806
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14807
      if (part->children == NULL)
14808
    continue;
14809
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14810
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14811
    cur = part->maxOccurs;
14812
      else
14813
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14814
      if (cur == UNBOUNDED)
14815
    return (UNBOUNDED);
14816
      if ((max < cur) || (max == -1))
14817
    max = cur;
14818
  }
14819
  /* TODO: Handle overflows? */
14820
  return (particle->maxOccurs * max);
14821
    } else {
14822
  /* <all> and <sequence> */
14823
  int sum = 0, cur;
14824
  xmlSchemaParticlePtr part =
14825
      (xmlSchemaParticlePtr) particle->children->children;
14826
14827
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14828
      if (part->children == NULL)
14829
    continue;
14830
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14831
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14832
    cur = part->maxOccurs;
14833
      else
14834
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14835
      if (cur == UNBOUNDED)
14836
    return (UNBOUNDED);
14837
      if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14838
    return (UNBOUNDED);
14839
      sum += cur;
14840
  }
14841
  /* TODO: Handle overflows? */
14842
  return (particle->maxOccurs * sum);
14843
    }
14844
}
14845
#endif
14846
14847
/**
14848
 * xmlSchemaGetParticleEmptiable:
14849
 * @particle: the particle
14850
 *
14851
 * Returns 1 if emptiable, 0 otherwise.
14852
 */
14853
static int
14854
xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14855
0
{
14856
0
    xmlSchemaParticlePtr part;
14857
0
    int emptiable;
14858
14859
0
    if ((particle->children == NULL) || (particle->minOccurs == 0))
14860
0
  return (1);
14861
14862
0
    part = (xmlSchemaParticlePtr) particle->children->children;
14863
0
    if (part == NULL)
14864
0
        return (1);
14865
14866
0
    while (part != NULL) {
14867
0
        if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14868
0
            (part->children->type == XML_SCHEMA_TYPE_ANY))
14869
0
            emptiable = (part->minOccurs == 0);
14870
0
        else
14871
0
            emptiable = xmlSchemaGetParticleEmptiable(part);
14872
0
        if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14873
0
            if (emptiable)
14874
0
                return (1);
14875
0
        } else {
14876
      /* <all> and <sequence> */
14877
0
            if (!emptiable)
14878
0
                return (0);
14879
0
        }
14880
0
        part = (xmlSchemaParticlePtr) part->next;
14881
0
    }
14882
14883
0
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14884
0
        return (0);
14885
0
    else
14886
0
        return (1);
14887
0
}
14888
14889
/**
14890
 * xmlSchemaIsParticleEmptiable:
14891
 * @particle: the particle
14892
 *
14893
 * Schema Component Constraint: Particle Emptiable
14894
 * Checks whether the given particle is emptiable.
14895
 *
14896
 * Returns 1 if emptiable, 0 otherwise.
14897
 */
14898
static int
14899
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14900
0
{
14901
    /*
14902
    * SPEC (1) "Its {min occurs} is 0."
14903
    */
14904
0
    if ((particle == NULL) || (particle->minOccurs == 0) ||
14905
0
  (particle->children == NULL))
14906
0
  return (1);
14907
    /*
14908
    * SPEC (2) "Its {term} is a group and the minimum part of the
14909
    * effective total range of that group, [...] is 0."
14910
    */
14911
0
    if (WXS_IS_MODEL_GROUP(particle->children))
14912
0
  return (xmlSchemaGetParticleEmptiable(particle));
14913
0
    return (0);
14914
0
}
14915
14916
/**
14917
 * xmlSchemaCheckCOSSTDerivedOK:
14918
 * @actxt: a context
14919
 * @type:  the derived simple type definition
14920
 * @baseType:  the base type definition
14921
 * @subset: the subset of ('restriction', etc.)
14922
 *
14923
 * Schema Component Constraint:
14924
 * Type Derivation OK (Simple) (cos-st-derived-OK)
14925
 *
14926
 * Checks whether @type can be validly
14927
 * derived from @baseType.
14928
 *
14929
 * Returns 0 on success, an positive error code otherwise.
14930
 */
14931
static int
14932
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14933
           xmlSchemaTypePtr type,
14934
           xmlSchemaTypePtr baseType,
14935
           int subset)
14936
0
{
14937
    /*
14938
    * 1 They are the same type definition.
14939
    * TODO: The identity check might have to be more complex than this.
14940
    */
14941
0
    if (type == baseType)
14942
0
  return (0);
14943
    /*
14944
    * 2.1 restriction is not in the subset, or in the {final}
14945
    * of its own {base type definition};
14946
    *
14947
    * NOTE that this will be used also via "xsi:type".
14948
    *
14949
    * TODO: Revise this, it looks strange. How can the "type"
14950
    * not be fixed or *in* fixing?
14951
    */
14952
0
    if (WXS_IS_TYPE_NOT_FIXED(type))
14953
0
  if (xmlSchemaTypeFixup(type, actxt) == -1)
14954
0
      return(-1);
14955
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14956
0
  if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14957
0
      return(-1);
14958
0
    if ((subset & SUBSET_RESTRICTION) ||
14959
0
  (xmlSchemaTypeFinalContains(type->baseType,
14960
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14961
0
  return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14962
0
    }
14963
    /* 2.2 */
14964
0
    if (type->baseType == baseType) {
14965
  /*
14966
  * 2.2.1 D's `base type definition` is B.
14967
  */
14968
0
  return (0);
14969
0
    }
14970
    /*
14971
    * 2.2.2 D's `base type definition` is not the `ur-type definition`
14972
    * and is validly derived from B given the subset, as defined by this
14973
    * constraint.
14974
    */
14975
0
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14976
0
  (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14977
0
      baseType, subset) == 0)) {
14978
0
  return (0);
14979
0
    }
14980
    /*
14981
    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14982
    * definition`.
14983
    */
14984
0
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14985
0
  (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14986
0
  return (0);
14987
0
    }
14988
    /*
14989
    * 2.2.4 B's {variety} is union and D is validly derived from a type
14990
    * definition in B's {member type definitions} given the subset, as
14991
    * defined by this constraint.
14992
    *
14993
    * NOTE: This seems not to involve built-in types, since there is no
14994
    * built-in Union Simple Type.
14995
    */
14996
0
    if (WXS_IS_UNION(baseType)) {
14997
0
  xmlSchemaTypeLinkPtr cur;
14998
14999
0
  cur = baseType->memberTypes;
15000
0
  while (cur != NULL) {
15001
0
      if (WXS_IS_TYPE_NOT_FIXED(cur->type))
15002
0
    if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
15003
0
        return(-1);
15004
0
      if (xmlSchemaCheckCOSSTDerivedOK(actxt,
15005
0
        type, cur->type, subset) == 0)
15006
0
      {
15007
    /*
15008
    * It just has to be validly derived from at least one
15009
    * member-type.
15010
    */
15011
0
    return (0);
15012
0
      }
15013
0
      cur = cur->next;
15014
0
  }
15015
0
    }
15016
0
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
15017
0
}
15018
15019
/**
15020
 * xmlSchemaCheckTypeDefCircularInternal:
15021
 * @pctxt:  the schema parser context
15022
 * @ctxtType:  the type definition
15023
 * @ancestor: an ancestor of @ctxtType
15024
 *
15025
 * Checks st-props-correct (2) + ct-props-correct (3).
15026
 * Circular type definitions are not allowed.
15027
 *
15028
 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
15029
 * circular, 0 otherwise.
15030
 */
15031
static int
15032
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
15033
         xmlSchemaTypePtr ctxtType,
15034
         xmlSchemaTypePtr ancestor)
15035
0
{
15036
0
    int ret;
15037
15038
0
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
15039
0
  return (0);
15040
15041
0
    if (ctxtType == ancestor) {
15042
0
  xmlSchemaPCustomErr(pctxt,
15043
0
      XML_SCHEMAP_ST_PROPS_CORRECT_2,
15044
0
      WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
15045
0
      "The definition is circular", NULL);
15046
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
15047
0
    }
15048
0
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
15049
  /*
15050
  * Avoid infinite recursion on circular types not yet checked.
15051
  */
15052
0
  return (0);
15053
0
    }
15054
0
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
15055
0
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
15056
0
  ancestor->baseType);
15057
0
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
15058
0
    return (ret);
15059
0
}
15060
15061
/**
15062
 * xmlSchemaCheckTypeDefCircular:
15063
 * @item:  the complex/simple type definition
15064
 * @ctxt:  the parser context
15065
 * @name:  the name
15066
 *
15067
 * Checks for circular type definitions.
15068
 */
15069
static void
15070
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
15071
            xmlSchemaParserCtxtPtr ctxt)
15072
0
{
15073
0
    if ((item == NULL) ||
15074
0
  (item->type == XML_SCHEMA_TYPE_BASIC) ||
15075
0
  (item->baseType == NULL))
15076
0
  return;
15077
0
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
15078
0
  item->baseType);
15079
0
}
15080
15081
/*
15082
* Simple Type Definition Representation OK (src-simple-type) 4
15083
*
15084
* "4 Circular union type definition is disallowed. That is, if the
15085
* <union> alternative is chosen, there must not be any entries in the
15086
* memberTypes [attribute] at any depth which resolve to the component
15087
* corresponding to the <simpleType>."
15088
*
15089
* Note that this should work on the *representation* of a component,
15090
* thus assumes any union types in the member types not being yet
15091
* substituted. At this stage we need the variety of the types
15092
* to be already computed.
15093
*/
15094
static int
15095
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
15096
          xmlSchemaTypePtr ctxType,
15097
          xmlSchemaTypeLinkPtr members)
15098
0
{
15099
0
    xmlSchemaTypeLinkPtr member;
15100
0
    xmlSchemaTypePtr memberType;
15101
15102
0
    member = members;
15103
0
    while (member != NULL) {
15104
0
  memberType = member->type;
15105
0
  while ((memberType != NULL) &&
15106
0
      (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
15107
0
      if (memberType == ctxType) {
15108
0
    xmlSchemaPCustomErr(pctxt,
15109
0
        XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
15110
0
        WXS_BASIC_CAST ctxType, NULL,
15111
0
        "The union type definition is circular", NULL);
15112
0
    return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
15113
0
      }
15114
0
      if ((WXS_IS_UNION(memberType)) &&
15115
0
    ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
15116
0
      {
15117
0
    int res;
15118
0
    memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
15119
0
    res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
15120
0
        ctxType,
15121
0
        xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
15122
0
    memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
15123
0
    if (res != 0)
15124
0
        return(res);
15125
0
      }
15126
0
      memberType = memberType->baseType;
15127
0
  }
15128
0
  member = member->next;
15129
0
    }
15130
0
    return(0);
15131
0
}
15132
15133
static int
15134
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15135
           xmlSchemaTypePtr type)
15136
0
{
15137
0
    if (! WXS_IS_UNION(type))
15138
0
  return(0);
15139
0
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15140
0
  type->memberTypes));
15141
0
}
15142
15143
/**
15144
 * xmlSchemaResolveTypeReferences:
15145
 * @item:  the complex/simple type definition
15146
 * @ctxt:  the parser context
15147
 * @name:  the name
15148
 *
15149
 * Resolves type definition references
15150
 */
15151
static void
15152
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15153
       xmlSchemaParserCtxtPtr ctxt)
15154
0
{
15155
0
    if (typeDef == NULL)
15156
0
  return;
15157
15158
    /*
15159
    * Resolve the base type.
15160
    */
15161
0
    if (typeDef->baseType == NULL) {
15162
0
  typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15163
0
      typeDef->base, typeDef->baseNs);
15164
0
  if (typeDef->baseType == NULL) {
15165
0
      xmlSchemaPResCompAttrErr(ctxt,
15166
0
    XML_SCHEMAP_SRC_RESOLVE,
15167
0
    WXS_BASIC_CAST typeDef, typeDef->node,
15168
0
    "base", typeDef->base, typeDef->baseNs,
15169
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
15170
0
      return;
15171
0
  }
15172
0
    }
15173
0
    if (WXS_IS_SIMPLE(typeDef)) {
15174
0
  if (WXS_IS_UNION(typeDef)) {
15175
      /*
15176
      * Resolve the memberTypes.
15177
      */
15178
0
      xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15179
0
      return;
15180
0
  } else if (WXS_IS_LIST(typeDef)) {
15181
      /*
15182
      * Resolve the itemType.
15183
      */
15184
0
      if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15185
15186
0
    typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15187
0
        typeDef->base, typeDef->baseNs);
15188
15189
0
    if ((typeDef->subtypes == NULL) ||
15190
0
        (! WXS_IS_SIMPLE(typeDef->subtypes)))
15191
0
    {
15192
0
        typeDef->subtypes = NULL;
15193
0
        xmlSchemaPResCompAttrErr(ctxt,
15194
0
      XML_SCHEMAP_SRC_RESOLVE,
15195
0
      WXS_BASIC_CAST typeDef, typeDef->node,
15196
0
      "itemType", typeDef->base, typeDef->baseNs,
15197
0
      XML_SCHEMA_TYPE_SIMPLE, NULL);
15198
0
    }
15199
0
      }
15200
0
      return;
15201
0
  }
15202
0
    }
15203
    /*
15204
    * The ball of letters below means, that if we have a particle
15205
    * which has a QName-helper component as its {term}, we want
15206
    * to resolve it...
15207
    */
15208
0
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15209
0
  ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15210
0
      XML_SCHEMA_TYPE_PARTICLE) &&
15211
0
  (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15212
0
  ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15213
0
      XML_SCHEMA_EXTRA_QNAMEREF))
15214
0
    {
15215
0
  xmlSchemaQNameRefPtr ref =
15216
0
      WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15217
0
  xmlSchemaModelGroupDefPtr groupDef;
15218
15219
  /*
15220
  * URGENT TODO: Test this.
15221
  */
15222
0
  WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15223
  /*
15224
  * Resolve the MG definition reference.
15225
  */
15226
0
  groupDef =
15227
0
      WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15228
0
    ref->itemType, ref->name, ref->targetNamespace);
15229
0
  if (groupDef == NULL) {
15230
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15231
0
    NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15232
0
    "ref", ref->name, ref->targetNamespace, ref->itemType,
15233
0
    NULL);
15234
      /* Remove the particle. */
15235
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15236
0
  } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15237
      /* Remove the particle. */
15238
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15239
0
  else {
15240
      /*
15241
      * Assign the MG definition's {model group} to the
15242
      * particle's {term}.
15243
      */
15244
0
      WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15245
15246
0
      if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15247
    /*
15248
    * SPEC cos-all-limited (1.2)
15249
    * "1.2 the {term} property of a particle with
15250
    * {max occurs}=1 which is part of a pair which constitutes
15251
    * the {content type} of a complex type definition."
15252
    */
15253
0
    if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15254
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
15255
      /* TODO: error code */
15256
0
      XML_SCHEMAP_COS_ALL_LIMITED,
15257
0
      WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15258
0
      "The particle's {max occurs} must be 1, since the "
15259
0
      "reference resolves to an 'all' model group",
15260
0
      NULL, NULL);
15261
0
    }
15262
0
      }
15263
0
  }
15264
0
    }
15265
0
}
15266
15267
15268
15269
/**
15270
 * xmlSchemaCheckSTPropsCorrect:
15271
 * @ctxt:  the schema parser context
15272
 * @type:  the simple type definition
15273
 *
15274
 * Checks st-props-correct.
15275
 *
15276
 * Returns 0 if the properties are correct,
15277
 * if not, a positive error code and -1 on internal
15278
 * errors.
15279
 */
15280
static int
15281
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15282
           xmlSchemaTypePtr type)
15283
0
{
15284
0
    xmlSchemaTypePtr baseType = type->baseType;
15285
0
    xmlChar *str = NULL;
15286
15287
    /* STATE: error funcs converted. */
15288
    /*
15289
    * Schema Component Constraint: Simple Type Definition Properties Correct
15290
    *
15291
    * NOTE: This is somehow redundant, since we actually built a simple type
15292
    * to have all the needed information; this acts as an self test.
15293
    */
15294
    /* Base type: If the datatype has been `derived` by `restriction`
15295
    * then the Simple Type Definition component from which it is `derived`,
15296
    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15297
    */
15298
0
    if (baseType == NULL) {
15299
  /*
15300
  * TODO: Think about: "modulo the impact of Missing
15301
  * Sub-components ($5.3)."
15302
  */
15303
0
  xmlSchemaPCustomErr(ctxt,
15304
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15305
0
      WXS_BASIC_CAST type, NULL,
15306
0
      "No base type existent", NULL);
15307
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15308
15309
0
    }
15310
0
    if (! WXS_IS_SIMPLE(baseType)) {
15311
0
  xmlSchemaPCustomErr(ctxt,
15312
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15313
0
      WXS_BASIC_CAST type, NULL,
15314
0
      "The base type '%s' is not a simple type",
15315
0
      xmlSchemaGetComponentQName(&str, baseType));
15316
0
  FREE_AND_NULL(str)
15317
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15318
0
    }
15319
0
    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15320
0
  (WXS_IS_RESTRICTION(type) == 0) &&
15321
0
  ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15322
0
         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15323
0
  xmlSchemaPCustomErr(ctxt,
15324
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15325
0
      WXS_BASIC_CAST type, NULL,
15326
0
      "A type, derived by list or union, must have "
15327
0
      "the simple ur-type definition as base type, not '%s'",
15328
0
      xmlSchemaGetComponentQName(&str, baseType));
15329
0
  FREE_AND_NULL(str)
15330
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15331
0
    }
15332
    /*
15333
    * Variety: One of {atomic, list, union}.
15334
    */
15335
0
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15336
0
  (! WXS_IS_LIST(type))) {
15337
0
  xmlSchemaPCustomErr(ctxt,
15338
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15339
0
      WXS_BASIC_CAST type, NULL,
15340
0
      "The variety is absent", NULL);
15341
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15342
0
    }
15343
    /* TODO: Finish this. Hmm, is this finished? */
15344
15345
    /*
15346
    * 3 The {final} of the {base type definition} must not contain restriction.
15347
    */
15348
0
    if (xmlSchemaTypeFinalContains(baseType,
15349
0
  XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15350
0
  xmlSchemaPCustomErr(ctxt,
15351
0
      XML_SCHEMAP_ST_PROPS_CORRECT_3,
15352
0
      WXS_BASIC_CAST type, NULL,
15353
0
      "The 'final' of its base type '%s' must not contain "
15354
0
      "'restriction'",
15355
0
      xmlSchemaGetComponentQName(&str, baseType));
15356
0
  FREE_AND_NULL(str)
15357
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15358
0
    }
15359
15360
    /*
15361
    * 2 All simple type definitions must be derived ultimately from the `simple
15362
    * ur-type definition` (so circular definitions are disallowed). That is, it
15363
    * must be possible to reach a built-in primitive datatype or the `simple
15364
    * ur-type definition` by repeatedly following the {base type definition}.
15365
    *
15366
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15367
    */
15368
0
    return (0);
15369
0
}
15370
15371
/**
15372
 * xmlSchemaCheckCOSSTRestricts:
15373
 * @ctxt:  the schema parser context
15374
 * @type:  the simple type definition
15375
 *
15376
 * Schema Component Constraint:
15377
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15378
15379
 * Checks if the given @type (simpleType) is derived validly by restriction.
15380
 * STATUS:
15381
 *
15382
 * Returns -1 on internal errors, 0 if the type is validly derived,
15383
 * a positive error code otherwise.
15384
 */
15385
static int
15386
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15387
           xmlSchemaTypePtr type)
15388
0
{
15389
0
    xmlChar *str = NULL;
15390
15391
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15392
0
  PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15393
0
      "given type is not a user-derived simpleType");
15394
0
  return (-1);
15395
0
    }
15396
15397
0
    if (WXS_IS_ATOMIC(type)) {
15398
0
  xmlSchemaTypePtr primitive;
15399
  /*
15400
  * 1.1 The {base type definition} must be an atomic simple
15401
  * type definition or a built-in primitive datatype.
15402
  */
15403
0
  if (! WXS_IS_ATOMIC(type->baseType)) {
15404
0
      xmlSchemaPCustomErr(pctxt,
15405
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15406
0
    WXS_BASIC_CAST type, NULL,
15407
0
    "The base type '%s' is not an atomic simple type",
15408
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15409
0
      FREE_AND_NULL(str)
15410
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15411
0
  }
15412
  /* 1.2 The {final} of the {base type definition} must not contain
15413
  * restriction.
15414
  */
15415
  /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15416
0
  if (xmlSchemaTypeFinalContains(type->baseType,
15417
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15418
0
      xmlSchemaPCustomErr(pctxt,
15419
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15420
0
    WXS_BASIC_CAST type, NULL,
15421
0
    "The final of its base type '%s' must not contain 'restriction'",
15422
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15423
0
      FREE_AND_NULL(str)
15424
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15425
0
  }
15426
15427
  /*
15428
  * 1.3.1 DF must be an allowed constraining facet for the {primitive
15429
  * type definition}, as specified in the appropriate subsection of 3.2
15430
  * Primitive datatypes.
15431
  */
15432
0
  if (type->facets != NULL) {
15433
0
      xmlSchemaFacetPtr facet;
15434
0
      int ok = 1;
15435
15436
0
      primitive = xmlSchemaGetPrimitiveType(type);
15437
0
      if (primitive == NULL) {
15438
0
    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15439
0
        "failed to get primitive type");
15440
0
    return (-1);
15441
0
      }
15442
0
      facet = type->facets;
15443
0
      do {
15444
0
    if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15445
0
        ok = 0;
15446
0
        xmlSchemaPIllegalFacetAtomicErr(pctxt,
15447
0
      XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15448
0
      type, primitive, facet);
15449
0
    }
15450
0
    facet = facet->next;
15451
0
      } while (facet != NULL);
15452
0
      if (ok == 0)
15453
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15454
0
  }
15455
  /*
15456
  * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15457
  * of the {base type definition} (call this BF),then the DF's {value}
15458
  * must be a valid restriction of BF's {value} as defined in
15459
  * [XML Schemas: Datatypes]."
15460
  *
15461
  * NOTE (1.3.2) Facet derivation constraints are currently handled in
15462
  * xmlSchemaDeriveAndValidateFacets()
15463
  */
15464
0
    } else if (WXS_IS_LIST(type)) {
15465
0
  xmlSchemaTypePtr itemType = NULL;
15466
15467
0
  itemType = type->subtypes;
15468
0
  if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15469
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15470
0
    "failed to evaluate the item type");
15471
0
      return (-1);
15472
0
  }
15473
0
  if (WXS_IS_TYPE_NOT_FIXED(itemType))
15474
0
      xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15475
  /*
15476
  * 2.1 The {item type definition} must have a {variety} of atomic or
15477
  * union (in which case all the {member type definitions}
15478
  * must be atomic).
15479
  */
15480
0
  if ((! WXS_IS_ATOMIC(itemType)) &&
15481
0
      (! WXS_IS_UNION(itemType))) {
15482
0
      xmlSchemaPCustomErr(pctxt,
15483
0
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15484
0
    WXS_BASIC_CAST type, NULL,
15485
0
    "The item type '%s' does not have a variety of atomic or union",
15486
0
    xmlSchemaGetComponentQName(&str, itemType));
15487
0
      FREE_AND_NULL(str)
15488
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15489
0
  } else if (WXS_IS_UNION(itemType)) {
15490
0
      xmlSchemaTypeLinkPtr member;
15491
15492
0
      member = itemType->memberTypes;
15493
0
      while (member != NULL) {
15494
0
    if (! WXS_IS_ATOMIC(member->type)) {
15495
0
        xmlSchemaPCustomErr(pctxt,
15496
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15497
0
      WXS_BASIC_CAST type, NULL,
15498
0
      "The item type is a union type, but the "
15499
0
      "member type '%s' of this item type is not atomic",
15500
0
      xmlSchemaGetComponentQName(&str, member->type));
15501
0
        FREE_AND_NULL(str)
15502
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15503
0
    }
15504
0
    member = member->next;
15505
0
      }
15506
0
  }
15507
15508
0
  if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15509
0
      xmlSchemaFacetPtr facet;
15510
      /*
15511
      * This is the case if we have: <simpleType><list ..
15512
      */
15513
      /*
15514
      * 2.3.1
15515
      * 2.3.1.1 The {final} of the {item type definition} must not
15516
      * contain list.
15517
      */
15518
0
      if (xmlSchemaTypeFinalContains(itemType,
15519
0
    XML_SCHEMAS_TYPE_FINAL_LIST)) {
15520
0
    xmlSchemaPCustomErr(pctxt,
15521
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15522
0
        WXS_BASIC_CAST type, NULL,
15523
0
        "The final of its item type '%s' must not contain 'list'",
15524
0
        xmlSchemaGetComponentQName(&str, itemType));
15525
0
    FREE_AND_NULL(str)
15526
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15527
0
      }
15528
      /*
15529
      * 2.3.1.2 The {facets} must only contain the whiteSpace
15530
      * facet component.
15531
      * OPTIMIZE TODO: the S4S already disallows any facet
15532
      * to be specified.
15533
      */
15534
0
      if (type->facets != NULL) {
15535
0
    facet = type->facets;
15536
0
    do {
15537
0
        if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15538
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15539
0
          XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15540
0
          type, facet);
15541
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15542
0
        }
15543
0
        facet = facet->next;
15544
0
    } while (facet != NULL);
15545
0
      }
15546
      /*
15547
      * MAYBE TODO: (Hmm, not really) Datatypes states:
15548
      * A `list` datatype can be `derived` from an `atomic` datatype
15549
      * whose `lexical space` allows space (such as string or anyURI)or
15550
      * a `union` datatype any of whose {member type definitions}'s
15551
      * `lexical space` allows space.
15552
      */
15553
0
  } else {
15554
      /*
15555
      * This is the case if we have: <simpleType><restriction ...
15556
      * I.e. the variety of "list" is inherited.
15557
      */
15558
      /*
15559
      * 2.3.2
15560
      * 2.3.2.1 The {base type definition} must have a {variety} of list.
15561
      */
15562
0
      if (! WXS_IS_LIST(type->baseType)) {
15563
0
    xmlSchemaPCustomErr(pctxt,
15564
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15565
0
        WXS_BASIC_CAST type, NULL,
15566
0
        "The base type '%s' must be a list type",
15567
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15568
0
    FREE_AND_NULL(str)
15569
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15570
0
      }
15571
      /*
15572
      * 2.3.2.2 The {final} of the {base type definition} must not
15573
      * contain restriction.
15574
      */
15575
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15576
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15577
0
    xmlSchemaPCustomErr(pctxt,
15578
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15579
0
        WXS_BASIC_CAST type, NULL,
15580
0
        "The 'final' of the base type '%s' must not contain 'restriction'",
15581
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15582
0
    FREE_AND_NULL(str)
15583
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15584
0
      }
15585
      /*
15586
      * 2.3.2.3 The {item type definition} must be validly derived
15587
      * from the {base type definition}'s {item type definition} given
15588
      * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15589
      */
15590
0
      {
15591
0
    xmlSchemaTypePtr baseItemType;
15592
15593
0
    baseItemType = type->baseType->subtypes;
15594
0
    if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15595
0
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15596
0
      "failed to eval the item type of a base type");
15597
0
        return (-1);
15598
0
    }
15599
0
    if ((itemType != baseItemType) &&
15600
0
        (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15601
0
      baseItemType, 0) != 0)) {
15602
0
        xmlChar *strBIT = NULL, *strBT = NULL;
15603
0
        xmlSchemaPCustomErrExt(pctxt,
15604
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15605
0
      WXS_BASIC_CAST type, NULL,
15606
0
      "The item type '%s' is not validly derived from "
15607
0
      "the item type '%s' of the base type '%s'",
15608
0
      xmlSchemaGetComponentQName(&str, itemType),
15609
0
      xmlSchemaGetComponentQName(&strBIT, baseItemType),
15610
0
      xmlSchemaGetComponentQName(&strBT, type->baseType));
15611
15612
0
        FREE_AND_NULL(str)
15613
0
        FREE_AND_NULL(strBIT)
15614
0
        FREE_AND_NULL(strBT)
15615
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15616
0
    }
15617
0
      }
15618
15619
0
      if (type->facets != NULL) {
15620
0
    xmlSchemaFacetPtr facet;
15621
0
    int ok = 1;
15622
    /*
15623
    * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15624
    * and enumeration facet components are allowed among the {facets}.
15625
    */
15626
0
    facet = type->facets;
15627
0
    do {
15628
0
        switch (facet->type) {
15629
0
      case XML_SCHEMA_FACET_LENGTH:
15630
0
      case XML_SCHEMA_FACET_MINLENGTH:
15631
0
      case XML_SCHEMA_FACET_MAXLENGTH:
15632
0
      case XML_SCHEMA_FACET_WHITESPACE:
15633
          /*
15634
          * TODO: 2.5.1.2 List datatypes
15635
          * The value of `whiteSpace` is fixed to the value collapse.
15636
          */
15637
0
      case XML_SCHEMA_FACET_PATTERN:
15638
0
      case XML_SCHEMA_FACET_ENUMERATION:
15639
0
          break;
15640
0
      default: {
15641
0
          xmlSchemaPIllegalFacetListUnionErr(pctxt,
15642
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15643
0
        type, facet);
15644
          /*
15645
          * We could return, but it's nicer to report all
15646
          * invalid facets.
15647
          */
15648
0
          ok = 0;
15649
0
      }
15650
0
        }
15651
0
        facet = facet->next;
15652
0
    } while (facet != NULL);
15653
0
    if (ok == 0)
15654
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15655
    /*
15656
    * SPEC (2.3.2.5) (same as 1.3.2)
15657
    *
15658
    * NOTE (2.3.2.5) This is currently done in
15659
    * xmlSchemaDeriveAndValidateFacets()
15660
    */
15661
0
      }
15662
0
  }
15663
0
    } else if (WXS_IS_UNION(type)) {
15664
  /*
15665
  * 3.1 The {member type definitions} must all have {variety} of
15666
  * atomic or list.
15667
  */
15668
0
  xmlSchemaTypeLinkPtr member;
15669
15670
0
  member = type->memberTypes;
15671
0
  while (member != NULL) {
15672
0
      if (WXS_IS_TYPE_NOT_FIXED(member->type))
15673
0
    xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15674
15675
0
      if ((! WXS_IS_ATOMIC(member->type)) &&
15676
0
    (! WXS_IS_LIST(member->type))) {
15677
0
    xmlSchemaPCustomErr(pctxt,
15678
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15679
0
        WXS_BASIC_CAST type, NULL,
15680
0
        "The member type '%s' is neither an atomic, nor a list type",
15681
0
        xmlSchemaGetComponentQName(&str, member->type));
15682
0
    FREE_AND_NULL(str)
15683
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15684
0
      }
15685
0
      member = member->next;
15686
0
  }
15687
  /*
15688
  * 3.3.1 If the {base type definition} is the `simple ur-type
15689
  * definition`
15690
  */
15691
0
  if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15692
      /*
15693
      * 3.3.1.1 All of the {member type definitions} must have a
15694
      * {final} which does not contain union.
15695
      */
15696
0
      member = type->memberTypes;
15697
0
      while (member != NULL) {
15698
0
    if (xmlSchemaTypeFinalContains(member->type,
15699
0
        XML_SCHEMAS_TYPE_FINAL_UNION)) {
15700
0
        xmlSchemaPCustomErr(pctxt,
15701
0
      XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15702
0
      WXS_BASIC_CAST type, NULL,
15703
0
      "The 'final' of member type '%s' contains 'union'",
15704
0
      xmlSchemaGetComponentQName(&str, member->type));
15705
0
        FREE_AND_NULL(str)
15706
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15707
0
    }
15708
0
    member = member->next;
15709
0
      }
15710
      /*
15711
      * 3.3.1.2 The {facets} must be empty.
15712
      */
15713
0
      if (type->facetSet != NULL) {
15714
0
    xmlSchemaPCustomErr(pctxt,
15715
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15716
0
        WXS_BASIC_CAST type, NULL,
15717
0
        "No facets allowed", NULL);
15718
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15719
0
      }
15720
0
  } else {
15721
      /*
15722
      * 3.3.2.1 The {base type definition} must have a {variety} of union.
15723
      * I.e. the variety of "list" is inherited.
15724
      */
15725
0
      if (! WXS_IS_UNION(type->baseType)) {
15726
0
    xmlSchemaPCustomErr(pctxt,
15727
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15728
0
        WXS_BASIC_CAST type, NULL,
15729
0
        "The base type '%s' is not a union type",
15730
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15731
0
    FREE_AND_NULL(str)
15732
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15733
0
      }
15734
      /*
15735
      * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15736
      */
15737
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15738
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15739
0
    xmlSchemaPCustomErr(pctxt,
15740
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15741
0
        WXS_BASIC_CAST type, NULL,
15742
0
        "The 'final' of its base type '%s' must not contain 'restriction'",
15743
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15744
0
    FREE_AND_NULL(str)
15745
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15746
0
      }
15747
      /*
15748
      * 3.3.2.3 The {member type definitions}, in order, must be validly
15749
      * derived from the corresponding type definitions in the {base
15750
      * type definition}'s {member type definitions} given the empty set,
15751
      * as defined in Type Derivation OK (Simple) ($3.14.6).
15752
      */
15753
0
      {
15754
0
    xmlSchemaTypeLinkPtr baseMember;
15755
15756
    /*
15757
    * OPTIMIZE: if the type is restricting, it has no local defined
15758
    * member types and inherits the member types of the base type;
15759
    * thus a check for equality can be skipped.
15760
    */
15761
    /*
15762
    * Even worse: I cannot see a scenario where a restricting
15763
    * union simple type can have other member types as the member
15764
    * types of it's base type. This check seems not necessary with
15765
    * respect to the derivation process in libxml2.
15766
    * But necessary if constructing types with an API.
15767
    */
15768
0
    if (type->memberTypes != NULL) {
15769
0
        member = type->memberTypes;
15770
0
        baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15771
0
        if ((member == NULL) && (baseMember != NULL)) {
15772
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15773
0
          "different number of member types in base");
15774
0
        }
15775
0
        while (member != NULL) {
15776
0
      if (baseMember == NULL) {
15777
0
          PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15778
0
          "different number of member types in base");
15779
0
      } else if ((member->type != baseMember->type) &&
15780
0
          (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15781
0
        member->type, baseMember->type, 0) != 0)) {
15782
0
          xmlChar *strBMT = NULL, *strBT = NULL;
15783
15784
0
          xmlSchemaPCustomErrExt(pctxt,
15785
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15786
0
        WXS_BASIC_CAST type, NULL,
15787
0
        "The member type %s is not validly "
15788
0
        "derived from its corresponding member "
15789
0
        "type %s of the base type %s",
15790
0
        xmlSchemaGetComponentQName(&str, member->type),
15791
0
        xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15792
0
        xmlSchemaGetComponentQName(&strBT, type->baseType));
15793
0
          FREE_AND_NULL(str)
15794
0
          FREE_AND_NULL(strBMT)
15795
0
          FREE_AND_NULL(strBT)
15796
0
          return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15797
0
      }
15798
0
      member = member->next;
15799
0
                        if (baseMember != NULL)
15800
0
                            baseMember = baseMember->next;
15801
0
        }
15802
0
    }
15803
0
      }
15804
      /*
15805
      * 3.3.2.4 Only pattern and enumeration facet components are
15806
      * allowed among the {facets}.
15807
      */
15808
0
      if (type->facets != NULL) {
15809
0
    xmlSchemaFacetPtr facet;
15810
0
    int ok = 1;
15811
15812
0
    facet = type->facets;
15813
0
    do {
15814
0
        if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15815
0
      (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15816
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15817
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15818
0
        type, facet);
15819
0
      ok = 0;
15820
0
        }
15821
0
        facet = facet->next;
15822
0
    } while (facet != NULL);
15823
0
    if (ok == 0)
15824
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15825
15826
0
      }
15827
      /*
15828
      * SPEC (3.3.2.5) (same as 1.3.2)
15829
      *
15830
      * NOTE (3.3.2.5) This is currently done in
15831
      * xmlSchemaDeriveAndValidateFacets()
15832
      */
15833
0
  }
15834
0
    }
15835
15836
0
    return (0);
15837
0
}
15838
15839
/**
15840
 * xmlSchemaCheckSRCSimpleType:
15841
 * @ctxt:  the schema parser context
15842
 * @type:  the simple type definition
15843
 *
15844
 * Checks crc-simple-type constraints.
15845
 *
15846
 * Returns 0 if the constraints are satisfied,
15847
 * if not a positive error code and -1 on internal
15848
 * errors.
15849
 */
15850
#if 0
15851
static int
15852
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15853
          xmlSchemaTypePtr type)
15854
{
15855
    /*
15856
    * src-simple-type.1 The corresponding simple type definition, if any,
15857
    * must satisfy the conditions set out in Constraints on Simple Type
15858
    * Definition Schema Components ($3.14.6).
15859
    */
15860
    if (WXS_IS_RESTRICTION(type)) {
15861
  /*
15862
  * src-simple-type.2 "If the <restriction> alternative is chosen,
15863
  * either it must have a base [attribute] or a <simpleType> among its
15864
  * [children], but not both."
15865
  * NOTE: This is checked in the parse function of <restriction>.
15866
  */
15867
  /*
15868
  *
15869
  */
15870
    } else if (WXS_IS_LIST(type)) {
15871
  /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15872
  * an itemType [attribute] or a <simpleType> among its [children],
15873
  * but not both."
15874
  *
15875
  * NOTE: This is checked in the parse function of <list>.
15876
  */
15877
    } else if (WXS_IS_UNION(type)) {
15878
  /*
15879
  * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15880
  */
15881
    }
15882
    return (0);
15883
}
15884
#endif
15885
15886
static int
15887
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15888
0
{
15889
0
   if (ctxt->vctxt == NULL) {
15890
0
  ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15891
0
  if (ctxt->vctxt == NULL) {
15892
0
      xmlSchemaPErr(ctxt, NULL,
15893
0
    XML_SCHEMAP_INTERNAL,
15894
0
    "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15895
0
    "failed to create a temp. validation context.\n",
15896
0
    NULL, NULL);
15897
0
      return (-1);
15898
0
  }
15899
  /* TODO: Pass user data. */
15900
0
  xmlSchemaSetValidErrors(ctxt->vctxt,
15901
0
      ctxt->error, ctxt->warning, ctxt->errCtxt);
15902
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15903
0
      ctxt->serror, ctxt->errCtxt);
15904
0
    }
15905
0
    return (0);
15906
0
}
15907
15908
static int
15909
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15910
           xmlNodePtr node,
15911
           xmlSchemaTypePtr type,
15912
           const xmlChar *value,
15913
           xmlSchemaValPtr *retVal,
15914
           int fireErrors,
15915
           int normalize,
15916
           int isNormalized);
15917
15918
/**
15919
 * xmlSchemaParseCheckCOSValidDefault:
15920
 * @pctxt:  the schema parser context
15921
 * @type:  the simple type definition
15922
 * @value: the default value
15923
 * @node: an optional node (the holder of the value)
15924
 *
15925
 * Schema Component Constraint: Element Default Valid (Immediate)
15926
 * (cos-valid-default)
15927
 * This will be used by the parser only. For the validator there's
15928
 * an other version.
15929
 *
15930
 * Returns 0 if the constraints are satisfied,
15931
 * if not, a positive error code and -1 on internal
15932
 * errors.
15933
 */
15934
static int
15935
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15936
           xmlNodePtr node,
15937
           xmlSchemaTypePtr type,
15938
           const xmlChar *value,
15939
           xmlSchemaValPtr *val)
15940
0
{
15941
0
    int ret = 0;
15942
15943
    /*
15944
    * cos-valid-default:
15945
    * Schema Component Constraint: Element Default Valid (Immediate)
15946
    * For a string to be a valid default with respect to a type
15947
    * definition the appropriate case among the following must be true:
15948
    */
15949
0
    if WXS_IS_COMPLEX(type) {
15950
  /*
15951
  * Complex type.
15952
  *
15953
  * SPEC (2.1) "its {content type} must be a simple type definition
15954
  * or mixed."
15955
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15956
  * type}'s particle must be `emptiable` as defined by
15957
  * Particle Emptiable ($3.9.6)."
15958
  */
15959
0
  if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15960
0
      ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15961
      /* NOTE that this covers (2.2.2) as well. */
15962
0
      xmlSchemaPCustomErr(pctxt,
15963
0
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15964
0
    WXS_BASIC_CAST type, type->node,
15965
0
    "For a string to be a valid default, the type definition "
15966
0
    "must be a simple type or a complex type with mixed content "
15967
0
    "and a particle emptiable", NULL);
15968
0
      return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15969
0
  }
15970
0
    }
15971
    /*
15972
    * 1 If the type definition is a simple type definition, then the string
15973
    * must be `valid` with respect to that definition as defined by String
15974
    * Valid ($3.14.4).
15975
    *
15976
    * AND
15977
    *
15978
    * 2.2.1 If the {content type} is a simple type definition, then the
15979
    * string must be `valid` with respect to that simple type definition
15980
    * as defined by String Valid ($3.14.4).
15981
    */
15982
0
    if (WXS_IS_SIMPLE(type))
15983
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15984
0
      type, value, val, 1, 1, 0);
15985
0
    else if (WXS_HAS_SIMPLE_CONTENT(type))
15986
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15987
0
      type->contentTypeDef, value, val, 1, 1, 0);
15988
0
    else
15989
0
  return (ret);
15990
15991
0
    if (ret < 0) {
15992
0
  PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15993
0
      "calling xmlSchemaVCheckCVCSimpleType()");
15994
0
    }
15995
15996
0
    return (ret);
15997
0
}
15998
15999
/**
16000
 * xmlSchemaCheckCTPropsCorrect:
16001
 * @ctxt:  the schema parser context
16002
 * @type:  the complex type definition
16003
 *
16004
 *.(4.6) Constraints on Complex Type Definition Schema Components
16005
 * Schema Component Constraint:
16006
 * Complex Type Definition Properties Correct (ct-props-correct)
16007
 * STATUS: (seems) complete
16008
 *
16009
 * Returns 0 if the constraints are satisfied, a positive
16010
 * error code if not and -1 if an internal error occurred.
16011
 */
16012
static int
16013
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
16014
           xmlSchemaTypePtr type)
16015
0
{
16016
    /*
16017
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
16018
    *
16019
    * SPEC (1) "The values of the properties of a complex type definition must
16020
    * be as described in the property tableau in The Complex Type Definition
16021
    * Schema Component ($3.4.1), modulo the impact of Missing
16022
    * Sub-components ($5.3)."
16023
    */
16024
0
    if ((type->baseType != NULL) &&
16025
0
  (WXS_IS_SIMPLE(type->baseType)) &&
16026
0
  (WXS_IS_EXTENSION(type) == 0)) {
16027
  /*
16028
  * SPEC (2) "If the {base type definition} is a simple type definition,
16029
  * the {derivation method} must be extension."
16030
  */
16031
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
16032
0
      XML_SCHEMAP_SRC_CT_1,
16033
0
      NULL, WXS_BASIC_CAST type,
16034
0
      "If the base type is a simple type, the derivation method must be "
16035
0
      "'extension'", NULL, NULL);
16036
0
  return (XML_SCHEMAP_SRC_CT_1);
16037
0
    }
16038
    /*
16039
    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
16040
    * definition`. That is, it must be possible to reach the `ur-type
16041
    * definition` by repeatedly following the {base type definition}."
16042
    *
16043
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
16044
    */
16045
    /*
16046
    * NOTE that (4) and (5) need the following:
16047
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
16048
    *   - attribute group references need to be expanded already
16049
    *   - simple types need to be typefixed already
16050
    */
16051
0
    if (type->attrUses &&
16052
0
  (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
16053
0
    {
16054
0
  xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
16055
0
  xmlSchemaAttributeUsePtr use, tmp;
16056
0
  int i, j, hasId = 0;
16057
16058
0
  for (i = uses->nbItems -1; i >= 0; i--) {
16059
0
      use = uses->items[i];
16060
16061
      /*
16062
      * SPEC ct-props-correct
16063
      * (4) "Two distinct attribute declarations in the
16064
      * {attribute uses} must not have identical {name}s and
16065
      * {target namespace}s."
16066
      */
16067
0
      if (i > 0) {
16068
0
    for (j = i -1; j >= 0; j--) {
16069
0
        tmp = uses->items[j];
16070
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
16071
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
16072
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
16073
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
16074
0
        {
16075
0
      xmlChar *str = NULL;
16076
16077
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
16078
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
16079
0
          NULL, WXS_BASIC_CAST type,
16080
0
          "Duplicate %s",
16081
0
          xmlSchemaGetComponentDesignation(&str, use),
16082
0
          NULL);
16083
0
      FREE_AND_NULL(str);
16084
      /*
16085
      * Remove the duplicate.
16086
      */
16087
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
16088
0
          goto exit_failure;
16089
0
      goto next_use;
16090
0
        }
16091
0
    }
16092
0
      }
16093
      /*
16094
      * SPEC ct-props-correct
16095
      * (5) "Two distinct attribute declarations in the
16096
      * {attribute uses} must not have {type definition}s which
16097
      * are or are derived from ID."
16098
      */
16099
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
16100
0
    if (xmlSchemaIsDerivedFromBuiltInType(
16101
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
16102
0
    {
16103
0
        if (hasId) {
16104
0
      xmlChar *str = NULL;
16105
16106
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
16107
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
16108
0
          NULL, WXS_BASIC_CAST type,
16109
0
          "There must not exist more than one attribute "
16110
0
          "declaration of type 'xs:ID' "
16111
0
          "(or derived from 'xs:ID'). The %s violates this "
16112
0
          "constraint",
16113
0
          xmlSchemaGetComponentDesignation(&str, use),
16114
0
          NULL);
16115
0
      FREE_AND_NULL(str);
16116
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
16117
0
          goto exit_failure;
16118
0
        }
16119
16120
0
        hasId = 1;
16121
0
    }
16122
0
      }
16123
0
next_use: {}
16124
0
  }
16125
0
    }
16126
0
    return (0);
16127
0
exit_failure:
16128
0
    return(-1);
16129
0
}
16130
16131
static int
16132
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16133
           xmlSchemaTypePtr typeB)
16134
0
{
16135
    /*
16136
    * TODO: This should implement component-identity
16137
    * in the future.
16138
    */
16139
0
    if ((typeA == NULL) || (typeB == NULL))
16140
0
  return (0);
16141
0
    return (typeA == typeB);
16142
0
}
16143
16144
/**
16145
 * xmlSchemaCheckCOSCTDerivedOK:
16146
 * @ctxt:  the schema parser context
16147
 * @type:  the to-be derived complex type definition
16148
 * @baseType:  the base complex type definition
16149
 * @set: the given set
16150
 *
16151
 * Schema Component Constraint:
16152
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16153
 *
16154
 * STATUS: completed
16155
 *
16156
 * Returns 0 if the constraints are satisfied, or 1
16157
 * if not.
16158
 */
16159
static int
16160
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16161
           xmlSchemaTypePtr type,
16162
           xmlSchemaTypePtr baseType,
16163
           int set)
16164
0
{
16165
0
    int equal = xmlSchemaAreEqualTypes(type, baseType);
16166
    /* TODO: Error codes. */
16167
    /*
16168
    * SPEC "For a complex type definition (call it D, for derived)
16169
    * to be validly derived from a type definition (call this
16170
    * B, for base) given a subset of {extension, restriction}
16171
    * all of the following must be true:"
16172
    */
16173
0
    if (! equal) {
16174
  /*
16175
  * SPEC (1) "If B and D are not the same type definition, then the
16176
  * {derivation method} of D must not be in the subset."
16177
  */
16178
0
  if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16179
0
      ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16180
0
      return (1);
16181
0
    } else {
16182
  /*
16183
  * SPEC (2.1) "B and D must be the same type definition."
16184
  */
16185
0
  return (0);
16186
0
    }
16187
    /*
16188
    * SPEC (2.2) "B must be D's {base type definition}."
16189
    */
16190
0
    if (type->baseType == baseType)
16191
0
  return (0);
16192
    /*
16193
    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16194
    * definition`."
16195
    */
16196
0
    if (WXS_IS_ANYTYPE(type->baseType))
16197
0
  return (1);
16198
16199
0
    if (WXS_IS_COMPLEX(type->baseType)) {
16200
  /*
16201
  * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16202
  * must be validly derived from B given the subset as defined by this
16203
  * constraint."
16204
  */
16205
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16206
0
      baseType, set));
16207
0
    } else {
16208
  /*
16209
  * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16210
  * must be validly derived from B given the subset as defined in Type
16211
  * Derivation OK (Simple) ($3.14.6).
16212
  */
16213
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16214
0
      baseType, set));
16215
0
    }
16216
0
}
16217
16218
/**
16219
 * xmlSchemaCheckCOSDerivedOK:
16220
 * @type:  the derived simple type definition
16221
 * @baseType:  the base type definition
16222
 *
16223
 * Calls:
16224
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16225
 *
16226
 * Checks whether @type can be validly derived from @baseType.
16227
 *
16228
 * Returns 0 on success, an positive error code otherwise.
16229
 */
16230
static int
16231
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16232
         xmlSchemaTypePtr type,
16233
         xmlSchemaTypePtr baseType,
16234
         int set)
16235
0
{
16236
0
    if (WXS_IS_SIMPLE(type))
16237
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16238
0
    else
16239
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16240
0
}
16241
16242
/**
16243
 * xmlSchemaCheckCOSCTExtends:
16244
 * @ctxt:  the schema parser context
16245
 * @type:  the complex type definition
16246
 *
16247
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16248
 * Schema Component Constraint:
16249
 * Derivation Valid (Extension) (cos-ct-extends)
16250
 *
16251
 * STATUS:
16252
 *   missing:
16253
 *     (1.5)
16254
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16255
 *
16256
 * Returns 0 if the constraints are satisfied, a positive
16257
 * error code if not and -1 if an internal error occurred.
16258
 */
16259
static int
16260
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16261
         xmlSchemaTypePtr type)
16262
0
{
16263
0
    xmlSchemaTypePtr base = type->baseType;
16264
    /*
16265
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16266
    * temporarily only.
16267
    */
16268
    /*
16269
    * SPEC (1) "If the {base type definition} is a complex type definition,
16270
    * then all of the following must be true:"
16271
    */
16272
0
    if (WXS_IS_COMPLEX(base)) {
16273
  /*
16274
  * SPEC (1.1) "The {final} of the {base type definition} must not
16275
  * contain extension."
16276
  */
16277
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16278
0
      xmlSchemaPCustomErr(ctxt,
16279
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16280
0
    WXS_BASIC_CAST type, NULL,
16281
0
    "The 'final' of the base type definition "
16282
0
    "contains 'extension'", NULL);
16283
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16284
0
  }
16285
16286
  /*
16287
  * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16288
  * since they are automatically satisfied through the
16289
  * inheriting mechanism.
16290
  * Note that even if redefining components, the inheriting mechanism
16291
  * is used.
16292
  */
16293
#if 0
16294
  /*
16295
  * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16296
  * uses}
16297
  * of the complex type definition itself, that is, for every attribute
16298
  * use in the {attribute uses} of the {base type definition}, there
16299
  * must be an attribute use in the {attribute uses} of the complex
16300
  * type definition itself whose {attribute declaration} has the same
16301
  * {name}, {target namespace} and {type definition} as its attribute
16302
  * declaration"
16303
  */
16304
  if (base->attrUses != NULL) {
16305
      int i, j, found;
16306
      xmlSchemaAttributeUsePtr use, buse;
16307
16308
      for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16309
    buse = (WXS_LIST_CAST base->attrUses)->items[i];
16310
    found = 0;
16311
    if (type->attrUses != NULL) {
16312
        use = (WXS_LIST_CAST type->attrUses)->items[j];
16313
        for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16314
        {
16315
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
16316
        WXS_ATTRUSE_DECL_NAME(buse)) &&
16317
          (WXS_ATTRUSE_DECL_TNS(use) ==
16318
        WXS_ATTRUSE_DECL_TNS(buse)) &&
16319
          (WXS_ATTRUSE_TYPEDEF(use) ==
16320
        WXS_ATTRUSE_TYPEDEF(buse))
16321
      {
16322
          found = 1;
16323
          break;
16324
      }
16325
        }
16326
    }
16327
    if (! found) {
16328
        xmlChar *str = NULL;
16329
16330
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
16331
      XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16332
      NULL, WXS_BASIC_CAST type,
16333
      /*
16334
      * TODO: The report does not indicate that also the
16335
      * type needs to be the same.
16336
      */
16337
      "This type is missing a matching correspondent "
16338
      "for its {base type}'s %s in its {attribute uses}",
16339
      xmlSchemaGetComponentDesignation(&str,
16340
          buse->children),
16341
      NULL);
16342
        FREE_AND_NULL(str)
16343
    }
16344
      }
16345
  }
16346
  /*
16347
  * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16348
  * definition must also have one, and the base type definition's
16349
  * {attribute  wildcard}'s {namespace constraint} must be a subset
16350
  * of the complex  type definition's {attribute wildcard}'s {namespace
16351
  * constraint}, as defined by Wildcard Subset ($3.10.6)."
16352
  */
16353
16354
  /*
16355
  * MAYBE TODO: Enable if ever needed. But this will be needed only
16356
  * if created the type via a schema construction API.
16357
  */
16358
  if (base->attributeWildcard != NULL) {
16359
      if (type->attributeWildcard == NULL) {
16360
    xmlChar *str = NULL;
16361
16362
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16363
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16364
        NULL, type,
16365
        "The base %s has an attribute wildcard, "
16366
        "but this type is missing an attribute wildcard",
16367
        xmlSchemaGetComponentDesignation(&str, base));
16368
    FREE_AND_NULL(str)
16369
16370
      } else if (xmlSchemaCheckCOSNSSubset(
16371
    base->attributeWildcard, type->attributeWildcard))
16372
      {
16373
    xmlChar *str = NULL;
16374
16375
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16376
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16377
        NULL, type,
16378
        "The attribute wildcard is not a valid "
16379
        "superset of the one in the base %s",
16380
        xmlSchemaGetComponentDesignation(&str, base));
16381
    FREE_AND_NULL(str)
16382
      }
16383
  }
16384
#endif
16385
  /*
16386
  * SPEC (1.4) "One of the following must be true:"
16387
  */
16388
0
  if ((type->contentTypeDef != NULL) &&
16389
0
      (type->contentTypeDef == base->contentTypeDef)) {
16390
      /*
16391
      * SPEC (1.4.1) "The {content type} of the {base type definition}
16392
      * and the {content type} of the complex type definition itself
16393
      * must be the same simple type definition"
16394
      * PASS
16395
      */
16396
0
  } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16397
0
      (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16398
      /*
16399
      * SPEC (1.4.2) "The {content type} of both the {base type
16400
      * definition} and the complex type definition itself must
16401
      * be empty."
16402
      * PASS
16403
      */
16404
0
  } else {
16405
      /*
16406
      * SPEC (1.4.3) "All of the following must be true:"
16407
      */
16408
0
      if (type->subtypes == NULL) {
16409
    /*
16410
    * SPEC 1.4.3.1 The {content type} of the complex type
16411
    * definition itself must specify a particle.
16412
    */
16413
0
    xmlSchemaPCustomErr(ctxt,
16414
0
        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16415
0
        WXS_BASIC_CAST type, NULL,
16416
0
        "The content type must specify a particle", NULL);
16417
0
    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16418
0
      }
16419
      /*
16420
      * SPEC (1.4.3.2) "One of the following must be true:"
16421
      */
16422
0
      if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16423
    /*
16424
    * SPEC (1.4.3.2.1) "The {content type} of the {base type
16425
    * definition} must be empty.
16426
    * PASS
16427
    */
16428
0
      } else {
16429
    /*
16430
    * SPEC (1.4.3.2.2) "All of the following must be true:"
16431
    */
16432
0
    if ((type->contentType != base->contentType) ||
16433
0
        ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16434
0
        (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16435
        /*
16436
        * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16437
        * or both must be element-only."
16438
        */
16439
0
        xmlSchemaPCustomErr(ctxt,
16440
0
      XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16441
0
      WXS_BASIC_CAST type, NULL,
16442
0
      "The content type of both, the type and its base "
16443
0
      "type, must either 'mixed' or 'element-only'", NULL);
16444
0
        return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16445
0
    }
16446
    /*
16447
    * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16448
    * complex type definition must be a `valid extension`
16449
    * of the {base type definition}'s particle, as defined
16450
    * in Particle Valid (Extension) ($3.9.6)."
16451
    *
16452
    * NOTE that we won't check "Particle Valid (Extension)",
16453
    * since it is ensured by the derivation process in
16454
    * xmlSchemaTypeFixup(). We need to implement this when heading
16455
    * for a construction API
16456
    * TODO: !! This is needed to be checked if redefining a type !!
16457
    */
16458
0
      }
16459
      /*
16460
      * URGENT TODO (1.5)
16461
      */
16462
0
  }
16463
0
    } else {
16464
  /*
16465
  * SPEC (2) "If the {base type definition} is a simple type definition,
16466
  * then all of the following must be true:"
16467
  */
16468
0
  if (type->contentTypeDef != base) {
16469
      /*
16470
      * SPEC (2.1) "The {content type} must be the same simple type
16471
      * definition."
16472
      */
16473
0
      xmlSchemaPCustomErr(ctxt,
16474
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16475
0
    WXS_BASIC_CAST type, NULL,
16476
0
    "The content type must be the simple base type", NULL);
16477
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16478
0
  }
16479
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16480
      /*
16481
      * SPEC (2.2) "The {final} of the {base type definition} must not
16482
      * contain extension"
16483
      * NOTE that this is the same as (1.1).
16484
      */
16485
0
      xmlSchemaPCustomErr(ctxt,
16486
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16487
0
    WXS_BASIC_CAST type, NULL,
16488
0
    "The 'final' of the base type definition "
16489
0
    "contains 'extension'", NULL);
16490
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16491
0
  }
16492
0
    }
16493
0
    return (0);
16494
0
}
16495
16496
/**
16497
 * xmlSchemaCheckDerivationOKRestriction:
16498
 * @ctxt:  the schema parser context
16499
 * @type:  the complex type definition
16500
 *
16501
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16502
 * Schema Component Constraint:
16503
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16504
 *
16505
 * STATUS:
16506
 *   missing:
16507
 *     (5.4.2) ???
16508
 *
16509
 * ATTENTION:
16510
 * In XML Schema 1.1 this will be:
16511
 * Validation Rule: Checking complex type subsumption
16512
 *
16513
 * Returns 0 if the constraints are satisfied, a positive
16514
 * error code if not and -1 if an internal error occurred.
16515
 */
16516
static int
16517
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16518
              xmlSchemaTypePtr type)
16519
0
{
16520
0
    xmlSchemaTypePtr base;
16521
16522
    /*
16523
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16524
    * temporarily only.
16525
    */
16526
0
    base = type->baseType;
16527
0
    if (! WXS_IS_COMPLEX(base)) {
16528
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16529
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16530
0
      type->node, WXS_BASIC_CAST type,
16531
0
      "The base type must be a complex type", NULL, NULL);
16532
0
  return(ctxt->err);
16533
0
    }
16534
0
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16535
  /*
16536
  * SPEC (1) "The {base type definition} must be a complex type
16537
  * definition whose {final} does not contain restriction."
16538
  */
16539
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16540
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16541
0
      type->node, WXS_BASIC_CAST type,
16542
0
      "The 'final' of the base type definition "
16543
0
      "contains 'restriction'", NULL, NULL);
16544
0
  return (ctxt->err);
16545
0
    }
16546
    /*
16547
    * SPEC (2), (3) and (4)
16548
    * Those are handled in a separate function, since the
16549
    * same constraints are needed for redefinition of
16550
    * attribute groups as well.
16551
    */
16552
0
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16553
0
  XML_SCHEMA_ACTION_DERIVE,
16554
0
  WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16555
0
  type->attrUses, base->attrUses,
16556
0
  type->attributeWildcard,
16557
0
  base->attributeWildcard) == -1)
16558
0
    {
16559
0
  return(-1);
16560
0
    }
16561
    /*
16562
    * SPEC (5) "One of the following must be true:"
16563
    */
16564
0
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16565
  /*
16566
  * SPEC (5.1) "The {base type definition} must be the
16567
  * `ur-type definition`."
16568
  * PASS
16569
  */
16570
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16571
0
      (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16572
  /*
16573
  * SPEC (5.2.1) "The {content type} of the complex type definition
16574
  * must be a simple type definition"
16575
  *
16576
  * SPEC (5.2.2) "One of the following must be true:"
16577
  */
16578
0
  if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16579
0
      (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16580
0
  {
16581
0
      int err;
16582
      /*
16583
      * SPEC (5.2.2.1) "The {content type} of the {base type
16584
      * definition} must be a simple type definition from which
16585
      * the {content type} is validly derived given the empty
16586
      * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16587
      *
16588
      * ATTENTION TODO: This seems not needed if the type implicitly
16589
      * derived from the base type.
16590
      *
16591
      */
16592
0
      err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16593
0
    type->contentTypeDef, base->contentTypeDef, 0);
16594
0
      if (err != 0) {
16595
0
    xmlChar *strA = NULL, *strB = NULL;
16596
16597
0
    if (err == -1)
16598
0
        return(-1);
16599
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16600
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16601
0
        NULL, WXS_BASIC_CAST type,
16602
0
        "The {content type} %s is not validly derived from the "
16603
0
        "base type's {content type} %s",
16604
0
        xmlSchemaGetComponentDesignation(&strA,
16605
0
      type->contentTypeDef),
16606
0
        xmlSchemaGetComponentDesignation(&strB,
16607
0
      base->contentTypeDef));
16608
0
    FREE_AND_NULL(strA);
16609
0
    FREE_AND_NULL(strB);
16610
0
    return(ctxt->err);
16611
0
      }
16612
0
  } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16613
0
      (xmlSchemaIsParticleEmptiable(
16614
0
    (xmlSchemaParticlePtr) base->subtypes))) {
16615
      /*
16616
      * SPEC (5.2.2.2) "The {base type definition} must be mixed
16617
      * and have a particle which is `emptiable` as defined in
16618
      * Particle Emptiable ($3.9.6)."
16619
      * PASS
16620
      */
16621
0
  } else {
16622
0
      xmlSchemaPCustomErr(ctxt,
16623
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16624
0
    WXS_BASIC_CAST type, NULL,
16625
0
    "The content type of the base type must be either "
16626
0
    "a simple type or 'mixed' and an emptiable particle", NULL);
16627
0
      return (ctxt->err);
16628
0
  }
16629
0
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16630
  /*
16631
  * SPEC (5.3.1) "The {content type} of the complex type itself must
16632
  * be empty"
16633
  */
16634
0
  if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16635
      /*
16636
      * SPEC (5.3.2.1) "The {content type} of the {base type
16637
      * definition} must also be empty."
16638
      * PASS
16639
      */
16640
0
  } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16641
0
      (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16642
0
      xmlSchemaIsParticleEmptiable(
16643
0
    (xmlSchemaParticlePtr) base->subtypes)) {
16644
      /*
16645
      * SPEC (5.3.2.2) "The {content type} of the {base type
16646
      * definition} must be elementOnly or mixed and have a particle
16647
      * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16648
      * PASS
16649
      */
16650
0
  } else {
16651
0
      xmlSchemaPCustomErr(ctxt,
16652
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16653
0
    WXS_BASIC_CAST type, NULL,
16654
0
    "The content type of the base type must be either "
16655
0
    "empty or 'mixed' (or 'elements-only') and an emptiable "
16656
0
    "particle", NULL);
16657
0
      return (ctxt->err);
16658
0
  }
16659
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16660
0
  WXS_HAS_MIXED_CONTENT(type)) {
16661
  /*
16662
  * SPEC (5.4.1.1) "The {content type} of the complex type definition
16663
  * itself must be element-only"
16664
  */
16665
0
  if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16666
      /*
16667
      * SPEC (5.4.1.2) "The {content type} of the complex type
16668
      * definition itself and of the {base type definition} must be
16669
      * mixed"
16670
      */
16671
0
      xmlSchemaPCustomErr(ctxt,
16672
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16673
0
    WXS_BASIC_CAST type, NULL,
16674
0
    "If the content type is 'mixed', then the content type of the "
16675
0
    "base type must also be 'mixed'", NULL);
16676
0
      return (ctxt->err);
16677
0
  }
16678
  /*
16679
  * SPEC (5.4.2) "The particle of the complex type definition itself
16680
  * must be a `valid restriction` of the particle of the {content
16681
  * type} of the {base type definition} as defined in Particle Valid
16682
  * (Restriction) ($3.9.6).
16683
  *
16684
  * URGENT TODO: (5.4.2)
16685
  */
16686
0
    } else {
16687
0
  xmlSchemaPCustomErr(ctxt,
16688
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16689
0
      WXS_BASIC_CAST type, NULL,
16690
0
      "The type is not a valid restriction of its base type", NULL);
16691
0
  return (ctxt->err);
16692
0
    }
16693
0
    return (0);
16694
0
}
16695
16696
/**
16697
 * xmlSchemaCheckCTComponent:
16698
 * @ctxt:  the schema parser context
16699
 * @type:  the complex type definition
16700
 *
16701
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16702
 *
16703
 * Returns 0 if the constraints are satisfied, a positive
16704
 * error code if not and -1 if an internal error occurred.
16705
 */
16706
static int
16707
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16708
        xmlSchemaTypePtr type)
16709
0
{
16710
0
    int ret;
16711
    /*
16712
    * Complex Type Definition Properties Correct
16713
    */
16714
0
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16715
0
    if (ret != 0)
16716
0
  return (ret);
16717
0
    if (WXS_IS_EXTENSION(type))
16718
0
  ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16719
0
    else
16720
0
  ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16721
0
    return (ret);
16722
0
}
16723
16724
/**
16725
 * xmlSchemaCheckSRCCT:
16726
 * @ctxt:  the schema parser context
16727
 * @type:  the complex type definition
16728
 *
16729
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16730
 * Schema Representation Constraint:
16731
 * Complex Type Definition Representation OK (src-ct)
16732
 *
16733
 * Returns 0 if the constraints are satisfied, a positive
16734
 * error code if not and -1 if an internal error occurred.
16735
 */
16736
static int
16737
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16738
        xmlSchemaTypePtr type)
16739
0
{
16740
0
    xmlSchemaTypePtr base;
16741
0
    int ret = 0;
16742
16743
    /*
16744
    * TODO: Adjust the error codes here, as I used
16745
    * XML_SCHEMAP_SRC_CT_1 only yet.
16746
    */
16747
0
    base = type->baseType;
16748
0
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16749
  /*
16750
  * 1 If the <complexContent> alternative is chosen, the type definition
16751
  * `resolved` to by the `actual value` of the base [attribute]
16752
  * must be a complex type definition;
16753
  */
16754
0
  if (! WXS_IS_COMPLEX(base)) {
16755
0
      xmlChar *str = NULL;
16756
0
      xmlSchemaPCustomErr(ctxt,
16757
0
    XML_SCHEMAP_SRC_CT_1,
16758
0
    WXS_BASIC_CAST type, type->node,
16759
0
    "If using <complexContent>, the base type is expected to be "
16760
0
    "a complex type. The base type '%s' is a simple type",
16761
0
    xmlSchemaFormatQName(&str, base->targetNamespace,
16762
0
    base->name));
16763
0
      FREE_AND_NULL(str)
16764
0
      return (XML_SCHEMAP_SRC_CT_1);
16765
0
  }
16766
0
    } else {
16767
  /*
16768
  * SPEC
16769
  * 2 If the <simpleContent> alternative is chosen, all of the
16770
  * following must be true:
16771
  * 2.1 The type definition `resolved` to by the `actual value` of the
16772
  * base [attribute] must be one of the following:
16773
  */
16774
0
  if (WXS_IS_SIMPLE(base)) {
16775
0
      if (WXS_IS_EXTENSION(type) == 0) {
16776
0
    xmlChar *str = NULL;
16777
    /*
16778
    * 2.1.3 only if the <extension> alternative is also
16779
    * chosen, a simple type definition.
16780
    */
16781
    /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16782
0
    xmlSchemaPCustomErr(ctxt,
16783
0
        XML_SCHEMAP_SRC_CT_1,
16784
0
        WXS_BASIC_CAST type, NULL,
16785
0
        "If using <simpleContent> and <restriction>, the base "
16786
0
        "type must be a complex type. The base type '%s' is "
16787
0
        "a simple type",
16788
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16789
0
      base->name));
16790
0
    FREE_AND_NULL(str)
16791
0
    return (XML_SCHEMAP_SRC_CT_1);
16792
0
      }
16793
0
  } else {
16794
      /* Base type is a complex type. */
16795
0
      if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16796
0
    (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16797
    /*
16798
    * 2.1.1 a complex type definition whose {content type} is a
16799
    * simple type definition;
16800
    * PASS
16801
    */
16802
0
    if (base->contentTypeDef == NULL) {
16803
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16804
0
      WXS_BASIC_CAST type, NULL,
16805
0
      "Internal error: xmlSchemaCheckSRCCT, "
16806
0
      "'%s', base type has no content type",
16807
0
      type->name);
16808
0
        return (-1);
16809
0
    }
16810
0
      } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16811
0
    (WXS_IS_RESTRICTION(type))) {
16812
16813
    /*
16814
    * 2.1.2 only if the <restriction> alternative is also
16815
    * chosen, a complex type definition whose {content type}
16816
    * is mixed and a particle emptiable.
16817
    */
16818
0
    if (! xmlSchemaIsParticleEmptiable(
16819
0
        (xmlSchemaParticlePtr) base->subtypes)) {
16820
0
        ret = XML_SCHEMAP_SRC_CT_1;
16821
0
    } else
16822
        /*
16823
        * Attention: at this point the <simpleType> child is in
16824
        * ->contentTypeDef (put there during parsing).
16825
        */
16826
0
        if (type->contentTypeDef == NULL) {
16827
0
        xmlChar *str = NULL;
16828
        /*
16829
        * 2.2 If clause 2.1.2 above is satisfied, then there
16830
        * must be a <simpleType> among the [children] of
16831
        * <restriction>.
16832
        */
16833
        /* TODO: Change error code to ..._SRC_CT_2_2. */
16834
0
        xmlSchemaPCustomErr(ctxt,
16835
0
      XML_SCHEMAP_SRC_CT_1,
16836
0
      WXS_BASIC_CAST type, NULL,
16837
0
      "A <simpleType> is expected among the children "
16838
0
      "of <restriction>, if <simpleContent> is used and "
16839
0
      "the base type '%s' is a complex type",
16840
0
      xmlSchemaFormatQName(&str, base->targetNamespace,
16841
0
      base->name));
16842
0
        FREE_AND_NULL(str)
16843
0
        return (XML_SCHEMAP_SRC_CT_1);
16844
0
    }
16845
0
      } else {
16846
0
    ret = XML_SCHEMAP_SRC_CT_1;
16847
0
      }
16848
0
  }
16849
0
  if (ret > 0) {
16850
0
      xmlChar *str = NULL;
16851
0
      if (WXS_IS_RESTRICTION(type)) {
16852
0
    xmlSchemaPCustomErr(ctxt,
16853
0
        XML_SCHEMAP_SRC_CT_1,
16854
0
        WXS_BASIC_CAST type, NULL,
16855
0
        "If <simpleContent> and <restriction> is used, the "
16856
0
        "base type must be a simple type or a complex type with "
16857
0
        "mixed content and particle emptiable. The base type "
16858
0
        "'%s' is none of those",
16859
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16860
0
        base->name));
16861
0
      } else {
16862
0
    xmlSchemaPCustomErr(ctxt,
16863
0
        XML_SCHEMAP_SRC_CT_1,
16864
0
        WXS_BASIC_CAST type, NULL,
16865
0
        "If <simpleContent> and <extension> is used, the "
16866
0
        "base type must be a simple type. The base type '%s' "
16867
0
        "is a complex type",
16868
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16869
0
        base->name));
16870
0
      }
16871
0
      FREE_AND_NULL(str)
16872
0
  }
16873
0
    }
16874
    /*
16875
    * SPEC (3) "The corresponding complex type definition component must
16876
    * satisfy the conditions set out in Constraints on Complex Type
16877
    * Definition Schema Components ($3.4.6);"
16878
    * NOTE (3) will be done in xmlSchemaTypeFixup().
16879
    */
16880
    /*
16881
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16882
    * above for {attribute wildcard} is satisfied, the intensional
16883
    * intersection must be expressible, as defined in Attribute Wildcard
16884
    * Intersection ($3.10.6).
16885
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16886
    */
16887
0
    return (ret);
16888
0
}
16889
16890
#ifdef ENABLE_PARTICLE_RESTRICTION
16891
/**
16892
 * xmlSchemaCheckParticleRangeOK:
16893
 * @ctxt:  the schema parser context
16894
 * @type:  the complex type definition
16895
 *
16896
 * (3.9.6) Constraints on Particle Schema Components
16897
 * Schema Component Constraint:
16898
 * Occurrence Range OK (range-ok)
16899
 *
16900
 * STATUS: complete
16901
 *
16902
 * Returns 0 if the constraints are satisfied, a positive
16903
 * error code if not and -1 if an internal error occurred.
16904
 */
16905
static int
16906
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16907
            int bmin, int bmax)
16908
{
16909
    if (rmin < bmin)
16910
  return (1);
16911
    if ((bmax != UNBOUNDED) &&
16912
  (rmax > bmax))
16913
  return (1);
16914
    return (0);
16915
}
16916
16917
/**
16918
 * xmlSchemaCheckRCaseNameAndTypeOK:
16919
 * @ctxt:  the schema parser context
16920
 * @r: the restricting element declaration particle
16921
 * @b: the base element declaration particle
16922
 *
16923
 * (3.9.6) Constraints on Particle Schema Components
16924
 * Schema Component Constraint:
16925
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16926
 * (rcase-NameAndTypeOK)
16927
 *
16928
 * STATUS:
16929
 *   MISSING (3.2.3)
16930
 *   CLARIFY: (3.2.2)
16931
 *
16932
 * Returns 0 if the constraints are satisfied, a positive
16933
 * error code if not and -1 if an internal error occurred.
16934
 */
16935
static int
16936
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16937
         xmlSchemaParticlePtr r,
16938
         xmlSchemaParticlePtr b)
16939
{
16940
    xmlSchemaElementPtr elemR, elemB;
16941
16942
    /* TODO: Error codes (rcase-NameAndTypeOK). */
16943
    elemR = (xmlSchemaElementPtr) r->children;
16944
    elemB = (xmlSchemaElementPtr) b->children;
16945
    /*
16946
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
16947
    * the same."
16948
    */
16949
    if ((elemR != elemB) &&
16950
  ((! xmlStrEqual(elemR->name, elemB->name)) ||
16951
  (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16952
  return (1);
16953
    /*
16954
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16955
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16956
    */
16957
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16958
      b->minOccurs, b->maxOccurs) != 0)
16959
  return (1);
16960
    /*
16961
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16962
    * {scope} are global."
16963
    */
16964
    if (elemR == elemB)
16965
  return (0);
16966
    /*
16967
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16968
    */
16969
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16970
  (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16971
   return (1);
16972
    /*
16973
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16974
    * or is not fixed, or R's declaration's {value constraint} is fixed
16975
    * with the same value."
16976
    */
16977
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16978
  ((elemR->value == NULL) ||
16979
   ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16980
   /* TODO: Equality of the initial value or normalized or canonical? */
16981
   (! xmlStrEqual(elemR->value, elemB->value))))
16982
   return (1);
16983
    /*
16984
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16985
    * definitions} is a subset of B's declaration's {identity-constraint
16986
    * definitions}, if any."
16987
    */
16988
    if (elemB->idcs != NULL) {
16989
  /* TODO */
16990
    }
16991
    /*
16992
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16993
    * superset of B's declaration's {disallowed substitutions}."
16994
    */
16995
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16996
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16997
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16998
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16999
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
17000
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
17001
   return (1);
17002
    /*
17003
    * SPEC (3.2.5) "R's {type definition} is validly derived given
17004
    * {extension, list, union} from B's {type definition}"
17005
    *
17006
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
17007
    * set, if the corresponding constraints handle "restriction" and
17008
    * "extension" only?
17009
    *
17010
    */
17011
    {
17012
  int set = 0;
17013
17014
  set |= SUBSET_EXTENSION;
17015
  set |= SUBSET_LIST;
17016
  set |= SUBSET_UNION;
17017
  if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
17018
      elemB->subtypes, set) != 0)
17019
      return (1);
17020
    }
17021
    return (0);
17022
}
17023
17024
/**
17025
 * xmlSchemaCheckRCaseNSCompat:
17026
 * @ctxt:  the schema parser context
17027
 * @r: the restricting element declaration particle
17028
 * @b: the base wildcard particle
17029
 *
17030
 * (3.9.6) Constraints on Particle Schema Components
17031
 * Schema Component Constraint:
17032
 * Particle Derivation OK (Elt:Any -- NSCompat)
17033
 * (rcase-NSCompat)
17034
 *
17035
 * STATUS: complete
17036
 *
17037
 * Returns 0 if the constraints are satisfied, a positive
17038
 * error code if not and -1 if an internal error occurred.
17039
 */
17040
static int
17041
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
17042
          xmlSchemaParticlePtr r,
17043
          xmlSchemaParticlePtr b)
17044
{
17045
    /* TODO:Error codes (rcase-NSCompat). */
17046
    /*
17047
    * SPEC "For an element declaration particle to be a `valid restriction`
17048
    * of a wildcard particle all of the following must be true:"
17049
    *
17050
    * SPEC (1) "The element declaration's {target namespace} is `valid`
17051
    * with respect to the wildcard's {namespace constraint} as defined by
17052
    * Wildcard allows Namespace Name ($3.10.4)."
17053
    */
17054
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
17055
  ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
17056
  return (1);
17057
    /*
17058
    * SPEC (2) "R's occurrence range is a valid restriction of B's
17059
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17060
    */
17061
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17062
      b->minOccurs, b->maxOccurs) != 0)
17063
  return (1);
17064
17065
    return (0);
17066
}
17067
17068
/**
17069
 * xmlSchemaCheckRCaseRecurseAsIfGroup:
17070
 * @ctxt:  the schema parser context
17071
 * @r: the restricting element declaration particle
17072
 * @b: the base model group particle
17073
 *
17074
 * (3.9.6) Constraints on Particle Schema Components
17075
 * Schema Component Constraint:
17076
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
17077
 * (rcase-RecurseAsIfGroup)
17078
 *
17079
 * STATUS: TODO
17080
 *
17081
 * Returns 0 if the constraints are satisfied, a positive
17082
 * error code if not and -1 if an internal error occurred.
17083
 */
17084
static int
17085
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
17086
            xmlSchemaParticlePtr r,
17087
            xmlSchemaParticlePtr b)
17088
{
17089
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
17090
    TODO
17091
    return (0);
17092
}
17093
17094
/**
17095
 * xmlSchemaCheckRCaseNSSubset:
17096
 * @ctxt:  the schema parser context
17097
 * @r: the restricting wildcard particle
17098
 * @b: the base wildcard particle
17099
 *
17100
 * (3.9.6) Constraints on Particle Schema Components
17101
 * Schema Component Constraint:
17102
 * Particle Derivation OK (Any:Any -- NSSubset)
17103
 * (rcase-NSSubset)
17104
 *
17105
 * STATUS: complete
17106
 *
17107
 * Returns 0 if the constraints are satisfied, a positive
17108
 * error code if not and -1 if an internal error occurred.
17109
 */
17110
static int
17111
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
17112
            xmlSchemaParticlePtr r,
17113
            xmlSchemaParticlePtr b,
17114
            int isAnyTypeBase)
17115
{
17116
    /* TODO: Error codes (rcase-NSSubset). */
17117
    /*
17118
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17119
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17120
    */
17121
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17122
      b->minOccurs, b->maxOccurs))
17123
  return (1);
17124
    /*
17125
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
17126
    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17127
    */
17128
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
17129
  (xmlSchemaWildcardPtr) b->children))
17130
  return (1);
17131
    /*
17132
    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17133
    * definition`, R's {process contents} must be identical to or stronger
17134
    * than B's {process contents}, where strict is stronger than lax is
17135
    * stronger than skip."
17136
    */
17137
    if (! isAnyTypeBase) {
17138
  if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17139
      ((xmlSchemaWildcardPtr) b->children)->processContents)
17140
      return (1);
17141
    }
17142
17143
    return (0);
17144
}
17145
17146
/**
17147
 * xmlSchemaCheckCOSParticleRestrict:
17148
 * @ctxt:  the schema parser context
17149
 * @type:  the complex type definition
17150
 *
17151
 * (3.9.6) Constraints on Particle Schema Components
17152
 * Schema Component Constraint:
17153
 * Particle Valid (Restriction) (cos-particle-restrict)
17154
 *
17155
 * STATUS: TODO
17156
 *
17157
 * Returns 0 if the constraints are satisfied, a positive
17158
 * error code if not and -1 if an internal error occurred.
17159
 */
17160
static int
17161
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17162
          xmlSchemaParticlePtr r,
17163
          xmlSchemaParticlePtr b)
17164
{
17165
    int ret = 0;
17166
17167
    /*part = WXS_TYPE_PARTICLE(type);
17168
    basePart = WXS_TYPE_PARTICLE(base);
17169
    */
17170
17171
    TODO
17172
17173
    /*
17174
    * SPEC (1) "They are the same particle."
17175
    */
17176
    if (r == b)
17177
  return (0);
17178
17179
17180
    return (0);
17181
}
17182
17183
#if 0
17184
/**
17185
 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17186
 * @ctxt:  the schema parser context
17187
 * @r: the model group particle
17188
 * @b: the base wildcard particle
17189
 *
17190
 * (3.9.6) Constraints on Particle Schema Components
17191
 * Schema Component Constraint:
17192
 * Particle Derivation OK (All/Choice/Sequence:Any --
17193
 *                         NSRecurseCheckCardinality)
17194
 * (rcase-NSRecurseCheckCardinality)
17195
 *
17196
 * STATUS: TODO: subst-groups
17197
 *
17198
 * Returns 0 if the constraints are satisfied, a positive
17199
 * error code if not and -1 if an internal error occurred.
17200
 */
17201
static int
17202
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17203
               xmlSchemaParticlePtr r,
17204
               xmlSchemaParticlePtr b)
17205
{
17206
    xmlSchemaParticlePtr part;
17207
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17208
    if ((r->children == NULL) || (r->children->children == NULL))
17209
  return (-1);
17210
    /*
17211
    * SPEC "For a group particle to be a `valid restriction` of a
17212
    * wildcard particle..."
17213
    *
17214
    * SPEC (1) "Every member of the {particles} of the group is a `valid
17215
    * restriction` of the wildcard as defined by
17216
    * Particle Valid (Restriction) ($3.9.6)."
17217
    */
17218
    part = (xmlSchemaParticlePtr) r->children->children;
17219
    do {
17220
  if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17221
      return (1);
17222
  part = (xmlSchemaParticlePtr) part->next;
17223
    } while (part != NULL);
17224
    /*
17225
    * SPEC (2) "The effective total range of the group [...] is a
17226
    * valid restriction of B's occurrence range as defined by
17227
    * Occurrence Range OK ($3.9.6)."
17228
    */
17229
    if (xmlSchemaCheckParticleRangeOK(
17230
      xmlSchemaGetParticleTotalRangeMin(r),
17231
      xmlSchemaGetParticleTotalRangeMax(r),
17232
      b->minOccurs, b->maxOccurs) != 0)
17233
  return (1);
17234
    return (0);
17235
}
17236
#endif
17237
17238
/**
17239
 * xmlSchemaCheckRCaseRecurse:
17240
 * @ctxt:  the schema parser context
17241
 * @r: the <all> or <sequence> model group particle
17242
 * @b: the base <all> or <sequence> model group particle
17243
 *
17244
 * (3.9.6) Constraints on Particle Schema Components
17245
 * Schema Component Constraint:
17246
 * Particle Derivation OK (All:All,Sequence:Sequence --
17247
                           Recurse)
17248
 * (rcase-Recurse)
17249
 *
17250
 * STATUS:  ?
17251
 * TODO: subst-groups
17252
 *
17253
 * Returns 0 if the constraints are satisfied, a positive
17254
 * error code if not and -1 if an internal error occurred.
17255
 */
17256
static int
17257
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17258
         xmlSchemaParticlePtr r,
17259
         xmlSchemaParticlePtr b)
17260
{
17261
    /* xmlSchemaParticlePtr part; */
17262
    /* TODO: Error codes (rcase-Recurse). */
17263
    if ((r->children == NULL) || (b->children == NULL) ||
17264
  (r->children->type != b->children->type))
17265
  return (-1);
17266
    /*
17267
    * SPEC "For an all or sequence group particle to be a `valid
17268
    * restriction` of another group particle with the same {compositor}..."
17269
    *
17270
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17271
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17272
    */
17273
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17274
      b->minOccurs, b->maxOccurs))
17275
  return (1);
17276
17277
17278
    return (0);
17279
}
17280
17281
#endif
17282
17283
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17284
0
    xmlSchemaPCustomErrExt(pctxt,      \
17285
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17286
0
  WXS_BASIC_CAST fac1, fac1->node, \
17287
0
  "It is an error for both '%s' and '%s' to be specified on the "\
17288
0
  "same type definition", \
17289
0
  BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17290
0
  BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17291
17292
#define FACET_RESTR_ERR(fac1, msg) \
17293
0
    xmlSchemaPCustomErr(pctxt,      \
17294
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17295
0
  WXS_BASIC_CAST fac1, fac1->node, \
17296
0
  msg, NULL);
17297
17298
#define FACET_RESTR_FIXED_ERR(fac) \
17299
0
    xmlSchemaPCustomErr(pctxt, \
17300
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17301
0
  WXS_BASIC_CAST fac, fac->node, \
17302
0
  "The base type's facet is 'fixed', thus the value must not " \
17303
0
  "differ", NULL);
17304
17305
static void
17306
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17307
      xmlSchemaFacetPtr facet1,
17308
      xmlSchemaFacetPtr facet2,
17309
      int lessGreater,
17310
      int orEqual,
17311
      int ofBase)
17312
0
{
17313
0
    xmlChar *msg = NULL;
17314
17315
0
    msg = xmlStrdup(BAD_CAST "'");
17316
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17317
0
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
17318
0
    if (lessGreater == 0)
17319
0
  msg = xmlStrcat(msg, BAD_CAST " equal to");
17320
0
    if (lessGreater == 1)
17321
0
  msg = xmlStrcat(msg, BAD_CAST " greater than");
17322
0
    else
17323
0
  msg = xmlStrcat(msg, BAD_CAST " less than");
17324
17325
0
    if (orEqual)
17326
0
  msg = xmlStrcat(msg, BAD_CAST " or equal to");
17327
0
    msg = xmlStrcat(msg, BAD_CAST " '");
17328
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17329
0
    if (ofBase)
17330
0
  msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17331
0
    else
17332
0
  msg = xmlStrcat(msg, BAD_CAST "'");
17333
17334
0
    xmlSchemaPCustomErr(pctxt,
17335
0
  XML_SCHEMAP_INVALID_FACET_VALUE,
17336
0
  WXS_BASIC_CAST facet1, NULL,
17337
0
  (const char *) msg, NULL);
17338
17339
0
    if (msg != NULL)
17340
0
  xmlFree(msg);
17341
0
}
17342
17343
/*
17344
* xmlSchemaDeriveAndValidateFacets:
17345
*
17346
* Schema Component Constraint: Simple Type Restriction (Facets)
17347
* (st-restrict-facets)
17348
*/
17349
static int
17350
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17351
         xmlSchemaTypePtr type)
17352
0
{
17353
0
    xmlSchemaTypePtr base = type->baseType;
17354
0
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
17355
0
    xmlSchemaFacetPtr facet, bfacet,
17356
0
  flength = NULL, ftotdig = NULL, ffracdig = NULL,
17357
0
  fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17358
0
  fmininc = NULL, fmaxinc = NULL,
17359
0
  fminexc = NULL, fmaxexc = NULL,
17360
0
  bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17361
0
  bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17362
0
  bfmininc = NULL, bfmaxinc = NULL,
17363
0
  bfminexc = NULL, bfmaxexc = NULL;
17364
0
    int res; /* err = 0, fixedErr; */
17365
17366
    /*
17367
    * SPEC st-restrict-facets 1:
17368
    * "The {variety} of R is the same as that of B."
17369
    */
17370
    /*
17371
    * SPEC st-restrict-facets 2:
17372
    * "If {variety} is atomic, the {primitive type definition}
17373
    * of R is the same as that of B."
17374
    *
17375
    * NOTE: we leave 1 & 2 out for now, since this will be
17376
    * satisfied by the derivation process.
17377
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
17378
    */
17379
    /*
17380
    * SPEC st-restrict-facets 3:
17381
    * "The {facets} of R are the union of S and the {facets}
17382
    * of B, eliminating duplicates. To eliminate duplicates,
17383
    * when a facet of the same kind occurs in both S and the
17384
    * {facets} of B, the one in the {facets} of B is not
17385
    * included, with the exception of enumeration and pattern
17386
    * facets, for which multiple occurrences with distinct values
17387
    * are allowed."
17388
    */
17389
17390
0
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
17391
0
  return (0);
17392
17393
0
    last = type->facetSet;
17394
0
    if (last != NULL)
17395
0
  while (last->next != NULL)
17396
0
      last = last->next;
17397
17398
0
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17399
0
  facet = cur->facet;
17400
0
  switch (facet->type) {
17401
0
      case XML_SCHEMA_FACET_LENGTH:
17402
0
    flength = facet; break;
17403
0
      case XML_SCHEMA_FACET_MINLENGTH:
17404
0
    fminlen = facet; break;
17405
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17406
0
    fmininc = facet; break;
17407
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17408
0
    fminexc = facet; break;
17409
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17410
0
    fmaxlen = facet; break;
17411
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17412
0
    fmaxinc = facet; break;
17413
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17414
0
    fmaxexc = facet; break;
17415
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17416
0
    ftotdig = facet; break;
17417
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17418
0
    ffracdig = facet; break;
17419
0
      default:
17420
0
    break;
17421
0
  }
17422
0
    }
17423
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17424
0
  facet = cur->facet;
17425
0
  switch (facet->type) {
17426
0
      case XML_SCHEMA_FACET_LENGTH:
17427
0
    bflength = facet; break;
17428
0
      case XML_SCHEMA_FACET_MINLENGTH:
17429
0
    bfminlen = facet; break;
17430
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17431
0
    bfmininc = facet; break;
17432
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17433
0
    bfminexc = facet; break;
17434
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17435
0
    bfmaxlen = facet; break;
17436
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17437
0
    bfmaxinc = facet; break;
17438
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17439
0
    bfmaxexc = facet; break;
17440
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17441
0
    bftotdig = facet; break;
17442
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17443
0
    bffracdig = facet; break;
17444
0
      default:
17445
0
    break;
17446
0
  }
17447
0
    }
17448
    /*
17449
    * length and minLength or maxLength (2.2) + (3.2)
17450
    */
17451
0
    if (flength && (fminlen || fmaxlen)) {
17452
0
  FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17453
0
      "either of 'minLength' or 'maxLength' to be specified on "
17454
0
      "the same type definition")
17455
0
    }
17456
    /*
17457
    * Mutual exclusions in the same derivation step.
17458
    */
17459
0
    if ((fmaxinc) && (fmaxexc)) {
17460
  /*
17461
  * SCC "maxInclusive and maxExclusive"
17462
  */
17463
0
  FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17464
0
    }
17465
0
    if ((fmininc) && (fminexc)) {
17466
  /*
17467
  * SCC "minInclusive and minExclusive"
17468
  */
17469
0
  FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17470
0
    }
17471
17472
0
    if (flength && bflength) {
17473
  /*
17474
  * SCC "length valid restriction"
17475
  * The values have to be equal.
17476
  */
17477
0
  res = xmlSchemaCompareValues(flength->val, bflength->val);
17478
0
  if (res == -2)
17479
0
      goto internal_error;
17480
0
  if (res != 0)
17481
0
      xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17482
0
  if ((res != 0) && (bflength->fixed)) {
17483
0
      FACET_RESTR_FIXED_ERR(flength)
17484
0
  }
17485
17486
0
    }
17487
0
    if (fminlen && bfminlen) {
17488
  /*
17489
  * SCC "minLength valid restriction"
17490
  * minLength >= BASE minLength
17491
  */
17492
0
  res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17493
0
  if (res == -2)
17494
0
      goto internal_error;
17495
0
  if (res == -1)
17496
0
      xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17497
0
  if ((res != 0) && (bfminlen->fixed)) {
17498
0
      FACET_RESTR_FIXED_ERR(fminlen)
17499
0
  }
17500
0
    }
17501
0
    if (fmaxlen && bfmaxlen) {
17502
  /*
17503
  * SCC "maxLength valid restriction"
17504
  * maxLength <= BASE minLength
17505
  */
17506
0
  res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17507
0
  if (res == -2)
17508
0
      goto internal_error;
17509
0
  if (res == 1)
17510
0
      xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17511
0
  if ((res != 0) && (bfmaxlen->fixed)) {
17512
0
      FACET_RESTR_FIXED_ERR(fmaxlen)
17513
0
  }
17514
0
    }
17515
    /*
17516
    * SCC "length and minLength or maxLength"
17517
    */
17518
0
    if (! flength)
17519
0
  flength = bflength;
17520
0
    if (flength) {
17521
0
  if (! fminlen)
17522
0
      fminlen = bfminlen;
17523
0
  if (fminlen) {
17524
      /* (1.1) length >= minLength */
17525
0
      res = xmlSchemaCompareValues(flength->val, fminlen->val);
17526
0
      if (res == -2)
17527
0
    goto internal_error;
17528
0
      if (res == -1)
17529
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17530
0
  }
17531
0
  if (! fmaxlen)
17532
0
      fmaxlen = bfmaxlen;
17533
0
  if (fmaxlen) {
17534
      /* (2.1) length <= maxLength */
17535
0
      res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17536
0
      if (res == -2)
17537
0
    goto internal_error;
17538
0
      if (res == 1)
17539
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17540
0
  }
17541
0
    }
17542
0
    if (fmaxinc) {
17543
  /*
17544
  * "maxInclusive"
17545
  */
17546
0
  if (fmininc) {
17547
      /* SCC "maxInclusive >= minInclusive" */
17548
0
      res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17549
0
      if (res == -2)
17550
0
    goto internal_error;
17551
0
      if (res == -1) {
17552
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17553
0
      }
17554
0
  }
17555
  /*
17556
  * SCC "maxInclusive valid restriction"
17557
  */
17558
0
  if (bfmaxinc) {
17559
      /* maxInclusive <= BASE maxInclusive */
17560
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17561
0
      if (res == -2)
17562
0
    goto internal_error;
17563
0
      if (res == 1)
17564
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17565
0
      if ((res != 0) && (bfmaxinc->fixed)) {
17566
0
    FACET_RESTR_FIXED_ERR(fmaxinc)
17567
0
      }
17568
0
  }
17569
0
  if (bfmaxexc) {
17570
      /* maxInclusive < BASE maxExclusive */
17571
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17572
0
      if (res == -2)
17573
0
    goto internal_error;
17574
0
      if (res != -1) {
17575
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17576
0
      }
17577
0
  }
17578
0
  if (bfmininc) {
17579
      /* maxInclusive >= BASE minInclusive */
17580
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17581
0
      if (res == -2)
17582
0
    goto internal_error;
17583
0
      if (res == -1) {
17584
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17585
0
      }
17586
0
  }
17587
0
  if (bfminexc) {
17588
      /* maxInclusive > BASE minExclusive */
17589
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17590
0
      if (res == -2)
17591
0
    goto internal_error;
17592
0
      if (res != 1) {
17593
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17594
0
      }
17595
0
  }
17596
0
    }
17597
0
    if (fmaxexc) {
17598
  /*
17599
  * "maxExclusive >= minExclusive"
17600
  */
17601
0
  if (fminexc) {
17602
0
      res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17603
0
      if (res == -2)
17604
0
    goto internal_error;
17605
0
      if (res == -1) {
17606
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17607
0
      }
17608
0
  }
17609
  /*
17610
  * "maxExclusive valid restriction"
17611
  */
17612
0
  if (bfmaxexc) {
17613
      /* maxExclusive <= BASE maxExclusive */
17614
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17615
0
      if (res == -2)
17616
0
    goto internal_error;
17617
0
      if (res == 1) {
17618
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17619
0
      }
17620
0
      if ((res != 0) && (bfmaxexc->fixed)) {
17621
0
    FACET_RESTR_FIXED_ERR(fmaxexc)
17622
0
      }
17623
0
  }
17624
0
  if (bfmaxinc) {
17625
      /* maxExclusive <= BASE maxInclusive */
17626
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17627
0
      if (res == -2)
17628
0
    goto internal_error;
17629
0
      if (res == 1) {
17630
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17631
0
      }
17632
0
  }
17633
0
  if (bfmininc) {
17634
      /* maxExclusive > BASE minInclusive */
17635
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17636
0
      if (res == -2)
17637
0
    goto internal_error;
17638
0
      if (res != 1) {
17639
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17640
0
      }
17641
0
  }
17642
0
  if (bfminexc) {
17643
      /* maxExclusive > BASE minExclusive */
17644
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17645
0
      if (res == -2)
17646
0
    goto internal_error;
17647
0
      if (res != 1) {
17648
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17649
0
      }
17650
0
  }
17651
0
    }
17652
0
    if (fminexc) {
17653
  /*
17654
  * "minExclusive < maxInclusive"
17655
  */
17656
0
  if (fmaxinc) {
17657
0
      res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17658
0
      if (res == -2)
17659
0
    goto internal_error;
17660
0
      if (res != -1) {
17661
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17662
0
      }
17663
0
  }
17664
  /*
17665
  * "minExclusive valid restriction"
17666
  */
17667
0
  if (bfminexc) {
17668
      /* minExclusive >= BASE minExclusive */
17669
0
      res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17670
0
      if (res == -2)
17671
0
    goto internal_error;
17672
0
      if (res == -1) {
17673
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17674
0
      }
17675
0
      if ((res != 0) && (bfminexc->fixed)) {
17676
0
    FACET_RESTR_FIXED_ERR(fminexc)
17677
0
      }
17678
0
  }
17679
0
  if (bfmaxinc) {
17680
      /* minExclusive <= BASE maxInclusive */
17681
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17682
0
      if (res == -2)
17683
0
    goto internal_error;
17684
0
      if (res == 1) {
17685
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17686
0
      }
17687
0
  }
17688
0
  if (bfmininc) {
17689
      /* minExclusive >= BASE minInclusive */
17690
0
      res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17691
0
      if (res == -2)
17692
0
    goto internal_error;
17693
0
      if (res == -1) {
17694
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17695
0
      }
17696
0
  }
17697
0
  if (bfmaxexc) {
17698
      /* minExclusive < BASE maxExclusive */
17699
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17700
0
      if (res == -2)
17701
0
    goto internal_error;
17702
0
      if (res != -1) {
17703
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17704
0
      }
17705
0
  }
17706
0
    }
17707
0
    if (fmininc) {
17708
  /*
17709
  * "minInclusive < maxExclusive"
17710
  */
17711
0
  if (fmaxexc) {
17712
0
      res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17713
0
      if (res == -2)
17714
0
    goto internal_error;
17715
0
      if (res != -1) {
17716
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17717
0
      }
17718
0
  }
17719
  /*
17720
  * "minExclusive valid restriction"
17721
  */
17722
0
  if (bfmininc) {
17723
      /* minInclusive >= BASE minInclusive */
17724
0
      res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17725
0
      if (res == -2)
17726
0
    goto internal_error;
17727
0
      if (res == -1) {
17728
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17729
0
      }
17730
0
      if ((res != 0) && (bfmininc->fixed)) {
17731
0
    FACET_RESTR_FIXED_ERR(fmininc)
17732
0
      }
17733
0
  }
17734
0
  if (bfmaxinc) {
17735
      /* minInclusive <= BASE maxInclusive */
17736
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17737
0
      if (res == -2)
17738
0
    goto internal_error;
17739
0
      if (res == 1) {
17740
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17741
0
      }
17742
0
  }
17743
0
  if (bfminexc) {
17744
      /* minInclusive > BASE minExclusive */
17745
0
      res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17746
0
      if (res == -2)
17747
0
    goto internal_error;
17748
0
      if (res != 1)
17749
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17750
0
  }
17751
0
  if (bfmaxexc) {
17752
      /* minInclusive < BASE maxExclusive */
17753
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17754
0
      if (res == -2)
17755
0
    goto internal_error;
17756
0
      if (res != -1)
17757
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17758
0
  }
17759
0
    }
17760
0
    if (ftotdig && bftotdig) {
17761
  /*
17762
  * SCC " totalDigits valid restriction"
17763
  * totalDigits <= BASE totalDigits
17764
  */
17765
0
  res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17766
0
  if (res == -2)
17767
0
      goto internal_error;
17768
0
  if (res == 1)
17769
0
      xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17770
0
      -1, 1, 1);
17771
0
  if ((res != 0) && (bftotdig->fixed)) {
17772
0
      FACET_RESTR_FIXED_ERR(ftotdig)
17773
0
  }
17774
0
    }
17775
0
    if (ffracdig && bffracdig) {
17776
  /*
17777
  * SCC  "fractionDigits valid restriction"
17778
  * fractionDigits <= BASE fractionDigits
17779
  */
17780
0
  res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17781
0
  if (res == -2)
17782
0
      goto internal_error;
17783
0
  if (res == 1)
17784
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17785
0
      -1, 1, 1);
17786
0
  if ((res != 0) && (bffracdig->fixed)) {
17787
0
      FACET_RESTR_FIXED_ERR(ffracdig)
17788
0
  }
17789
0
    }
17790
    /*
17791
    * SCC "fractionDigits less than or equal to totalDigits"
17792
    */
17793
0
    if (! ftotdig)
17794
0
  ftotdig = bftotdig;
17795
0
    if (! ffracdig)
17796
0
  ffracdig = bffracdig;
17797
0
    if (ftotdig && ffracdig) {
17798
0
  res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17799
0
  if (res == -2)
17800
0
      goto internal_error;
17801
0
  if (res == 1)
17802
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17803
0
    -1, 1, 0);
17804
0
    }
17805
    /*
17806
    * *Enumerations* won' be added here, since only the first set
17807
    * of enumerations in the ancestor-or-self axis is used
17808
    * for validation, plus we need to use the base type of those
17809
    * enumerations for whitespace.
17810
    *
17811
    * *Patterns*: won't be add here, since they are ORed at
17812
    * type level and ANDed at ancestor level. This will
17813
    * happen during validation by walking the base axis
17814
    * of the type.
17815
    */
17816
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17817
0
  bfacet = cur->facet;
17818
  /*
17819
  * Special handling of enumerations and patterns.
17820
  * TODO: hmm, they should not appear in the set, so remove this.
17821
  */
17822
0
  if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17823
0
      (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17824
0
      continue;
17825
  /*
17826
  * Search for a duplicate facet in the current type.
17827
  */
17828
0
  link = type->facetSet;
17829
  /* err = 0; */
17830
  /* fixedErr = 0; */
17831
0
  while (link != NULL) {
17832
0
      facet = link->facet;
17833
0
      if (facet->type == bfacet->type) {
17834
0
    switch (facet->type) {
17835
0
        case XML_SCHEMA_FACET_WHITESPACE:
17836
      /*
17837
      * The whitespace must be stronger.
17838
      */
17839
0
      if (facet->whitespace < bfacet->whitespace) {
17840
0
          FACET_RESTR_ERR(facet,
17841
0
        "The 'whitespace' value has to be equal to "
17842
0
        "or stronger than the 'whitespace' value of "
17843
0
        "the base type")
17844
0
      }
17845
0
      if ((bfacet->fixed) &&
17846
0
          (facet->whitespace != bfacet->whitespace)) {
17847
0
          FACET_RESTR_FIXED_ERR(facet)
17848
0
      }
17849
0
      break;
17850
0
        default:
17851
0
      break;
17852
0
    }
17853
    /* Duplicate found. */
17854
0
    break;
17855
0
      }
17856
0
      link = link->next;
17857
0
  }
17858
  /*
17859
  * If no duplicate was found: add the base types's facet
17860
  * to the set.
17861
  */
17862
0
  if (link == NULL) {
17863
0
      link = (xmlSchemaFacetLinkPtr)
17864
0
    xmlMalloc(sizeof(xmlSchemaFacetLink));
17865
0
      if (link == NULL) {
17866
0
    xmlSchemaPErrMemory(pctxt,
17867
0
        "deriving facets, creating a facet link", NULL);
17868
0
    return (-1);
17869
0
      }
17870
0
      link->facet = cur->facet;
17871
0
      link->next = NULL;
17872
0
      if (last == NULL)
17873
0
    type->facetSet = link;
17874
0
      else
17875
0
    last->next = link;
17876
0
      last = link;
17877
0
  }
17878
17879
0
    }
17880
17881
0
    return (0);
17882
0
internal_error:
17883
0
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17884
0
  "an error occurred");
17885
0
    return (-1);
17886
0
}
17887
17888
static int
17889
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17890
               xmlSchemaTypePtr type)
17891
0
{
17892
0
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17893
    /*
17894
    * The actual value is then formed by replacing any union type
17895
    * definition in the `explicit members` with the members of their
17896
    * {member type definitions}, in order.
17897
    *
17898
    * TODO: There's a bug entry at
17899
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17900
    * which indicates that we'll keep the union types the future.
17901
    */
17902
0
    link = type->memberTypes;
17903
0
    while (link != NULL) {
17904
17905
0
  if (WXS_IS_TYPE_NOT_FIXED(link->type))
17906
0
      xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17907
17908
0
  if (WXS_IS_UNION(link->type)) {
17909
0
      subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17910
0
      if (subLink != NULL) {
17911
0
    link->type = subLink->type;
17912
0
    if (subLink->next != NULL) {
17913
0
        lastLink = link->next;
17914
0
        subLink = subLink->next;
17915
0
        prevLink = link;
17916
0
        while (subLink != NULL) {
17917
0
      newLink = (xmlSchemaTypeLinkPtr)
17918
0
          xmlMalloc(sizeof(xmlSchemaTypeLink));
17919
0
      if (newLink == NULL) {
17920
0
          xmlSchemaPErrMemory(pctxt, "allocating a type link",
17921
0
        NULL);
17922
0
          return (-1);
17923
0
      }
17924
0
      newLink->type = subLink->type;
17925
0
      prevLink->next = newLink;
17926
0
      prevLink = newLink;
17927
0
      newLink->next = lastLink;
17928
17929
0
      subLink = subLink->next;
17930
0
        }
17931
0
    }
17932
0
      }
17933
0
  }
17934
0
  link = link->next;
17935
0
    }
17936
0
    return (0);
17937
0
}
17938
17939
static void
17940
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17941
0
{
17942
0
    int has = 0, needVal = 0, normVal = 0;
17943
17944
0
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17945
0
    if (has) {
17946
0
  needVal = (type->baseType->flags &
17947
0
      XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17948
0
  normVal = (type->baseType->flags &
17949
0
      XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17950
0
    }
17951
0
    if (type->facets != NULL) {
17952
0
  xmlSchemaFacetPtr fac;
17953
17954
0
  for (fac = type->facets; fac != NULL; fac = fac->next) {
17955
0
      switch (fac->type) {
17956
0
    case XML_SCHEMA_FACET_WHITESPACE:
17957
0
        break;
17958
0
    case XML_SCHEMA_FACET_PATTERN:
17959
0
        normVal = 1;
17960
0
        has = 1;
17961
0
        break;
17962
0
    case XML_SCHEMA_FACET_ENUMERATION:
17963
0
        needVal = 1;
17964
0
        normVal = 1;
17965
0
        has = 1;
17966
0
        break;
17967
0
    default:
17968
0
        has = 1;
17969
0
        break;
17970
0
      }
17971
0
  }
17972
0
    }
17973
0
    if (normVal)
17974
0
  type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17975
0
    if (needVal)
17976
0
  type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17977
0
    if (has)
17978
0
  type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17979
17980
0
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17981
0
  xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17982
  /*
17983
  * OPTIMIZE VAL TODO: Some facets need a computed value.
17984
  */
17985
0
  if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17986
0
      (prim->builtInType != XML_SCHEMAS_STRING)) {
17987
0
      type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17988
0
  }
17989
0
    }
17990
0
}
17991
17992
static int
17993
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17994
0
{
17995
17996
17997
    /*
17998
    * Evaluate the whitespace-facet value.
17999
    */
18000
0
    if (WXS_IS_LIST(type)) {
18001
0
  type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18002
0
  return (0);
18003
0
    } else if (WXS_IS_UNION(type))
18004
0
  return (0);
18005
18006
0
    if (type->facetSet != NULL) {
18007
0
  xmlSchemaFacetLinkPtr lin;
18008
18009
0
  for (lin = type->facetSet; lin != NULL; lin = lin->next) {
18010
0
      if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
18011
0
    switch (lin->facet->whitespace) {
18012
0
    case XML_SCHEMAS_FACET_PRESERVE:
18013
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
18014
0
        break;
18015
0
    case XML_SCHEMAS_FACET_REPLACE:
18016
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
18017
0
        break;
18018
0
    case XML_SCHEMAS_FACET_COLLAPSE:
18019
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18020
0
        break;
18021
0
    default:
18022
0
        return (-1);
18023
0
    }
18024
0
    return (0);
18025
0
      }
18026
0
  }
18027
0
    }
18028
    /*
18029
    * For all `atomic` datatypes other than string (and types `derived`
18030
    * by `restriction` from it) the value of whiteSpace is fixed to
18031
    * collapse
18032
    */
18033
0
    {
18034
0
  xmlSchemaTypePtr anc;
18035
18036
0
  for (anc = type->baseType; anc != NULL &&
18037
0
    anc->builtInType != XML_SCHEMAS_ANYTYPE;
18038
0
    anc = anc->baseType) {
18039
18040
0
      if (anc->type == XML_SCHEMA_TYPE_BASIC) {
18041
0
    if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
18042
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
18043
18044
0
    } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
18045
0
        (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
18046
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
18047
18048
0
    } else
18049
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
18050
0
    break;
18051
0
      }
18052
0
  }
18053
0
    }
18054
0
    return (0);
18055
0
}
18056
18057
static int
18058
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
18059
        xmlSchemaTypePtr type)
18060
0
{
18061
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18062
0
  return(0);
18063
0
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
18064
0
  return(0);
18065
0
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
18066
18067
0
    if (WXS_IS_LIST(type)) {
18068
  /*
18069
  * Corresponds to <simpleType><list>...
18070
  */
18071
0
  if (type->subtypes == NULL) {
18072
      /*
18073
      * This one is really needed, so get out.
18074
      */
18075
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18076
0
    "list type has no item-type assigned");
18077
0
      return(-1);
18078
0
  }
18079
0
    } else if (WXS_IS_UNION(type)) {
18080
  /*
18081
  * Corresponds to <simpleType><union>...
18082
  */
18083
0
  if (type->memberTypes == NULL) {
18084
      /*
18085
      * This one is really needed, so get out.
18086
      */
18087
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18088
0
    "union type has no member-types assigned");
18089
0
      return(-1);
18090
0
  }
18091
0
    } else {
18092
  /*
18093
  * Corresponds to <simpleType><restriction>...
18094
  */
18095
0
  if (type->baseType == NULL) {
18096
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18097
0
    "type has no base-type assigned");
18098
0
      return(-1);
18099
0
  }
18100
0
  if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
18101
0
      if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
18102
0
    return(-1);
18103
  /*
18104
  * Variety
18105
  * If the <restriction> alternative is chosen, then the
18106
  * {variety} of the {base type definition}.
18107
  */
18108
0
  if (WXS_IS_ATOMIC(type->baseType))
18109
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
18110
0
  else if (WXS_IS_LIST(type->baseType)) {
18111
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
18112
      /*
18113
      * Inherit the itemType.
18114
      */
18115
0
      type->subtypes = type->baseType->subtypes;
18116
0
  } else if (WXS_IS_UNION(type->baseType)) {
18117
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
18118
      /*
18119
      * NOTE that we won't assign the memberTypes of the base,
18120
      * since this will make trouble when freeing them; we will
18121
      * use a lookup function to access them instead.
18122
      */
18123
0
  }
18124
0
    }
18125
0
    return(0);
18126
0
}
18127
18128
#ifdef DEBUG_TYPE
18129
static void
18130
xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
18131
           xmlSchemaTypePtr type)
18132
{
18133
    if (type->node != NULL) {
18134
        xmlGenericError(xmlGenericErrorContext,
18135
                        "Type of %s : %s:%d :", name,
18136
                        type->node->doc->URL,
18137
                        xmlGetLineNo(type->node));
18138
    } else {
18139
        xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
18140
    }
18141
    if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
18142
  switch (type->contentType) {
18143
      case XML_SCHEMA_CONTENT_SIMPLE:
18144
    xmlGenericError(xmlGenericErrorContext, "simple\n");
18145
    break;
18146
      case XML_SCHEMA_CONTENT_ELEMENTS:
18147
    xmlGenericError(xmlGenericErrorContext, "elements\n");
18148
    break;
18149
      case XML_SCHEMA_CONTENT_UNKNOWN:
18150
    xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
18151
    break;
18152
      case XML_SCHEMA_CONTENT_EMPTY:
18153
    xmlGenericError(xmlGenericErrorContext, "empty\n");
18154
    break;
18155
      case XML_SCHEMA_CONTENT_MIXED:
18156
    if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
18157
        type->subtypes))
18158
        xmlGenericError(xmlGenericErrorContext,
18159
      "mixed as emptiable particle\n");
18160
    else
18161
        xmlGenericError(xmlGenericErrorContext, "mixed\n");
18162
    break;
18163
    /* Removed, since not used. */
18164
    /*
18165
    case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18166
    xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18167
    break;
18168
    */
18169
      case XML_SCHEMA_CONTENT_BASIC:
18170
    xmlGenericError(xmlGenericErrorContext, "basic\n");
18171
    break;
18172
      default:
18173
    xmlGenericError(xmlGenericErrorContext,
18174
        "not registered !!!\n");
18175
    break;
18176
  }
18177
    }
18178
}
18179
#endif
18180
18181
/*
18182
* 3.14.6 Constraints on Simple Type Definition Schema Components
18183
*/
18184
static int
18185
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18186
         xmlSchemaTypePtr type)
18187
0
{
18188
0
    int res, olderrs = pctxt->nberrors;
18189
18190
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18191
0
  return(-1);
18192
18193
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18194
0
  return(0);
18195
18196
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18197
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18198
18199
0
    if (type->baseType == NULL) {
18200
0
  PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18201
0
      "missing baseType");
18202
0
  goto exit_failure;
18203
0
    }
18204
0
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18205
0
  xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18206
    /*
18207
    * If a member type of a union is a union itself, we need to substitute
18208
    * that member type for its member types.
18209
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18210
    * types in WXS 1.1.
18211
    */
18212
0
    if ((type->memberTypes != NULL) &&
18213
0
  (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18214
0
  return(-1);
18215
    /*
18216
    * SPEC src-simple-type 1
18217
    * "The corresponding simple type definition, if any, must satisfy
18218
    * the conditions set out in Constraints on Simple Type Definition
18219
    * Schema Components ($3.14.6)."
18220
    */
18221
    /*
18222
    * Schema Component Constraint: Simple Type Definition Properties Correct
18223
    * (st-props-correct)
18224
    */
18225
0
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18226
0
    HFAILURE HERROR
18227
    /*
18228
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18229
    * (cos-st-restricts)
18230
    */
18231
0
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18232
0
    HFAILURE HERROR
18233
    /*
18234
    * TODO: Removed the error report, since it got annoying to get an
18235
    * extra error report, if anything failed until now.
18236
    * Enable this if needed.
18237
    *
18238
    * xmlSchemaPErr(ctxt, type->node,
18239
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18240
    *    "Simple type '%s' does not satisfy the constraints "
18241
    *    "on simple type definitions.\n",
18242
    *    type->name, NULL);
18243
    */
18244
    /*
18245
    * Schema Component Constraint: Simple Type Restriction (Facets)
18246
    * (st-restrict-facets)
18247
    */
18248
0
    res = xmlSchemaCheckFacetValues(type, pctxt);
18249
0
    HFAILURE HERROR
18250
0
    if ((type->facetSet != NULL) ||
18251
0
  (type->baseType->facetSet != NULL)) {
18252
0
  res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18253
0
  HFAILURE HERROR
18254
0
    }
18255
    /*
18256
    * Whitespace value.
18257
    */
18258
0
    res = xmlSchemaTypeFixupWhitespace(type);
18259
0
    HFAILURE HERROR
18260
0
    xmlSchemaTypeFixupOptimFacets(type);
18261
18262
0
exit_error:
18263
#ifdef DEBUG_TYPE
18264
    xmlSchemaDebugFixedType(pctxt, type);
18265
#endif
18266
0
    if (olderrs != pctxt->nberrors)
18267
0
  return(pctxt->err);
18268
0
    return(0);
18269
18270
0
exit_failure:
18271
#ifdef DEBUG_TYPE
18272
    xmlSchemaDebugFixedType(pctxt, type);
18273
#endif
18274
0
    return(-1);
18275
0
}
18276
18277
static int
18278
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18279
        xmlSchemaTypePtr type)
18280
0
{
18281
0
    int res = 0, olderrs = pctxt->nberrors;
18282
0
    xmlSchemaTypePtr baseType = type->baseType;
18283
18284
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18285
0
  return(0);
18286
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18287
0
    if (baseType == NULL) {
18288
0
  PERROR_INT("xmlSchemaFixupComplexType",
18289
0
      "missing baseType");
18290
0
  goto exit_failure;
18291
0
    }
18292
    /*
18293
    * Fixup the base type.
18294
    */
18295
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
18296
0
  xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18297
0
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18298
  /*
18299
  * Skip fixup if the base type is invalid.
18300
  * TODO: Generate a warning!
18301
  */
18302
0
  return(0);
18303
0
    }
18304
    /*
18305
    * This basically checks if the base type can be derived.
18306
    */
18307
0
    res = xmlSchemaCheckSRCCT(pctxt, type);
18308
0
    HFAILURE HERROR
18309
    /*
18310
    * Fixup the content type.
18311
    */
18312
0
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18313
  /*
18314
  * Corresponds to <complexType><simpleContent>...
18315
  */
18316
0
  if ((WXS_IS_COMPLEX(baseType)) &&
18317
0
      (baseType->contentTypeDef != NULL) &&
18318
0
      (WXS_IS_RESTRICTION(type))) {
18319
0
      xmlSchemaTypePtr contentBase, content;
18320
#ifdef ENABLE_NAMED_LOCALS
18321
      char buf[30];
18322
      const xmlChar *tmpname;
18323
#endif
18324
      /*
18325
      * SPEC (1) If <restriction> + base type is <complexType>,
18326
      * "whose own {content type} is a simple type..."
18327
      */
18328
0
      if (type->contentTypeDef != NULL) {
18329
    /*
18330
    * SPEC (1.1) "the simple type definition corresponding to the
18331
    * <simpleType> among the [children] of <restriction> if there
18332
    * is one;"
18333
    * Note that this "<simpleType> among the [children]" was put
18334
    * into ->contentTypeDef during parsing.
18335
    */
18336
0
    contentBase = type->contentTypeDef;
18337
0
    type->contentTypeDef = NULL;
18338
0
      } else {
18339
    /*
18340
    * (1.2) "...otherwise (<restriction> has no <simpleType>
18341
    * among its [children]), the simple type definition which
18342
    * is the {content type} of the ... base type."
18343
    */
18344
0
    contentBase = baseType->contentTypeDef;
18345
0
      }
18346
      /*
18347
      * SPEC
18348
      * "... a simple type definition which restricts the simple
18349
      * type definition identified in clause 1.1 or clause 1.2
18350
      * with a set of facet components"
18351
      *
18352
      * Create the anonymous simple type, which will be the content
18353
      * type of the complex type.
18354
      */
18355
#ifdef ENABLE_NAMED_LOCALS
18356
      snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18357
      tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18358
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18359
    XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18360
    type->node, 0);
18361
#else
18362
0
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18363
0
    XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18364
0
    type->node, 0);
18365
0
#endif
18366
0
      if (content == NULL)
18367
0
    goto exit_failure;
18368
      /*
18369
      * We will use the same node as for the <complexType>
18370
      * to have it somehow anchored in the schema doc.
18371
      */
18372
0
      content->type = XML_SCHEMA_TYPE_SIMPLE;
18373
0
      content->baseType = contentBase;
18374
      /*
18375
      * Move the facets, previously anchored on the
18376
      * complexType during parsing.
18377
      */
18378
0
      content->facets = type->facets;
18379
0
      type->facets = NULL;
18380
0
      content->facetSet = type->facetSet;
18381
0
      type->facetSet = NULL;
18382
18383
0
      type->contentTypeDef = content;
18384
0
      if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18385
0
    xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18386
      /*
18387
      * Fixup the newly created type. We don't need to check
18388
      * for circularity here.
18389
      */
18390
0
      res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18391
0
      HFAILURE HERROR
18392
0
      res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18393
0
      HFAILURE HERROR
18394
18395
0
  } else if ((WXS_IS_COMPLEX(baseType)) &&
18396
0
      (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18397
0
      (WXS_IS_RESTRICTION(type))) {
18398
      /*
18399
      * SPEC (2) If <restriction> + base is a mixed <complexType> with
18400
      * an emptiable particle, then a simple type definition which
18401
      * restricts the <restriction>'s <simpleType> child.
18402
      */
18403
0
      if ((type->contentTypeDef == NULL) ||
18404
0
    (type->contentTypeDef->baseType == NULL)) {
18405
    /*
18406
    * TODO: Check if this ever happens.
18407
    */
18408
0
    xmlSchemaPCustomErr(pctxt,
18409
0
        XML_SCHEMAP_INTERNAL,
18410
0
        WXS_BASIC_CAST type, NULL,
18411
0
        "Internal error: xmlSchemaTypeFixup, "
18412
0
        "complex type '%s': the <simpleContent><restriction> "
18413
0
        "is missing a <simpleType> child, but was not caught "
18414
0
        "by xmlSchemaCheckSRCCT()", type->name);
18415
0
    goto exit_failure;
18416
0
      }
18417
0
  } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18418
      /*
18419
      * SPEC (3) If <extension> + base is <complexType> with
18420
      * <simpleType> content, "...then the {content type} of that
18421
      * complex type definition"
18422
      */
18423
0
      if (baseType->contentTypeDef == NULL) {
18424
    /*
18425
    * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18426
    * should have caught this already.
18427
    */
18428
0
    xmlSchemaPCustomErr(pctxt,
18429
0
        XML_SCHEMAP_INTERNAL,
18430
0
        WXS_BASIC_CAST type, NULL,
18431
0
        "Internal error: xmlSchemaTypeFixup, "
18432
0
        "complex type '%s': the <extension>ed base type is "
18433
0
        "a complex type with no simple content type",
18434
0
        type->name);
18435
0
    goto exit_failure;
18436
0
      }
18437
0
      type->contentTypeDef = baseType->contentTypeDef;
18438
0
  } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18439
      /*
18440
      * SPEC (4) <extension> + base is <simpleType>
18441
      * "... then that simple type definition"
18442
      */
18443
0
      type->contentTypeDef = baseType;
18444
0
  } else {
18445
      /*
18446
      * TODO: Check if this ever happens.
18447
      */
18448
0
      xmlSchemaPCustomErr(pctxt,
18449
0
    XML_SCHEMAP_INTERNAL,
18450
0
    WXS_BASIC_CAST type, NULL,
18451
0
    "Internal error: xmlSchemaTypeFixup, "
18452
0
    "complex type '%s' with <simpleContent>: unhandled "
18453
0
    "derivation case", type->name);
18454
0
      goto exit_failure;
18455
0
  }
18456
0
    } else {
18457
0
  int dummySequence = 0;
18458
0
  xmlSchemaParticlePtr particle =
18459
0
      (xmlSchemaParticlePtr) type->subtypes;
18460
  /*
18461
  * Corresponds to <complexType><complexContent>...
18462
  *
18463
  * NOTE that the effective mixed was already set during parsing of
18464
  * <complexType> and <complexContent>; its flag value is
18465
  * XML_SCHEMAS_TYPE_MIXED.
18466
  *
18467
  * Compute the "effective content":
18468
  * (2.1.1) + (2.1.2) + (2.1.3)
18469
  */
18470
0
  if ((particle == NULL) ||
18471
0
      ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18472
0
      ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18473
0
      (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18474
0
      ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18475
0
      (particle->minOccurs == 0))) &&
18476
0
      ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18477
0
      if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18478
    /*
18479
    * SPEC (2.1.4) "If the `effective mixed` is true, then
18480
    * a particle whose properties are as follows:..."
18481
    *
18482
    * Empty sequence model group with
18483
    * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18484
    * NOTE that we sill assign it the <complexType> node to
18485
    * somehow anchor it in the doc.
18486
    */
18487
0
    if ((particle == NULL) ||
18488
0
        (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18489
        /*
18490
        * Create the particle.
18491
        */
18492
0
        particle = xmlSchemaAddParticle(pctxt,
18493
0
      type->node, 1, 1);
18494
0
        if (particle == NULL)
18495
0
      goto exit_failure;
18496
        /*
18497
        * Create the model group.
18498
        */ /* URGENT TODO: avoid adding to pending items. */
18499
0
        particle->children = (xmlSchemaTreeItemPtr)
18500
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18501
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18502
0
        if (particle->children == NULL)
18503
0
      goto exit_failure;
18504
18505
0
        type->subtypes = (xmlSchemaTypePtr) particle;
18506
0
    }
18507
0
    dummySequence = 1;
18508
0
    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18509
0
      } else {
18510
    /*
18511
    * SPEC (2.1.5) "otherwise empty"
18512
    */
18513
0
    type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18514
0
      }
18515
0
  } else {
18516
      /*
18517
      * SPEC (2.2) "otherwise the particle corresponding to the
18518
      * <all>, <choice>, <group> or <sequence> among the
18519
      * [children]."
18520
      */
18521
0
      type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18522
0
  }
18523
  /*
18524
  * Compute the "content type".
18525
  */
18526
0
  if (WXS_IS_RESTRICTION(type)) {
18527
      /*
18528
      * SPEC (3.1) "If <restriction>..."
18529
      * (3.1.1) + (3.1.2) */
18530
0
      if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18531
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18532
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18533
0
      }
18534
0
  } else {
18535
      /*
18536
      * SPEC (3.2) "If <extension>..."
18537
      */
18538
0
      if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18539
    /*
18540
    * SPEC (3.2.1)
18541
    * "If the `effective content` is empty, then the
18542
    *  {content type} of the [...] base ..."
18543
    */
18544
0
    type->contentType = baseType->contentType;
18545
0
    type->subtypes = baseType->subtypes;
18546
    /*
18547
    * Fixes bug #347316:
18548
    * This is the case when the base type has a simple
18549
    * type definition as content.
18550
    */
18551
0
    type->contentTypeDef = baseType->contentTypeDef;
18552
    /*
18553
    * NOTE that the effective mixed is ignored here.
18554
    */
18555
0
      } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18556
    /*
18557
    * SPEC (3.2.2)
18558
    */
18559
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18560
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18561
0
      } else {
18562
    /*
18563
    * SPEC (3.2.3)
18564
    */
18565
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18566
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18567
        /*
18568
        * "A model group whose {compositor} is sequence and whose
18569
        * {particles} are..."
18570
        */
18571
0
    if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18572
0
        (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18573
0
        ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18574
0
      XML_SCHEMA_TYPE_ALL))
18575
0
    {
18576
        /*
18577
        * SPEC cos-all-limited (1)
18578
        */
18579
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18580
      /* TODO: error code */
18581
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18582
0
      WXS_ITEM_NODE(type), NULL,
18583
0
      "The type has an 'all' model group in its "
18584
0
      "{content type} and thus cannot be derived from "
18585
0
      "a non-empty type, since this would produce a "
18586
0
      "'sequence' model group containing the 'all' "
18587
0
      "model group; 'all' model groups are not "
18588
0
      "allowed to appear inside other model groups",
18589
0
      NULL, NULL);
18590
18591
0
    } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18592
0
        (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18593
0
        ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18594
0
      XML_SCHEMA_TYPE_ALL))
18595
0
    {
18596
        /*
18597
        * SPEC cos-all-limited (1)
18598
        */
18599
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18600
      /* TODO: error code */
18601
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18602
0
      WXS_ITEM_NODE(type), NULL,
18603
0
      "A type cannot be derived by extension from a type "
18604
0
      "which has an 'all' model group in its "
18605
0
      "{content type}, since this would produce a "
18606
0
      "'sequence' model group containing the 'all' "
18607
0
      "model group; 'all' model groups are not "
18608
0
      "allowed to appear inside other model groups",
18609
0
      NULL, NULL);
18610
18611
0
    } else if (! dummySequence) {
18612
0
        xmlSchemaTreeItemPtr effectiveContent =
18613
0
      (xmlSchemaTreeItemPtr) type->subtypes;
18614
        /*
18615
        * Create the particle.
18616
        */
18617
0
        particle = xmlSchemaAddParticle(pctxt,
18618
0
      type->node, 1, 1);
18619
0
        if (particle == NULL)
18620
0
      goto exit_failure;
18621
        /*
18622
        * Create the "sequence" model group.
18623
        */
18624
0
        particle->children = (xmlSchemaTreeItemPtr)
18625
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18626
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18627
0
        if (particle->children == NULL)
18628
0
      goto exit_failure;
18629
0
        WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18630
        /*
18631
        * SPEC "the particle of the {content type} of
18632
        * the ... base ..."
18633
        * Create a duplicate of the base type's particle
18634
        * and assign its "term" to it.
18635
        */
18636
0
        particle->children->children =
18637
0
      (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18638
0
      type->node,
18639
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18640
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18641
0
        if (particle->children->children == NULL)
18642
0
      goto exit_failure;
18643
0
        particle = (xmlSchemaParticlePtr)
18644
0
      particle->children->children;
18645
0
        particle->children =
18646
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18647
        /*
18648
        * SPEC "followed by the `effective content`."
18649
        */
18650
0
        particle->next = effectiveContent;
18651
        /*
18652
        * This all will result in:
18653
        * new-particle
18654
        *   --> new-sequence(
18655
        *         new-particle
18656
        *           --> base-model,
18657
        *         this-particle
18658
        *         --> this-model
18659
        *     )
18660
        */
18661
0
    } else {
18662
        /*
18663
        * This is the case when there is already an empty
18664
        * <sequence> with minOccurs==maxOccurs==1.
18665
        * Just add the base types's content type.
18666
        * NOTE that, although we miss to add an intermediate
18667
        * <sequence>, this should produce no difference to
18668
        * neither the regex compilation of the content model,
18669
        * nor to the complex type constraints.
18670
        */
18671
0
        particle->children->children =
18672
0
      (xmlSchemaTreeItemPtr) baseType->subtypes;
18673
0
    }
18674
0
      }
18675
0
  }
18676
0
    }
18677
    /*
18678
    * Now fixup attribute uses:
18679
    *   - expand attr. group references
18680
    *     - intersect attribute wildcards
18681
    *   - inherit attribute uses of the base type
18682
    *   - inherit or union attr. wildcards if extending
18683
    *   - apply attr. use prohibitions if restricting
18684
    */
18685
0
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18686
0
    HFAILURE HERROR
18687
    /*
18688
    * Apply the complex type component constraints; this will not
18689
    * check attributes, since this is done in
18690
    * xmlSchemaFixupTypeAttributeUses().
18691
    */
18692
0
    res = xmlSchemaCheckCTComponent(pctxt, type);
18693
0
    HFAILURE HERROR
18694
18695
#ifdef DEBUG_TYPE
18696
    xmlSchemaDebugFixedType(pctxt, type);
18697
#endif
18698
0
    if (olderrs != pctxt->nberrors)
18699
0
  return(pctxt->err);
18700
0
    else
18701
0
  return(0);
18702
18703
0
exit_error:
18704
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18705
#ifdef DEBUG_TYPE
18706
    xmlSchemaDebugFixedType(pctxt, type);
18707
#endif
18708
0
    return(pctxt->err);
18709
18710
0
exit_failure:
18711
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18712
#ifdef DEBUG_TYPE
18713
    xmlSchemaDebugFixedType(pctxt, type);
18714
#endif
18715
0
    return(-1);
18716
0
}
18717
18718
18719
/**
18720
 * xmlSchemaTypeFixup:
18721
 * @typeDecl:  the schema type definition
18722
 * @ctxt:  the schema parser context
18723
 *
18724
 * Fixes the content model of the type.
18725
 * URGENT TODO: We need an int result!
18726
 */
18727
static int
18728
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18729
                   xmlSchemaAbstractCtxtPtr actxt)
18730
0
{
18731
0
    if (type == NULL)
18732
0
        return(0);
18733
0
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18734
0
  AERROR_INT("xmlSchemaTypeFixup",
18735
0
      "this function needs a parser context");
18736
0
  return(-1);
18737
0
    }
18738
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18739
0
  return(0);
18740
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18741
0
  return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18742
0
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18743
0
  return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18744
0
    return(0);
18745
0
}
18746
18747
/**
18748
 * xmlSchemaCheckFacet:
18749
 * @facet:  the facet
18750
 * @typeDecl:  the schema type definition
18751
 * @pctxt:  the schema parser context or NULL
18752
 * @name: the optional name of the type
18753
 *
18754
 * Checks and computes the values of facets.
18755
 *
18756
 * Returns 0 if valid, a positive error code if not valid and
18757
 *         -1 in case of an internal or API error.
18758
 */
18759
int
18760
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18761
                    xmlSchemaTypePtr typeDecl,
18762
                    xmlSchemaParserCtxtPtr pctxt,
18763
        const xmlChar * name ATTRIBUTE_UNUSED)
18764
0
{
18765
0
    int ret = 0, ctxtGiven;
18766
18767
0
    if ((facet == NULL) || (typeDecl == NULL))
18768
0
        return(-1);
18769
    /*
18770
    * TODO: will the parser context be given if used from
18771
    * the relaxNG module?
18772
    */
18773
0
    if (pctxt == NULL)
18774
0
  ctxtGiven = 0;
18775
0
    else
18776
0
  ctxtGiven = 1;
18777
18778
0
    switch (facet->type) {
18779
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
18780
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
18781
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
18782
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18783
0
  case XML_SCHEMA_FACET_ENUMERATION: {
18784
                /*
18785
                 * Okay we need to validate the value
18786
                 * at that point.
18787
                 */
18788
0
    xmlSchemaTypePtr base;
18789
18790
    /* 4.3.5.5 Constraints on enumeration Schema Components
18791
    * Schema Component Constraint: enumeration valid restriction
18792
    * It is an `error` if any member of {value} is not in the
18793
    * `value space` of {base type definition}.
18794
    *
18795
    * minInclusive, maxInclusive, minExclusive, maxExclusive:
18796
    * The value `must` be in the
18797
    * `value space` of the `base type`.
18798
    */
18799
    /*
18800
    * This function is intended to deliver a compiled value
18801
    * on the facet. In this implementation of XML Schemata the
18802
    * type holding a facet, won't be a built-in type.
18803
    * Thus to ensure that other API
18804
    * calls (relaxng) do work, if the given type is a built-in
18805
    * type, we will assume that the given built-in type *is
18806
    * already* the base type.
18807
    */
18808
0
    if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18809
0
        base = typeDecl->baseType;
18810
0
        if (base == NULL) {
18811
0
      PERROR_INT("xmlSchemaCheckFacet",
18812
0
          "a type user derived type has no base type");
18813
0
      return (-1);
18814
0
        }
18815
0
    } else
18816
0
        base = typeDecl;
18817
18818
0
    if (! ctxtGiven) {
18819
        /*
18820
        * A context is needed if called from RelaxNG.
18821
        */
18822
0
        pctxt = xmlSchemaNewParserCtxt("*");
18823
0
        if (pctxt == NULL)
18824
0
      return (-1);
18825
0
    }
18826
    /*
18827
    * NOTE: This call does not check the content nodes,
18828
    * since they are not available:
18829
    * facet->node is just the node holding the facet
18830
    * definition, *not* the attribute holding the *value*
18831
    * of the facet.
18832
    */
18833
0
    ret = xmlSchemaVCheckCVCSimpleType(
18834
0
        ACTXT_CAST pctxt, facet->node, base,
18835
0
        facet->value, &(facet->val), 1, 1, 0);
18836
0
                if (ret != 0) {
18837
0
        if (ret < 0) {
18838
      /* No error message for RelaxNG. */
18839
0
      if (ctxtGiven) {
18840
0
          xmlSchemaCustomErr(ACTXT_CAST pctxt,
18841
0
        XML_SCHEMAP_INTERNAL, facet->node, NULL,
18842
0
        "Internal error: xmlSchemaCheckFacet, "
18843
0
        "failed to validate the value '%s' of the "
18844
0
        "facet '%s' against the base type",
18845
0
        facet->value, xmlSchemaFacetTypeToString(facet->type));
18846
0
      }
18847
0
      goto internal_error;
18848
0
        }
18849
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18850
        /* No error message for RelaxNG. */
18851
0
        if (ctxtGiven) {
18852
0
      xmlChar *str = NULL;
18853
18854
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18855
0
          ret, facet->node, WXS_BASIC_CAST facet,
18856
0
          "The value '%s' of the facet does not validate "
18857
0
          "against the base type '%s'",
18858
0
          facet->value,
18859
0
          xmlSchemaFormatQName(&str,
18860
0
        base->targetNamespace, base->name));
18861
0
      FREE_AND_NULL(str);
18862
0
        }
18863
0
        goto exit;
18864
0
                } else if (facet->val == NULL) {
18865
0
        if (ctxtGiven) {
18866
0
      PERROR_INT("xmlSchemaCheckFacet",
18867
0
          "value was not computed");
18868
0
        }
18869
0
        TODO
18870
0
    }
18871
0
                break;
18872
0
            }
18873
0
        case XML_SCHEMA_FACET_PATTERN:
18874
0
            facet->regexp = xmlRegexpCompile(facet->value);
18875
0
            if (facet->regexp == NULL) {
18876
0
    ret = XML_SCHEMAP_REGEXP_INVALID;
18877
    /* No error message for RelaxNG. */
18878
0
    if (ctxtGiven) {
18879
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18880
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18881
0
      "The value '%s' of the facet 'pattern' is not a "
18882
0
      "valid regular expression",
18883
0
      facet->value, NULL);
18884
0
    }
18885
0
            }
18886
0
            break;
18887
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
18888
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
18889
0
        case XML_SCHEMA_FACET_LENGTH:
18890
0
        case XML_SCHEMA_FACET_MAXLENGTH:
18891
0
        case XML_SCHEMA_FACET_MINLENGTH:
18892
18893
0
      if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18894
0
    ret = xmlSchemaValidatePredefinedType(
18895
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18896
0
        facet->value, &(facet->val));
18897
0
      } else {
18898
0
    ret = xmlSchemaValidatePredefinedType(
18899
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18900
0
        facet->value, &(facet->val));
18901
0
      }
18902
0
      if (ret != 0) {
18903
0
    if (ret < 0) {
18904
        /* No error message for RelaxNG. */
18905
0
        if (ctxtGiven) {
18906
0
      PERROR_INT("xmlSchemaCheckFacet",
18907
0
          "validating facet value");
18908
0
        }
18909
0
        goto internal_error;
18910
0
    }
18911
0
    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18912
    /* No error message for RelaxNG. */
18913
0
    if (ctxtGiven) {
18914
        /* error code */
18915
0
        xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18916
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18917
0
      "The value '%s' of the facet '%s' is not a valid '%s'",
18918
0
      facet->value,
18919
0
      xmlSchemaFacetTypeToString(facet->type),
18920
0
      (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18921
0
          BAD_CAST "nonNegativeInteger" :
18922
0
          BAD_CAST "positiveInteger",
18923
0
      NULL);
18924
0
    }
18925
0
      }
18926
0
      break;
18927
18928
0
        case XML_SCHEMA_FACET_WHITESPACE:{
18929
0
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18930
0
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18931
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18932
0
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18933
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18934
0
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18935
0
                } else {
18936
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18937
                    /* No error message for RelaxNG. */
18938
0
        if (ctxtGiven) {
18939
      /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18940
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18941
0
          ret, facet->node, WXS_BASIC_CAST typeDecl,
18942
0
          "The value '%s' of the facet 'whitespace' is not "
18943
0
          "valid", facet->value, NULL);
18944
0
                    }
18945
0
                }
18946
0
            }
18947
0
        default:
18948
0
            break;
18949
0
    }
18950
0
exit:
18951
0
    if ((! ctxtGiven) && (pctxt != NULL))
18952
0
  xmlSchemaFreeParserCtxt(pctxt);
18953
0
    return (ret);
18954
0
internal_error:
18955
0
    if ((! ctxtGiven) && (pctxt != NULL))
18956
0
  xmlSchemaFreeParserCtxt(pctxt);
18957
0
    return (-1);
18958
0
}
18959
18960
/**
18961
 * xmlSchemaCheckFacetValues:
18962
 * @typeDecl:  the schema type definition
18963
 * @ctxt:  the schema parser context
18964
 *
18965
 * Checks the default values types, especially for facets
18966
 */
18967
static int
18968
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18969
        xmlSchemaParserCtxtPtr pctxt)
18970
0
{
18971
0
    int res, olderrs = pctxt->nberrors;
18972
0
    const xmlChar *name = typeDecl->name;
18973
    /*
18974
    * NOTE: It is intended to use the facets list, instead
18975
    * of facetSet.
18976
    */
18977
0
    if (typeDecl->facets != NULL) {
18978
0
  xmlSchemaFacetPtr facet = typeDecl->facets;
18979
18980
  /*
18981
  * Temporarily assign the "schema" to the validation context
18982
  * of the parser context. This is needed for NOTATION validation.
18983
  */
18984
0
  if (pctxt->vctxt == NULL) {
18985
0
      if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18986
0
    return(-1);
18987
0
  }
18988
0
  pctxt->vctxt->schema = pctxt->schema;
18989
0
  while (facet != NULL) {
18990
0
      res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18991
0
      HFAILURE
18992
0
      facet = facet->next;
18993
0
  }
18994
0
  pctxt->vctxt->schema = NULL;
18995
0
    }
18996
0
    if (olderrs != pctxt->nberrors)
18997
0
  return(pctxt->err);
18998
0
    return(0);
18999
0
exit_failure:
19000
0
    return(-1);
19001
0
}
19002
19003
/**
19004
 * xmlSchemaGetCircModelGrDefRef:
19005
 * @ctxtMGroup: the searched model group
19006
 * @selfMGroup: the second searched model group
19007
 * @particle: the first particle
19008
 *
19009
 * This one is intended to be used by
19010
 * xmlSchemaCheckGroupDefCircular only.
19011
 *
19012
 * Returns the particle with the circular model group definition reference,
19013
 * otherwise NULL.
19014
 */
19015
static xmlSchemaTreeItemPtr
19016
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
19017
            xmlSchemaTreeItemPtr particle)
19018
0
{
19019
0
    xmlSchemaTreeItemPtr circ = NULL;
19020
0
    xmlSchemaTreeItemPtr term;
19021
0
    xmlSchemaModelGroupDefPtr gdef;
19022
19023
0
    for (; particle != NULL; particle = particle->next) {
19024
0
  term = particle->children;
19025
0
  if (term == NULL)
19026
0
      continue;
19027
0
  switch (term->type) {
19028
0
      case XML_SCHEMA_TYPE_GROUP:
19029
0
    gdef = (xmlSchemaModelGroupDefPtr) term;
19030
0
    if (gdef == groupDef)
19031
0
        return (particle);
19032
    /*
19033
    * Mark this model group definition to avoid infinite
19034
    * recursion on circular references not yet examined.
19035
    */
19036
0
    if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
19037
0
        continue;
19038
0
    if (gdef->children != NULL) {
19039
0
        gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
19040
0
        circ = xmlSchemaGetCircModelGrDefRef(groupDef,
19041
0
      gdef->children->children);
19042
0
        gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
19043
0
        if (circ != NULL)
19044
0
      return (circ);
19045
0
    }
19046
0
    break;
19047
0
      case XML_SCHEMA_TYPE_SEQUENCE:
19048
0
      case XML_SCHEMA_TYPE_CHOICE:
19049
0
      case XML_SCHEMA_TYPE_ALL:
19050
0
    circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
19051
0
    if (circ != NULL)
19052
0
        return (circ);
19053
0
    break;
19054
0
      default:
19055
0
    break;
19056
0
  }
19057
0
    }
19058
0
    return (NULL);
19059
0
}
19060
19061
/**
19062
 * xmlSchemaCheckGroupDefCircular:
19063
 * @item:  the model group definition
19064
 * @ctxt:  the parser context
19065
 * @name:  the name
19066
 *
19067
 * Checks for circular references to model group definitions.
19068
 */
19069
static void
19070
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
19071
             xmlSchemaParserCtxtPtr ctxt)
19072
0
{
19073
    /*
19074
    * Schema Component Constraint: Model Group Correct
19075
    * 2 Circular groups are disallowed. That is, within the {particles}
19076
    * of a group there must not be at any depth a particle whose {term}
19077
    * is the group itself.
19078
    */
19079
0
    if ((item == NULL) ||
19080
0
  (item->type != XML_SCHEMA_TYPE_GROUP) ||
19081
0
  (item->children == NULL))
19082
0
  return;
19083
0
    {
19084
0
  xmlSchemaTreeItemPtr circ;
19085
19086
0
  circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
19087
0
  if (circ != NULL) {
19088
0
      xmlChar *str = NULL;
19089
      /*
19090
      * TODO: The error report is not adequate: this constraint
19091
      * is defined for model groups but not definitions, but since
19092
      * there cannot be any circular model groups without a model group
19093
      * definition (if not using a construction API), we check those
19094
      * definitions only.
19095
      */
19096
0
      xmlSchemaPCustomErr(ctxt,
19097
0
    XML_SCHEMAP_MG_PROPS_CORRECT_2,
19098
0
    NULL, WXS_ITEM_NODE(circ),
19099
0
    "Circular reference to the model group definition '%s' "
19100
0
    "defined", xmlSchemaFormatQName(&str,
19101
0
        item->targetNamespace, item->name));
19102
0
      FREE_AND_NULL(str)
19103
      /*
19104
      * NOTE: We will cut the reference to avoid further
19105
      * confusion of the processor. This is a fatal error.
19106
      */
19107
0
      circ->children = NULL;
19108
0
  }
19109
0
    }
19110
0
}
19111
19112
/**
19113
 * xmlSchemaModelGroupToModelGroupDefFixup:
19114
 * @ctxt:  the parser context
19115
 * @mg:  the model group
19116
 *
19117
 * Assigns the model group of model group definitions to the "term"
19118
 * of the referencing particle.
19119
 * In xmlSchemaResolveModelGroupParticleReferences the model group
19120
 * definitions were assigned to the "term", since needed for the
19121
 * circularity check.
19122
 *
19123
 * Schema Component Constraint:
19124
 *     All Group Limited (cos-all-limited) (1.2)
19125
 */
19126
static void
19127
xmlSchemaModelGroupToModelGroupDefFixup(
19128
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
19129
    xmlSchemaModelGroupPtr mg)
19130
0
{
19131
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19132
19133
0
    while (particle != NULL) {
19134
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19135
0
      ((WXS_PARTICLE_TERM(particle))->type !=
19136
0
    XML_SCHEMA_TYPE_GROUP))
19137
0
  {
19138
0
      particle = WXS_PTC_CAST particle->next;
19139
0
      continue;
19140
0
  }
19141
0
  if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
19142
      /*
19143
      * TODO: Remove the particle.
19144
      */
19145
0
      WXS_PARTICLE_TERM(particle) = NULL;
19146
0
      particle = WXS_PTC_CAST particle->next;
19147
0
      continue;
19148
0
  }
19149
  /*
19150
  * Assign the model group to the {term} of the particle.
19151
  */
19152
0
  WXS_PARTICLE_TERM(particle) =
19153
0
      WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
19154
19155
0
  particle = WXS_PTC_CAST particle->next;
19156
0
    }
19157
0
}
19158
19159
/**
19160
 * xmlSchemaCheckAttrGroupCircularRecur:
19161
 * @ctxtGr: the searched attribute group
19162
 * @attr: the current attribute list to be processed
19163
 *
19164
 * This one is intended to be used by
19165
 * xmlSchemaCheckAttrGroupCircular only.
19166
 *
19167
 * Returns the circular attribute group reference, otherwise NULL.
19168
 */
19169
static xmlSchemaQNameRefPtr
19170
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
19171
             xmlSchemaItemListPtr list)
19172
0
{
19173
0
    xmlSchemaAttributeGroupPtr gr;
19174
0
    xmlSchemaQNameRefPtr ref, circ;
19175
0
    int i;
19176
    /*
19177
    * We will search for an attribute group reference which
19178
    * references the context attribute group.
19179
    */
19180
0
    for (i = 0; i < list->nbItems; i++) {
19181
0
  ref = list->items[i];
19182
0
  if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19183
0
      (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
19184
0
      (ref->item != NULL))
19185
0
  {
19186
0
      gr = WXS_ATTR_GROUP_CAST ref->item;
19187
0
      if (gr == ctxtGr)
19188
0
    return(ref);
19189
0
      if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19190
0
    continue;
19191
      /*
19192
      * Mark as visited to avoid infinite recursion on
19193
      * circular references not yet examined.
19194
      */
19195
0
      if ((gr->attrUses) &&
19196
0
    (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19197
0
      {
19198
0
    gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19199
0
    circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19200
0
        (xmlSchemaItemListPtr) gr->attrUses);
19201
0
    gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19202
0
    if (circ != NULL)
19203
0
        return (circ);
19204
0
      }
19205
19206
0
  }
19207
0
    }
19208
0
    return (NULL);
19209
0
}
19210
19211
/**
19212
 * xmlSchemaCheckAttrGroupCircular:
19213
 * attrGr:  the attribute group definition
19214
 * @ctxt:  the parser context
19215
 * @name:  the name
19216
 *
19217
 * Checks for circular references of attribute groups.
19218
 */
19219
static int
19220
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19221
        xmlSchemaParserCtxtPtr ctxt)
19222
0
{
19223
    /*
19224
    * Schema Representation Constraint:
19225
    * Attribute Group Definition Representation OK
19226
    * 3 Circular group reference is disallowed outside <redefine>.
19227
    * That is, unless this element information item's parent is
19228
    * <redefine>, then among the [children], if any, there must
19229
    * not be an <attributeGroup> with ref [attribute] which resolves
19230
    * to the component corresponding to this <attributeGroup>. Indirect
19231
    * circularity is also ruled out. That is, when QName resolution
19232
    * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19233
    * any <attributeGroup>s with a ref [attribute] among the [children],
19234
    * it must not be the case that a `QName` is encountered at any depth
19235
    * which resolves to the component corresponding to this <attributeGroup>.
19236
    */
19237
0
    if (attrGr->attrUses == NULL)
19238
0
  return(0);
19239
0
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19240
0
  return(0);
19241
0
    else {
19242
0
  xmlSchemaQNameRefPtr circ;
19243
19244
0
  circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19245
0
      (xmlSchemaItemListPtr) attrGr->attrUses);
19246
0
  if (circ != NULL) {
19247
0
      xmlChar *str = NULL;
19248
      /*
19249
      * TODO: Report the referenced attr group as QName.
19250
      */
19251
0
      xmlSchemaPCustomErr(ctxt,
19252
0
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19253
0
    NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19254
0
    "Circular reference to the attribute group '%s' "
19255
0
    "defined", xmlSchemaGetComponentQName(&str, attrGr));
19256
0
      FREE_AND_NULL(str);
19257
      /*
19258
      * NOTE: We will cut the reference to avoid further
19259
      * confusion of the processor.
19260
      * BADSPEC TODO: The spec should define how to process in this case.
19261
      */
19262
0
      circ->item = NULL;
19263
0
      return(ctxt->err);
19264
0
  }
19265
0
    }
19266
0
    return(0);
19267
0
}
19268
19269
static int
19270
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19271
          xmlSchemaAttributeGroupPtr attrGr);
19272
19273
/**
19274
 * xmlSchemaExpandAttributeGroupRefs:
19275
 * @pctxt: the parser context
19276
 * @node: the node of the component holding the attribute uses
19277
 * @completeWild: the intersected wildcard to be returned
19278
 * @list: the attribute uses
19279
 *
19280
 * Substitutes contained attribute group references
19281
 * for their attribute uses. Wildcards are intersected.
19282
 * Attribute use prohibitions are removed from the list
19283
 * and returned via the @prohibs list.
19284
 * Pointlessness of attr. prohibs, if a matching attr. decl
19285
 * is existent a well, are checked.
19286
 */
19287
static int
19288
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19289
          xmlSchemaBasicItemPtr item,
19290
          xmlSchemaWildcardPtr *completeWild,
19291
          xmlSchemaItemListPtr list,
19292
          xmlSchemaItemListPtr prohibs)
19293
0
{
19294
0
    xmlSchemaAttributeGroupPtr gr;
19295
0
    xmlSchemaAttributeUsePtr use;
19296
0
    xmlSchemaItemListPtr sublist;
19297
0
    int i, j;
19298
0
    int created = (*completeWild == NULL) ? 0 : 1;
19299
19300
0
    if (prohibs)
19301
0
  prohibs->nbItems = 0;
19302
19303
0
    for (i = 0; i < list->nbItems; i++) {
19304
0
  use = list->items[i];
19305
19306
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19307
0
      if (prohibs == NULL) {
19308
0
    PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19309
0
        "unexpected attr prohibition found");
19310
0
    return(-1);
19311
0
      }
19312
      /*
19313
      * Remove from attribute uses.
19314
      */
19315
0
      if (xmlSchemaItemListRemove(list, i) == -1)
19316
0
    return(-1);
19317
0
      i--;
19318
      /*
19319
      * Note that duplicate prohibitions were already
19320
      * handled at parsing time.
19321
      */
19322
      /*
19323
      * Add to list of prohibitions.
19324
      */
19325
0
      xmlSchemaItemListAddSize(prohibs, 2, use);
19326
0
      continue;
19327
0
  }
19328
0
  if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19329
0
      ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19330
0
  {
19331
0
      if ((WXS_QNAME_CAST use)->item == NULL)
19332
0
    return(-1);
19333
0
      gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19334
      /*
19335
      * Expand the referenced attr. group.
19336
      * TODO: remove this, this is done in a previous step, so
19337
      * already done here.
19338
      */
19339
0
      if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19340
0
    if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19341
0
        return(-1);
19342
0
      }
19343
      /*
19344
      * Build the 'complete' wildcard; i.e. intersect multiple
19345
      * wildcards.
19346
      */
19347
0
      if (gr->attributeWildcard != NULL) {
19348
0
    if (*completeWild == NULL) {
19349
0
        *completeWild = gr->attributeWildcard;
19350
0
    } else {
19351
0
        if (! created) {
19352
0
      xmlSchemaWildcardPtr tmpWild;
19353
19354
       /*
19355
      * Copy the first encountered wildcard as context,
19356
      * except for the annotation.
19357
      *
19358
      * Although the complete wildcard might not correspond
19359
      * to any node in the schema, we will anchor it on
19360
      * the node of the owner component.
19361
      */
19362
0
      tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19363
0
          XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19364
0
          WXS_ITEM_NODE(item));
19365
0
      if (tmpWild == NULL)
19366
0
          return(-1);
19367
0
      if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19368
0
          tmpWild, *completeWild) == -1)
19369
0
          return (-1);
19370
0
      tmpWild->processContents = (*completeWild)->processContents;
19371
0
      *completeWild = tmpWild;
19372
0
      created = 1;
19373
0
        }
19374
19375
0
        if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19376
0
      gr->attributeWildcard) == -1)
19377
0
      return(-1);
19378
0
    }
19379
0
      }
19380
      /*
19381
      * Just remove the reference if the referenced group does not
19382
      * contain any attribute uses.
19383
      */
19384
0
      sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19385
0
      if ((sublist == NULL) || sublist->nbItems == 0) {
19386
0
    if (xmlSchemaItemListRemove(list, i) == -1)
19387
0
        return(-1);
19388
0
    i--;
19389
0
    continue;
19390
0
      }
19391
      /*
19392
      * Add the attribute uses.
19393
      */
19394
0
      list->items[i] = sublist->items[0];
19395
0
      if (sublist->nbItems != 1) {
19396
0
    for (j = 1; j < sublist->nbItems; j++) {
19397
0
        i++;
19398
0
        if (xmlSchemaItemListInsert(list,
19399
0
          sublist->items[j], i) == -1)
19400
0
      return(-1);
19401
0
    }
19402
0
      }
19403
0
  }
19404
19405
0
    }
19406
    /*
19407
    * Handle pointless prohibitions of declared attributes.
19408
    */
19409
0
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19410
0
  xmlSchemaAttributeUseProhibPtr prohib;
19411
19412
0
  for (i = prohibs->nbItems -1; i >= 0; i--) {
19413
0
      prohib = prohibs->items[i];
19414
0
      for (j = 0; j < list->nbItems; j++) {
19415
0
    use = list->items[j];
19416
19417
0
    if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19418
0
        (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19419
0
    {
19420
0
        xmlChar *str = NULL;
19421
19422
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19423
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19424
0
      prohib->node, NULL,
19425
0
      "Skipping pointless attribute use prohibition "
19426
0
      "'%s', since a corresponding attribute use "
19427
0
      "exists already in the type definition",
19428
0
      xmlSchemaFormatQName(&str,
19429
0
          prohib->targetNamespace, prohib->name),
19430
0
      NULL, NULL);
19431
0
        FREE_AND_NULL(str);
19432
        /*
19433
        * Remove the prohibition.
19434
        */
19435
0
        if (xmlSchemaItemListRemove(prohibs, i) == -1)
19436
0
      return(-1);
19437
0
        break;
19438
0
    }
19439
0
      }
19440
0
  }
19441
0
    }
19442
0
    return(0);
19443
0
}
19444
19445
/**
19446
 * xmlSchemaAttributeGroupExpandRefs:
19447
 * @pctxt:  the parser context
19448
 * @attrGr:  the attribute group definition
19449
 *
19450
 * Computation of:
19451
 * {attribute uses} property
19452
 * {attribute wildcard} property
19453
 *
19454
 * Substitutes contained attribute group references
19455
 * for their attribute uses. Wildcards are intersected.
19456
 */
19457
static int
19458
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19459
          xmlSchemaAttributeGroupPtr attrGr)
19460
0
{
19461
0
    if ((attrGr->attrUses == NULL) ||
19462
0
  (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19463
0
  return(0);
19464
19465
0
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19466
0
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19467
0
  &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19468
0
  return(-1);
19469
0
    return(0);
19470
0
}
19471
19472
/**
19473
 * xmlSchemaAttributeGroupExpandRefs:
19474
 * @pctxt:  the parser context
19475
 * @attrGr:  the attribute group definition
19476
 *
19477
 * Substitutes contained attribute group references
19478
 * for their attribute uses. Wildcards are intersected.
19479
 *
19480
 * Schema Component Constraint:
19481
 *    Attribute Group Definition Properties Correct (ag-props-correct)
19482
 */
19483
static int
19484
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19485
          xmlSchemaAttributeGroupPtr attrGr)
19486
0
{
19487
    /*
19488
    * SPEC ag-props-correct
19489
    * (1) "The values of the properties of an attribute group definition
19490
    * must be as described in the property tableau in The Attribute
19491
    * Group Definition Schema Component ($3.6.1), modulo the impact of
19492
    * Missing Sub-components ($5.3);"
19493
    */
19494
19495
0
    if ((attrGr->attrUses != NULL) &&
19496
0
  (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19497
0
    {
19498
0
  xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19499
0
  xmlSchemaAttributeUsePtr use, tmp;
19500
0
  int i, j, hasId = 0;
19501
19502
0
  for (i = uses->nbItems -1; i >= 0; i--) {
19503
0
      use = uses->items[i];
19504
      /*
19505
      * SPEC ag-props-correct
19506
      * (2) "Two distinct members of the {attribute uses} must not have
19507
      * {attribute declaration}s both of whose {name}s match and whose
19508
      * {target namespace}s are identical."
19509
      */
19510
0
      if (i > 0) {
19511
0
    for (j = i -1; j >= 0; j--) {
19512
0
        tmp = uses->items[j];
19513
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
19514
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
19515
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
19516
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
19517
0
        {
19518
0
      xmlChar *str = NULL;
19519
19520
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19521
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19522
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19523
0
          "Duplicate %s",
19524
0
          xmlSchemaGetComponentDesignation(&str, use),
19525
0
          NULL);
19526
0
      FREE_AND_NULL(str);
19527
      /*
19528
      * Remove the duplicate.
19529
      */
19530
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19531
0
          return(-1);
19532
0
      goto next_use;
19533
0
        }
19534
0
    }
19535
0
      }
19536
      /*
19537
      * SPEC ag-props-correct
19538
      * (3) "Two distinct members of the {attribute uses} must not have
19539
      * {attribute declaration}s both of whose {type definition}s are or
19540
      * are derived from ID."
19541
      * TODO: Does 'derived' include member-types of unions?
19542
      */
19543
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19544
0
    if (xmlSchemaIsDerivedFromBuiltInType(
19545
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19546
0
    {
19547
0
        if (hasId) {
19548
0
      xmlChar *str = NULL;
19549
19550
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19551
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19552
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19553
0
          "There must not exist more than one attribute "
19554
0
          "declaration of type 'xs:ID' "
19555
0
          "(or derived from 'xs:ID'). The %s violates this "
19556
0
          "constraint",
19557
0
          xmlSchemaGetComponentDesignation(&str, use),
19558
0
          NULL);
19559
0
      FREE_AND_NULL(str);
19560
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19561
0
          return(-1);
19562
0
        }
19563
0
        hasId = 1;
19564
0
    }
19565
0
      }
19566
0
next_use: {}
19567
0
  }
19568
0
    }
19569
0
    return(0);
19570
0
}
19571
19572
/**
19573
 * xmlSchemaResolveAttrGroupReferences:
19574
 * @attrgrpDecl:  the schema attribute definition
19575
 * @ctxt:  the schema parser context
19576
 * @name:  the attribute name
19577
 *
19578
 * Resolves references to attribute group definitions.
19579
 */
19580
static int
19581
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19582
            xmlSchemaParserCtxtPtr ctxt)
19583
0
{
19584
0
    xmlSchemaAttributeGroupPtr group;
19585
19586
0
    if (ref->item != NULL)
19587
0
        return(0);
19588
0
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
19589
0
  ref->name,
19590
0
  ref->targetNamespace);
19591
0
    if (group == NULL) {
19592
0
  xmlSchemaPResCompAttrErr(ctxt,
19593
0
      XML_SCHEMAP_SRC_RESOLVE,
19594
0
      NULL, ref->node,
19595
0
      "ref", ref->name, ref->targetNamespace,
19596
0
      ref->itemType, NULL);
19597
0
  return(ctxt->err);
19598
0
    }
19599
0
    ref->item = WXS_BASIC_CAST group;
19600
0
    return(0);
19601
0
}
19602
19603
/**
19604
 * xmlSchemaCheckAttrPropsCorrect:
19605
 * @item:  an schema attribute declaration/use
19606
 * @ctxt:  a schema parser context
19607
 * @name:  the name of the attribute
19608
 *
19609
 *
19610
 * Schema Component Constraint:
19611
 *    Attribute Declaration Properties Correct (a-props-correct)
19612
 *
19613
 * Validates the value constraints of an attribute declaration/use.
19614
 * NOTE that this needs the simple type definitions to be already
19615
 *   built and checked.
19616
 */
19617
static int
19618
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19619
             xmlSchemaAttributePtr attr)
19620
0
{
19621
19622
    /*
19623
    * SPEC a-props-correct (1)
19624
    * "The values of the properties of an attribute declaration must
19625
    * be as described in the property tableau in The Attribute
19626
    * Declaration Schema Component ($3.2.1), modulo the impact of
19627
    * Missing Sub-components ($5.3)."
19628
    */
19629
19630
0
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
19631
0
  return(0);
19632
19633
0
    if (attr->defValue != NULL) {
19634
0
  int ret;
19635
19636
  /*
19637
  * SPEC a-props-correct (3)
19638
  * "If the {type definition} is or is derived from ID then there
19639
  * must not be a {value constraint}."
19640
  */
19641
0
  if (xmlSchemaIsDerivedFromBuiltInType(
19642
0
      WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19643
0
  {
19644
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19645
0
    XML_SCHEMAP_A_PROPS_CORRECT_3,
19646
0
    NULL, WXS_BASIC_CAST attr,
19647
0
    "Value constraints are not allowed if the type definition "
19648
0
    "is or is derived from xs:ID",
19649
0
    NULL, NULL);
19650
0
      return(pctxt->err);
19651
0
  }
19652
  /*
19653
  * SPEC a-props-correct (2)
19654
  * "if there is a {value constraint}, the canonical lexical
19655
  * representation of its value must be `valid` with respect
19656
  * to the {type definition} as defined in String Valid ($3.14.4)."
19657
  * TODO: Don't care about the *canonical* stuff here, this requirement
19658
  * will be removed in WXS 1.1 anyway.
19659
  */
19660
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19661
0
      attr->node, WXS_ATTR_TYPEDEF(attr),
19662
0
      attr->defValue, &(attr->defVal),
19663
0
      1, 1, 0);
19664
0
  if (ret != 0) {
19665
0
      if (ret < 0) {
19666
0
    PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19667
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19668
0
    return(-1);
19669
0
      }
19670
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19671
0
    XML_SCHEMAP_A_PROPS_CORRECT_2,
19672
0
    NULL, WXS_BASIC_CAST attr,
19673
0
    "The value of the value constraint is not valid",
19674
0
    NULL, NULL);
19675
0
      return(pctxt->err);
19676
0
  }
19677
0
    }
19678
19679
0
    return(0);
19680
0
}
19681
19682
static xmlSchemaElementPtr
19683
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19684
         xmlSchemaElementPtr ancestor)
19685
0
{
19686
0
    xmlSchemaElementPtr ret;
19687
19688
0
    if (WXS_SUBST_HEAD(ancestor) == NULL)
19689
0
  return (NULL);
19690
0
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19691
0
  return (ancestor);
19692
19693
0
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19694
0
  return (NULL);
19695
0
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19696
0
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19697
0
  WXS_SUBST_HEAD(ancestor));
19698
0
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19699
19700
0
    return (ret);
19701
0
}
19702
19703
/**
19704
 * xmlSchemaCheckElemPropsCorrect:
19705
 * @ctxt:  a schema parser context
19706
 * @decl: the element declaration
19707
 * @name:  the name of the attribute
19708
 *
19709
 * Schema Component Constraint:
19710
 * Element Declaration Properties Correct (e-props-correct)
19711
 *
19712
 * STATUS:
19713
 *   missing: (6)
19714
 */
19715
static int
19716
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19717
             xmlSchemaElementPtr elemDecl)
19718
0
{
19719
0
    int ret = 0;
19720
0
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19721
    /*
19722
    * SPEC (1) "The values of the properties of an element declaration
19723
    * must be as described in the property tableau in The Element
19724
    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19725
    * Sub-components ($5.3)."
19726
    */
19727
0
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19728
0
  xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19729
19730
0
  xmlSchemaCheckElementDeclComponent(head, pctxt);
19731
  /*
19732
  * SPEC (3) "If there is a non-`absent` {substitution group
19733
  * affiliation}, then {scope} must be global."
19734
  */
19735
0
  if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19736
0
      xmlSchemaPCustomErr(pctxt,
19737
0
    XML_SCHEMAP_E_PROPS_CORRECT_3,
19738
0
    WXS_BASIC_CAST elemDecl, NULL,
19739
0
    "Only global element declarations can have a "
19740
0
    "substitution group affiliation", NULL);
19741
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19742
0
  }
19743
  /*
19744
  * TODO: SPEC (6) "Circular substitution groups are disallowed.
19745
  * That is, it must not be possible to return to an element declaration
19746
  * by repeatedly following the {substitution group affiliation}
19747
  * property."
19748
  */
19749
0
  if (head == elemDecl)
19750
0
      circ = head;
19751
0
  else if (WXS_SUBST_HEAD(head) != NULL)
19752
0
      circ = xmlSchemaCheckSubstGroupCircular(head, head);
19753
0
  else
19754
0
      circ = NULL;
19755
0
  if (circ != NULL) {
19756
0
      xmlChar *strA = NULL, *strB = NULL;
19757
19758
0
      xmlSchemaPCustomErrExt(pctxt,
19759
0
    XML_SCHEMAP_E_PROPS_CORRECT_6,
19760
0
    WXS_BASIC_CAST circ, NULL,
19761
0
    "The element declaration '%s' defines a circular "
19762
0
    "substitution group to element declaration '%s'",
19763
0
    xmlSchemaGetComponentQName(&strA, circ),
19764
0
    xmlSchemaGetComponentQName(&strB, head),
19765
0
    NULL);
19766
0
      FREE_AND_NULL(strA)
19767
0
      FREE_AND_NULL(strB)
19768
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19769
0
  }
19770
  /*
19771
  * SPEC (4) "If there is a {substitution group affiliation},
19772
  * the {type definition}
19773
  * of the element declaration must be validly derived from the {type
19774
  * definition} of the {substitution group affiliation}, given the value
19775
  * of the {substitution group exclusions} of the {substitution group
19776
  * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19777
  * (if the {type definition} is complex) or as defined in
19778
  * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19779
  * simple)."
19780
  *
19781
  * NOTE: {substitution group exclusions} means the values of the
19782
  * attribute "final".
19783
  */
19784
19785
0
  if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19786
0
      int set = 0;
19787
19788
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19789
0
    set |= SUBSET_EXTENSION;
19790
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19791
0
    set |= SUBSET_RESTRICTION;
19792
19793
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19794
0
    WXS_ELEM_TYPEDEF(head), set) != 0) {
19795
0
    xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19796
19797
0
    ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19798
0
    xmlSchemaPCustomErrExt(pctxt,
19799
0
        XML_SCHEMAP_E_PROPS_CORRECT_4,
19800
0
        WXS_BASIC_CAST elemDecl, NULL,
19801
0
        "The type definition '%s' was "
19802
0
        "either rejected by the substitution group "
19803
0
        "affiliation '%s', or not validly derived from its type "
19804
0
        "definition '%s'",
19805
0
        xmlSchemaGetComponentQName(&strA, typeDef),
19806
0
        xmlSchemaGetComponentQName(&strB, head),
19807
0
        xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19808
0
    FREE_AND_NULL(strA)
19809
0
    FREE_AND_NULL(strB)
19810
0
    FREE_AND_NULL(strC)
19811
0
      }
19812
0
  }
19813
0
    }
19814
    /*
19815
    * SPEC (5) "If the {type definition} or {type definition}'s
19816
    * {content type}
19817
    * is or is derived from ID then there must not be a {value constraint}.
19818
    * Note: The use of ID as a type definition for elements goes beyond
19819
    * XML 1.0, and should be avoided if backwards compatibility is desired"
19820
    */
19821
0
    if ((elemDecl->value != NULL) &&
19822
0
  ((WXS_IS_SIMPLE(typeDef) &&
19823
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19824
0
   (WXS_IS_COMPLEX(typeDef) &&
19825
0
    WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19826
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19827
0
      XML_SCHEMAS_ID)))) {
19828
19829
0
  ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19830
0
  xmlSchemaPCustomErr(pctxt,
19831
0
      XML_SCHEMAP_E_PROPS_CORRECT_5,
19832
0
      WXS_BASIC_CAST elemDecl, NULL,
19833
0
      "The type definition (or type definition's content type) is or "
19834
0
      "is derived from ID; value constraints are not allowed in "
19835
0
      "conjunction with such a type definition", NULL);
19836
0
    } else if (elemDecl->value != NULL) {
19837
0
  int vcret;
19838
0
  xmlNodePtr node = NULL;
19839
19840
  /*
19841
  * SPEC (2) "If there is a {value constraint}, the canonical lexical
19842
  * representation of its value must be `valid` with respect to the
19843
  * {type definition} as defined in Element Default Valid (Immediate)
19844
  * ($3.3.6)."
19845
  */
19846
0
  if (typeDef == NULL) {
19847
0
      xmlSchemaPErr(pctxt, elemDecl->node,
19848
0
    XML_SCHEMAP_INTERNAL,
19849
0
    "Internal error: xmlSchemaCheckElemPropsCorrect, "
19850
0
    "type is missing... skipping validation of "
19851
0
    "the value constraint", NULL, NULL);
19852
0
      return (-1);
19853
0
  }
19854
0
  if (elemDecl->node != NULL) {
19855
0
      if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19856
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19857
0
        BAD_CAST "fixed");
19858
0
      else
19859
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19860
0
        BAD_CAST "default");
19861
0
  }
19862
0
  vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19863
0
      typeDef, elemDecl->value, &(elemDecl->defVal));
19864
0
  if (vcret != 0) {
19865
0
      if (vcret < 0) {
19866
0
    PERROR_INT("xmlSchemaElemCheckValConstr",
19867
0
        "failed to validate the value constraint of an "
19868
0
        "element declaration");
19869
0
    return (-1);
19870
0
      }
19871
0
      return (vcret);
19872
0
  }
19873
0
    }
19874
19875
0
    return (ret);
19876
0
}
19877
19878
/**
19879
 * xmlSchemaCheckElemSubstGroup:
19880
 * @ctxt:  a schema parser context
19881
 * @decl: the element declaration
19882
 * @name:  the name of the attribute
19883
 *
19884
 * Schema Component Constraint:
19885
 * Substitution Group (cos-equiv-class)
19886
 *
19887
 * In Libxml2 the subst. groups will be precomputed, in terms of that
19888
 * a list will be built for each subst. group head, holding all direct
19889
 * referents to this head.
19890
 * NOTE that this function needs:
19891
 *   1. circular subst. groups to be checked beforehand
19892
 *   2. the declaration's type to be derived from the head's type
19893
 *
19894
 * STATUS:
19895
 *
19896
 */
19897
static void
19898
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19899
           xmlSchemaElementPtr elemDecl)
19900
0
{
19901
0
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19902
  /* SPEC (1) "Its {abstract} is false." */
19903
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19904
0
  return;
19905
0
    {
19906
0
  xmlSchemaElementPtr head;
19907
0
  xmlSchemaTypePtr headType, type;
19908
0
  int set, methSet;
19909
  /*
19910
  * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19911
  * {disallowed substitutions} as the blocking constraint, as defined in
19912
  * Substitution Group OK (Transitive) ($3.3.6)."
19913
  */
19914
0
  for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19915
0
      head = WXS_SUBST_HEAD(head)) {
19916
0
      set = 0;
19917
0
      methSet = 0;
19918
      /*
19919
      * The blocking constraints.
19920
      */
19921
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19922
0
    continue;
19923
0
      headType = head->subtypes;
19924
0
      type = elemDecl->subtypes;
19925
0
      if (headType == type)
19926
0
    goto add_member;
19927
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19928
0
    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19929
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19930
0
    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19931
      /*
19932
      * SPEC: Substitution Group OK (Transitive) (2.3)
19933
      * "The set of all {derivation method}s involved in the
19934
      * derivation of D's {type definition} from C's {type definition}
19935
      * does not intersect with the union of the blocking constraint,
19936
      * C's {prohibited substitutions} (if C is complex, otherwise the
19937
      * empty set) and the {prohibited substitutions} (respectively the
19938
      * empty set) of any intermediate {type definition}s in the
19939
      * derivation of D's {type definition} from C's {type definition}."
19940
      */
19941
      /*
19942
      * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19943
      * subst.head axis, the methSet does not need to be computed for
19944
      * the full depth over and over.
19945
      */
19946
      /*
19947
      * The set of all {derivation method}s involved in the derivation
19948
      */
19949
0
      while ((type != NULL) && (type != headType)) {
19950
0
    if ((WXS_IS_EXTENSION(type)) &&
19951
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19952
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19953
19954
0
    if (WXS_IS_RESTRICTION(type) &&
19955
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19956
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19957
19958
0
    type = type->baseType;
19959
0
      }
19960
      /*
19961
      * The {prohibited substitutions} of all intermediate types +
19962
      * the head's type.
19963
      */
19964
0
      type = elemDecl->subtypes->baseType;
19965
0
      while (type != NULL) {
19966
0
    if (WXS_IS_COMPLEX(type)) {
19967
0
        if ((type->flags &
19968
0
          XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19969
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19970
0
        set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19971
0
        if ((type->flags &
19972
0
          XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19973
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19974
0
        set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19975
0
    } else
19976
0
        break;
19977
0
    if (type == headType)
19978
0
        break;
19979
0
    type = type->baseType;
19980
0
      }
19981
0
      if ((set != 0) &&
19982
0
    (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19983
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19984
0
    ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19985
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19986
0
    continue;
19987
0
      }
19988
0
add_member:
19989
0
      xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19990
0
      if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19991
0
    head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19992
0
  }
19993
0
    }
19994
0
}
19995
19996
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19997
/**
19998
 * xmlSchemaCheckElementDeclComponent
19999
 * @pctxt: the schema parser context
20000
 * @ctxtComponent: the context component (an element declaration)
20001
 * @ctxtParticle: the first particle of the context component
20002
 * @searchParticle: the element declaration particle to be analysed
20003
 *
20004
 * Schema Component Constraint: Element Declarations Consistent
20005
 */
20006
static int
20007
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
20008
            xmlSchemaBasicItemPtr ctxtComponent,
20009
            xmlSchemaParticlePtr ctxtParticle,
20010
            xmlSchemaParticlePtr searchParticle,
20011
            xmlSchemaParticlePtr curParticle,
20012
            int search)
20013
{
20014
    return(0);
20015
20016
    int ret = 0;
20017
    xmlSchemaParticlePtr cur = curParticle;
20018
    if (curParticle == NULL) {
20019
  return(0);
20020
    }
20021
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
20022
  /*
20023
  * Just return in this case. A missing "term" of the particle
20024
  * might arise due to an invalid "term" component.
20025
  */
20026
  return(0);
20027
    }
20028
    while (cur != NULL) {
20029
  switch (WXS_PARTICLE_TERM(cur)->type) {
20030
      case XML_SCHEMA_TYPE_ANY:
20031
    break;
20032
      case XML_SCHEMA_TYPE_ELEMENT:
20033
    if (search == 0) {
20034
        ret = xmlSchemaCheckElementDeclConsistent(pctxt,
20035
      ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
20036
        if (ret != 0)
20037
      return(ret);
20038
    } else {
20039
        xmlSchemaElementPtr elem =
20040
      WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
20041
        /*
20042
        * SPEC Element Declarations Consistent:
20043
        * "If the {particles} contains, either directly,
20044
        * indirectly (that is, within the {particles} of a
20045
        * contained model group, recursively) or `implicitly`
20046
        * two or more element declaration particles with
20047
        * the same {name} and {target namespace}, then
20048
        * all their type definitions must be the same
20049
        * top-level definition [...]"
20050
        */
20051
        if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
20052
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
20053
      xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
20054
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
20055
        {
20056
      xmlChar *strA = NULL, *strB = NULL;
20057
20058
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20059
          /* TODO: error code */
20060
          XML_SCHEMAP_COS_NONAMBIG,
20061
          WXS_ITEM_NODE(cur), NULL,
20062
          "In the content model of %s, there are multiple "
20063
          "element declarations for '%s' with different "
20064
          "type definitions",
20065
          xmlSchemaGetComponentDesignation(&strA,
20066
        ctxtComponent),
20067
          xmlSchemaFormatQName(&strB,
20068
        WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
20069
        WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
20070
      FREE_AND_NULL(strA);
20071
      FREE_AND_NULL(strB);
20072
      return(XML_SCHEMAP_COS_NONAMBIG);
20073
        }
20074
    }
20075
    break;
20076
      case XML_SCHEMA_TYPE_SEQUENCE: {
20077
    break;
20078
    }
20079
      case XML_SCHEMA_TYPE_CHOICE:{
20080
    /*
20081
    xmlSchemaTreeItemPtr sub;
20082
20083
    sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
20084
    while (sub != NULL) {
20085
        ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
20086
      ctxtParticle, ctxtElem);
20087
        if (ret != 0)
20088
      return(ret);
20089
        sub = sub->next;
20090
    }
20091
    */
20092
    break;
20093
    }
20094
      case XML_SCHEMA_TYPE_ALL:
20095
    break;
20096
      case XML_SCHEMA_TYPE_GROUP:
20097
    break;
20098
      default:
20099
    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
20100
        "xmlSchemaCheckElementDeclConsistent",
20101
        "found unexpected term of type '%s' in content model",
20102
        WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
20103
    return(-1);
20104
  }
20105
  cur = (xmlSchemaParticlePtr) cur->next;
20106
    }
20107
20108
exit:
20109
    return(ret);
20110
}
20111
#endif
20112
20113
/**
20114
 * xmlSchemaCheckElementDeclComponent
20115
 * @item:  an schema element declaration/particle
20116
 * @ctxt:  a schema parser context
20117
 * @name:  the name of the attribute
20118
 *
20119
 * Validates the value constraints of an element declaration.
20120
 * Adds substitution group members.
20121
 */
20122
static void
20123
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
20124
           xmlSchemaParserCtxtPtr ctxt)
20125
0
{
20126
0
    if (elemDecl == NULL)
20127
0
  return;
20128
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
20129
0
  return;
20130
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
20131
0
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
20132
  /*
20133
  * Adds substitution group members.
20134
  */
20135
0
  xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
20136
0
    }
20137
0
}
20138
20139
/**
20140
 * xmlSchemaResolveModelGroupParticleReferences:
20141
 * @particle:  a particle component
20142
 * @ctxt:  a parser context
20143
 *
20144
 * Resolves references of a model group's {particles} to
20145
 * model group definitions and to element declarations.
20146
 */
20147
static void
20148
xmlSchemaResolveModelGroupParticleReferences(
20149
    xmlSchemaParserCtxtPtr ctxt,
20150
    xmlSchemaModelGroupPtr mg)
20151
0
{
20152
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
20153
0
    xmlSchemaQNameRefPtr ref;
20154
0
    xmlSchemaBasicItemPtr refItem;
20155
20156
    /*
20157
    * URGENT TODO: Test this.
20158
    */
20159
0
    while (particle != NULL) {
20160
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
20161
0
      ((WXS_PARTICLE_TERM(particle))->type !=
20162
0
    XML_SCHEMA_EXTRA_QNAMEREF))
20163
0
  {
20164
0
      goto next_particle;
20165
0
  }
20166
0
  ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
20167
  /*
20168
  * Resolve the reference.
20169
  * NULL the {term} by default.
20170
  */
20171
0
  particle->children = NULL;
20172
20173
0
  refItem = xmlSchemaGetNamedComponent(ctxt->schema,
20174
0
      ref->itemType, ref->name, ref->targetNamespace);
20175
0
  if (refItem == NULL) {
20176
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
20177
0
    NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
20178
0
    ref->targetNamespace, ref->itemType, NULL);
20179
      /* TODO: remove the particle. */
20180
0
      goto next_particle;
20181
0
  }
20182
0
  if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
20183
0
      if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
20184
    /* TODO: remove the particle. */
20185
0
    goto next_particle;
20186
      /*
20187
      * NOTE that we will assign the model group definition
20188
      * itself to the "term" of the particle. This will ease
20189
      * the check for circular model group definitions. After
20190
      * that the "term" will be assigned the model group of the
20191
      * model group definition.
20192
      */
20193
0
      if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20194
0
        XML_SCHEMA_TYPE_ALL) {
20195
    /*
20196
    * SPEC cos-all-limited (1)
20197
    * SPEC cos-all-limited (1.2)
20198
    * "It appears only as the value of one or both of the
20199
    * following properties:"
20200
    * (1.1) "the {model group} property of a model group
20201
    *        definition."
20202
    * (1.2) "the {term} property of a particle [... of] the "
20203
    * {content type} of a complex type definition."
20204
    */
20205
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20206
        /* TODO: error code */
20207
0
        XML_SCHEMAP_COS_ALL_LIMITED,
20208
0
        WXS_ITEM_NODE(particle), NULL,
20209
0
        "A model group definition is referenced, but "
20210
0
        "it contains an 'all' model group, which "
20211
0
        "cannot be contained by model groups",
20212
0
        NULL, NULL);
20213
    /* TODO: remove the particle. */
20214
0
    goto next_particle;
20215
0
      }
20216
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20217
0
  } else {
20218
      /*
20219
      * TODO: Are referenced element declarations the only
20220
      * other components we expect here?
20221
      */
20222
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
20223
0
  }
20224
0
next_particle:
20225
0
  particle = WXS_PTC_CAST particle->next;
20226
0
    }
20227
0
}
20228
20229
static int
20230
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20231
           xmlSchemaValPtr y)
20232
0
{
20233
0
    xmlSchemaTypePtr tx, ty, ptx, pty;
20234
0
    int ret;
20235
20236
0
    while (x != NULL) {
20237
  /* Same types. */
20238
0
  tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20239
0
  ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20240
0
  ptx = xmlSchemaGetPrimitiveType(tx);
20241
0
  pty = xmlSchemaGetPrimitiveType(ty);
20242
  /*
20243
  * (1) if a datatype T' is `derived` by `restriction` from an
20244
  * atomic datatype T then the `value space` of T' is a subset of
20245
  * the `value space` of T. */
20246
  /*
20247
  * (2) if datatypes T' and T'' are `derived` by `restriction`
20248
  * from a common atomic ancestor T then the `value space`s of T'
20249
  * and T'' may overlap.
20250
  */
20251
0
  if (ptx != pty)
20252
0
      return(0);
20253
  /*
20254
  * We assume computed values to be normalized, so do a fast
20255
  * string comparison for string based types.
20256
  */
20257
0
  if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20258
0
      WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20259
0
      if (! xmlStrEqual(
20260
0
    xmlSchemaValueGetAsString(x),
20261
0
    xmlSchemaValueGetAsString(y)))
20262
0
    return (0);
20263
0
  } else {
20264
0
      ret = xmlSchemaCompareValuesWhtsp(
20265
0
    x, XML_SCHEMA_WHITESPACE_PRESERVE,
20266
0
    y, XML_SCHEMA_WHITESPACE_PRESERVE);
20267
0
      if (ret == -2)
20268
0
    return(-1);
20269
0
      if (ret != 0)
20270
0
    return(0);
20271
0
  }
20272
  /*
20273
  * Lists.
20274
  */
20275
0
  x = xmlSchemaValueGetNext(x);
20276
0
  if (x != NULL) {
20277
0
      y = xmlSchemaValueGetNext(y);
20278
0
      if (y == NULL)
20279
0
    return (0);
20280
0
  } else if (xmlSchemaValueGetNext(y) != NULL)
20281
0
      return (0);
20282
0
  else
20283
0
      return (1);
20284
0
    }
20285
0
    return (0);
20286
0
}
20287
20288
/**
20289
 * xmlSchemaResolveAttrUseReferences:
20290
 * @item:  an attribute use
20291
 * @ctxt:  a parser context
20292
 *
20293
 * Resolves the referenced attribute declaration.
20294
 */
20295
static int
20296
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20297
          xmlSchemaParserCtxtPtr ctxt)
20298
0
{
20299
0
    if ((ctxt == NULL) || (ause == NULL))
20300
0
  return(-1);
20301
0
    if ((ause->attrDecl == NULL) ||
20302
0
  (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20303
0
  return(0);
20304
20305
0
    {
20306
0
  xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20307
20308
  /*
20309
  * TODO: Evaluate, what errors could occur if the declaration is not
20310
  * found.
20311
  */
20312
0
  ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20313
0
      ref->name, ref->targetNamespace);
20314
0
        if (ause->attrDecl == NULL) {
20315
0
      xmlSchemaPResCompAttrErr(ctxt,
20316
0
    XML_SCHEMAP_SRC_RESOLVE,
20317
0
    WXS_BASIC_CAST ause, ause->node,
20318
0
    "ref", ref->name, ref->targetNamespace,
20319
0
    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20320
0
            return(ctxt->err);;
20321
0
        }
20322
0
    }
20323
0
    return(0);
20324
0
}
20325
20326
/**
20327
 * xmlSchemaCheckAttrUsePropsCorrect:
20328
 * @ctxt:  a parser context
20329
 * @use:  an attribute use
20330
 *
20331
 * Schema Component Constraint:
20332
 * Attribute Use Correct (au-props-correct)
20333
 *
20334
 */
20335
static int
20336
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20337
           xmlSchemaAttributeUsePtr use)
20338
0
{
20339
0
    if ((ctxt == NULL) || (use == NULL))
20340
0
  return(-1);
20341
0
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20342
0
  ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20343
0
  return(0);
20344
20345
    /*
20346
    * SPEC au-props-correct (1)
20347
    * "The values of the properties of an attribute use must be as
20348
    * described in the property tableau in The Attribute Use Schema
20349
    * Component ($3.5.1), modulo the impact of Missing
20350
    * Sub-components ($5.3)."
20351
    */
20352
20353
0
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20354
0
  ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20355
0
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20356
0
    {
20357
0
  xmlSchemaPCustomErr(ctxt,
20358
0
      XML_SCHEMAP_AU_PROPS_CORRECT_2,
20359
0
      WXS_BASIC_CAST use, NULL,
20360
0
      "The attribute declaration has a 'fixed' value constraint "
20361
0
      ", thus the attribute use must also have a 'fixed' value "
20362
0
      "constraint",
20363
0
      NULL);
20364
0
  return(ctxt->err);
20365
0
    }
20366
    /*
20367
    * Compute and check the value constraint's value.
20368
    */
20369
0
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20370
0
  int ret;
20371
  /*
20372
  * TODO: The spec seems to be missing a check of the
20373
  * value constraint of the attribute use. We will do it here.
20374
  */
20375
  /*
20376
  * SPEC a-props-correct (3)
20377
  */
20378
0
  if (xmlSchemaIsDerivedFromBuiltInType(
20379
0
      WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20380
0
  {
20381
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20382
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20383
0
    NULL, WXS_BASIC_CAST use,
20384
0
    "Value constraints are not allowed if the type definition "
20385
0
    "is or is derived from xs:ID",
20386
0
    NULL, NULL);
20387
0
      return(ctxt->err);
20388
0
  }
20389
20390
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20391
0
      use->node, WXS_ATTRUSE_TYPEDEF(use),
20392
0
      use->defValue, &(use->defVal),
20393
0
      1, 1, 0);
20394
0
  if (ret != 0) {
20395
0
      if (ret < 0) {
20396
0
    PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20397
0
        "calling xmlSchemaVCheckCVCSimpleType()");
20398
0
    return(-1);
20399
0
      }
20400
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20401
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20402
0
    NULL, WXS_BASIC_CAST use,
20403
0
    "The value of the value constraint is not valid",
20404
0
    NULL, NULL);
20405
0
      return(ctxt->err);
20406
0
  }
20407
0
    }
20408
    /*
20409
    * SPEC au-props-correct (2)
20410
    * "If the {attribute declaration} has a fixed
20411
    * {value constraint}, then if the attribute use itself has a
20412
    * {value constraint}, it must also be fixed and its value must match
20413
    * that of the {attribute declaration}'s {value constraint}."
20414
    */
20415
0
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20416
0
  (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20417
0
    {
20418
0
  if (! xmlSchemaAreValuesEqual(use->defVal,
20419
0
    (WXS_ATTRUSE_DECL(use))->defVal))
20420
0
  {
20421
0
      xmlSchemaPCustomErr(ctxt,
20422
0
    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20423
0
    WXS_BASIC_CAST use, NULL,
20424
0
    "The 'fixed' value constraint of the attribute use "
20425
0
    "must match the attribute declaration's value "
20426
0
    "constraint '%s'",
20427
0
    (WXS_ATTRUSE_DECL(use))->defValue);
20428
0
  }
20429
0
  return(ctxt->err);
20430
0
    }
20431
0
    return(0);
20432
0
}
20433
20434
20435
20436
20437
/**
20438
 * xmlSchemaResolveAttrTypeReferences:
20439
 * @item:  an attribute declaration
20440
 * @ctxt:  a parser context
20441
 *
20442
 * Resolves the referenced type definition component.
20443
 */
20444
static int
20445
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20446
           xmlSchemaParserCtxtPtr ctxt)
20447
0
{
20448
    /*
20449
    * The simple type definition corresponding to the <simpleType> element
20450
    * information item in the [children], if present, otherwise the simple
20451
    * type definition `resolved` to by the `actual value` of the type
20452
    * [attribute], if present, otherwise the `simple ur-type definition`.
20453
    */
20454
0
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20455
0
  return(0);
20456
0
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20457
0
    if (item->subtypes != NULL)
20458
0
        return(0);
20459
0
    if (item->typeName != NULL) {
20460
0
        xmlSchemaTypePtr type;
20461
20462
0
  type = xmlSchemaGetType(ctxt->schema, item->typeName,
20463
0
      item->typeNs);
20464
0
  if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20465
0
      xmlSchemaPResCompAttrErr(ctxt,
20466
0
    XML_SCHEMAP_SRC_RESOLVE,
20467
0
    WXS_BASIC_CAST item, item->node,
20468
0
    "type", item->typeName, item->typeNs,
20469
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
20470
0
      return(ctxt->err);
20471
0
  } else
20472
0
      item->subtypes = type;
20473
20474
0
    } else {
20475
  /*
20476
  * The type defaults to the xs:anySimpleType.
20477
  */
20478
0
  item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20479
0
    }
20480
0
    return(0);
20481
0
}
20482
20483
/**
20484
 * xmlSchemaResolveIDCKeyReferences:
20485
 * @idc:  the identity-constraint definition
20486
 * @ctxt:  the schema parser context
20487
 * @name:  the attribute name
20488
 *
20489
 * Resolve keyRef references to key/unique IDCs.
20490
 * Schema Component Constraint:
20491
 *   Identity-constraint Definition Properties Correct (c-props-correct)
20492
 */
20493
static int
20494
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20495
        xmlSchemaParserCtxtPtr pctxt)
20496
0
{
20497
0
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20498
0
        return(0);
20499
0
    if (idc->ref->name != NULL) {
20500
0
  idc->ref->item = (xmlSchemaBasicItemPtr)
20501
0
      xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20502
0
    idc->ref->targetNamespace);
20503
0
        if (idc->ref->item == NULL) {
20504
      /*
20505
      * TODO: It is actually not an error to fail to resolve
20506
      * at this stage. BUT we need to be that strict!
20507
      */
20508
0
      xmlSchemaPResCompAttrErr(pctxt,
20509
0
    XML_SCHEMAP_SRC_RESOLVE,
20510
0
    WXS_BASIC_CAST idc, idc->node,
20511
0
    "refer", idc->ref->name,
20512
0
    idc->ref->targetNamespace,
20513
0
    XML_SCHEMA_TYPE_IDC_KEY, NULL);
20514
0
            return(pctxt->err);
20515
0
  } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20516
      /*
20517
      * SPEC c-props-correct (1)
20518
      */
20519
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20520
0
    XML_SCHEMAP_C_PROPS_CORRECT,
20521
0
    NULL, WXS_BASIC_CAST idc,
20522
0
    "The keyref references a keyref",
20523
0
    NULL, NULL);
20524
0
      idc->ref->item = NULL;
20525
0
      return(pctxt->err);
20526
0
  } else {
20527
0
      if (idc->nbFields !=
20528
0
    ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20529
0
    xmlChar *str = NULL;
20530
0
    xmlSchemaIDCPtr refer;
20531
20532
0
    refer = (xmlSchemaIDCPtr) idc->ref->item;
20533
    /*
20534
    * SPEC c-props-correct(2)
20535
    * "If the {identity-constraint category} is keyref,
20536
    * the cardinality of the {fields} must equal that of
20537
    * the {fields} of the {referenced key}.
20538
    */
20539
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20540
0
        XML_SCHEMAP_C_PROPS_CORRECT,
20541
0
        NULL, WXS_BASIC_CAST idc,
20542
0
        "The cardinality of the keyref differs from the "
20543
0
        "cardinality of the referenced key/unique '%s'",
20544
0
        xmlSchemaFormatQName(&str, refer->targetNamespace,
20545
0
      refer->name),
20546
0
        NULL);
20547
0
    FREE_AND_NULL(str)
20548
0
    return(pctxt->err);
20549
0
      }
20550
0
  }
20551
0
    }
20552
0
    return(0);
20553
0
}
20554
20555
static int
20556
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20557
               xmlSchemaParserCtxtPtr pctxt)
20558
0
{
20559
0
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20560
0
  prohib->targetNamespace) == NULL) {
20561
20562
0
  xmlSchemaPResCompAttrErr(pctxt,
20563
0
      XML_SCHEMAP_SRC_RESOLVE,
20564
0
      NULL, prohib->node,
20565
0
      "ref", prohib->name, prohib->targetNamespace,
20566
0
      XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20567
0
  return(XML_SCHEMAP_SRC_RESOLVE);
20568
0
    }
20569
0
    return(0);
20570
0
}
20571
20572
0
#define WXS_REDEFINED_TYPE(c) \
20573
0
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20574
20575
0
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20576
0
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20577
20578
0
#define WXS_REDEFINED_ATTR_GROUP(c) \
20579
0
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20580
20581
static int
20582
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20583
0
{
20584
0
    int err = 0;
20585
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20586
0
    xmlSchemaBasicItemPtr prev, item;
20587
0
    int wasRedefined;
20588
20589
0
    if (redef == NULL)
20590
0
  return(0);
20591
20592
0
    do {
20593
0
  item = redef->item;
20594
  /*
20595
  * First try to locate the redefined component in the
20596
  * schema graph starting with the redefined schema.
20597
  * NOTE: According to this schema bug entry:
20598
  *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20599
  *   it's not clear if the referenced component needs to originate
20600
  *   from the <redefine>d schema _document_ or the schema; the latter
20601
  *   would include all imported and included sub-schemas of the
20602
  *   <redefine>d schema. Currently the latter approach is used.
20603
  *   SUPPLEMENT: It seems that the WG moves towards the latter
20604
  *   approach, so we are doing it right.
20605
  *
20606
  */
20607
0
  prev = xmlSchemaFindRedefCompInGraph(
20608
0
      redef->targetBucket, item->type,
20609
0
      redef->refName, redef->refTargetNs);
20610
0
  if (prev == NULL) {
20611
0
      xmlChar *str = NULL;
20612
0
      xmlNodePtr node;
20613
20614
      /*
20615
      * SPEC src-redefine:
20616
      * (6.2.1) "The `actual value` of its own name attribute plus
20617
      * target namespace must successfully `resolve` to a model
20618
      * group definition in I."
20619
      * (7.2.1) "The `actual value` of its own name attribute plus
20620
      * target namespace must successfully `resolve` to an attribute
20621
      * group definition in I."
20622
20623
      *
20624
      * Note that, if we are redefining with the use of references
20625
      * to components, the spec assumes the src-resolve to be used;
20626
      * but this won't assure that we search only *inside* the
20627
      * redefined schema.
20628
      */
20629
0
      if (redef->reference)
20630
0
    node = WXS_ITEM_NODE(redef->reference);
20631
0
      else
20632
0
    node = WXS_ITEM_NODE(item);
20633
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20634
    /*
20635
    * TODO: error code.
20636
    * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20637
    * reference kind.
20638
    */
20639
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20640
0
    "The %s '%s' to be redefined could not be found in "
20641
0
    "the redefined schema",
20642
0
    WXS_ITEM_TYPE_NAME(item),
20643
0
    xmlSchemaFormatQName(&str, redef->refTargetNs,
20644
0
        redef->refName));
20645
0
      FREE_AND_NULL(str);
20646
0
      err = pctxt->err;
20647
0
      redef = redef->next;
20648
0
      continue;
20649
0
  }
20650
  /*
20651
  * TODO: Obtaining and setting the redefinition state is really
20652
  * clumsy.
20653
  */
20654
0
  wasRedefined = 0;
20655
0
  switch (item->type) {
20656
0
      case XML_SCHEMA_TYPE_COMPLEX:
20657
0
      case XML_SCHEMA_TYPE_SIMPLE:
20658
0
    if ((WXS_TYPE_CAST prev)->flags &
20659
0
        XML_SCHEMAS_TYPE_REDEFINED)
20660
0
    {
20661
0
        wasRedefined = 1;
20662
0
        break;
20663
0
    }
20664
    /* Mark it as redefined. */
20665
0
    (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20666
    /*
20667
    * Assign the redefined type to the
20668
    * base type of the redefining type.
20669
    * TODO: How
20670
    */
20671
0
    ((xmlSchemaTypePtr) item)->baseType =
20672
0
        (xmlSchemaTypePtr) prev;
20673
0
    break;
20674
0
      case XML_SCHEMA_TYPE_GROUP:
20675
0
    if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20676
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20677
0
    {
20678
0
        wasRedefined = 1;
20679
0
        break;
20680
0
    }
20681
    /* Mark it as redefined. */
20682
0
    (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20683
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20684
0
    if (redef->reference != NULL) {
20685
        /*
20686
        * Overwrite the QName-reference with the
20687
        * referenced model group def.
20688
        */
20689
0
        (WXS_PTC_CAST redef->reference)->children =
20690
0
      WXS_TREE_CAST prev;
20691
0
    }
20692
0
    redef->target = prev;
20693
0
    break;
20694
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20695
0
    if ((WXS_ATTR_GROUP_CAST prev)->flags &
20696
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED)
20697
0
    {
20698
0
        wasRedefined = 1;
20699
0
        break;
20700
0
    }
20701
0
    (WXS_ATTR_GROUP_CAST prev)->flags |=
20702
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED;
20703
0
    if (redef->reference != NULL) {
20704
        /*
20705
        * Assign the redefined attribute group to the
20706
        * QName-reference component.
20707
        * This is the easy case, since we will just
20708
        * expand the redefined group.
20709
        */
20710
0
        (WXS_QNAME_CAST redef->reference)->item = prev;
20711
0
        redef->target = NULL;
20712
0
    } else {
20713
        /*
20714
        * This is the complicated case: we need
20715
        * to apply src-redefine (7.2.2) at a later
20716
        * stage, i.e. when attribute group references
20717
        * have been expanded and simple types have
20718
        * been fixed.
20719
        */
20720
0
        redef->target = prev;
20721
0
    }
20722
0
    break;
20723
0
      default:
20724
0
    PERROR_INT("xmlSchemaResolveRedefReferences",
20725
0
        "Unexpected redefined component type");
20726
0
    return(-1);
20727
0
  }
20728
0
  if (wasRedefined) {
20729
0
      xmlChar *str = NULL;
20730
0
      xmlNodePtr node;
20731
20732
0
      if (redef->reference)
20733
0
    node = WXS_ITEM_NODE(redef->reference);
20734
0
      else
20735
0
    node = WXS_ITEM_NODE(redef->item);
20736
20737
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20738
    /* TODO: error code. */
20739
0
    XML_SCHEMAP_SRC_REDEFINE,
20740
0
    node, NULL,
20741
0
    "The referenced %s was already redefined. Multiple "
20742
0
    "redefinition of the same component is not supported",
20743
0
    xmlSchemaGetComponentDesignation(&str, prev),
20744
0
    NULL);
20745
0
      FREE_AND_NULL(str)
20746
0
      err = pctxt->err;
20747
0
      redef = redef->next;
20748
0
      continue;
20749
0
  }
20750
0
  redef = redef->next;
20751
0
    } while (redef != NULL);
20752
20753
0
    return(err);
20754
0
}
20755
20756
static int
20757
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20758
0
{
20759
0
    int err = 0;
20760
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20761
0
    xmlSchemaBasicItemPtr item;
20762
20763
0
    if (redef == NULL)
20764
0
  return(0);
20765
20766
0
    do {
20767
0
  if (redef->target == NULL) {
20768
0
      redef = redef->next;
20769
0
      continue;
20770
0
  }
20771
0
  item = redef->item;
20772
20773
0
  switch (item->type) {
20774
0
      case XML_SCHEMA_TYPE_SIMPLE:
20775
0
      case XML_SCHEMA_TYPE_COMPLEX:
20776
    /*
20777
    * Since the spec wants the {name} of the redefined
20778
    * type to be 'absent', we'll NULL it.
20779
    */
20780
0
    (WXS_TYPE_CAST redef->target)->name = NULL;
20781
20782
    /*
20783
    * TODO: Seems like there's nothing more to do. The normal
20784
    * inheritance mechanism is used. But not 100% sure.
20785
    */
20786
0
    break;
20787
0
      case XML_SCHEMA_TYPE_GROUP:
20788
    /*
20789
    * URGENT TODO:
20790
    * SPEC src-redefine:
20791
    * (6.2.2) "The {model group} of the model group definition
20792
    * which corresponds to it per XML Representation of Model
20793
    * Group Definition Schema Components ($3.7.2) must be a
20794
    * `valid restriction` of the {model group} of that model
20795
    * group definition in I, as defined in Particle Valid
20796
    * (Restriction) ($3.9.6)."
20797
    */
20798
0
    break;
20799
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20800
    /*
20801
    * SPEC src-redefine:
20802
    * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20803
    * the attribute group definition which corresponds to it
20804
    * per XML Representation of Attribute Group Definition Schema
20805
    * Components ($3.6.2) must be `valid restrictions` of the
20806
    * {attribute uses} and {attribute wildcard} of that attribute
20807
    * group definition in I, as defined in clause 2, clause 3 and
20808
    * clause 4 of Derivation Valid (Restriction, Complex)
20809
    * ($3.4.6) (where references to the base type definition are
20810
    * understood as references to the attribute group definition
20811
    * in I)."
20812
    */
20813
0
    err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20814
0
        XML_SCHEMA_ACTION_REDEFINE,
20815
0
        item, redef->target,
20816
0
        (WXS_ATTR_GROUP_CAST item)->attrUses,
20817
0
        (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20818
0
        (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20819
0
        (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20820
0
    if (err == -1)
20821
0
        return(-1);
20822
0
    break;
20823
0
      default:
20824
0
    break;
20825
0
  }
20826
0
  redef = redef->next;
20827
0
    } while (redef != NULL);
20828
0
    return(0);
20829
0
}
20830
20831
20832
static int
20833
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20834
           xmlSchemaBucketPtr bucket)
20835
0
{
20836
0
    xmlSchemaBasicItemPtr item;
20837
0
    int err;
20838
0
    xmlHashTablePtr *table;
20839
0
    const xmlChar *name;
20840
0
    int i;
20841
20842
0
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20843
0
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20844
0
  table = &(WXS_IMPBUCKET((c))->schema->slot); \
20845
0
    else \
20846
0
  table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20847
20848
    /*
20849
    * Add global components to the schema's hash tables.
20850
    * This is the place where duplicate components will be
20851
    * detected.
20852
    * TODO: I think normally we should support imports of the
20853
    *   same namespace from multiple locations. We don't do currently,
20854
    *   but if we do then according to:
20855
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20856
    *   we would need, if imported directly, to import redefined
20857
    *   components as well to be able to catch clashing components.
20858
    *   (I hope I'll still know what this means after some months :-()
20859
    */
20860
0
    if (bucket == NULL)
20861
0
  return(-1);
20862
0
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20863
0
  return(0);
20864
0
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20865
20866
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
20867
0
  item = bucket->globals->items[i];
20868
0
  table = NULL;
20869
0
  switch (item->type) {
20870
0
      case XML_SCHEMA_TYPE_COMPLEX:
20871
0
      case XML_SCHEMA_TYPE_SIMPLE:
20872
0
    if (WXS_REDEFINED_TYPE(item))
20873
0
        continue;
20874
0
    name = (WXS_TYPE_CAST item)->name;
20875
0
    WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20876
0
    break;
20877
0
      case XML_SCHEMA_TYPE_ELEMENT:
20878
0
    name = (WXS_ELEM_CAST item)->name;
20879
0
    WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20880
0
    break;
20881
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20882
0
    name = (WXS_ATTR_CAST item)->name;
20883
0
    WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20884
0
    break;
20885
0
      case XML_SCHEMA_TYPE_GROUP:
20886
0
    if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20887
0
        continue;
20888
0
    name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20889
0
    WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20890
0
    break;
20891
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20892
0
    if (WXS_REDEFINED_ATTR_GROUP(item))
20893
0
        continue;
20894
0
    name = (WXS_ATTR_GROUP_CAST item)->name;
20895
0
    WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20896
0
    break;
20897
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20898
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20899
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20900
0
    name = (WXS_IDC_CAST item)->name;
20901
0
    WXS_GET_GLOBAL_HASH(bucket, idcDef)
20902
0
    break;
20903
0
      case XML_SCHEMA_TYPE_NOTATION:
20904
0
    name = ((xmlSchemaNotationPtr) item)->name;
20905
0
    WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20906
0
    break;
20907
0
      default:
20908
0
    PERROR_INT("xmlSchemaAddComponents",
20909
0
        "Unexpected global component type");
20910
0
    continue;
20911
0
  }
20912
0
  if (*table == NULL) {
20913
0
      *table = xmlHashCreateDict(10, pctxt->dict);
20914
0
      if (*table == NULL) {
20915
0
    PERROR_INT("xmlSchemaAddComponents",
20916
0
        "failed to create a component hash table");
20917
0
    return(-1);
20918
0
      }
20919
0
  }
20920
0
  err = xmlHashAddEntry(*table, name, item);
20921
0
  if (err != 0) {
20922
0
      xmlChar *str = NULL;
20923
20924
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20925
0
    XML_SCHEMAP_REDEFINED_TYPE,
20926
0
    WXS_ITEM_NODE(item),
20927
0
    WXS_BASIC_CAST item,
20928
0
    "A global %s '%s' does already exist",
20929
0
    WXS_ITEM_TYPE_NAME(item),
20930
0
    xmlSchemaGetComponentQName(&str, item));
20931
0
      FREE_AND_NULL(str);
20932
0
  }
20933
0
    }
20934
    /*
20935
    * Process imported/included schemas.
20936
    */
20937
0
    if (bucket->relations != NULL) {
20938
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
20939
0
  do {
20940
0
      if ((rel->bucket != NULL) &&
20941
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20942
0
    if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20943
0
        return(-1);
20944
0
      }
20945
0
      rel = rel->next;
20946
0
  } while (rel != NULL);
20947
0
    }
20948
0
    return(0);
20949
0
}
20950
20951
static int
20952
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20953
       xmlSchemaBucketPtr rootBucket)
20954
0
{
20955
0
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20956
0
    xmlSchemaTreeItemPtr item, *items;
20957
0
    int nbItems, i, ret = 0;
20958
0
    xmlSchemaBucketPtr oldbucket = con->bucket;
20959
0
    xmlSchemaElementPtr elemDecl;
20960
20961
0
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20962
20963
0
    if ((con->pending == NULL) ||
20964
0
  (con->pending->nbItems == 0))
20965
0
  return(0);
20966
20967
    /*
20968
    * Since xmlSchemaFixupComplexType() will create new particles
20969
    * (local components), and those particle components need a bucket
20970
    * on the constructor, we'll assure here that the constructor has
20971
    * a bucket.
20972
    * TODO: Think about storing locals _only_ on the main bucket.
20973
    */
20974
0
    if (con->bucket == NULL)
20975
0
  con->bucket = rootBucket;
20976
20977
    /* TODO:
20978
    * SPEC (src-redefine):
20979
    * (6.2) "If it has no such self-reference, then all of the
20980
    * following must be true:"
20981
20982
    * (6.2.2) The {model group} of the model group definition which
20983
    * corresponds to it per XML Representation of Model Group
20984
    * Definition Schema Components ($3.7.2) must be a `valid
20985
    * restriction` of the {model group} of that model group definition
20986
    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20987
    */
20988
0
    xmlSchemaCheckSRCRedefineFirst(pctxt);
20989
20990
    /*
20991
    * Add global components to the schemata's hash tables.
20992
    */
20993
0
    xmlSchemaAddComponents(pctxt, rootBucket);
20994
20995
0
    pctxt->ctxtType = NULL;
20996
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
20997
0
    nbItems = con->pending->nbItems;
20998
    /*
20999
    * Now that we have parsed *all* the schema document(s) and converted
21000
    * them to schema components, we can resolve references, apply component
21001
    * constraints, create the FSA from the content model, etc.
21002
    */
21003
    /*
21004
    * Resolve references of..
21005
    *
21006
    * 1. element declarations:
21007
    *   - the type definition
21008
    *   - the substitution group affiliation
21009
    * 2. simple/complex types:
21010
    *   - the base type definition
21011
    *   - the memberTypes of union types
21012
    *   - the itemType of list types
21013
    * 3. attributes declarations and attribute uses:
21014
    *   - the type definition
21015
    *   - if an attribute use, then the attribute declaration
21016
    * 4. attribute group references:
21017
    *   - the attribute group definition
21018
    * 5. particles:
21019
    *   - the term of the particle (e.g. a model group)
21020
    * 6. IDC key-references:
21021
    *   - the referenced IDC 'key' or 'unique' definition
21022
    * 7. Attribute prohibitions which had a "ref" attribute.
21023
    */
21024
0
    for (i = 0; i < nbItems; i++) {
21025
0
  item = items[i];
21026
0
  switch (item->type) {
21027
0
      case XML_SCHEMA_TYPE_ELEMENT:
21028
0
    xmlSchemaResolveElementReferences(
21029
0
        (xmlSchemaElementPtr) item, pctxt);
21030
0
    FIXHFAILURE;
21031
0
    break;
21032
0
      case XML_SCHEMA_TYPE_COMPLEX:
21033
0
      case XML_SCHEMA_TYPE_SIMPLE:
21034
0
    xmlSchemaResolveTypeReferences(
21035
0
        (xmlSchemaTypePtr) item, pctxt);
21036
0
    FIXHFAILURE;
21037
0
    break;
21038
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21039
0
    xmlSchemaResolveAttrTypeReferences(
21040
0
        (xmlSchemaAttributePtr) item, pctxt);
21041
0
    FIXHFAILURE;
21042
0
    break;
21043
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21044
0
    xmlSchemaResolveAttrUseReferences(
21045
0
        (xmlSchemaAttributeUsePtr) item, pctxt);
21046
0
    FIXHFAILURE;
21047
0
    break;
21048
0
      case XML_SCHEMA_EXTRA_QNAMEREF:
21049
0
    if ((WXS_QNAME_CAST item)->itemType ==
21050
0
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
21051
0
    {
21052
0
        xmlSchemaResolveAttrGroupReferences(
21053
0
      WXS_QNAME_CAST item, pctxt);
21054
0
    }
21055
0
    FIXHFAILURE;
21056
0
    break;
21057
0
      case XML_SCHEMA_TYPE_SEQUENCE:
21058
0
      case XML_SCHEMA_TYPE_CHOICE:
21059
0
      case XML_SCHEMA_TYPE_ALL:
21060
0
    xmlSchemaResolveModelGroupParticleReferences(pctxt,
21061
0
        WXS_MODEL_GROUP_CAST item);
21062
0
    FIXHFAILURE;
21063
0
    break;
21064
0
      case XML_SCHEMA_TYPE_IDC_KEY:
21065
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
21066
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
21067
0
    xmlSchemaResolveIDCKeyReferences(
21068
0
        (xmlSchemaIDCPtr) item, pctxt);
21069
0
    FIXHFAILURE;
21070
0
    break;
21071
0
      case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
21072
    /*
21073
    * Handle attribute prohibition which had a
21074
    * "ref" attribute.
21075
    */
21076
0
    xmlSchemaResolveAttrUseProhibReferences(
21077
0
        WXS_ATTR_PROHIB_CAST item, pctxt);
21078
0
    FIXHFAILURE;
21079
0
    break;
21080
0
      default:
21081
0
    break;
21082
0
  }
21083
0
    }
21084
0
    if (pctxt->nberrors != 0)
21085
0
  goto exit_error;
21086
21087
    /*
21088
    * Now that all references are resolved we
21089
    * can check for circularity of...
21090
    * 1. the base axis of type definitions
21091
    * 2. nested model group definitions
21092
    * 3. nested attribute group definitions
21093
    * TODO: check for circular substitution groups.
21094
    */
21095
0
    for (i = 0; i < nbItems; i++) {
21096
0
  item = items[i];
21097
  /*
21098
  * Let's better stop on the first error here.
21099
  */
21100
0
  switch (item->type) {
21101
0
      case XML_SCHEMA_TYPE_COMPLEX:
21102
0
      case XML_SCHEMA_TYPE_SIMPLE:
21103
0
    xmlSchemaCheckTypeDefCircular(
21104
0
        (xmlSchemaTypePtr) item, pctxt);
21105
0
    FIXHFAILURE;
21106
0
    if (pctxt->nberrors != 0)
21107
0
        goto exit_error;
21108
0
    break;
21109
0
      case XML_SCHEMA_TYPE_GROUP:
21110
0
    xmlSchemaCheckGroupDefCircular(
21111
0
        (xmlSchemaModelGroupDefPtr) item, pctxt);
21112
0
    FIXHFAILURE;
21113
0
    if (pctxt->nberrors != 0)
21114
0
        goto exit_error;
21115
0
    break;
21116
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21117
0
    xmlSchemaCheckAttrGroupCircular(
21118
0
        (xmlSchemaAttributeGroupPtr) item, pctxt);
21119
0
    FIXHFAILURE;
21120
0
    if (pctxt->nberrors != 0)
21121
0
        goto exit_error;
21122
0
    break;
21123
0
      default:
21124
0
    break;
21125
0
  }
21126
0
    }
21127
0
    if (pctxt->nberrors != 0)
21128
0
  goto exit_error;
21129
    /*
21130
    * Model group definition references:
21131
    * Such a reference is reflected by a particle at the component
21132
    * level. Until now the 'term' of such particles pointed
21133
    * to the model group definition; this was done, in order to
21134
    * ease circularity checks. Now we need to set the 'term' of
21135
    * such particles to the model group of the model group definition.
21136
    */
21137
0
    for (i = 0; i < nbItems; i++) {
21138
0
  item = items[i];
21139
0
  switch (item->type) {
21140
0
      case XML_SCHEMA_TYPE_SEQUENCE:
21141
0
      case XML_SCHEMA_TYPE_CHOICE:
21142
0
    xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
21143
0
        WXS_MODEL_GROUP_CAST item);
21144
0
    break;
21145
0
      default:
21146
0
    break;
21147
0
  }
21148
0
    }
21149
0
    if (pctxt->nberrors != 0)
21150
0
  goto exit_error;
21151
    /*
21152
    * Expand attribute group references of attribute group definitions.
21153
    */
21154
0
    for (i = 0; i < nbItems; i++) {
21155
0
  item = items[i];
21156
0
  switch (item->type) {
21157
0
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21158
0
    if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
21159
0
        WXS_ATTR_GROUP_HAS_REFS(item))
21160
0
    {
21161
0
        xmlSchemaAttributeGroupExpandRefs(pctxt,
21162
0
      WXS_ATTR_GROUP_CAST item);
21163
0
        FIXHFAILURE;
21164
0
    }
21165
0
    break;
21166
0
      default:
21167
0
    break;
21168
0
  }
21169
0
    }
21170
0
    if (pctxt->nberrors != 0)
21171
0
  goto exit_error;
21172
    /*
21173
    * First compute the variety of simple types. This is needed as
21174
    * a separate step, since otherwise we won't be able to detect
21175
    * circular union types in all cases.
21176
    */
21177
0
    for (i = 0; i < nbItems; i++) {
21178
0
  item = items[i];
21179
0
  switch (item->type) {
21180
0
            case XML_SCHEMA_TYPE_SIMPLE:
21181
0
    if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
21182
0
        xmlSchemaFixupSimpleTypeStageOne(pctxt,
21183
0
      (xmlSchemaTypePtr) item);
21184
0
        FIXHFAILURE;
21185
0
    }
21186
0
    break;
21187
0
      default:
21188
0
    break;
21189
0
  }
21190
0
    }
21191
0
    if (pctxt->nberrors != 0)
21192
0
  goto exit_error;
21193
    /*
21194
    * Detect circular union types. Note that this needs the variety to
21195
    * be already computed.
21196
    */
21197
0
    for (i = 0; i < nbItems; i++) {
21198
0
  item = items[i];
21199
0
  switch (item->type) {
21200
0
            case XML_SCHEMA_TYPE_SIMPLE:
21201
0
    if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21202
0
        xmlSchemaCheckUnionTypeDefCircular(pctxt,
21203
0
      (xmlSchemaTypePtr) item);
21204
0
        FIXHFAILURE;
21205
0
    }
21206
0
    break;
21207
0
      default:
21208
0
    break;
21209
0
  }
21210
0
    }
21211
0
    if (pctxt->nberrors != 0)
21212
0
  goto exit_error;
21213
21214
    /*
21215
    * Do the complete type fixup for simple types.
21216
    */
21217
0
    for (i = 0; i < nbItems; i++) {
21218
0
  item = items[i];
21219
0
  switch (item->type) {
21220
0
            case XML_SCHEMA_TYPE_SIMPLE:
21221
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21222
0
        xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21223
0
        FIXHFAILURE;
21224
0
    }
21225
0
    break;
21226
0
      default:
21227
0
    break;
21228
0
  }
21229
0
    }
21230
0
    if (pctxt->nberrors != 0)
21231
0
  goto exit_error;
21232
    /*
21233
    * At this point we need build and check all simple types.
21234
    */
21235
    /*
21236
    * Apply constraints for attribute declarations.
21237
    */
21238
0
    for (i = 0; i < nbItems; i++) {
21239
0
  item = items[i];
21240
0
  switch (item->type) {
21241
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21242
0
    xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21243
0
    FIXHFAILURE;
21244
0
    break;
21245
0
      default:
21246
0
    break;
21247
0
  }
21248
0
    }
21249
0
    if (pctxt->nberrors != 0)
21250
0
  goto exit_error;
21251
    /*
21252
    * Apply constraints for attribute uses.
21253
    */
21254
0
    for (i = 0; i < nbItems; i++) {
21255
0
  item = items[i];
21256
0
  switch (item->type) {
21257
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21258
0
    if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21259
0
        xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21260
0
      WXS_ATTR_USE_CAST item);
21261
0
        FIXHFAILURE;
21262
0
    }
21263
0
    break;
21264
0
      default:
21265
0
    break;
21266
0
  }
21267
0
    }
21268
0
    if (pctxt->nberrors != 0)
21269
0
  goto exit_error;
21270
21271
    /*
21272
    * Apply constraints for attribute group definitions.
21273
    */
21274
0
    for (i = 0; i < nbItems; i++) {
21275
0
  item = items[i];
21276
0
  switch (item->type) {
21277
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21278
0
      if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21279
0
    ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21280
0
      {
21281
0
    xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21282
0
    FIXHFAILURE;
21283
0
      }
21284
0
      break;
21285
0
  default:
21286
0
      break;
21287
0
  }
21288
0
    }
21289
0
    if (pctxt->nberrors != 0)
21290
0
  goto exit_error;
21291
21292
    /*
21293
    * Apply constraints for redefinitions.
21294
    */
21295
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21296
0
  xmlSchemaCheckSRCRedefineSecond(pctxt);
21297
0
    if (pctxt->nberrors != 0)
21298
0
  goto exit_error;
21299
21300
    /*
21301
    * Complex types are built and checked.
21302
    */
21303
0
    for (i = 0; i < nbItems; i++) {
21304
0
  item = con->pending->items[i];
21305
0
  switch (item->type) {
21306
0
      case XML_SCHEMA_TYPE_COMPLEX:
21307
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21308
0
        xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21309
0
        FIXHFAILURE;
21310
0
    }
21311
0
    break;
21312
0
      default:
21313
0
    break;
21314
0
  }
21315
0
    }
21316
0
    if (pctxt->nberrors != 0)
21317
0
  goto exit_error;
21318
21319
    /*
21320
    * The list could have changed, since xmlSchemaFixupComplexType()
21321
    * will create particles and model groups in some cases.
21322
    */
21323
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
21324
0
    nbItems = con->pending->nbItems;
21325
21326
    /*
21327
    * Apply some constraints for element declarations.
21328
    */
21329
0
    for (i = 0; i < nbItems; i++) {
21330
0
  item = items[i];
21331
0
  switch (item->type) {
21332
0
      case XML_SCHEMA_TYPE_ELEMENT:
21333
0
    elemDecl = (xmlSchemaElementPtr) item;
21334
21335
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21336
0
    {
21337
0
        xmlSchemaCheckElementDeclComponent(
21338
0
      (xmlSchemaElementPtr) elemDecl, pctxt);
21339
0
        FIXHFAILURE;
21340
0
    }
21341
21342
#ifdef WXS_ELEM_DECL_CONS_ENABLED
21343
    /*
21344
    * Schema Component Constraint: Element Declarations Consistent
21345
    * Apply this constraint to local types of element declarations.
21346
    */
21347
    if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21348
        (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21349
        (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21350
    {
21351
        xmlSchemaCheckElementDeclConsistent(pctxt,
21352
      WXS_BASIC_CAST elemDecl,
21353
      WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21354
      NULL, NULL, 0);
21355
    }
21356
#endif
21357
0
    break;
21358
0
      default:
21359
0
    break;
21360
0
  }
21361
0
    }
21362
0
    if (pctxt->nberrors != 0)
21363
0
  goto exit_error;
21364
21365
    /*
21366
    * Finally we can build the automaton from the content model of
21367
    * complex types.
21368
    */
21369
21370
0
    for (i = 0; i < nbItems; i++) {
21371
0
  item = items[i];
21372
0
  switch (item->type) {
21373
0
      case XML_SCHEMA_TYPE_COMPLEX:
21374
0
    xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21375
    /* FIXHFAILURE; */
21376
0
    break;
21377
0
      default:
21378
0
    break;
21379
0
  }
21380
0
    }
21381
0
    if (pctxt->nberrors != 0)
21382
0
  goto exit_error;
21383
    /*
21384
    * URGENT TODO: cos-element-consistent
21385
    */
21386
0
    goto exit;
21387
21388
0
exit_error:
21389
0
    ret = pctxt->err;
21390
0
    goto exit;
21391
21392
0
exit_failure:
21393
0
    ret = -1;
21394
21395
0
exit:
21396
    /*
21397
    * Reset the constructor. This is needed for XSI acquisition, since
21398
    * those items will be processed over and over again for every XSI
21399
    * if not cleared here.
21400
    */
21401
0
    con->bucket = oldbucket;
21402
0
    con->pending->nbItems = 0;
21403
0
    if (con->substGroups != NULL) {
21404
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21405
0
  con->substGroups = NULL;
21406
0
    }
21407
0
    if (con->redefs != NULL) {
21408
0
  xmlSchemaRedefListFree(con->redefs);
21409
0
  con->redefs = NULL;
21410
0
    }
21411
0
    return(ret);
21412
0
}
21413
/**
21414
 * xmlSchemaParse:
21415
 * @ctxt:  a schema validation context
21416
 *
21417
 * parse a schema definition resource and build an internal
21418
 * XML Schema structure which can be used to validate instances.
21419
 *
21420
 * Returns the internal XML Schema structure built from the resource or
21421
 *         NULL in case of error
21422
 */
21423
xmlSchemaPtr
21424
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21425
0
{
21426
0
    xmlSchemaPtr mainSchema = NULL;
21427
0
    xmlSchemaBucketPtr bucket = NULL;
21428
0
    int res;
21429
21430
    /*
21431
    * This one is used if the schema to be parsed was specified via
21432
    * the API; i.e. not automatically by the validated instance document.
21433
    */
21434
21435
0
    xmlSchemaInitTypes();
21436
21437
0
    if (ctxt == NULL)
21438
0
        return (NULL);
21439
21440
    /* TODO: Init the context. Is this all we need?*/
21441
0
    ctxt->nberrors = 0;
21442
0
    ctxt->err = 0;
21443
0
    ctxt->counter = 0;
21444
21445
    /* Create the *main* schema. */
21446
0
    mainSchema = xmlSchemaNewSchema(ctxt);
21447
0
    if (mainSchema == NULL)
21448
0
  goto exit_failure;
21449
    /*
21450
    * Create the schema constructor.
21451
    */
21452
0
    if (ctxt->constructor == NULL) {
21453
0
  ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21454
0
  if (ctxt->constructor == NULL)
21455
0
      return(NULL);
21456
  /* Take ownership of the constructor to be able to free it. */
21457
0
  ctxt->ownsConstructor = 1;
21458
0
    }
21459
0
    ctxt->constructor->mainSchema = mainSchema;
21460
    /*
21461
    * Locate and add the schema document.
21462
    */
21463
0
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21464
0
  ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21465
0
  NULL, NULL, &bucket);
21466
0
    if (res == -1)
21467
0
  goto exit_failure;
21468
0
    if (res != 0)
21469
0
  goto exit;
21470
21471
0
    if (bucket == NULL) {
21472
  /* TODO: Error code, actually we failed to *locate* the schema. */
21473
0
  if (ctxt->URL)
21474
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21475
0
    NULL, NULL,
21476
0
    "Failed to locate the main schema resource at '%s'",
21477
0
    ctxt->URL, NULL);
21478
0
  else
21479
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21480
0
    NULL, NULL,
21481
0
    "Failed to locate the main schema resource",
21482
0
        NULL, NULL);
21483
0
  goto exit;
21484
0
    }
21485
    /* Then do the parsing for good. */
21486
0
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21487
0
  goto exit_failure;
21488
0
    if (ctxt->nberrors != 0)
21489
0
  goto exit;
21490
21491
0
    mainSchema->doc = bucket->doc;
21492
0
    mainSchema->preserve = ctxt->preserve;
21493
21494
0
    ctxt->schema = mainSchema;
21495
21496
0
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21497
0
  goto exit_failure;
21498
21499
    /*
21500
    * TODO: This is not nice, since we cannot distinguish from the
21501
    * result if there was an internal error or not.
21502
    */
21503
0
exit:
21504
0
    if (ctxt->nberrors != 0) {
21505
0
  if (mainSchema) {
21506
0
      xmlSchemaFree(mainSchema);
21507
0
      mainSchema = NULL;
21508
0
  }
21509
0
  if (ctxt->constructor) {
21510
0
      xmlSchemaConstructionCtxtFree(ctxt->constructor);
21511
0
      ctxt->constructor = NULL;
21512
0
      ctxt->ownsConstructor = 0;
21513
0
  }
21514
0
    }
21515
0
    ctxt->schema = NULL;
21516
0
    return(mainSchema);
21517
0
exit_failure:
21518
    /*
21519
    * Quite verbose, but should catch internal errors, which were
21520
    * not communicated.
21521
    */
21522
0
    if (mainSchema) {
21523
0
        xmlSchemaFree(mainSchema);
21524
0
  mainSchema = NULL;
21525
0
    }
21526
0
    if (ctxt->constructor) {
21527
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
21528
0
  ctxt->constructor = NULL;
21529
0
  ctxt->ownsConstructor = 0;
21530
0
    }
21531
0
    PERROR_INT2("xmlSchemaParse",
21532
0
  "An internal error occurred");
21533
0
    ctxt->schema = NULL;
21534
0
    return(NULL);
21535
0
}
21536
21537
/**
21538
 * xmlSchemaSetParserErrors:
21539
 * @ctxt:  a schema validation context
21540
 * @err:  the error callback
21541
 * @warn:  the warning callback
21542
 * @ctx:  contextual data for the callbacks
21543
 *
21544
 * Set the callback functions used to handle errors for a validation context
21545
 */
21546
void
21547
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21548
                         xmlSchemaValidityErrorFunc err,
21549
                         xmlSchemaValidityWarningFunc warn, void *ctx)
21550
0
{
21551
0
    if (ctxt == NULL)
21552
0
        return;
21553
0
    ctxt->error = err;
21554
0
    ctxt->warning = warn;
21555
0
    ctxt->errCtxt = ctx;
21556
0
    if (ctxt->vctxt != NULL)
21557
0
  xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21558
0
}
21559
21560
/**
21561
 * xmlSchemaSetParserStructuredErrors:
21562
 * @ctxt:  a schema parser context
21563
 * @serror:  the structured error function
21564
 * @ctx: the functions context
21565
 *
21566
 * Set the structured error callback
21567
 */
21568
void
21569
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21570
           xmlStructuredErrorFunc serror,
21571
           void *ctx)
21572
0
{
21573
0
    if (ctxt == NULL)
21574
0
  return;
21575
0
    ctxt->serror = serror;
21576
0
    ctxt->errCtxt = ctx;
21577
0
    if (ctxt->vctxt != NULL)
21578
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21579
0
}
21580
21581
/**
21582
 * xmlSchemaGetParserErrors:
21583
 * @ctxt:  a XMl-Schema parser context
21584
 * @err: the error callback result
21585
 * @warn: the warning callback result
21586
 * @ctx: contextual data for the callbacks result
21587
 *
21588
 * Get the callback information used to handle errors for a parser context
21589
 *
21590
 * Returns -1 in case of failure, 0 otherwise
21591
 */
21592
int
21593
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21594
       xmlSchemaValidityErrorFunc * err,
21595
       xmlSchemaValidityWarningFunc * warn, void **ctx)
21596
0
{
21597
0
  if (ctxt == NULL)
21598
0
    return(-1);
21599
0
  if (err != NULL)
21600
0
    *err = ctxt->error;
21601
0
  if (warn != NULL)
21602
0
    *warn = ctxt->warning;
21603
0
  if (ctx != NULL)
21604
0
    *ctx = ctxt->errCtxt;
21605
0
  return(0);
21606
0
}
21607
21608
/**
21609
 * xmlSchemaFacetTypeToString:
21610
 * @type:  the facet type
21611
 *
21612
 * Convert the xmlSchemaTypeType to a char string.
21613
 *
21614
 * Returns the char string representation of the facet type if the
21615
 *     type is a facet and an "Internal Error" string otherwise.
21616
 */
21617
static const xmlChar *
21618
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21619
0
{
21620
0
    switch (type) {
21621
0
        case XML_SCHEMA_FACET_PATTERN:
21622
0
            return (BAD_CAST "pattern");
21623
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21624
0
            return (BAD_CAST "maxExclusive");
21625
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
21626
0
            return (BAD_CAST "maxInclusive");
21627
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
21628
0
            return (BAD_CAST "minExclusive");
21629
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
21630
0
            return (BAD_CAST "minInclusive");
21631
0
        case XML_SCHEMA_FACET_WHITESPACE:
21632
0
            return (BAD_CAST "whiteSpace");
21633
0
        case XML_SCHEMA_FACET_ENUMERATION:
21634
0
            return (BAD_CAST "enumeration");
21635
0
        case XML_SCHEMA_FACET_LENGTH:
21636
0
            return (BAD_CAST "length");
21637
0
        case XML_SCHEMA_FACET_MAXLENGTH:
21638
0
            return (BAD_CAST "maxLength");
21639
0
        case XML_SCHEMA_FACET_MINLENGTH:
21640
0
            return (BAD_CAST "minLength");
21641
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
21642
0
            return (BAD_CAST "totalDigits");
21643
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
21644
0
            return (BAD_CAST "fractionDigits");
21645
0
        default:
21646
0
            break;
21647
0
    }
21648
0
    return (BAD_CAST "Internal Error");
21649
0
}
21650
21651
static xmlSchemaWhitespaceValueType
21652
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21653
0
{
21654
    /*
21655
    * The normalization type can be changed only for types which are derived
21656
    * from xsd:string.
21657
    */
21658
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
21659
  /*
21660
  * Note that we assume a whitespace of preserve for anySimpleType.
21661
  */
21662
0
  if ((type->builtInType == XML_SCHEMAS_STRING) ||
21663
0
      (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21664
0
      return(XML_SCHEMA_WHITESPACE_PRESERVE);
21665
0
  else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21666
0
      return(XML_SCHEMA_WHITESPACE_REPLACE);
21667
0
  else {
21668
      /*
21669
      * For all `atomic` datatypes other than string (and types `derived`
21670
      * by `restriction` from it) the value of whiteSpace is fixed to
21671
      * collapse
21672
      * Note that this includes built-in list datatypes.
21673
      */
21674
0
      return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21675
0
  }
21676
0
    } else if (WXS_IS_LIST(type)) {
21677
  /*
21678
  * For list types the facet "whiteSpace" is fixed to "collapse".
21679
  */
21680
0
  return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21681
0
    } else if (WXS_IS_UNION(type)) {
21682
0
  return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21683
0
    } else if (WXS_IS_ATOMIC(type)) {
21684
0
  if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21685
0
      return (XML_SCHEMA_WHITESPACE_PRESERVE);
21686
0
  else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21687
0
      return (XML_SCHEMA_WHITESPACE_REPLACE);
21688
0
  else
21689
0
      return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21690
0
    }
21691
0
    return (-1);
21692
0
}
21693
21694
/************************************************************************
21695
 *                  *
21696
 *      Simple type validation        *
21697
 *                  *
21698
 ************************************************************************/
21699
21700
21701
/************************************************************************
21702
 *                  *
21703
 *      DOM Validation code       *
21704
 *                  *
21705
 ************************************************************************/
21706
21707
/**
21708
 * xmlSchemaAssembleByLocation:
21709
 * @pctxt:  a schema parser context
21710
 * @vctxt:  a schema validation context
21711
 * @schema: the existing schema
21712
 * @node: the node that fired the assembling
21713
 * @nsName: the namespace name of the new schema
21714
 * @location: the location of the schema
21715
 *
21716
 * Expands an existing schema by an additional schema.
21717
 *
21718
 * Returns 0 if the new schema is correct, a positive error code
21719
 * number otherwise and -1 in case of an internal or API error.
21720
 */
21721
static int
21722
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21723
          xmlSchemaPtr schema,
21724
          xmlNodePtr node,
21725
          const xmlChar *nsName,
21726
          const xmlChar *location)
21727
0
{
21728
0
    int ret = 0;
21729
0
    xmlSchemaParserCtxtPtr pctxt;
21730
0
    xmlSchemaBucketPtr bucket = NULL;
21731
21732
0
    if ((vctxt == NULL) || (schema == NULL))
21733
0
  return (-1);
21734
21735
0
    if (vctxt->pctxt == NULL) {
21736
0
  VERROR_INT("xmlSchemaAssembleByLocation",
21737
0
      "no parser context available");
21738
0
  return(-1);
21739
0
    }
21740
0
    pctxt = vctxt->pctxt;
21741
0
    if (pctxt->constructor == NULL) {
21742
0
  PERROR_INT("xmlSchemaAssembleByLocation",
21743
0
      "no constructor");
21744
0
  return(-1);
21745
0
    }
21746
    /*
21747
    * Acquire the schema document.
21748
    */
21749
0
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21750
0
  location, node);
21751
    /*
21752
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21753
    * the process will automatically change this to
21754
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21755
    */
21756
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21757
0
  location, NULL, NULL, 0, node, NULL, nsName,
21758
0
  &bucket);
21759
0
    if (ret != 0)
21760
0
  return(ret);
21761
0
    if (bucket == NULL) {
21762
  /*
21763
  * Generate a warning that the document could not be located.
21764
  */
21765
0
  xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21766
0
      node, NULL,
21767
0
      "The document at location '%s' could not be acquired",
21768
0
      location, NULL, NULL);
21769
0
  return(ret);
21770
0
    }
21771
    /*
21772
    * The first located schema will be handled as if all other
21773
    * schemas imported by XSI were imported by this first schema.
21774
    */
21775
0
    if ((bucket != NULL) &&
21776
0
  (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21777
0
  WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21778
    /*
21779
    * TODO: Is this handled like an import? I.e. is it not an error
21780
    * if the schema cannot be located?
21781
    */
21782
0
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21783
0
  return(0);
21784
    /*
21785
    * We will reuse the parser context for every schema imported
21786
    * directly via XSI. So reset the context.
21787
    */
21788
0
    pctxt->nberrors = 0;
21789
0
    pctxt->err = 0;
21790
0
    pctxt->doc = bucket->doc;
21791
21792
0
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21793
0
    if (ret == -1) {
21794
0
  pctxt->doc = NULL;
21795
0
  goto exit_failure;
21796
0
    }
21797
    /* Paranoid error channelling. */
21798
0
    if ((ret == 0) && (pctxt->nberrors != 0))
21799
0
  ret = pctxt->err;
21800
0
    if (pctxt->nberrors == 0) {
21801
  /*
21802
  * Only bother to fixup pending components, if there was
21803
  * no error yet.
21804
  * For every XSI acquired schema (and its sub-schemata) we will
21805
  * fixup the components.
21806
  */
21807
0
  xmlSchemaFixupComponents(pctxt, bucket);
21808
0
  ret = pctxt->err;
21809
  /*
21810
  * Not nice, but we need somehow to channel the schema parser
21811
  * error to the validation context.
21812
  */
21813
0
  if ((ret != 0) && (vctxt->err == 0))
21814
0
      vctxt->err = ret;
21815
0
  vctxt->nberrors += pctxt->nberrors;
21816
0
    } else {
21817
  /* Add to validation error sum. */
21818
0
  vctxt->nberrors += pctxt->nberrors;
21819
0
    }
21820
0
    pctxt->doc = NULL;
21821
0
    return(ret);
21822
0
exit_failure:
21823
0
    pctxt->doc = NULL;
21824
0
    return (-1);
21825
0
}
21826
21827
static xmlSchemaAttrInfoPtr
21828
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21829
       int metaType)
21830
0
{
21831
0
    if (vctxt->nbAttrInfos == 0)
21832
0
  return (NULL);
21833
0
    {
21834
0
  int i;
21835
0
  xmlSchemaAttrInfoPtr iattr;
21836
21837
0
  for (i = 0; i < vctxt->nbAttrInfos; i++) {
21838
0
      iattr = vctxt->attrInfos[i];
21839
0
      if (iattr->metaType == metaType)
21840
0
    return (iattr);
21841
0
  }
21842
21843
0
    }
21844
0
    return (NULL);
21845
0
}
21846
21847
/**
21848
 * xmlSchemaAssembleByXSI:
21849
 * @vctxt:  a schema validation context
21850
 *
21851
 * Expands an existing schema by an additional schema using
21852
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21853
 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21854
 * must be set to 1.
21855
 *
21856
 * Returns 0 if the new schema is correct, a positive error code
21857
 * number otherwise and -1 in case of an internal or API error.
21858
 */
21859
static int
21860
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21861
0
{
21862
0
    const xmlChar *cur, *end;
21863
0
    const xmlChar *nsname = NULL, *location;
21864
0
    int count = 0;
21865
0
    int ret = 0;
21866
0
    xmlSchemaAttrInfoPtr iattr;
21867
21868
    /*
21869
    * Parse the value; we will assume an even number of values
21870
    * to be given (this is how Xerces and XSV work).
21871
    *
21872
    * URGENT TODO: !! This needs to work for both
21873
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
21874
    * element !!
21875
    */
21876
0
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21877
0
  XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21878
0
    if (iattr == NULL)
21879
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21880
0
  XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21881
0
    if (iattr == NULL)
21882
0
  return (0);
21883
0
    cur = iattr->value;
21884
0
    do {
21885
  /*
21886
  * TODO: Move the string parsing mechanism away from here.
21887
  */
21888
0
  if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21889
      /*
21890
      * Get the namespace name.
21891
      */
21892
0
      while (IS_BLANK_CH(*cur))
21893
0
    cur++;
21894
0
      end = cur;
21895
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21896
0
    end++;
21897
0
      if (end == cur)
21898
0
    break;
21899
0
      count++; /* TODO: Don't use the schema's dict. */
21900
0
      nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21901
0
      cur = end;
21902
0
  }
21903
  /*
21904
  * Get the URI.
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
      if (iattr->metaType ==
21913
0
    XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21914
0
      {
21915
    /*
21916
    * If using @schemaLocation then tuples are expected.
21917
    * I.e. the namespace name *and* the document's URI.
21918
    */
21919
0
    xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21920
0
        iattr->node, NULL,
21921
0
        "The value must consist of tuples: the target namespace "
21922
0
        "name and the document's URI", NULL, NULL, NULL);
21923
0
      }
21924
0
      break;
21925
0
  }
21926
0
  count++; /* TODO: Don't use the schema's dict. */
21927
0
  location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21928
0
  cur = end;
21929
0
  ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21930
0
      iattr->node, nsname, location);
21931
0
  if (ret == -1) {
21932
0
      VERROR_INT("xmlSchemaAssembleByXSI",
21933
0
    "assembling schemata");
21934
0
      return (-1);
21935
0
  }
21936
0
    } while (*cur != 0);
21937
0
    return (ret);
21938
0
}
21939
21940
static const xmlChar *
21941
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21942
       const xmlChar *prefix)
21943
0
{
21944
0
    if (vctxt->sax != NULL) {
21945
0
  int i, j;
21946
0
  xmlSchemaNodeInfoPtr inode;
21947
21948
0
  for (i = vctxt->depth; i >= 0; i--) {
21949
0
      if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21950
0
    inode = vctxt->elemInfos[i];
21951
0
    for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21952
0
        if (((prefix == NULL) &&
21953
0
          (inode->nsBindings[j] == NULL)) ||
21954
0
      ((prefix != NULL) && xmlStrEqual(prefix,
21955
0
          inode->nsBindings[j]))) {
21956
21957
      /*
21958
      * Note that the namespace bindings are already
21959
      * in a string dict.
21960
      */
21961
0
      return (inode->nsBindings[j+1]);
21962
0
        }
21963
0
    }
21964
0
      }
21965
0
  }
21966
0
  return (NULL);
21967
0
#ifdef LIBXML_READER_ENABLED
21968
0
    } else if (vctxt->reader != NULL) {
21969
0
  xmlChar *nsName;
21970
21971
0
  nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21972
0
  if (nsName != NULL) {
21973
0
      const xmlChar *ret;
21974
21975
0
      ret = xmlDictLookup(vctxt->dict, nsName, -1);
21976
0
      xmlFree(nsName);
21977
0
      return (ret);
21978
0
  } else
21979
0
      return (NULL);
21980
0
#endif
21981
0
    } else {
21982
0
  xmlNsPtr ns;
21983
21984
0
  if ((vctxt->inode->node == NULL) ||
21985
0
      (vctxt->inode->node->doc == NULL)) {
21986
0
      VERROR_INT("xmlSchemaLookupNamespace",
21987
0
    "no node or node's doc available");
21988
0
      return (NULL);
21989
0
  }
21990
0
  ns = xmlSearchNs(vctxt->inode->node->doc,
21991
0
      vctxt->inode->node, prefix);
21992
0
  if (ns != NULL)
21993
0
      return (ns->href);
21994
0
  return (NULL);
21995
0
    }
21996
0
}
21997
21998
/*
21999
* This one works on the schema of the validation context.
22000
*/
22001
static int
22002
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
22003
        xmlSchemaPtr schema,
22004
        xmlNodePtr node,
22005
        const xmlChar *value,
22006
        xmlSchemaValPtr *val,
22007
        int valNeeded)
22008
0
{
22009
0
    int ret;
22010
22011
0
    if (vctxt && (vctxt->schema == NULL)) {
22012
0
  VERROR_INT("xmlSchemaValidateNotation",
22013
0
      "a schema is needed on the validation context");
22014
0
  return (-1);
22015
0
    }
22016
0
    ret = xmlValidateQName(value, 1);
22017
0
    if (ret != 0)
22018
0
  return (ret);
22019
0
    {
22020
0
  xmlChar *localName = NULL;
22021
0
  xmlChar *prefix = NULL;
22022
22023
0
  localName = xmlSplitQName2(value, &prefix);
22024
0
  if (prefix != NULL) {
22025
0
      const xmlChar *nsName = NULL;
22026
22027
0
      if (vctxt != NULL)
22028
0
    nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
22029
0
      else if (node != NULL) {
22030
0
    xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
22031
0
    if (ns != NULL)
22032
0
        nsName = ns->href;
22033
0
      } else {
22034
0
    xmlFree(prefix);
22035
0
    xmlFree(localName);
22036
0
    return (1);
22037
0
      }
22038
0
      if (nsName == NULL) {
22039
0
    xmlFree(prefix);
22040
0
    xmlFree(localName);
22041
0
    return (1);
22042
0
      }
22043
0
      if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
22044
0
    if ((valNeeded) && (val != NULL)) {
22045
0
        (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
22046
0
                   xmlStrdup(nsName));
22047
0
        if (*val == NULL)
22048
0
      ret = -1;
22049
0
    }
22050
0
      } else
22051
0
    ret = 1;
22052
0
      xmlFree(prefix);
22053
0
      xmlFree(localName);
22054
0
  } else {
22055
0
      if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
22056
0
    if (valNeeded && (val != NULL)) {
22057
0
        (*val) = xmlSchemaNewNOTATIONValue(
22058
0
      BAD_CAST xmlStrdup(value), NULL);
22059
0
        if (*val == NULL)
22060
0
      ret = -1;
22061
0
    }
22062
0
      } else
22063
0
    return (1);
22064
0
  }
22065
0
    }
22066
0
    return (ret);
22067
0
}
22068
22069
static int
22070
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
22071
           const xmlChar* lname,
22072
           const xmlChar* nsname)
22073
0
{
22074
0
    int i;
22075
22076
0
    lname = xmlDictLookup(vctxt->dict, lname, -1);
22077
0
    if (lname == NULL)
22078
0
  return(-1);
22079
0
    if (nsname != NULL) {
22080
0
  nsname = xmlDictLookup(vctxt->dict, nsname, -1);
22081
0
  if (nsname == NULL)
22082
0
      return(-1);
22083
0
    }
22084
0
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
22085
0
  if ((vctxt->nodeQNames->items [i] == lname) &&
22086
0
      (vctxt->nodeQNames->items[i +1] == nsname))
22087
      /* Already there */
22088
0
      return(i);
22089
0
    }
22090
    /* Add new entry. */
22091
0
    i = vctxt->nodeQNames->nbItems;
22092
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
22093
0
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
22094
0
    return(i);
22095
0
}
22096
22097
/************************************************************************
22098
 *                  *
22099
 *  Validation of identity-constraints (IDC)                            *
22100
 *                  *
22101
 ************************************************************************/
22102
22103
/**
22104
 * xmlSchemaAugmentIDC:
22105
 * @idcDef: the IDC definition
22106
 *
22107
 * Creates an augmented IDC definition item.
22108
 *
22109
 * Returns the item, or NULL on internal errors.
22110
 */
22111
static void
22112
xmlSchemaAugmentIDC(void *payload, void *data,
22113
                    const xmlChar *name ATTRIBUTE_UNUSED)
22114
0
{
22115
0
    xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
22116
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
22117
0
    xmlSchemaIDCAugPtr aidc;
22118
22119
0
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
22120
0
    if (aidc == NULL) {
22121
0
  xmlSchemaVErrMemory(vctxt,
22122
0
      "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
22123
0
      NULL);
22124
0
  return;
22125
0
    }
22126
0
    aidc->keyrefDepth = -1;
22127
0
    aidc->def = idcDef;
22128
0
    aidc->next = NULL;
22129
0
    if (vctxt->aidcs == NULL)
22130
0
  vctxt->aidcs = aidc;
22131
0
    else {
22132
0
  aidc->next = vctxt->aidcs;
22133
0
  vctxt->aidcs = aidc;
22134
0
    }
22135
    /*
22136
    * Save if we have keyrefs at all.
22137
    */
22138
0
    if ((vctxt->hasKeyrefs == 0) &&
22139
0
  (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
22140
0
  vctxt->hasKeyrefs = 1;
22141
0
}
22142
22143
/**
22144
 * xmlSchemaAugmentImportedIDC:
22145
 * @imported: the imported schema
22146
 *
22147
 * Creates an augmented IDC definition for the imported schema.
22148
 */
22149
static void
22150
xmlSchemaAugmentImportedIDC(void *payload, void *data,
22151
0
                            const xmlChar *name ATTRIBUTE_UNUSED) {
22152
0
    xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
22153
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
22154
0
    if (imported->schema->idcDef != NULL) {
22155
0
      xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
22156
0
    }
22157
0
}
22158
22159
/**
22160
 * xmlSchemaIDCNewBinding:
22161
 * @idcDef: the IDC definition of this binding
22162
 *
22163
 * Creates a new IDC binding.
22164
 *
22165
 * Returns the new IDC binding, NULL on internal errors.
22166
 */
22167
static xmlSchemaPSVIIDCBindingPtr
22168
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22169
0
{
22170
0
    xmlSchemaPSVIIDCBindingPtr ret;
22171
22172
0
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22173
0
      sizeof(xmlSchemaPSVIIDCBinding));
22174
0
    if (ret == NULL) {
22175
0
  xmlSchemaVErrMemory(NULL,
22176
0
      "allocating a PSVI IDC binding item", NULL);
22177
0
  return (NULL);
22178
0
    }
22179
0
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22180
0
    ret->definition = idcDef;
22181
0
    return (ret);
22182
0
}
22183
22184
/**
22185
 * xmlSchemaIDCStoreNodeTableItem:
22186
 * @vctxt: the WXS validation context
22187
 * @item: the IDC node table item
22188
 *
22189
 * The validation context is used to store IDC node table items.
22190
 * They are stored to avoid copying them if IDC node-tables are merged
22191
 * with corresponding parent IDC node-tables (bubbling).
22192
 *
22193
 * Returns 0 if succeeded, -1 on internal errors.
22194
 */
22195
static int
22196
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22197
             xmlSchemaPSVIIDCNodePtr item)
22198
0
{
22199
    /*
22200
    * Add to global list.
22201
    */
22202
0
    if (vctxt->idcNodes == NULL) {
22203
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22204
0
      xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22205
0
  if (vctxt->idcNodes == NULL) {
22206
0
      xmlSchemaVErrMemory(vctxt,
22207
0
    "allocating the IDC node table item list", NULL);
22208
0
      return (-1);
22209
0
  }
22210
0
  vctxt->sizeIdcNodes = 20;
22211
0
    } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22212
0
  vctxt->sizeIdcNodes *= 2;
22213
0
  vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22214
0
      xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22215
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
22216
0
  if (vctxt->idcNodes == NULL) {
22217
0
      xmlSchemaVErrMemory(vctxt,
22218
0
    "re-allocating the IDC node table item list", NULL);
22219
0
      return (-1);
22220
0
  }
22221
0
    }
22222
0
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22223
22224
0
    return (0);
22225
0
}
22226
22227
/**
22228
 * xmlSchemaIDCStoreKey:
22229
 * @vctxt: the WXS validation context
22230
 * @item: the IDC key
22231
 *
22232
 * The validation context is used to store an IDC key.
22233
 *
22234
 * Returns 0 if succeeded, -1 on internal errors.
22235
 */
22236
static int
22237
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22238
         xmlSchemaPSVIIDCKeyPtr key)
22239
0
{
22240
    /*
22241
    * Add to global list.
22242
    */
22243
0
    if (vctxt->idcKeys == NULL) {
22244
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22245
0
      xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22246
0
  if (vctxt->idcKeys == NULL) {
22247
0
      xmlSchemaVErrMemory(vctxt,
22248
0
    "allocating the IDC key storage list", NULL);
22249
0
      return (-1);
22250
0
  }
22251
0
  vctxt->sizeIdcKeys = 40;
22252
0
    } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22253
0
  vctxt->sizeIdcKeys *= 2;
22254
0
  vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22255
0
      xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22256
0
      sizeof(xmlSchemaPSVIIDCKeyPtr));
22257
0
  if (vctxt->idcKeys == NULL) {
22258
0
      xmlSchemaVErrMemory(vctxt,
22259
0
    "re-allocating the IDC key storage list", NULL);
22260
0
      return (-1);
22261
0
  }
22262
0
    }
22263
0
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22264
22265
0
    return (0);
22266
0
}
22267
22268
/**
22269
 * xmlSchemaIDCAppendNodeTableItem:
22270
 * @bind: the IDC binding
22271
 * @ntItem: the node-table item
22272
 *
22273
 * Appends the IDC node-table item to the binding.
22274
 *
22275
 * Returns 0 on success and -1 on internal errors.
22276
 */
22277
static int
22278
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22279
        xmlSchemaPSVIIDCNodePtr ntItem)
22280
0
{
22281
0
    if (bind->nodeTable == NULL) {
22282
0
  bind->sizeNodes = 10;
22283
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22284
0
      xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22285
0
  if (bind->nodeTable == NULL) {
22286
0
      xmlSchemaVErrMemory(NULL,
22287
0
    "allocating an array of IDC node-table items", NULL);
22288
0
      return(-1);
22289
0
  }
22290
0
    } else if (bind->sizeNodes <= bind->nbNodes) {
22291
0
  bind->sizeNodes *= 2;
22292
0
  bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22293
0
      xmlRealloc(bind->nodeTable, bind->sizeNodes *
22294
0
    sizeof(xmlSchemaPSVIIDCNodePtr));
22295
0
  if (bind->nodeTable == NULL) {
22296
0
      xmlSchemaVErrMemory(NULL,
22297
0
    "re-allocating an array of IDC node-table items", NULL);
22298
0
      return(-1);
22299
0
  }
22300
0
    }
22301
0
    bind->nodeTable[bind->nbNodes++] = ntItem;
22302
0
    return(0);
22303
0
}
22304
22305
/**
22306
 * xmlSchemaIDCAcquireBinding:
22307
 * @vctxt: the WXS validation context
22308
 * @matcher: the IDC matcher
22309
 *
22310
 * Looks up an PSVI IDC binding, for the IDC definition and
22311
 * of the given matcher. If none found, a new one is created
22312
 * and added to the IDC table.
22313
 *
22314
 * Returns an IDC binding or NULL on internal errors.
22315
 */
22316
static xmlSchemaPSVIIDCBindingPtr
22317
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22318
        xmlSchemaIDCMatcherPtr matcher)
22319
0
{
22320
0
    xmlSchemaNodeInfoPtr ielem;
22321
22322
0
    ielem = vctxt->elemInfos[matcher->depth];
22323
22324
0
    if (ielem->idcTable == NULL) {
22325
0
  ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22326
0
  if (ielem->idcTable == NULL)
22327
0
      return (NULL);
22328
0
  return(ielem->idcTable);
22329
0
    } else {
22330
0
  xmlSchemaPSVIIDCBindingPtr bind = NULL;
22331
22332
0
  bind = ielem->idcTable;
22333
0
  do {
22334
0
      if (bind->definition == matcher->aidc->def)
22335
0
    return(bind);
22336
0
      if (bind->next == NULL) {
22337
0
    bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22338
0
    if (bind->next == NULL)
22339
0
        return (NULL);
22340
0
    return(bind->next);
22341
0
      }
22342
0
      bind = bind->next;
22343
0
  } while (bind != NULL);
22344
0
    }
22345
0
    return (NULL);
22346
0
}
22347
22348
static xmlSchemaItemListPtr
22349
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22350
           xmlSchemaIDCMatcherPtr matcher)
22351
0
{
22352
0
    if (matcher->targets == NULL)
22353
0
  matcher->targets = xmlSchemaItemListCreate();
22354
0
    return(matcher->targets);
22355
0
}
22356
22357
/**
22358
 * xmlSchemaIDCFreeKey:
22359
 * @key: the IDC key
22360
 *
22361
 * Frees an IDC key together with its compiled value.
22362
 */
22363
static void
22364
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22365
0
{
22366
0
    if (key->val != NULL)
22367
0
  xmlSchemaFreeValue(key->val);
22368
0
    xmlFree(key);
22369
0
}
22370
22371
/**
22372
 * xmlSchemaIDCFreeBinding:
22373
 *
22374
 * Frees an IDC binding. Note that the node table-items
22375
 * are not freed.
22376
 */
22377
static void
22378
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22379
0
{
22380
0
    if (bind->nodeTable != NULL)
22381
0
  xmlFree(bind->nodeTable);
22382
0
    if (bind->dupls != NULL)
22383
0
  xmlSchemaItemListFree(bind->dupls);
22384
0
    xmlFree(bind);
22385
0
}
22386
22387
/**
22388
 * xmlSchemaIDCFreeIDCTable:
22389
 * @bind: the first IDC binding in the list
22390
 *
22391
 * Frees an IDC table, i.e. all the IDC bindings in the list.
22392
 */
22393
static void
22394
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22395
0
{
22396
0
    xmlSchemaPSVIIDCBindingPtr prev;
22397
22398
0
    while (bind != NULL) {
22399
0
  prev = bind;
22400
0
  bind = bind->next;
22401
0
  xmlSchemaIDCFreeBinding(prev);
22402
0
    }
22403
0
}
22404
22405
static void
22406
xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
22407
0
{
22408
0
    xmlIDCHashEntryPtr e = payload, n;
22409
0
    while (e) {
22410
0
  n = e->next;
22411
0
  xmlFree(e);
22412
0
  e = n;
22413
0
    }
22414
0
}
22415
22416
/**
22417
 * xmlSchemaIDCFreeMatcherList:
22418
 * @matcher: the first IDC matcher in the list
22419
 *
22420
 * Frees a list of IDC matchers.
22421
 */
22422
static void
22423
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22424
0
{
22425
0
    xmlSchemaIDCMatcherPtr next;
22426
22427
0
    while (matcher != NULL) {
22428
0
  next = matcher->next;
22429
0
  if (matcher->keySeqs != NULL) {
22430
0
      int i;
22431
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22432
0
    if (matcher->keySeqs[i] != NULL)
22433
0
        xmlFree(matcher->keySeqs[i]);
22434
0
      xmlFree(matcher->keySeqs);
22435
0
  }
22436
0
  if (matcher->targets != NULL) {
22437
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22438
0
    int i;
22439
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22440
    /*
22441
    * Node-table items for keyrefs are not stored globally
22442
    * to the validation context, since they are not bubbled.
22443
    * We need to free them here.
22444
    */
22445
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22446
0
        idcNode =
22447
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22448
0
        xmlFree(idcNode->keys);
22449
0
        xmlFree(idcNode);
22450
0
    }
22451
0
      }
22452
0
      xmlSchemaItemListFree(matcher->targets);
22453
0
  }
22454
0
  if (matcher->htab != NULL)
22455
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22456
0
  xmlFree(matcher);
22457
0
  matcher = next;
22458
0
    }
22459
0
}
22460
22461
/**
22462
 * xmlSchemaIDCReleaseMatcherList:
22463
 * @vctxt: the WXS validation context
22464
 * @matcher: the first IDC matcher in the list
22465
 *
22466
 * Caches a list of IDC matchers for reuse.
22467
 */
22468
static void
22469
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22470
             xmlSchemaIDCMatcherPtr matcher)
22471
0
{
22472
0
    xmlSchemaIDCMatcherPtr next;
22473
22474
0
    while (matcher != NULL) {
22475
0
  next = matcher->next;
22476
0
  if (matcher->keySeqs != NULL) {
22477
0
      int i;
22478
      /*
22479
      * Don't free the array, but only the content.
22480
      */
22481
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22482
0
    if (matcher->keySeqs[i] != NULL) {
22483
0
        xmlFree(matcher->keySeqs[i]);
22484
0
        matcher->keySeqs[i] = NULL;
22485
0
    }
22486
0
  }
22487
0
  if (matcher->targets) {
22488
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22489
0
    int i;
22490
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22491
    /*
22492
    * Node-table items for keyrefs are not stored globally
22493
    * to the validation context, since they are not bubbled.
22494
    * We need to free them here.
22495
    */
22496
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22497
0
        idcNode =
22498
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22499
0
        xmlFree(idcNode->keys);
22500
0
        xmlFree(idcNode);
22501
0
    }
22502
0
      }
22503
0
      xmlSchemaItemListFree(matcher->targets);
22504
0
      matcher->targets = NULL;
22505
0
  }
22506
0
  if (matcher->htab != NULL) {
22507
0
      xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22508
0
      matcher->htab = NULL;
22509
0
  }
22510
0
  matcher->next = NULL;
22511
  /*
22512
  * Cache the matcher.
22513
  */
22514
0
  if (vctxt->idcMatcherCache != NULL)
22515
0
      matcher->nextCached = vctxt->idcMatcherCache;
22516
0
  vctxt->idcMatcherCache = matcher;
22517
22518
0
  matcher = next;
22519
0
    }
22520
0
}
22521
22522
/**
22523
 * xmlSchemaIDCAddStateObject:
22524
 * @vctxt: the WXS validation context
22525
 * @matcher: the IDC matcher
22526
 * @sel: the XPath information
22527
 * @parent: the parent "selector" state object if any
22528
 * @type: "selector" or "field"
22529
 *
22530
 * Creates/reuses and activates state objects for the given
22531
 * XPath information; if the XPath expression consists of unions,
22532
 * multiple state objects are created for every unioned expression.
22533
 *
22534
 * Returns 0 on success and -1 on internal errors.
22535
 */
22536
static int
22537
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22538
      xmlSchemaIDCMatcherPtr matcher,
22539
      xmlSchemaIDCSelectPtr sel,
22540
      int type)
22541
0
{
22542
0
    xmlSchemaIDCStateObjPtr sto;
22543
22544
    /*
22545
    * Reuse the state objects from the pool.
22546
    */
22547
0
    if (vctxt->xpathStatePool != NULL) {
22548
0
  sto = vctxt->xpathStatePool;
22549
0
  vctxt->xpathStatePool = sto->next;
22550
0
  sto->next = NULL;
22551
0
    } else {
22552
  /*
22553
  * Create a new state object.
22554
  */
22555
0
  sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22556
0
  if (sto == NULL) {
22557
0
      xmlSchemaVErrMemory(NULL,
22558
0
    "allocating an IDC state object", NULL);
22559
0
      return (-1);
22560
0
  }
22561
0
  memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22562
0
    }
22563
    /*
22564
    * Add to global list.
22565
    */
22566
0
    if (vctxt->xpathStates != NULL)
22567
0
  sto->next = vctxt->xpathStates;
22568
0
    vctxt->xpathStates = sto;
22569
22570
    /*
22571
    * Free the old xpath validation context.
22572
    */
22573
0
    if (sto->xpathCtxt != NULL)
22574
0
  xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22575
22576
    /*
22577
    * Create a new XPath (pattern) validation context.
22578
    */
22579
0
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22580
0
  (xmlPatternPtr) sel->xpathComp);
22581
0
    if (sto->xpathCtxt == NULL) {
22582
0
  VERROR_INT("xmlSchemaIDCAddStateObject",
22583
0
      "failed to create an XPath validation context");
22584
0
  return (-1);
22585
0
    }
22586
0
    sto->type = type;
22587
0
    sto->depth = vctxt->depth;
22588
0
    sto->matcher = matcher;
22589
0
    sto->sel = sel;
22590
0
    sto->nbHistory = 0;
22591
22592
#ifdef DEBUG_IDC
22593
    xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
22594
  sto->sel->xpath);
22595
#endif
22596
0
    return (0);
22597
0
}
22598
22599
/**
22600
 * xmlSchemaXPathEvaluate:
22601
 * @vctxt: the WXS validation context
22602
 * @nodeType: the nodeType of the current node
22603
 *
22604
 * Evaluates all active XPath state objects.
22605
 *
22606
 * Returns the number of IC "field" state objects which resolved to
22607
 * this node, 0 if none resolved and -1 on internal errors.
22608
 */
22609
static int
22610
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22611
           xmlElementType nodeType)
22612
0
{
22613
0
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22614
0
    int res, resolved = 0, depth = vctxt->depth;
22615
22616
0
    if (vctxt->xpathStates == NULL)
22617
0
  return (0);
22618
22619
0
    if (nodeType == XML_ATTRIBUTE_NODE)
22620
0
  depth++;
22621
#ifdef DEBUG_IDC
22622
    {
22623
  xmlChar *str = NULL;
22624
  xmlGenericError(xmlGenericErrorContext,
22625
      "IDC: EVAL on %s, depth %d, type %d\n",
22626
      xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22627
    vctxt->inode->localName), depth, nodeType);
22628
  FREE_AND_NULL(str)
22629
    }
22630
#endif
22631
    /*
22632
    * Process all active XPath state objects.
22633
    */
22634
0
    first = vctxt->xpathStates;
22635
0
    sto = first;
22636
0
    while (sto != head) {
22637
#ifdef DEBUG_IDC
22638
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22639
      xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
22640
    sto->matcher->aidc->def->name, sto->sel->xpath);
22641
  else
22642
      xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
22643
    sto->matcher->aidc->def->name, sto->sel->xpath);
22644
#endif
22645
0
  if (nodeType == XML_ELEMENT_NODE)
22646
0
      res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22647
0
    vctxt->inode->localName, vctxt->inode->nsName);
22648
0
  else
22649
0
      res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22650
0
    vctxt->inode->localName, vctxt->inode->nsName);
22651
22652
0
  if (res == -1) {
22653
0
      VERROR_INT("xmlSchemaXPathEvaluate",
22654
0
    "calling xmlStreamPush()");
22655
0
      return (-1);
22656
0
  }
22657
0
  if (res == 0)
22658
0
      goto next_sto;
22659
  /*
22660
  * Full match.
22661
  */
22662
#ifdef DEBUG_IDC
22663
  xmlGenericError(xmlGenericErrorContext, "IDC:     "
22664
      "MATCH\n");
22665
#endif
22666
  /*
22667
  * Register a match in the state object history.
22668
  */
22669
0
  if (sto->history == NULL) {
22670
0
      sto->history = (int *) xmlMalloc(5 * sizeof(int));
22671
0
      if (sto->history == NULL) {
22672
0
    xmlSchemaVErrMemory(NULL,
22673
0
        "allocating the state object history", NULL);
22674
0
    return(-1);
22675
0
      }
22676
0
      sto->sizeHistory = 5;
22677
0
  } else if (sto->sizeHistory <= sto->nbHistory) {
22678
0
      sto->sizeHistory *= 2;
22679
0
      sto->history = (int *) xmlRealloc(sto->history,
22680
0
    sto->sizeHistory * sizeof(int));
22681
0
      if (sto->history == NULL) {
22682
0
    xmlSchemaVErrMemory(NULL,
22683
0
        "re-allocating the state object history", NULL);
22684
0
    return(-1);
22685
0
      }
22686
0
  }
22687
0
  sto->history[sto->nbHistory++] = depth;
22688
22689
#ifdef DEBUG_IDC
22690
  xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
22691
      vctxt->depth);
22692
#endif
22693
22694
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22695
0
      xmlSchemaIDCSelectPtr sel;
22696
      /*
22697
      * Activate state objects for the IDC fields of
22698
      * the IDC selector.
22699
      */
22700
#ifdef DEBUG_IDC
22701
      xmlGenericError(xmlGenericErrorContext, "IDC:     "
22702
    "activating field states\n");
22703
#endif
22704
0
      sel = sto->matcher->aidc->def->fields;
22705
0
      while (sel != NULL) {
22706
0
    if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22707
0
        sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22708
0
        return (-1);
22709
0
    sel = sel->next;
22710
0
      }
22711
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22712
      /*
22713
      * An IDC key node was found by the IDC field.
22714
      */
22715
#ifdef DEBUG_IDC
22716
      xmlGenericError(xmlGenericErrorContext,
22717
    "IDC:     key found\n");
22718
#endif
22719
      /*
22720
      * Notify that the character value of this node is
22721
      * needed.
22722
      */
22723
0
      if (resolved == 0) {
22724
0
    if ((vctxt->inode->flags &
22725
0
        XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22726
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22727
0
      }
22728
0
      resolved++;
22729
0
  }
22730
0
next_sto:
22731
0
  if (sto->next == NULL) {
22732
      /*
22733
      * Evaluate field state objects created on this node as well.
22734
      */
22735
0
      head = first;
22736
0
      sto = vctxt->xpathStates;
22737
0
  } else
22738
0
      sto = sto->next;
22739
0
    }
22740
0
    return (resolved);
22741
0
}
22742
22743
static const xmlChar *
22744
xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22745
        xmlChar **buf,
22746
        xmlSchemaPSVIIDCKeyPtr *seq,
22747
        int count, int for_hash)
22748
0
{
22749
0
    int i, res;
22750
0
    xmlChar *value = NULL;
22751
22752
0
    *buf = xmlStrdup(BAD_CAST "[");
22753
0
    for (i = 0; i < count; i++) {
22754
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
22755
0
  if (!for_hash)
22756
0
      res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22757
0
        xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22758
0
        &value);
22759
0
  else {
22760
0
      res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22761
0
  }
22762
0
  if (res == 0)
22763
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
22764
0
  else {
22765
0
      VERROR_INT("xmlSchemaFormatIDCKeySequence",
22766
0
    "failed to compute a canonical value");
22767
0
      *buf = xmlStrcat(*buf, BAD_CAST "???");
22768
0
  }
22769
0
  if (i < count -1)
22770
0
      *buf = xmlStrcat(*buf, BAD_CAST "', ");
22771
0
  else
22772
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
22773
0
  if (value != NULL) {
22774
0
      xmlFree(value);
22775
0
      value = NULL;
22776
0
  }
22777
0
    }
22778
0
    *buf = xmlStrcat(*buf, BAD_CAST "]");
22779
22780
0
    return (BAD_CAST *buf);
22781
0
}
22782
22783
static const xmlChar *
22784
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22785
            xmlChar **buf,
22786
            xmlSchemaPSVIIDCKeyPtr *seq,
22787
            int count)
22788
0
{
22789
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22790
0
}
22791
22792
static const xmlChar *
22793
xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22794
       xmlChar **buf,
22795
       xmlSchemaPSVIIDCKeyPtr *seq,
22796
       int count)
22797
0
{
22798
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22799
0
}
22800
22801
/**
22802
 * xmlSchemaXPathPop:
22803
 * @vctxt: the WXS validation context
22804
 *
22805
 * Pops all XPath states.
22806
 *
22807
 * Returns 0 on success and -1 on internal errors.
22808
 */
22809
static int
22810
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22811
0
{
22812
0
    xmlSchemaIDCStateObjPtr sto;
22813
0
    int res;
22814
22815
0
    if (vctxt->xpathStates == NULL)
22816
0
  return(0);
22817
0
    sto = vctxt->xpathStates;
22818
0
    do {
22819
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22820
0
  if (res == -1)
22821
0
      return (-1);
22822
0
  sto = sto->next;
22823
0
    } while (sto != NULL);
22824
0
    return(0);
22825
0
}
22826
22827
/**
22828
 * xmlSchemaXPathProcessHistory:
22829
 * @vctxt: the WXS validation context
22830
 * @type: the simple/complex type of the current node if any at all
22831
 * @val: the precompiled value
22832
 *
22833
 * Processes and pops the history items of the IDC state objects.
22834
 * IDC key-sequences are validated/created on IDC bindings.
22835
 *
22836
 * Returns 0 on success and -1 on internal errors.
22837
 */
22838
static int
22839
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22840
           int depth)
22841
0
{
22842
0
    xmlSchemaIDCStateObjPtr sto, nextsto;
22843
0
    int res, matchDepth;
22844
0
    xmlSchemaPSVIIDCKeyPtr key = NULL;
22845
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22846
22847
0
    if (vctxt->xpathStates == NULL)
22848
0
  return (0);
22849
0
    sto = vctxt->xpathStates;
22850
22851
#ifdef DEBUG_IDC
22852
    {
22853
  xmlChar *str = NULL;
22854
  xmlGenericError(xmlGenericErrorContext,
22855
      "IDC: BACK on %s, depth %d\n",
22856
      xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22857
    vctxt->inode->localName), vctxt->depth);
22858
  FREE_AND_NULL(str)
22859
    }
22860
#endif
22861
    /*
22862
    * Evaluate the state objects.
22863
    */
22864
0
    while (sto != NULL) {
22865
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22866
0
  if (res == -1) {
22867
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22868
0
    "calling xmlStreamPop()");
22869
0
      return (-1);
22870
0
  }
22871
#ifdef DEBUG_IDC
22872
  xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
22873
      sto->sel->xpath);
22874
#endif
22875
0
  if (sto->nbHistory == 0)
22876
0
      goto deregister_check;
22877
22878
0
  matchDepth = sto->history[sto->nbHistory -1];
22879
22880
  /*
22881
  * Only matches at the current depth are of interest.
22882
  */
22883
0
  if (matchDepth != depth) {
22884
0
      sto = sto->next;
22885
0
      continue;
22886
0
  }
22887
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22888
      /*
22889
      * NOTE: According to
22890
      *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22891
      *   ... the simple-content of complex types is also allowed.
22892
      */
22893
22894
0
      if (WXS_IS_COMPLEX(type)) {
22895
0
    if (WXS_HAS_SIMPLE_CONTENT(type)) {
22896
        /*
22897
        * Sanity check for complex types with simple content.
22898
        */
22899
0
        simpleType = type->contentTypeDef;
22900
0
        if (simpleType == NULL) {
22901
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22902
0
          "field resolves to a CT with simple content "
22903
0
          "but the CT is missing the ST definition");
22904
0
      return (-1);
22905
0
        }
22906
0
    } else
22907
0
        simpleType = NULL;
22908
0
      } else
22909
0
    simpleType = type;
22910
0
      if (simpleType == NULL) {
22911
0
    xmlChar *str = NULL;
22912
22913
    /*
22914
    * Not qualified if the field resolves to a node of non
22915
    * simple type.
22916
    */
22917
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22918
0
        XML_SCHEMAV_CVC_IDC, NULL,
22919
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22920
0
        "The XPath '%s' of a field of %s does evaluate to a node of "
22921
0
        "non-simple type",
22922
0
        sto->sel->xpath,
22923
0
        xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22924
0
    FREE_AND_NULL(str);
22925
0
    sto->nbHistory--;
22926
0
    goto deregister_check;
22927
0
      }
22928
22929
0
      if ((key == NULL) && (vctxt->inode->val == NULL)) {
22930
    /*
22931
    * Failed to provide the normalized value; maybe
22932
    * the value was invalid.
22933
    */
22934
0
    VERROR(XML_SCHEMAV_CVC_IDC,
22935
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22936
0
        "Warning: No precomputed value available, the value "
22937
0
        "was either invalid or something strange happened");
22938
0
    sto->nbHistory--;
22939
0
    goto deregister_check;
22940
0
      } else {
22941
0
    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22942
0
    xmlSchemaPSVIIDCKeyPtr *keySeq;
22943
0
    int pos, idx;
22944
22945
    /*
22946
    * The key will be anchored on the matcher's list of
22947
    * key-sequences. The position in this list is determined
22948
    * by the target node's depth relative to the matcher's
22949
    * depth of creation (i.e. the depth of the scope element).
22950
    *
22951
    * Element        Depth    Pos   List-entries
22952
    * <scope>          0              NULL
22953
    *   <bar>          1              NULL
22954
    *     <target/>    2       2      target
22955
    *   <bar>
22956
                * </scope>
22957
    *
22958
    * The size of the list is only dependent on the depth of
22959
    * the tree.
22960
    * An entry will be NULLed in selector_leave, i.e. when
22961
    * we hit the target's
22962
    */
22963
0
    pos = sto->depth - matcher->depth;
22964
0
    idx = sto->sel->index;
22965
22966
    /*
22967
    * Create/grow the array of key-sequences.
22968
    */
22969
0
    if (matcher->keySeqs == NULL) {
22970
0
        if (pos > 9)
22971
0
      matcher->sizeKeySeqs = pos * 2;
22972
0
        else
22973
0
      matcher->sizeKeySeqs = 10;
22974
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22975
0
      xmlMalloc(matcher->sizeKeySeqs *
22976
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22977
0
        if (matcher->keySeqs == NULL) {
22978
0
      xmlSchemaVErrMemory(NULL,
22979
0
          "allocating an array of key-sequences",
22980
0
          NULL);
22981
0
      return(-1);
22982
0
        }
22983
0
        memset(matcher->keySeqs, 0,
22984
0
      matcher->sizeKeySeqs *
22985
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22986
0
    } else if (pos >= matcher->sizeKeySeqs) {
22987
0
        int i = matcher->sizeKeySeqs;
22988
22989
0
        matcher->sizeKeySeqs *= 2;
22990
0
        matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22991
0
      xmlRealloc(matcher->keySeqs,
22992
0
      matcher->sizeKeySeqs *
22993
0
      sizeof(xmlSchemaPSVIIDCKeyPtr *));
22994
0
        if (matcher->keySeqs == NULL) {
22995
0
      xmlSchemaVErrMemory(NULL,
22996
0
          "reallocating an array of key-sequences",
22997
0
          NULL);
22998
0
      return (-1);
22999
0
        }
23000
        /*
23001
        * The array needs to be NULLed.
23002
        * TODO: Use memset?
23003
        */
23004
0
        for (; i < matcher->sizeKeySeqs; i++)
23005
0
      matcher->keySeqs[i] = NULL;
23006
0
    }
23007
23008
    /*
23009
    * Get/create the key-sequence.
23010
    */
23011
0
    keySeq = matcher->keySeqs[pos];
23012
0
    if (keySeq == NULL) {
23013
0
        goto create_sequence;
23014
0
    } else if (keySeq[idx] != NULL) {
23015
0
        xmlChar *str = NULL;
23016
        /*
23017
        * cvc-identity-constraint:
23018
        * 3 For each node in the `target node set` all
23019
        * of the {fields}, with that node as the context
23020
        * node, evaluate to either an empty node-set or
23021
        * a node-set with exactly one member, which must
23022
        * have a simple type.
23023
        *
23024
        * The key was already set; report an error.
23025
        */
23026
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
23027
0
      XML_SCHEMAV_CVC_IDC, NULL,
23028
0
      WXS_BASIC_CAST matcher->aidc->def,
23029
0
      "The XPath '%s' of a field of %s evaluates to a "
23030
0
      "node-set with more than one member",
23031
0
      sto->sel->xpath,
23032
0
      xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
23033
0
        FREE_AND_NULL(str);
23034
0
        sto->nbHistory--;
23035
0
        goto deregister_check;
23036
0
    } else
23037
0
        goto create_key;
23038
23039
0
create_sequence:
23040
    /*
23041
    * Create a key-sequence.
23042
    */
23043
0
    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
23044
0
        matcher->aidc->def->nbFields *
23045
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
23046
0
    if (keySeq == NULL) {
23047
0
        xmlSchemaVErrMemory(NULL,
23048
0
      "allocating an IDC key-sequence", NULL);
23049
0
        return(-1);
23050
0
    }
23051
0
    memset(keySeq, 0, matcher->aidc->def->nbFields *
23052
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
23053
0
    matcher->keySeqs[pos] = keySeq;
23054
0
create_key:
23055
    /*
23056
    * Create a key once per node only.
23057
    */
23058
0
    if (key == NULL) {
23059
0
        key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
23060
0
      sizeof(xmlSchemaPSVIIDCKey));
23061
0
        if (key == NULL) {
23062
0
      xmlSchemaVErrMemory(NULL,
23063
0
          "allocating a IDC key", NULL);
23064
0
      xmlFree(keySeq);
23065
0
      matcher->keySeqs[pos] = NULL;
23066
0
      return(-1);
23067
0
        }
23068
        /*
23069
        * Consume the compiled value.
23070
        */
23071
0
        key->type = simpleType;
23072
0
        key->val = vctxt->inode->val;
23073
0
        vctxt->inode->val = NULL;
23074
        /*
23075
        * Store the key in a global list.
23076
        */
23077
0
        if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
23078
0
      xmlSchemaIDCFreeKey(key);
23079
0
      return (-1);
23080
0
        }
23081
0
    }
23082
0
    keySeq[idx] = key;
23083
0
      }
23084
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
23085
23086
0
      xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
23087
      /* xmlSchemaPSVIIDCBindingPtr bind; */
23088
0
      xmlSchemaPSVIIDCNodePtr ntItem;
23089
0
      xmlSchemaIDCMatcherPtr matcher;
23090
0
      xmlSchemaIDCPtr idc;
23091
0
      xmlSchemaItemListPtr targets;
23092
0
      int pos, i, j, nbKeys;
23093
      /*
23094
      * Here we have the following scenario:
23095
      * An IDC 'selector' state object resolved to a target node,
23096
      * during the time this target node was in the
23097
      * ancestor-or-self axis, the 'field' state object(s) looked
23098
      * out for matching nodes to create a key-sequence for this
23099
      * target node. Now we are back to this target node and need
23100
      * to put the key-sequence, together with the target node
23101
      * itself, into the node-table of the corresponding IDC
23102
      * binding.
23103
      */
23104
0
      matcher = sto->matcher;
23105
0
      idc = matcher->aidc->def;
23106
0
      nbKeys = idc->nbFields;
23107
0
      pos = depth - matcher->depth;
23108
      /*
23109
      * Check if the matcher has any key-sequences at all, plus
23110
      * if it has a key-sequence for the current target node.
23111
      */
23112
0
      if ((matcher->keySeqs == NULL) ||
23113
0
    (matcher->sizeKeySeqs <= pos)) {
23114
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
23115
0
        goto selector_key_error;
23116
0
    else
23117
0
        goto selector_leave;
23118
0
      }
23119
23120
0
      keySeq = &(matcher->keySeqs[pos]);
23121
0
      if (*keySeq == NULL) {
23122
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
23123
0
        goto selector_key_error;
23124
0
    else
23125
0
        goto selector_leave;
23126
0
      }
23127
23128
0
      for (i = 0; i < nbKeys; i++) {
23129
0
    if ((*keySeq)[i] == NULL) {
23130
        /*
23131
        * Not qualified, if not all fields did resolve.
23132
        */
23133
0
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
23134
      /*
23135
      * All fields of a "key" IDC must resolve.
23136
      */
23137
0
      goto selector_key_error;
23138
0
        }
23139
0
        goto selector_leave;
23140
0
    }
23141
0
      }
23142
      /*
23143
      * All fields did resolve.
23144
      */
23145
23146
      /*
23147
      * 4.1 If the {identity-constraint category} is unique(/key),
23148
      * then no two members of the `qualified node set` have
23149
      * `key-sequences` whose members are pairwise equal, as
23150
      * defined by Equal in [XML Schemas: Datatypes].
23151
      *
23152
      * Get the IDC binding from the matcher and check for
23153
      * duplicate key-sequences.
23154
      */
23155
#if 0
23156
      bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23157
#endif
23158
0
      targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
23159
0
      if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
23160
0
    (targets->nbItems != 0)) {
23161
0
    xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
23162
0
    xmlIDCHashEntryPtr e;
23163
23164
0
    res = 0;
23165
23166
0
    if (!matcher->htab)
23167
0
        e = NULL;
23168
0
    else {
23169
0
        xmlChar *value = NULL;
23170
0
        xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
23171
0
        e = xmlHashLookup(matcher->htab, value);
23172
0
        FREE_AND_NULL(value);
23173
0
    }
23174
23175
    /*
23176
    * Compare the key-sequences, key by key.
23177
    */
23178
0
    for (;e; e = e->next) {
23179
0
        bkeySeq =
23180
0
      ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
23181
0
        for (j = 0; j < nbKeys; j++) {
23182
0
      ckey = (*keySeq)[j];
23183
0
      bkey = bkeySeq[j];
23184
0
      res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
23185
0
      if (res == -1) {
23186
0
          return (-1);
23187
0
      } else if (res == 0) {
23188
          /*
23189
          * One of the keys differs, so the key-sequence
23190
          * won't be equal; get out.
23191
          */
23192
0
          break;
23193
0
      }
23194
0
        }
23195
0
        if (res == 1) {
23196
      /*
23197
      * Duplicate key-sequence found.
23198
      */
23199
0
      break;
23200
0
        }
23201
0
    }
23202
0
    if (e) {
23203
0
        xmlChar *str = NULL, *strB = NULL;
23204
        /*
23205
        * TODO: Try to report the key-sequence.
23206
        */
23207
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
23208
0
      XML_SCHEMAV_CVC_IDC, NULL,
23209
0
      WXS_BASIC_CAST idc,
23210
0
      "Duplicate key-sequence %s in %s",
23211
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
23212
0
          (*keySeq), nbKeys),
23213
0
      xmlSchemaGetIDCDesignation(&strB, idc));
23214
0
        FREE_AND_NULL(str);
23215
0
        FREE_AND_NULL(strB);
23216
0
        goto selector_leave;
23217
0
    }
23218
0
      }
23219
      /*
23220
      * Add a node-table item to the IDC binding.
23221
      */
23222
0
      ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
23223
0
    sizeof(xmlSchemaPSVIIDCNode));
23224
0
      if (ntItem == NULL) {
23225
0
    xmlSchemaVErrMemory(NULL,
23226
0
        "allocating an IDC node-table item", NULL);
23227
0
    xmlFree(*keySeq);
23228
0
    *keySeq = NULL;
23229
0
    return(-1);
23230
0
      }
23231
0
      memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
23232
23233
      /*
23234
      * Store the node-table item in a global list.
23235
      */
23236
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23237
0
    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
23238
0
        xmlFree(ntItem);
23239
0
        xmlFree(*keySeq);
23240
0
        *keySeq = NULL;
23241
0
        return (-1);
23242
0
    }
23243
0
    ntItem->nodeQNameID = -1;
23244
0
      } else {
23245
    /*
23246
    * Save a cached QName for this node on the IDC node, to be
23247
    * able to report it, even if the node is not saved.
23248
    */
23249
0
    ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23250
0
        vctxt->inode->localName, vctxt->inode->nsName);
23251
0
    if (ntItem->nodeQNameID == -1) {
23252
0
        xmlFree(ntItem);
23253
0
        xmlFree(*keySeq);
23254
0
        *keySeq = NULL;
23255
0
        return (-1);
23256
0
    }
23257
0
      }
23258
      /*
23259
      * Init the node-table item: Save the node, position and
23260
      * consume the key-sequence.
23261
      */
23262
0
      ntItem->node = vctxt->node;
23263
0
      ntItem->nodeLine = vctxt->inode->nodeLine;
23264
0
      ntItem->keys = *keySeq;
23265
0
      *keySeq = NULL;
23266
#if 0
23267
      if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23268
#endif
23269
0
      if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23270
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23271
        /*
23272
        * Free the item, since keyref items won't be
23273
        * put on a global list.
23274
        */
23275
0
        xmlFree(ntItem->keys);
23276
0
        xmlFree(ntItem);
23277
0
    }
23278
0
    return (-1);
23279
0
      }
23280
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23281
0
    xmlChar *value = NULL;
23282
0
    xmlIDCHashEntryPtr r, e;
23283
0
    if (!matcher->htab)
23284
0
      matcher->htab = xmlHashCreate(4);
23285
0
    xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23286
0
    e = xmlMalloc(sizeof *e);
23287
0
    e->index = targets->nbItems - 1;
23288
0
    r = xmlHashLookup(matcher->htab, value);
23289
0
    if (r) {
23290
0
        e->next = r->next;
23291
0
        r->next = e;
23292
0
    } else {
23293
0
        e->next = NULL;
23294
0
        xmlHashAddEntry(matcher->htab, value, e);
23295
0
    }
23296
0
    FREE_AND_NULL(value);
23297
0
      }
23298
23299
0
      goto selector_leave;
23300
0
selector_key_error:
23301
0
      {
23302
0
    xmlChar *str = NULL;
23303
    /*
23304
    * 4.2.1 (KEY) The `target node set` and the
23305
    * `qualified node set` are equal, that is, every
23306
    * member of the `target node set` is also a member
23307
    * of the `qualified node set` and vice versa.
23308
    */
23309
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
23310
0
        XML_SCHEMAV_CVC_IDC, NULL,
23311
0
        WXS_BASIC_CAST idc,
23312
0
        "Not all fields of %s evaluate to a node",
23313
0
        xmlSchemaGetIDCDesignation(&str, idc), NULL);
23314
0
    FREE_AND_NULL(str);
23315
0
      }
23316
0
selector_leave:
23317
      /*
23318
      * Free the key-sequence if not added to the IDC table.
23319
      */
23320
0
      if ((keySeq != NULL) && (*keySeq != NULL)) {
23321
0
    xmlFree(*keySeq);
23322
0
    *keySeq = NULL;
23323
0
      }
23324
0
  } /* if selector */
23325
23326
0
  sto->nbHistory--;
23327
23328
0
deregister_check:
23329
  /*
23330
  * Deregister state objects if they reach the depth of creation.
23331
  */
23332
0
  if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23333
#ifdef DEBUG_IDC
23334
      xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
23335
    sto->sel->xpath);
23336
#endif
23337
0
      if (vctxt->xpathStates != sto) {
23338
0
    VERROR_INT("xmlSchemaXPathProcessHistory",
23339
0
        "The state object to be removed is not the first "
23340
0
        "in the list");
23341
0
      }
23342
0
      nextsto = sto->next;
23343
      /*
23344
      * Unlink from the list of active XPath state objects.
23345
      */
23346
0
      vctxt->xpathStates = sto->next;
23347
0
      sto->next = vctxt->xpathStatePool;
23348
      /*
23349
      * Link it to the pool of reusable state objects.
23350
      */
23351
0
      vctxt->xpathStatePool = sto;
23352
0
      sto = nextsto;
23353
0
  } else
23354
0
      sto = sto->next;
23355
0
    } /* while (sto != NULL) */
23356
0
    return (0);
23357
0
}
23358
23359
/**
23360
 * xmlSchemaIDCRegisterMatchers:
23361
 * @vctxt: the WXS validation context
23362
 * @elemDecl: the element declaration
23363
 *
23364
 * Creates helper objects to evaluate IDC selectors/fields
23365
 * successively.
23366
 *
23367
 * Returns 0 if OK and -1 on internal errors.
23368
 */
23369
static int
23370
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23371
           xmlSchemaElementPtr elemDecl)
23372
0
{
23373
0
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
23374
0
    xmlSchemaIDCPtr idc, refIdc;
23375
0
    xmlSchemaIDCAugPtr aidc;
23376
23377
0
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23378
0
    if (idc == NULL)
23379
0
  return (0);
23380
23381
#ifdef DEBUG_IDC
23382
    {
23383
  xmlChar *str = NULL;
23384
  xmlGenericError(xmlGenericErrorContext,
23385
      "IDC: REGISTER on %s, depth %d\n",
23386
      (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23387
    vctxt->inode->localName), vctxt->depth);
23388
  FREE_AND_NULL(str)
23389
    }
23390
#endif
23391
0
    if (vctxt->inode->idcMatchers != NULL) {
23392
0
  VERROR_INT("xmlSchemaIDCRegisterMatchers",
23393
0
      "The chain of IDC matchers is expected to be empty");
23394
0
  return (-1);
23395
0
    }
23396
0
    do {
23397
0
  if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23398
      /*
23399
      * Since IDCs bubbles are expensive we need to know the
23400
      * depth at which the bubbles should stop; this will be
23401
      * the depth of the top-most keyref IDC. If no keyref
23402
      * references a key/unique IDC, the keyrefDepth will
23403
      * be -1, indicating that no bubbles are needed.
23404
      */
23405
0
      refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23406
0
      if (refIdc != NULL) {
23407
    /*
23408
    * Remember that we have keyrefs on this node.
23409
    */
23410
0
    vctxt->inode->hasKeyrefs = 1;
23411
    /*
23412
    * Lookup the referenced augmented IDC info.
23413
    */
23414
0
    aidc = vctxt->aidcs;
23415
0
    while (aidc != NULL) {
23416
0
        if (aidc->def == refIdc)
23417
0
      break;
23418
0
        aidc = aidc->next;
23419
0
    }
23420
0
    if (aidc == NULL) {
23421
0
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
23422
0
      "Could not find an augmented IDC item for an IDC "
23423
0
      "definition");
23424
0
        return (-1);
23425
0
    }
23426
0
    if ((aidc->keyrefDepth == -1) ||
23427
0
        (vctxt->depth < aidc->keyrefDepth))
23428
0
        aidc->keyrefDepth = vctxt->depth;
23429
0
      }
23430
0
  }
23431
  /*
23432
  * Lookup the augmented IDC item for the IDC definition.
23433
  */
23434
0
  aidc = vctxt->aidcs;
23435
0
  while (aidc != NULL) {
23436
0
      if (aidc->def == idc)
23437
0
    break;
23438
0
      aidc = aidc->next;
23439
0
  }
23440
0
  if (aidc == NULL) {
23441
0
      VERROR_INT("xmlSchemaIDCRegisterMatchers",
23442
0
    "Could not find an augmented IDC item for an IDC definition");
23443
0
      return (-1);
23444
0
  }
23445
  /*
23446
  * Create an IDC matcher for every IDC definition.
23447
  */
23448
0
  if (vctxt->idcMatcherCache != NULL) {
23449
      /*
23450
      * Reuse a cached matcher.
23451
      */
23452
0
      matcher = vctxt->idcMatcherCache;
23453
0
      vctxt->idcMatcherCache = matcher->nextCached;
23454
0
      matcher->nextCached = NULL;
23455
0
  } else {
23456
0
      matcher = (xmlSchemaIDCMatcherPtr)
23457
0
    xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23458
0
      if (matcher == NULL) {
23459
0
    xmlSchemaVErrMemory(vctxt,
23460
0
        "allocating an IDC matcher", NULL);
23461
0
    return (-1);
23462
0
      }
23463
0
      memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23464
0
  }
23465
0
  if (last == NULL)
23466
0
      vctxt->inode->idcMatchers = matcher;
23467
0
  else
23468
0
      last->next = matcher;
23469
0
  last = matcher;
23470
23471
0
  matcher->type = IDC_MATCHER;
23472
0
  matcher->depth = vctxt->depth;
23473
0
  matcher->aidc = aidc;
23474
0
  matcher->idcType = aidc->def->type;
23475
#ifdef DEBUG_IDC
23476
  xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
23477
#endif
23478
  /*
23479
  * Init the automaton state object.
23480
  */
23481
0
  if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23482
0
      idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23483
0
      return (-1);
23484
23485
0
  idc = idc->next;
23486
0
    } while (idc != NULL);
23487
0
    return (0);
23488
0
}
23489
23490
static int
23491
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23492
         xmlSchemaNodeInfoPtr ielem)
23493
0
{
23494
0
    xmlSchemaPSVIIDCBindingPtr bind;
23495
0
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23496
0
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23497
0
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23498
23499
0
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23500
    /* vctxt->createIDCNodeTables */
23501
0
    while (matcher != NULL) {
23502
  /*
23503
  * Skip keyref IDCs and empty IDC target-lists.
23504
  */
23505
0
  if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23506
0
      WXS_ILIST_IS_EMPTY(matcher->targets))
23507
0
  {
23508
0
      matcher = matcher->next;
23509
0
      continue;
23510
0
  }
23511
  /*
23512
  * If we _want_ the IDC node-table to be created in any case
23513
  * then do so. Otherwise create them only if keyrefs need them.
23514
  */
23515
0
  if ((! vctxt->createIDCNodeTables) &&
23516
0
      ((matcher->aidc->keyrefDepth == -1) ||
23517
0
       (matcher->aidc->keyrefDepth > vctxt->depth)))
23518
0
  {
23519
0
      matcher = matcher->next;
23520
0
      continue;
23521
0
  }
23522
  /*
23523
  * Get/create the IDC binding on this element for the IDC definition.
23524
  */
23525
0
  bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23526
0
  if (bind == NULL)
23527
0
     goto internal_error;
23528
23529
0
  if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23530
0
      dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23531
0
      nbDupls = bind->dupls->nbItems;
23532
0
  } else {
23533
0
      dupls = NULL;
23534
0
      nbDupls = 0;
23535
0
  }
23536
0
  if (bind->nodeTable != NULL) {
23537
0
      nbNodeTable = bind->nbNodes;
23538
0
  } else {
23539
0
      nbNodeTable = 0;
23540
0
  }
23541
23542
0
  if ((nbNodeTable == 0) && (nbDupls == 0)) {
23543
      /*
23544
      * Transfer all IDC target-nodes to the IDC node-table.
23545
      */
23546
0
      bind->nodeTable =
23547
0
    (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23548
0
      bind->sizeNodes = matcher->targets->sizeItems;
23549
0
      bind->nbNodes = matcher->targets->nbItems;
23550
23551
0
      matcher->targets->items = NULL;
23552
0
      matcher->targets->sizeItems = 0;
23553
0
      matcher->targets->nbItems = 0;
23554
0
      if (matcher->htab) {
23555
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23556
0
    matcher->htab = NULL;
23557
0
      }
23558
0
  } else {
23559
      /*
23560
      * Compare the key-sequences and add to the IDC node-table.
23561
      */
23562
0
      nbTargets = matcher->targets->nbItems;
23563
0
      targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23564
0
      nbFields = matcher->aidc->def->nbFields;
23565
0
      i = 0;
23566
0
      do {
23567
0
    keys = targets[i]->keys;
23568
0
    if (nbDupls) {
23569
        /*
23570
        * Search in already found duplicates first.
23571
        */
23572
0
        j = 0;
23573
0
        do {
23574
0
      if (nbFields == 1) {
23575
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23576
0
        dupls[j]->keys[0]->val);
23577
0
          if (res == -1)
23578
0
        goto internal_error;
23579
0
          if (res == 1) {
23580
        /*
23581
        * Equal key-sequence.
23582
        */
23583
0
        goto next_target;
23584
0
          }
23585
0
      } else {
23586
0
          res = 0;
23587
0
          ntkeys = dupls[j]->keys;
23588
0
          for (k = 0; k < nbFields; k++) {
23589
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23590
0
            ntkeys[k]->val);
23591
0
        if (res == -1)
23592
0
            goto internal_error;
23593
0
        if (res == 0) {
23594
            /*
23595
            * One of the keys differs.
23596
            */
23597
0
            break;
23598
0
        }
23599
0
          }
23600
0
          if (res == 1) {
23601
        /*
23602
        * Equal key-sequence found.
23603
        */
23604
0
        goto next_target;
23605
0
          }
23606
0
      }
23607
0
      j++;
23608
0
        } while (j < nbDupls);
23609
0
    }
23610
0
    if (nbNodeTable) {
23611
0
        j = 0;
23612
0
        do {
23613
0
      if (nbFields == 1) {
23614
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23615
0
        bind->nodeTable[j]->keys[0]->val);
23616
0
          if (res == -1)
23617
0
        goto internal_error;
23618
0
          if (res == 0) {
23619
        /*
23620
        * The key-sequence differs.
23621
        */
23622
0
        goto next_node_table_entry;
23623
0
          }
23624
0
      } else {
23625
0
          res = 0;
23626
0
          ntkeys = bind->nodeTable[j]->keys;
23627
0
          for (k = 0; k < nbFields; k++) {
23628
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23629
0
            ntkeys[k]->val);
23630
0
        if (res == -1)
23631
0
            goto internal_error;
23632
0
        if (res == 0) {
23633
            /*
23634
            * One of the keys differs.
23635
            */
23636
0
            goto next_node_table_entry;
23637
0
        }
23638
0
          }
23639
0
      }
23640
      /*
23641
      * Add the duplicate to the list of duplicates.
23642
      */
23643
0
      if (bind->dupls == NULL) {
23644
0
          bind->dupls = xmlSchemaItemListCreate();
23645
0
          if (bind->dupls == NULL)
23646
0
        goto internal_error;
23647
0
      }
23648
0
      if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23649
0
          goto internal_error;
23650
      /*
23651
      * Remove the duplicate entry from the IDC node-table.
23652
      */
23653
0
      bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23654
0
      bind->nbNodes--;
23655
23656
0
      goto next_target;
23657
23658
0
next_node_table_entry:
23659
0
      j++;
23660
0
        } while (j < nbNodeTable);
23661
0
    }
23662
    /*
23663
    * If everything is fine, then add the IDC target-node to
23664
    * the IDC node-table.
23665
    */
23666
0
    if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23667
0
        goto internal_error;
23668
23669
0
next_target:
23670
0
    i++;
23671
0
      } while (i < nbTargets);
23672
0
  }
23673
0
  matcher = matcher->next;
23674
0
    }
23675
0
    return(0);
23676
23677
0
internal_error:
23678
0
    return(-1);
23679
0
}
23680
23681
/**
23682
 * xmlSchemaBubbleIDCNodeTables:
23683
 * @depth: the current tree depth
23684
 *
23685
 * Merges IDC bindings of an element at @depth into the corresponding IDC
23686
 * bindings of its parent element. If a duplicate note-table entry is found,
23687
 * both, the parent node-table entry and child entry are discarded from the
23688
 * node-table of the parent.
23689
 *
23690
 * Returns 0 if OK and -1 on internal errors.
23691
 */
23692
static int
23693
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23694
0
{
23695
0
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23696
0
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23697
0
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23698
0
    xmlSchemaIDCAugPtr aidc;
23699
0
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23700
23701
0
    bind = vctxt->inode->idcTable;
23702
0
    if (bind == NULL) {
23703
  /* Fine, no table, no bubbles. */
23704
0
  return (0);
23705
0
    }
23706
23707
0
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23708
    /*
23709
    * Walk all bindings; create new or add to existing bindings.
23710
    * Remove duplicate key-sequences.
23711
    */
23712
0
    while (bind != NULL) {
23713
23714
0
  if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23715
0
      goto next_binding;
23716
  /*
23717
  * Check if the key/unique IDC table needs to be bubbled.
23718
  */
23719
0
  if (! vctxt->createIDCNodeTables) {
23720
0
      aidc = vctxt->aidcs;
23721
0
      do {
23722
0
    if (aidc->def == bind->definition) {
23723
0
        if ((aidc->keyrefDepth == -1) ||
23724
0
      (aidc->keyrefDepth >= vctxt->depth)) {
23725
0
      goto next_binding;
23726
0
        }
23727
0
        break;
23728
0
    }
23729
0
    aidc = aidc->next;
23730
0
      } while (aidc != NULL);
23731
0
  }
23732
23733
0
  if (parTable != NULL)
23734
0
      parBind = *parTable;
23735
  /*
23736
  * Search a matching parent binding for the
23737
  * IDC definition.
23738
  */
23739
0
  while (parBind != NULL) {
23740
0
      if (parBind->definition == bind->definition)
23741
0
    break;
23742
0
      parBind = parBind->next;
23743
0
  }
23744
23745
0
  if (parBind != NULL) {
23746
      /*
23747
      * Compare every node-table entry of the child node,
23748
      * i.e. the key-sequence within, ...
23749
      */
23750
0
      oldNum = parBind->nbNodes; /* Skip newly added items. */
23751
23752
0
      if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23753
0
    oldDupls = parBind->dupls->nbItems;
23754
0
    dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23755
0
      } else {
23756
0
    dupls = NULL;
23757
0
    oldDupls = 0;
23758
0
      }
23759
23760
0
      parNodes = parBind->nodeTable;
23761
0
      nbFields = bind->definition->nbFields;
23762
23763
0
      for (i = 0; i < bind->nbNodes; i++) {
23764
0
    node = bind->nodeTable[i];
23765
0
    if (node == NULL)
23766
0
        continue;
23767
    /*
23768
    * ...with every key-sequence of the parent node, already
23769
    * evaluated to be a duplicate key-sequence.
23770
    */
23771
0
    if (oldDupls) {
23772
0
        j = 0;
23773
0
        while (j < oldDupls) {
23774
0
      if (nbFields == 1) {
23775
0
          ret = xmlSchemaAreValuesEqual(
23776
0
        node->keys[0]->val,
23777
0
        dupls[j]->keys[0]->val);
23778
0
          if (ret == -1)
23779
0
        goto internal_error;
23780
0
          if (ret == 0) {
23781
0
        j++;
23782
0
        continue;
23783
0
          }
23784
0
      } else {
23785
0
          parNode = dupls[j];
23786
0
          for (k = 0; k < nbFields; k++) {
23787
0
        ret = xmlSchemaAreValuesEqual(
23788
0
            node->keys[k]->val,
23789
0
            parNode->keys[k]->val);
23790
0
        if (ret == -1)
23791
0
            goto internal_error;
23792
0
        if (ret == 0)
23793
0
            break;
23794
0
          }
23795
0
      }
23796
0
      if (ret == 1)
23797
          /* Duplicate found. */
23798
0
          break;
23799
0
      j++;
23800
0
        }
23801
0
        if (j != oldDupls) {
23802
      /* Duplicate found. Skip this entry. */
23803
0
      continue;
23804
0
        }
23805
0
    }
23806
    /*
23807
    * ... and with every key-sequence of the parent node.
23808
    */
23809
0
    if (oldNum) {
23810
0
        j = 0;
23811
0
        while (j < oldNum) {
23812
0
      parNode = parNodes[j];
23813
0
      if (nbFields == 1) {
23814
0
          ret = xmlSchemaAreValuesEqual(
23815
0
        node->keys[0]->val,
23816
0
        parNode->keys[0]->val);
23817
0
          if (ret == -1)
23818
0
        goto internal_error;
23819
0
          if (ret == 0) {
23820
0
        j++;
23821
0
        continue;
23822
0
          }
23823
0
      } else {
23824
0
          for (k = 0; k < nbFields; k++) {
23825
0
        ret = xmlSchemaAreValuesEqual(
23826
0
            node->keys[k]->val,
23827
0
            parNode->keys[k]->val);
23828
0
        if (ret == -1)
23829
0
            goto internal_error;
23830
0
        if (ret == 0)
23831
0
            break;
23832
0
          }
23833
0
      }
23834
0
      if (ret == 1)
23835
          /* Duplicate found. */
23836
0
          break;
23837
0
      j++;
23838
0
        }
23839
0
        if (j != oldNum) {
23840
      /*
23841
      * Handle duplicates. Move the duplicate in
23842
      * the parent's node-table to the list of
23843
      * duplicates.
23844
      */
23845
0
      oldNum--;
23846
0
      parBind->nbNodes--;
23847
      /*
23848
      * Move last old item to pos of duplicate.
23849
      */
23850
0
      parNodes[j] = parNodes[oldNum];
23851
23852
0
      if (parBind->nbNodes != oldNum) {
23853
          /*
23854
          * If new items exist, move last new item to
23855
          * last of old items.
23856
          */
23857
0
          parNodes[oldNum] =
23858
0
        parNodes[parBind->nbNodes];
23859
0
      }
23860
0
      if (parBind->dupls == NULL) {
23861
0
          parBind->dupls = xmlSchemaItemListCreate();
23862
0
          if (parBind->dupls == NULL)
23863
0
        goto internal_error;
23864
0
      }
23865
0
      xmlSchemaItemListAdd(parBind->dupls, parNode);
23866
0
        } else {
23867
      /*
23868
      * Add the node-table entry (node and key-sequence) of
23869
      * the child node to the node table of the parent node.
23870
      */
23871
0
      if (parBind->nodeTable == NULL) {
23872
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23873
0
        xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23874
0
          if (parBind->nodeTable == NULL) {
23875
0
        xmlSchemaVErrMemory(NULL,
23876
0
            "allocating IDC list of node-table items", NULL);
23877
0
        goto internal_error;
23878
0
          }
23879
0
          parBind->sizeNodes = 1;
23880
0
      } else if (parBind->nbNodes >= parBind->sizeNodes) {
23881
0
          parBind->sizeNodes *= 2;
23882
0
          parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23883
0
        xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23884
0
        sizeof(xmlSchemaPSVIIDCNodePtr));
23885
0
          if (parBind->nodeTable == NULL) {
23886
0
        xmlSchemaVErrMemory(NULL,
23887
0
            "re-allocating IDC list of node-table items", NULL);
23888
0
        goto internal_error;
23889
0
          }
23890
0
      }
23891
0
      parNodes = parBind->nodeTable;
23892
      /*
23893
      * Append the new node-table entry to the 'new node-table
23894
      * entries' section.
23895
      */
23896
0
      parNodes[parBind->nbNodes++] = node;
23897
0
        }
23898
23899
0
    }
23900
23901
0
      }
23902
0
  } else {
23903
      /*
23904
      * No binding for the IDC was found: create a new one and
23905
      * copy all node-tables.
23906
      */
23907
0
      parBind = xmlSchemaIDCNewBinding(bind->definition);
23908
0
      if (parBind == NULL)
23909
0
    goto internal_error;
23910
23911
      /*
23912
      * TODO: Hmm, how to optimize the initial number of
23913
      * allocated entries?
23914
      */
23915
0
      if (bind->nbNodes != 0) {
23916
    /*
23917
    * Add all IDC node-table entries.
23918
    */
23919
0
    if (! vctxt->psviExposeIDCNodeTables) {
23920
        /*
23921
        * Just move the entries.
23922
        * NOTE: this is quite save here, since
23923
        * all the keyref lookups have already been
23924
        * performed.
23925
        */
23926
0
        parBind->nodeTable = bind->nodeTable;
23927
0
        bind->nodeTable = NULL;
23928
0
        parBind->sizeNodes = bind->sizeNodes;
23929
0
        bind->sizeNodes = 0;
23930
0
        parBind->nbNodes = bind->nbNodes;
23931
0
        bind->nbNodes = 0;
23932
0
    } else {
23933
        /*
23934
        * Copy the entries.
23935
        */
23936
0
        parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23937
0
      xmlMalloc(bind->nbNodes *
23938
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
23939
0
        if (parBind->nodeTable == NULL) {
23940
0
      xmlSchemaVErrMemory(NULL,
23941
0
          "allocating an array of IDC node-table "
23942
0
          "items", NULL);
23943
0
      xmlSchemaIDCFreeBinding(parBind);
23944
0
      goto internal_error;
23945
0
        }
23946
0
        parBind->sizeNodes = bind->nbNodes;
23947
0
        parBind->nbNodes = bind->nbNodes;
23948
0
        memcpy(parBind->nodeTable, bind->nodeTable,
23949
0
      bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23950
0
    }
23951
0
      }
23952
0
      if (bind->dupls) {
23953
    /*
23954
    * Move the duplicates.
23955
    */
23956
0
    if (parBind->dupls != NULL)
23957
0
        xmlSchemaItemListFree(parBind->dupls);
23958
0
    parBind->dupls = bind->dupls;
23959
0
    bind->dupls = NULL;
23960
0
      }
23961
0
            if (parTable != NULL) {
23962
0
                if (*parTable == NULL)
23963
0
                    *parTable = parBind;
23964
0
                else {
23965
0
                    parBind->next = *parTable;
23966
0
                    *parTable = parBind;
23967
0
                }
23968
0
            }
23969
0
  }
23970
23971
0
next_binding:
23972
0
  bind = bind->next;
23973
0
    }
23974
0
    return (0);
23975
23976
0
internal_error:
23977
0
    return(-1);
23978
0
}
23979
23980
/**
23981
 * xmlSchemaCheckCVCIDCKeyRef:
23982
 * @vctxt: the WXS validation context
23983
 * @elemDecl: the element declaration
23984
 *
23985
 * Check the cvc-idc-keyref constraints.
23986
 */
23987
static int
23988
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23989
0
{
23990
0
    xmlSchemaIDCMatcherPtr matcher;
23991
0
    xmlSchemaPSVIIDCBindingPtr bind;
23992
23993
0
    matcher = vctxt->inode->idcMatchers;
23994
    /*
23995
    * Find a keyref.
23996
    */
23997
0
    while (matcher != NULL) {
23998
0
  if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23999
0
      matcher->targets &&
24000
0
      matcher->targets->nbItems)
24001
0
  {
24002
0
      int i, j, k, res, nbFields, hasDupls;
24003
0
      xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
24004
0
      xmlSchemaPSVIIDCNodePtr refNode = NULL;
24005
0
      xmlHashTablePtr table = NULL;
24006
24007
0
      nbFields = matcher->aidc->def->nbFields;
24008
24009
      /*
24010
      * Find the IDC node-table for the referenced IDC key/unique.
24011
      */
24012
0
      bind = vctxt->inode->idcTable;
24013
0
      while (bind != NULL) {
24014
0
    if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
24015
0
        bind->definition)
24016
0
        break;
24017
0
    bind = bind->next;
24018
0
      }
24019
0
      hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
24020
      /*
24021
      * Search for a matching key-sequences.
24022
      */
24023
0
      if (bind) {
24024
0
    table = xmlHashCreate(bind->nbNodes * 2);
24025
0
    for (j = 0; j < bind->nbNodes; j++) {
24026
0
        xmlChar *value;
24027
0
        xmlIDCHashEntryPtr r, e;
24028
0
        keys = bind->nodeTable[j]->keys;
24029
0
        xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
24030
0
        e = xmlMalloc(sizeof *e);
24031
0
        e->index = j;
24032
0
        r = xmlHashLookup(table, value);
24033
0
        if (r) {
24034
0
      e->next = r->next;
24035
0
      r->next = e;
24036
0
        } else {
24037
0
      e->next = NULL;
24038
0
      xmlHashAddEntry(table, value, e);
24039
0
        }
24040
0
        FREE_AND_NULL(value);
24041
0
    }
24042
0
      }
24043
0
      for (i = 0; i < matcher->targets->nbItems; i++) {
24044
0
    res = 0;
24045
0
    refNode = matcher->targets->items[i];
24046
0
    if (bind != NULL) {
24047
0
        xmlChar *value;
24048
0
        xmlIDCHashEntryPtr e;
24049
0
        refKeys = refNode->keys;
24050
0
        xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
24051
0
        e = xmlHashLookup(table, value);
24052
0
        FREE_AND_NULL(value);
24053
0
        res = 0;
24054
0
        for (;e; e = e->next) {
24055
0
      keys = bind->nodeTable[e->index]->keys;
24056
0
      for (k = 0; k < nbFields; k++) {
24057
0
          res = xmlSchemaAreValuesEqual(keys[k]->val,
24058
0
                refKeys[k]->val);
24059
0
          if (res == 0)
24060
0
              break;
24061
0
          else if (res == -1) {
24062
0
        return (-1);
24063
0
          }
24064
0
      }
24065
0
      if (res == 1) {
24066
          /*
24067
           * Match found.
24068
           */
24069
0
          break;
24070
0
      }
24071
0
        }
24072
0
        if ((res == 0) && hasDupls) {
24073
      /*
24074
      * Search in duplicates
24075
      */
24076
0
      for (j = 0; j < bind->dupls->nbItems; j++) {
24077
0
          keys = ((xmlSchemaPSVIIDCNodePtr)
24078
0
        bind->dupls->items[j])->keys;
24079
0
          for (k = 0; k < nbFields; k++) {
24080
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
24081
0
            refKeys[k]->val);
24082
0
        if (res == 0)
24083
0
            break;
24084
0
        else if (res == -1) {
24085
0
            return (-1);
24086
0
        }
24087
0
          }
24088
0
          if (res == 1) {
24089
        /*
24090
        * Match in duplicates found.
24091
        */
24092
0
        xmlChar *str = NULL, *strB = NULL;
24093
0
        xmlSchemaKeyrefErr(vctxt,
24094
0
            XML_SCHEMAV_CVC_IDC, refNode,
24095
0
            (xmlSchemaTypePtr) matcher->aidc->def,
24096
0
            "More than one match found for "
24097
0
            "key-sequence %s of keyref '%s'",
24098
0
            xmlSchemaFormatIDCKeySequence(vctxt, &str,
24099
0
          refNode->keys, nbFields),
24100
0
            xmlSchemaGetComponentQName(&strB,
24101
0
          matcher->aidc->def));
24102
0
        FREE_AND_NULL(str);
24103
0
        FREE_AND_NULL(strB);
24104
0
        break;
24105
0
          }
24106
0
      }
24107
0
        }
24108
0
    }
24109
24110
0
    if (res == 0) {
24111
0
        xmlChar *str = NULL, *strB = NULL;
24112
0
        xmlSchemaKeyrefErr(vctxt,
24113
0
      XML_SCHEMAV_CVC_IDC, refNode,
24114
0
      (xmlSchemaTypePtr) matcher->aidc->def,
24115
0
      "No match found for key-sequence %s of keyref '%s'",
24116
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
24117
0
          refNode->keys, nbFields),
24118
0
      xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
24119
0
        FREE_AND_NULL(str);
24120
0
        FREE_AND_NULL(strB);
24121
0
    }
24122
0
      }
24123
0
      if (table) {
24124
0
    xmlHashFree(table, xmlFreeIDCHashEntry);
24125
0
      }
24126
0
  }
24127
0
  matcher = matcher->next;
24128
0
    }
24129
    /* TODO: Return an error if any error encountered. */
24130
0
    return (0);
24131
0
}
24132
24133
/************************************************************************
24134
 *                  *
24135
 *      XML Reader validation code                      *
24136
 *                  *
24137
 ************************************************************************/
24138
24139
static xmlSchemaAttrInfoPtr
24140
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
24141
0
{
24142
0
    xmlSchemaAttrInfoPtr iattr;
24143
    /*
24144
    * Grow/create list of attribute infos.
24145
    */
24146
0
    if (vctxt->attrInfos == NULL) {
24147
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
24148
0
      xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
24149
0
  vctxt->sizeAttrInfos = 1;
24150
0
  if (vctxt->attrInfos == NULL) {
24151
0
      xmlSchemaVErrMemory(vctxt,
24152
0
    "allocating attribute info list", NULL);
24153
0
      return (NULL);
24154
0
  }
24155
0
    } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
24156
0
  vctxt->sizeAttrInfos++;
24157
0
  vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
24158
0
      xmlRealloc(vctxt->attrInfos,
24159
0
    vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
24160
0
  if (vctxt->attrInfos == NULL) {
24161
0
      xmlSchemaVErrMemory(vctxt,
24162
0
    "re-allocating attribute info list", NULL);
24163
0
      return (NULL);
24164
0
  }
24165
0
    } else {
24166
0
  iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
24167
0
  if (iattr->localName != NULL) {
24168
0
      VERROR_INT("xmlSchemaGetFreshAttrInfo",
24169
0
    "attr info not cleared");
24170
0
      return (NULL);
24171
0
  }
24172
0
  iattr->nodeType = XML_ATTRIBUTE_NODE;
24173
0
  return (iattr);
24174
0
    }
24175
    /*
24176
    * Create an attribute info.
24177
    */
24178
0
    iattr = (xmlSchemaAttrInfoPtr)
24179
0
  xmlMalloc(sizeof(xmlSchemaAttrInfo));
24180
0
    if (iattr == NULL) {
24181
0
  xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
24182
0
  return (NULL);
24183
0
    }
24184
0
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
24185
0
    iattr->nodeType = XML_ATTRIBUTE_NODE;
24186
0
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
24187
24188
0
    return (iattr);
24189
0
}
24190
24191
static int
24192
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
24193
      xmlNodePtr attrNode,
24194
      int nodeLine,
24195
      const xmlChar *localName,
24196
      const xmlChar *nsName,
24197
      int ownedNames,
24198
      xmlChar *value,
24199
      int ownedValue)
24200
0
{
24201
0
    xmlSchemaAttrInfoPtr attr;
24202
24203
0
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
24204
0
    if (attr == NULL) {
24205
0
  VERROR_INT("xmlSchemaPushAttribute",
24206
0
      "calling xmlSchemaGetFreshAttrInfo()");
24207
0
  return (-1);
24208
0
    }
24209
0
    attr->node = attrNode;
24210
0
    attr->nodeLine = nodeLine;
24211
0
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
24212
0
    attr->localName = localName;
24213
0
    attr->nsName = nsName;
24214
0
    if (ownedNames)
24215
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
24216
    /*
24217
    * Evaluate if it's an XSI attribute.
24218
    */
24219
0
    if (nsName != NULL) {
24220
0
  if (xmlStrEqual(localName, BAD_CAST "nil")) {
24221
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24222
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
24223
0
      }
24224
0
  } else if (xmlStrEqual(localName, BAD_CAST "type")) {
24225
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24226
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
24227
0
      }
24228
0
  } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
24229
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24230
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
24231
0
      }
24232
0
  } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
24233
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
24234
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
24235
0
      }
24236
0
  } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
24237
0
      attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
24238
0
  }
24239
0
    }
24240
0
    attr->value = value;
24241
0
    if (ownedValue)
24242
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
24243
0
    if (attr->metaType != 0)
24244
0
  attr->state = XML_SCHEMAS_ATTR_META;
24245
0
    return (0);
24246
0
}
24247
24248
/**
24249
 * xmlSchemaClearElemInfo:
24250
 * @vctxt: the WXS validation context
24251
 * @ielem: the element information item
24252
 */
24253
static void
24254
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
24255
           xmlSchemaNodeInfoPtr ielem)
24256
0
{
24257
0
    ielem->hasKeyrefs = 0;
24258
0
    ielem->appliedXPath = 0;
24259
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
24260
0
  FREE_AND_NULL(ielem->localName);
24261
0
  FREE_AND_NULL(ielem->nsName);
24262
0
    } else {
24263
0
  ielem->localName = NULL;
24264
0
  ielem->nsName = NULL;
24265
0
    }
24266
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24267
0
  FREE_AND_NULL(ielem->value);
24268
0
    } else {
24269
0
  ielem->value = NULL;
24270
0
    }
24271
0
    if (ielem->val != NULL) {
24272
  /*
24273
  * PSVI TODO: Be careful not to free it when the value is
24274
  * exposed via PSVI.
24275
  */
24276
0
  xmlSchemaFreeValue(ielem->val);
24277
0
  ielem->val = NULL;
24278
0
    }
24279
0
    if (ielem->idcMatchers != NULL) {
24280
  /*
24281
  * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24282
  *   Does it work?
24283
  */
24284
0
  xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24285
#if 0
24286
  xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24287
#endif
24288
0
  ielem->idcMatchers = NULL;
24289
0
    }
24290
0
    if (ielem->idcTable != NULL) {
24291
  /*
24292
  * OPTIMIZE TODO: Use a pool of IDC tables??.
24293
  */
24294
0
  xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24295
0
  ielem->idcTable = NULL;
24296
0
    }
24297
0
    if (ielem->regexCtxt != NULL) {
24298
0
  xmlRegFreeExecCtxt(ielem->regexCtxt);
24299
0
  ielem->regexCtxt = NULL;
24300
0
    }
24301
0
    if (ielem->nsBindings != NULL) {
24302
0
  xmlFree((xmlChar **)ielem->nsBindings);
24303
0
  ielem->nsBindings = NULL;
24304
0
  ielem->nbNsBindings = 0;
24305
0
  ielem->sizeNsBindings = 0;
24306
0
    }
24307
0
}
24308
24309
/**
24310
 * xmlSchemaGetFreshElemInfo:
24311
 * @vctxt: the schema validation context
24312
 *
24313
 * Creates/reuses and initializes the element info item for
24314
 * the current tree depth.
24315
 *
24316
 * Returns the element info item or NULL on API or internal errors.
24317
 */
24318
static xmlSchemaNodeInfoPtr
24319
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24320
0
{
24321
0
    xmlSchemaNodeInfoPtr info = NULL;
24322
24323
0
    if (vctxt->depth > vctxt->sizeElemInfos) {
24324
0
  VERROR_INT("xmlSchemaGetFreshElemInfo",
24325
0
      "inconsistent depth encountered");
24326
0
  return (NULL);
24327
0
    }
24328
0
    if (vctxt->elemInfos == NULL) {
24329
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24330
0
      xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24331
0
  if (vctxt->elemInfos == NULL) {
24332
0
      xmlSchemaVErrMemory(vctxt,
24333
0
    "allocating the element info array", NULL);
24334
0
      return (NULL);
24335
0
  }
24336
0
  memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24337
0
  vctxt->sizeElemInfos = 10;
24338
0
    } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24339
0
  int i = vctxt->sizeElemInfos;
24340
24341
0
  vctxt->sizeElemInfos *= 2;
24342
0
  vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24343
0
      xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24344
0
      sizeof(xmlSchemaNodeInfoPtr));
24345
0
  if (vctxt->elemInfos == NULL) {
24346
0
      xmlSchemaVErrMemory(vctxt,
24347
0
    "re-allocating the element info array", NULL);
24348
0
      return (NULL);
24349
0
  }
24350
  /*
24351
  * We need the new memory to be NULLed.
24352
  * TODO: Use memset instead?
24353
  */
24354
0
  for (; i < vctxt->sizeElemInfos; i++)
24355
0
      vctxt->elemInfos[i] = NULL;
24356
0
    } else
24357
0
  info = vctxt->elemInfos[vctxt->depth];
24358
24359
0
    if (info == NULL) {
24360
0
  info = (xmlSchemaNodeInfoPtr)
24361
0
      xmlMalloc(sizeof(xmlSchemaNodeInfo));
24362
0
  if (info == NULL) {
24363
0
      xmlSchemaVErrMemory(vctxt,
24364
0
    "allocating an element info", NULL);
24365
0
      return (NULL);
24366
0
  }
24367
0
  vctxt->elemInfos[vctxt->depth] = info;
24368
0
    } else {
24369
0
  if (info->localName != NULL) {
24370
0
      VERROR_INT("xmlSchemaGetFreshElemInfo",
24371
0
    "elem info has not been cleared");
24372
0
      return (NULL);
24373
0
  }
24374
0
    }
24375
0
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
24376
0
    info->nodeType = XML_ELEMENT_NODE;
24377
0
    info->depth = vctxt->depth;
24378
24379
0
    return (info);
24380
0
}
24381
24382
0
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24383
0
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24384
0
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24385
24386
static int
24387
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24388
      xmlNodePtr node,
24389
      xmlSchemaTypePtr type,
24390
      xmlSchemaValType valType,
24391
      const xmlChar * value,
24392
      xmlSchemaValPtr val,
24393
      unsigned long length,
24394
      int fireErrors)
24395
0
{
24396
0
    int ret, error = 0, found;
24397
24398
0
    xmlSchemaTypePtr tmpType;
24399
0
    xmlSchemaFacetLinkPtr facetLink;
24400
0
    xmlSchemaFacetPtr facet;
24401
0
    unsigned long len = 0;
24402
0
    xmlSchemaWhitespaceValueType ws;
24403
24404
    /*
24405
    * In Libxml2, derived built-in types have currently no explicit facets.
24406
    */
24407
0
    if (type->type == XML_SCHEMA_TYPE_BASIC)
24408
0
  return (0);
24409
24410
    /*
24411
    * NOTE: Do not jump away, if the facetSet of the given type is
24412
    * empty: until now, "pattern" and "enumeration" facets of the
24413
    * *base types* need to be checked as well.
24414
    */
24415
0
    if (type->facetSet == NULL)
24416
0
  goto pattern_and_enum;
24417
24418
0
    if (! WXS_IS_ATOMIC(type)) {
24419
0
  if (WXS_IS_LIST(type))
24420
0
      goto WXS_IS_LIST;
24421
0
  else
24422
0
      goto pattern_and_enum;
24423
0
    }
24424
24425
    /*
24426
    * Whitespace handling is only of importance for string-based
24427
    * types.
24428
    */
24429
0
    tmpType = xmlSchemaGetPrimitiveType(type);
24430
0
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24431
0
  WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24432
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24433
0
    } else
24434
0
  ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24435
24436
    /*
24437
    * If the value was not computed (for string or
24438
    * anySimpleType based types), then use the provided
24439
    * type.
24440
    */
24441
0
    if (val != NULL)
24442
0
  valType = xmlSchemaGetValType(val);
24443
24444
0
    ret = 0;
24445
0
    for (facetLink = type->facetSet; facetLink != NULL;
24446
0
  facetLink = facetLink->next) {
24447
  /*
24448
  * Skip the pattern "whiteSpace": it is used to
24449
  * format the character content beforehand.
24450
  */
24451
0
  switch (facetLink->facet->type) {
24452
0
      case XML_SCHEMA_FACET_WHITESPACE:
24453
0
      case XML_SCHEMA_FACET_PATTERN:
24454
0
      case XML_SCHEMA_FACET_ENUMERATION:
24455
0
    continue;
24456
0
      case XML_SCHEMA_FACET_LENGTH:
24457
0
      case XML_SCHEMA_FACET_MINLENGTH:
24458
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24459
0
    ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24460
0
        valType, value, val, &len, ws);
24461
0
    break;
24462
0
      default:
24463
0
    ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24464
0
        valType, value, val, ws);
24465
0
    break;
24466
0
  }
24467
0
  if (ret < 0) {
24468
0
      AERROR_INT("xmlSchemaValidateFacets",
24469
0
    "validating against a atomic type facet");
24470
0
      return (-1);
24471
0
  } else if (ret > 0) {
24472
0
      if (fireErrors)
24473
0
    xmlSchemaFacetErr(actxt, ret, node,
24474
0
    value, len, type, facetLink->facet, NULL, NULL, NULL);
24475
0
      else
24476
0
    return (ret);
24477
0
      if (error == 0)
24478
0
    error = ret;
24479
0
  }
24480
0
  ret = 0;
24481
0
    }
24482
24483
0
WXS_IS_LIST:
24484
0
    if (! WXS_IS_LIST(type))
24485
0
  goto pattern_and_enum;
24486
    /*
24487
    * "length", "minLength" and "maxLength" of list types.
24488
    */
24489
0
    ret = 0;
24490
0
    for (facetLink = type->facetSet; facetLink != NULL;
24491
0
  facetLink = facetLink->next) {
24492
24493
0
  switch (facetLink->facet->type) {
24494
0
      case XML_SCHEMA_FACET_LENGTH:
24495
0
      case XML_SCHEMA_FACET_MINLENGTH:
24496
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24497
0
    ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24498
0
        value, length, NULL);
24499
0
    break;
24500
0
      default:
24501
0
    continue;
24502
0
  }
24503
0
  if (ret < 0) {
24504
0
      AERROR_INT("xmlSchemaValidateFacets",
24505
0
    "validating against a list type facet");
24506
0
      return (-1);
24507
0
  } else if (ret > 0) {
24508
0
      if (fireErrors)
24509
0
    xmlSchemaFacetErr(actxt, ret, node,
24510
0
    value, length, type, facetLink->facet, NULL, NULL, NULL);
24511
0
      else
24512
0
    return (ret);
24513
0
      if (error == 0)
24514
0
    error = ret;
24515
0
  }
24516
0
  ret = 0;
24517
0
    }
24518
24519
0
pattern_and_enum:
24520
0
    found = 0;
24521
    /*
24522
    * Process enumerations. Facet values are in the value space
24523
    * of the defining type's base type. This seems to be a bug in the
24524
    * XML Schema 1.0 spec. Use the whitespace type of the base type.
24525
    * Only the first set of enumerations in the ancestor-or-self axis
24526
    * is used for validation.
24527
    */
24528
0
    ret = 0;
24529
0
    tmpType = type;
24530
0
    do {
24531
0
        for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24532
0
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24533
0
                continue;
24534
0
            found = 1;
24535
0
            ret = xmlSchemaAreValuesEqual(facet->val, val);
24536
0
            if (ret == 1)
24537
0
                break;
24538
0
            else if (ret < 0) {
24539
0
                AERROR_INT("xmlSchemaValidateFacets",
24540
0
                    "validating against an enumeration facet");
24541
0
                return (-1);
24542
0
            }
24543
0
        }
24544
0
        if (ret != 0)
24545
0
            break;
24546
        /*
24547
        * Break on the first set of enumerations. Any additional
24548
        *  enumerations which might be existent on the ancestors
24549
        *  of the current type are restricted by this set; thus
24550
        *  *must* *not* be taken into account.
24551
        */
24552
0
        if (found)
24553
0
            break;
24554
0
        tmpType = tmpType->baseType;
24555
0
    } while ((tmpType != NULL) &&
24556
0
        (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24557
0
    if (found && (ret == 0)) {
24558
0
        ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24559
0
        if (fireErrors) {
24560
0
            xmlSchemaFacetErr(actxt, ret, node,
24561
0
                value, 0, type, NULL, NULL, NULL, NULL);
24562
0
        } else
24563
0
            return (ret);
24564
0
        if (error == 0)
24565
0
            error = ret;
24566
0
    }
24567
24568
    /*
24569
    * Process patters. Pattern facets are ORed at type level
24570
    * and ANDed if derived. Walk the base type axis.
24571
    */
24572
0
    tmpType = type;
24573
0
    facet = NULL;
24574
0
    do {
24575
0
        found = 0;
24576
0
        for (facetLink = tmpType->facetSet; facetLink != NULL;
24577
0
            facetLink = facetLink->next) {
24578
0
            if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24579
0
                continue;
24580
0
            found = 1;
24581
            /*
24582
            * NOTE that for patterns, @value needs to be the
24583
            * normalized value.
24584
            */
24585
0
            ret = xmlRegexpExec(facetLink->facet->regexp, value);
24586
0
            if (ret == 1)
24587
0
                break;
24588
0
            else if (ret < 0) {
24589
0
                AERROR_INT("xmlSchemaValidateFacets",
24590
0
                    "validating against a pattern facet");
24591
0
                return (-1);
24592
0
            } else {
24593
                /*
24594
                * Save the last non-validating facet.
24595
                */
24596
0
                facet = facetLink->facet;
24597
0
            }
24598
0
        }
24599
0
        if (found && (ret != 1)) {
24600
0
            ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24601
0
            if (fireErrors) {
24602
0
                xmlSchemaFacetErr(actxt, ret, node,
24603
0
                    value, 0, type, facet, NULL, NULL, NULL);
24604
0
            } else
24605
0
                return (ret);
24606
0
            if (error == 0)
24607
0
                error = ret;
24608
0
            break;
24609
0
        }
24610
0
        tmpType = tmpType->baseType;
24611
0
    } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24612
24613
0
    return (error);
24614
0
}
24615
24616
static xmlChar *
24617
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24618
      const xmlChar *value)
24619
0
{
24620
0
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24621
0
  case XML_SCHEMA_WHITESPACE_COLLAPSE:
24622
0
      return (xmlSchemaCollapseString(value));
24623
0
  case XML_SCHEMA_WHITESPACE_REPLACE:
24624
0
      return (xmlSchemaWhiteSpaceReplace(value));
24625
0
  default:
24626
0
      return (NULL);
24627
0
    }
24628
0
}
24629
24630
static int
24631
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24632
           const xmlChar *value,
24633
           xmlSchemaValPtr *val,
24634
           int valNeeded)
24635
0
{
24636
0
    int ret;
24637
0
    xmlChar *stripped;
24638
0
    const xmlChar *nsName;
24639
0
    xmlChar *local, *prefix = NULL;
24640
24641
0
    ret = xmlValidateQName(value, 1);
24642
0
    if (ret != 0) {
24643
0
  if (ret == -1) {
24644
0
      VERROR_INT("xmlSchemaValidateQName",
24645
0
    "calling xmlValidateQName()");
24646
0
      return (-1);
24647
0
  }
24648
0
  return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24649
0
    }
24650
    /*
24651
    * NOTE: xmlSplitQName2 will always return a duplicated
24652
    * strings.
24653
    */
24654
    /* TODO: Export and use xmlSchemaStrip instead */
24655
0
    stripped = xmlSchemaCollapseString(value);
24656
0
    local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24657
0
    xmlFree(stripped);
24658
0
    if (local == NULL)
24659
0
  local = xmlStrdup(value);
24660
    /*
24661
    * OPTIMIZE TODO: Use flags for:
24662
    *  - is there any namespace binding?
24663
    *  - is there a default namespace?
24664
    */
24665
0
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24666
24667
0
    if (prefix != NULL) {
24668
0
  xmlFree(prefix);
24669
  /*
24670
  * A namespace must be found if the prefix is
24671
  * NOT NULL.
24672
  */
24673
0
  if (nsName == NULL) {
24674
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24675
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24676
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24677
0
    "The QName value '%s' has no "
24678
0
    "corresponding namespace declaration in "
24679
0
    "scope", value, NULL);
24680
0
      if (local != NULL)
24681
0
    xmlFree(local);
24682
0
      return (ret);
24683
0
  }
24684
0
    }
24685
0
    if (valNeeded && val) {
24686
0
  if (nsName != NULL)
24687
0
      *val = xmlSchemaNewQNameValue(
24688
0
    BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24689
0
  else
24690
0
      *val = xmlSchemaNewQNameValue(NULL,
24691
0
    BAD_CAST local);
24692
0
    } else
24693
0
  xmlFree(local);
24694
0
    return (0);
24695
0
}
24696
24697
/*
24698
* cvc-simple-type
24699
*/
24700
static int
24701
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24702
           xmlNodePtr node,
24703
           xmlSchemaTypePtr type,
24704
           const xmlChar *value,
24705
           xmlSchemaValPtr *retVal,
24706
           int fireErrors,
24707
           int normalize,
24708
           int isNormalized)
24709
0
{
24710
0
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
24711
0
    xmlSchemaValPtr val = NULL;
24712
    /* xmlSchemaWhitespaceValueType ws; */
24713
0
    xmlChar *normValue = NULL;
24714
24715
0
#define NORMALIZE(atype) \
24716
0
    if ((! isNormalized) && \
24717
0
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24718
0
  normValue = xmlSchemaNormalizeValue(atype, value); \
24719
0
  if (normValue != NULL) \
24720
0
      value = normValue; \
24721
0
  isNormalized = 1; \
24722
0
    }
24723
24724
0
    if ((retVal != NULL) && (*retVal != NULL)) {
24725
0
  xmlSchemaFreeValue(*retVal);
24726
0
  *retVal = NULL;
24727
0
    }
24728
    /*
24729
    * 3.14.4 Simple Type Definition Validation Rules
24730
    * Validation Rule: String Valid
24731
    */
24732
    /*
24733
    * 1 It is schema-valid with respect to that definition as defined
24734
    * by Datatype Valid in [XML Schemas: Datatypes].
24735
    */
24736
    /*
24737
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24738
    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24739
    * the string must be a `declared entity name`.
24740
    */
24741
    /*
24742
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24743
    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24744
    * then every whitespace-delimited substring of the string must be a `declared
24745
    * entity name`.
24746
    */
24747
    /*
24748
    * 2.3 otherwise no further condition applies.
24749
    */
24750
0
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24751
0
  valNeeded = 1;
24752
0
    if (value == NULL)
24753
0
  value = BAD_CAST "";
24754
0
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24755
0
  xmlSchemaTypePtr biType; /* The built-in type. */
24756
  /*
24757
  * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24758
  * a literal in the `lexical space` of {base type definition}"
24759
  */
24760
  /*
24761
  * Whitespace-normalize.
24762
  */
24763
0
  NORMALIZE(type);
24764
0
  if (type->type != XML_SCHEMA_TYPE_BASIC) {
24765
      /*
24766
      * Get the built-in type.
24767
      */
24768
0
      biType = type->baseType;
24769
0
      while ((biType != NULL) &&
24770
0
    (biType->type != XML_SCHEMA_TYPE_BASIC))
24771
0
    biType = biType->baseType;
24772
24773
0
      if (biType == NULL) {
24774
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24775
0
        "could not get the built-in type");
24776
0
    goto internal_error;
24777
0
      }
24778
0
  } else
24779
0
      biType = type;
24780
  /*
24781
  * NOTATIONs need to be processed here, since they need
24782
  * to lookup in the hashtable of NOTATION declarations of the schema.
24783
  */
24784
0
  if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24785
0
      switch (biType->builtInType) {
24786
0
    case XML_SCHEMAS_NOTATION:
24787
0
        ret = xmlSchemaValidateNotation(
24788
0
      (xmlSchemaValidCtxtPtr) actxt,
24789
0
      ((xmlSchemaValidCtxtPtr) actxt)->schema,
24790
0
      NULL, value, &val, valNeeded);
24791
0
        break;
24792
0
    case XML_SCHEMAS_QNAME:
24793
0
        ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24794
0
      value, &val, valNeeded);
24795
0
        break;
24796
0
    default:
24797
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24798
0
        if (valNeeded)
24799
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24800
0
          value, &val, node);
24801
0
        else
24802
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24803
0
          value, NULL, node);
24804
0
        break;
24805
0
      }
24806
0
  } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24807
0
      switch (biType->builtInType) {
24808
0
    case XML_SCHEMAS_NOTATION:
24809
0
        ret = xmlSchemaValidateNotation(NULL,
24810
0
      ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24811
0
      value, &val, valNeeded);
24812
0
        break;
24813
0
    default:
24814
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24815
0
        if (valNeeded)
24816
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24817
0
          value, &val, node);
24818
0
        else
24819
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24820
0
          value, NULL, node);
24821
0
        break;
24822
0
      }
24823
0
  } else {
24824
      /*
24825
      * Validation via a public API is not implemented yet.
24826
      */
24827
0
      TODO
24828
0
      goto internal_error;
24829
0
  }
24830
0
  if (ret != 0) {
24831
0
      if (ret < 0) {
24832
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24833
0
        "validating against a built-in type");
24834
0
    goto internal_error;
24835
0
      }
24836
0
      if (WXS_IS_LIST(type))
24837
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24838
0
      else
24839
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24840
0
  }
24841
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24842
      /*
24843
      * Check facets.
24844
      */
24845
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24846
0
    (xmlSchemaValType) biType->builtInType, value, val,
24847
0
    0, fireErrors);
24848
0
      if (ret != 0) {
24849
0
    if (ret < 0) {
24850
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24851
0
      "validating facets of atomic simple type");
24852
0
        goto internal_error;
24853
0
    }
24854
0
    if (WXS_IS_LIST(type))
24855
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24856
0
    else
24857
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24858
0
      }
24859
0
  }
24860
0
  else if (fireErrors && (ret > 0))
24861
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24862
0
    } else if (WXS_IS_LIST(type)) {
24863
24864
0
  xmlSchemaTypePtr itemType;
24865
0
  const xmlChar *cur, *end;
24866
0
  xmlChar *tmpValue = NULL;
24867
0
  unsigned long len = 0;
24868
0
  xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24869
  /* 1.2.2 if {variety} is `list` then the string must be a sequence
24870
  * of white space separated tokens, each of which `match`es a literal
24871
  * in the `lexical space` of {item type definition}
24872
  */
24873
  /*
24874
  * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24875
  * the list type has an enum or pattern facet.
24876
  */
24877
0
  NORMALIZE(type);
24878
  /*
24879
  * VAL TODO: Optimize validation of empty values.
24880
  * VAL TODO: We do not have computed values for lists.
24881
  */
24882
0
  itemType = WXS_LIST_ITEMTYPE(type);
24883
0
  cur = value;
24884
0
  do {
24885
0
      while (IS_BLANK_CH(*cur))
24886
0
    cur++;
24887
0
      end = cur;
24888
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24889
0
    end++;
24890
0
      if (end == cur)
24891
0
    break;
24892
0
      tmpValue = xmlStrndup(cur, end - cur);
24893
0
      len++;
24894
24895
0
      if (valNeeded)
24896
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24897
0
        tmpValue, &curVal, fireErrors, 0, 1);
24898
0
      else
24899
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24900
0
        tmpValue, NULL, fireErrors, 0, 1);
24901
0
      FREE_AND_NULL(tmpValue);
24902
0
      if (curVal != NULL) {
24903
    /*
24904
    * Add to list of computed values.
24905
    */
24906
0
    if (val == NULL)
24907
0
        val = curVal;
24908
0
    else
24909
0
        xmlSchemaValueAppend(prevVal, curVal);
24910
0
    prevVal = curVal;
24911
0
    curVal = NULL;
24912
0
      }
24913
0
      if (ret != 0) {
24914
0
    if (ret < 0) {
24915
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24916
0
      "validating an item of list simple type");
24917
0
        goto internal_error;
24918
0
    }
24919
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24920
0
    break;
24921
0
      }
24922
0
      cur = end;
24923
0
  } while (*cur != 0);
24924
0
  FREE_AND_NULL(tmpValue);
24925
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24926
      /*
24927
      * Apply facets (pattern, enumeration).
24928
      */
24929
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24930
0
    XML_SCHEMAS_UNKNOWN, value, val,
24931
0
    len, fireErrors);
24932
0
      if (ret != 0) {
24933
0
    if (ret < 0) {
24934
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24935
0
      "validating facets of list simple type");
24936
0
        goto internal_error;
24937
0
    }
24938
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24939
0
      }
24940
0
  }
24941
0
  if (fireErrors && (ret > 0)) {
24942
      /*
24943
      * Report the normalized value.
24944
      */
24945
0
      normalize = 1;
24946
0
      NORMALIZE(type);
24947
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24948
0
  }
24949
0
    } else if (WXS_IS_UNION(type)) {
24950
0
  xmlSchemaTypeLinkPtr memberLink;
24951
  /*
24952
  * TODO: For all datatypes `derived` by `union`  whiteSpace does
24953
  * not apply directly; however, the normalization behavior of `union`
24954
  * types is controlled by the value of whiteSpace on that one of the
24955
  * `memberTypes` against which the `union` is successfully validated.
24956
  *
24957
  * This means that the value is normalized by the first validating
24958
  * member type, then the facets of the union type are applied. This
24959
  * needs changing of the value!
24960
  */
24961
24962
  /*
24963
  * 1.2.3 if {variety} is `union` then the string must `match` a
24964
  * literal in the `lexical space` of at least one member of
24965
  * {member type definitions}
24966
  */
24967
0
  memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24968
0
  if (memberLink == NULL) {
24969
0
      AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24970
0
    "union simple type has no member types");
24971
0
      goto internal_error;
24972
0
  }
24973
  /*
24974
  * Always normalize union type values, since we currently
24975
  * cannot store the whitespace information with the value
24976
  * itself; otherwise a later value-comparison would be
24977
  * not possible.
24978
  */
24979
0
  while (memberLink != NULL) {
24980
0
      if (valNeeded)
24981
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24982
0
        memberLink->type, value, &val, 0, 1, 0);
24983
0
      else
24984
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24985
0
        memberLink->type, value, NULL, 0, 1, 0);
24986
0
      if (ret <= 0)
24987
0
    break;
24988
0
      memberLink = memberLink->next;
24989
0
  }
24990
0
  if (ret != 0) {
24991
0
      if (ret < 0) {
24992
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24993
0
        "validating members of union simple type");
24994
0
    goto internal_error;
24995
0
      }
24996
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24997
0
  }
24998
  /*
24999
  * Apply facets (pattern, enumeration).
25000
  */
25001
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
25002
      /*
25003
      * The normalization behavior of `union` types is controlled by
25004
      * the value of whiteSpace on that one of the `memberTypes`
25005
      * against which the `union` is successfully validated.
25006
      */
25007
0
      NORMALIZE(memberLink->type);
25008
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
25009
0
    XML_SCHEMAS_UNKNOWN, value, val,
25010
0
    0, fireErrors);
25011
0
      if (ret != 0) {
25012
0
    if (ret < 0) {
25013
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
25014
0
      "validating facets of union simple type");
25015
0
        goto internal_error;
25016
0
    }
25017
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
25018
0
      }
25019
0
  }
25020
0
  if (fireErrors && (ret > 0))
25021
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
25022
0
    }
25023
25024
0
    if (normValue != NULL)
25025
0
  xmlFree(normValue);
25026
0
    if (ret == 0) {
25027
0
  if (retVal != NULL)
25028
0
      *retVal = val;
25029
0
  else if (val != NULL)
25030
0
      xmlSchemaFreeValue(val);
25031
0
    } else if (val != NULL)
25032
0
  xmlSchemaFreeValue(val);
25033
0
    return (ret);
25034
0
internal_error:
25035
0
    if (normValue != NULL)
25036
0
  xmlFree(normValue);
25037
0
    if (val != NULL)
25038
0
  xmlSchemaFreeValue(val);
25039
0
    return (-1);
25040
0
}
25041
25042
static int
25043
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
25044
         const xmlChar *value,
25045
         const xmlChar **nsName,
25046
         const xmlChar **localName)
25047
0
{
25048
0
    int ret = 0;
25049
25050
0
    if ((nsName == NULL) || (localName == NULL))
25051
0
  return (-1);
25052
0
    *nsName = NULL;
25053
0
    *localName = NULL;
25054
25055
0
    ret = xmlValidateQName(value, 1);
25056
0
    if (ret == -1)
25057
0
  return (-1);
25058
0
    if (ret > 0) {
25059
0
  xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
25060
0
      XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
25061
0
      value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
25062
0
  return (1);
25063
0
    }
25064
0
    {
25065
0
  xmlChar *local = NULL;
25066
0
  xmlChar *prefix;
25067
25068
  /*
25069
  * NOTE: xmlSplitQName2 will return a duplicated
25070
  * string.
25071
  */
25072
0
  local = xmlSplitQName2(value, &prefix);
25073
0
  if (local == NULL)
25074
0
      *localName = xmlDictLookup(vctxt->dict, value, -1);
25075
0
  else {
25076
0
      *localName = xmlDictLookup(vctxt->dict, local, -1);
25077
0
      xmlFree(local);
25078
0
  }
25079
25080
0
  *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
25081
25082
0
  if (prefix != NULL) {
25083
0
      xmlFree(prefix);
25084
      /*
25085
      * A namespace must be found if the prefix is NOT NULL.
25086
      */
25087
0
      if (*nsName == NULL) {
25088
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25089
0
        XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
25090
0
        WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
25091
0
        "The QName value '%s' has no "
25092
0
        "corresponding namespace declaration in scope",
25093
0
        value, NULL);
25094
0
    return (2);
25095
0
      }
25096
0
  }
25097
0
    }
25098
0
    return (0);
25099
0
}
25100
25101
static int
25102
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
25103
      xmlSchemaAttrInfoPtr iattr,
25104
      xmlSchemaTypePtr *localType,
25105
      xmlSchemaElementPtr elemDecl)
25106
0
{
25107
0
    int ret = 0;
25108
    /*
25109
    * cvc-elt (3.3.4) : (4)
25110
    * AND
25111
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
25112
    *   (1.2.1.2.1) - (1.2.1.2.4)
25113
    * Handle 'xsi:type'.
25114
    */
25115
0
    if (localType == NULL)
25116
0
  return (-1);
25117
0
    *localType = NULL;
25118
0
    if (iattr == NULL)
25119
0
  return (0);
25120
0
    else {
25121
0
  const xmlChar *nsName = NULL, *local = NULL;
25122
  /*
25123
  * TODO: We should report a *warning* that the type was overridden
25124
  * by the instance.
25125
  */
25126
0
  ACTIVATE_ATTRIBUTE(iattr);
25127
  /*
25128
  * (cvc-elt) (3.3.4) : (4.1)
25129
  * (cvc-assess-elt) (1.2.1.2.2)
25130
  */
25131
0
  ret = xmlSchemaVExpandQName(vctxt, iattr->value,
25132
0
      &nsName, &local);
25133
0
  if (ret != 0) {
25134
0
      if (ret < 0) {
25135
0
    VERROR_INT("xmlSchemaValidateElementByDeclaration",
25136
0
        "calling xmlSchemaQNameExpand() to validate the "
25137
0
        "attribute 'xsi:type'");
25138
0
    goto internal_error;
25139
0
      }
25140
0
      goto exit;
25141
0
  }
25142
  /*
25143
  * (cvc-elt) (3.3.4) : (4.2)
25144
  * (cvc-assess-elt) (1.2.1.2.3)
25145
  */
25146
0
  *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
25147
0
  if (*localType == NULL) {
25148
0
      xmlChar *str = NULL;
25149
25150
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
25151
0
    XML_SCHEMAV_CVC_ELT_4_2, NULL,
25152
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
25153
0
    "The QName value '%s' of the xsi:type attribute does not "
25154
0
    "resolve to a type definition",
25155
0
    xmlSchemaFormatQName(&str, nsName, local), NULL);
25156
0
      FREE_AND_NULL(str);
25157
0
      ret = vctxt->err;
25158
0
      goto exit;
25159
0
  }
25160
0
  if (elemDecl != NULL) {
25161
0
      int set = 0;
25162
25163
      /*
25164
      * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
25165
      * "The `local type definition` must be validly
25166
      * derived from the {type definition} given the union of
25167
      * the {disallowed substitutions} and the {type definition}'s
25168
      * {prohibited substitutions}, as defined in
25169
      * Type Derivation OK (Complex) ($3.4.6)
25170
      * (if it is a complex type definition),
25171
      * or given {disallowed substitutions} as defined in Type
25172
      * Derivation OK (Simple) ($3.14.6) (if it is a simple type
25173
      * definition)."
25174
      *
25175
      * {disallowed substitutions}: the "block" on the element decl.
25176
      * {prohibited substitutions}: the "block" on the type def.
25177
      */
25178
      /*
25179
      * OPTIMIZE TODO: We could map types already evaluated
25180
      * to be validly derived from other types to avoid checking
25181
      * this over and over for the same types.
25182
      */
25183
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
25184
0
    (elemDecl->subtypes->flags &
25185
0
        XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
25186
0
    set |= SUBSET_EXTENSION;
25187
25188
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
25189
0
    (elemDecl->subtypes->flags &
25190
0
        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
25191
0
    set |= SUBSET_RESTRICTION;
25192
25193
      /*
25194
      * REMOVED and CHANGED since this produced a parser context
25195
      * which adds to the string dict of the schema. So this would
25196
      * change the schema and we don't want this. We don't need
25197
      * the parser context anymore.
25198
      *
25199
      * if ((vctxt->pctxt == NULL) &&
25200
      * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
25201
      *     return (-1);
25202
      */
25203
25204
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
25205
0
    elemDecl->subtypes, set) != 0) {
25206
0
    xmlChar *str = NULL;
25207
25208
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25209
0
        XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
25210
0
        "The type definition '%s', specified by xsi:type, is "
25211
0
        "blocked or not validly derived from the type definition "
25212
0
        "of the element declaration",
25213
0
        xmlSchemaFormatQName(&str,
25214
0
      (*localType)->targetNamespace,
25215
0
      (*localType)->name),
25216
0
        NULL);
25217
0
    FREE_AND_NULL(str);
25218
0
    ret = vctxt->err;
25219
0
    *localType = NULL;
25220
0
      }
25221
0
  }
25222
0
    }
25223
0
exit:
25224
0
    ACTIVATE_ELEM;
25225
0
    return (ret);
25226
0
internal_error:
25227
0
    ACTIVATE_ELEM;
25228
0
    return (-1);
25229
0
}
25230
25231
static int
25232
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
25233
0
{
25234
0
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
25235
0
    xmlSchemaTypePtr actualType;
25236
25237
    /*
25238
    * cvc-elt (3.3.4) : 1
25239
    */
25240
0
    if (elemDecl == NULL) {
25241
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
25242
0
      "No matching declaration available");
25243
0
        return (vctxt->err);
25244
0
    }
25245
0
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
25246
    /*
25247
    * cvc-elt (3.3.4) : 2
25248
    */
25249
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
25250
0
  VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
25251
0
      "The element declaration is abstract");
25252
0
        return (vctxt->err);
25253
0
    }
25254
0
    if (actualType == NULL) {
25255
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25256
0
      "The type definition is absent");
25257
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25258
0
    }
25259
0
    if (vctxt->nbAttrInfos != 0) {
25260
0
  int ret;
25261
0
  xmlSchemaAttrInfoPtr iattr;
25262
  /*
25263
  * cvc-elt (3.3.4) : 3
25264
  * Handle 'xsi:nil'.
25265
  */
25266
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25267
0
      XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25268
0
  if (iattr) {
25269
0
      ACTIVATE_ATTRIBUTE(iattr);
25270
      /*
25271
      * Validate the value.
25272
      */
25273
0
      ret = xmlSchemaVCheckCVCSimpleType(
25274
0
    ACTXT_CAST vctxt, NULL,
25275
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25276
0
    iattr->value, &(iattr->val), 1, 0, 0);
25277
0
      ACTIVATE_ELEM;
25278
0
      if (ret < 0) {
25279
0
    VERROR_INT("xmlSchemaValidateElemDecl",
25280
0
        "calling xmlSchemaVCheckCVCSimpleType() to "
25281
0
        "validate the attribute 'xsi:nil'");
25282
0
    return (-1);
25283
0
      }
25284
0
      if (ret == 0) {
25285
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25286
        /*
25287
        * cvc-elt (3.3.4) : 3.1
25288
        */
25289
0
        VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25290
0
      "The element is not 'nillable'");
25291
        /* Does not return an error on purpose. */
25292
0
    } else {
25293
0
        if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25294
      /*
25295
      * cvc-elt (3.3.4) : 3.2.2
25296
      */
25297
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25298
0
          (elemDecl->value != NULL)) {
25299
0
          VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25300
0
        "The element cannot be 'nilled' because "
25301
0
        "there is a fixed value constraint defined "
25302
0
        "for it");
25303
           /* Does not return an error on purpose. */
25304
0
      } else
25305
0
          vctxt->inode->flags |=
25306
0
        XML_SCHEMA_ELEM_INFO_NILLED;
25307
0
        }
25308
0
    }
25309
0
      }
25310
0
  }
25311
  /*
25312
  * cvc-elt (3.3.4) : 4
25313
  * Handle 'xsi:type'.
25314
  */
25315
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25316
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25317
0
  if (iattr) {
25318
0
      xmlSchemaTypePtr localType = NULL;
25319
25320
0
      ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25321
0
    elemDecl);
25322
0
      if (ret != 0) {
25323
0
    if (ret == -1) {
25324
0
        VERROR_INT("xmlSchemaValidateElemDecl",
25325
0
      "calling xmlSchemaProcessXSIType() to "
25326
0
      "process the attribute 'xsi:type'");
25327
0
        return (-1);
25328
0
    }
25329
    /* Does not return an error on purpose. */
25330
0
      }
25331
0
      if (localType != NULL) {
25332
0
    vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25333
0
    actualType = localType;
25334
0
      }
25335
0
  }
25336
0
    }
25337
    /*
25338
    * IDC: Register identity-constraint XPath matchers.
25339
    */
25340
0
    if ((elemDecl->idcs != NULL) &&
25341
0
  (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25342
0
      return (-1);
25343
    /*
25344
    * No actual type definition.
25345
    */
25346
0
    if (actualType == NULL) {
25347
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25348
0
      "The type definition is absent");
25349
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25350
0
    }
25351
    /*
25352
    * Remember the actual type definition.
25353
    */
25354
0
    vctxt->inode->typeDef = actualType;
25355
25356
0
    return (0);
25357
0
}
25358
25359
static int
25360
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25361
0
{
25362
0
    xmlSchemaAttrInfoPtr iattr;
25363
0
    int ret = 0, i;
25364
25365
    /*
25366
    * SPEC cvc-type (3.1.1)
25367
    * "The attributes of must be empty, excepting those whose namespace
25368
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25369
    * whose local name is one of type, nil, schemaLocation or
25370
    * noNamespaceSchemaLocation."
25371
    */
25372
0
    if (vctxt->nbAttrInfos == 0)
25373
0
  return (0);
25374
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25375
0
  iattr = vctxt->attrInfos[i];
25376
0
  if (! iattr->metaType) {
25377
0
      ACTIVATE_ATTRIBUTE(iattr)
25378
0
      xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25379
0
    XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25380
0
      ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25381
0
        }
25382
0
    }
25383
0
    ACTIVATE_ELEM
25384
0
    return (ret);
25385
0
}
25386
25387
/*
25388
* Cleanup currently used attribute infos.
25389
*/
25390
static void
25391
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25392
0
{
25393
0
    int i;
25394
0
    xmlSchemaAttrInfoPtr attr;
25395
25396
0
    if (vctxt->nbAttrInfos == 0)
25397
0
  return;
25398
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25399
0
  attr = vctxt->attrInfos[i];
25400
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25401
0
      if (attr->localName != NULL)
25402
0
    xmlFree((xmlChar *) attr->localName);
25403
0
      if (attr->nsName != NULL)
25404
0
    xmlFree((xmlChar *) attr->nsName);
25405
0
  }
25406
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25407
0
      if (attr->value != NULL)
25408
0
    xmlFree((xmlChar *) attr->value);
25409
0
  }
25410
0
  if (attr->val != NULL) {
25411
0
      xmlSchemaFreeValue(attr->val);
25412
0
      attr->val = NULL;
25413
0
  }
25414
0
  memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25415
0
    }
25416
0
    vctxt->nbAttrInfos = 0;
25417
0
}
25418
25419
/*
25420
* 3.4.4 Complex Type Definition Validation Rules
25421
*   Element Locally Valid (Complex Type) (cvc-complex-type)
25422
* 3.2.4 Attribute Declaration Validation Rules
25423
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
25424
*   Attribute Locally Valid (Use) (cvc-au)
25425
*
25426
* Only "assessed" attribute information items will be visible to
25427
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25428
*/
25429
static int
25430
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25431
0
{
25432
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef;
25433
0
    xmlSchemaItemListPtr attrUseList;
25434
0
    xmlSchemaAttributeUsePtr attrUse = NULL;
25435
0
    xmlSchemaAttributePtr attrDecl = NULL;
25436
0
    xmlSchemaAttrInfoPtr iattr, tmpiattr;
25437
0
    int i, j, found, nbAttrs, nbUses;
25438
0
    int xpathRes = 0, res, wildIDs = 0, fixed;
25439
0
    xmlNodePtr defAttrOwnerElem = NULL;
25440
25441
    /*
25442
    * SPEC (cvc-attribute)
25443
    * (1) "The declaration must not be `absent` (see Missing
25444
    * Sub-components ($5.3) for how this can fail to be
25445
    * the case)."
25446
    * (2) "Its {type definition} must not be absent."
25447
    *
25448
    * NOTE (1) + (2): This is not handled here, since we currently do not
25449
    * allow validation against schemas which have missing sub-components.
25450
    *
25451
    * SPEC (cvc-complex-type)
25452
    * (3) "For each attribute information item in the element information
25453
    * item's [attributes] excepting those whose [namespace name] is
25454
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25455
    * [local name] is one of type, nil, schemaLocation or
25456
    * noNamespaceSchemaLocation, the appropriate case among the following
25457
    * must be true:
25458
    *
25459
    */
25460
0
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25461
    /*
25462
    * @nbAttrs is the number of attributes present in the instance.
25463
    */
25464
0
    nbAttrs = vctxt->nbAttrInfos;
25465
0
    if (attrUseList != NULL)
25466
0
  nbUses = attrUseList->nbItems;
25467
0
    else
25468
0
  nbUses = 0;
25469
0
    for (i = 0; i < nbUses; i++) {
25470
0
        found = 0;
25471
0
  attrUse = attrUseList->items[i];
25472
0
  attrDecl = WXS_ATTRUSE_DECL(attrUse);
25473
0
        for (j = 0; j < nbAttrs; j++) {
25474
0
      iattr = vctxt->attrInfos[j];
25475
      /*
25476
      * SPEC (cvc-complex-type) (3)
25477
      * Skip meta attributes.
25478
      */
25479
0
      if (iattr->metaType)
25480
0
    continue;
25481
0
      if (iattr->localName[0] != attrDecl->name[0])
25482
0
    continue;
25483
0
      if (!xmlStrEqual(iattr->localName, attrDecl->name))
25484
0
    continue;
25485
0
      if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25486
0
    continue;
25487
0
      found = 1;
25488
      /*
25489
      * SPEC (cvc-complex-type)
25490
      * (3.1) "If there is among the {attribute uses} an attribute
25491
      * use with an {attribute declaration} whose {name} matches
25492
      * the attribute information item's [local name] and whose
25493
      * {target namespace} is identical to the attribute information
25494
      * item's [namespace name] (where an `absent` {target namespace}
25495
      * is taken to be identical to a [namespace name] with no value),
25496
      * then the attribute information must be `valid` with respect
25497
      * to that attribute use as per Attribute Locally Valid (Use)
25498
      * ($3.5.4). In this case the {attribute declaration} of that
25499
      * attribute use is the `context-determined declaration` for the
25500
      * attribute information item with respect to Schema-Validity
25501
      * Assessment (Attribute) ($3.2.4) and
25502
      * Assessment Outcome (Attribute) ($3.2.5).
25503
      */
25504
0
      iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25505
0
      iattr->use = attrUse;
25506
      /*
25507
      * Context-determined declaration.
25508
      */
25509
0
      iattr->decl = attrDecl;
25510
0
      iattr->typeDef = attrDecl->subtypes;
25511
0
      break;
25512
0
  }
25513
25514
0
  if (found)
25515
0
      continue;
25516
25517
0
  if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25518
      /*
25519
      * Handle non-existent, required attributes.
25520
      *
25521
      * SPEC (cvc-complex-type)
25522
      * (4) "The {attribute declaration} of each attribute use in
25523
      * the {attribute uses} whose {required} is true matches one
25524
      * of the attribute information items in the element information
25525
      * item's [attributes] as per clause 3.1 above."
25526
      */
25527
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25528
0
      if (tmpiattr == NULL) {
25529
0
    VERROR_INT(
25530
0
        "xmlSchemaVAttributesComplex",
25531
0
        "calling xmlSchemaGetFreshAttrInfo()");
25532
0
    return (-1);
25533
0
      }
25534
0
      tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25535
0
      tmpiattr->use = attrUse;
25536
0
      tmpiattr->decl = attrDecl;
25537
0
  } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25538
0
      ((attrUse->defValue != NULL) ||
25539
0
       (attrDecl->defValue != NULL))) {
25540
      /*
25541
      * Handle non-existent, optional, default/fixed attributes.
25542
      */
25543
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25544
0
      if (tmpiattr == NULL) {
25545
0
    VERROR_INT(
25546
0
        "xmlSchemaVAttributesComplex",
25547
0
        "calling xmlSchemaGetFreshAttrInfo()");
25548
0
    return (-1);
25549
0
      }
25550
0
      tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25551
0
      tmpiattr->use = attrUse;
25552
0
      tmpiattr->decl = attrDecl;
25553
0
      tmpiattr->typeDef = attrDecl->subtypes;
25554
0
      tmpiattr->localName = attrDecl->name;
25555
0
      tmpiattr->nsName = attrDecl->targetNamespace;
25556
0
  }
25557
0
    }
25558
25559
0
    if (vctxt->nbAttrInfos == 0)
25560
0
  return (0);
25561
    /*
25562
    * Validate against the wildcard.
25563
    */
25564
0
    if (type->attributeWildcard != NULL) {
25565
  /*
25566
  * SPEC (cvc-complex-type)
25567
  * (3.2.1) "There must be an {attribute wildcard}."
25568
  */
25569
0
  for (i = 0; i < nbAttrs; i++) {
25570
0
      iattr = vctxt->attrInfos[i];
25571
      /*
25572
      * SPEC (cvc-complex-type) (3)
25573
      * Skip meta attributes.
25574
      */
25575
0
      if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25576
0
    continue;
25577
      /*
25578
      * SPEC (cvc-complex-type)
25579
      * (3.2.2) "The attribute information item must be `valid` with
25580
      * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25581
      *
25582
      * SPEC Item Valid (Wildcard) (cvc-wildcard)
25583
      * "... its [namespace name] must be `valid` with respect to
25584
      * the wildcard constraint, as defined in Wildcard allows
25585
      * Namespace Name ($3.10.4)."
25586
      */
25587
0
      if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25588
0
        iattr->nsName) == 0) {
25589
    /*
25590
    * Handle processContents.
25591
    *
25592
    * SPEC (cvc-wildcard):
25593
    * processContents | context-determined declaration:
25594
    * "strict"          "mustFind"
25595
    * "lax"             "none"
25596
    * "skip"            "skip"
25597
    */
25598
0
    if (type->attributeWildcard->processContents ==
25599
0
        XML_SCHEMAS_ANY_SKIP) {
25600
         /*
25601
        * context-determined declaration = "skip"
25602
        *
25603
        * SPEC PSVI Assessment Outcome (Attribute)
25604
        * [validity] = "notKnown"
25605
        * [validation attempted] = "none"
25606
        */
25607
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25608
0
        continue;
25609
0
    }
25610
    /*
25611
    * Find an attribute declaration.
25612
    */
25613
0
    iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25614
0
        iattr->localName, iattr->nsName);
25615
0
    if (iattr->decl != NULL) {
25616
0
        iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25617
        /*
25618
        * SPEC (cvc-complex-type)
25619
        * (5) "Let [Definition:]  the wild IDs be the set of
25620
        * all attribute information item to which clause 3.2
25621
        * applied and whose `validation` resulted in a
25622
        * `context-determined declaration` of mustFind or no
25623
        * `context-determined declaration` at all, and whose
25624
        * [local name] and [namespace name] resolve (as
25625
        * defined by QName resolution (Instance) ($3.15.4)) to
25626
        * an attribute declaration whose {type definition} is
25627
        * or is derived from ID. Then all of the following
25628
        * must be true:"
25629
        */
25630
0
        iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25631
0
        if (xmlSchemaIsDerivedFromBuiltInType(
25632
0
      iattr->typeDef, XML_SCHEMAS_ID)) {
25633
      /*
25634
      * SPEC (5.1) "There must be no more than one
25635
      * item in `wild IDs`."
25636
      */
25637
0
      if (wildIDs != 0) {
25638
          /* VAL TODO */
25639
0
          iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25640
0
          TODO
25641
0
          continue;
25642
0
      }
25643
0
      wildIDs++;
25644
      /*
25645
      * SPEC (cvc-complex-type)
25646
      * (5.2) "If `wild IDs` is non-empty, there must not
25647
      * be any attribute uses among the {attribute uses}
25648
      * whose {attribute declaration}'s {type definition}
25649
      * is or is derived from ID."
25650
      */
25651
0
                        if (attrUseList != NULL) {
25652
0
                            for (j = 0; j < attrUseList->nbItems; j++) {
25653
0
                                if (xmlSchemaIsDerivedFromBuiltInType(
25654
0
                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25655
0
                                    XML_SCHEMAS_ID)) {
25656
                                    /* URGENT VAL TODO: implement */
25657
0
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25658
0
                                    TODO
25659
0
                                    break;
25660
0
                                }
25661
0
                            }
25662
0
                        }
25663
0
        }
25664
0
    } else if (type->attributeWildcard->processContents ==
25665
0
        XML_SCHEMAS_ANY_LAX) {
25666
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25667
        /*
25668
        * SPEC PSVI Assessment Outcome (Attribute)
25669
        * [validity] = "notKnown"
25670
        * [validation attempted] = "none"
25671
        */
25672
0
    } else {
25673
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25674
0
    }
25675
0
      }
25676
0
  }
25677
0
    }
25678
25679
0
    if (vctxt->nbAttrInfos == 0)
25680
0
  return (0);
25681
25682
    /*
25683
    * Get the owner element; needed for creation of default attributes.
25684
    * This fixes bug #341337, reported by David Grohmann.
25685
    */
25686
0
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25687
0
  xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25688
0
  if (ielem && ielem->node && ielem->node->doc)
25689
0
      defAttrOwnerElem = ielem->node;
25690
0
    }
25691
    /*
25692
    * Validate values, create default attributes, evaluate IDCs.
25693
    */
25694
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25695
0
  iattr = vctxt->attrInfos[i];
25696
  /*
25697
  * VAL TODO: Note that we won't try to resolve IDCs to
25698
  * "lax" and "skip" validated attributes. Check what to
25699
  * do in this case.
25700
  */
25701
0
  if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25702
0
      (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25703
0
      continue;
25704
  /*
25705
  * VAL TODO: What to do if the type definition is missing?
25706
  */
25707
0
  if (iattr->typeDef == NULL) {
25708
0
      iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25709
0
      continue;
25710
0
  }
25711
25712
0
  ACTIVATE_ATTRIBUTE(iattr);
25713
0
  fixed = 0;
25714
0
  xpathRes = 0;
25715
25716
0
  if (vctxt->xpathStates != NULL) {
25717
      /*
25718
      * Evaluate IDCs.
25719
      */
25720
0
      xpathRes = xmlSchemaXPathEvaluate(vctxt,
25721
0
    XML_ATTRIBUTE_NODE);
25722
0
      if (xpathRes == -1) {
25723
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25724
0
        "calling xmlSchemaXPathEvaluate()");
25725
0
    goto internal_error;
25726
0
      }
25727
0
  }
25728
25729
0
  if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25730
      /*
25731
      * Default/fixed attributes.
25732
      * We need the value only if we need to resolve IDCs or
25733
      * will create default attributes.
25734
      */
25735
0
      if ((xpathRes) || (defAttrOwnerElem)) {
25736
0
    if (iattr->use->defValue != NULL) {
25737
0
        iattr->value = (xmlChar *) iattr->use->defValue;
25738
0
        iattr->val = iattr->use->defVal;
25739
0
    } else {
25740
0
        iattr->value = (xmlChar *) iattr->decl->defValue;
25741
0
        iattr->val = iattr->decl->defVal;
25742
0
    }
25743
    /*
25744
    * IDCs will consume the precomputed default value,
25745
    * so we need to clone it.
25746
    */
25747
0
    if (iattr->val == NULL) {
25748
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25749
0
      "default/fixed value on an attribute use was "
25750
0
      "not precomputed");
25751
0
        goto internal_error;
25752
0
    }
25753
0
    iattr->val = xmlSchemaCopyValue(iattr->val);
25754
0
    if (iattr->val == NULL) {
25755
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25756
0
      "calling xmlSchemaCopyValue()");
25757
0
        goto internal_error;
25758
0
    }
25759
0
      }
25760
      /*
25761
      * PSVI: Add the default attribute to the current element.
25762
      * VAL TODO: Should we use the *normalized* value? This currently
25763
      *   uses the *initial* value.
25764
      */
25765
25766
0
      if (defAttrOwnerElem) {
25767
0
    xmlChar *normValue;
25768
0
    const xmlChar *value;
25769
25770
0
    value = iattr->value;
25771
    /*
25772
    * Normalize the value.
25773
    */
25774
0
    normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25775
0
        iattr->value);
25776
0
    if (normValue != NULL)
25777
0
        value = BAD_CAST normValue;
25778
25779
0
    if (iattr->nsName == NULL) {
25780
0
        if (xmlNewProp(defAttrOwnerElem,
25781
0
      iattr->localName, value) == NULL) {
25782
0
      VERROR_INT("xmlSchemaVAttributesComplex",
25783
0
          "calling xmlNewProp()");
25784
0
      if (normValue != NULL)
25785
0
          xmlFree(normValue);
25786
0
      goto internal_error;
25787
0
        }
25788
0
    } else {
25789
0
        xmlNsPtr ns;
25790
25791
0
        ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25792
0
      defAttrOwnerElem, iattr->nsName);
25793
0
        if (ns == NULL) {
25794
0
      xmlChar prefix[12];
25795
0
      int counter = 0;
25796
25797
      /*
25798
      * Create a namespace declaration on the validation
25799
      * root node if no namespace declaration is in scope.
25800
      */
25801
0
      do {
25802
0
          snprintf((char *) prefix, 12, "p%d", counter++);
25803
0
          ns = xmlSearchNs(defAttrOwnerElem->doc,
25804
0
        defAttrOwnerElem, BAD_CAST prefix);
25805
0
          if (counter > 1000) {
25806
0
        VERROR_INT(
25807
0
            "xmlSchemaVAttributesComplex",
25808
0
            "could not compute a ns prefix for a "
25809
0
            "default/fixed attribute");
25810
0
        if (normValue != NULL)
25811
0
            xmlFree(normValue);
25812
0
        goto internal_error;
25813
0
          }
25814
0
      } while (ns != NULL);
25815
0
      ns = xmlNewNs(vctxt->validationRoot,
25816
0
          iattr->nsName, BAD_CAST prefix);
25817
0
        }
25818
        /*
25819
        * TODO:
25820
        * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25821
        * If we have QNames: do we need to ensure there's a
25822
        * prefix defined for the QName?
25823
        */
25824
0
        xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25825
0
    }
25826
0
    if (normValue != NULL)
25827
0
        xmlFree(normValue);
25828
0
      }
25829
      /*
25830
      * Go directly to IDC evaluation.
25831
      */
25832
0
      goto eval_idcs;
25833
0
  }
25834
  /*
25835
  * Validate the value.
25836
  */
25837
0
  if (vctxt->value != NULL) {
25838
      /*
25839
      * Free last computed value; just for safety reasons.
25840
      */
25841
0
      xmlSchemaFreeValue(vctxt->value);
25842
0
      vctxt->value = NULL;
25843
0
  }
25844
  /*
25845
  * Note that the attribute *use* can be unavailable, if
25846
  * the attribute was a wild attribute.
25847
  */
25848
0
  if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25849
0
      ((iattr->use != NULL) &&
25850
0
       (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25851
0
      fixed = 1;
25852
0
  else
25853
0
      fixed = 0;
25854
  /*
25855
  * SPEC (cvc-attribute)
25856
  * (3) "The item's `normalized value` must be locally `valid`
25857
  * with respect to that {type definition} as per
25858
  * String Valid ($3.14.4)."
25859
  *
25860
  * VAL TODO: Do we already have the
25861
  * "normalized attribute value" here?
25862
  */
25863
0
  if (xpathRes || fixed) {
25864
0
      iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25865
      /*
25866
      * Request a computed value.
25867
      */
25868
0
      res = xmlSchemaVCheckCVCSimpleType(
25869
0
    ACTXT_CAST vctxt,
25870
0
    iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25871
0
    1, 1, 0);
25872
0
  } else {
25873
0
      res = xmlSchemaVCheckCVCSimpleType(
25874
0
    ACTXT_CAST vctxt,
25875
0
    iattr->node, iattr->typeDef, iattr->value, NULL,
25876
0
    1, 0, 0);
25877
0
  }
25878
25879
0
  if (res != 0) {
25880
0
      if (res == -1) {
25881
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25882
0
        "calling xmlSchemaStreamValidateSimpleTypeValue()");
25883
0
    goto internal_error;
25884
0
      }
25885
0
      iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25886
      /*
25887
      * SPEC PSVI Assessment Outcome (Attribute)
25888
      * [validity] = "invalid"
25889
      */
25890
0
      goto eval_idcs;
25891
0
  }
25892
25893
0
  if (fixed) {
25894
      /*
25895
      * SPEC Attribute Locally Valid (Use) (cvc-au)
25896
      * "For an attribute information item to be `valid`
25897
      * with respect to an attribute use its *normalized*
25898
      * value must match the *canonical* lexical
25899
      * representation of the attribute use's {value
25900
      * constraint}value, if it is present and fixed."
25901
      *
25902
      * VAL TODO: The requirement for the *canonical* value
25903
      * will be removed in XML Schema 1.1.
25904
      */
25905
      /*
25906
      * SPEC Attribute Locally Valid (cvc-attribute)
25907
      * (4) "The item's *actual* value must match the *value* of
25908
      * the {value constraint}, if it is present and fixed."
25909
      */
25910
0
      if (iattr->val == NULL) {
25911
    /* VAL TODO: A value was not precomputed. */
25912
0
    TODO
25913
0
    goto eval_idcs;
25914
0
      }
25915
0
      if ((iattr->use != NULL) &&
25916
0
    (iattr->use->defValue != NULL)) {
25917
0
    if (iattr->use->defVal == NULL) {
25918
        /* VAL TODO: A default value was not precomputed. */
25919
0
        TODO
25920
0
        goto eval_idcs;
25921
0
    }
25922
0
    iattr->vcValue = iattr->use->defValue;
25923
    /*
25924
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25925
        (xmlSchemaWhitespaceValueType) ws,
25926
        attr->use->defVal,
25927
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25928
    */
25929
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25930
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25931
0
      } else {
25932
0
    if (iattr->decl->defVal == NULL) {
25933
        /* VAL TODO: A default value was not precomputed. */
25934
0
        TODO
25935
0
        goto eval_idcs;
25936
0
    }
25937
0
    iattr->vcValue = iattr->decl->defValue;
25938
    /*
25939
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25940
        (xmlSchemaWhitespaceValueType) ws,
25941
        attrDecl->defVal,
25942
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25943
    */
25944
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25945
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25946
0
      }
25947
      /*
25948
      * [validity] = "valid"
25949
      */
25950
0
  }
25951
0
eval_idcs:
25952
  /*
25953
  * Evaluate IDCs.
25954
  */
25955
0
  if (xpathRes) {
25956
0
      if (xmlSchemaXPathProcessHistory(vctxt,
25957
0
    vctxt->depth +1) == -1) {
25958
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25959
0
        "calling xmlSchemaXPathEvaluate()");
25960
0
    goto internal_error;
25961
0
      }
25962
0
  } else if (vctxt->xpathStates != NULL)
25963
0
      xmlSchemaXPathPop(vctxt);
25964
0
    }
25965
25966
    /*
25967
    * Report errors.
25968
    */
25969
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25970
0
  iattr = vctxt->attrInfos[i];
25971
0
  if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25972
0
      (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25973
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25974
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25975
0
      continue;
25976
0
  ACTIVATE_ATTRIBUTE(iattr);
25977
0
  switch (iattr->state) {
25978
0
      case XML_SCHEMAS_ATTR_ERR_MISSING: {
25979
0
        xmlChar *str = NULL;
25980
0
        ACTIVATE_ELEM;
25981
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
25982
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25983
0
      "The attribute '%s' is required but missing",
25984
0
      xmlSchemaFormatQName(&str,
25985
0
          iattr->decl->targetNamespace,
25986
0
          iattr->decl->name),
25987
0
      NULL);
25988
0
        FREE_AND_NULL(str)
25989
0
        break;
25990
0
    }
25991
0
      case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25992
0
    VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25993
0
        "The type definition is absent");
25994
0
    break;
25995
0
      case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25996
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25997
0
        XML_SCHEMAV_CVC_AU, NULL, NULL,
25998
0
        "The value '%s' does not match the fixed "
25999
0
        "value constraint '%s'",
26000
0
        iattr->value, iattr->vcValue);
26001
0
    break;
26002
0
      case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
26003
0
    VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
26004
0
        "No matching global attribute declaration available, but "
26005
0
        "demanded by the strict wildcard");
26006
0
    break;
26007
0
      case XML_SCHEMAS_ATTR_UNKNOWN:
26008
0
    if (iattr->metaType)
26009
0
        break;
26010
    /*
26011
    * MAYBE VAL TODO: One might report different error messages
26012
    * for the following errors.
26013
    */
26014
0
    if (type->attributeWildcard == NULL) {
26015
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
26016
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
26017
0
    } else {
26018
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
26019
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
26020
0
    }
26021
0
    break;
26022
0
      default:
26023
0
    break;
26024
0
  }
26025
0
    }
26026
26027
0
    ACTIVATE_ELEM;
26028
0
    return (0);
26029
0
internal_error:
26030
0
    ACTIVATE_ELEM;
26031
0
    return (-1);
26032
0
}
26033
26034
static int
26035
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
26036
            int *skip)
26037
0
{
26038
0
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
26039
    /*
26040
    * The namespace of the element was already identified to be
26041
    * matching the wildcard.
26042
    */
26043
0
    if ((skip == NULL) || (wild == NULL) ||
26044
0
  (wild->type != XML_SCHEMA_TYPE_ANY)) {
26045
0
  VERROR_INT("xmlSchemaValidateElemWildcard",
26046
0
      "bad arguments");
26047
0
  return (-1);
26048
0
    }
26049
0
    *skip = 0;
26050
0
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
26051
  /*
26052
  * URGENT VAL TODO: Either we need to position the stream to the
26053
  * next sibling, or walk the whole subtree.
26054
  */
26055
0
  *skip = 1;
26056
0
  return (0);
26057
0
    }
26058
0
    {
26059
0
  xmlSchemaElementPtr decl = NULL;
26060
26061
0
  decl = xmlSchemaGetElem(vctxt->schema,
26062
0
      vctxt->inode->localName, vctxt->inode->nsName);
26063
0
  if (decl != NULL) {
26064
0
      vctxt->inode->decl = decl;
26065
0
      return (0);
26066
0
  }
26067
0
    }
26068
0
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
26069
  /* VAL TODO: Change to proper error code. */
26070
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
26071
0
      "No matching global element declaration available, but "
26072
0
      "demanded by the strict wildcard");
26073
0
  return (vctxt->err);
26074
0
    }
26075
0
    if (vctxt->nbAttrInfos != 0) {
26076
0
  xmlSchemaAttrInfoPtr iattr;
26077
  /*
26078
  * SPEC Validation Rule: Schema-Validity Assessment (Element)
26079
  * (1.2.1.2.1) - (1.2.1.2.3 )
26080
  *
26081
  * Use the xsi:type attribute for the type definition.
26082
  */
26083
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26084
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26085
0
  if (iattr != NULL) {
26086
0
      if (xmlSchemaProcessXSIType(vctxt, iattr,
26087
0
    &(vctxt->inode->typeDef), NULL) == -1) {
26088
0
    VERROR_INT("xmlSchemaValidateElemWildcard",
26089
0
        "calling xmlSchemaProcessXSIType() to "
26090
0
        "process the attribute 'xsi:nil'");
26091
0
    return (-1);
26092
0
      }
26093
      /*
26094
      * Don't return an error on purpose.
26095
      */
26096
0
      return (0);
26097
0
  }
26098
0
    }
26099
    /*
26100
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
26101
    *
26102
    * Fallback to "anyType".
26103
    */
26104
0
    vctxt->inode->typeDef =
26105
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26106
0
    return (0);
26107
0
}
26108
26109
/*
26110
* xmlSchemaCheckCOSValidDefault:
26111
*
26112
* This will be called if: not nilled, no content and a default/fixed
26113
* value is provided.
26114
*/
26115
26116
static int
26117
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
26118
            const xmlChar *value,
26119
            xmlSchemaValPtr *val)
26120
0
{
26121
0
    int ret = 0;
26122
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
26123
26124
    /*
26125
    * cos-valid-default:
26126
    * Schema Component Constraint: Element Default Valid (Immediate)
26127
    * For a string to be a valid default with respect to a type
26128
    * definition the appropriate case among the following must be true:
26129
    */
26130
0
    if WXS_IS_COMPLEX(inode->typeDef) {
26131
  /*
26132
  * Complex type.
26133
  *
26134
  * SPEC (2.1) "its {content type} must be a simple type definition
26135
  * or mixed."
26136
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
26137
  * type}'s particle must be `emptiable` as defined by
26138
  * Particle Emptiable ($3.9.6)."
26139
  */
26140
0
  if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
26141
0
      ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
26142
0
       (! WXS_EMPTIABLE(inode->typeDef)))) {
26143
0
      ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
26144
      /* NOTE that this covers (2.2.2) as well. */
26145
0
      VERROR(ret, NULL,
26146
0
    "For a string to be a valid default, the type definition "
26147
0
    "must be a simple type or a complex type with simple content "
26148
0
    "or mixed content and a particle emptiable");
26149
0
      return(ret);
26150
0
  }
26151
0
    }
26152
    /*
26153
    * 1 If the type definition is a simple type definition, then the string
26154
    * must be `valid` with respect to that definition as defined by String
26155
    * Valid ($3.14.4).
26156
    *
26157
    * AND
26158
    *
26159
    * 2.2.1 If the {content type} is a simple type definition, then the
26160
    * string must be `valid` with respect to that simple type definition
26161
    * as defined by String Valid ($3.14.4).
26162
    */
26163
0
    if (WXS_IS_SIMPLE(inode->typeDef)) {
26164
26165
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
26166
0
      NULL, inode->typeDef, value, val, 1, 1, 0);
26167
26168
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26169
26170
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
26171
0
      NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
26172
0
    }
26173
0
    if (ret < 0) {
26174
0
  VERROR_INT("xmlSchemaCheckCOSValidDefault",
26175
0
      "calling xmlSchemaVCheckCVCSimpleType()");
26176
0
    }
26177
0
    return (ret);
26178
0
}
26179
26180
static void
26181
xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
26182
             const xmlChar * name ATTRIBUTE_UNUSED,
26183
             void *transdata, void *inputdata)
26184
0
{
26185
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
26186
0
    xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
26187
0
    inode->decl = item;
26188
#ifdef DEBUG_CONTENT
26189
    {
26190
  xmlChar *str = NULL;
26191
26192
  if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
26193
      xmlGenericError(xmlGenericErrorContext,
26194
    "AUTOMATON callback for '%s' [declaration]\n",
26195
    xmlSchemaFormatQName(&str,
26196
    inode->localName, inode->nsName));
26197
  } else {
26198
      xmlGenericError(xmlGenericErrorContext,
26199
        "AUTOMATON callback for '%s' [wildcard]\n",
26200
        xmlSchemaFormatQName(&str,
26201
        inode->localName, inode->nsName));
26202
26203
  }
26204
  FREE_AND_NULL(str)
26205
    }
26206
#endif
26207
0
}
26208
26209
static int
26210
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
26211
0
{
26212
0
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
26213
0
    if (vctxt->inode == NULL) {
26214
0
  VERROR_INT("xmlSchemaValidatorPushElem",
26215
0
      "calling xmlSchemaGetFreshElemInfo()");
26216
0
  return (-1);
26217
0
    }
26218
0
    vctxt->nbAttrInfos = 0;
26219
0
    return (0);
26220
0
}
26221
26222
static int
26223
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
26224
           xmlSchemaNodeInfoPtr inode,
26225
           xmlSchemaTypePtr type,
26226
           const xmlChar *value)
26227
0
{
26228
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
26229
0
  return (xmlSchemaVCheckCVCSimpleType(
26230
0
      ACTXT_CAST vctxt, NULL,
26231
0
      type, value, &(inode->val), 1, 1, 0));
26232
0
    else
26233
0
  return (xmlSchemaVCheckCVCSimpleType(
26234
0
      ACTXT_CAST vctxt, NULL,
26235
0
      type, value, NULL, 1, 0, 0));
26236
0
}
26237
26238
26239
26240
/*
26241
* Process END of element.
26242
*/
26243
static int
26244
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
26245
0
{
26246
0
    int ret = 0;
26247
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
26248
26249
0
    if (vctxt->nbAttrInfos != 0)
26250
0
  xmlSchemaClearAttrInfos(vctxt);
26251
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
26252
  /*
26253
  * This element was not expected;
26254
  * we will not validate child elements of broken parents.
26255
  * Skip validation of all content of the parent.
26256
  */
26257
0
  vctxt->skipDepth = vctxt->depth -1;
26258
0
  goto end_elem;
26259
0
    }
26260
0
    if ((inode->typeDef == NULL) ||
26261
0
  (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
26262
  /*
26263
  * 1. the type definition might be missing if the element was
26264
  *    error prone
26265
  * 2. it might be abstract.
26266
  */
26267
0
  goto end_elem;
26268
0
    }
26269
    /*
26270
    * Check the content model.
26271
    */
26272
0
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
26273
0
  (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
26274
26275
  /*
26276
  * Workaround for "anyType".
26277
  */
26278
0
  if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26279
0
      goto character_content;
26280
26281
0
  if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
26282
0
      xmlChar *values[10];
26283
0
      int terminal, nbval = 10, nbneg;
26284
26285
0
      if (inode->regexCtxt == NULL) {
26286
    /*
26287
    * Create the regex context.
26288
    */
26289
0
    inode->regexCtxt =
26290
0
        xmlRegNewExecCtxt(inode->typeDef->contModel,
26291
0
        xmlSchemaVContentModelCallback, vctxt);
26292
0
    if (inode->regexCtxt == NULL) {
26293
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26294
0
      "failed to create a regex context");
26295
0
        goto internal_error;
26296
0
    }
26297
#ifdef DEBUG_AUTOMATA
26298
    xmlGenericError(xmlGenericErrorContext,
26299
        "AUTOMATON create on '%s'\n", inode->localName);
26300
#endif
26301
0
      }
26302
26303
      /*
26304
       * Do not check further content if the node has been nilled
26305
       */
26306
0
      if (INODE_NILLED(inode)) {
26307
0
    ret = 0;
26308
#ifdef DEBUG_AUTOMATA
26309
    xmlGenericError(xmlGenericErrorContext,
26310
        "AUTOMATON succeeded on nilled '%s'\n",
26311
        inode->localName);
26312
#endif
26313
0
                goto skip_nilled;
26314
0
      }
26315
26316
      /*
26317
      * Get hold of the still expected content, since a further
26318
      * call to xmlRegExecPushString() will lose this information.
26319
      */
26320
0
      xmlRegExecNextValues(inode->regexCtxt,
26321
0
    &nbval, &nbneg, &values[0], &terminal);
26322
0
      ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26323
0
      if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26324
    /*
26325
    * Still missing something.
26326
    */
26327
0
    ret = 1;
26328
0
    inode->flags |=
26329
0
        XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26330
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26331
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26332
0
        "Missing child element(s)",
26333
0
        nbval, nbneg, values);
26334
#ifdef DEBUG_AUTOMATA
26335
    xmlGenericError(xmlGenericErrorContext,
26336
        "AUTOMATON missing ERROR on '%s'\n",
26337
        inode->localName);
26338
#endif
26339
0
      } else {
26340
    /*
26341
    * Content model is satisfied.
26342
    */
26343
0
    ret = 0;
26344
#ifdef DEBUG_AUTOMATA
26345
    xmlGenericError(xmlGenericErrorContext,
26346
        "AUTOMATON succeeded on '%s'\n",
26347
        inode->localName);
26348
#endif
26349
0
      }
26350
26351
0
  }
26352
0
    }
26353
26354
0
skip_nilled:
26355
26356
0
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26357
0
  goto end_elem;
26358
26359
0
character_content:
26360
26361
0
    if (vctxt->value != NULL) {
26362
0
  xmlSchemaFreeValue(vctxt->value);
26363
0
  vctxt->value = NULL;
26364
0
    }
26365
    /*
26366
    * Check character content.
26367
    */
26368
0
    if (inode->decl == NULL) {
26369
  /*
26370
  * Speedup if no declaration exists.
26371
  */
26372
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26373
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26374
0
    inode, inode->typeDef, inode->value);
26375
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26376
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26377
0
    inode, inode->typeDef->contentTypeDef,
26378
0
    inode->value);
26379
0
  }
26380
0
  if (ret < 0) {
26381
0
      VERROR_INT("xmlSchemaValidatorPopElem",
26382
0
    "calling xmlSchemaVCheckCVCSimpleType()");
26383
0
      goto internal_error;
26384
0
  }
26385
0
  goto end_elem;
26386
0
    }
26387
    /*
26388
    * cvc-elt (3.3.4) : 5
26389
    * The appropriate case among the following must be true:
26390
    */
26391
    /*
26392
    * cvc-elt (3.3.4) : 5.1
26393
    * If the declaration has a {value constraint},
26394
    * the item has neither element nor character [children] and
26395
    * clause 3.2 has not applied, then all of the following must be true:
26396
    */
26397
0
    if ((inode->decl->value != NULL) &&
26398
0
  (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26399
0
  (! INODE_NILLED(inode))) {
26400
  /*
26401
  * cvc-elt (3.3.4) : 5.1.1
26402
  * If the `actual type definition` is a `local type definition`
26403
  * then the canonical lexical representation of the {value constraint}
26404
  * value must be a valid default for the `actual type definition` as
26405
  * defined in Element Default Valid (Immediate) ($3.3.6).
26406
  */
26407
  /*
26408
  * NOTE: 'local' above means types acquired by xsi:type.
26409
  * NOTE: Although the *canonical* value is stated, it is not
26410
  * relevant if canonical or not. Additionally XML Schema 1.1
26411
  * will removed this requirement as well.
26412
  */
26413
0
  if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26414
26415
0
      ret = xmlSchemaCheckCOSValidDefault(vctxt,
26416
0
    inode->decl->value, &(inode->val));
26417
0
      if (ret != 0) {
26418
0
    if (ret < 0) {
26419
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26420
0
      "calling xmlSchemaCheckCOSValidDefault()");
26421
0
        goto internal_error;
26422
0
    }
26423
0
    goto end_elem;
26424
0
      }
26425
      /*
26426
      * Stop here, to avoid redundant validation of the value
26427
      * (see following).
26428
      */
26429
0
      goto default_psvi;
26430
0
  }
26431
  /*
26432
  * cvc-elt (3.3.4) : 5.1.2
26433
  * The element information item with the canonical lexical
26434
  * representation of the {value constraint} value used as its
26435
  * `normalized value` must be `valid` with respect to the
26436
  * `actual type definition` as defined by Element Locally Valid (Type)
26437
  * ($3.3.4).
26438
  */
26439
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26440
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26441
0
    inode, inode->typeDef, inode->decl->value);
26442
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26443
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26444
0
    inode, inode->typeDef->contentTypeDef,
26445
0
    inode->decl->value);
26446
0
  }
26447
0
  if (ret != 0) {
26448
0
      if (ret < 0) {
26449
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26450
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26451
0
    goto internal_error;
26452
0
      }
26453
0
      goto end_elem;
26454
0
  }
26455
26456
0
default_psvi:
26457
  /*
26458
  * PSVI: Create a text node on the instance element.
26459
  */
26460
0
  if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26461
0
      (inode->node != NULL)) {
26462
0
      xmlNodePtr textChild;
26463
0
      xmlChar *normValue;
26464
      /*
26465
      * VAL TODO: Normalize the value.
26466
      */
26467
0
      normValue = xmlSchemaNormalizeValue(inode->typeDef,
26468
0
    inode->decl->value);
26469
0
      if (normValue != NULL) {
26470
0
    textChild = xmlNewDocText(inode->node->doc,
26471
0
                        BAD_CAST normValue);
26472
0
    xmlFree(normValue);
26473
0
      } else
26474
0
    textChild = xmlNewDocText(inode->node->doc,
26475
0
                        inode->decl->value);
26476
0
      if (textChild == NULL) {
26477
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26478
0
        "calling xmlNewDocText()");
26479
0
    goto internal_error;
26480
0
      } else
26481
0
    xmlAddChild(inode->node, textChild);
26482
0
  }
26483
26484
0
    } else if (! INODE_NILLED(inode)) {
26485
  /*
26486
  * 5.2.1 The element information item must be `valid` with respect
26487
  * to the `actual type definition` as defined by Element Locally
26488
  * Valid (Type) ($3.3.4).
26489
  */
26490
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26491
       /*
26492
      * SPEC (cvc-type) (3.1)
26493
      * "If the type definition is a simple type definition, ..."
26494
      * (3.1.3) "If clause 3.2 of Element Locally Valid
26495
      * (Element) ($3.3.4) did not apply, then the `normalized value`
26496
      * must be `valid` with respect to the type definition as defined
26497
      * by String Valid ($3.14.4).
26498
      */
26499
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26500
0
        inode, inode->typeDef, inode->value);
26501
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26502
      /*
26503
      * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26504
      * definition, then the element information item must be
26505
      * `valid` with respect to the type definition as per
26506
      * Element Locally Valid (Complex Type) ($3.4.4);"
26507
      *
26508
      * SPEC (cvc-complex-type) (2.2)
26509
      * "If the {content type} is a simple type definition, ...
26510
      * the `normalized value` of the element information item is
26511
      * `valid` with respect to that simple type definition as
26512
      * defined by String Valid ($3.14.4)."
26513
      */
26514
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26515
0
    inode, inode->typeDef->contentTypeDef, inode->value);
26516
0
  }
26517
0
  if (ret != 0) {
26518
0
      if (ret < 0) {
26519
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26520
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26521
0
    goto internal_error;
26522
0
      }
26523
0
      goto end_elem;
26524
0
  }
26525
  /*
26526
  * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26527
  * not applied, all of the following must be true:
26528
  */
26529
0
  if ((inode->decl->value != NULL) &&
26530
0
      (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26531
26532
      /*
26533
      * TODO: We will need a computed value, when comparison is
26534
      * done on computed values.
26535
      */
26536
      /*
26537
      * 5.2.2.1 The element information item must have no element
26538
      * information item [children].
26539
      */
26540
0
      if (inode->flags &
26541
0
        XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26542
0
    ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26543
0
    VERROR(ret, NULL,
26544
0
        "The content must not contain element nodes since "
26545
0
        "there is a fixed value constraint");
26546
0
    goto end_elem;
26547
0
      } else {
26548
    /*
26549
    * 5.2.2.2 The appropriate case among the following must
26550
    * be true:
26551
    */
26552
0
    if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26553
        /*
26554
        * 5.2.2.2.1 If the {content type} of the `actual type
26555
        * definition` is mixed, then the *initial value* of the
26556
        * item must match the canonical lexical representation
26557
        * of the {value constraint} value.
26558
        *
26559
        * ... the *initial value* of an element information
26560
        * item is the string composed of, in order, the
26561
        * [character code] of each character information item in
26562
        * the [children] of that element information item.
26563
        */
26564
0
        if (! xmlStrEqual(inode->value, inode->decl->value)){
26565
      /*
26566
      * VAL TODO: Report invalid & expected values as well.
26567
      * VAL TODO: Implement the canonical stuff.
26568
      */
26569
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26570
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26571
0
          ret, NULL, NULL,
26572
0
          "The initial value '%s' does not match the fixed "
26573
0
          "value constraint '%s'",
26574
0
          inode->value, inode->decl->value);
26575
0
      goto end_elem;
26576
0
        }
26577
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26578
        /*
26579
        * 5.2.2.2.2 If the {content type} of the `actual type
26580
        * definition` is a simple type definition, then the
26581
        * *actual value* of the item must match the canonical
26582
        * lexical representation of the {value constraint} value.
26583
        */
26584
        /*
26585
        * VAL TODO: *actual value* is the normalized value, impl.
26586
        *           this.
26587
        * VAL TODO: Report invalid & expected values as well.
26588
        * VAL TODO: Implement a comparison with the computed values.
26589
        */
26590
0
        if (! xmlStrEqual(inode->value,
26591
0
          inode->decl->value)) {
26592
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26593
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26594
0
          ret, NULL, NULL,
26595
0
          "The actual value '%s' does not match the fixed "
26596
0
          "value constraint '%s'",
26597
0
          inode->value,
26598
0
          inode->decl->value);
26599
0
      goto end_elem;
26600
0
        }
26601
0
    }
26602
0
      }
26603
0
  }
26604
0
    }
26605
26606
0
end_elem:
26607
0
    if (vctxt->depth < 0) {
26608
  /* TODO: raise error? */
26609
0
  return (0);
26610
0
    }
26611
0
    if (vctxt->depth == vctxt->skipDepth)
26612
0
  vctxt->skipDepth = -1;
26613
    /*
26614
    * Evaluate the history of XPath state objects.
26615
    */
26616
0
    if (inode->appliedXPath &&
26617
0
  (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26618
0
  goto internal_error;
26619
    /*
26620
    * MAYBE TODO:
26621
    * SPEC (6) "The element information item must be `valid` with
26622
    * respect to each of the {identity-constraint definitions} as per
26623
    * Identity-constraint Satisfied ($3.11.4)."
26624
    */
26625
    /*
26626
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26627
    *   need to be built in any case.
26628
    *   We will currently build IDC node-tables and bubble them only if
26629
    *   keyrefs do exist.
26630
    */
26631
26632
    /*
26633
    * Add the current IDC target-nodes to the IDC node-tables.
26634
    */
26635
0
    if ((inode->idcMatchers != NULL) &&
26636
0
  (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26637
0
    {
26638
0
  if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26639
0
      goto internal_error;
26640
0
    }
26641
    /*
26642
    * Validate IDC keyrefs.
26643
    */
26644
0
    if (vctxt->inode->hasKeyrefs)
26645
0
  if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26646
0
      goto internal_error;
26647
    /*
26648
    * Merge/free the IDC table.
26649
    */
26650
0
    if (inode->idcTable != NULL) {
26651
#ifdef DEBUG_IDC_NODE_TABLE
26652
  xmlSchemaDebugDumpIDCTable(stdout,
26653
      inode->nsName,
26654
      inode->localName,
26655
      inode->idcTable);
26656
#endif
26657
0
  if ((vctxt->depth > 0) &&
26658
0
      (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26659
0
  {
26660
      /*
26661
      * Merge the IDC node table with the table of the parent node.
26662
      */
26663
0
      if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26664
0
    goto internal_error;
26665
0
  }
26666
0
    }
26667
    /*
26668
    * Clear the current ielem.
26669
    * VAL TODO: Don't free the PSVI IDC tables if they are
26670
    * requested for the PSVI.
26671
    */
26672
0
    xmlSchemaClearElemInfo(vctxt, inode);
26673
    /*
26674
    * Skip further processing if we are on the validation root.
26675
    */
26676
0
    if (vctxt->depth == 0) {
26677
0
  vctxt->depth--;
26678
0
  vctxt->inode = NULL;
26679
0
  return (0);
26680
0
    }
26681
    /*
26682
    * Reset the keyrefDepth if needed.
26683
    */
26684
0
    if (vctxt->aidcs != NULL) {
26685
0
  xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26686
0
  do {
26687
0
      if (aidc->keyrefDepth == vctxt->depth) {
26688
    /*
26689
    * A 'keyrefDepth' of a key/unique IDC matches the current
26690
    * depth, this means that we are leaving the scope of the
26691
    * top-most keyref IDC which refers to this IDC.
26692
    */
26693
0
    aidc->keyrefDepth = -1;
26694
0
      }
26695
0
      aidc = aidc->next;
26696
0
  } while (aidc != NULL);
26697
0
    }
26698
0
    vctxt->depth--;
26699
0
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
26700
    /*
26701
    * VAL TODO: 7 If the element information item is the `validation root`, it must be
26702
    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26703
    */
26704
0
    return (ret);
26705
26706
0
internal_error:
26707
0
    vctxt->err = -1;
26708
0
    return (-1);
26709
0
}
26710
26711
/*
26712
* 3.4.4 Complex Type Definition Validation Rules
26713
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26714
*/
26715
static int
26716
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26717
0
{
26718
0
    xmlSchemaNodeInfoPtr pielem;
26719
0
    xmlSchemaTypePtr ptype;
26720
0
    int ret = 0;
26721
26722
0
    if (vctxt->depth <= 0) {
26723
0
  VERROR_INT("xmlSchemaValidateChildElem",
26724
0
      "not intended for the validation root");
26725
0
  return (-1);
26726
0
    }
26727
0
    pielem = vctxt->elemInfos[vctxt->depth -1];
26728
0
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26729
0
  pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26730
    /*
26731
    * Handle 'nilled' elements.
26732
    */
26733
0
    if (INODE_NILLED(pielem)) {
26734
  /*
26735
  * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26736
  */
26737
0
  ACTIVATE_PARENT_ELEM;
26738
0
  ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26739
0
  VERROR(ret, NULL,
26740
0
      "Neither character nor element content is allowed, "
26741
0
      "because the element was 'nilled'");
26742
0
  ACTIVATE_ELEM;
26743
0
  goto unexpected_elem;
26744
0
    }
26745
26746
0
    ptype = pielem->typeDef;
26747
26748
0
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26749
  /*
26750
  * Workaround for "anyType": we have currently no content model
26751
  * assigned for "anyType", so handle it explicitly.
26752
  * "anyType" has an unbounded, lax "any" wildcard.
26753
  */
26754
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26755
0
      vctxt->inode->localName,
26756
0
      vctxt->inode->nsName);
26757
26758
0
  if (vctxt->inode->decl == NULL) {
26759
0
      xmlSchemaAttrInfoPtr iattr;
26760
      /*
26761
      * Process "xsi:type".
26762
      * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26763
      */
26764
0
      iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26765
0
    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26766
0
      if (iattr != NULL) {
26767
0
    ret = xmlSchemaProcessXSIType(vctxt, iattr,
26768
0
        &(vctxt->inode->typeDef), NULL);
26769
0
    if (ret != 0) {
26770
0
        if (ret == -1) {
26771
0
      VERROR_INT("xmlSchemaValidateChildElem",
26772
0
          "calling xmlSchemaProcessXSIType() to "
26773
0
          "process the attribute 'xsi:nil'");
26774
0
      return (-1);
26775
0
        }
26776
0
        return (ret);
26777
0
    }
26778
0
      } else {
26779
     /*
26780
     * Fallback to "anyType".
26781
     *
26782
     * SPEC (cvc-assess-elt)
26783
     * "If the item cannot be `strictly assessed`, [...]
26784
     * an element information item's schema validity may be laxly
26785
     * assessed if its `context-determined declaration` is not
26786
     * skip by `validating` with respect to the `ur-type
26787
     * definition` as per Element Locally Valid (Type) ($3.3.4)."
26788
    */
26789
0
    vctxt->inode->typeDef =
26790
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26791
0
      }
26792
0
  }
26793
0
  return (0);
26794
0
    }
26795
26796
0
    switch (ptype->contentType) {
26797
0
  case XML_SCHEMA_CONTENT_EMPTY:
26798
      /*
26799
      * SPEC (2.1) "If the {content type} is empty, then the
26800
      * element information item has no character or element
26801
      * information item [children]."
26802
      */
26803
0
      ACTIVATE_PARENT_ELEM
26804
0
      ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26805
0
      VERROR(ret, NULL,
26806
0
    "Element content is not allowed, "
26807
0
    "because the content type is empty");
26808
0
      ACTIVATE_ELEM
26809
0
      goto unexpected_elem;
26810
0
      break;
26811
26812
0
  case XML_SCHEMA_CONTENT_MIXED:
26813
0
        case XML_SCHEMA_CONTENT_ELEMENTS: {
26814
0
      xmlRegExecCtxtPtr regexCtxt;
26815
0
      xmlChar *values[10];
26816
0
      int terminal, nbval = 10, nbneg;
26817
26818
      /* VAL TODO: Optimized "anyType" validation.*/
26819
26820
0
      if (ptype->contModel == NULL) {
26821
0
    VERROR_INT("xmlSchemaValidateChildElem",
26822
0
        "type has elem content but no content model");
26823
0
    return (-1);
26824
0
      }
26825
      /*
26826
      * Safety belt for evaluation if the cont. model was already
26827
      * examined to be invalid.
26828
      */
26829
0
      if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26830
0
    VERROR_INT("xmlSchemaValidateChildElem",
26831
0
        "validating elem, but elem content is already invalid");
26832
0
    return (-1);
26833
0
      }
26834
26835
0
      regexCtxt = pielem->regexCtxt;
26836
0
      if (regexCtxt == NULL) {
26837
    /*
26838
    * Create the regex context.
26839
    */
26840
0
    regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26841
0
        xmlSchemaVContentModelCallback, vctxt);
26842
0
    if (regexCtxt == NULL) {
26843
0
        VERROR_INT("xmlSchemaValidateChildElem",
26844
0
      "failed to create a regex context");
26845
0
        return (-1);
26846
0
    }
26847
0
    pielem->regexCtxt = regexCtxt;
26848
#ifdef DEBUG_AUTOMATA
26849
    xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26850
        pielem->localName);
26851
#endif
26852
0
      }
26853
26854
      /*
26855
      * SPEC (2.4) "If the {content type} is element-only or mixed,
26856
      * then the sequence of the element information item's
26857
      * element information item [children], if any, taken in
26858
      * order, is `valid` with respect to the {content type}'s
26859
      * particle, as defined in Element Sequence Locally Valid
26860
      * (Particle) ($3.9.4)."
26861
      */
26862
0
      ret = xmlRegExecPushString2(regexCtxt,
26863
0
    vctxt->inode->localName,
26864
0
    vctxt->inode->nsName,
26865
0
    vctxt->inode);
26866
#ifdef DEBUG_AUTOMATA
26867
      if (ret < 0)
26868
    xmlGenericError(xmlGenericErrorContext,
26869
    "AUTOMATON push ERROR for '%s' on '%s'\n",
26870
    vctxt->inode->localName, pielem->localName);
26871
      else
26872
    xmlGenericError(xmlGenericErrorContext,
26873
    "AUTOMATON push OK for '%s' on '%s'\n",
26874
    vctxt->inode->localName, pielem->localName);
26875
#endif
26876
0
      if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26877
0
    VERROR_INT("xmlSchemaValidateChildElem",
26878
0
        "calling xmlRegExecPushString2()");
26879
0
    return (-1);
26880
0
      }
26881
0
      if (ret < 0) {
26882
0
    xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26883
0
        &values[0], &terminal);
26884
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26885
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26886
0
        "This element is not expected",
26887
0
        nbval, nbneg, values);
26888
0
    ret = vctxt->err;
26889
0
    goto unexpected_elem;
26890
0
      } else
26891
0
    ret = 0;
26892
0
  }
26893
0
      break;
26894
0
  case XML_SCHEMA_CONTENT_SIMPLE:
26895
0
  case XML_SCHEMA_CONTENT_BASIC:
26896
0
      ACTIVATE_PARENT_ELEM
26897
0
      if (WXS_IS_COMPLEX(ptype)) {
26898
    /*
26899
    * SPEC (cvc-complex-type) (2.2)
26900
    * "If the {content type} is a simple type definition, then
26901
    * the element information item has no element information
26902
    * item [children], ..."
26903
    */
26904
0
    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26905
0
    VERROR(ret, NULL, "Element content is not allowed, "
26906
0
        "because the content type is a simple type definition");
26907
0
      } else {
26908
    /*
26909
    * SPEC (cvc-type) (3.1.2) "The element information item must
26910
    * have no element information item [children]."
26911
    */
26912
0
    ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26913
0
    VERROR(ret, NULL, "Element content is not allowed, "
26914
0
        "because the type definition is simple");
26915
0
      }
26916
0
      ACTIVATE_ELEM
26917
0
      ret = vctxt->err;
26918
0
      goto unexpected_elem;
26919
0
      break;
26920
26921
0
  default:
26922
0
      break;
26923
0
    }
26924
0
    return (ret);
26925
0
unexpected_elem:
26926
    /*
26927
    * Pop this element and set the skipDepth to skip
26928
    * all further content of the parent element.
26929
    */
26930
0
    vctxt->skipDepth = vctxt->depth;
26931
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26932
0
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26933
0
    return (ret);
26934
0
}
26935
26936
0
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26937
0
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26938
0
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26939
26940
static int
26941
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26942
      int nodeType, const xmlChar *value, int len,
26943
      int mode, int *consumed)
26944
0
{
26945
    /*
26946
    * Unfortunately we have to duplicate the text sometimes.
26947
    * OPTIMIZE: Maybe we could skip it, if:
26948
    *   1. content type is simple
26949
    *   2. whitespace is "collapse"
26950
    *   3. it consists of whitespace only
26951
    *
26952
    * Process character content.
26953
    */
26954
0
    if (consumed != NULL)
26955
0
  *consumed = 0;
26956
0
    if (INODE_NILLED(vctxt->inode)) {
26957
  /*
26958
  * SPEC cvc-elt (3.3.4 - 3.2.1)
26959
  * "The element information item must have no character or
26960
  * element information item [children]."
26961
  */
26962
0
  VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26963
0
      "Neither character nor element content is allowed "
26964
0
      "because the element is 'nilled'");
26965
0
  return (vctxt->err);
26966
0
    }
26967
    /*
26968
    * SPEC (2.1) "If the {content type} is empty, then the
26969
    * element information item has no character or element
26970
    * information item [children]."
26971
    */
26972
0
    if (vctxt->inode->typeDef->contentType ==
26973
0
      XML_SCHEMA_CONTENT_EMPTY) {
26974
0
  VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26975
0
      "Character content is not allowed, "
26976
0
      "because the content type is empty");
26977
0
  return (vctxt->err);
26978
0
    }
26979
26980
0
    if (vctxt->inode->typeDef->contentType ==
26981
0
      XML_SCHEMA_CONTENT_ELEMENTS) {
26982
0
  if ((nodeType != XML_TEXT_NODE) ||
26983
0
      (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26984
      /*
26985
      * SPEC cvc-complex-type (2.3)
26986
      * "If the {content type} is element-only, then the
26987
      * element information item has no character information
26988
      * item [children] other than those whose [character
26989
      * code] is defined as a white space in [XML 1.0 (Second
26990
      * Edition)]."
26991
      */
26992
0
      VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26993
0
    "Character content other than whitespace is not allowed "
26994
0
    "because the content type is 'element-only'");
26995
0
      return (vctxt->err);
26996
0
  }
26997
0
  return (0);
26998
0
    }
26999
27000
0
    if ((value == NULL) || (value[0] == 0))
27001
0
  return (0);
27002
    /*
27003
    * Save the value.
27004
    * NOTE that even if the content type is *mixed*, we need the
27005
    * *initial value* for default/fixed value constraints.
27006
    */
27007
0
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
27008
0
  ((vctxt->inode->decl == NULL) ||
27009
0
  (vctxt->inode->decl->value == NULL)))
27010
0
  return (0);
27011
27012
0
    if (vctxt->inode->value == NULL) {
27013
  /*
27014
  * Set the value.
27015
  */
27016
0
  switch (mode) {
27017
0
      case XML_SCHEMA_PUSH_TEXT_PERSIST:
27018
    /*
27019
    * When working on a tree.
27020
    */
27021
0
    vctxt->inode->value = value;
27022
0
    break;
27023
0
      case XML_SCHEMA_PUSH_TEXT_CREATED:
27024
    /*
27025
    * When working with the reader.
27026
    * The value will be freed by the element info.
27027
    */
27028
0
    vctxt->inode->value = value;
27029
0
    if (consumed != NULL)
27030
0
        *consumed = 1;
27031
0
    vctxt->inode->flags |=
27032
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27033
0
    break;
27034
0
      case XML_SCHEMA_PUSH_TEXT_VOLATILE:
27035
    /*
27036
    * When working with SAX.
27037
    * The value will be freed by the element info.
27038
    */
27039
0
    if (len != -1)
27040
0
        vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
27041
0
    else
27042
0
        vctxt->inode->value = BAD_CAST xmlStrdup(value);
27043
0
    vctxt->inode->flags |=
27044
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27045
0
    break;
27046
0
      default:
27047
0
    break;
27048
0
  }
27049
0
    } else {
27050
0
  if (len < 0)
27051
0
      len = xmlStrlen(value);
27052
  /*
27053
  * Concat the value.
27054
  */
27055
0
  if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
27056
0
      vctxt->inode->value = BAD_CAST xmlStrncat(
27057
0
    (xmlChar *) vctxt->inode->value, value, len);
27058
0
  } else {
27059
0
      vctxt->inode->value =
27060
0
    BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
27061
0
      vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
27062
0
  }
27063
0
    }
27064
27065
0
    return (0);
27066
0
}
27067
27068
static int
27069
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
27070
0
{
27071
0
    int ret = 0;
27072
27073
0
    if ((vctxt->skipDepth != -1) &&
27074
0
  (vctxt->depth >= vctxt->skipDepth)) {
27075
0
  VERROR_INT("xmlSchemaValidateElem",
27076
0
      "in skip-state");
27077
0
  goto internal_error;
27078
0
    }
27079
0
    if (vctxt->xsiAssemble) {
27080
  /*
27081
  * We will stop validation if there was an error during
27082
  * dynamic schema construction.
27083
  * Note that we simply set @skipDepth to 0, this could
27084
  * mean that a streaming document via SAX would be
27085
  * still read to the end but it won't be validated any more.
27086
  * TODO: If we are sure how to stop the validation at once
27087
  *   for all input scenarios, then this should be changed to
27088
  *   instantly stop the validation.
27089
  */
27090
0
  ret = xmlSchemaAssembleByXSI(vctxt);
27091
0
  if (ret != 0) {
27092
0
      if (ret == -1)
27093
0
    goto internal_error;
27094
0
      vctxt->skipDepth = 0;
27095
0
      return(ret);
27096
0
  }
27097
        /*
27098
         * Augment the IDC definitions for the main schema and all imported ones
27099
         * NOTE: main schema is the first in the imported list
27100
         */
27101
0
        xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
27102
0
                    vctxt);
27103
0
    }
27104
0
    if (vctxt->depth > 0) {
27105
  /*
27106
  * Validate this element against the content model
27107
  * of the parent.
27108
  */
27109
0
  ret = xmlSchemaValidateChildElem(vctxt);
27110
0
  if (ret != 0) {
27111
0
      if (ret < 0) {
27112
0
    VERROR_INT("xmlSchemaValidateElem",
27113
0
        "calling xmlSchemaStreamValidateChildElement()");
27114
0
    goto internal_error;
27115
0
      }
27116
0
      goto exit;
27117
0
  }
27118
0
  if (vctxt->depth == vctxt->skipDepth)
27119
0
      goto exit;
27120
0
  if ((vctxt->inode->decl == NULL) &&
27121
0
      (vctxt->inode->typeDef == NULL)) {
27122
0
      VERROR_INT("xmlSchemaValidateElem",
27123
0
    "the child element was valid but neither the "
27124
0
    "declaration nor the type was set");
27125
0
      goto internal_error;
27126
0
  }
27127
0
    } else {
27128
  /*
27129
  * Get the declaration of the validation root.
27130
  */
27131
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
27132
0
      vctxt->inode->localName,
27133
0
      vctxt->inode->nsName);
27134
0
  if (vctxt->inode->decl == NULL) {
27135
0
      ret = XML_SCHEMAV_CVC_ELT_1;
27136
0
      VERROR(ret, NULL,
27137
0
    "No matching global declaration available "
27138
0
    "for the validation root");
27139
0
      goto exit;
27140
0
  }
27141
0
    }
27142
27143
0
    if (vctxt->inode->decl == NULL)
27144
0
  goto type_validation;
27145
27146
0
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
27147
0
  int skip;
27148
  /*
27149
  * Wildcards.
27150
  */
27151
0
  ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
27152
0
  if (ret != 0) {
27153
0
      if (ret < 0) {
27154
0
    VERROR_INT("xmlSchemaValidateElem",
27155
0
        "calling xmlSchemaValidateElemWildcard()");
27156
0
    goto internal_error;
27157
0
      }
27158
0
      goto exit;
27159
0
  }
27160
0
  if (skip) {
27161
0
      vctxt->skipDepth = vctxt->depth;
27162
0
      goto exit;
27163
0
  }
27164
  /*
27165
  * The declaration might be set by the wildcard validation,
27166
  * when the processContents is "lax" or "strict".
27167
  */
27168
0
  if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
27169
      /*
27170
      * Clear the "decl" field to not confuse further processing.
27171
      */
27172
0
      vctxt->inode->decl = NULL;
27173
0
      goto type_validation;
27174
0
  }
27175
0
    }
27176
    /*
27177
    * Validate against the declaration.
27178
    */
27179
0
    ret = xmlSchemaValidateElemDecl(vctxt);
27180
0
    if (ret != 0) {
27181
0
  if (ret < 0) {
27182
0
      VERROR_INT("xmlSchemaValidateElem",
27183
0
    "calling xmlSchemaValidateElemDecl()");
27184
0
      goto internal_error;
27185
0
  }
27186
0
  goto exit;
27187
0
    }
27188
    /*
27189
    * Validate against the type definition.
27190
    */
27191
0
type_validation:
27192
27193
0
    if (vctxt->inode->typeDef == NULL) {
27194
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
27195
0
  ret = XML_SCHEMAV_CVC_TYPE_1;
27196
0
  VERROR(ret, NULL,
27197
0
      "The type definition is absent");
27198
0
  goto exit;
27199
0
    }
27200
0
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
27201
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
27202
0
  ret = XML_SCHEMAV_CVC_TYPE_2;
27203
0
      VERROR(ret, NULL,
27204
0
      "The type definition is abstract");
27205
0
  goto exit;
27206
0
    }
27207
    /*
27208
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
27209
    * during validation against the declaration. This must be done
27210
    * _before_ attribute validation.
27211
    */
27212
0
    if (vctxt->xpathStates != NULL) {
27213
0
  ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
27214
0
  vctxt->inode->appliedXPath = 1;
27215
0
  if (ret == -1) {
27216
0
      VERROR_INT("xmlSchemaValidateElem",
27217
0
    "calling xmlSchemaXPathEvaluate()");
27218
0
      goto internal_error;
27219
0
  }
27220
0
    }
27221
    /*
27222
    * Validate attributes.
27223
    */
27224
0
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
27225
0
  if ((vctxt->nbAttrInfos != 0) ||
27226
0
      (vctxt->inode->typeDef->attrUses != NULL)) {
27227
27228
0
      ret = xmlSchemaVAttributesComplex(vctxt);
27229
0
  }
27230
0
    } else if (vctxt->nbAttrInfos != 0) {
27231
27232
0
  ret = xmlSchemaVAttributesSimple(vctxt);
27233
0
    }
27234
    /*
27235
    * Clear registered attributes.
27236
    */
27237
0
    if (vctxt->nbAttrInfos != 0)
27238
0
  xmlSchemaClearAttrInfos(vctxt);
27239
0
    if (ret == -1) {
27240
0
  VERROR_INT("xmlSchemaValidateElem",
27241
0
      "calling attributes validation");
27242
0
  goto internal_error;
27243
0
    }
27244
    /*
27245
    * Don't return an error if attributes are invalid on purpose.
27246
    */
27247
0
    ret = 0;
27248
27249
0
exit:
27250
0
    if (ret != 0)
27251
0
  vctxt->skipDepth = vctxt->depth;
27252
0
    return (ret);
27253
0
internal_error:
27254
0
    return (-1);
27255
0
}
27256
27257
#ifdef XML_SCHEMA_READER_ENABLED
27258
static int
27259
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
27260
{
27261
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
27262
    int depth, nodeType, ret = 0, consumed;
27263
    xmlSchemaNodeInfoPtr ielem;
27264
27265
    vctxt->depth = -1;
27266
    ret = xmlTextReaderRead(vctxt->reader);
27267
    /*
27268
    * Move to the document element.
27269
    */
27270
    while (ret == 1) {
27271
  nodeType = xmlTextReaderNodeType(vctxt->reader);
27272
  if (nodeType == XML_ELEMENT_NODE)
27273
      goto root_found;
27274
  ret = xmlTextReaderRead(vctxt->reader);
27275
    }
27276
    goto exit;
27277
27278
root_found:
27279
27280
    do {
27281
  depth = xmlTextReaderDepth(vctxt->reader);
27282
  nodeType = xmlTextReaderNodeType(vctxt->reader);
27283
27284
  if (nodeType == XML_ELEMENT_NODE) {
27285
27286
      vctxt->depth++;
27287
      if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27288
    VERROR_INT("xmlSchemaVReaderWalk",
27289
        "calling xmlSchemaValidatorPushElem()");
27290
    goto internal_error;
27291
      }
27292
      ielem = vctxt->inode;
27293
      ielem->localName = xmlTextReaderLocalName(vctxt->reader);
27294
      ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
27295
      ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
27296
      /*
27297
      * Is the element empty?
27298
      */
27299
      ret = xmlTextReaderIsEmptyElement(vctxt->reader);
27300
      if (ret == -1) {
27301
    VERROR_INT("xmlSchemaVReaderWalk",
27302
        "calling xmlTextReaderIsEmptyElement()");
27303
    goto internal_error;
27304
      }
27305
      if (ret) {
27306
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27307
      }
27308
      /*
27309
      * Register attributes.
27310
      */
27311
      vctxt->nbAttrInfos = 0;
27312
      ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
27313
      if (ret == -1) {
27314
    VERROR_INT("xmlSchemaVReaderWalk",
27315
        "calling xmlTextReaderMoveToFirstAttribute()");
27316
    goto internal_error;
27317
      }
27318
      if (ret == 1) {
27319
    do {
27320
        /*
27321
        * VAL TODO: How do we know that the reader works on a
27322
        * node tree, to be able to pass a node here?
27323
        */
27324
        if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27325
      (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27326
      xmlTextReaderNamespaceUri(vctxt->reader), 1,
27327
      xmlTextReaderValue(vctxt->reader), 1) == -1) {
27328
27329
      VERROR_INT("xmlSchemaVReaderWalk",
27330
          "calling xmlSchemaValidatorPushAttribute()");
27331
      goto internal_error;
27332
        }
27333
        ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27334
        if (ret == -1) {
27335
      VERROR_INT("xmlSchemaVReaderWalk",
27336
          "calling xmlTextReaderMoveToFirstAttribute()");
27337
      goto internal_error;
27338
        }
27339
    } while (ret == 1);
27340
    /*
27341
    * Back to element position.
27342
    */
27343
    ret = xmlTextReaderMoveToElement(vctxt->reader);
27344
    if (ret == -1) {
27345
        VERROR_INT("xmlSchemaVReaderWalk",
27346
      "calling xmlTextReaderMoveToElement()");
27347
        goto internal_error;
27348
    }
27349
      }
27350
      /*
27351
      * Validate the element.
27352
      */
27353
      ret= xmlSchemaValidateElem(vctxt);
27354
      if (ret != 0) {
27355
    if (ret == -1) {
27356
        VERROR_INT("xmlSchemaVReaderWalk",
27357
      "calling xmlSchemaValidateElem()");
27358
        goto internal_error;
27359
    }
27360
    goto exit;
27361
      }
27362
      if (vctxt->depth == vctxt->skipDepth) {
27363
    int curDepth;
27364
    /*
27365
    * Skip all content.
27366
    */
27367
    if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27368
        ret = xmlTextReaderRead(vctxt->reader);
27369
        curDepth = xmlTextReaderDepth(vctxt->reader);
27370
        while ((ret == 1) && (curDepth != depth)) {
27371
      ret = xmlTextReaderRead(vctxt->reader);
27372
      curDepth = xmlTextReaderDepth(vctxt->reader);
27373
        }
27374
        if (ret < 0) {
27375
      /*
27376
      * VAL TODO: A reader error occurred; what to do here?
27377
      */
27378
      ret = 1;
27379
      goto exit;
27380
        }
27381
    }
27382
    goto leave_elem;
27383
      }
27384
      /*
27385
      * READER VAL TODO: Is an END_ELEM really never called
27386
      * if the elem is empty?
27387
      */
27388
      if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27389
    goto leave_elem;
27390
  } else if (nodeType == END_ELEM) {
27391
      /*
27392
      * Process END of element.
27393
      */
27394
leave_elem:
27395
      ret = xmlSchemaValidatorPopElem(vctxt);
27396
      if (ret != 0) {
27397
    if (ret < 0) {
27398
        VERROR_INT("xmlSchemaVReaderWalk",
27399
      "calling xmlSchemaValidatorPopElem()");
27400
        goto internal_error;
27401
    }
27402
    goto exit;
27403
      }
27404
      if (vctxt->depth >= 0)
27405
    ielem = vctxt->inode;
27406
      else
27407
    ielem = NULL;
27408
  } else if ((nodeType == XML_TEXT_NODE) ||
27409
      (nodeType == XML_CDATA_SECTION_NODE) ||
27410
      (nodeType == WHTSP) ||
27411
      (nodeType == SIGN_WHTSP)) {
27412
      /*
27413
      * Process character content.
27414
      */
27415
      xmlChar *value;
27416
27417
      if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27418
    nodeType = XML_TEXT_NODE;
27419
27420
      value = xmlTextReaderValue(vctxt->reader);
27421
      ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27422
    -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27423
      if (! consumed)
27424
    xmlFree(value);
27425
      if (ret == -1) {
27426
    VERROR_INT("xmlSchemaVReaderWalk",
27427
        "calling xmlSchemaVPushText()");
27428
    goto internal_error;
27429
      }
27430
  } else if ((nodeType == XML_ENTITY_NODE) ||
27431
      (nodeType == XML_ENTITY_REF_NODE)) {
27432
      /*
27433
      * VAL TODO: What to do with entities?
27434
      */
27435
      TODO
27436
  }
27437
  /*
27438
  * Read next node.
27439
  */
27440
  ret = xmlTextReaderRead(vctxt->reader);
27441
    } while (ret == 1);
27442
27443
exit:
27444
    return (ret);
27445
internal_error:
27446
    return (-1);
27447
}
27448
#endif
27449
27450
/************************************************************************
27451
 *                  *
27452
 *      SAX validation handlers       *
27453
 *                  *
27454
 ************************************************************************/
27455
27456
/*
27457
* Process text content.
27458
*/
27459
static void
27460
xmlSchemaSAXHandleText(void *ctx,
27461
           const xmlChar * ch,
27462
           int len)
27463
0
{
27464
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27465
27466
0
    if (vctxt->depth < 0)
27467
0
  return;
27468
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27469
0
  return;
27470
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27471
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27472
0
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27473
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27474
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27475
0
      "calling xmlSchemaVPushText()");
27476
0
  vctxt->err = -1;
27477
0
  xmlStopParser(vctxt->parserCtxt);
27478
0
    }
27479
0
}
27480
27481
/*
27482
* Process CDATA content.
27483
*/
27484
static void
27485
xmlSchemaSAXHandleCDataSection(void *ctx,
27486
           const xmlChar * ch,
27487
           int len)
27488
0
{
27489
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27490
27491
0
    if (vctxt->depth < 0)
27492
0
  return;
27493
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27494
0
  return;
27495
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27496
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27497
0
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27498
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27499
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27500
0
      "calling xmlSchemaVPushText()");
27501
0
  vctxt->err = -1;
27502
0
  xmlStopParser(vctxt->parserCtxt);
27503
0
    }
27504
0
}
27505
27506
static void
27507
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27508
          const xmlChar * name ATTRIBUTE_UNUSED)
27509
0
{
27510
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27511
27512
0
    if (vctxt->depth < 0)
27513
0
  return;
27514
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27515
0
  return;
27516
    /* SAX VAL TODO: What to do here? */
27517
0
    TODO
27518
0
}
27519
27520
static void
27521
xmlSchemaSAXHandleStartElementNs(void *ctx,
27522
         const xmlChar * localname,
27523
         const xmlChar * prefix ATTRIBUTE_UNUSED,
27524
         const xmlChar * URI,
27525
         int nb_namespaces,
27526
         const xmlChar ** namespaces,
27527
         int nb_attributes,
27528
         int nb_defaulted ATTRIBUTE_UNUSED,
27529
         const xmlChar ** attributes)
27530
0
{
27531
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27532
0
    int ret;
27533
0
    xmlSchemaNodeInfoPtr ielem;
27534
0
    int i, j;
27535
27536
    /*
27537
    * SAX VAL TODO: What to do with nb_defaulted?
27538
    */
27539
    /*
27540
    * Skip elements if inside a "skip" wildcard or invalid.
27541
    */
27542
0
    vctxt->depth++;
27543
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27544
0
  return;
27545
    /*
27546
    * Push the element.
27547
    */
27548
0
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27549
0
  VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27550
0
      "calling xmlSchemaValidatorPushElem()");
27551
0
  goto internal_error;
27552
0
    }
27553
0
    ielem = vctxt->inode;
27554
    /*
27555
    * TODO: Is this OK?
27556
    */
27557
0
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27558
0
    ielem->localName = localname;
27559
0
    ielem->nsName = URI;
27560
0
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27561
    /*
27562
    * Register namespaces on the elem info.
27563
    */
27564
0
    if (nb_namespaces != 0) {
27565
  /*
27566
  * Although the parser builds its own namespace list,
27567
  * we have no access to it, so we'll use an own one.
27568
  */
27569
0
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27570
      /*
27571
      * Store prefix and namespace name.
27572
      */
27573
0
      if (ielem->nsBindings == NULL) {
27574
0
    ielem->nsBindings =
27575
0
        (const xmlChar **) xmlMalloc(10 *
27576
0
      sizeof(const xmlChar *));
27577
0
    if (ielem->nsBindings == NULL) {
27578
0
        xmlSchemaVErrMemory(vctxt,
27579
0
      "allocating namespace bindings for SAX validation",
27580
0
      NULL);
27581
0
        goto internal_error;
27582
0
    }
27583
0
    ielem->nbNsBindings = 0;
27584
0
    ielem->sizeNsBindings = 5;
27585
0
      } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27586
0
    ielem->sizeNsBindings *= 2;
27587
0
    ielem->nsBindings =
27588
0
        (const xmlChar **) xmlRealloc(
27589
0
      (void *) ielem->nsBindings,
27590
0
      ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27591
0
    if (ielem->nsBindings == NULL) {
27592
0
        xmlSchemaVErrMemory(vctxt,
27593
0
      "re-allocating namespace bindings for SAX validation",
27594
0
      NULL);
27595
0
        goto internal_error;
27596
0
    }
27597
0
      }
27598
27599
0
      ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27600
0
      if (namespaces[j+1][0] == 0) {
27601
    /*
27602
    * Handle xmlns="".
27603
    */
27604
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27605
0
      } else
27606
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27607
0
        namespaces[j+1];
27608
0
      ielem->nbNsBindings++;
27609
0
  }
27610
0
    }
27611
    /*
27612
    * Register attributes.
27613
    * SAX VAL TODO: We are not adding namespace declaration
27614
    * attributes yet.
27615
    */
27616
0
    if (nb_attributes != 0) {
27617
0
  int valueLen, k, l;
27618
0
  xmlChar *value;
27619
27620
0
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27621
      /*
27622
      * Duplicate the value, changing any &#38; to a literal ampersand.
27623
      *
27624
      * libxml2 differs from normal SAX here in that it escapes all ampersands
27625
      * as &#38; instead of delivering the raw converted string. Changing the
27626
      * behavior at this point would break applications that use this API, so
27627
      * we are forced to work around it.
27628
      */
27629
0
      valueLen = attributes[j+4] - attributes[j+3];
27630
0
      value = xmlMallocAtomic(valueLen + 1);
27631
0
      if (value == NULL) {
27632
0
    xmlSchemaVErrMemory(vctxt,
27633
0
        "allocating string for decoded attribute",
27634
0
        NULL);
27635
0
    goto internal_error;
27636
0
      }
27637
0
      for (k = 0, l = 0; k < valueLen; l++) {
27638
0
    if (k < valueLen - 4 &&
27639
0
        attributes[j+3][k+0] == '&' &&
27640
0
        attributes[j+3][k+1] == '#' &&
27641
0
        attributes[j+3][k+2] == '3' &&
27642
0
        attributes[j+3][k+3] == '8' &&
27643
0
        attributes[j+3][k+4] == ';') {
27644
0
        value[l] = '&';
27645
0
        k += 5;
27646
0
    } else {
27647
0
        value[l] = attributes[j+3][k];
27648
0
        k++;
27649
0
    }
27650
0
      }
27651
0
      value[l] = '\0';
27652
      /*
27653
      * TODO: Set the node line.
27654
      */
27655
0
      ret = xmlSchemaValidatorPushAttribute(vctxt,
27656
0
    NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27657
0
    value, 1);
27658
0
      if (ret == -1) {
27659
0
    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27660
0
        "calling xmlSchemaValidatorPushAttribute()");
27661
0
    goto internal_error;
27662
0
      }
27663
0
  }
27664
0
    }
27665
    /*
27666
    * Validate the element.
27667
    */
27668
0
    ret = xmlSchemaValidateElem(vctxt);
27669
0
    if (ret != 0) {
27670
0
  if (ret == -1) {
27671
0
      VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27672
0
    "calling xmlSchemaValidateElem()");
27673
0
      goto internal_error;
27674
0
  }
27675
0
  goto exit;
27676
0
    }
27677
27678
0
exit:
27679
0
    return;
27680
0
internal_error:
27681
0
    vctxt->err = -1;
27682
0
    xmlStopParser(vctxt->parserCtxt);
27683
0
    return;
27684
0
}
27685
27686
static void
27687
xmlSchemaSAXHandleEndElementNs(void *ctx,
27688
             const xmlChar * localname ATTRIBUTE_UNUSED,
27689
             const xmlChar * prefix ATTRIBUTE_UNUSED,
27690
             const xmlChar * URI ATTRIBUTE_UNUSED)
27691
0
{
27692
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27693
0
    int res;
27694
27695
    /*
27696
    * Skip elements if inside a "skip" wildcard or if invalid.
27697
    */
27698
0
    if (vctxt->skipDepth != -1) {
27699
0
  if (vctxt->depth > vctxt->skipDepth) {
27700
0
      vctxt->depth--;
27701
0
      return;
27702
0
  } else
27703
0
      vctxt->skipDepth = -1;
27704
0
    }
27705
    /*
27706
    * SAX VAL TODO: Just a temporary check.
27707
    */
27708
0
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27709
0
  (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27710
0
  VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27711
0
      "elem pop mismatch");
27712
0
    }
27713
0
    res = xmlSchemaValidatorPopElem(vctxt);
27714
0
    if (res != 0) {
27715
0
  if (res < 0) {
27716
0
      VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27717
0
    "calling xmlSchemaValidatorPopElem()");
27718
0
      goto internal_error;
27719
0
  }
27720
0
  goto exit;
27721
0
    }
27722
0
exit:
27723
0
    return;
27724
0
internal_error:
27725
0
    vctxt->err = -1;
27726
0
    xmlStopParser(vctxt->parserCtxt);
27727
0
    return;
27728
0
}
27729
27730
/************************************************************************
27731
 *                  *
27732
 *      Validation interfaces       *
27733
 *                  *
27734
 ************************************************************************/
27735
27736
/**
27737
 * xmlSchemaNewValidCtxt:
27738
 * @schema:  a precompiled XML Schemas
27739
 *
27740
 * Create an XML Schemas validation context based on the given schema.
27741
 *
27742
 * Returns the validation context or NULL in case of error
27743
 */
27744
xmlSchemaValidCtxtPtr
27745
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27746
0
{
27747
0
    xmlSchemaValidCtxtPtr ret;
27748
27749
0
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27750
0
    if (ret == NULL) {
27751
0
        xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27752
0
        return (NULL);
27753
0
    }
27754
0
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27755
0
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27756
0
    ret->dict = xmlDictCreate();
27757
0
    ret->nodeQNames = xmlSchemaItemListCreate();
27758
0
    ret->schema = schema;
27759
0
    return (ret);
27760
0
}
27761
27762
/**
27763
 * xmlSchemaValidateSetFilename:
27764
 * @vctxt: the schema validation context
27765
 * @filename: the file name
27766
 *
27767
 * Workaround to provide file error reporting information when this is
27768
 * not provided by current APIs
27769
 */
27770
void
27771
0
xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27772
0
    if (vctxt == NULL)
27773
0
        return;
27774
0
    if (vctxt->filename != NULL)
27775
0
        xmlFree(vctxt->filename);
27776
0
    if (filename != NULL)
27777
0
        vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27778
0
    else
27779
0
        vctxt->filename = NULL;
27780
0
}
27781
27782
/**
27783
 * xmlSchemaClearValidCtxt:
27784
 * @vctxt: the schema validation context
27785
 *
27786
 * Free the resources associated to the schema validation context;
27787
 * leaves some fields alive intended for reuse of the context.
27788
 */
27789
static void
27790
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27791
0
{
27792
0
    if (vctxt == NULL)
27793
0
        return;
27794
27795
    /*
27796
    * TODO: Should we clear the flags?
27797
    *   Might be problematic if one reuses the context
27798
    *   and assumes that the options remain the same.
27799
    */
27800
0
    vctxt->flags = 0;
27801
0
    vctxt->validationRoot = NULL;
27802
0
    vctxt->doc = NULL;
27803
0
#ifdef LIBXML_READER_ENABLED
27804
0
    vctxt->reader = NULL;
27805
0
#endif
27806
0
    vctxt->hasKeyrefs = 0;
27807
27808
0
    if (vctxt->value != NULL) {
27809
0
        xmlSchemaFreeValue(vctxt->value);
27810
0
  vctxt->value = NULL;
27811
0
    }
27812
    /*
27813
    * Augmented IDC information.
27814
    */
27815
0
    if (vctxt->aidcs != NULL) {
27816
0
  xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27817
0
  do {
27818
0
      next = cur->next;
27819
0
      xmlFree(cur);
27820
0
      cur = next;
27821
0
  } while (cur != NULL);
27822
0
  vctxt->aidcs = NULL;
27823
0
    }
27824
27825
0
    if (vctxt->idcNodes != NULL) {
27826
0
  int i;
27827
0
  xmlSchemaPSVIIDCNodePtr item;
27828
27829
0
  for (i = 0; i < vctxt->nbIdcNodes; i++) {
27830
0
      item = vctxt->idcNodes[i];
27831
0
      xmlFree(item->keys);
27832
0
      xmlFree(item);
27833
0
  }
27834
0
  xmlFree(vctxt->idcNodes);
27835
0
  vctxt->idcNodes = NULL;
27836
0
  vctxt->nbIdcNodes = 0;
27837
0
  vctxt->sizeIdcNodes = 0;
27838
0
    }
27839
27840
0
    if (vctxt->idcKeys != NULL) {
27841
0
  int i;
27842
0
  for (i = 0; i < vctxt->nbIdcKeys; i++)
27843
0
      xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27844
0
  xmlFree(vctxt->idcKeys);
27845
0
  vctxt->idcKeys = NULL;
27846
0
  vctxt->nbIdcKeys = 0;
27847
0
  vctxt->sizeIdcKeys = 0;
27848
0
    }
27849
27850
    /*
27851
    * Note that we won't delete the XPath state pool here.
27852
    */
27853
0
    if (vctxt->xpathStates != NULL) {
27854
0
  xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27855
0
  vctxt->xpathStates = NULL;
27856
0
    }
27857
    /*
27858
    * Attribute info.
27859
    */
27860
0
    if (vctxt->nbAttrInfos != 0) {
27861
0
  xmlSchemaClearAttrInfos(vctxt);
27862
0
    }
27863
    /*
27864
    * Element info.
27865
    */
27866
0
    if (vctxt->elemInfos != NULL) {
27867
0
  int i;
27868
0
  xmlSchemaNodeInfoPtr ei;
27869
27870
0
  for (i = 0; i < vctxt->sizeElemInfos; i++) {
27871
0
      ei = vctxt->elemInfos[i];
27872
0
      if (ei == NULL)
27873
0
    break;
27874
0
      xmlSchemaClearElemInfo(vctxt, ei);
27875
0
  }
27876
0
    }
27877
0
    xmlSchemaItemListClear(vctxt->nodeQNames);
27878
    /* Recreate the dict. */
27879
0
    xmlDictFree(vctxt->dict);
27880
    /*
27881
    * TODO: Is is save to recreate it? Do we have a scenario
27882
    * where the user provides the dict?
27883
    */
27884
0
    vctxt->dict = xmlDictCreate();
27885
27886
0
    if (vctxt->filename != NULL) {
27887
0
        xmlFree(vctxt->filename);
27888
0
  vctxt->filename = NULL;
27889
0
    }
27890
27891
    /*
27892
     * Note that some cleanup functions can move items to the cache,
27893
     * so the cache shouldn't be freed too early.
27894
     */
27895
0
    if (vctxt->idcMatcherCache != NULL) {
27896
0
  xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27897
27898
0
  while (matcher) {
27899
0
      tmp = matcher;
27900
0
      matcher = matcher->nextCached;
27901
0
      xmlSchemaIDCFreeMatcherList(tmp);
27902
0
  }
27903
0
  vctxt->idcMatcherCache = NULL;
27904
0
    }
27905
0
}
27906
27907
/**
27908
 * xmlSchemaFreeValidCtxt:
27909
 * @ctxt:  the schema validation context
27910
 *
27911
 * Free the resources associated to the schema validation context
27912
 */
27913
void
27914
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27915
0
{
27916
0
    if (ctxt == NULL)
27917
0
        return;
27918
0
    if (ctxt->value != NULL)
27919
0
        xmlSchemaFreeValue(ctxt->value);
27920
0
    if (ctxt->pctxt != NULL)
27921
0
  xmlSchemaFreeParserCtxt(ctxt->pctxt);
27922
0
    if (ctxt->idcNodes != NULL) {
27923
0
  int i;
27924
0
  xmlSchemaPSVIIDCNodePtr item;
27925
27926
0
  for (i = 0; i < ctxt->nbIdcNodes; i++) {
27927
0
      item = ctxt->idcNodes[i];
27928
0
      xmlFree(item->keys);
27929
0
      xmlFree(item);
27930
0
  }
27931
0
  xmlFree(ctxt->idcNodes);
27932
0
    }
27933
0
    if (ctxt->idcKeys != NULL) {
27934
0
  int i;
27935
0
  for (i = 0; i < ctxt->nbIdcKeys; i++)
27936
0
      xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27937
0
  xmlFree(ctxt->idcKeys);
27938
0
    }
27939
27940
0
    if (ctxt->xpathStates != NULL) {
27941
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27942
0
  ctxt->xpathStates = NULL;
27943
0
    }
27944
0
    if (ctxt->xpathStatePool != NULL) {
27945
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27946
0
  ctxt->xpathStatePool = NULL;
27947
0
    }
27948
27949
    /*
27950
    * Augmented IDC information.
27951
    */
27952
0
    if (ctxt->aidcs != NULL) {
27953
0
  xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27954
0
  do {
27955
0
      next = cur->next;
27956
0
      xmlFree(cur);
27957
0
      cur = next;
27958
0
  } while (cur != NULL);
27959
0
    }
27960
0
    if (ctxt->attrInfos != NULL) {
27961
0
  int i;
27962
0
  xmlSchemaAttrInfoPtr attr;
27963
27964
  /* Just a paranoid call to the cleanup. */
27965
0
  if (ctxt->nbAttrInfos != 0)
27966
0
      xmlSchemaClearAttrInfos(ctxt);
27967
0
  for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27968
0
      attr = ctxt->attrInfos[i];
27969
0
      xmlFree(attr);
27970
0
  }
27971
0
  xmlFree(ctxt->attrInfos);
27972
0
    }
27973
0
    if (ctxt->elemInfos != NULL) {
27974
0
  int i;
27975
0
  xmlSchemaNodeInfoPtr ei;
27976
27977
0
  for (i = 0; i < ctxt->sizeElemInfos; i++) {
27978
0
      ei = ctxt->elemInfos[i];
27979
0
      if (ei == NULL)
27980
0
    break;
27981
0
      xmlSchemaClearElemInfo(ctxt, ei);
27982
0
      xmlFree(ei);
27983
0
  }
27984
0
  xmlFree(ctxt->elemInfos);
27985
0
    }
27986
0
    if (ctxt->nodeQNames != NULL)
27987
0
  xmlSchemaItemListFree(ctxt->nodeQNames);
27988
0
    if (ctxt->dict != NULL)
27989
0
  xmlDictFree(ctxt->dict);
27990
0
    if (ctxt->filename != NULL)
27991
0
  xmlFree(ctxt->filename);
27992
0
    xmlFree(ctxt);
27993
0
}
27994
27995
/**
27996
 * xmlSchemaIsValid:
27997
 * @ctxt: the schema validation context
27998
 *
27999
 * Check if any error was detected during validation.
28000
 *
28001
 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
28002
 *         of internal error.
28003
 */
28004
int
28005
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
28006
0
{
28007
0
    if (ctxt == NULL)
28008
0
        return(-1);
28009
0
    return(ctxt->err == 0);
28010
0
}
28011
28012
/**
28013
 * xmlSchemaSetValidErrors:
28014
 * @ctxt:  a schema validation context
28015
 * @err:  the error function
28016
 * @warn: the warning function
28017
 * @ctx: the functions context
28018
 *
28019
 * Set the error and warning callback information
28020
 */
28021
void
28022
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
28023
                        xmlSchemaValidityErrorFunc err,
28024
                        xmlSchemaValidityWarningFunc warn, void *ctx)
28025
0
{
28026
0
    if (ctxt == NULL)
28027
0
        return;
28028
0
    ctxt->error = err;
28029
0
    ctxt->warning = warn;
28030
0
    ctxt->errCtxt = ctx;
28031
0
    if (ctxt->pctxt != NULL)
28032
0
  xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
28033
0
}
28034
28035
/**
28036
 * xmlSchemaSetValidStructuredErrors:
28037
 * @ctxt:  a schema validation context
28038
 * @serror:  the structured error function
28039
 * @ctx: the functions context
28040
 *
28041
 * Set the structured error callback
28042
 */
28043
void
28044
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
28045
          xmlStructuredErrorFunc serror, void *ctx)
28046
0
{
28047
0
    if (ctxt == NULL)
28048
0
        return;
28049
0
    ctxt->serror = serror;
28050
0
    ctxt->error = NULL;
28051
0
    ctxt->warning = NULL;
28052
0
    ctxt->errCtxt = ctx;
28053
0
    if (ctxt->pctxt != NULL)
28054
0
  xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
28055
0
}
28056
28057
/**
28058
 * xmlSchemaGetValidErrors:
28059
 * @ctxt: a XML-Schema validation context
28060
 * @err: the error function result
28061
 * @warn: the warning function result
28062
 * @ctx: the functions context result
28063
 *
28064
 * Get the error and warning callback information
28065
 *
28066
 * Returns -1 in case of error and 0 otherwise
28067
 */
28068
int
28069
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
28070
      xmlSchemaValidityErrorFunc * err,
28071
      xmlSchemaValidityWarningFunc * warn, void **ctx)
28072
0
{
28073
0
  if (ctxt == NULL)
28074
0
    return (-1);
28075
0
  if (err != NULL)
28076
0
    *err = ctxt->error;
28077
0
  if (warn != NULL)
28078
0
    *warn = ctxt->warning;
28079
0
  if (ctx != NULL)
28080
0
    *ctx = ctxt->errCtxt;
28081
0
  return (0);
28082
0
}
28083
28084
28085
/**
28086
 * xmlSchemaSetValidOptions:
28087
 * @ctxt: a schema validation context
28088
 * @options: a combination of xmlSchemaValidOption
28089
 *
28090
 * Sets the options to be used during the validation.
28091
 *
28092
 * Returns 0 in case of success, -1 in case of an
28093
 * API error.
28094
 */
28095
int
28096
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
28097
       int options)
28098
28099
0
{
28100
0
    int i;
28101
28102
0
    if (ctxt == NULL)
28103
0
  return (-1);
28104
    /*
28105
    * WARNING: Change the start value if adding to the
28106
    * xmlSchemaValidOption.
28107
    * TODO: Is there an other, more easy to maintain,
28108
    * way?
28109
    */
28110
0
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
28111
0
        if (options & 1<<i)
28112
0
      return (-1);
28113
0
    }
28114
0
    ctxt->options = options;
28115
0
    return (0);
28116
0
}
28117
28118
/**
28119
 * xmlSchemaValidCtxtGetOptions:
28120
 * @ctxt: a schema validation context
28121
 *
28122
 * Get the validation context options.
28123
 *
28124
 * Returns the option combination or -1 on error.
28125
 */
28126
int
28127
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
28128
28129
0
{
28130
0
    if (ctxt == NULL)
28131
0
  return (-1);
28132
0
    else
28133
0
  return (ctxt->options);
28134
0
}
28135
28136
static int
28137
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
28138
0
{
28139
0
    xmlAttrPtr attr;
28140
0
    int ret = 0;
28141
0
    xmlSchemaNodeInfoPtr ielem = NULL;
28142
0
    xmlNodePtr node, valRoot;
28143
0
    const xmlChar *nsName;
28144
28145
    /* DOC VAL TODO: Move this to the start function. */
28146
0
    if (vctxt->validationRoot != NULL)
28147
0
        valRoot = vctxt->validationRoot;
28148
0
    else
28149
0
  valRoot = xmlDocGetRootElement(vctxt->doc);
28150
0
    if (valRoot == NULL) {
28151
  /* VAL TODO: Error code? */
28152
0
  VERROR(1, NULL, "The document has no document element");
28153
0
  return (1);
28154
0
    }
28155
0
    vctxt->depth = -1;
28156
0
    vctxt->validationRoot = valRoot;
28157
0
    node = valRoot;
28158
0
    while (node != NULL) {
28159
0
  if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
28160
0
      goto next_sibling;
28161
0
  if (node->type == XML_ELEMENT_NODE) {
28162
28163
      /*
28164
      * Init the node-info.
28165
      */
28166
0
      vctxt->depth++;
28167
0
      if (xmlSchemaValidatorPushElem(vctxt) == -1)
28168
0
    goto internal_error;
28169
0
      ielem = vctxt->inode;
28170
0
      ielem->node = node;
28171
0
      ielem->nodeLine = node->line;
28172
0
      ielem->localName = node->name;
28173
0
      if (node->ns != NULL)
28174
0
    ielem->nsName = node->ns->href;
28175
0
      ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
28176
      /*
28177
      * Register attributes.
28178
      * DOC VAL TODO: We do not register namespace declaration
28179
      * attributes yet.
28180
      */
28181
0
      vctxt->nbAttrInfos = 0;
28182
0
      if (node->properties != NULL) {
28183
0
    attr = node->properties;
28184
0
    do {
28185
0
        if (attr->ns != NULL)
28186
0
      nsName = attr->ns->href;
28187
0
        else
28188
0
      nsName = NULL;
28189
0
        ret = xmlSchemaValidatorPushAttribute(vctxt,
28190
0
      (xmlNodePtr) attr,
28191
      /*
28192
      * Note that we give it the line number of the
28193
      * parent element.
28194
      */
28195
0
      ielem->nodeLine,
28196
0
      attr->name, nsName, 0,
28197
0
      xmlNodeListGetString(attr->doc, attr->children, 1), 1);
28198
0
        if (ret == -1) {
28199
0
      VERROR_INT("xmlSchemaDocWalk",
28200
0
          "calling xmlSchemaValidatorPushAttribute()");
28201
0
      goto internal_error;
28202
0
        }
28203
0
        attr = attr->next;
28204
0
    } while (attr);
28205
0
      }
28206
      /*
28207
      * Validate the element.
28208
      */
28209
0
      ret = xmlSchemaValidateElem(vctxt);
28210
0
      if (ret != 0) {
28211
0
    if (ret == -1) {
28212
0
        VERROR_INT("xmlSchemaDocWalk",
28213
0
      "calling xmlSchemaValidateElem()");
28214
0
        goto internal_error;
28215
0
    }
28216
    /*
28217
    * Don't stop validation; just skip the content
28218
    * of this element.
28219
    */
28220
0
    goto leave_node;
28221
0
      }
28222
0
      if ((vctxt->skipDepth != -1) &&
28223
0
    (vctxt->depth >= vctxt->skipDepth))
28224
0
    goto leave_node;
28225
0
  } else if ((node->type == XML_TEXT_NODE) ||
28226
0
      (node->type == XML_CDATA_SECTION_NODE)) {
28227
      /*
28228
      * Process character content.
28229
      */
28230
0
      if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
28231
0
    ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
28232
0
      ret = xmlSchemaVPushText(vctxt, node->type, node->content,
28233
0
    -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
28234
0
      if (ret < 0) {
28235
0
    VERROR_INT("xmlSchemaVDocWalk",
28236
0
        "calling xmlSchemaVPushText()");
28237
0
    goto internal_error;
28238
0
      }
28239
      /*
28240
      * DOC VAL TODO: Should we skip further validation of the
28241
      * element content here?
28242
      */
28243
0
  } else if ((node->type == XML_ENTITY_NODE) ||
28244
0
      (node->type == XML_ENTITY_REF_NODE)) {
28245
      /*
28246
      * DOC VAL TODO: What to do with entities?
28247
      */
28248
0
      VERROR_INT("xmlSchemaVDocWalk",
28249
0
    "there is at least one entity reference in the node-tree "
28250
0
    "currently being validated. Processing of entities with "
28251
0
    "this XML Schema processor is not supported (yet). Please "
28252
0
    "substitute entities before validation.");
28253
0
      goto internal_error;
28254
0
  } else {
28255
0
      goto leave_node;
28256
      /*
28257
      * DOC VAL TODO: XInclude nodes, etc.
28258
      */
28259
0
  }
28260
  /*
28261
  * Walk the doc.
28262
  */
28263
0
  if (node->children != NULL) {
28264
0
      node = node->children;
28265
0
      continue;
28266
0
  }
28267
0
leave_node:
28268
0
  if (node->type == XML_ELEMENT_NODE) {
28269
      /*
28270
      * Leaving the scope of an element.
28271
      */
28272
0
      if (node != vctxt->inode->node) {
28273
0
    VERROR_INT("xmlSchemaVDocWalk",
28274
0
        "element position mismatch");
28275
0
    goto internal_error;
28276
0
      }
28277
0
      ret = xmlSchemaValidatorPopElem(vctxt);
28278
0
      if (ret != 0) {
28279
0
    if (ret < 0) {
28280
0
        VERROR_INT("xmlSchemaVDocWalk",
28281
0
      "calling xmlSchemaValidatorPopElem()");
28282
0
        goto internal_error;
28283
0
    }
28284
0
      }
28285
0
      if (node == valRoot)
28286
0
    goto exit;
28287
0
  }
28288
0
next_sibling:
28289
0
  if (node->next != NULL)
28290
0
      node = node->next;
28291
0
  else {
28292
0
      node = node->parent;
28293
0
      goto leave_node;
28294
0
  }
28295
0
    }
28296
28297
0
exit:
28298
0
    return (ret);
28299
0
internal_error:
28300
0
    return (-1);
28301
0
}
28302
28303
static int
28304
0
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
28305
    /*
28306
    * Some initialization.
28307
    */
28308
0
    vctxt->err = 0;
28309
0
    vctxt->nberrors = 0;
28310
0
    vctxt->depth = -1;
28311
0
    vctxt->skipDepth = -1;
28312
0
    vctxt->hasKeyrefs = 0;
28313
#ifdef ENABLE_IDC_NODE_TABLES_TEST
28314
    vctxt->createIDCNodeTables = 1;
28315
#else
28316
0
    vctxt->createIDCNodeTables = 0;
28317
0
#endif
28318
    /*
28319
    * Create a schema + parser if necessary.
28320
    */
28321
0
    if (vctxt->schema == NULL) {
28322
0
  xmlSchemaParserCtxtPtr pctxt;
28323
28324
0
  vctxt->xsiAssemble = 1;
28325
  /*
28326
  * If not schema was given then we will create a schema
28327
  * dynamically using XSI schema locations.
28328
  *
28329
  * Create the schema parser context.
28330
  */
28331
0
  if ((vctxt->pctxt == NULL) &&
28332
0
     (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
28333
0
     return (-1);
28334
0
  pctxt = vctxt->pctxt;
28335
0
  pctxt->xsiAssemble = 1;
28336
  /*
28337
  * Create the schema.
28338
  */
28339
0
  vctxt->schema = xmlSchemaNewSchema(pctxt);
28340
0
  if (vctxt->schema == NULL)
28341
0
      return (-1);
28342
  /*
28343
  * Create the schema construction context.
28344
  */
28345
0
  pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
28346
0
  if (pctxt->constructor == NULL)
28347
0
      return(-1);
28348
0
  pctxt->constructor->mainSchema = vctxt->schema;
28349
  /*
28350
  * Take ownership of the constructor to be able to free it.
28351
  */
28352
0
  pctxt->ownsConstructor = 1;
28353
0
    }
28354
    /*
28355
    * Augment the IDC definitions for the main schema and all imported ones
28356
    * NOTE: main schema if the first in the imported list
28357
    */
28358
0
    xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
28359
0
                vctxt);
28360
28361
0
    return(0);
28362
0
}
28363
28364
static void
28365
0
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28366
0
    if (vctxt->xsiAssemble) {
28367
0
  if (vctxt->schema != NULL) {
28368
0
      xmlSchemaFree(vctxt->schema);
28369
0
      vctxt->schema = NULL;
28370
0
  }
28371
0
    }
28372
0
    xmlSchemaClearValidCtxt(vctxt);
28373
0
}
28374
28375
static int
28376
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28377
0
{
28378
0
    int ret = 0;
28379
28380
0
    if (xmlSchemaPreRun(vctxt) < 0)
28381
0
        return(-1);
28382
28383
0
    if (vctxt->doc != NULL) {
28384
  /*
28385
   * Tree validation.
28386
   */
28387
0
  ret = xmlSchemaVDocWalk(vctxt);
28388
0
#ifdef LIBXML_READER_ENABLED
28389
0
    } else if (vctxt->reader != NULL) {
28390
  /*
28391
   * XML Reader validation.
28392
   */
28393
#ifdef XML_SCHEMA_READER_ENABLED
28394
  ret = xmlSchemaVReaderWalk(vctxt);
28395
#endif
28396
0
#endif
28397
0
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28398
  /*
28399
   * SAX validation.
28400
   */
28401
0
  ret = xmlParseDocument(vctxt->parserCtxt);
28402
0
    } else {
28403
0
  VERROR_INT("xmlSchemaVStart",
28404
0
      "no instance to validate");
28405
0
  ret = -1;
28406
0
    }
28407
28408
0
    xmlSchemaPostRun(vctxt);
28409
0
    if (ret == 0)
28410
0
  ret = vctxt->err;
28411
0
    return (ret);
28412
0
}
28413
28414
/**
28415
 * xmlSchemaValidateOneElement:
28416
 * @ctxt:  a schema validation context
28417
 * @elem:  an element node
28418
 *
28419
 * Validate a branch of a tree, starting with the given @elem.
28420
 *
28421
 * Returns 0 if the element and its subtree is valid, a positive error
28422
 * code number otherwise and -1 in case of an internal or API error.
28423
 */
28424
int
28425
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28426
0
{
28427
0
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28428
0
  return (-1);
28429
28430
0
    if (ctxt->schema == NULL)
28431
0
  return (-1);
28432
28433
0
    ctxt->doc = elem->doc;
28434
0
    ctxt->node = elem;
28435
0
    ctxt->validationRoot = elem;
28436
0
    return(xmlSchemaVStart(ctxt));
28437
0
}
28438
28439
/**
28440
 * xmlSchemaValidateDoc:
28441
 * @ctxt:  a schema validation context
28442
 * @doc:  a parsed document tree
28443
 *
28444
 * Validate a document tree in memory.
28445
 *
28446
 * Returns 0 if the document is schemas valid, a positive error code
28447
 *     number otherwise and -1 in case of internal or API error.
28448
 */
28449
int
28450
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28451
0
{
28452
0
    if ((ctxt == NULL) || (doc == NULL))
28453
0
        return (-1);
28454
28455
0
    ctxt->doc = doc;
28456
0
    ctxt->node = xmlDocGetRootElement(doc);
28457
0
    if (ctxt->node == NULL) {
28458
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
28459
0
      XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28460
0
      (xmlNodePtr) doc, NULL,
28461
0
      "The document has no document element", NULL, NULL);
28462
0
        return (ctxt->err);
28463
0
    }
28464
0
    ctxt->validationRoot = ctxt->node;
28465
0
    return (xmlSchemaVStart(ctxt));
28466
0
}
28467
28468
28469
/************************************************************************
28470
 *                  *
28471
 *    Function and data for SAX streaming API     *
28472
 *                  *
28473
 ************************************************************************/
28474
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28475
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28476
28477
struct _xmlSchemaSplitSAXData {
28478
    xmlSAXHandlerPtr      user_sax;
28479
    void                 *user_data;
28480
    xmlSchemaValidCtxtPtr ctxt;
28481
    xmlSAXHandlerPtr      schemas_sax;
28482
};
28483
28484
0
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28485
28486
struct _xmlSchemaSAXPlug {
28487
    unsigned int magic;
28488
28489
    /* the original callbacks information */
28490
    xmlSAXHandlerPtr     *user_sax_ptr;
28491
    xmlSAXHandlerPtr      user_sax;
28492
    void                **user_data_ptr;
28493
    void                 *user_data;
28494
28495
    /* the block plugged back and validation information */
28496
    xmlSAXHandler         schemas_sax;
28497
    xmlSchemaValidCtxtPtr ctxt;
28498
};
28499
28500
/* All those functions just bounces to the user provided SAX handlers */
28501
static void
28502
internalSubsetSplit(void *ctx, const xmlChar *name,
28503
         const xmlChar *ExternalID, const xmlChar *SystemID)
28504
0
{
28505
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28506
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28507
0
        (ctxt->user_sax->internalSubset != NULL))
28508
0
  ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28509
0
                                 SystemID);
28510
0
}
28511
28512
static int
28513
isStandaloneSplit(void *ctx)
28514
0
{
28515
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28516
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28517
0
        (ctxt->user_sax->isStandalone != NULL))
28518
0
  return(ctxt->user_sax->isStandalone(ctxt->user_data));
28519
0
    return(0);
28520
0
}
28521
28522
static int
28523
hasInternalSubsetSplit(void *ctx)
28524
0
{
28525
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28526
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28527
0
        (ctxt->user_sax->hasInternalSubset != NULL))
28528
0
  return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28529
0
    return(0);
28530
0
}
28531
28532
static int
28533
hasExternalSubsetSplit(void *ctx)
28534
0
{
28535
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28536
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28537
0
        (ctxt->user_sax->hasExternalSubset != NULL))
28538
0
  return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28539
0
    return(0);
28540
0
}
28541
28542
static void
28543
externalSubsetSplit(void *ctx, const xmlChar *name,
28544
         const xmlChar *ExternalID, const xmlChar *SystemID)
28545
0
{
28546
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28547
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28548
0
        (ctxt->user_sax->externalSubset != NULL))
28549
0
  ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28550
0
                                 SystemID);
28551
0
}
28552
28553
static xmlParserInputPtr
28554
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28555
0
{
28556
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28557
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28558
0
        (ctxt->user_sax->resolveEntity != NULL))
28559
0
  return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28560
0
                                       systemId));
28561
0
    return(NULL);
28562
0
}
28563
28564
static xmlEntityPtr
28565
getEntitySplit(void *ctx, const xmlChar *name)
28566
0
{
28567
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28568
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28569
0
        (ctxt->user_sax->getEntity != NULL))
28570
0
  return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28571
0
    return(NULL);
28572
0
}
28573
28574
static xmlEntityPtr
28575
getParameterEntitySplit(void *ctx, const xmlChar *name)
28576
0
{
28577
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28578
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28579
0
        (ctxt->user_sax->getParameterEntity != NULL))
28580
0
  return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28581
0
    return(NULL);
28582
0
}
28583
28584
28585
static void
28586
entityDeclSplit(void *ctx, const xmlChar *name, int type,
28587
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28588
0
{
28589
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28590
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28591
0
        (ctxt->user_sax->entityDecl != NULL))
28592
0
  ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28593
0
                             systemId, content);
28594
0
}
28595
28596
static void
28597
attributeDeclSplit(void *ctx, const xmlChar * elem,
28598
                   const xmlChar * name, int type, int def,
28599
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
28600
0
{
28601
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28602
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28603
0
        (ctxt->user_sax->attributeDecl != NULL)) {
28604
0
  ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28605
0
                                def, defaultValue, tree);
28606
0
    } else {
28607
0
  xmlFreeEnumeration(tree);
28608
0
    }
28609
0
}
28610
28611
static void
28612
elementDeclSplit(void *ctx, const xmlChar *name, int type,
28613
      xmlElementContentPtr content)
28614
0
{
28615
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28616
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28617
0
        (ctxt->user_sax->elementDecl != NULL))
28618
0
  ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28619
0
}
28620
28621
static void
28622
notationDeclSplit(void *ctx, const xmlChar *name,
28623
       const xmlChar *publicId, const xmlChar *systemId)
28624
0
{
28625
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28626
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28627
0
        (ctxt->user_sax->notationDecl != NULL))
28628
0
  ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28629
0
                               systemId);
28630
0
}
28631
28632
static void
28633
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28634
       const xmlChar *publicId, const xmlChar *systemId,
28635
       const xmlChar *notationName)
28636
0
{
28637
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28638
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28639
0
        (ctxt->user_sax->unparsedEntityDecl != NULL))
28640
0
  ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28641
0
                                     systemId, notationName);
28642
0
}
28643
28644
static void
28645
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28646
0
{
28647
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28648
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28649
0
        (ctxt->user_sax->setDocumentLocator != NULL))
28650
0
  ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28651
0
}
28652
28653
static void
28654
startDocumentSplit(void *ctx)
28655
0
{
28656
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28657
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28658
0
        (ctxt->user_sax->startDocument != NULL))
28659
0
  ctxt->user_sax->startDocument(ctxt->user_data);
28660
0
}
28661
28662
static void
28663
endDocumentSplit(void *ctx)
28664
0
{
28665
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28666
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28667
0
        (ctxt->user_sax->endDocument != NULL))
28668
0
  ctxt->user_sax->endDocument(ctxt->user_data);
28669
0
}
28670
28671
static void
28672
processingInstructionSplit(void *ctx, const xmlChar *target,
28673
                      const xmlChar *data)
28674
0
{
28675
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28676
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28677
0
        (ctxt->user_sax->processingInstruction != NULL))
28678
0
  ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28679
0
}
28680
28681
static void
28682
commentSplit(void *ctx, const xmlChar *value)
28683
0
{
28684
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28685
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28686
0
        (ctxt->user_sax->comment != NULL))
28687
0
  ctxt->user_sax->comment(ctxt->user_data, value);
28688
0
}
28689
28690
/*
28691
 * Varargs error callbacks to the user application, harder ...
28692
 */
28693
28694
static void XMLCDECL
28695
0
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28696
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28697
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28698
0
        (ctxt->user_sax->warning != NULL)) {
28699
0
  TODO
28700
0
    }
28701
0
}
28702
static void XMLCDECL
28703
0
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28704
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28705
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28706
0
        (ctxt->user_sax->error != NULL)) {
28707
0
  TODO
28708
0
    }
28709
0
}
28710
static void XMLCDECL
28711
0
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28712
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28713
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28714
0
        (ctxt->user_sax->fatalError != NULL)) {
28715
0
  TODO
28716
0
    }
28717
0
}
28718
28719
/*
28720
 * Those are function where both the user handler and the schemas handler
28721
 * need to be called.
28722
 */
28723
static void
28724
charactersSplit(void *ctx, const xmlChar *ch, int len)
28725
0
{
28726
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28727
0
    if (ctxt == NULL)
28728
0
        return;
28729
0
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28730
0
  ctxt->user_sax->characters(ctxt->user_data, ch, len);
28731
0
    if (ctxt->ctxt != NULL)
28732
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28733
0
}
28734
28735
static void
28736
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28737
0
{
28738
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28739
0
    if (ctxt == NULL)
28740
0
        return;
28741
0
    if ((ctxt->user_sax != NULL) &&
28742
0
        (ctxt->user_sax->ignorableWhitespace != NULL))
28743
0
  ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28744
0
    if (ctxt->ctxt != NULL)
28745
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28746
0
}
28747
28748
static void
28749
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28750
0
{
28751
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28752
0
    if (ctxt == NULL)
28753
0
        return;
28754
0
    if ((ctxt->user_sax != NULL) &&
28755
0
        (ctxt->user_sax->cdataBlock != NULL))
28756
0
  ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28757
0
    if (ctxt->ctxt != NULL)
28758
0
  xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28759
0
}
28760
28761
static void
28762
referenceSplit(void *ctx, const xmlChar *name)
28763
0
{
28764
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28765
0
    if (ctxt == NULL)
28766
0
        return;
28767
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28768
0
        (ctxt->user_sax->reference != NULL))
28769
0
  ctxt->user_sax->reference(ctxt->user_data, name);
28770
0
    if (ctxt->ctxt != NULL)
28771
0
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
28772
0
}
28773
28774
static void
28775
startElementNsSplit(void *ctx, const xmlChar * localname,
28776
        const xmlChar * prefix, const xmlChar * URI,
28777
        int nb_namespaces, const xmlChar ** namespaces,
28778
        int nb_attributes, int nb_defaulted,
28779
0
        const xmlChar ** attributes) {
28780
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28781
0
    if (ctxt == NULL)
28782
0
        return;
28783
0
    if ((ctxt->user_sax != NULL) &&
28784
0
        (ctxt->user_sax->startElementNs != NULL))
28785
0
  ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28786
0
                                 URI, nb_namespaces, namespaces,
28787
0
               nb_attributes, nb_defaulted,
28788
0
               attributes);
28789
0
    if (ctxt->ctxt != NULL)
28790
0
  xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28791
0
                                   URI, nb_namespaces, namespaces,
28792
0
           nb_attributes, nb_defaulted,
28793
0
           attributes);
28794
0
}
28795
28796
static void
28797
endElementNsSplit(void *ctx, const xmlChar * localname,
28798
0
        const xmlChar * prefix, const xmlChar * URI) {
28799
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28800
0
    if (ctxt == NULL)
28801
0
        return;
28802
0
    if ((ctxt->user_sax != NULL) &&
28803
0
        (ctxt->user_sax->endElementNs != NULL))
28804
0
  ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28805
0
    if (ctxt->ctxt != NULL)
28806
0
  xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28807
0
}
28808
28809
/**
28810
 * xmlSchemaSAXPlug:
28811
 * @ctxt:  a schema validation context
28812
 * @sax:  a pointer to the original xmlSAXHandlerPtr
28813
 * @user_data:  a pointer to the original SAX user data pointer
28814
 *
28815
 * Plug a SAX based validation layer in a SAX parsing event flow.
28816
 * The original @saxptr and @dataptr data are replaced by new pointers
28817
 * but the calls to the original will be maintained.
28818
 *
28819
 * Returns a pointer to a data structure needed to unplug the validation layer
28820
 *         or NULL in case of errors.
28821
 */
28822
xmlSchemaSAXPlugPtr
28823
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28824
     xmlSAXHandlerPtr *sax, void **user_data)
28825
0
{
28826
0
    xmlSchemaSAXPlugPtr ret;
28827
0
    xmlSAXHandlerPtr old_sax;
28828
28829
0
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28830
0
        return(NULL);
28831
28832
    /*
28833
     * We only allow to plug into SAX2 event streams
28834
     */
28835
0
    old_sax = *sax;
28836
0
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28837
0
        return(NULL);
28838
0
    if ((old_sax != NULL) &&
28839
0
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28840
0
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28841
0
        return(NULL);
28842
28843
    /*
28844
     * everything seems right allocate the local data needed for that layer
28845
     */
28846
0
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28847
0
    if (ret == NULL) {
28848
0
        return(NULL);
28849
0
    }
28850
0
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28851
0
    ret->magic = XML_SAX_PLUG_MAGIC;
28852
0
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28853
0
    ret->ctxt = ctxt;
28854
0
    ret->user_sax_ptr = sax;
28855
0
    ret->user_sax = old_sax;
28856
0
    if (old_sax == NULL) {
28857
        /*
28858
   * go direct, no need for the split block and functions.
28859
   */
28860
0
  ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28861
0
  ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28862
  /*
28863
   * Note that we use the same text-function for both, to prevent
28864
   * the parser from testing for ignorable whitespace.
28865
   */
28866
0
  ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28867
0
  ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28868
28869
0
  ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28870
0
  ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28871
28872
0
  ret->user_data = ctxt;
28873
0
  *user_data = ctxt;
28874
0
    } else {
28875
       /*
28876
        * for each callback unused by Schemas initialize it to the Split
28877
  * routine only if non NULL in the user block, this can speed up
28878
  * things at the SAX level.
28879
  */
28880
0
        if (old_sax->internalSubset != NULL)
28881
0
            ret->schemas_sax.internalSubset = internalSubsetSplit;
28882
0
        if (old_sax->isStandalone != NULL)
28883
0
            ret->schemas_sax.isStandalone = isStandaloneSplit;
28884
0
        if (old_sax->hasInternalSubset != NULL)
28885
0
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28886
0
        if (old_sax->hasExternalSubset != NULL)
28887
0
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28888
0
        if (old_sax->resolveEntity != NULL)
28889
0
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
28890
0
        if (old_sax->getEntity != NULL)
28891
0
            ret->schemas_sax.getEntity = getEntitySplit;
28892
0
        if (old_sax->entityDecl != NULL)
28893
0
            ret->schemas_sax.entityDecl = entityDeclSplit;
28894
0
        if (old_sax->notationDecl != NULL)
28895
0
            ret->schemas_sax.notationDecl = notationDeclSplit;
28896
0
        if (old_sax->attributeDecl != NULL)
28897
0
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
28898
0
        if (old_sax->elementDecl != NULL)
28899
0
            ret->schemas_sax.elementDecl = elementDeclSplit;
28900
0
        if (old_sax->unparsedEntityDecl != NULL)
28901
0
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28902
0
        if (old_sax->setDocumentLocator != NULL)
28903
0
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28904
0
        if (old_sax->startDocument != NULL)
28905
0
            ret->schemas_sax.startDocument = startDocumentSplit;
28906
0
        if (old_sax->endDocument != NULL)
28907
0
            ret->schemas_sax.endDocument = endDocumentSplit;
28908
0
        if (old_sax->processingInstruction != NULL)
28909
0
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
28910
0
        if (old_sax->comment != NULL)
28911
0
            ret->schemas_sax.comment = commentSplit;
28912
0
        if (old_sax->warning != NULL)
28913
0
            ret->schemas_sax.warning = warningSplit;
28914
0
        if (old_sax->error != NULL)
28915
0
            ret->schemas_sax.error = errorSplit;
28916
0
        if (old_sax->fatalError != NULL)
28917
0
            ret->schemas_sax.fatalError = fatalErrorSplit;
28918
0
        if (old_sax->getParameterEntity != NULL)
28919
0
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28920
0
        if (old_sax->externalSubset != NULL)
28921
0
            ret->schemas_sax.externalSubset = externalSubsetSplit;
28922
28923
  /*
28924
   * the 6 schemas callback have to go to the splitter functions
28925
   * Note that we use the same text-function for ignorableWhitespace
28926
   * if possible, to prevent the parser from testing for ignorable
28927
   * whitespace.
28928
   */
28929
0
        ret->schemas_sax.characters = charactersSplit;
28930
0
  if ((old_sax->ignorableWhitespace != NULL) &&
28931
0
      (old_sax->ignorableWhitespace != old_sax->characters))
28932
0
      ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28933
0
  else
28934
0
      ret->schemas_sax.ignorableWhitespace = charactersSplit;
28935
0
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
28936
0
        ret->schemas_sax.reference = referenceSplit;
28937
0
        ret->schemas_sax.startElementNs = startElementNsSplit;
28938
0
        ret->schemas_sax.endElementNs = endElementNsSplit;
28939
28940
0
  ret->user_data_ptr = user_data;
28941
0
  ret->user_data = *user_data;
28942
0
  *user_data = ret;
28943
0
    }
28944
28945
    /*
28946
     * plug the pointers back.
28947
     */
28948
0
    *sax = &(ret->schemas_sax);
28949
0
    ctxt->sax = *sax;
28950
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28951
0
    xmlSchemaPreRun(ctxt);
28952
0
    return(ret);
28953
0
}
28954
28955
/**
28956
 * xmlSchemaSAXUnplug:
28957
 * @plug:  a data structure returned by xmlSchemaSAXPlug
28958
 *
28959
 * Unplug a SAX based validation layer in a SAX parsing event flow.
28960
 * The original pointers used in the call are restored.
28961
 *
28962
 * Returns 0 in case of success and -1 in case of failure.
28963
 */
28964
int
28965
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28966
0
{
28967
0
    xmlSAXHandlerPtr *sax;
28968
0
    void **user_data;
28969
28970
0
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28971
0
        return(-1);
28972
0
    plug->magic = 0;
28973
28974
0
    xmlSchemaPostRun(plug->ctxt);
28975
    /* restore the data */
28976
0
    sax = plug->user_sax_ptr;
28977
0
    *sax = plug->user_sax;
28978
0
    if (plug->user_sax != NULL) {
28979
0
  user_data = plug->user_data_ptr;
28980
0
  *user_data = plug->user_data;
28981
0
    }
28982
28983
    /* free and return */
28984
0
    xmlFree(plug);
28985
0
    return(0);
28986
0
}
28987
28988
/**
28989
 * xmlSchemaValidateSetLocator:
28990
 * @vctxt: a schema validation context
28991
 * @f: the locator function pointer
28992
 * @ctxt: the locator context
28993
 *
28994
 * Allows to set a locator function to the validation context,
28995
 * which will be used to provide file and line information since
28996
 * those are not provided as part of the SAX validation flow
28997
 * Setting @f to NULL disable the locator.
28998
 */
28999
29000
void
29001
xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
29002
                            xmlSchemaValidityLocatorFunc f,
29003
          void *ctxt)
29004
0
{
29005
0
    if (vctxt == NULL) return;
29006
0
    vctxt->locFunc = f;
29007
0
    vctxt->locCtxt = ctxt;
29008
0
}
29009
29010
/**
29011
 * xmlSchemaValidateStreamLocator:
29012
 * @ctx: the xmlTextReaderPtr used
29013
 * @file: returned file information
29014
 * @line: returned line information
29015
 *
29016
 * Internal locator function for the readers
29017
 *
29018
 * Returns 0 in case the Schema validation could be (de)activated and
29019
 *         -1 in case of error.
29020
 */
29021
static int
29022
xmlSchemaValidateStreamLocator(void *ctx, const char **file,
29023
0
                               unsigned long *line) {
29024
0
    xmlParserCtxtPtr ctxt;
29025
29026
0
    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
29027
0
        return(-1);
29028
29029
0
    if (file != NULL)
29030
0
        *file = NULL;
29031
0
    if (line != NULL)
29032
0
        *line = 0;
29033
29034
0
    ctxt = (xmlParserCtxtPtr) ctx;
29035
0
    if (ctxt->input != NULL) {
29036
0
       if (file != NULL)
29037
0
           *file = ctxt->input->filename;
29038
0
       if (line != NULL)
29039
0
           *line = ctxt->input->line;
29040
0
       return(0);
29041
0
    }
29042
0
    return(-1);
29043
0
}
29044
29045
/**
29046
 * xmlSchemaValidateStream:
29047
 * @ctxt:  a schema validation context
29048
 * @input:  the input to use for reading the data
29049
 * @enc:  an optional encoding information
29050
 * @sax:  a SAX handler for the resulting events
29051
 * @user_data:  the context to provide to the SAX handler.
29052
 *
29053
 * Validate an input based on a flow of SAX event from the parser
29054
 * and forward the events to the @sax handler with the provided @user_data
29055
 * the user provided @sax handler must be a SAX2 one.
29056
 *
29057
 * Returns 0 if the document is schemas valid, a positive error code
29058
 *     number otherwise and -1 in case of internal or API error.
29059
 */
29060
int
29061
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
29062
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
29063
                        xmlSAXHandlerPtr sax, void *user_data)
29064
0
{
29065
0
    xmlSchemaSAXPlugPtr plug = NULL;
29066
0
    xmlSAXHandlerPtr old_sax = NULL;
29067
0
    xmlParserCtxtPtr pctxt = NULL;
29068
0
    xmlParserInputPtr inputStream = NULL;
29069
0
    int ret;
29070
29071
0
    if ((ctxt == NULL) || (input == NULL))
29072
0
        return (-1);
29073
29074
    /*
29075
     * prepare the parser
29076
     */
29077
0
    pctxt = xmlNewParserCtxt();
29078
0
    if (pctxt == NULL)
29079
0
        return (-1);
29080
0
    old_sax = pctxt->sax;
29081
0
    pctxt->sax = sax;
29082
0
    pctxt->userData = user_data;
29083
#if 0
29084
    if (options)
29085
        xmlCtxtUseOptions(pctxt, options);
29086
#endif
29087
0
    pctxt->linenumbers = 1;
29088
0
    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
29089
29090
0
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
29091
0
    if (inputStream == NULL) {
29092
0
        ret = -1;
29093
0
  goto done;
29094
0
    }
29095
0
    inputPush(pctxt, inputStream);
29096
0
    ctxt->parserCtxt = pctxt;
29097
0
    ctxt->input = input;
29098
29099
    /*
29100
     * Plug the validation and launch the parsing
29101
     */
29102
0
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
29103
0
    if (plug == NULL) {
29104
0
        ret = -1;
29105
0
  goto done;
29106
0
    }
29107
0
    ctxt->input = input;
29108
0
    ctxt->enc = enc;
29109
0
    ctxt->sax = pctxt->sax;
29110
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
29111
0
    ret = xmlSchemaVStart(ctxt);
29112
29113
0
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
29114
0
  ret = ctxt->parserCtxt->errNo;
29115
0
  if (ret == 0)
29116
0
      ret = 1;
29117
0
    }
29118
29119
0
done:
29120
0
    ctxt->parserCtxt = NULL;
29121
0
    ctxt->sax = NULL;
29122
0
    ctxt->input = NULL;
29123
0
    if (plug != NULL) {
29124
0
        xmlSchemaSAXUnplug(plug);
29125
0
    }
29126
    /* cleanup */
29127
0
    if (pctxt != NULL) {
29128
0
  pctxt->sax = old_sax;
29129
0
  xmlFreeParserCtxt(pctxt);
29130
0
    }
29131
0
    return (ret);
29132
0
}
29133
29134
/**
29135
 * xmlSchemaValidateFile:
29136
 * @ctxt: a schema validation context
29137
 * @filename: the URI of the instance
29138
 * @options: a future set of options, currently unused
29139
 *
29140
 * Do a schemas validation of the given resource, it will use the
29141
 * SAX streamable validation internally.
29142
 *
29143
 * Returns 0 if the document is valid, a positive error code
29144
 *     number otherwise and -1 in case of an internal or API error.
29145
 */
29146
int
29147
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
29148
                      const char * filename,
29149
          int options ATTRIBUTE_UNUSED)
29150
0
{
29151
0
    int ret;
29152
0
    xmlParserInputBufferPtr input;
29153
29154
0
    if ((ctxt == NULL) || (filename == NULL))
29155
0
        return (-1);
29156
29157
0
    input = xmlParserInputBufferCreateFilename(filename,
29158
0
  XML_CHAR_ENCODING_NONE);
29159
0
    if (input == NULL)
29160
0
  return (-1);
29161
0
    ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
29162
0
  NULL, NULL);
29163
0
    return (ret);
29164
0
}
29165
29166
/**
29167
 * xmlSchemaValidCtxtGetParserCtxt:
29168
 * @ctxt: a schema validation context
29169
 *
29170
 * allow access to the parser context of the schema validation context
29171
 *
29172
 * Returns the parser context of the schema validation context or NULL
29173
 *         in case of error.
29174
 */
29175
xmlParserCtxtPtr
29176
xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
29177
0
{
29178
0
    if (ctxt == NULL)
29179
0
        return(NULL);
29180
0
    return (ctxt->parserCtxt);
29181
0
}
29182
29183
#endif /* LIBXML_SCHEMAS_ENABLED */