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:
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>
|
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
31
SAX2.c
@ -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
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
|
* 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;
|
||||||
|
6
valid.c
6
valid.c
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user