diff options
Diffstat (limited to 'xmlschemas.c')
-rw-r--r-- | xmlschemas.c | 287 |
1 files changed, 173 insertions, 114 deletions
diff --git a/xmlschemas.c b/xmlschemas.c index 0da3564..453a31c 100644 --- a/xmlschemas.c +++ b/xmlschemas.c @@ -578,7 +578,7 @@ struct _xmlSchemaConstructionCtxt { struct _xmlSchemaParserCtxt { int type; - void *errCtxt; /* user specific error context */ + void *errCtxt; /* user specific error context */ xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ int err; @@ -1774,7 +1774,7 @@ xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, xmlSchemaFacetPtr facet; xmlSchemaWhitespaceValueType ws; xmlChar *value = NULL; - int res; + int res, found = 0; if (*buf != NULL) xmlFree(*buf); @@ -1788,6 +1788,7 @@ xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, for (facet = type->facets; facet != NULL; facet = facet->next) { if (facet->type != XML_SCHEMA_FACET_ENUMERATION) continue; + found = 1; res = xmlSchemaGetCanonValueWhtspExt(facet->val, ws, &value); if (res == -1) { @@ -1810,6 +1811,14 @@ xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, value = NULL; } } + /* + * The enumeration facet of a type restricts the enumeration + * facet of the ancestor type; i.e., such restricted enumerations + * do not belong to the set of the given type. Thus we break + * on the first found enumeration. + */ + if (found) + break; type = type->baseType; } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); @@ -2232,6 +2241,8 @@ xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, { xmlChar *msg = NULL; + if (actxt == NULL) + return; msg = xmlStrdup(BAD_CAST "Internal error: "); msg = xmlStrcat(msg, BAD_CAST funcName); msg = xmlStrcat(msg, BAD_CAST ", "); @@ -2820,9 +2831,16 @@ xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, des = *ownerDes; } else des = *ownerDes; - xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, - "%s, attribute '%s': %s.\n", - BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); + if (attr == NULL) { + xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, + "%s, attribute '%s': %s.\n", + BAD_CAST des, (const xmlChar *) "Unknown", + (const xmlChar *) msg, NULL, NULL); + } else { + xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, + "%s, attribute '%s': %s.\n", + BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); + } if (ownerDes == NULL) FREE_AND_NULL(des); } @@ -3001,7 +3019,7 @@ xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr type, xmlSchemaFacetPtr facet) { - xmlChar *des = NULL, *strT = NULL; + xmlChar *des = NULL; xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); @@ -3009,7 +3027,6 @@ xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, "%s: The facet '%s' is not allowed.\n", BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); FREE_AND_NULL(des); - FREE_AND_NULL(strT); } /** @@ -3537,6 +3554,8 @@ xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, * The following will assure that only the first bucket is marked as * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. * For each following import buckets an xmlSchema will be created. + * An xmlSchema will be created for every distinct targetNamespace. + * We assign the targetNamespace to the schemata here. */ if (! WXS_HAS_BUCKETS(pctxt)) { if (WXS_IS_BUCKET_INCREDEF(type)) { @@ -3550,6 +3569,10 @@ xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, /* Point to the *main* schema. */ WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; WXS_IMPBUCKET(ret)->schema = mainSchema; + /* + * Ensure that the main schema gets a targetNamespace. + */ + mainSchema->targetNamespace = targetNamespace; } else { if (type == XML_SCHEMA_SCHEMA_MAIN) { PERROR_INT("xmlSchemaBucketCreate", @@ -3558,18 +3581,24 @@ xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, return(NULL); } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { /* - * Create a schema for imports. + * Create a schema for imports and assign the + * targetNamespace. */ WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); if (WXS_IMPBUCKET(ret)->schema == NULL) { xmlSchemaBucketFree(ret); return(NULL); } + WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; } } if (WXS_IS_BUCKET_IMPMAIN(type)) { int res; - /* Imports go into the "schemasImports" slot of the main *schema*. */ + /* + * Imports go into the "schemasImports" slot of the main *schema*. + * Note that we create an import entry for the main schema as well; i.e., + * even if there's only one schema, we'll get an import. + */ if (mainSchema->schemasImports == NULL) { mainSchema->schemasImports = xmlHashCreateDict(5, WXS_CONSTRUCTOR(pctxt)->dict); @@ -5445,11 +5474,11 @@ xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, * Returns the new struture or NULL in case of error */ static xmlSchemaParticlePtr -xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, +xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int min, int max) { xmlSchemaParticlePtr ret = NULL; - if ((ctxt == NULL) || (schema == NULL)) + if (ctxt == NULL) return (NULL); #ifdef DEBUG @@ -6451,8 +6480,7 @@ xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * 1 in case of success. */ static xmlSchemaAnnotPtr -xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, - xmlNodePtr node, int needed) +xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) { xmlSchemaAnnotPtr ret; xmlNodePtr child = NULL; @@ -6467,7 +6495,7 @@ xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * {any attributes with non-schema namespace . . .}> * Content: (appinfo | documentation)* */ - if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) + if ((ctxt == NULL) || (node == NULL)) return (NULL); if (needed) ret = xmlSchemaNewAnnot(ctxt, node); @@ -6639,7 +6667,7 @@ xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, child = node->children; if (IS_SCHEMA(child, "annotation")) { - facet->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (child != NULL) { @@ -6884,7 +6912,7 @@ xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (child != NULL) { @@ -6903,7 +6931,7 @@ xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, /* * Create the particle. */ - particle = xmlSchemaAddParticle(ctxt, schema, node, min, max); + particle = xmlSchemaAddParticle(ctxt, node, min, max); if (particle == NULL) return (NULL); particle->annot = annot; @@ -6944,14 +6972,9 @@ xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, return (NULL); xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); - if (IS_SCHEMA(child, "annotation")) { - ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); - child = child->next; - } - child = node->children; if (IS_SCHEMA(child, "annotation")) { - ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (child != NULL) { @@ -7020,7 +7043,7 @@ xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (child != NULL) { @@ -7311,7 +7334,7 @@ check_children: xmlSchemaAttributeUseProhibPtr prohib; if (IS_SCHEMA(child, "annotation")) { - xmlSchemaParseAnnotation(pctxt, schema, child, 0); + xmlSchemaParseAnnotation(pctxt, child, 0); child = child->next; } if (child != NULL) { @@ -7390,7 +7413,7 @@ check_children: /* * TODO: Should this go into the attr decl? */ - use->annot = xmlSchemaParseAnnotation(pctxt, schema, child, 1); + use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); child = child->next; } if (isRef) { @@ -7552,7 +7575,7 @@ xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - ret->annot = xmlSchemaParseAnnotation(pctxt, schema, child, 1); + ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); child = child->next; } if (IS_SCHEMA(child, "simpleType")) { @@ -7644,7 +7667,7 @@ xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, /* * TODO: We do not have a place to store the annotation, do we? */ - xmlSchemaParseAnnotation(pctxt, schema, child, 0); + xmlSchemaParseAnnotation(pctxt, child, 0); child = child->next; } if (child != NULL) { @@ -7779,7 +7802,7 @@ xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - ret->annot = xmlSchemaParseAnnotation(pctxt, schema, child, 1); + ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); child = child->next; } /* @@ -7980,7 +8003,10 @@ xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, * TODO: Call xmlPatterncompile with different options for selector/ * field. */ - nsList = xmlGetNsList(attr->doc, attr->parent); + if (attr == NULL) + nsList = NULL; + else + nsList = xmlGetNsList(attr->doc, attr->parent); /* * Build an array of prefixes and namespaces. */ @@ -8150,8 +8176,7 @@ xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, * Returns the parsed identity-constraint definition. */ static xmlSchemaIDCSelectPtr -xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, - xmlSchemaPtr schema, +xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, xmlSchemaIDCPtr idc, xmlNodePtr node, int isField) @@ -8224,7 +8249,7 @@ xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, * Add the annotation to the parent IDC. */ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, - xmlSchemaParseAnnotation(ctxt, schema, child, 1)); + xmlSchemaParseAnnotation(ctxt, child, 1)); child = child->next; } if (child != NULL) { @@ -8332,7 +8357,7 @@ xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - item->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (child == NULL) { @@ -8346,7 +8371,7 @@ xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, * Child element <selector>. */ if (IS_SCHEMA(child, "selector")) { - item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, schema, + item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, item, child, 0); child = child->next; /* @@ -8354,7 +8379,7 @@ xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, */ if (IS_SCHEMA(child, "field")) { do { - field = xmlSchemaParseIDCSelectorAndField(ctxt, schema, + field = xmlSchemaParseIDCSelectorAndField(ctxt, item, child, 1); if (field != NULL) { field->index = item->nbFields; @@ -8437,7 +8462,7 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); child = node->children; if (IS_SCHEMA(child, "annotation")) { - annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } /* @@ -8451,7 +8476,7 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); - particle = xmlSchemaAddParticle(ctxt, schema, node, min, max); + particle = xmlSchemaAddParticle(ctxt, node, min, max); if (particle == NULL) goto return_null; @@ -8906,7 +8931,7 @@ xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * Add the annotation to the simple type ancestor. */ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, - xmlSchemaParseAnnotation(ctxt, schema, child, 1)); + xmlSchemaParseAnnotation(ctxt, child, 1)); child = child->next; } if (IS_SCHEMA(child, "simpleType")) { @@ -9020,7 +9045,7 @@ xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, child = node->children; if (IS_SCHEMA(child, "annotation")) { xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, - xmlSchemaParseAnnotation(ctxt, schema, child, 1)); + xmlSchemaParseAnnotation(ctxt, child, 1)); child = child->next; } if (IS_SCHEMA(child, "simpleType")) { @@ -9237,7 +9262,7 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, child = node->children; if (IS_SCHEMA(child, "annotation")) { - type->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (child == NULL) { @@ -9337,7 +9362,7 @@ xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, attr = attr->next; } xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); - item = xmlSchemaAddParticle(ctxt, schema, node, min, max); + item = xmlSchemaAddParticle(ctxt, node, min, max); if (item == NULL) return (NULL); /* @@ -9356,7 +9381,7 @@ xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, /* * TODO: What to do exactly with the annotation? */ - item->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (child != NULL) { @@ -9442,7 +9467,7 @@ xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - item->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (IS_SCHEMA(child, "all")) { @@ -9707,7 +9732,7 @@ xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, (IS_SCHEMA(child, "redefine")) || (IS_SCHEMA(child, "annotation"))) { if (IS_SCHEMA(child, "annotation")) { - annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + annot = xmlSchemaParseAnnotation(ctxt, child, 1); if (schema->annot == NULL) schema->annot = annot; else @@ -9775,7 +9800,7 @@ xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, /* * TODO: We should add all annotations. */ - annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + annot = xmlSchemaParseAnnotation(ctxt, child, 1); if (schema->annot == NULL) schema->annot = annot; else @@ -10052,14 +10077,14 @@ xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, /* * Save old values; reset the *main* schema. * URGENT TODO: This is not good; move the per-document information - * to the parser. + * to the parser. Get rid of passing the main schema to the + * parsing functions. */ oldFlags = schema->flags; oldDoc = schema->doc; if (schema->flags != 0) xmlSchemaClearSchemaDefaults(schema); - schema->doc = bucket->doc; - /* !! REMOVED: schema->targetNamespace = bucket->targetNamespace; */ + schema->doc = bucket->doc; pctxt->schema = schema; /* * Keep the current target namespace on the parser *not* on the @@ -10540,8 +10565,6 @@ doc_load: invokingNode, NULL, "The document '%s' has no document element", schemaLocation, NULL); - xmlFreeDoc(doc); - doc = NULL; goto exit_error; } /* @@ -10556,8 +10579,6 @@ doc_load: invokingNode, NULL, "The XML document '%s' is not a schema document", schemaLocation, NULL); - xmlFreeDoc(doc); - doc = NULL; goto exit_error; } /* @@ -11171,7 +11192,7 @@ xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, /* * Create a particle */ - particle = xmlSchemaAddParticle(ctxt, schema, node, min, max); + particle = xmlSchemaAddParticle(ctxt, node, min, max); if (particle == NULL) return (NULL); particle->children = (xmlSchemaTreeItemPtr) item; @@ -11221,7 +11242,7 @@ xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - item->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } if (type == XML_SCHEMA_TYPE_ALL) { @@ -11480,7 +11501,7 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, "value '%s' of the 'base' attribute does not match the " "type's designation '%s'", xmlSchemaFormatQName(&str1, type->baseNs, type->base), - xmlSchemaFormatQName(&str1, type->targetNamespace, + xmlSchemaFormatQName(&str2, type->targetNamespace, type->name), NULL); FREE_AND_NULL(str1); FREE_AND_NULL(str2); @@ -11499,7 +11520,7 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * Add the annotation to the simple type ancestor. */ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, - xmlSchemaParseAnnotation(ctxt, schema, child, 1)); + xmlSchemaParseAnnotation(ctxt, child, 1)); child = child->next; } if (parentType == XML_SCHEMA_TYPE_SIMPLE) { @@ -11760,7 +11781,7 @@ xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * Add the annotation to the type ancestor. */ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, - xmlSchemaParseAnnotation(ctxt, schema, child, 1)); + xmlSchemaParseAnnotation(ctxt, child, 1)); child = child->next; } if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { @@ -11886,7 +11907,7 @@ xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, * Add the annotation to the complex type ancestor. */ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, - xmlSchemaParseAnnotation(ctxt, schema, child, 1)); + xmlSchemaParseAnnotation(ctxt, child, 1)); child = child->next; } if (child == NULL) { @@ -11981,7 +12002,7 @@ xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, * Add the annotation to the complex type ancestor. */ xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, - xmlSchemaParseAnnotation(ctxt, schema, child, 1)); + xmlSchemaParseAnnotation(ctxt, child, 1)); child = child->next; } if (child == NULL) { @@ -12202,7 +12223,7 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, */ child = node->children; if (IS_SCHEMA(child, "annotation")) { - type->annot = xmlSchemaParseAnnotation(ctxt, schema, child, 1); + type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); child = child->next; } ctxt->ctxtType = type; @@ -15495,8 +15516,7 @@ xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, if (baseMember == NULL) { PERROR_INT("xmlSchemaCheckCOSSTRestricts", "different number of member types in base"); - } - if ((member->type != baseMember->type) && + } else if ((member->type != baseMember->type) && (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, member->type, baseMember->type, 0) != 0)) { xmlChar *strBMT = NULL, *strBT = NULL; @@ -18206,7 +18226,7 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, /* * Create the particle. */ - particle = xmlSchemaAddParticle(pctxt, pctxt->schema, + particle = xmlSchemaAddParticle(pctxt, type->node, 1, 1); if (particle == NULL) goto exit_failure; @@ -18323,7 +18343,7 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, /* * Create the particle. */ - particle = xmlSchemaAddParticle(pctxt, pctxt->schema, + particle = xmlSchemaAddParticle(pctxt, type->node, 1, 1); if (particle == NULL) goto exit_failure; @@ -18344,7 +18364,7 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, */ particle->children->children = (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, - pctxt->schema, type->node, + type->node, ((xmlSchemaParticlePtr) type->subtypes)->minOccurs, ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs); if (particle->children->children == NULL) @@ -20430,7 +20450,7 @@ xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, const xmlChar *name; int i; -#define WXS_GET_GLOBAL_HASH(c, s, slot) { \ +#define WXS_GET_GLOBAL_HASH(c, slot) { \ if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ table = &(WXS_IMPBUCKET((c))->schema->slot); \ else \ @@ -20463,37 +20483,37 @@ xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, if (WXS_REDEFINED_TYPE(item)) continue; name = (WXS_TYPE_CAST item)->name; - WXS_GET_GLOBAL_HASH(bucket, schema, typeDecl) + WXS_GET_GLOBAL_HASH(bucket, typeDecl) break; case XML_SCHEMA_TYPE_ELEMENT: name = (WXS_ELEM_CAST item)->name; - WXS_GET_GLOBAL_HASH(bucket, schema, elemDecl) + WXS_GET_GLOBAL_HASH(bucket, elemDecl) break; case XML_SCHEMA_TYPE_ATTRIBUTE: name = (WXS_ATTR_CAST item)->name; - WXS_GET_GLOBAL_HASH(bucket, schema, attrDecl) + WXS_GET_GLOBAL_HASH(bucket, attrDecl) break; case XML_SCHEMA_TYPE_GROUP: if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) continue; name = (WXS_MODEL_GROUPDEF_CAST item)->name; - WXS_GET_GLOBAL_HASH(bucket, schema, groupDecl) + WXS_GET_GLOBAL_HASH(bucket, groupDecl) break; case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: if (WXS_REDEFINED_ATTR_GROUP(item)) continue; name = (WXS_ATTR_GROUP_CAST item)->name; - WXS_GET_GLOBAL_HASH(bucket, schema, attrgrpDecl) + WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) break; case XML_SCHEMA_TYPE_IDC_KEY: case XML_SCHEMA_TYPE_IDC_UNIQUE: case XML_SCHEMA_TYPE_IDC_KEYREF: name = (WXS_IDC_CAST item)->name; - WXS_GET_GLOBAL_HASH(bucket, schema, idcDef) + WXS_GET_GLOBAL_HASH(bucket, idcDef) break; case XML_SCHEMA_TYPE_NOTATION: name = ((xmlSchemaNotationPtr) item)->name; - WXS_GET_GLOBAL_HASH(bucket, schema, notaDecl) + WXS_GET_GLOBAL_HASH(bucket, notaDecl) break; default: PERROR_INT("xmlSchemaAddComponents", @@ -20540,11 +20560,13 @@ xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, } static int -xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt) +xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, + xmlSchemaBucketPtr rootBucket) { xmlSchemaConstructionCtxtPtr con = pctxt->constructor; xmlSchemaTreeItemPtr item, *items; - int nbItems, i; + int nbItems, i, ret = 0; + xmlSchemaBucketPtr oldbucket = con->bucket; #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; @@ -20552,6 +20574,16 @@ xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt) (con->pending->nbItems == 0)) return(0); + /* + * Since xmlSchemaFixupComplexType() will create new particles + * (local components), and those particle components need a bucket + * on the constructor, we'll assure here that the constructor has + * a bucket. + * TODO: Think about storing locals _only_ on the main bucket. + */ + if (con->bucket == NULL) + con->bucket = rootBucket; + /* TODO: * SPEC (src-redefine): * (6.2) "If it has no such self-reference, then all of the @@ -20567,8 +20599,8 @@ xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt) /* * Add global components to the schemata's hash tables. - */ - xmlSchemaAddComponents(pctxt, WXS_CONSTRUCTOR(pctxt)->mainBucket); + */ + xmlSchemaAddComponents(pctxt, rootBucket); pctxt->ctxtType = NULL; items = (xmlSchemaTreeItemPtr *) con->pending->items; @@ -20945,15 +20977,34 @@ xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt) goto exit_error; /* * URGENT TODO: cos-element-consistent - */ - con->pending->nbItems = 0; - return(0); -exit_error: - con->pending->nbItems = 0; - return(pctxt->err); + */ + goto exit; + +exit_error: + ret = pctxt->err; + goto exit; + exit_failure: - con->pending->nbItems = 0; - return(-1); + ret = -1; + +exit: + /* + * Reset the constructor. This is needed for XSI acquisition, since + * those items will be processed over and over again for every XSI + * if not cleared here. + */ + con->bucket = oldbucket; + con->pending->nbItems = 0; + if (con->substGroups != NULL) { + xmlHashFree(con->substGroups, + (xmlHashDeallocator) xmlSchemaSubstGroupFree); + con->substGroups = NULL; + } + if (con->redefs != NULL) { + xmlSchemaRedefListFree(con->redefs); + con->redefs = NULL; + } + return(ret); } /** * xmlSchemaParse: @@ -20968,7 +21019,7 @@ exit_failure: xmlSchemaPtr xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) { - xmlSchemaPtr schema = NULL; + xmlSchemaPtr mainSchema = NULL; xmlSchemaBucketPtr bucket = NULL; int res; @@ -20988,8 +21039,8 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) ctxt->counter = 0; /* Create the *main* schema. */ - schema = xmlSchemaNewSchema(ctxt); - if (schema == NULL) + mainSchema = xmlSchemaNewSchema(ctxt); + if (mainSchema == NULL) goto exit_failure; /* * Create the schema constructor. @@ -21001,7 +21052,7 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) /* Take ownership of the constructor to be able to free it. */ ctxt->ownsConstructor = 1; } - ctxt->constructor->mainSchema = schema; + ctxt->constructor->mainSchema = mainSchema; /* * Locate and add the schema document. */ @@ -21026,24 +21077,19 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) "Failed to locate the main schema resource", NULL, NULL); goto exit; - } - /* Set the main schema bucket. */ - ctxt->constructor->bucket = bucket; - ctxt->targetNamespace = bucket->targetNamespace; - schema->targetNamespace = bucket->targetNamespace; - + } /* Then do the parsing for good. */ - if (xmlSchemaParseNewDocWithContext(ctxt, schema, bucket) == -1) + if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) goto exit_failure; if (ctxt->nberrors != 0) goto exit; + + mainSchema->doc = bucket->doc; + mainSchema->preserve = ctxt->preserve; + + ctxt->schema = mainSchema; - schema->doc = bucket->doc; - schema->preserve = ctxt->preserve; - - ctxt->schema = schema; - - if (xmlSchemaFixupComponents(ctxt) == -1) + if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) goto exit_failure; /* @@ -21052,9 +21098,9 @@ xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) */ exit: if (ctxt->nberrors != 0) { - if (schema) { - xmlSchemaFree(schema); - schema = NULL; + if (mainSchema) { + xmlSchemaFree(mainSchema); + mainSchema = NULL; } if (ctxt->constructor) { xmlSchemaConstructionCtxtFree(ctxt->constructor); @@ -21063,15 +21109,15 @@ exit: } } ctxt->schema = NULL; - return(schema); + return(mainSchema); exit_failure: /* * Quite verbose, but should catch internal errors, which were * not communitated. */ - if (schema) { - xmlSchemaFree(schema); - schema = NULL; + if (mainSchema) { + xmlSchemaFree(mainSchema); + mainSchema = NULL; } if (ctxt->constructor) { xmlSchemaConstructionCtxtFree(ctxt->constructor); @@ -21342,12 +21388,14 @@ xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, /* Paranoid error channelling. */ if ((ret == 0) && (pctxt->nberrors != 0)) ret = pctxt->err; - if (pctxt->nberrors == 0) { + if (pctxt->nberrors == 0) { /* * Only bother to fixup pending components, if there was * no error yet. + * For every XSI acquired schema (and its sub-schemata) we will + * fixup the components. */ - xmlSchemaFixupComponents(pctxt); + xmlSchemaFixupComponents(pctxt, bucket); ret = pctxt->err; /* * Not nice, but we need somehow to channel the schema parser @@ -23873,6 +23921,14 @@ pattern_and_enum: } if (ret != 0) break; + /* + * Break on the first set of enumerations. Any additional + * enumerations which might be existent on the ancestors + * of the current type are restricted by this set; thus + * *must* *not* be taken into account. + */ + if (found) + break; tmpType = tmpType->baseType; } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); @@ -24554,7 +24610,7 @@ static int xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) { xmlSchemaElementPtr elemDecl = vctxt->inode->decl; - xmlSchemaTypePtr actualType = WXS_ELEM_TYPEDEF(elemDecl); + xmlSchemaTypePtr actualType; /* * cvc-elt (3.3.4) : 1 @@ -24564,6 +24620,7 @@ xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) "No matching declaration available"); return (vctxt->err); } + actualType = WXS_ELEM_TYPEDEF(elemDecl); /* * cvc-elt (3.3.4) : 2 */ @@ -27422,7 +27479,7 @@ xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) /* * Process character content. */ - if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) + if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; ret = xmlSchemaVPushText(vctxt, node->type, node->content, -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); @@ -27953,6 +28010,8 @@ static void referenceSplit(void *ctx, const xmlChar *name) { xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; + if (ctxt == NULL) + return; if ((ctxt != NULL) && (ctxt->user_sax != NULL) && (ctxt->user_sax->reference != NULL)) ctxt->user_sax->reference(ctxt->user_data, name); |