Skip to content

Commit 941a7e5

Browse files
committed
Avoid allocation when getting the node content, if possible
Closes phpGH-11543.
1 parent ed6df1f commit 941a7e5

File tree

7 files changed

+57
-61
lines changed

7 files changed

+57
-61
lines changed

ext/dom/attr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ int dom_attr_value_read(dom_object *obj, zval *retval)
121121
return FAILURE;
122122
}
123123

124+
/* Can't avoid a content copy because it's an attribute node */
124125
if ((content = xmlNodeGetContent((xmlNodePtr) attrp)) != NULL) {
125126
ZVAL_STRING(retval, (char *) content);
126127
xmlFree(content);

ext/dom/characterdata.c

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,13 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-
3838
int dom_characterdata_data_read(dom_object *obj, zval *retval)
3939
{
4040
xmlNodePtr nodep = dom_object_get_node(obj);
41-
xmlChar *content;
4241

4342
if (nodep == NULL) {
4443
php_dom_throw_error(INVALID_STATE_ERR, 1);
4544
return FAILURE;
4645
}
4746

48-
if ((content = xmlNodeGetContent(nodep)) != NULL) {
49-
ZVAL_STRING(retval, (char *) content);
50-
xmlFree(content);
51-
} else {
52-
ZVAL_EMPTY_STRING(retval);
53-
}
47+
php_dom_get_content_into_zval(nodep, retval, false);
5448

5549
return SUCCESS;
5650
}
@@ -86,19 +80,15 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-
8680
int dom_characterdata_length_read(dom_object *obj, zval *retval)
8781
{
8882
xmlNodePtr nodep = dom_object_get_node(obj);
89-
xmlChar *content;
9083
long length = 0;
9184

9285
if (nodep == NULL) {
9386
php_dom_throw_error(INVALID_STATE_ERR, 1);
9487
return FAILURE;
9588
}
9689

97-
content = xmlNodeGetContent(nodep);
98-
99-
if (content) {
100-
length = xmlUTF8Strlen(content);
101-
xmlFree(content);
90+
if (nodep->content) {
91+
length = xmlUTF8Strlen(nodep->content);
10292
}
10393

10494
ZVAL_LONG(retval, length);
@@ -128,15 +118,14 @@ PHP_METHOD(DOMCharacterData, substringData)
128118

129119
DOM_GET_OBJ(node, id, xmlNodePtr, intern);
130120

131-
cur = xmlNodeGetContent(node);
121+
cur = node->content;
132122
if (cur == NULL) {
133123
RETURN_FALSE;
134124
}
135125

136126
length = xmlUTF8Strlen(cur);
137127

138128
if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
139-
xmlFree(cur);
140129
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
141130
RETURN_FALSE;
142131
}
@@ -146,7 +135,6 @@ PHP_METHOD(DOMCharacterData, substringData)
146135
}
147136

148137
substring = xmlUTF8Strsub(cur, (int)offset, (int)count);
149-
xmlFree(cur);
150138

151139
if (substring) {
152140
RETVAL_STRING((char *) substring);
@@ -200,22 +188,20 @@ PHP_METHOD(DOMCharacterData, insertData)
200188

201189
DOM_GET_OBJ(node, id, xmlNodePtr, intern);
202190

203-
cur = xmlNodeGetContent(node);
191+
cur = node->content;
204192
if (cur == NULL) {
205193
RETURN_FALSE;
206194
}
207195

208196
length = xmlUTF8Strlen(cur);
209197

210198
if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || offset > length) {
211-
xmlFree(cur);
212199
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
213200
RETURN_FALSE;
214201
}
215202

216203
first = xmlUTF8Strndup(cur, (int)offset);
217204
second = xmlUTF8Strsub(cur, (int)offset, length - (int)offset);
218-
xmlFree(cur);
219205

220206
xmlNodeSetContent(node, first);
221207
xmlNodeAddContent(node, (xmlChar *) arg);
@@ -247,15 +233,14 @@ PHP_METHOD(DOMCharacterData, deleteData)
247233

248234
DOM_GET_OBJ(node, id, xmlNodePtr, intern);
249235

250-
cur = xmlNodeGetContent(node);
236+
cur = node->content;
251237
if (cur == NULL) {
252238
RETURN_FALSE;
253239
}
254240

255241
length = xmlUTF8Strlen(cur);
256242

257243
if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
258-
xmlFree(cur);
259244
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
260245
RETURN_FALSE;
261246
}
@@ -275,7 +260,6 @@ PHP_METHOD(DOMCharacterData, deleteData)
275260

