From 2caad3909444a5186e43d3bc99c6aa8828d6b237 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Mon, 27 Apr 2026 07:53:51 -0400 Subject: [PATCH 1/2] ext/xsl: handle xsltNewTransformContext allocation failure xsltNewTransformContext can return NULL on libxslt-internal allocation failure. The next line dereferences ctxt unconditionally to set ctxt->_private, segfaulting on OOM. Bail through the existing out: label, which already handles secPrefs/intern->doc cleanup. xsltFreeTransformContext(NULL) is a documented no-op in libxslt. --- ext/xsl/xsltprocessor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 71971332a251..f4355876af88 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -350,6 +350,9 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl php_libxml_increment_doc_ref(intern->doc, doc); ctxt = xsltNewTransformContext(style, doc); + if (UNEXPECTED(ctxt == NULL)) { + goto out; + } ctxt->_private = (void *) intern; if (intern->parameter) { From 1156db91617467fa0e24c7e6a6abb87924cab03d Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Mon, 27 Apr 2026 07:54:30 -0400 Subject: [PATCH 2/2] ext/xsl: discard partially-constructed ns on xmlStrdup failure If xmlStrdup fails for either href or prefix in xsl_add_ns_def, the malformed xmlNs (NULL href, or NULL prefix when one was expected) was linked into node->nsDef. Subsequent libxml2 traversal of the namespace chain dereferenced those NULLs. Free the xmlNs via xmlFreeNs and return without linking it. --- ext/xsl/xsltprocessor.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index f4355876af88..d50092a3c921 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -140,6 +140,12 @@ static void xsl_add_ns_def(xmlNodePtr node) ns->type = XML_LOCAL_NAMESPACE; ns->href = should_free ? attr_value : xmlStrdup(attr_value); ns->prefix = attr->ns->prefix ? xmlStrdup(attr->name) : NULL; + + if (UNEXPECTED(ns->href == NULL || (attr->ns->prefix != NULL && ns->prefix == NULL))) { + xmlFreeNs(ns); + return; + } + ns->next = node->nsDef; node->nsDef = ns; }