mirror of
				https://gitlab.gnome.org/GNOME/libxml2.git
				synced 2025-10-31 21:50:33 +03:00 
			
		
		
		
	tree: Report malloc failures in attribute setters
This commit is contained in:
		
							
								
								
									
										82
									
								
								fuzz/api.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								fuzz/api.c
									
									
									
									
									
								
							| @@ -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; | ||||||
|   | |||||||
| @@ -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 */ | ||||||
|   | |||||||
							
								
								
									
										113
									
								
								tree.c
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								tree.c
									
									
									
									
									
								
							| @@ -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) |  | ||||||
| 	    xmlFree(prefix); |  | ||||||
|         if (ns != NULL) |         if (ns != NULL) | ||||||
| 	    return(xmlSetNsProp(node, ns, nqname, value)); |             return(xmlSetNsProp(node, ns, localname, value)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return(xmlSetNsProp(node, NULL, name, value)); |     return(xmlSetNsProp(node, NULL, name, value)); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user