From b1319c902f6e44d08f8cb33f1fc28847f2bc8aeb Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Sat, 18 Mar 2023 16:34:01 +0100 Subject: [PATCH] malloc-fail: Check for malloc failures when creating XPath strings Prevent null derefs. Found by OSS-Fuzz, see #344. --- xpath.c | 123 ++++++++++++++++++++++---------------------------------- 1 file changed, 48 insertions(+), 75 deletions(-) diff --git a/xpath.c b/xpath.c index 27628586..0f969950 100644 --- a/xpath.c +++ b/xpath.c @@ -2494,55 +2494,6 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val) return(xmlXPathNewNodeSet(val)); } -/** - * xmlXPathCacheNewCString: - * @ctxt: the XPath context - * @val: the char * value - * - * This is the cached version of xmlXPathNewCString(). - * Acquire an xmlXPathObjectPtr of type string and of value @val - * - * Returns the created or reused object. - */ -static xmlXPathObjectPtr -xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val) -{ - if ((ctxt != NULL) && (ctxt->cache)) { - xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache; - - if ((cache->stringObjs != NULL) && - (cache->stringObjs->number != 0)) - { - xmlXPathObjectPtr ret; - - ret = (xmlXPathObjectPtr) - cache->stringObjs->items[--cache->stringObjs->number]; - - ret->type = XPATH_STRING; - ret->stringval = xmlStrdup(BAD_CAST val); -#ifdef XP_DEBUG_OBJ_USAGE - xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING); -#endif - return(ret); - } else if ((cache->miscObjs != NULL) && - (cache->miscObjs->number != 0)) - { - xmlXPathObjectPtr ret; - - ret = (xmlXPathObjectPtr) - cache->miscObjs->items[--cache->miscObjs->number]; - - ret->type = XPATH_STRING; - ret->stringval = xmlStrdup(BAD_CAST val); -#ifdef XP_DEBUG_OBJ_USAGE - xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING); -#endif - return(ret); - } - } - return(xmlXPathNewCString(val)); -} - /** * xmlXPathCacheNewString: * @ctxt: the XPath context @@ -2563,14 +2514,20 @@ xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val) (cache->stringObjs->number != 0)) { xmlXPathObjectPtr ret; + xmlChar *copy; + + if (val == NULL) + val = BAD_CAST ""; + copy = xmlStrdup(val); + if (copy == NULL) { + xmlXPathErrMemory(ctxt, NULL); + return(NULL); + } ret = (xmlXPathObjectPtr) cache->stringObjs->items[--cache->stringObjs->number]; ret->type = XPATH_STRING; - if (val != NULL) - ret->stringval = xmlStrdup(val); - else - ret->stringval = xmlStrdup((const xmlChar *)""); + ret->stringval = copy; #ifdef XP_DEBUG_OBJ_USAGE xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING); #endif @@ -2579,15 +2536,21 @@ xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val) (cache->miscObjs->number != 0)) { xmlXPathObjectPtr ret; + xmlChar *copy; + + if (val == NULL) + val = BAD_CAST ""; + copy = xmlStrdup(val); + if (copy == NULL) { + xmlXPathErrMemory(ctxt, NULL); + return(NULL); + } ret = (xmlXPathObjectPtr) cache->miscObjs->items[--cache->miscObjs->number]; ret->type = XPATH_STRING; - if (val != NULL) - ret->stringval = xmlStrdup(val); - else - ret->stringval = xmlStrdup((const xmlChar *)""); + ret->stringval = copy; #ifdef XP_DEBUG_OBJ_USAGE xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING); #endif @@ -2597,6 +2560,22 @@ xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val) return(xmlXPathNewString(val)); } +/** + * xmlXPathCacheNewCString: + * @ctxt: the XPath context + * @val: the char * value + * + * This is the cached version of xmlXPathNewCString(). + * Acquire an xmlXPathObjectPtr of type string and of value @val + * + * Returns the created or reused object. + */ +static xmlXPathObjectPtr +xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val) +{ + return xmlXPathCacheNewString(ctxt, BAD_CAST val); +} + /** * xmlXPathCacheNewBoolean: * @ctxt: the XPath context @@ -5271,10 +5250,13 @@ xmlXPathNewString(const xmlChar *val) { } memset(ret, 0 , sizeof(xmlXPathObject)); ret->type = XPATH_STRING; - if (val != NULL) - ret->stringval = xmlStrdup(val); - else - ret->stringval = xmlStrdup((const xmlChar *)""); + if (val == NULL) + val = BAD_CAST ""; + ret->stringval = xmlStrdup(val); + if (ret->stringval == NULL) { + xmlFree(ret); + return(NULL); + } #ifdef XP_DEBUG_OBJ_USAGE xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING); #endif @@ -5320,20 +5302,7 @@ xmlXPathWrapString (xmlChar *val) { */ xmlXPathObjectPtr xmlXPathNewCString(const char *val) { - xmlXPathObjectPtr ret; - - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPathErrMemory(NULL, "creating string object\n"); - return(NULL); - } - memset(ret, 0 , sizeof(xmlXPathObject)); - ret->type = XPATH_STRING; - ret->stringval = xmlStrdup(BAD_CAST val); -#ifdef XP_DEBUG_OBJ_USAGE - xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING); -#endif - return(ret); + return(xmlXPathNewString(BAD_CAST val)); } /** @@ -5409,6 +5378,10 @@ xmlXPathObjectCopy(xmlXPathObjectPtr val) { break; case XPATH_STRING: ret->stringval = xmlStrdup(val->stringval); + if (ret->stringval == NULL) { + xmlFree(ret); + return(NULL); + } break; case XPATH_XSLT_TREE: #if 0