From dfde0d4cef6e7b02648b124db81733ccd8414f11 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Sat, 11 May 2024 01:40:55 +0200
Subject: [PATCH] Handle dumping node to file
---
.../common/namespace_sxe_interaction.phpt | 20 ++++++++++++++---
ext/dom/xml_document.c | 10 +++++++--
ext/libxml/libxml.c | 13 +++++++++++
ext/libxml/php_libxml.h | 1 +
ext/simplexml/simplexml.c | 22 ++++++-------------
5 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt b/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt
index dfe01ba279b92..c25518616fca9 100644
--- a/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt
+++ b/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt
@@ -24,6 +24,11 @@ var_dump($dom->documentElement->firstElementChild->firstElementChild->lookupName
echo "=== serialize SimpleXML ===\n";
echo $sxe->saveXML(), "\n";
+echo $sxe->foo->saveXML(), "\n";
+$sxe->asXML(__DIR__ . "/namespace_sxe_interaction1.xml");
+$sxe->foo->asXML(__DIR__ . "/namespace_sxe_interaction2.xml");
+echo file_get_contents(__DIR__ . "/namespace_sxe_interaction1.xml"), "\n";
+echo file_get_contents(__DIR__ . "/namespace_sxe_interaction2.xml"), "\n";
echo "=== serialize DOM ===\n";
@@ -36,6 +41,11 @@ $new_dom = Dom\XMLDocument::createEmpty();
$new_dom->append($new_dom->importNode($dom->documentElement, true));
echo $new_dom->saveXML(), "\n";
+?>
+--CLEAN--
+
--EXPECT--
namespace c: string(5) "urn:c"
@@ -43,11 +53,15 @@ namespace b: string(5) "urn:b"
namespace a: NULL
=== serialize SimpleXML ===
-value
+valuevalue2
+value2
+
+valuevalue2
+value2
=== serialize DOM ===
-value
+valuevalue2
=== serialize imported DOM ===
-value
+valuevalue2
diff --git a/ext/dom/xml_document.c b/ext/dom/xml_document.c
index 87b80b7365550..32eaa4b4cf92d 100644
--- a/ext/dom/xml_document.c
+++ b/ext/dom/xml_document.c
@@ -293,7 +293,7 @@ static zend_string *php_new_dom_dump_doc_to_str(xmlDocPtr doc, int options, cons
return php_new_dom_dump_node_to_str(doc, (xmlNodePtr) doc, options & XML_SAVE_FORMAT, encoding);
}
-static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding)
+zend_long php_new_dom_dump_node_to_file(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding)
{
xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler(encoding);
xmlOutputBufferPtr out = xmlOutputBufferCreateFilename(filename, handler, 0);
@@ -307,7 +307,7 @@ static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr do
int status = -1;
xmlSaveCtxtPtr ctxt = xmlSaveToIO(out->writecallback, NULL, stream, encoding, XML_SAVE_AS_XML);
if (EXPECTED(ctxt != NULL)) {
- status = dom_xml_serialize(ctxt, out, (xmlNodePtr) doc, format);
+ status = dom_xml_serialize(ctxt, out, node, format);
status |= xmlOutputBufferFlush(out);
(void) xmlSaveClose(ctxt);
}
@@ -319,9 +319,15 @@ static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr do
return status < 0 ? status : (zend_long) offset;
}
+static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding)
+{
+ return php_new_dom_dump_node_to_file(filename, doc, (xmlNodePtr) doc, format, encoding);
+}
+
static const php_libxml_document_handlers php_new_dom_default_document_handlers = {
.dump_node_to_str = php_new_dom_dump_node_to_str,
.dump_doc_to_str = php_new_dom_dump_doc_to_str,
+ .dump_node_to_file = php_new_dom_dump_node_to_file,
.dump_doc_to_file = php_new_dom_dump_doc_to_file,
};
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index 6d052ff66ac07..858da6922c078 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -83,6 +83,7 @@ static zend_result php_libxml_post_deactivate(void);
static zend_string *php_libxml_default_dump_node_to_str(xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding);
static zend_string *php_libxml_default_dump_doc_to_str(xmlDocPtr doc, int options, const char *encoding);
+static zend_long php_libxml_dump_node_to_file(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding);
static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding);
/* }}} */
@@ -109,6 +110,7 @@ zend_module_entry libxml_module_entry = {
static const php_libxml_document_handlers php_libxml_default_document_handlers = {
.dump_node_to_str = php_libxml_default_dump_node_to_str,
.dump_doc_to_str = php_libxml_default_dump_doc_to_str,
+ .dump_node_to_file = php_libxml_dump_node_to_file,
.dump_doc_to_file = php_libxml_default_dump_doc_to_file,
};
@@ -1540,6 +1542,17 @@ static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDo
return xmlSaveFormatFileEnc(filename, doc, encoding, format);
}
+static zend_long php_libxml_dump_node_to_file(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding)
+{
+ xmlOutputBufferPtr outbuf = xmlOutputBufferCreateFilename(filename, NULL, 0);
+ if (!outbuf) {
+ return -1;
+ }
+
+ xmlNodeDumpOutput(outbuf, doc, node, 0, format, encoding);
+ return xmlOutputBufferClose(outbuf);
+}
+
#if defined(PHP_WIN32) && defined(COMPILE_DL_LIBXML)
PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h
index e6b0a3a887882..4d799c39b165f 100644
--- a/ext/libxml/php_libxml.h
+++ b/ext/libxml/php_libxml.h
@@ -75,6 +75,7 @@ typedef struct _php_libxml_private_data_header {
typedef struct php_libxml_document_handlers {
zend_string *(*dump_node_to_str)(xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding);
zend_string *(*dump_doc_to_str)(xmlDocPtr doc, int options, const char *encoding);
+ zend_long (*dump_node_to_file)(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding);
zend_long (*dump_doc_to_file)(const char *filename, xmlDocPtr doc, bool format, const char *encoding);
} php_libxml_document_handlers;
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index b104784f5369c..3bc7964541e9f 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -1342,7 +1342,6 @@ PHP_METHOD(SimpleXMLElement, asXML)
{
php_sxe_object *sxe;
xmlNodePtr node;
- xmlOutputBufferPtr outbuf;
char *filename = NULL;
size_t filename_len;
@@ -1361,22 +1360,15 @@ PHP_METHOD(SimpleXMLElement, asXML)
xmlDocPtr doc = sxe->document->ptr;
if (filename) {
+ zend_long bytes;
if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
- zend_long bytes = sxe->document->handlers->dump_doc_to_file(filename, doc, false, (const char *) doc->encoding);
- if (bytes == -1) {
- RETURN_FALSE;
- } else {
- RETURN_TRUE;
- }
+ bytes = sxe->document->handlers->dump_doc_to_file(filename, doc, false, (const char *) doc->encoding);
+ } else {
+ bytes = sxe->document->handlers->dump_node_to_file(filename, doc, node, false, NULL);
+ }
+ if (bytes == -1) {
+ RETURN_FALSE;
} else {
- outbuf = xmlOutputBufferCreateFilename(filename, NULL, 0);
-
- if (outbuf == NULL) {
- RETURN_FALSE;
- }
-
- xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, NULL);
- xmlOutputBufferClose(outbuf);
RETURN_TRUE;
}
}