Commit c00cda8c authored by Daniel Veillard's avatar Daniel Veillard
Browse files

fixing bug #107129, removing excessive allocation and calls to *printf in

* tree.c valid.c xpath.c include/libxml/tree.h include/libxml/valid.h:
  fixing bug #107129, removing excessive allocation and calls
  to *printf in the code to build QName strings.
Daniel
parent 6965118d
Mon Apr 7 12:19:26 CEST 2003 Daniel Veillard <daniel@veillard.com>
* tree.c valid.c xpath.c include/libxml/tree.h include/libxml/valid.h:
fixing bug #107129, removing excessive allocation and calls
to *printf in the code to build QName strings.
Sat Apr 5 11:41:36 CEST 2003 Igoe Zlatkovic <igor@zlatkovic.com> Sat Apr 5 11:41:36 CEST 2003 Igoe Zlatkovic <igor@zlatkovic.com>
* win32/libxml2.def.src: fixed conditional exports, reported by * win32/libxml2.def.src: fixed conditional exports, reported by
......
...@@ -538,11 +538,24 @@ LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags; /* save empty tags as <empty></ ...@@ -538,11 +538,24 @@ LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags; /* save empty tags as <empty></
LIBXML_DLL_IMPORT extern int xmlDefaultBufferSize; /* default buffer size */ LIBXML_DLL_IMPORT extern int xmlDefaultBufferSize; /* default buffer size */
#endif #endif
int xmlValidateNCName (const xmlChar *value, int space); /*
int xmlValidateQName (const xmlChar *value, int space); * Some helper functions
int xmlValidateName (const xmlChar *value, int space); */
int xmlValidateNMToken (const xmlChar *value, int space); int xmlValidateNCName (const xmlChar *value,
int space);
int xmlValidateQName (const xmlChar *value,
int space);
int xmlValidateName (const xmlChar *value,
int space);
int xmlValidateNMToken (const xmlChar *value,
int space);
xmlChar * xmlBuildQName (const xmlChar *ncname,
const xmlChar *prefix,
xmlChar *memory,
int len);
xmlChar * xmlSplitQName2 (const xmlChar *name,
xmlChar **prefix);
/* /*
* Handling Buffers. * Handling Buffers.
*/ */
......
...@@ -127,10 +127,6 @@ typedef xmlIDTable *xmlIDTablePtr; ...@@ -127,10 +127,6 @@ typedef xmlIDTable *xmlIDTablePtr;
typedef struct _xmlHashTable xmlRefTable; typedef struct _xmlHashTable xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr; typedef xmlRefTable *xmlRefTablePtr;
/* helper */
xmlChar * xmlSplitQName2 (const xmlChar *name,
xmlChar **prefix);
/* Notation */ /* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt, xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
xmlDtdPtr dtd, xmlDtdPtr dtd,
......
...@@ -123,6 +123,102 @@ xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) { ...@@ -123,6 +123,102 @@ xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
return(NULL); return(NULL);
} }
/************************************************************************
* *
* QName handling helper *
* *
************************************************************************/
/**
* xmlBuildQName:
* @ncname: the Name
* @prefix: the prefix
* @memory: preallocated memory
* @len: preallocated memory length
*
* Builds the QName @prefix:@ncname in @memory if there is enough space
* and prefix is not NULL nor empty, otherwise allocate a new string.
* If prefix is NULL or empty it returns ncname.
*
* Returns the new string which must be freed by the caller if different from
* @memory and @ncname or NULL in case of error
*/
xmlChar *
xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix,
xmlChar *memory, int len) {
int lenn, lenp;
xmlChar *ret;
if ((ncname == NULL) || (*ncname == 0)) return(NULL);
if ((prefix == NULL) || (*prefix == 0)) return((xmlChar *) ncname);
lenn = strlen((char *) ncname);
lenp = strlen((char *) prefix);
if ((memory == NULL) || (len < lenn + lenp + 2)) {
ret = (xmlChar *) xmlMalloc(lenn + lenp + 2);
if (ret == NULL) return(NULL);
} else {
ret = memory;
}
memcpy(&ret[0], prefix, lenp);
ret[lenp] = ':';
memcpy(&ret[lenp + 1], ncname, lenn);
ret[lenn + lenp + 1] = 0;
return(ret);
}
/**
* xmlSplitQName2:
* @name: the full QName
* @prefix: a xmlChar **
*
* parse an XML qualified name string
*
* [NS 5] QName ::= (Prefix ':')? LocalPart
*
* [NS 6] Prefix ::= NCName
*
* [NS 7] LocalPart ::= NCName
*
* Returns NULL if not a QName, otherwise the local part, and prefix
* is updated to get the Prefix if any.
*/
xmlChar *
xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
int len = 0;
xmlChar *ret = NULL;
*prefix = NULL;
#ifndef XML_XML_NAMESPACE
/* xml: prefix is not really a namespace */
if ((name[0] == 'x') && (name[1] == 'm') &&
(name[2] == 'l') && (name[3] == ':'))
return(NULL);
#endif
/* nasty but valid */
if (name[0] == ':')
return(NULL);
/*
* we are not trying to validate but just to cut, and yes it will
* work even if this is as set of UTF-8 encoded chars
*/
while ((name[len] != 0) && (name[len] != ':'))
len++;
if (name[len] == 0)
return(NULL);
*prefix = xmlStrndup(name, len);
ret = xmlStrdup(&name[len + 1]);
return(ret);
}
/************************************************************************ /************************************************************************
* * * *
* Check Name, NCName and QName strings * * Check Name, NCName and QName strings *
...@@ -3915,6 +4011,7 @@ xmlGetNodePath(xmlNodePtr node) ...@@ -3915,6 +4011,7 @@ xmlGetNodePath(xmlNodePtr node)
/* /*
* Thumbler index computation * Thumbler index computation
* TODO: the ocurence test seems bogus for namespaced names
*/ */
tmp = cur->prev; tmp = cur->prev;
while (tmp != NULL) { while (tmp != NULL) {
......
...@@ -505,51 +505,40 @@ xmlValidBuildAContentModel(xmlElementContentPtr content, ...@@ -505,51 +505,40 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
break; break;
case XML_ELEMENT_CONTENT_ELEMENT: { case XML_ELEMENT_CONTENT_ELEMENT: {
xmlAutomataStatePtr oldstate = ctxt->state; xmlAutomataStatePtr oldstate = ctxt->state;
xmlChar *QName = NULL; xmlChar fn[50];
const xmlChar *fname = content->name; xmlChar *fullname;
if (content->prefix != NULL) { fullname = xmlBuildQName(content->name, content->prefix, fn, 50);
int len; if (fullname == NULL) {
VERROR(ctxt->userData, "Out of memory\n");
len = xmlStrlen(content->name) + return(0);
xmlStrlen(content->prefix) + 2;
QName = xmlMalloc(len);
if (QName == NULL) {
VERROR(ctxt->userData,
"ContentModel %s : alloc failed\n", name);
return(0);
}
snprintf((char *) QName, len, "%s:%s",
(char *)content->prefix,
(char *)content->name);
fname = QName;
} }
switch (content->ocur) { switch (content->ocur) {
case XML_ELEMENT_CONTENT_ONCE: case XML_ELEMENT_CONTENT_ONCE:
ctxt->state = xmlAutomataNewTransition(ctxt->am, ctxt->state = xmlAutomataNewTransition(ctxt->am,
ctxt->state, NULL, fname, NULL); ctxt->state, NULL, fullname, NULL);
break; break;
case XML_ELEMENT_CONTENT_OPT: case XML_ELEMENT_CONTENT_OPT:
ctxt->state = xmlAutomataNewTransition(ctxt->am, ctxt->state = xmlAutomataNewTransition(ctxt->am,
ctxt->state, NULL, fname, NULL); ctxt->state, NULL, fullname, NULL);
xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
break; break;
case XML_ELEMENT_CONTENT_PLUS: case XML_ELEMENT_CONTENT_PLUS:
ctxt->state = xmlAutomataNewTransition(ctxt->am, ctxt->state = xmlAutomataNewTransition(ctxt->am,
ctxt->state, NULL, fname, NULL); ctxt->state, NULL, fullname, NULL);
xmlAutomataNewTransition(ctxt->am, ctxt->state, xmlAutomataNewTransition(ctxt->am, ctxt->state,
ctxt->state, fname, NULL); ctxt->state, fullname, NULL);
break; break;
case XML_ELEMENT_CONTENT_MULT: case XML_ELEMENT_CONTENT_MULT:
xmlAutomataNewTransition(ctxt->am, ctxt->state, xmlAutomataNewTransition(ctxt->am, ctxt->state,
ctxt->state, fname, NULL); ctxt->state, fullname, NULL);
ctxt->state = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, ctxt->state = xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
NULL); NULL);
break; break;
} }
if (QName != NULL) if ((fullname != fn) && (fullname != content->name))
xmlFree(QName); xmlFree(fullname);
break; break;
} }
case XML_ELEMENT_CONTENT_SEQ: { case XML_ELEMENT_CONTENT_SEQ: {
...@@ -702,63 +691,6 @@ xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) { ...@@ -702,63 +691,6 @@ xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
#endif /* LIBXML_REGEXP_ENABLED */ #endif /* LIBXML_REGEXP_ENABLED */
/************************************************************************
* *
* QName handling helper *
* *
************************************************************************/
/**
* xmlSplitQName2:
* @name: an XML parser context
* @prefix: a xmlChar **
*
* parse an XML qualified name string
*
* [NS 5] QName ::= (Prefix ':')? LocalPart
*
* [NS 6] Prefix ::= NCName
*
* [NS 7] LocalPart ::= NCName
*
* Returns NULL if not a QName, otherwise the local part, and prefix
* is updated to get the Prefix if any.
*/
xmlChar *
xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
int len = 0;
xmlChar *ret = NULL;
*prefix = NULL;
#ifndef XML_XML_NAMESPACE
/* xml: prefix is not really a namespace */
if ((name[0] == 'x') && (name[1] == 'm') &&
(name[2] == 'l') && (name[3] == ':'))
return(NULL);
#endif
/* nasty but valid */
if (name[0] == ':')
return(NULL);
/*
* we are not trying to validate but just to cut, and yes it will
* work even if this is as set of UTF-8 encoded chars
*/
while ((name[len] != 0) && (name[len] != ':'))
len++;
if (name[len] == 0)
return(NULL);
*prefix = xmlStrndup(name, len);
ret = xmlStrdup(&name[len + 1]);
return(ret);
}
/**************************************************************** /****************************************************************
* * * *
* Util functions for data allocation/deallocation * * Util functions for data allocation/deallocation *
...@@ -2332,23 +2264,19 @@ xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) { ...@@ -2332,23 +2264,19 @@ xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
if (elem == NULL) return(0); if (elem == NULL) return(0);
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
/* xmlChar fn[50];
* TODO: this sucks ... recomputing this every time is stupid
*/
int len = xmlStrlen(elem->name) + xmlStrlen(elem->ns->prefix) + 2;
xmlChar *fullname; xmlChar *fullname;
fullname = xmlMalloc(len); fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
if (fullname == NULL) if (fullname == NULL)
return(0); return(0);
snprintf((char *) fullname, len, "%s:%s", (char *) elem->ns->prefix,
(char *) elem->name);
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname,
attr->name); attr->name);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) if ((attrDecl == NULL) && (doc->extSubset != NULL))
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname,
attr->name); attr->name);
xmlFree(fullname); if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
} else { } else {
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name,
attr->name); attr->name);
...@@ -3469,16 +3397,20 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc, ...@@ -3469,16 +3397,20 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if (value == NULL) return(NULL); if (value == NULL) return(NULL);
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
xmlChar qname[500]; xmlChar fn[50];
snprintf((char *) qname, sizeof(qname), "%s:%s", xmlChar *fullname;
elem->ns->prefix, elem->name);
qname[sizeof(qname) - 1] = 0; fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name); if (fullname == NULL)
return(0);
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, name);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) { if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name); attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, name);
if (attrDecl != NULL) if (attrDecl != NULL)
extsubset = 1; extsubset = 1;
} }
if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
} }
if ((attrDecl == NULL) && (doc->intSubset != NULL)) if ((attrDecl == NULL) && (doc->intSubset != NULL))
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name); attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
...@@ -3550,13 +3482,17 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem, ...@@ -3550,13 +3482,17 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
if (value == NULL) return(NULL); if (value == NULL) return(NULL);
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
xmlChar qname[500]; xmlChar fn[50];
snprintf((char *) qname, sizeof(qname), "%s:%s", xmlChar *fullname;
elem->ns->prefix, elem->name);
qname[sizeof(qname) - 1] = 0; fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name); if (fullname == NULL)
return(0);
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, name);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) if ((attrDecl == NULL) && (doc->extSubset != NULL))
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name); attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, name);
if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
} }
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name); attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) if ((attrDecl == NULL) && (doc->extSubset != NULL))
...@@ -3836,22 +3772,26 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc, ...@@ -3836,22 +3772,26 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if ((attr == NULL) || (attr->name == NULL)) return(0); if ((attr == NULL) || (attr->name == NULL)) return(0);
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
xmlChar qname[500]; xmlChar fn[50];
snprintf((char *) qname, sizeof(qname), "%s:%s", xmlChar *fullname;
elem->ns->prefix, elem->name);
qname[sizeof(qname) - 1] = 0; fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
if (fullname == NULL)
return(0);
if (attr->ns != NULL) { if (attr->ns != NULL) {
attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname, attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullname,
attr->name, attr->ns->prefix); attr->name, attr->ns->prefix);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) if ((attrDecl == NULL) && (doc->extSubset != NULL))
attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname, attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
attr->name, attr->ns->prefix); attr->name, attr->ns->prefix);
} else { } else {
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, attr->name); attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, attr->name);
if ((attrDecl == NULL) && (doc->extSubset != NULL)) if ((attrDecl == NULL) && (doc->extSubset != NULL))
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
qname, attr->name); fullname, attr->name);
} }
if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
} }
if (attrDecl == NULL) { if (attrDecl == NULL) {
if (attr->ns != NULL) { if (attr->ns != NULL) {
...@@ -4016,23 +3956,29 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) { ...@@ -4016,23 +3956,29 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
if ((ns == NULL) || (ns->href == NULL)) return(0); if ((ns == NULL) || (ns->href == NULL)) return(0);
if (prefix != NULL) { if (prefix != NULL) {
xmlChar qname[500]; xmlChar fn[50];
snprintf((char *) qname, sizeof(qname), "%s:%s", xmlChar *fullname;
prefix, elem->name);
qname[sizeof(qname) - 1] = 0; fullname = xmlBuildQName(elem->name, prefix, fn, 50);
if (fullname == NULL) {
VERROR(ctxt->userData, "Out of memory\n");
return(0);
}
if (ns->prefix != NULL) { if (ns->prefix != NULL) {
attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname, attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, fullname,
ns->prefix, BAD_CAST "xmlns"); ns->prefix, BAD_CAST "xmlns");
if ((attrDecl == NULL) && (doc->extSubset != NULL)) if ((attrDecl == NULL) && (doc->extSubset != NULL))
attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname, attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, fullname,
ns->prefix, BAD_CAST "xmlns"); ns->prefix, BAD_CAST "xmlns");
} else { } else {
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname,
BAD_CAST "xmlns"); BAD_CAST "xmlns");
if ((attrDecl == NULL) && (doc->extSubset != NULL)) if ((attrDecl == NULL) && (doc->extSubset != NULL))
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname,
BAD_CAST "xmlns"); BAD_CAST "xmlns");
} }
if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
} }
if (attrDecl == NULL) { if (attrDecl == NULL) {
if (ns->prefix != NULL) { if (ns->prefix != NULL) {
...@@ -4766,21 +4712,18 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child, ...@@ -4766,21 +4712,18 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
goto fail; goto fail;
case XML_ELEMENT_NODE: case XML_ELEMENT_NODE:
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
xmlChar *QName; xmlChar fn[50];
int len; xmlChar *fullname;
len = xmlStrlen(cur->name) + fullname = xmlBuildQName(cur->name,
xmlStrlen(cur->ns->prefix) + 2; cur->ns->prefix, fn, 50);
QName = xmlMalloc(len); if (fullname == NULL) {
if (QName == NULL) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
snprintf((char *) QName, len, "%s:%s", ret = xmlRegExecPushString(exec, fullname, NULL);
(char *)cur->ns->prefix, if ((fullname != fn) && (fullname != cur->name))
(char *)cur->name); xmlFree(fullname);
ret = xmlRegExecPushString(exec, QName, NULL);
xmlFree(QName);
} else { } else {
ret = xmlRegExecPushString(exec, cur->name, NULL); ret = xmlRegExecPushString(exec, cur->name, NULL);
} }
...@@ -5524,18 +5467,23 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, ...@@ -5524,18 +5467,23 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if (child->type == XML_ELEMENT_NODE) { if (child->type == XML_ELEMENT_NODE) {
name = child->name; name = child->name;
if ((child->ns != NULL) && (child->ns->prefix != NULL)) { if ((child->ns != NULL) && (child->ns->prefix != NULL)) {
xmlChar qname[500]; xmlChar fn[50];
snprintf((char *) qname, sizeof(qname), "%s:%s", xmlChar *fullname;
child->ns->prefix, child->name);
qname[sizeof(qname) - 1] = 0; fullname = xmlBuildQName(child->name, child->ns->prefix,
fn, 50);
if (fullname == NULL)
return(0);
cont = elemDecl->content; cont = elemDecl->content;
while (cont != NULL) { while (cont != NULL) {
if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) { if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
if (xmlStrEqual(cont->name, qname)) break; if (xmlStrEqual(cont->name, fullname))
break;
} else if ((cont->type == XML_ELEMENT_CONTENT_OR) && } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
(cont->c1 != NULL) && (cont->c1 != NULL) &&
(cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){ (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
if (xmlStrEqual(cont->c1->name, qname)) break; if (xmlStrEqual(cont->c1->name, fullname))
break;
} else if ((cont->type != XML_ELEMENT_CONTENT_OR) || } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
(cont->c1 == NULL) || (cont->c1 == NULL) ||
(cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){ (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
...@@ -5546,6 +5494,8 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, ...@@ -5546,6 +5494,8 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
} }
cont = cont->c2; cont = cont->c2;
} }
if ((fullname != fn) && (fullname != child->name))
xmlFree(fullname);
if (cont != NULL) if (cont != NULL)
goto child_ok; goto child_ok