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 diff --git a/catalog.c b/catalog.c index f5c6fd4cd..76c063a8b 100644 --- a/catalog.c +++ b/catalog.c @@ -65,7 +65,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); /************************************************************************ * * @@ -2249,17 +2249,24 @@ xmlGetSGMLCatalogEntryType(const xmlChar *name) { * @param file the filepath for the catalog * @param super should this be handled as a Super Catalog in which case * parsing is not recursive + * @param depth the current depth of the catalog * @returns 0 in case of success, -1 in case of error. */ 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)) { @@ -2437,7 +2444,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, filename = xmlBuildURI(sysid, base); if (filename != NULL) { - xmlExpandCatalog(catal, (const char *)filename); + xmlExpandCatalog(catal, (const char *)filename, depth); xmlFree(filename); } } @@ -2584,7 +2591,7 @@ xmlLoadSGMLSuperCatalog(const char *filename) return(NULL); } - ret = xmlParseSGMLCatalog(catal, content, filename, 1); + ret = xmlParseSGMLCatalog(catal, content, filename, 1, 0); xmlFree(content); if (ret < 0) { xmlFreeCatalog(catal); @@ -2633,7 +2640,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); @@ -2660,14 +2667,20 @@ xmlLoadACatalog(const char *filename) * * @param catal a catalog * @param filename a file path + * @param depth the current depth of the catalog * @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) { if ((catal == NULL) || (filename == NULL)) return(-1); + /* Check recursion depth */ + if (depth > MAX_CATAL_DEPTH) { + return(-1); + } + #ifdef LIBXML_SGML_CATALOG_ENABLED if (catal->type == XML_SGML_CATALOG_TYPE) { xmlChar *content; @@ -2677,7 +2690,7 @@ xmlExpandCatalog(xmlCatalogPtr catal, const char *filename) 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); @@ -3138,7 +3151,7 @@ xmlLoadCatalog(const char *filename) return(0); } - ret = xmlExpandCatalog(xmlDefaultCatalog, filename); + ret = xmlExpandCatalog(xmlDefaultCatalog, filename, 0); xmlRMutexUnlock(&xmlCatalogMutex); return(ret); } diff --git a/result/catalogs/recursive b/result/catalogs/recursive new file mode 100644 index 000000000..56ca91ea5 --- /dev/null +++ b/result/catalogs/recursive @@ -0,0 +1 @@ +> \ No newline at end of file diff --git a/test/catalogs/recursive.script b/test/catalogs/recursive.script new file mode 100644 index 000000000..e69de29bb diff --git a/test/catalogs/recursive.sgml b/test/catalogs/recursive.sgml new file mode 100644 index 000000000..ac2148be4 --- /dev/null +++ b/test/catalogs/recursive.sgml @@ -0,0 +1 @@ +CATALOG recursive.sgml