1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-28 23:14:57 +03:00

tree: Report malloc failures in attribute setters

This commit is contained in:
Nick Wellnhofer
2024-03-18 14:14:00 +01:00
parent 3bdd0d7b30
commit 3f05508a53
3 changed files with 136 additions and 65 deletions

View File

@@ -109,9 +109,9 @@ typedef enum {
OP_XML_NODE_IS_TEXT, OP_XML_NODE_IS_TEXT,
OP_XML_NODE_GET_ATTR_VALUE, OP_XML_NODE_GET_ATTR_VALUE,
OP_XML_NODE_GET_LANG, OP_XML_NODE_GET_LANG,
OP_XML_NODE_SET_LANG, /* TODO */ OP_XML_NODE_SET_LANG,
OP_XML_NODE_GET_SPACE_PRESERVE, OP_XML_NODE_GET_SPACE_PRESERVE,
OP_XML_NODE_SET_SPACE_PRESERVE, /* TODO */ OP_XML_NODE_SET_SPACE_PRESERVE,
OP_XML_NODE_GET_BASE, OP_XML_NODE_GET_BASE,
OP_XML_NODE_GET_BASE_SAFE, OP_XML_NODE_GET_BASE_SAFE,
OP_XML_NODE_SET_BASE, OP_XML_NODE_SET_BASE,
@@ -1736,12 +1736,60 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
break; break;
} }
case OP_XML_NODE_GET_SPACE_PRESERVE: case OP_XML_NODE_SET_LANG: {
incIntIdx(); xmlNodePtr node;
startOp("xmlNodeGetSpacePreserve"); xmlAttrPtr attr;
setInt(0, xmlNodeGetSpacePreserve(getNode(0))); int res;
startOp("xmlNodeSetLang");
node = getNode(0);
attr = xmlHasNsProp(
node,
BAD_CAST "lang",
XML_XML_NAMESPACE);
xmlFuzzResetMallocFailed();
removeChildren((xmlNodePtr) attr, 0);
res = xmlNodeSetLang(
node,
getStr(0));
oomReport = (res < 0);
endOp(); endOp();
break; break;
}
case OP_XML_NODE_GET_SPACE_PRESERVE: {
int res;
incIntIdx();
startOp("xmlNodeGetSpacePreserve");
res = xmlNodeGetSpacePreserve(getNode(0));
if (res >= 0)
oomReport = 0;
setInt(0, res);
endOp();
break;
}
case OP_XML_NODE_SET_SPACE_PRESERVE: {
xmlNodePtr node;
xmlAttrPtr attr;
int res;
startOp("xmlNodeSetSpacePreserve");
node = getNode(0);
attr = xmlHasNsProp(
node,
BAD_CAST "space",
XML_XML_NAMESPACE);
xmlFuzzResetMallocFailed();
removeChildren((xmlNodePtr) attr, 0);
res = xmlNodeSetSpacePreserve(
node,
getInt(0));
oomReport = (res < 0);
endOp();
break;
}
case OP_XML_NODE_GET_BASE: { case OP_XML_NODE_GET_BASE: {
xmlChar *base; xmlChar *base;
@@ -1897,11 +1945,9 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
break; break;
} }
#if 0
/* TODO: Split QName */
case OP_XML_SET_PROP: { case OP_XML_SET_PROP: {
xmlNodePtr node; xmlNodePtr node;
xmlAttrPtr attr; xmlAttrPtr oldAttr, attr;
const xmlChar *name, *value; const xmlChar *name, *value;
startOp("xmlSetProp"); startOp("xmlSetProp");
@@ -1909,16 +1955,18 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
node = getNode(1); node = getNode(1);
name = getStr(0); name = getStr(0);
value = getStr(1); value = getStr(1);
attr = xmlHasProp(node, name); oldAttr = xmlHasProp(node, name);
if (attr != NULL) xmlFuzzResetMallocFailed();
removeChildren((xmlNodePtr) attr, 0); if (oldAttr != NULL)
setNode(0, (xmlNodePtr) xmlSetProp( removeChildren((xmlNodePtr) oldAttr, 0);
node, attr = xmlSetProp(node, name, value);
name, oomReport =
value)); (node != NULL && node->type == XML_ELEMENT_NODE &&
name != NULL &&
attr == NULL);
setNode(0, (xmlNodePtr) attr);
break; break;
} }
#endif
case OP_XML_SET_NS_PROP: { case OP_XML_SET_NS_PROP: {
xmlNodePtr node; xmlNodePtr node;

View File

@@ -1125,10 +1125,10 @@ XMLPUBFUN xmlChar *
XMLPUBFUN int XMLPUBFUN int
xmlNodeGetSpacePreserve (const xmlNode *cur); xmlNodeGetSpacePreserve (const xmlNode *cur);
#ifdef LIBXML_TREE_ENABLED #ifdef LIBXML_TREE_ENABLED
XMLPUBFUN void XMLPUBFUN int
xmlNodeSetLang (xmlNodePtr cur, xmlNodeSetLang (xmlNodePtr cur,
const xmlChar *lang); const xmlChar *lang);
XMLPUBFUN void XMLPUBFUN int
xmlNodeSetSpacePreserve (xmlNodePtr cur, xmlNodeSetSpacePreserve (xmlNodePtr cur,
int val); int val);
#endif /* LIBXML_TREE_ENABLED */ #endif /* LIBXML_TREE_ENABLED */

115
tree.c
View File

@@ -5052,23 +5052,27 @@ xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
* *
* Set the language of a node, i.e. the values of the xml:lang * Set the language of a node, i.e. the values of the xml:lang
* attribute. * attribute.
*
* Return 0 on success, 1 if arguments are invalid, -1 if a
* memory allocation failed.
*/ */
void int
xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) { xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
xmlNsPtr ns; xmlNsPtr ns;
xmlAttrPtr attr;
int res;
if (cur == NULL) return; if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
switch(cur->type) { return(1);
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE: res = xmlSearchNsByHrefSafe(cur, XML_XML_NAMESPACE, &ns);
break; if (res != 0)
default: return(res);
return; attr = xmlSetNsProp(cur, ns, BAD_CAST "lang", lang);
} if (attr == NULL)
xmlSearchNsByHrefSafe(cur, XML_XML_NAMESPACE, &ns); return(-1);
if (ns == NULL)
return; return(0);
xmlSetNsProp(cur, ns, BAD_CAST "lang", lang);
} }
#endif /* LIBXML_TREE_ENABLED */ #endif /* LIBXML_TREE_ENABLED */
@@ -5085,15 +5089,22 @@ xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
xmlChar * xmlChar *
xmlNodeGetLang(const xmlNode *cur) { xmlNodeGetLang(const xmlNode *cur) {
xmlChar *lang; xmlChar *lang;
int res;
if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
return(NULL); return(NULL);
while (cur != NULL) { while (cur != NULL) {
lang = xmlGetNsProp(cur, BAD_CAST "lang", XML_XML_NAMESPACE); res = xmlNodeGetAttrValue(cur, BAD_CAST "lang", XML_XML_NAMESPACE,
&lang);
if (res < 0)
return(NULL);
if (lang != NULL) if (lang != NULL)
return(lang); return(lang);
cur = cur->parent; cur = cur->parent;
} }
return(NULL); return(NULL);
} }
@@ -5106,30 +5117,34 @@ xmlNodeGetLang(const xmlNode *cur) {
* *
* Set (or reset) the space preserving behaviour of a node, i.e. the * Set (or reset) the space preserving behaviour of a node, i.e. the
* value of the xml:space attribute. * value of the xml:space attribute.
*
* Return 0 on success, 1 if arguments are invalid, -1 if a
* memory allocation failed.
*/ */
void int
xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) { xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
xmlNsPtr ns; xmlNsPtr ns;
xmlAttrPtr attr;
const char *string;
int res;
if (cur == NULL) return; if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
switch(cur->type) { return(1);
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE: res = xmlSearchNsByHrefSafe(cur, XML_XML_NAMESPACE, &ns);
break; if (res != 0)
default: return(res);
return;
} if (val == 0)
xmlSearchNsByHrefSafe(cur, XML_XML_NAMESPACE, &ns); string = "default";
if (ns == NULL) else
return; string = "preserve";
switch (val) {
case 0: attr = xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST string);
xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "default"); if (attr == NULL)
break; return(-1);
case 1:
xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "preserve"); return(0);
break;
}
} }
#endif /* LIBXML_TREE_ENABLED */ #endif /* LIBXML_TREE_ENABLED */
@@ -5146,11 +5161,16 @@ xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
int int
xmlNodeGetSpacePreserve(const xmlNode *cur) { xmlNodeGetSpacePreserve(const xmlNode *cur) {
xmlChar *space; xmlChar *space;
int res;
if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE)) if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
return(-1); return(-1);
while (cur != NULL) { while (cur != NULL) {
space = xmlGetNsProp(cur, BAD_CAST "space", XML_XML_NAMESPACE); res = xmlNodeGetAttrValue(cur, BAD_CAST "space", XML_XML_NAMESPACE,
&space);
if (res < 0)
return(-1);
if (space != NULL) { if (space != NULL) {
if (xmlStrEqual(space, BAD_CAST "preserve")) { if (xmlStrEqual(space, BAD_CAST "preserve")) {
xmlFree(space); xmlFree(space);
@@ -5162,8 +5182,10 @@ xmlNodeGetSpacePreserve(const xmlNode *cur) {
} }
xmlFree(space); xmlFree(space);
} }
cur = cur->parent; cur = cur->parent;
} }
return(-1); return(-1);
} }
@@ -6790,8 +6812,10 @@ xmlUnsetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name) {
*/ */
xmlAttrPtr xmlAttrPtr
xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) { xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
int len; xmlNsPtr ns = NULL;
const xmlChar *nqname; const xmlChar *localname;
xmlChar *prefix;
int res;
if ((node == NULL) || (name == NULL) || (node->type != XML_ELEMENT_NODE)) if ((node == NULL) || (name == NULL) || (node->type != XML_ELEMENT_NODE))
return(NULL); return(NULL);
@@ -6799,20 +6823,19 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
/* /*
* handle QNames * handle QNames
*/ */
nqname = xmlSplitQName3(name, &len); localname = xmlSplitQName4(name, &prefix);
if (nqname != NULL) { if (localname == NULL)
xmlNsPtr ns; return(NULL);
xmlChar *prefix = xmlStrndup(name, len);
int res;
if (prefix != NULL) {
res = xmlSearchNsSafe(node, prefix, &ns); res = xmlSearchNsSafe(node, prefix, &ns);
xmlFree(prefix);
if (res < 0) if (res < 0)
return(NULL); return(NULL);
if (prefix != NULL) if (ns != NULL)
xmlFree(prefix); return(xmlSetNsProp(node, ns, localname, value));
if (ns != NULL)
return(xmlSetNsProp(node, ns, nqname, value));
} }
return(xmlSetNsProp(node, NULL, name, value)); return(xmlSetNsProp(node, NULL, name, value));
} }