summaryrefslogtreecommitdiff
path: root/ext/xmlwriter/php_xmlwriter.c
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-02-03 23:10:20 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2020-02-03 23:31:46 +0100
commitfe1bfb78d65d28dd151da417477a0cee51de8afb (patch)
treeef3cb80b0b846a838ec47cb3266b080223cabfe3 /ext/xmlwriter/php_xmlwriter.c
parentb93e4aa11c409ae34c9088ba976117438fc80b9c (diff)
downloadphp-git-fe1bfb78d65d28dd151da417477a0cee51de8afb.tar.gz
Fix #79191: Error in SoapClient ctor disables DOMDocument::save()
The culprit is the too restrictive fix for bug #71536, which prevents `php_libxml_streams_IO_write()` from properly executing when unclean shutdown is flagged. A *more* suitable solution is to move the `xmlwriter_free_resource_ptr()` call from the `free_obj` handler to an added `dtor_obj` handler, to avoid to write to a closed stream in case of late object freeing. This makes the `EG(active)` guard superfluous. We also fix bug79029.phpt which has to use different variables for the three parts to actually check the original shutdown issue. Thanks to bwoebi and daverandom for helping to investigate this issue.
Diffstat (limited to 'ext/xmlwriter/php_xmlwriter.c')
-rw-r--r--ext/xmlwriter/php_xmlwriter.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c
index 24bb9dd182..aac3049b2f 100644
--- a/ext/xmlwriter/php_xmlwriter.c
+++ b/ext/xmlwriter/php_xmlwriter.c
@@ -91,15 +91,13 @@ typedef int (*xmlwriter_read_int_t)(xmlTextWriterPtr writer);
static void xmlwriter_free_resource_ptr(xmlwriter_object *intern)
{
if (intern) {
- if (EG(active)) {
- if (intern->ptr) {
- xmlFreeTextWriter(intern->ptr);
- intern->ptr = NULL;
- }
- if (intern->output) {
- xmlBufferFree(intern->output);
- intern->output = NULL;
- }
+ if (intern->ptr) {
+ xmlFreeTextWriter(intern->ptr);
+ intern->ptr = NULL;
+ }
+ if (intern->output) {
+ xmlBufferFree(intern->output);
+ intern->output = NULL;
}
efree(intern);
}
@@ -120,17 +118,25 @@ static void xmlwriter_free_resource_ptr(xmlwriter_object *intern)
static zend_object_handlers xmlwriter_object_handlers;
-/* {{{ xmlwriter_object_free_storage */
-static void xmlwriter_object_free_storage(zend_object *object)
+/* {{{{ xmlwriter_object_dtor */
+static void xmlwriter_object_dtor(zend_object *object)
{
ze_xmlwriter_object *intern = php_xmlwriter_fetch_object(object);
- if (!intern) {
- return;
- }
+
+ /* freeing the resource here may leak, but otherwise we may use it after it has been freed */
if (intern->xmlwriter_ptr) {
xmlwriter_free_resource_ptr(intern->xmlwriter_ptr);
}
intern->xmlwriter_ptr = NULL;
+ zend_objects_destroy_object(object);
+}
+/* }}} */
+
+/* {{{ xmlwriter_object_free_storage */
+static void xmlwriter_object_free_storage(zend_object *object)
+{
+ ze_xmlwriter_object *intern = php_xmlwriter_fetch_object(object);
+
zend_object_std_dtor(&intern->std);
}
/* }}} */
@@ -1844,6 +1850,7 @@ static PHP_MINIT_FUNCTION(xmlwriter)
memcpy(&xmlwriter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
xmlwriter_object_handlers.offset = XtOffsetOf(ze_xmlwriter_object, std);
+ xmlwriter_object_handlers.dtor_obj = xmlwriter_object_dtor;
xmlwriter_object_handlers.free_obj = xmlwriter_object_free_storage;
xmlwriter_object_handlers.clone_obj = NULL;
INIT_CLASS_ENTRY(ce, "XMLWriter", xmlwriter_class_functions);