1From c24909ba2601848825b49a60f988222da3019667 Mon Sep 17 00:00:00 2001 2From: Michael Mann <mmann78@netscape.net> 3Date: Sat, 21 Jun 2025 12:11:30 -0400 4Subject: [PATCH] Schematron: Fix null pointer dereference leading to DoS 5 6(CVE-2025-49795) 7 8Fixes #932 9--- 10 result/schematron/zvon16_0.err | 3 +++ 11 runtest.c | 11 ++++++++--- 12 schematron.c | 5 +++++ 13 test/schematron/zvon16.sct | 7 +++++++ 14 test/schematron/zvon16_0.xml | 5 +++++ 15 5 files changed, 28 insertions(+), 3 deletions(-) 16 create mode 100644 result/schematron/zvon16_0.err 17 create mode 100644 test/schematron/zvon16.sct 18 create mode 100644 test/schematron/zvon16_0.xml 19 20diff --git a/result/schematron/zvon16_0.err b/result/schematron/zvon16_0.err 21new file mode 100644 22index 000000000..3d0524095 23--- /dev/null 24+++ b/result/schematron/zvon16_0.err 25@@ -0,0 +1,3 @@ 26+XPath error : Unregistered function 27+./test/schematron/zvon16_0.xml:2: element book: schematron error : /library/book line 2: Book 28+./test/schematron/zvon16_0.xml fails to validate 29diff --git a/runtest.c b/runtest.c 30index 84518ae91..721a1b331 100644 31--- a/runtest.c 32+++ b/runtest.c 33@@ -3999,6 +3999,9 @@ schematronTest(const char *filename, 34 size_t i; 35 char count = 0; 36 37+ /* Redirect XPath errors */ 38+ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler); 39+ 40 pctxt = xmlSchematronNewParserCtxt(filename); 41 schematron = xmlSchematronParse(pctxt); 42 xmlSchematronFreeParserCtxt(pctxt); 43@@ -4012,8 +4015,8 @@ schematronTest(const char *filename, 44 */ 45 len = strlen(base); 46 if ((len > 499) || (len < 5)) { 47- xmlSchematronFree(schematron); 48- return(-1); 49+ ret = -1; 50+ goto done; 51 } 52 len -= 4; /* remove trailing .sct */ 53 memcpy(prefix, base, len); 54@@ -4053,8 +4056,10 @@ schematronTest(const char *filename, 55 } 56 } 57 globfree(&globbuf); 58- xmlSchematronFree(schematron); 59 60+done: 61+ xmlSchematronFree(schematron); 62+ xmlSetStructuredErrorFunc(NULL, NULL); 63 return(ret); 64 } 65 #endif /* LIBXML_SCHEMATRON_ENABLED */ 66diff --git a/schematron.c b/schematron.c 67index 21e9956bb..33e924a0a 100644 68--- a/schematron.c 69+++ b/schematron.c 70@@ -1505,6 +1505,11 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt, 71 select = xmlGetNoNsProp(child, BAD_CAST "select"); 72 comp = xmlXPathCtxtCompile(ctxt->xctxt, select); 73 eval = xmlXPathCompiledEval(comp, ctxt->xctxt); 74+ if (eval == NULL) { 75+ xmlXPathFreeCompExpr(comp); 76+ xmlFree(select); 77+ return ret; 78+ } 79 80 switch (eval->type) { 81 case XPATH_NODESET: { 82diff --git a/test/schematron/zvon16.sct b/test/schematron/zvon16.sct 83new file mode 100644 84index 000000000..f03848aae 85--- /dev/null 86+++ b/test/schematron/zvon16.sct 87@@ -0,0 +1,7 @@ 88+<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron"> 89+ <sch:pattern id="TestPattern"> 90+ <sch:rule context="book"> 91+ <sch:report test="not(@available)">Book <sch:value-of select="falae()"/> test</sch:report> 92+ </sch:rule> 93+ </sch:pattern> 94+</sch:schema> 95diff --git a/test/schematron/zvon16_0.xml b/test/schematron/zvon16_0.xml 96new file mode 100644 97index 000000000..551e2d654 98--- /dev/null 99+++ b/test/schematron/zvon16_0.xml 100@@ -0,0 +1,5 @@ 101+<library> 102+ <book title="Test Book" id="bk101"> 103+ <author>Test Author</author> 104+ </book> 105+</library> 106-- 107GitLab 108 109