1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-12-25 23:21:26 +03:00

fixing a number of issues raised by xml:id but more generally related to

* SAX2.c tree.c valid.c: fixing a number of issues raised by xml:id
  but more generally related to attributes and ID handling, fixes
  #314358 among other things
Daniel
This commit is contained in:
Daniel Veillard 2005-09-03 13:28:24 +00:00
parent 2e7598cb06
commit 54f9a4f508
4 changed files with 107 additions and 62 deletions

View File

@ -1,3 +1,9 @@
Sat Sep 3 15:26:31 CEST 2005 Daniel Veillard <daniel@veillard.com>
* SAX2.c tree.c valid.c: fixing a number of issues raised by xml:id
but more generally related to attributes and ID handling, fixes
#314358 among other things
Fri Sep 2 14:26:43 CEST 2005 Daniel Veillard <daniel@veillard.com>
* encoding.c parserInternals.c: avoid passing a char[] as snprintf

31
SAX2.c
View File

@ -1316,11 +1316,7 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
* when validating, the ID registration is done at the attribute
* validation level. Otherwise we have to do specific handling here.
*/
if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
else if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
/*
* Add the xml:id value
*
@ -1332,7 +1328,10 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
(const char *) value, NULL);
}
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
}
} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
}
error:
@ -2047,16 +2046,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
* when validating, the ID registration is done at the attribute
* validation level. Otherwise we have to do specific handling here.
*/
if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
/* might be worth duplicate entry points and not copy */
if (dup == NULL)
dup = xmlStrndup(value, valueend - value);
xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
} else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
if (dup == NULL)
dup = xmlStrndup(value, valueend - value);
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
} else if ((prefix == ctxt->str_xml) &&
if ((prefix == ctxt->str_xml) &&
(localname[0] == 'i') && (localname[1] == 'd') &&
(localname[2] == 0)) {
/*
@ -2074,6 +2064,15 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
}
#endif
xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
/* might be worth duplicate entry points and not copy */
if (dup == NULL)
dup = xmlStrndup(value, valueend - value);
xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
} else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
if (dup == NULL)
dup = xmlStrndup(value, valueend - value);
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
}
}
if (dup != NULL)

122
tree.c
View File

