From fa6a0f80f644932506666beb7c85e4041c4a4646 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 1/8] Backport 0a39890c: 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 3959b362a0e..6cdfbd397f7 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 651eab23b7a..7a7ce304d61 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 dbde99d875289b14b1c9e9cd59c53bbf2fcae767 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 6 Dec 2023 20:39:57 +0100 Subject: [PATCH 2/8] Backport e2d97314: Backport deprecation warning ignores to unbreak CI In master I use ZEND_DIAGNOSTIC_IGNORED_START, but that doesn't exist on 8.2 or 8.3 (8.3 has a similar macro though). So to unbreak CI I just made a variation of this directly in the php_libxml.h header. See https://github.com/php/php-src/commit/683e78786070ab77d33f7787598ac1b90d68390a#commitcomment-134301083 --- ext/libxml/php_libxml.h | 25 +++++++++++++++++++++++-- ext/xsl/xsltprocessor.c | 2 ++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h index a1011f0b178..06729205a05 100644 --- a/ext/libxml/php_libxml.h +++ b/ext/libxml/php_libxml.h @@ -119,12 +119,30 @@ PHP_LIBXML_API void php_libxml_shutdown(void); ZEND_TSRMLS_CACHE_EXTERN() #endif +#if defined(__clang__) +# define PHP_LIBXML_IGNORE_DEPRECATIONS_START \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") +# define PHP_LIBXML_IGNORE_DEPRECATIONS_END \ + _Pragma("clang diagnostic pop") +#elif defined(__GNUC__) +# define PHP_LIBXML_IGNORE_DEPRECATIONS_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define PHP_LIBXML_IGNORE_DEPRECATIONS_END \ + _Pragma("GCC diagnostic pop") +#else +# define PHP_LIBXML_IGNORE_DEPRECATIONS_START +# define PHP_LIBXML_IGNORE_DEPRECATIONS_END +#endif + /* Other extension may override the global state options, these global options * are copied initially to ctxt->options. Set the options to a known good value. * See libxml2 globals.c and parserInternals.c. * The unique_name argument allows multiple sanitizes and restores within the * same function, even nested is necessary. */ #define PHP_LIBXML_SANITIZE_GLOBALS(unique_name) \ + PHP_LIBXML_IGNORE_DEPRECATIONS_START \ int xml_old_loadsubset_##unique_name = xmlLoadExtDtdDefaultValue; \ xmlLoadExtDtdDefaultValue = 0; \ int xml_old_validate_##unique_name = xmlDoValidityCheckingDefaultValue; \ @@ -132,15 +150,18 @@ ZEND_TSRMLS_CACHE_EXTERN() int xml_old_pedantic_##unique_name = xmlPedanticParserDefault(0); \ int xml_old_substitute_##unique_name = xmlSubstituteEntitiesDefault(0); \ int xml_old_linenrs_##unique_name = xmlLineNumbersDefault(0); \ - int xml_old_blanks_##unique_name = xmlKeepBlanksDefault(1); + int xml_old_blanks_##unique_name = xmlKeepBlanksDefault(1); \ + PHP_LIBXML_IGNORE_DEPRECATIONS_END #define PHP_LIBXML_RESTORE_GLOBALS(unique_name) \ + PHP_LIBXML_IGNORE_DEPRECATIONS_START \ xmlLoadExtDtdDefaultValue = xml_old_loadsubset_##unique_name; \ xmlDoValidityCheckingDefaultValue = xml_old_validate_##unique_name; \ (void) xmlPedanticParserDefault(xml_old_pedantic_##unique_name); \ (void) xmlSubstituteEntitiesDefault(xml_old_substitute_##unique_name); \ (void) xmlLineNumbersDefault(xml_old_linenrs_##unique_name); \ - (void) xmlKeepBlanksDefault(xml_old_blanks_##unique_name); + (void) xmlKeepBlanksDefault(xml_old_blanks_##unique_name); \ + PHP_LIBXML_IGNORE_DEPRECATIONS_END /* Alternative for above, working directly on the context and not setting globals. * Generally faster because no locking is involved, and this has the advantage that it sets the options to a known good value. */ diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 22d56c41fae..53bb8653969 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -345,8 +345,10 @@ PHP_METHOD(XSLTProcessor, importStylesheet) newdoc = xmlCopyDoc(doc, 1); xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL); PHP_LIBXML_SANITIZE_GLOBALS(parse); + PHP_LIBXML_IGNORE_DEPRECATIONS_START xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; + PHP_LIBXML_IGNORE_DEPRECATIONS_END sheetp = xsltParseStylesheetDoc(newdoc); PHP_LIBXML_RESTORE_GLOBALS(parse); From bb46b4b799b583528025a775af45308133bfd4c1 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 4 Jul 2024 06:29:50 -0700 Subject: [PATCH 3/8] Backport 4fe82131: Backport libxml2 2.13.2 fixes (#14816) Backproted from https://github.com/php/php-src/pull/14789 --- ext/dom/document.c | 6 ++-- .../DOMDocument_loadHTMLfile_error1.phpt | 2 +- .../DOMDocument_relaxNGValidate_error2.phpt | 2 +- .../tests/DOMDocument_saveHTMLFile_basic.phpt | 4 +++ ...DOMDocument_saveHTMLFile_formatOutput.phpt | 4 +++ ...nt_saveHTMLFile_formatOutput_gte_2_13.phpt | 32 +++++++++++++++++++ .../DOMDocument_saveHTML_basic_gte_2_13.phpt | 31 ++++++++++++++++++ .../DOMDocument_schemaValidate_error5.phpt | 2 +- ext/dom/tests/dom_create_element.phpt | 14 +++----- ext/libxml/libxml.c | 4 ++- ext/libxml/php_libxml.h | 2 ++ ext/simplexml/tests/bug79971_1.phpt | 2 +- ext/soap/php_encoding.c | 9 ++++-- ext/soap/php_xml.c | 8 ++++- ext/soap/tests/bugs/bug42151.phpt | 4 +-- ext/xml/compat.c | 3 +- ext/xmlwriter/php_xmlwriter.c | 3 +- 17 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput_gte_2_13.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTML_basic_gte_2_13.phpt diff --git a/ext/dom/document.c b/ext/dom/document.c index 8312d6c5939..431d69a89dc 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1287,11 +1287,13 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so if (keep_blanks == 0 && ! (options & XML_PARSE_NOBLANKS)) { options |= XML_PARSE_NOBLANKS; } + if (recover) { + options |= XML_PARSE_RECOVER; + } php_libxml_sanitize_parse_ctxt_options(ctxt); xmlCtxtUseOptions(ctxt, options); - ctxt->recovery = recover; if (recover) { old_error_reporting = EG(error_reporting); EG(error_reporting) = old_error_reporting | E_WARNING; @@ -1301,7 +1303,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so if (ctxt->wellFormed || recover) { ret = ctxt->myDoc; - if (ctxt->recovery) { + if (recover) { EG(error_reporting) = old_error_reporting; } /* If loading from memory, set the base reference uri for the document */ diff --git a/ext/dom/tests/DOMDocument_loadHTMLfile_error1.phpt b/ext/dom/tests/DOMDocument_loadHTMLfile_error1.phpt index 5b88546908d..bacf64edb2a 100644 --- a/ext/dom/tests/DOMDocument_loadHTMLfile_error1.phpt +++ b/ext/dom/tests/DOMDocument_loadHTMLfile_error1.phpt @@ -15,4 +15,4 @@ $result = $doc->loadHTMLFile(__DIR__ . "/ffff/test.html"); assert($result === false); ?> --EXPECTF-- -%r(PHP ){0,1}%rWarning: DOMDocument::loadHTMLFile(): I/O warning : failed to load external entity %s +%r(PHP ){0,1}%rWarning: DOMDocument::loadHTMLFile(): I/O %s diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt index 1ad46e014a0..cb506f70789 100644 --- a/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt +++ b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt @@ -20,7 +20,7 @@ $result = $doc->relaxNGValidate($rng); var_dump($result); ?> --EXPECTF-- -Warning: DOMDocument::relaxNGValidate(): I/O warning : failed to load external entity "%s/foo.rng" in %s on line %d +Warning: DOMDocument::relaxNGValidate(): I/O %s : failed to load %s Warning: DOMDocument::relaxNGValidate(): xmlRelaxNGParse: could not load %s/foo.rng in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt index cf392c0262f..32f1a3c36e2 100644 --- a/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt @@ -5,6 +5,10 @@ Knut Urdalen #PHPTestFest2009 Norway 2009-06-09 \o/ --EXTENSIONS-- dom +--SKIPIF-- += 21300) die("skip see https://gitlab.gnome.org/GNOME/libxml2/-/issues/756"); +?> --FILE-- #PHPTestFest2009 Norway 2009-06-09 \o/ --EXTENSIONS-- dom +--SKIPIF-- += 21300) die("skip see https://gitlab.gnome.org/GNOME/libxml2/-/issues/756"); +?> --FILE-- +#PHPTestFest2009 Norway 2009-06-09 \o/ +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- +formatOutput = true; +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +var_dump($bytes); +echo file_get_contents($filename); +unlink($filename); +?> +--EXPECT-- +int(59) +This is the title diff --git a/ext/dom/tests/DOMDocument_saveHTML_basic_gte_2_13.phpt b/ext/dom/tests/DOMDocument_saveHTML_basic_gte_2_13.phpt new file mode 100644 index 00000000000..c0be105253d --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_basic_gte_2_13.phpt @@ -0,0 +1,31 @@ +--TEST-- +DOMDocument::saveHTMLFile() should dump the internal document into a file using HTML formatting +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- +createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +var_dump($bytes); +echo file_get_contents($filename); +unlink($filename); +?> +--EXPECT-- +int(59) +This is the title diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt index 2feda5d1e1f..bc94abacf22 100644 --- a/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt +++ b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt @@ -17,7 +17,7 @@ var_dump($result); ?> --EXPECTF-- -Warning: DOMDocument::schemaValidate(): I/O warning : failed to load external entity "%snon-existent-file" in %s.php on line %d +Warning: DOMDocument::schemaValidate(): I/O %s : failed to load %s Warning: DOMDocument::schemaValidate(): Failed to locate the main schema resource at '%s/non-existent-file'. in %s.php on line %d diff --git a/ext/dom/tests/dom_create_element.phpt b/ext/dom/tests/dom_create_element.phpt index 82d73826da4..19acb5614d5 100644 --- a/ext/dom/tests/dom_create_element.phpt +++ b/ext/dom/tests/dom_create_element.phpt @@ -251,14 +251,10 @@ try { print $e->getMessage() . "\n"; } -/* This isn't because the xml namespace isn't there and we can't create it */ -print "29 DOMElement::__construct('xml:valid', '', 'http://www.w3.org/XML/1998/namespace')\n"; -try { - $element = new DomElement('xml:valid', '', 'http://www.w3.org/XML/1998/namespace'); - print "valid\n"; -} catch (Exception $e) { - print $e->getMessage() . "\n"; -} +/* There used to be a 29 here that tested DOMElement::__construct('xml:valid', '', 'http://www.w3.org/XML/1998/namespace'). + * In libxml2 version 2.12 or prior this didn't work because the xml namespace isn't there and you can't create it without + * a document. Starting from libxml2 version 2.13 it does actually work because the XML namespace is statically defined. + * The behaviour from version 2.13 is actually the desired behaviour anyway. */ /* the qualifiedName or its prefix is "xmlns" and the namespaceURI is @@ -378,8 +374,6 @@ Namespace Error Namespace Error 28 DOMDocument::createElementNS('http://www.w3.org/XML/1998/namespace', 'xml:valid') valid -29 DOMElement::__construct('xml:valid', '', 'http://www.w3.org/XML/1998/namespace') -Namespace Error 30 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xmlns:valid') Namespace Error 31 DOMElement::__construct('xmlns:valid', '', 'http://wrong.namespaceURI.com') diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 6cdfbd397f7..dc5e7790952 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -430,8 +430,10 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc) static xmlOutputBufferPtr php_libxml_output_buffer_create_filename(const char *URI, xmlCharEncodingHandlerPtr encoder, - int compression ATTRIBUTE_UNUSED) + int compression) { + ZEND_IGNORE_VALUE(compression); + xmlOutputBufferPtr ret; xmlURIPtr puri; void *context = NULL; diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h index 06729205a05..6cca3746ff8 100644 --- a/ext/libxml/php_libxml.h +++ b/ext/libxml/php_libxml.h @@ -167,6 +167,7 @@ ZEND_TSRMLS_CACHE_EXTERN() * Generally faster because no locking is involved, and this has the advantage that it sets the options to a known good value. */ static zend_always_inline void php_libxml_sanitize_parse_ctxt_options(xmlParserCtxtPtr ctxt) { + PHP_LIBXML_IGNORE_DEPRECATIONS_START ctxt->loadsubset = 0; ctxt->validate = 0; ctxt->pedantic = 0; @@ -174,6 +175,7 @@ static zend_always_inline void php_libxml_sanitize_parse_ctxt_options(xmlParserC ctxt->linenumbers = 0; ctxt->keepBlanks = 1; ctxt->options = 0; + PHP_LIBXML_IGNORE_DEPRECATIONS_END } #else /* HAVE_LIBXML */ diff --git a/ext/simplexml/tests/bug79971_1.phpt b/ext/simplexml/tests/bug79971_1.phpt index 1097d74bb29..2ee24e89f12 100644 --- a/ext/simplexml/tests/bug79971_1.phpt +++ b/ext/simplexml/tests/bug79971_1.phpt @@ -20,7 +20,7 @@ var_dump($sxe->asXML("$uri.out%00foo")); --EXPECTF-- Warning: simplexml_load_file(): URI must not contain percent-encoded NUL bytes in %s on line %d -Warning: simplexml_load_file(): I/O warning : failed to load external entity "%s/bug79971_1.xml%%r00%rfoo" in %s on line %d +Warning: simplexml_load_file(): I/O warning : failed to load %s bool(false) Warning: SimpleXMLElement::asXML(): URI must not contain percent-encoded NUL bytes in %s on line %d diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index a5fbd3df9dd..20f60f48d6a 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -3378,7 +3378,6 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns) } else { smart_str prefix = {0}; int num = ++SOAP_GLOBAL(cur_uniq_ns); - xmlChar *enc_ns; while (1) { smart_str_appendl(&prefix, "ns", 2); @@ -3392,9 +3391,15 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns) num = ++SOAP_GLOBAL(cur_uniq_ns); } - enc_ns = xmlEncodeSpecialChars(node->doc, BAD_CAST(ns)); + /* Starting with libxml 2.13, we don't have to do this workaround anymore, otherwise we get double-encoded + * entities. See libxml2 commit f506ec66547ef9bac97a2bf306d368ecea8c0c9e. */ +#if LIBXML_VERSION < 21300 + xmlChar *enc_ns = xmlEncodeSpecialChars(node->doc, BAD_CAST(ns)); xmlns = xmlNewNs(node->doc->children, enc_ns, BAD_CAST(prefix.s ? ZSTR_VAL(prefix.s) : "")); xmlFree(enc_ns); +#else + xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), BAD_CAST(prefix.s ? ZSTR_VAL(prefix.s) : "")); +#endif smart_str_free(&prefix); } } diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index 3ff7aa055fd..20fd91ac4b4 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -92,13 +92,16 @@ xmlDocPtr soap_xmlParseFile(const char *filename) bool old; php_libxml_sanitize_parse_ctxt_options(ctxt); + /* TODO: In libxml2 2.14.0 change this to the new options API so we don't rely on deprecated APIs. */ + PHP_LIBXML_IGNORE_DEPRECATIONS_START ctxt->keepBlanks = 0; + ctxt->options |= XML_PARSE_HUGE; + PHP_LIBXML_IGNORE_DEPRECATIONS_END ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; ctxt->sax->comment = soap_Comment; ctxt->sax->warning = NULL; ctxt->sax->error = NULL; /*ctxt->sax->fatalError = NULL;*/ - ctxt->options |= XML_PARSE_HUGE; old = php_libxml_disable_entity_loader(1); xmlParseDocument(ctxt); php_libxml_disable_entity_loader(old); @@ -146,7 +149,10 @@ xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size) ctxt->sax->warning = NULL; ctxt->sax->error = NULL; /*ctxt->sax->fatalError = NULL;*/ + /* TODO: In libxml2 2.14.0 change this to the new options API so we don't rely on deprecated APIs. */ + PHP_LIBXML_IGNORE_DEPRECATIONS_START ctxt->options |= XML_PARSE_HUGE; + PHP_LIBXML_IGNORE_DEPRECATIONS_END old = php_libxml_disable_entity_loader(1); xmlParseDocument(ctxt); php_libxml_disable_entity_loader(old); diff --git a/ext/soap/tests/bugs/bug42151.phpt b/ext/soap/tests/bugs/bug42151.phpt index 6f5c0c42077..2f9c1830ad3 100644 --- a/ext/soap/tests/bugs/bug42151.phpt +++ b/ext/soap/tests/bugs/bug42151.phpt @@ -25,8 +25,8 @@ try { } echo "ok\n"; ?> ---EXPECT-- -SOAP-ERROR: Parsing WSDL: Couldn't load from 'httpx://' : failed to load external entity "httpx://" +--EXPECTF-- +SOAP-ERROR: Parsing WSDL: Couldn't load from 'httpx://' : failed to load %s ok I don't get executed either. diff --git a/ext/xml/compat.c b/ext/xml/compat.c index 5c41e7d2f5d..7b463ebb511 100644 --- a/ext/xml/compat.c +++ b/ext/xml/compat.c @@ -714,8 +714,7 @@ XML_GetCurrentByteCount(XML_Parser parser) { /* WARNING: this is identical to ByteIndex; it should probably * be different */ - return parser->parser->input->consumed + - (parser->parser->input->cur - parser->parser->input->base); + return XML_GetCurrentByteIndex(parser); } PHP_XML_API const XML_Char *XML_ExpatVersion(void) diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index 2966747fc52..36664d66abb 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -1004,7 +1004,8 @@ static void php_xmlwriter_flush(INTERNAL_FUNCTION_PARAMETERS, int force_string) } output_bytes = xmlTextWriterFlush(ptr); if (buffer) { - RETVAL_STRING((char *) buffer->content); + const xmlChar *content = xmlBufferContent(buffer); + RETVAL_STRING((const char *) content); if (empty) { xmlBufferEmpty(buffer); } From b78618750febc7259d8739d5c3ee8ed2d03f0e92 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Sep 2024 22:35:34 +0200 Subject: [PATCH 4/8] Backport f74f9b07: Update libxml test for the directory field behaviour change See https://gitlab.gnome.org/GNOME/libxml2/-/issues/753. The base directory for the entity is no longer set, follow the upstream behaviour. --- .../tests/libxml_set_external_entity_loader_variation1.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt index b480652209d..e56e59c3869 100644 --- a/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt +++ b/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt @@ -61,7 +61,7 @@ string(13) "-//FOO/ENTITY" string(32) "http://example.com/fooentity.ent" array(4) { ["directory"]=> - string(%d) "%s" + %r(NULL|string\(%d\) "%s")%r ["intSubName"]=> string(3) "foo" ["extSubURI"]=> From 6199289b6ef4816af4209561d5972d4346219fb0 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Sep 2024 22:37:21 +0200 Subject: [PATCH 5/8] Backport 3ec5919e: Update error message for libxml 2.13 External entity loading got its error level decreased in upstream, which means they now map to E_NOTICE. Also the error message format has changed. --- ext/libxml/tests/bug61367-read_2.phpt | 2 +- ext/libxml/tests/libxml_disable_entity_loader_2.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/libxml/tests/bug61367-read_2.phpt b/ext/libxml/tests/bug61367-read_2.phpt index 38f12949bcb..b9538782329 100644 --- a/ext/libxml/tests/bug61367-read_2.phpt +++ b/ext/libxml/tests/bug61367-read_2.phpt @@ -56,6 +56,6 @@ bool(true) int(4) bool(true) -Warning: DOMDocument::loadXML(): %Sfailed to load external entity "file:///%s/test_bug_61367-read/bad" in %s on line %d +%s: DOMDocument::loadXML(): %Sfailed to load %s Warning: Attempt to read property "nodeValue" on null in %s on line %d diff --git a/ext/libxml/tests/libxml_disable_entity_loader_2.phpt b/ext/libxml/tests/libxml_disable_entity_loader_2.phpt index 182fe13cfda..216792600bf 100644 --- a/ext/libxml/tests/libxml_disable_entity_loader_2.phpt +++ b/ext/libxml/tests/libxml_disable_entity_loader_2.phpt @@ -39,6 +39,6 @@ bool(true) Deprecated: Function libxml_disable_entity_loader() is deprecated in %s on line %d bool(false) -Warning: DOMDocument::loadXML(): %Sfailed to load external entity "%s" in %s on line %d +%s: DOMDocument::loadXML(): %Sfailed to load %s bool(true) Done From 5bd04acfe9c21d2e647314c8a4e7788a833bc4ef Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 12 Oct 2024 00:37:21 +0200 Subject: [PATCH 6/8] Workaround deprecation warning in zend_test on 8.1 --- ext/zend_test/test.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index c2a6bd18a54..40875304ad0 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -280,16 +280,39 @@ static ZEND_FUNCTION(zend_get_current_func_name) } #if defined(HAVE_LIBXML) && !defined(PHP_WIN32) + +/* This test relies on deprecated code to modify the global state of libxml. + * We cannot include the libxml header here as that would create a dependency on libxml from zend_test. + * On 8.2+ this uses ZEND_DIAGNOSTIC_IGNORED_START, but this doesn't exist on 8.1 */ +#if defined(__clang__) +# define PHP_LIBXML_IGNORE_DEPRECATIONS_START \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") +# define PHP_LIBXML_IGNORE_DEPRECATIONS_END \ + _Pragma("clang diagnostic pop") +#elif defined(__GNUC__) +# define PHP_LIBXML_IGNORE_DEPRECATIONS_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define PHP_LIBXML_IGNORE_DEPRECATIONS_END \ + _Pragma("GCC diagnostic pop") +#else +# define PHP_LIBXML_IGNORE_DEPRECATIONS_START +# define PHP_LIBXML_IGNORE_DEPRECATIONS_END +#endif + static ZEND_FUNCTION(zend_test_override_libxml_global_state) { ZEND_PARSE_PARAMETERS_NONE(); + PHP_LIBXML_IGNORE_DEPRECATIONS_START xmlLoadExtDtdDefaultValue = 1; xmlDoValidityCheckingDefaultValue = 1; (void) xmlPedanticParserDefault(1); (void) xmlSubstituteEntitiesDefault(1); (void) xmlLineNumbersDefault(1); (void) xmlKeepBlanksDefault(0); + PHP_LIBXML_IGNORE_DEPRECATIONS_END } #endif From 14c107371ccc0f263ab08e65e5c7aaaef23843a1 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 7/8] Backport 061058a9: Test fixes for libxml2 2.12.0 --- 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 ++-- 10 files changed, 127 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 14d99e4ed9a..2af3217bd6c 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-- += 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 00000000000..e1ded0ffadd --- /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-- += 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 +--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 ff5ceb3fbed..f52d3348138 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-- = 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 00000000000..88f86664b1d --- /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-- += 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 +--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(): %s + +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 f736b0a0e81..2da8c0cd18b 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-- += 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 00000000000..183c8406fdf --- /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-- += 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 +--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 32b6bf16114..4d9f992b3ba 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-- = 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 00000000000..28e72859b65 --- /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-- += 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 +--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(): %s + +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 78aea041046..7380a9a9370 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 86dede1730f..a23ec8741d5 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) From 2c40762b4e69a6fb4d3e031326667436495cdce3 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 12 Oct 2024 10:29:12 +0200 Subject: [PATCH 8/8] Fix error message for newer libxml Normally I would backport 3354cc6e, but this doesn't apply cleanly due to observer changes. --- ext/zend_test/tests/observer_error_04.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/zend_test/tests/observer_error_04.phpt b/ext/zend_test/tests/observer_error_04.phpt index da0bc4b6c94..40c18e22dff 100644 --- a/ext/zend_test/tests/observer_error_04.phpt +++ b/ext/zend_test/tests/observer_error_04.phpt @@ -40,7 +40,7 @@ echo 'Done.' . PHP_EOL; -SOAP-ERROR: Parsing WSDL: Couldn't load from 'foo' : failed to load external entity "foo" +SOAP-ERROR: Parsing WSDL: %s Done.