From eae9291aa73907694dd3a4274d306e31217e746e Mon Sep 17 00:00:00 2001 From: Nathan Date: Wed, 10 Sep 2025 18:11:50 +0300 Subject: [PATCH] fix: Prevent infinite recursion in xmlCatalogListXMLResolve --- catalog.c | 29 +++++++++++++++++++++-------- result/catalogs/recursive | 1 + test/catalogs/recursive.script | 0 test/catalogs/recursive.sgml | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 result/catalogs/recursive create mode 100644 test/catalogs/recursive.script create mode 100644 test/catalogs/recursive.sgml Index: libxml2-2.14.5/catalog.c =================================================================== --- libxml2-2.14.5.orig/catalog.c +++ libxml2-2.14.5/catalog.c @@ -62,7 +62,7 @@ #endif static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID); -static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename); +static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename, int depth); /************************************************************************ * * @@ -2275,6 +2275,7 @@ xmlGetSGMLCatalogEntryType(const xmlChar * @file: the filepath for the catalog * @super: should this be handled as a Super Catalog in which case * parsing is not recursive + * @depth: the current depth of the catalog * * Parse an SGML catalog content and fill up the @catal hash table with * the new entries found. @@ -2283,13 +2284,19 @@ xmlGetSGMLCatalogEntryType(const xmlChar */ static int xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, - const char *file, int super) { + const char *file, int super, int depth) { const xmlChar *cur = value; xmlChar *base = NULL; int res; if ((cur == NULL) || (file == NULL)) return(-1); + + /* Check recursion depth */ + if (depth > MAX_CATAL_DEPTH) { + return(-1); + } + base = xmlStrdup((const xmlChar *) file); while ((cur != NULL) && (cur[0] != 0)) { @@ -2467,7 +2474,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, filename = xmlBuildURI(sysid, base); if (filename != NULL) { - xmlExpandCatalog(catal, (const char *)filename); + xmlExpandCatalog(catal, (const char *)filename, depth); xmlFree(filename); } } @@ -2617,7 +2624,7 @@ xmlLoadSGMLSuperCatalog(const char *file return(NULL); } - ret = xmlParseSGMLCatalog(catal, content, filename, 1); + ret = xmlParseSGMLCatalog(catal, content, filename, 1, 0); xmlFree(content); if (ret < 0) { xmlFreeCatalog(catal); @@ -2663,7 +2670,7 @@ xmlLoadACatalog(const char *filename) xmlFree(content); return(NULL); } - ret = xmlParseSGMLCatalog(catal, content, filename, 0); + ret = xmlParseSGMLCatalog(catal, content, filename, 0, 0); if (ret < 0) { xmlFreeCatalog(catal); xmlFree(content); @@ -2686,6 +2693,7 @@ xmlLoadACatalog(const char *filename) * xmlExpandCatalog: * @catal: a catalog * @filename: a file path + * @depth: the current depth of the catalog * * Load the catalog and expand the existing catal structure. * This can be either an XML Catalog or an SGML Catalog @@ -2693,13 +2701,17 @@ xmlLoadACatalog(const char *filename) * Returns 0 in case of success, -1 in case of error */ static int -xmlExpandCatalog(xmlCatalogPtr catal, const char *filename) +xmlExpandCatalog(xmlCatalogPtr catal, const char *filename, int depth) { int ret; if ((catal == NULL) || (filename == NULL)) return(-1); + /* Check recursion depth */ + if (depth > MAX_CATAL_DEPTH) { + return(-1); + } if (catal->type == XML_SGML_CATALOG_TYPE) { xmlChar *content; @@ -2708,7 +2720,7 @@ xmlExpandCatalog(xmlCatalogPtr catal, co if (content == NULL) return(-1); - ret = xmlParseSGMLCatalog(catal, content, filename, 0); + ret = xmlParseSGMLCatalog(catal, content, filename, 0, depth + 1); if (ret < 0) { xmlFree(content); return(-1); @@ -3142,7 +3154,7 @@ xmlLoadCatalog(const char *filename) return(0); } - ret = xmlExpandCatalog(xmlDefaultCatalog, filename); + ret = xmlExpandCatalog(xmlDefaultCatalog, filename, 0); xmlRMutexUnlock(&xmlCatalogMutex); return(ret); } Index: libxml2-2.14.5/result/catalogs/recursive =================================================================== --- /dev/null +++ libxml2-2.14.5/result/catalogs/recursive @@ -0,0 +1 @@ +> \ No newline at end of file Index: libxml2-2.14.5/test/catalogs/recursive.sgml =================================================================== --- /dev/null +++ libxml2-2.14.5/test/catalogs/recursive.sgml @@ -0,0 +1 @@ +CATALOG recursive.sgml