mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2024-12-24 21:33:51 +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:
parent
2e7598cb06
commit
54f9a4f508
@ -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
31
SAX2.c
@ -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)
|
||||
|
126
tree.c
126
tree.c
@ -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;
|
||||
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;
|
||||
|
6
valid.c
6
valid.c
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user