276261
xmlNodeSetContent(node, substring);
277262

278-
xmlFree(cur);
279263
xmlFree(second);
280264
xmlFree(substring);
281265

@@ -304,15 +288,14 @@ PHP_METHOD(DOMCharacterData, replaceData)
304288

305289
DOM_GET_OBJ(node, id, xmlNodePtr, intern);
306290

307-
cur = xmlNodeGetContent(node);
291+
cur = node->content;
308292
if (cur == NULL) {
309293
RETURN_FALSE;
310294
}
311295

312296
length = xmlUTF8Strlen(cur);
313297

314298
if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
315-
xmlFree(cur);
316299
php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
317300
RETURN_FALSE;
318301
}
@@ -336,7 +319,6 @@ PHP_METHOD(DOMCharacterData, replaceData)
336319

337320
xmlNodeSetContent(node, substring);
338321

339-
xmlFree(cur);
340322
if (second) {
341323
xmlFree(second);
342324
}

ext/dom/node.c

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-
124124
int dom_node_node_value_read(dom_object *obj, zval *retval)
125125
{
126126
xmlNode *nodep = dom_object_get_node(obj);
127-
char *str = NULL;
128127

129128
if (nodep == NULL) {
130129
php_dom_throw_error(INVALID_STATE_ERR, 1);
@@ -139,25 +138,24 @@ int dom_node_node_value_read(dom_object *obj, zval *retval)
139138
case XML_COMMENT_NODE:
140139
case XML_CDATA_SECTION_NODE:
141140
case XML_PI_NODE:
142-
str = (char *) xmlNodeGetContent(nodep);
141+
php_dom_get_content_into_zval(nodep, retval, true);
143142
break;
144-
case XML_NAMESPACE_DECL:
145-
str = (char *) xmlNodeGetContent(nodep->children);
143+
case XML_NAMESPACE_DECL: {
144+
char *str = (char *) xmlNodeGetContent(nodep->children);
145+
if (str != NULL) {
146+
ZVAL_STRING(retval, str);
147+
xmlFree(str);
148+
} else {
149+
ZVAL_NULL(retval);
150+
}
146151
break;
152+
}
147153
default:
148-
str = NULL;
154+
ZVAL_NULL(retval);
149155
break;
150156
}
151157

152-
if(str != NULL) {
153-
ZVAL_STRING(retval, str);
154-
xmlFree(str);
155-
} else {
156-
ZVAL_NULL(retval);
157-
}
158-
159158
return SUCCESS;
160-
161159
}
162160

163161
int dom_node_node_value_write(dom_object *obj, zval *newval)
@@ -733,21 +731,13 @@ Since: DOM Level 3
733731
int dom_node_text_content_read(dom_object *obj, zval *retval)
734732
{
735733
xmlNode *nodep = dom_object_get_node(obj);
736-
char *str = NULL;
737734

738735
if (nodep == NULL) {
739736
php_dom_throw_error(INVALID_STATE_ERR, 1);
740737
return FAILURE;
741738
}
742739

743-
str = (char *) xmlNodeGetContent(nodep);
744-
745-
if (str != NULL) {
746-
ZVAL_STRING(retval, str);
747-
xmlFree(str);
748-
} else {
749-
ZVAL_EMPTY_STRING(retval);
750-
}
740+
php_dom_get_content_into_zval(nodep, retval, false);
751741

752742
return SUCCESS;
753743
}

