mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-11792: LIBXML_NOXMLDECL is not implemented or broken
Fixes GH-11792. Closes GH-11794.
This commit is contained in:
4
NEWS
4
NEWS
@@ -8,6 +8,10 @@ PHP NEWS
|
|||||||
- Core:
|
- Core:
|
||||||
. Fixed oss-fuzz #60741 (Leak in open_basedir). (ilutov)
|
. Fixed oss-fuzz #60741 (Leak in open_basedir). (ilutov)
|
||||||
|
|
||||||
|
- DOM:
|
||||||
|
. Fixed bug GH-11792 (LIBXML_NOXMLDECL is not implemented or broken).
|
||||||
|
(nielsdos)
|
||||||
|
|
||||||
- FFI:
|
- FFI:
|
||||||
. Fix leaking definitions when using FFI::cdef()->new(...). (ilutov)
|
. Fix leaking definitions when using FFI::cdef()->new(...). (ilutov)
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
|
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
|
||||||
#include "php_dom.h"
|
#include "php_dom.h"
|
||||||
#include <libxml/SAX.h>
|
#include <libxml/SAX.h>
|
||||||
|
#include <libxml/xmlsave.h>
|
||||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||||
#include <libxml/relaxng.h>
|
#include <libxml/relaxng.h>
|
||||||
#include <libxml/xmlschemas.h>
|
#include <libxml/xmlschemas.h>
|
||||||
@@ -1462,9 +1463,9 @@ PHP_METHOD(DOMDocument, saveXML)
|
|||||||
xmlDoc *docp;
|
xmlDoc *docp;
|
||||||
xmlNode *node;
|
xmlNode *node;
|
||||||
xmlBufferPtr buf;
|
xmlBufferPtr buf;
|
||||||
xmlChar *mem;
|
const xmlChar *mem;
|
||||||
dom_object *intern, *nodeobj;
|
dom_object *intern, *nodeobj;
|
||||||
int size, format, saveempty = 0;
|
int size, format, old_xml_save_no_empty_tags;
|
||||||
zend_long options = 0;
|
zend_long options = 0;
|
||||||
|
|
||||||
id = ZEND_THIS;
|
id = ZEND_THIS;
|
||||||
@@ -1484,42 +1485,59 @@ PHP_METHOD(DOMDocument, saveXML)
|
|||||||
php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document));
|
php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document));
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = xmlBufferCreate();
|
buf = xmlBufferCreate();
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
php_error_docref(NULL, E_WARNING, "Could not fetch buffer");
|
php_error_docref(NULL, E_WARNING, "Could not fetch buffer");
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
if (options & LIBXML_SAVE_NOEMPTYTAG) {
|
/* Save libxml2 global, override its vaule, and restore after saving. */
|
||||||
saveempty = xmlSaveNoEmptyTags;
|
old_xml_save_no_empty_tags = xmlSaveNoEmptyTags;
|
||||||
xmlSaveNoEmptyTags = 1;
|
xmlSaveNoEmptyTags = (options & LIBXML_SAVE_NOEMPTYTAG) ? 1 : 0;
|
||||||
}
|
|
||||||
xmlNodeDump(buf, docp, node, 0, format);
|
xmlNodeDump(buf, docp, node, 0, format);
|
||||||
if (options & LIBXML_SAVE_NOEMPTYTAG) {
|
xmlSaveNoEmptyTags = old_xml_save_no_empty_tags;
|
||||||
xmlSaveNoEmptyTags = saveempty;
|
|
||||||
}
|
|
||||||
mem = (xmlChar*) xmlBufferContent(buf);
|
|
||||||
if (!mem) {
|
|
||||||
xmlBufferFree(buf);
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
RETVAL_STRING((char *) mem);
|
|
||||||
xmlBufferFree(buf);
|
|
||||||
} else {
|
} else {
|
||||||
if (options & LIBXML_SAVE_NOEMPTYTAG) {
|
buf = xmlBufferCreate();
|
||||||
saveempty = xmlSaveNoEmptyTags;
|
if (!buf) {
|
||||||
xmlSaveNoEmptyTags = 1;
|
php_error_docref(NULL, E_WARNING, "Could not fetch buffer");
|
||||||
}
|
|
||||||
/* Encoding is handled from the encoding property set on the document */
|
|
||||||
xmlDocDumpFormatMemory(docp, &mem, &size, format);
|
|
||||||
if (options & LIBXML_SAVE_NOEMPTYTAG) {
|
|
||||||
xmlSaveNoEmptyTags = saveempty;
|
|
||||||
}
|
|
||||||
if (!size || !mem) {
|
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
RETVAL_STRINGL((char *) mem, size);
|
|
||||||
xmlFree(mem);
|
int converted_options = XML_SAVE_AS_XML;
|
||||||
|
if (options & XML_SAVE_NO_DECL) {
|
||||||
|
converted_options |= XML_SAVE_NO_DECL;
|
||||||
|
}
|
||||||
|
if (format) {
|
||||||
|
converted_options |= XML_SAVE_FORMAT;
|
||||||
|
}
|
||||||
|
/* Save libxml2 global, override its vaule, and restore after saving. */
|
||||||
|
old_xml_save_no_empty_tags = xmlSaveNoEmptyTags;
|
||||||
|
xmlSaveNoEmptyTags = (options & LIBXML_SAVE_NOEMPTYTAG) ? 1 : 0;
|
||||||
|
/* Encoding is handled from the encoding property set on the document */
|
||||||
|
xmlSaveCtxtPtr ctxt = xmlSaveToBuffer(buf, (const char *) docp->encoding, converted_options);
|
||||||
|
xmlSaveNoEmptyTags = old_xml_save_no_empty_tags;
|
||||||
|
if (UNEXPECTED(!ctxt)) {
|
||||||
|
xmlBufferFree(buf);
|
||||||
|
php_error_docref(NULL, E_WARNING, "Could not create save context");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(xmlSaveDoc(ctxt, docp) < 0)) {
|
||||||
|
(void) xmlSaveClose(ctxt);
|
||||||
|
xmlBufferFree(buf);
|
||||||
|
php_error_docref(NULL, E_WARNING, "Could not save document");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
(void) xmlSaveFlush(ctxt);
|
||||||
|
(void) xmlSaveClose(ctxt);
|
||||||
}
|
}
|
||||||
|
mem = xmlBufferContent(buf);
|
||||||
|
if (!mem) {
|
||||||
|
xmlBufferFree(buf);
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
size = xmlBufferLength(buf);
|
||||||
|
RETVAL_STRINGL((const char *) mem, size);
|
||||||
|
xmlBufferFree(buf);
|
||||||
}
|
}
|
||||||
/* }}} end dom_document_savexml */
|
/* }}} end dom_document_savexml */
|
||||||
|
|
||||||
|
|||||||
24
ext/dom/tests/DOMDocument_saveXML_XML_SAVE_NO_DECL.phpt
Normal file
24
ext/dom/tests/DOMDocument_saveXML_XML_SAVE_NO_DECL.phpt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
DOMDocument::saveXML(): XML_SAVE_NO_DECL
|
||||||
|
--EXTENSIONS--
|
||||||
|
dom
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
$doc->loadXML('<root>é</root>');
|
||||||
|
|
||||||
|
echo $doc->saveXML(options: 0);
|
||||||
|
echo $doc->saveXML(options: LIBXML_NOXMLDECL);
|
||||||
|
$doc->encoding = "BIG5";
|
||||||
|
echo $doc->saveXML(options: LIBXML_NOXMLDECL);
|
||||||
|
|
||||||
|
// Edge case
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
var_dump($doc->saveXML(options: LIBXML_NOXMLDECL));
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<root>é</root>
|
||||||
|
<root>é</root>
|
||||||
|
<root>é</root>
|
||||||
|
string(0) ""
|
||||||
Reference in New Issue
Block a user