153aa9179Sopenharmony_ciFrom b1319c902f6e44d08f8cb33f1fc28847f2bc8aeb Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de>
353aa9179Sopenharmony_ciDate: Sat, 18 Mar 2023 16:34:01 +0100
453aa9179Sopenharmony_ciSubject: [PATCH] malloc-fail: Check for malloc failures when creating XPath
553aa9179Sopenharmony_ci strings
653aa9179Sopenharmony_ci
753aa9179Sopenharmony_ciPrevent null derefs.
853aa9179Sopenharmony_ci
953aa9179Sopenharmony_ciFound by OSS-Fuzz, see #344.
1053aa9179Sopenharmony_ci
1153aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/b1319c902f6e44d08f8cb33f1fc28847f2bc8aeb
1253aa9179Sopenharmony_ciConflict:xpath.c
1353aa9179Sopenharmony_ci
1453aa9179Sopenharmony_ci---
1553aa9179Sopenharmony_ci xpath.c | 111 +++++++++++++++++++++-----------------------------------
1653aa9179Sopenharmony_ci 1 file changed, 42 insertions(+), 69 deletions(-)
1753aa9179Sopenharmony_ci
1853aa9179Sopenharmony_cidiff --git a/xpath.c b/xpath.c
1953aa9179Sopenharmony_ciindex 005a6a2..2eceb5b 100644
2053aa9179Sopenharmony_ci--- a/xpath.c
2153aa9179Sopenharmony_ci+++ b/xpath.c
2253aa9179Sopenharmony_ci@@ -2476,17 +2476,17 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
2353aa9179Sopenharmony_ci }
2453aa9179Sopenharmony_ci 
2553aa9179Sopenharmony_ci /**
2653aa9179Sopenharmony_ci- * xmlXPathCacheNewCString:
2753aa9179Sopenharmony_ci+ * xmlXPathCacheNewString:
2853aa9179Sopenharmony_ci  * @ctxt: the XPath context
2953aa9179Sopenharmony_ci- * @val:  the char * value
3053aa9179Sopenharmony_ci+ * @val:  the xmlChar * value
3153aa9179Sopenharmony_ci  *
3253aa9179Sopenharmony_ci- * This is the cached version of xmlXPathNewCString().
3353aa9179Sopenharmony_ci+ * This is the cached version of xmlXPathNewString().
3453aa9179Sopenharmony_ci  * Acquire an xmlXPathObjectPtr of type string and of value @val
3553aa9179Sopenharmony_ci  *
3653aa9179Sopenharmony_ci  * Returns the created or reused object.
3753aa9179Sopenharmony_ci  */
3853aa9179Sopenharmony_ci static xmlXPathObjectPtr
3953aa9179Sopenharmony_ci-xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
4053aa9179Sopenharmony_ci+xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
4153aa9179Sopenharmony_ci {
4253aa9179Sopenharmony_ci     if ((ctxt != NULL) && (ctxt->cache)) {
4353aa9179Sopenharmony_ci 	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
4453aa9179Sopenharmony_ci@@ -2495,12 +2495,20 @@ xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
4553aa9179Sopenharmony_ci 	    (cache->stringObjs->number != 0))
4653aa9179Sopenharmony_ci 	{
4753aa9179Sopenharmony_ci 	    xmlXPathObjectPtr ret;
4853aa9179Sopenharmony_ci+            xmlChar *copy;
4953aa9179Sopenharmony_ci+
5053aa9179Sopenharmony_ci+            if (val == NULL)
5153aa9179Sopenharmony_ci+                val = BAD_CAST "";
5253aa9179Sopenharmony_ci+            copy = xmlStrdup(val);
5353aa9179Sopenharmony_ci+            if (copy == NULL) {
5453aa9179Sopenharmony_ci+                xmlXPathErrMemory(ctxt, NULL);
5553aa9179Sopenharmony_ci+                return(NULL);
5653aa9179Sopenharmony_ci+            }
5753aa9179Sopenharmony_ci 
5853aa9179Sopenharmony_ci 	    ret = (xmlXPathObjectPtr)
5953aa9179Sopenharmony_ci 		cache->stringObjs->items[--cache->stringObjs->number];
6053aa9179Sopenharmony_ci-
6153aa9179Sopenharmony_ci 	    ret->type = XPATH_STRING;
6253aa9179Sopenharmony_ci-	    ret->stringval = xmlStrdup(BAD_CAST val);
6353aa9179Sopenharmony_ci+            ret->stringval = copy;
6453aa9179Sopenharmony_ci #ifdef XP_DEBUG_OBJ_USAGE
6553aa9179Sopenharmony_ci 	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
6653aa9179Sopenharmony_ci #endif
6753aa9179Sopenharmony_ci@@ -2509,73 +2517,44 @@ xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
6853aa9179Sopenharmony_ci 	    (cache->miscObjs->number != 0))
6953aa9179Sopenharmony_ci 	{
7053aa9179Sopenharmony_ci 	    xmlXPathObjectPtr ret;
7153aa9179Sopenharmony_ci+            xmlChar *copy;
7253aa9179Sopenharmony_ci+
7353aa9179Sopenharmony_ci+            if (val == NULL)
7453aa9179Sopenharmony_ci+                val = BAD_CAST "";
7553aa9179Sopenharmony_ci+            copy = xmlStrdup(val);
7653aa9179Sopenharmony_ci+            if (copy == NULL) {
7753aa9179Sopenharmony_ci+                xmlXPathErrMemory(ctxt, NULL);
7853aa9179Sopenharmony_ci+                return(NULL);
7953aa9179Sopenharmony_ci+            }
8053aa9179Sopenharmony_ci 
8153aa9179Sopenharmony_ci 	    ret = (xmlXPathObjectPtr)
8253aa9179Sopenharmony_ci 		cache->miscObjs->items[--cache->miscObjs->number];
8353aa9179Sopenharmony_ci 
8453aa9179Sopenharmony_ci 	    ret->type = XPATH_STRING;
8553aa9179Sopenharmony_ci-	    ret->stringval = xmlStrdup(BAD_CAST val);
8653aa9179Sopenharmony_ci+            ret->stringval = copy;
8753aa9179Sopenharmony_ci #ifdef XP_DEBUG_OBJ_USAGE
8853aa9179Sopenharmony_ci 	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
8953aa9179Sopenharmony_ci #endif
9053aa9179Sopenharmony_ci 	    return(ret);
9153aa9179Sopenharmony_ci 	}
9253aa9179Sopenharmony_ci     }
9353aa9179Sopenharmony_ci-    return(xmlXPathNewCString(val));
9453aa9179Sopenharmony_ci+    return(xmlXPathNewString(val));
9553aa9179Sopenharmony_ci }
9653aa9179Sopenharmony_ci 
9753aa9179Sopenharmony_ci /**
9853aa9179Sopenharmony_ci- * xmlXPathCacheNewString:
9953aa9179Sopenharmony_ci+ * xmlXPathCacheNewCString:
10053aa9179Sopenharmony_ci  * @ctxt: the XPath context
10153aa9179Sopenharmony_ci- * @val:  the xmlChar * value
10253aa9179Sopenharmony_ci+ * @val:  the char * value
10353aa9179Sopenharmony_ci  *
10453aa9179Sopenharmony_ci- * This is the cached version of xmlXPathNewString().
10553aa9179Sopenharmony_ci+ * This is the cached version of xmlXPathNewCString().
10653aa9179Sopenharmony_ci  * Acquire an xmlXPathObjectPtr of type string and of value @val
10753aa9179Sopenharmony_ci  *
10853aa9179Sopenharmony_ci  * Returns the created or reused object.
10953aa9179Sopenharmony_ci  */
11053aa9179Sopenharmony_ci static xmlXPathObjectPtr
11153aa9179Sopenharmony_ci-xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
11253aa9179Sopenharmony_ci+xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
11353aa9179Sopenharmony_ci {
11453aa9179Sopenharmony_ci-    if ((ctxt != NULL) && (ctxt->cache)) {
11553aa9179Sopenharmony_ci-	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
11653aa9179Sopenharmony_ci-
11753aa9179Sopenharmony_ci-	if ((cache->stringObjs != NULL) &&
11853aa9179Sopenharmony_ci-	    (cache->stringObjs->number != 0))
11953aa9179Sopenharmony_ci-	{
12053aa9179Sopenharmony_ci-	    xmlXPathObjectPtr ret;
12153aa9179Sopenharmony_ci-
12253aa9179Sopenharmony_ci-	    ret = (xmlXPathObjectPtr)
12353aa9179Sopenharmony_ci-		cache->stringObjs->items[--cache->stringObjs->number];
12453aa9179Sopenharmony_ci-	    ret->type = XPATH_STRING;
12553aa9179Sopenharmony_ci-	    if (val != NULL)
12653aa9179Sopenharmony_ci-		ret->stringval = xmlStrdup(val);
12753aa9179Sopenharmony_ci-	    else
12853aa9179Sopenharmony_ci-		ret->stringval = xmlStrdup((const xmlChar *)"");
12953aa9179Sopenharmony_ci-#ifdef XP_DEBUG_OBJ_USAGE
13053aa9179Sopenharmony_ci-	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
13153aa9179Sopenharmony_ci-#endif
13253aa9179Sopenharmony_ci-	    return(ret);
13353aa9179Sopenharmony_ci-	} else if ((cache->miscObjs != NULL) &&
13453aa9179Sopenharmony_ci-	    (cache->miscObjs->number != 0))
13553aa9179Sopenharmony_ci-	{
13653aa9179Sopenharmony_ci-	    xmlXPathObjectPtr ret;
13753aa9179Sopenharmony_ci-
13853aa9179Sopenharmony_ci-	    ret = (xmlXPathObjectPtr)
13953aa9179Sopenharmony_ci-		cache->miscObjs->items[--cache->miscObjs->number];
14053aa9179Sopenharmony_ci-
14153aa9179Sopenharmony_ci-	    ret->type = XPATH_STRING;
14253aa9179Sopenharmony_ci-	    if (val != NULL)
14353aa9179Sopenharmony_ci-		ret->stringval = xmlStrdup(val);
14453aa9179Sopenharmony_ci-	    else
14553aa9179Sopenharmony_ci-		ret->stringval = xmlStrdup((const xmlChar *)"");
14653aa9179Sopenharmony_ci-#ifdef XP_DEBUG_OBJ_USAGE
14753aa9179Sopenharmony_ci-	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
14853aa9179Sopenharmony_ci-#endif
14953aa9179Sopenharmony_ci-	    return(ret);
15053aa9179Sopenharmony_ci-	}
15153aa9179Sopenharmony_ci-    }
15253aa9179Sopenharmony_ci-    return(xmlXPathNewString(val));
15353aa9179Sopenharmony_ci+    return xmlXPathCacheNewString(ctxt, BAD_CAST val);
15453aa9179Sopenharmony_ci }
15553aa9179Sopenharmony_ci 
15653aa9179Sopenharmony_ci /**
15753aa9179Sopenharmony_ci@@ -5291,10 +5270,13 @@ xmlXPathNewString(const xmlChar *val) {
15853aa9179Sopenharmony_ci     }
15953aa9179Sopenharmony_ci     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
16053aa9179Sopenharmony_ci     ret->type = XPATH_STRING;
16153aa9179Sopenharmony_ci-    if (val != NULL)
16253aa9179Sopenharmony_ci-	ret->stringval = xmlStrdup(val);
16353aa9179Sopenharmony_ci-    else
16453aa9179Sopenharmony_ci-	ret->stringval = xmlStrdup((const xmlChar *)"");
16553aa9179Sopenharmony_ci+    if (val == NULL)
16653aa9179Sopenharmony_ci+        val = BAD_CAST "";
16753aa9179Sopenharmony_ci+    ret->stringval = xmlStrdup(val);
16853aa9179Sopenharmony_ci+    if (ret->stringval == NULL) {
16953aa9179Sopenharmony_ci+        xmlFree(ret);
17053aa9179Sopenharmony_ci+        return(NULL);
17153aa9179Sopenharmony_ci+    }
17253aa9179Sopenharmony_ci #ifdef XP_DEBUG_OBJ_USAGE
17353aa9179Sopenharmony_ci     xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
17453aa9179Sopenharmony_ci #endif
17553aa9179Sopenharmony_ci@@ -5340,20 +5322,7 @@ xmlXPathWrapString (xmlChar *val) {
17653aa9179Sopenharmony_ci  */
17753aa9179Sopenharmony_ci xmlXPathObjectPtr
17853aa9179Sopenharmony_ci xmlXPathNewCString(const char *val) {
17953aa9179Sopenharmony_ci-    xmlXPathObjectPtr ret;
18053aa9179Sopenharmony_ci-
18153aa9179Sopenharmony_ci-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
18253aa9179Sopenharmony_ci-    if (ret == NULL) {
18353aa9179Sopenharmony_ci-        xmlXPathErrMemory(NULL, "creating string object\n");
18453aa9179Sopenharmony_ci-	return(NULL);
18553aa9179Sopenharmony_ci-    }
18653aa9179Sopenharmony_ci-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
18753aa9179Sopenharmony_ci-    ret->type = XPATH_STRING;
18853aa9179Sopenharmony_ci-    ret->stringval = xmlStrdup(BAD_CAST val);
18953aa9179Sopenharmony_ci-#ifdef XP_DEBUG_OBJ_USAGE
19053aa9179Sopenharmony_ci-    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
19153aa9179Sopenharmony_ci-#endif
19253aa9179Sopenharmony_ci-    return(ret);
19353aa9179Sopenharmony_ci+    return(xmlXPathNewString(BAD_CAST val));
19453aa9179Sopenharmony_ci }
19553aa9179Sopenharmony_ci 
19653aa9179Sopenharmony_ci /**
19753aa9179Sopenharmony_ci@@ -5427,6 +5396,10 @@ xmlXPathObjectCopy(xmlXPathObjectPtr val) {
19853aa9179Sopenharmony_ci 	    break;
19953aa9179Sopenharmony_ci 	case XPATH_STRING:
20053aa9179Sopenharmony_ci 	    ret->stringval = xmlStrdup(val->stringval);
20153aa9179Sopenharmony_ci+            if (ret->stringval == NULL) {
20253aa9179Sopenharmony_ci+                xmlFree(ret);
20353aa9179Sopenharmony_ci+                return(NULL);
20453aa9179Sopenharmony_ci+            }
20553aa9179Sopenharmony_ci 	    break;
20653aa9179Sopenharmony_ci 	case XPATH_XSLT_TREE:
20753aa9179Sopenharmony_ci #if 0
20853aa9179Sopenharmony_ci-- 
20953aa9179Sopenharmony_ci2.27.0
21053aa9179Sopenharmony_ci
211