diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | SAX2.c | 31 | ||||
-rw-r--r-- | tree.c | 128 | ||||
-rw-r--r-- | valid.c | 6 |
4 files changed, 108 insertions, 63 deletions
@@ -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 @@ -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) @@ -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; + 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; - - 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); - } + 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); + } /* * 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; @@ -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) { |