Skip to content

Backport libxml2 2.13.2 fixes #14816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ext/dom/document.c
Original file line number Diff line number Diff line change
Expand Up @@ -1292,11 +1292,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;
Expand All @@ -1306,7 +1308,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 */
Expand Down
2 changes: 1 addition & 1 deletion ext/dom/tests/DOMDocument_loadHTMLfile_error1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ 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():%sattributes%s

Warning: DOMDocument::loadXML(): Couldn't find end of Start Tag book line 4 in Entity, line: 4 in %s on line %d

Expand Down
2 changes: 1 addition & 1 deletion ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ 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():%sattributes%s

Warning: DOMDocument::load(): Couldn't find end of Start Tag book line 4 in %s on line %d

Expand Down
2 changes: 1 addition & 1 deletion ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Knut Urdalen <knut@php.net>
#PHPTestFest2009 Norway 2009-06-09 \o/
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (LIBXML_VERSION >= 21300) die("skip see https://gitlab.gnome.org/GNOME/libxml2/-/issues/756");
?>
--FILE--
<?php
$filename = __DIR__."/DOMDocument_saveHTMLFile_basic.html";
Expand Down
4 changes: 4 additions & 0 deletions ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Knut Urdalen <knut@php.net>
#PHPTestFest2009 Norway 2009-06-09 \o/
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (LIBXML_VERSION >= 21300) die("skip see https://gitlab.gnome.org/GNOME/libxml2/-/issues/756");
?>
--FILE--
<?php
$filename = __DIR__."/DOMDocument_saveHTMLFile_formatOutput.html";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
DOMDocument::saveHTMLFile() should format output on demand
--CREDITS--
Knut Urdalen <knut@php.net>
#PHPTestFest2009 Norway 2009-06-09 \o/
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (LIBXML_VERSION < 21300) die("skip see https://gitlab.gnome.org/GNOME/libxml2/-/issues/756");
?>
--FILE--
<?php
$filename = __DIR__."/DOMDocument_saveHTMLFile_formatOutput_gte_2_13.html";
$doc = new DOMDocument('1.0');
$doc->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)
<html><head><title>This is the title</title></head></html>
31 changes: 31 additions & 0 deletions ext/dom/tests/DOMDocument_saveHTML_basic_gte_2_13.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--TEST--
DOMDocument::saveHTMLFile() should dump the internal document into a file using HTML formatting
--CREDITS--
Knut Urdalen <knut@php.net>
#PHPTestFest2009 Norway 2009-06-09 \o/
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (LIBXML_VERSION < 21300) die("skip see https://gitlab.gnome.org/GNOME/libxml2/-/issues/756");
?>
--FILE--
<?php
$filename = __DIR__."/DOMDocument_saveHTMLFile_basic_gte_2_13.html";
$doc = new DOMDocument('1.0');
$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)
<html><head><title>This is the title</title></head></html>
2 changes: 1 addition & 1 deletion ext/dom/tests/DOMDocument_schemaValidate_error5.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
14 changes: 4 additions & 10 deletions ext/dom/tests/dom_create_element.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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')
Expand Down
4 changes: 3 additions & 1 deletion ext/libxml/libxml.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,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;
Expand Down
2 changes: 2 additions & 0 deletions ext/libxml/php_libxml.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,15 @@ 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;
ctxt->replaceEntities = 0;
ctxt->linenumbers = 0;
ctxt->keepBlanks = 1;
ctxt->options = 0;
PHP_LIBXML_IGNORE_DEPRECATIONS_END
}

#else /* HAVE_LIBXML */
Expand Down
2 changes: 1 addition & 1 deletion ext/simplexml/tests/bug79971_1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions ext/soap/php_encoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -3374,7 +3374,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);
Expand All @@ -3388,9 +3387,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);
}
}
Expand Down
8 changes: 7 additions & 1 deletion ext/soap/php_xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions ext/soap/tests/bugs/bug42151.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
3 changes: 1 addition & 2 deletions ext/xml/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion ext/xmlwriter/php_xmlwriter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Loading