From 0a39890c967aa57225bb6bdf4821aff7a3a3c082 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Fri, 1 Dec 2023 18:03:35 +0100
Subject: [PATCH] Fix libxml2 2.12 build due to API breaks

See https://github.com/php/php-src/actions/runs/7062192818/job/19225478601
---
 ext/libxml/libxml.c | 14 ++++++++++----
 ext/soap/php_sdl.c  |  2 +-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index 22eb1901b8909..1de693892b7aa 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -483,7 +483,11 @@ static void _php_libxml_free_error(void *ptr)
 	xmlResetError((xmlErrorPtr) ptr);
 }
 
-static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg)
+#if LIBXML_VERSION >= 21200
+static void _php_list_set_error_structure(const xmlError *error, const char *msg)
+#else
+static void _php_list_set_error_structure(xmlError *error, const char *msg)
+#endif
 {
 	xmlError error_copy;
 	int ret;
@@ -736,7 +740,11 @@ PHP_LIBXML_API void php_libxml_ctx_warning(void *ctx, const char *msg, ...)
 	va_end(args);
 }
 
+#if LIBXML_VERSION >= 21200
+PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, const xmlError *error)
+#else
 PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, xmlErrorPtr error)
+#endif
 {
 	_php_list_set_error_structure(error, NULL);
 
@@ -1009,11 +1017,9 @@ PHP_FUNCTION(libxml_use_internal_errors)
 /* {{{ Retrieve last error from libxml */
 PHP_FUNCTION(libxml_get_last_error)
 {
-	xmlErrorPtr error;
-
 	ZEND_PARSE_PARAMETERS_NONE();
 
-	error = xmlGetLastError();
+	const xmlError *error = xmlGetLastError();
 
 	if (error) {
 		object_init_ex(return_value, libxmlerror_class_entry);
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index 749f5a5685ec2..b731114775ad7 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -332,7 +332,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
 	sdl_restore_uri_credentials(ctx);
 
 	if (!wsdl) {
-		xmlErrorPtr xmlErrorPtr = xmlGetLastError();
+		const xmlError *xmlErrorPtr = xmlGetLastError();
 
 		if (xmlErrorPtr) {
 			soap_error2(E_ERROR, "Parsing WSDL: Couldn't load from '%s' : %s", struri, xmlErrorPtr->message);
From 061058a9b1bbd90d27d97d79aebcf2b5029767b0 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Wed, 29 Nov 2023 20:49:29 +0100
Subject: [PATCH] Test fixes for libxml2 2.12.0

---
 NEWS                                          |  1 +
 ext/dom/tests/DOMDocument_loadXML_error1.phpt |  4 +++
 .../DOMDocument_loadXML_error1_gte2_12.phpt   | 26 ++++++++++++++++
 .../DOMDocument_loadXML_error2_gte2_11.phpt   |  2 +-
 .../DOMDocument_loadXML_error2_gte2_12.phpt   | 30 +++++++++++++++++++
 ext/dom/tests/DOMDocument_load_error1.phpt    |  4 +++
 .../DOMDocument_load_error1_gte2_12.phpt      | 26 ++++++++++++++++
 .../DOMDocument_load_error2_gte2_11.phpt      |  2 +-
 .../DOMDocument_load_error2_gte2_12.phpt      | 30 +++++++++++++++++++
 ext/xml/tests/bug81351.phpt                   |  4 +--
 ext/xml/tests/xml_error_string_basic.phpt     |  6 ++--
 11 files changed, 128 insertions(+), 7 deletions(-)
 create mode 100644 ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt
 create mode 100644 ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt
 create mode 100644 ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt
 create mode 100644 ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt

diff --git a/ext/dom/tests/DOMDocument_loadXML_error1.phpt b/ext/dom/tests/DOMDocument_loadXML_error1.phpt
index 14d99e4ed9ad9..2af3217bd6c6a 100644
--- a/ext/dom/tests/DOMDocument_loadXML_error1.phpt
+++ b/ext/dom/tests/DOMDocument_loadXML_error1.phpt
@@ -1,5 +1,9 @@
 --TEST--
 Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version < 2.12');
+?>
 --DESCRIPTION--
 This test verifies the method detects an opening and ending tag mismatch
 Environment variables used in the test:
diff --git a/ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt b/ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt
new file mode 100644
index 0000000000000..e1ded0ffadd7f
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects an opening and ending tag mismatch
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: title line 5 and book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): %rexpected '>'|Opening and ending tag mismatch: book line (4|5) and books%r %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
index ff5ceb3fbed53..f52d3348138c5 100644
--- a/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
+++ b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
@@ -2,7 +2,7 @@
 Test DOMDocument::loadXML() detects not-well formed XML
 --SKIPIF--
 <?php
-if (LIBXML_VERSION < 21100) die('skip libxml2 test variant for version >= 2.11');
+if (LIBXML_VERSION < 21100 || LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version >= 2.11 && <= 2.12');
 ?>
 --DESCRIPTION--
 This test verifies the method detects attributes values not closed between " or '
diff --git a/ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt
new file mode 100644
index 0000000000000..6a3ff5841f565
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::loadXML(): AttValue: " or ' expected in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): internal error: xmlParseStartTag: problem parsing attributes in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): Couldn't find end of Start Tag book line 4 in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): Opening and ending tag mismatch: books line 3 and book in Entity, line: 7 in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_load_error1.phpt b/ext/dom/tests/DOMDocument_load_error1.phpt
index f736b0a0e81c6..2da8c0cd18b4e 100644
--- a/ext/dom/tests/DOMDocument_load_error1.phpt
+++ b/ext/dom/tests/DOMDocument_load_error1.phpt
@@ -1,5 +1,9 @@
 --TEST--
 Test DOMDocument::load() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version < 2.12');
+?>
 --DESCRIPTION--
 This test verifies the method detects an opening and ending tag mismatch
 Environment variables used in the test:
diff --git a/ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt b/ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt
new file mode 100644
index 0000000000000..183c8406fdfc8
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects an opening and ending tag mismatch
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: title line 5 and book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): %rexpected '>'|Opening and ending tag mismatch: book line (4|5) and books%r %s
diff --git a/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt b/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
index 32b6bf161142e..4d9f992b3bafd 100644
--- a/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
+++ b/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
@@ -2,7 +2,7 @@
 Test DOMDocument::load() detects not-well formed 
 --SKIPIF--
 <?php
-if (LIBXML_VERSION < 21100) die('skip libxml2 test variant for version >= 2.11');
+if (LIBXML_VERSION < 21100 || LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version >= 2.11 && <= 2.12');
 ?>
 --DESCRIPTION--
 This test verifies the method detects attributes values not closed between " or '
diff --git a/ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt b/ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt
new file mode 100644
index 0000000000000..4fadf41736124
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::load(): AttValue: " or ' expected in %s on line %d
+
+Warning: DOMDocument::load(): internal error: xmlParseStartTag: problem parsing attributes in %s on line %d
+
+Warning: DOMDocument::load(): Couldn't find end of Start Tag book line 4 in %s on line %d
+
+Warning: DOMDocument::load(): Opening and ending tag mismatch: books line 3 and book in %s on line %d
diff --git a/ext/xml/tests/bug81351.phpt b/ext/xml/tests/bug81351.phpt
index 78aea041046f7..7380a9a937008 100644
--- a/ext/xml/tests/bug81351.phpt
+++ b/ext/xml/tests/bug81351.phpt
@@ -21,6 +21,6 @@ $code = xml_get_error_code($parser);
 $error = xml_error_string($code);
 echo "xml_parse returned $success, xml_get_error_code = $code, xml_error_string = $error\r\n";
 ?>
---EXPECT--
+--EXPECTF--
 xml_parse returned 1, xml_get_error_code = 0, xml_error_string = No error
-xml_parse returned 0, xml_get_error_code = 5, xml_error_string = Invalid document end
+%rxml_parse returned 0, xml_get_error_code = 5, xml_error_string = Invalid document end|xml_parse returned 0, xml_get_error_code = 77, xml_error_string = Tag not finished%r
diff --git a/ext/xml/tests/xml_error_string_basic.phpt b/ext/xml/tests/xml_error_string_basic.phpt
index 86dede1730f7e..a23ec8741d592 100644
--- a/ext/xml/tests/xml_error_string_basic.phpt
+++ b/ext/xml/tests/xml_error_string_basic.phpt
@@ -21,9 +21,9 @@ foreach ($xmls as $xml) {
     xml_parser_free($xml_parser);
 }
 ?>
---EXPECT--
-int(5)
-string(20) "Invalid document end"
+--EXPECTF--
+int(%r5|77%r)
+string(%d) %r"Invalid document end"|"Tag not finished"%r
 int(47)
 string(35) "Processing Instruction not finished"
 int(57)