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> Fri Sep 2 14:26:43 CEST 2005 Daniel Veillard <daniel@veillard.com>
* encoding.c parserInternals.c: avoid passing a char[] as snprintf * 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 * when validating, the ID registration is done at the attribute
* validation level. Otherwise we have to do specific handling here. * validation level. Otherwise we have to do specific handling here.
*/ */
if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
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")) {
/* /*
* Add the xml:id value * Add the xml:id value
* *
@ -1332,7 +1328,10 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
(const char *) value, NULL); (const char *) value, NULL);
} }
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); 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: error:
@ -2047,16 +2046,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
* when validating, the ID registration is done at the attribute * when validating, the ID registration is done at the attribute
* validation level. Otherwise we have to do specific handling here. * validation level. Otherwise we have to do specific handling here.
*/ */
if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) { if ((prefix == ctxt->str_xml) &&
/* 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) &&
(localname[0] == 'i') && (localname[1] == 'd') && (localname[0] == 'i') && (localname[1] == 'd') &&
(localname[2] == 0)) { (localname[2] == 0)) {
/* /*
@ -2074,6 +2064,15 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
} }
#endif #endif
xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); 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) if (dup != NULL)

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

View File

@ -2703,8 +2703,12 @@ xmlFreeIDTable(xmlIDTablePtr table) {
*/ */
int int
xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) { 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 (doc == NULL) return(0);
if (attr == NULL) return(0);
if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) { if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
return(0); return(0);
} else if (doc->type == XML_HTML_DOCUMENT_NODE) { } else if (doc->type == XML_HTML_DOCUMENT_NODE) {