1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2026-01-26 21:41:34 +03:00

testcatalog: Add new tests for catalog.c

Adds a new test program to run specific tests related to catalog
parsing.

This initial version includes a couple of tests, the first one to check
the infinite recursion detection related to:
https://gitlab.gnome.org/GNOME/libxml2/-/issues/1018.

The second one tests the nextCatalog element repeated parsing, related
to:
https://gitlab.gnome.org/GNOME/libxml2/-/issues/1019
https://gitlab.gnome.org/GNOME/libxml2/-/issues/1040
This commit is contained in:
Daniel Garcia Moreno
2025-12-19 12:27:54 +01:00
committed by Daniel Garcia Moreno
parent 19549c6159
commit f8399e62a3
8 changed files with 164 additions and 19 deletions

View File

@@ -498,6 +498,7 @@ if(LIBXML2_WITH_TESTS)
runxmlconf
runsuite
testapi
testcatalog
testchar
testdict
testModule
@@ -520,6 +521,7 @@ if(LIBXML2_WITH_TESTS)
add_test(NAME runxmlconf COMMAND runxmlconf WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()
add_test(NAME testapi COMMAND testapi)
add_test(NAME testcatalog COMMAND testcatalog)
add_test(NAME testchar COMMAND testchar)
add_test(NAME testdict COMMAND testdict)
add_test(NAME testparser COMMAND testparser WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -23,6 +23,7 @@ check_PROGRAMS = \
runxmlconf \
testModule \
testapi \
testcatalog \
testchar \
testdict \
testlimits \
@@ -120,6 +121,10 @@ testlimits_SOURCES=testlimits.c
testlimits_DEPENDENCIES = $(DEPS)
testlimits_LDADD= $(LDADDS)
testcatalog_SOURCES=testcatalog.c
testcatalog_DEPENDENCIES = $(DEPS)
testcatalog_LDADD= $(LDADDS)
testchar_SOURCES=testchar.c
testchar_DEPENDENCIES = $(DEPS)
testchar_LDADD= $(LDADDS)
@@ -167,6 +172,7 @@ check-local:
$(CHECKER) ./runtest$(EXEEXT)
$(CHECKER) ./testrecurse$(EXEEXT)
$(CHECKER) ./testapi$(EXEEXT)
$(CHECKER) ./testcatalog$(EXEEXT)
$(CHECKER) ./testchar$(EXEEXT)
$(CHECKER) ./testdict$(EXEEXT)
$(CHECKER) ./testparser$(EXEEXT)

View File

@@ -640,43 +640,54 @@ static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
}
}
static int
xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
int ret;
xmlDocPtr doc;
static xmlDocPtr
xmlDumpXMLCatalogToDoc(xmlCatalogEntryPtr catal) {
xmlNsPtr ns;
xmlDtdPtr dtd;
xmlNodePtr catalog;
xmlOutputBufferPtr buf;
xmlDocPtr doc = xmlNewDoc(NULL);
if (doc == NULL) {
return(NULL);
}
/*
* Rebuild a catalog
*/
doc = xmlNewDoc(NULL);
if (doc == NULL)
return(-1);
dtd = xmlNewDtd(doc, BAD_CAST "catalog",
BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
if (ns == NULL) {
xmlFreeDoc(doc);
return(-1);
xmlFreeDoc(doc);
return(NULL);
}
catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
if (catalog == NULL) {
xmlFreeNs(ns);
xmlFreeDoc(doc);
return(-1);
xmlFreeDoc(doc);
xmlFreeNs(ns);
return(NULL);
}
catalog->nsDef = ns;
xmlAddChild((xmlNodePtr) doc, catalog);
xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL);
return(doc);
}
static int
xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
int ret;
xmlDocPtr doc;
xmlOutputBufferPtr buf;
/*
* Rebuild a catalog
*/
doc = xmlDumpXMLCatalogToDoc(catal);
if (doc == NULL) {
return(-1);
}
/*
* reserialize it
*/
@@ -3352,6 +3363,20 @@ xmlCatalogDump(FILE *out) {
xmlACatalogDump(xmlDefaultCatalog, out);
}
/**
* Dump all the global catalog content as a xmlDoc
* This function is just for testing/debugging purposes
*
* @returns The catalog as xmlDoc or NULL if failed, it must be freed by the caller.
*/
xmlDocPtr
xmlCatalogDumpDoc(void) {
if (!xmlCatalogInitialized)
xmlInitializeCatalog();
return xmlDumpXMLCatalogToDoc(xmlDefaultCatalog->xml);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**

View File

@@ -138,6 +138,8 @@ XMLPUBFUN void
#ifdef LIBXML_OUTPUT_ENABLED
XMLPUBFUN void
xmlCatalogDump (FILE *out);
XMLPUBFUN xmlDocPtr
xmlCatalogDumpDoc (void);
#endif /* LIBXML_OUTPUT_ENABLED */
XMLPUBFUN xmlChar *
xmlCatalogResolve (const xmlChar *pubID,

View File

@@ -517,6 +517,7 @@ checks = {
# Disabled for now, see #694
# 'testModule': [],
'testapi': [],
'testcatalog': [],
'testchar': [],
'testdict': [],
'testlimits': [],

View File

@@ -0,0 +1,3 @@
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<delegateURI uriStartString="/foo" catalog="catalog-recursive.xml"/>
</catalog>

View File

@@ -0,0 +1,10 @@
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<nextCatalog catalog="registry.xml"/>
<nextCatalog catalog="registry.xml"/>
<nextCatalog catalog="./registry.xml"/>
<nextCatalog catalog="././registry.xml"/>
<nextCatalog catalog="./././registry.xml"/>
<nextCatalog catalog="./../catalogs/registry.xml"/>
<nextCatalog catalog="./../catalogs/./registry.xml"/>
</catalog>

96
testcatalog.c Normal file
View File

@@ -0,0 +1,96 @@
/*
* testcatalog.c: C program to run libxml2 catalog.c unit tests
*
* To compile on Unixes:
* cc -o testcatalog `xml2-config --cflags` testcatalog.c `xml2-config --libs` -lpthread
*
* See Copyright for the status of this software.
*
* Author: Daniel Garcia <dani@danigm.net>
*/
#include "libxml.h"
#include <stdio.h>
#ifdef LIBXML_CATALOG_ENABLED
#include <libxml/catalog.h>
/* Test catalog resolve uri with recursive catalog */
static int
testRecursiveDelegateUri(void) {
int ret = 0;
const char *cat = "test/catalogs/catalog-recursive.xml";
const char *entity = "/foo.ent";
xmlChar *resolved = NULL;
xmlInitParser();
xmlLoadCatalog(cat);
/* This should trigger recursive error */
resolved = xmlCatalogResolveURI(BAD_CAST entity);
if (resolved != NULL) {
fprintf(stderr, "CATALOG-FAILURE: Catalog %s entity should fail to resolve\n", entity);
ret = 1;
}
xmlCatalogCleanup();
return ret;
}
/* Test parsing repeated NextCatalog */
static int
testRepeatedNextCatalog(void) {
int ret = 0;
int i = 0;
const char *cat = "test/catalogs/repeated-next-catalog.xml";
const char *entity = "/foo.ent";
xmlDocPtr doc = NULL;
xmlNodePtr node = NULL;
xmlInitParser();
xmlLoadCatalog(cat);
/* To force the complete recursive load */
xmlCatalogResolveURI(BAD_CAST entity);
/**
* Ensure that the doc doesn't contain the same nextCatalog
*/
doc = xmlCatalogDumpDoc();
xmlCatalogCleanup();
if (doc == NULL) {
fprintf(stderr, "CATALOG-FAILURE: Failed to dump the catalog\n");
return 1;
}
/* Just the root "catalog" node with a series of nextCatalog */
node = xmlDocGetRootElement(doc);
node = node->children;
for (i=0; node != NULL; node=node->next, i++) {}
if (i > 1) {
fprintf(stderr, "CATALOG-FAILURE: Found %d nextCatalog entries and should be 1\n", i);
ret = 1;
}
xmlFreeDoc(doc);
return ret;
}
int
main(void) {
int err = 0;
err |= testRecursiveDelegateUri();
err |= testRepeatedNextCatalog();
return err;
}
#else
/* No catalog, so everything okay */
int
main(void) {
return 0;
}
#endif