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>
@@ -1461,8 +1462,7 @@ PHP_METHOD(DOMDocument, saveXML)
1461
1462
zval * id , * nodep = NULL ;
1462
1463
xmlDoc * docp ;
1463
1464
xmlNode * node ;
1464
- xmlBufferPtr buf ;
1465
- xmlChar * mem ;
1465
+ const char * mem ;
1466
1466
dom_object * intern , * nodeobj ;
1467
1467
int size , format , saveempty = 0 ;
1468
1468
zend_long options = 0 ;
@@ -1477,18 +1477,20 @@ PHP_METHOD(DOMDocument, saveXML)
1477
1477
libxml_doc_props const * doc_props = dom_get_doc_props_read_only (intern -> document );
1478
1478
format = doc_props -> formatoutput ;
1479
1479
1480
+ xmlBufferPtr buf = xmlBufferCreate ();
1481
+ if (!buf ) {
1482
+ php_error_docref (NULL , E_WARNING , "Could not fetch buffer" );
1483
+ RETURN_FALSE ;
1484
+ }
1485
+
1480
1486
if (nodep != NULL ) {
1481
1487
/* Dump contents of Node */
1482
1488
DOM_GET_OBJ (node , nodep , xmlNodePtr , nodeobj );
1483
1489
if (node -> doc != docp ) {
1490
+ xmlBufferFree (buf );
1484
1491
php_dom_throw_error (WRONG_DOCUMENT_ERR , dom_get_strict_error (intern -> document ));
1485
1492
RETURN_FALSE ;
1486
1493
}
1487
- buf = xmlBufferCreate ();
1488
- if (!buf ) {
1489
- php_error_docref (NULL , E_WARNING , "Could not fetch buffer" );
1490
- RETURN_FALSE ;
1491
- }
1492
1494
if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1493
1495
saveempty = xmlSaveNoEmptyTags ;
1494
1496
xmlSaveNoEmptyTags = 1 ;
@@ -1497,29 +1499,45 @@ PHP_METHOD(DOMDocument, saveXML)
1497
1499
if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1498
1500
xmlSaveNoEmptyTags = saveempty ;
1499
1501
}
1500
- mem = (xmlChar * ) xmlBufferContent (buf );
1501
- if (!mem ) {
1502
- xmlBufferFree (buf );
1503
- RETURN_FALSE ;
1504
- }
1505
- RETVAL_STRING ((char * ) mem );
1506
- xmlBufferFree (buf );
1507
1502
} else {
1508
1503
if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1509
1504
saveempty = xmlSaveNoEmptyTags ;
1510
1505
xmlSaveNoEmptyTags = 1 ;
1511
1506
}
1507
+ int convertedOptions = XML_SAVE_AS_XML ;
1508
+ if (options & XML_SAVE_NO_DECL ) {
1509
+ convertedOptions |= XML_SAVE_NO_DECL ;
1510
+ }
1511
+ if (format ) {
1512
+ convertedOptions |= XML_SAVE_FORMAT ;
1513
+ }
1512
1514
/* Encoding is handled from the encoding property set on the document */
1513
- xmlDocDumpFormatMemory ( docp , & mem , & size , format );
1515
+ xmlSaveCtxtPtr ctxt = xmlSaveToBuffer ( buf , ( const char * ) docp -> encoding , convertedOptions );
1514
1516
if (options & LIBXML_SAVE_NOEMPTYTAG ) {
1515
1517
xmlSaveNoEmptyTags = saveempty ;
1516
1518
}
1517
- if (!size || !mem ) {
1519
+ if (UNEXPECTED (!ctxt )) {
1520
+ xmlBufferFree (buf );
1521
+ php_error_docref (NULL , E_WARNING , "Could not create save context" );
1518
1522
RETURN_FALSE ;
1519
1523
}
1520
- RETVAL_STRINGL ((char * ) mem , size );
1521
- xmlFree (mem );
1524
+ if (UNEXPECTED (xmlSaveDoc (ctxt , docp ) < 0 )) {
1525
+ xmlBufferFree (buf );
1526
+ (void ) xmlSaveClose (ctxt );
1527
+ php_error_docref (NULL , E_WARNING , "Could not save document" );
1528
+ RETURN_FALSE ;
1529
+ }
1530
+ (void ) xmlSaveFlush (ctxt );
1531
+ (void ) xmlSaveClose (ctxt );
1532
+ }
1533
+ mem = (const char * ) xmlBufferContent (buf );
1534
+ if (!mem ) {
1535
+ xmlBufferFree (buf );
1536
+ RETURN_FALSE ;
1522
1537
}
1538
+ size = xmlBufferLength (buf );
1539
+ RETVAL_STRINGL (mem , size );
1540
+ xmlBufferFree (buf );
1523
1541
}
1524
1542
/* }}} end dom_document_savexml */
1525
1543
0 commit comments