ext/dom/php_dom.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,39 @@ void dom_remove_all_children(xmlNodePtr nodep)
17411741
}
17421742
}
17431743

1744+
void php_dom_get_content_into_zval(const xmlNode *nodep, zval *retval, bool default_is_null)
1745+
{
1746+
ZEND_ASSERT(nodep != NULL);
1747+
1748+
if (nodep->type == XML_TEXT_NODE
1749+
|| nodep->type == XML_CDATA_SECTION_NODE
1750+
|| nodep->type == XML_PI_NODE
1751+
|| nodep->type == XML_COMMENT_NODE) {
1752+
char *str = (char * ) nodep->content;
1753+
if (str != NULL) {
1754+
ZVAL_STRING(retval, str);
1755+
} else {
1756+
goto failure;
1757+
}
1758+
return;
1759+
}
1760+
1761+
char *str = (char *) xmlNodeGetContent(nodep);
1762+
1763+
if (str != NULL) {
1764+
ZVAL_STRING(retval, str);
1765+
xmlFree(str);
1766+
return;
1767+
}
1768+
1769+
failure:
1770+
if (default_is_null) {
1771+
ZVAL_NULL(retval);
1772+
} else {
1773+
ZVAL_EMPTY_STRING(retval);
1774+
}
1775+
}
1776+
17441777
static zval *dom_nodemap_read_dimension(zend_object *object, zval *offset, int type, zval *rv) /* {{{ */
17451778
{
17461779
if (UNEXPECTED(!offset)) {

ext/dom/php_dom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index);
147147
zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref);
148148
void dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce);
149149
xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr original, zval *return_value, dom_object *parent_intern);
150+
void php_dom_get_content_into_zval(const xmlNode *nodep, zval *target, bool default_is_null);
150151

151152
void dom_parent_node_prepend(dom_object *context, zval *nodes, uint32_t nodesc);
152153
void dom_parent_node_append(dom_object *context, zval *nodes, uint32_t nodesc);

ext/dom/processinginstruction.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,14 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-83
9393
*/
9494
int dom_processinginstruction_data_read(dom_object *obj, zval *retval)
9595
{
96-
xmlNodePtr nodep;
97-
xmlChar *content;
98-
99-
nodep = dom_object_get_node(obj);
96+
xmlNodePtr nodep = dom_object_get_node(obj);
10097

10198
if (nodep == NULL) {
10299
php_dom_throw_error(INVALID_STATE_ERR, 1);
103100
return FAILURE;
104101
}
105102

106-
if ((content = xmlNodeGetContent(nodep)) != NULL) {
107-
ZVAL_STRING(retval, (char *) content);
108-
xmlFree(content);
109-
} else {
110-
ZVAL_EMPTY_STRING(retval);
111-
}
103+
php_dom_get_content_into_zval(nodep, retval, false);
112104

113105
return SUCCESS;
114106
}

ext/dom/text.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ PHP_METHOD(DOMText, splitText)
132132
RETURN_FALSE;
133133
}
134134

135-
cur = xmlNodeGetContent(node);
135+
cur = node->content;
136136
if (cur == NULL) {
137137
/* TODO Add warning? */
138138
RETURN_FALSE;
@@ -141,15 +141,12 @@ PHP_METHOD(DOMText, splitText)
141141

142142
if (ZEND_LONG_INT_OVFL(offset) || (int)offset > length) {
143143
/* TODO Add warning? */
144-
xmlFree(cur);
145144
RETURN_FALSE;
146145
}
147146

148147
first = xmlUTF8Strndup(cur, (int)offset);
149148
second = xmlUTF8Strsub(cur, (int)offset, (int)(length - offset));
150149

151-
xmlFree(cur);
152-
153150
xmlNodeSetContent(node, first);
154151
nnode = xmlNewDocText(node->doc, second);
155152

0 commit comments

Comments
 (0)