@ -297,6 +297,7 @@ xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
*
* returns NULL if it is not a Qualified Name, otherwise, update len
* with the lenght in byte of the prefix and return a pointer
* to the start of the name without the prefix
*/
const xmlChar *
@ -1723,80 +1724,87 @@ xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine)
}
#endif /* LIBXML_TREE_ENABLED */
static xmlAttrPtr xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
const xmlChar *name, const xmlChar *value, int eatname) {
static xmlAttrPtr
xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
const xmlChar * name, const xmlChar * value,
int eatname)
{
xmlAttrPtr cur;
xmlDocPtr doc = NULL;
if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) {
if (eatname == 1)
xmlFree((xmlChar *) name);
return(NULL);
}
if (eatname == 1)
xmlFree((xmlChar *) name);
return (NULL);
}
/*
* Allocate a new property and fill the fields.
*/
cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
if (cur == NULL) {
if (eatname == 1)
xmlFree((xmlChar *) name);
xmlTreeErrMemory("building attribute");
return(NULL);
if (eatname == 1)
xmlFree((xmlChar *) name);
xmlTreeErrMemory("building attribute");
return (NULL);
}
memset(cur, 0, sizeof(xmlAttr));
cur->type = XML_ATTRIBUTE_NODE;
cur->parent = node;
if (node != NULL) {
doc = node->doc;
cur->doc = doc;
doc = node->doc;
cur->doc = doc;
}
cur->ns = ns;
cur->ns = ns;
if (eatname == 0) {
if ((doc != NULL) && (doc->dict != NULL))
cur->name = (xmlChar *) xmlDictLookup(doc->dict, name, -1);
else
cur->name = xmlStrdup(name);
} else
cur->name = name;
if (eatname == 0) {
if ((doc != NULL) && (doc->dict != NULL))
cur->name = (xmlChar *) xmlDictLookup(doc->dict, name, -1);
else
cur->name = xmlStrdup(name);
} else
cur->name = name;
if (value != NULL) {
xmlChar *buffer;
xmlNodePtr tmp;
xmlChar *buffer;
xmlNodePtr tmp;
buffer = xmlEncodeEntitiesReentrant(doc, value);
cur->children = xmlStringGetNodeList(doc, buffer);
cur->last = NULL;
tmp = cur->children;
while (tmp != NULL) {
tmp->parent = (xmlNodePtr) cur;
if (tmp->next == NULL)
cur->last = tmp;
tmp = tmp->next;
}
xmlFree(buffer);
buffer = xmlEncodeEntitiesReentrant(doc, value);
cur->children = xmlStringGetNodeList(doc, buffer);
cur->last = NULL;
tmp = cur->children;
while (tmp != NULL) {
tmp->parent = (xmlNodePtr) cur;
if (tmp->next == NULL)
cur->last = tmp;
tmp = tmp->next;
}
xmlFree(buffer);
}
/*
* Add it at the end to preserve parsing order ...
*/
if (node != NULL) {
if (node->properties == NULL) {
node->properties = cur;
} else {
xmlAttrPtr prev = node->properties;
if (node->properties == NULL) {
node->properties = cur;
} else {
xmlAttrPtr prev = node->properties;
while (prev->next != NULL) prev = prev->next;
prev->next = cur;
cur->prev = prev;
}
while (prev->next != NULL)
prev = prev->next;
prev->next = cur;
cur->prev = prev;
}
}
if (xmlIsID((node == NULL) ? NULL : node->doc, node, cur) == 1)
xmlAddID(NULL, node->doc, value, cur);
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
xmlRegisterNodeDefaultValue((xmlNodePtr) cur);
return (cur);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
@ -6316,16 +6324,36 @@ xmlAttrPtr
xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
xmlAttrPtr prop;
xmlDocPtr doc;
int len;
const xmlChar *nqname;
if ((node == NULL) || (name == NULL) || (node->type != XML_ELEMENT_NODE))
return(NULL);
/*
* handle QNames
*/
nqname = xmlSplitQName3(name, &len);
if (nqname != NULL) {
xmlNsPtr ns;
xmlChar *prefix = xmlStrndup(name, len);
ns = xmlSearchNs(node->doc, node, prefix);
if (prefix != NULL)
xmlFree(prefix);
if (ns != NULL)
return(xmlSetNsProp(node, ns, nqname, value));
}
doc = node->doc;
prop = node->properties;
while (prop != NULL) {
if ((xmlStrEqual(prop->name, name)) &&
(prop->ns == NULL)){
xmlNodePtr oldprop = prop->children;
int id = xmlIsID(node->doc, node, prop);
if (id == 1)
xmlRemoveID(node->doc, prop);
prop->children = NULL;
prop->last = NULL;
if (value != NULL) {
@ -6348,6 +6376,8 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
}
if (oldprop != NULL)
xmlFreeNodeList(oldprop);
if (id)
xmlAddID(NULL, node->doc, value, prop);
return(prop);
}
prop = prop->next;
@ -6390,6 +6420,10 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
*/
if ((xmlStrEqual(prop->name, name)) &&
(prop->ns != NULL) && (xmlStrEqual(prop->ns->href, ns->href))) {
int id = xmlIsID(node->doc, node, prop);
if (id == 1)
xmlRemoveID(node->doc, prop);
if (prop->children != NULL)
xmlFreeNodeList(prop->children);
prop->children = NULL;
@ -6411,6 +6445,8 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
}
xmlFree(buffer);
}
if (id)
xmlAddID(NULL, node->doc, value, prop);
return(prop);
}
prop = prop->next;

View File

@ -2703,8 +2703,12 @@ xmlFreeIDTable(xmlIDTablePtr table) {
*/
int
xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
if ((attr == NULL) || (attr->name == NULL)) return(0);
if ((attr->ns != NULL) && (attr->ns->prefix != NULL) &&
(!strcmp((char *) attr->name, "id")) &&
(!strcmp((char *) attr->ns->prefix, "xml")))
return(1);
if (doc == NULL) return(0);
if (attr == NULL) return(0);
if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
return(0);
} else if (doc->type == XML_HTML_DOCUMENT_NODE) {