23
23
#if defined(HAVE_LIBXML ) && defined(HAVE_DOM )
24
24
#include "php_dom.h"
25
25
#include <libxml/SAX.h>
26
+ #include <libxml/xmlsave.h>
26
27
#ifdef LIBXML_SCHEMAS_ENABLED
27
28
#include <libxml/relaxng.h>
28
29
#include <libxml/xmlschemas.h>
@@ -1462,9 +1463,9 @@ PHP_METHOD(DOMDocument, saveXML)
1462
1463
xmlDoc * docp ;
1463
1464
xmlNode * node ;
1464
1465
xmlBufferPtr buf ;
1465
- xmlChar * mem ;
1466
+ const xmlChar * mem ;
1466
1467
dom_object * intern , * nodeobj ;
1467
- int size , format , saveempty = 0 ;
1468
+ int size , format , old_xml_save_no_empty_tags ;
1468
1469
zend_long options = 0 ;
1469
1470
1470
1471
id = ZEND_THIS ;
@@ -1484,42 +1485,59 @@ PHP_METHOD(DOMDocument, saveXML)
1484
1485
php_dom_throw_error (WRONG_DOCUMENT_ERR , dom_get_strict_error (intern -> document ));
1485
1486
RETURN_FALSE ;
1486
1487
}
1488
+
1487
1489
buf = xmlBufferCreate ();
1488
1490
if (!buf ) {
1489
1491
php_error_docref (NULL , E_WARNING , "Could not fetch buffer" );
1490
1492
RETURN_FALSE ;
1491
1493
}
1492
- if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1493
- saveempty = xmlSaveNoEmptyTags ;
1494
- xmlSaveNoEmptyTags = 1 ;
1495
- }
1494
+ /* Save libxml2 global, override its vaule, and restore after saving. */
1495
+ old_xml_save_no_empty_tags = xmlSaveNoEmptyTags ;
1496
+ xmlSaveNoEmptyTags = (options & LIBXML_SAVE_NOEMPTYTAG ) ? 1 : 0 ;
1496
1497
xmlNodeDump (buf , docp , node , 0 , format );
1497
- if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1498
- xmlSaveNoEmptyTags = saveempty ;
1499
- }
1500
- mem = (xmlChar * ) xmlBufferContent (buf );
1501
- if (!mem ) {
1502
- xmlBufferFree (buf );
1498
+ xmlSaveNoEmptyTags = old_xml_save_no_empty_tags ;
1499
+ } else {
1500
+ buf = xmlBufferCreate ();
1501
+ if (!buf ) {
1502
+ php_error_docref (NULL , E_WARNING , "Could not fetch buffer" );
1503
1503
RETURN_FALSE ;
1504
1504
}
1505
- RETVAL_STRING ((char * ) mem );
1506
- xmlBufferFree (buf );
1507
- } else {
1508
- if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1509
- saveempty = xmlSaveNoEmptyTags ;
1510
- xmlSaveNoEmptyTags = 1 ;
1505
+
1506
+ int converted_options = XML_SAVE_AS_XML ;
1507
+ if (options & XML_SAVE_NO_DECL ) {
1508
+ converted_options |= XML_SAVE_NO_DECL ;
1509
+ }
1510
+ if (format ) {
1511
+ converted_options |= XML_SAVE_FORMAT ;
1511
1512
}
1513
+ /* Save libxml2 global, override its vaule, and restore after saving. */
1514
+ old_xml_save_no_empty_tags = xmlSaveNoEmptyTags ;
1515
+ xmlSaveNoEmptyTags = (options & LIBXML_SAVE_NOEMPTYTAG ) ? 1 : 0 ;
1512
1516
/* Encoding is handled from the encoding property set on the document */
1513
- xmlDocDumpFormatMemory (docp , & mem , & size , format );
1514
- if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1515
- xmlSaveNoEmptyTags = saveempty ;
1517
+ xmlSaveCtxtPtr ctxt = xmlSaveToBuffer (buf , (const char * ) docp -> encoding , converted_options );
1518
+ xmlSaveNoEmptyTags = old_xml_save_no_empty_tags ;
1519
+ if (UNEXPECTED (!ctxt )) {
1520
+ xmlBufferFree (buf );
1521
+ php_error_docref (NULL , E_WARNING , "Could not create save context" );
1522
+ RETURN_FALSE ;
1516
1523
}
1517
- if (!size || !mem ) {
1524
+ if (UNEXPECTED (xmlSaveDoc (ctxt , docp ) < 0 )) {
1525
+ (void ) xmlSaveClose (ctxt );
1526
+ xmlBufferFree (buf );
1527
+ php_error_docref (NULL , E_WARNING , "Could not save document" );
1518
1528
RETURN_FALSE ;
1519
1529
}
1520
- RETVAL_STRINGL ((char * ) mem , size );
1521
- xmlFree (mem );
1530
+ (void ) xmlSaveFlush (ctxt );
1531
+ (void ) xmlSaveClose (ctxt );
1532
+ }
1533
+ mem = xmlBufferContent (buf );
1534
+ if (!mem ) {
1535
+ xmlBufferFree (buf );
1536
+ RETURN_FALSE ;
1522
1537
}
1538
+ size = xmlBufferLength (buf );
1539
+ RETVAL_STRINGL ((const char * ) mem , size );
1540
+ xmlBufferFree (buf );
1523
1541
}
1524
1542
/* }}} end dom_document_savexml */
1525
1543
0 commit comments