Skip to content

Commit 785bc24

Browse files
author
Rob Richards
committed
fix compile when ZTS enabled
fix bunch of memory leaks
1 parent 82ddb23 commit 785bc24

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

ext/simplexml/simplexml.c

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ sxe_property_read(zval *object, zval *member TSRMLS_DC)
106106
xmlAttrPtr attr;
107107
int counter = 0;
108108

109-
MAKE_STD_ZVAL(return_value);
109+
ALLOC_ZVAL(return_value);
110+
return_value->refcount = 0;
110111
ZVAL_NULL(return_value);
111112

112113
name = Z_STRVAL_P(member);
@@ -121,9 +122,9 @@ sxe_property_read(zval *object, zval *member TSRMLS_DC)
121122
APPEND_PREV_ELEMENT(counter, value);
122123

123124
MAKE_STD_ZVAL(value);
125+
value->refcount = 0;
124126
contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1);
125127
ZVAL_STRING(value, contents, 0);
126-
127128
APPEND_CUR_ELEMENT(counter, value);
128129
}
129130
attr = attr->next;
@@ -146,17 +147,19 @@ sxe_property_read(zval *object, zval *member TSRMLS_DC)
146147

147148
if (match_ns(sxe, node, name)) {
148149
MAKE_STD_ZVAL(value);
149-
_node_as_zval(sxe, node->parent, value);
150+
_node_as_zval(sxe, node->parent, value TSRMLS_CC);
151+
value->refcount = 0;
150152
APPEND_CUR_ELEMENT(counter, value);
151153
goto next_iter;
152154
}
153155
}
154156

155157
if (!xmlStrcmp(node->name, name)) {
156158
APPEND_PREV_ELEMENT(counter, value);
157-
159+
158160
MAKE_STD_ZVAL(value);
159161
_node_as_zval(sxe, node, value TSRMLS_CC);
162+
value->refcount = 0;
160163

161164
APPEND_CUR_ELEMENT(counter, value);
162165
}
@@ -167,6 +170,9 @@ sxe_property_read(zval *object, zval *member TSRMLS_DC)
167170

168171
/* Only one value found */
169172
if (counter == 1) {
173+
SEPARATE_ZVAL(&value);
174+
zval_dtor(return_value);
175+
FREE_ZVAL(return_value);
170176
return_value = value;
171177
}
172178

@@ -328,7 +334,8 @@ sxe_property_delete(zval *object, zval *member TSRMLS_DC)
328334
while (attr) {
329335
anext = attr->next;
330336
if (!xmlStrcmp(attr->name, Z_STRVAL_P(member))) {
331-
// free
337+
xmlUnlinkNode((xmlNodePtr) attr);
338+
xmlFreeProp(attr);
332339
}
333340
attr = anext;
334341
}
@@ -353,7 +360,7 @@ sxe_property_delete(zval *object, zval *member TSRMLS_DC)
353360
/* {{{ _get_base_node_value()
354361
*/
355362
static void
356-
_get_base_node_value(xmlNodePtr node, zval **value TSRMLS_CC)
363+
_get_base_node_value(xmlNodePtr node, zval **value TSRMLS_DC)
357364
{
358365
php_sxe_object *subnode;
359366
char *contents;
@@ -364,6 +371,7 @@ _get_base_node_value(xmlNodePtr node, zval **value TSRMLS_CC)
364371
contents = xmlNodeListGetString(node->doc, node->children, 1);
365372
if (contents) {
366373
ZVAL_STRING(*value, contents, 1);
374+
xmlFree(contents);
367375
}
368376
} else {
369377
subnode = php_sxe_object_new(TSRMLS_C);
@@ -455,6 +463,7 @@ sxe_objects_compare(zval *object1, zval *object2 TSRMLS_DC)
455463
} else {
456464
return !(sxe1->node == sxe2->node);
457465
}
466+
return 1;
458467
}
459468
/* }}} */
460469

@@ -525,9 +534,9 @@ simplexml_ce_xpath_search(INTERNAL_FUNCTION_PARAMETERS)
525534
* to the parent node.
526535
*/
527536
if (result->nodeTab[i]->type == XML_TEXT_NODE) {
528-
_node_as_zval(sxe, result->nodeTab[i]->parent, value);
537+
_node_as_zval(sxe, result->nodeTab[i]->parent, value TSRMLS_CC);
529538
} else {
530-
_node_as_zval(sxe, result->nodeTab[i], value);
539+
_node_as_zval(sxe, result->nodeTab[i], value TSRMLS_CC);
531540
}
532541
add_next_index_zval(return_value, value);
533542
}
@@ -576,6 +585,7 @@ simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
576585
is_valid = xmlSchemaValidateDoc(vptr, (xmlDocPtr) sxe->document->ptr);
577586
xmlSchemaFree(sptr);
578587
xmlSchemaFreeValidCtxt(vptr);
588+
xmlSchemaFreeParserCtxt(parser);
579589

580590
if (is_valid) {
581591
RETURN_TRUE;
@@ -683,7 +693,7 @@ static void
683693
sxe_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC)
684694
{
685695
php_sxe_object *sxe;
686-
char *contents;
696+
char *contents = NULL;
687697

688698
sxe = php_sxe_fetch_object(readobj TSRMLS_CC);
689699

@@ -699,6 +709,10 @@ sxe_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_
699709
}
700710

701711
cast_object(writeobj, type, contents TSRMLS_CC);
712+
713+
if (contents) {
714+
xmlFree(contents);
715+
}
702716
}
703717
/* }}} */
704718

@@ -783,20 +797,25 @@ sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
783797

784798
sxe = (php_sxe_object *) object;
785799

800+
zend_hash_destroy(sxe->zo.properties);
786801
FREE_HASHTABLE(sxe->zo.properties);
787802

788-
if (--sxe->document->refcount > 0) {
789-
return;
803+
if (sxe->document) {
804+
if (--sxe->document->refcount == 0) {
805+
if (sxe->document->ptr) {
806+
xmlFreeDoc(sxe->document->ptr);
807+
}
808+
efree(sxe->document);
809+
sxe->document = NULL;
810+
xmlHashFree(sxe->nsmap, _free_ns_entry);
811+
}
790812
}
791-
xmlFreeDoc(sxe->document->ptr);
792-
efree(sxe->document);
793-
813+
794814
if (sxe->xpath) {
795815
xmlXPathFreeContext(sxe->xpath);
796816
}
797817

798-
xmlHashFree(sxe->nsmap, _free_ns_entry);
799-
zend_objects_destroy_object(object, handle TSRMLS_CC);
818+
efree(object);
800819
}
801820
/* }}} */
802821

@@ -811,6 +830,9 @@ php_sxe_object_new(TSRMLS_D)
811830
intern->zo.ce = sxe_class_entry;
812831
intern->zo.in_get = 0;
813832
intern->zo.in_set = 0;
833+
intern->document = NULL;
834+
intern->nsmap = NULL;
835+
intern->xpath = NULL;
814836

815837
ALLOC_HASHTABLE(intern->zo.properties);
816838
zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
@@ -990,6 +1012,7 @@ PHP_MINIT_FUNCTION(simplexml)
9901012
*/
9911013
PHP_MSHUTDOWN_FUNCTION(simplexml)
9921014
{
1015+
xmlCleanupParser();
9931016
return SUCCESS;
9941017
}
9951018
/* }}} */

0 commit comments

Comments
 (0)