Skip to content

Commit b3899eb

Browse files
committed
Refactor dom_node_node_name_read() to avoid double allocation
We will use this helper later outside of the node name read handler.
1 parent 62ef7bb commit b3899eb

File tree

2 files changed

+39
-37
lines changed

2 files changed

+39
-37
lines changed

ext/dom/node.c

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,36 @@
3030
* Since:
3131
*/
3232

33+
zend_string *dom_node_concatenated_name_helper(size_t name_len, const char *name, size_t prefix_len, const char *prefix)
34+
{
35+
if (UNEXPECTED(prefix_len > ZSTR_MAX_LEN / 2 - 1 || name_len > ZSTR_MAX_LEN / 2 - 1)) {
36+
return zend_empty_string;
37+
}
38+
zend_string *str = zend_string_alloc(prefix_len + 1 + name_len, false);
39+
memcpy(ZSTR_VAL(str), prefix, prefix_len);
40+
ZSTR_VAL(str)[prefix_len] = ':';
41+
memcpy(ZSTR_VAL(str) + prefix_len + 1, name, name_len + 1 /* include \0 */);
42+
return str;
43+
}
44+
45+
zend_string *dom_node_get_node_name_attribute_or_element(const xmlNode *nodep)
46+
{
47+
size_t name_len = strlen((const char *) nodep->name);
48+
if (nodep->ns != NULL && nodep->ns->prefix != NULL) {
49+
return dom_node_concatenated_name_helper(name_len, (const char *) nodep->name, strlen((const char *) nodep->ns->prefix), (const char *) nodep->ns->prefix);
50+
} else {
51+
return zend_string_init((const char *) nodep->name, name_len, false);
52+
}
53+
}
54+
3355
/* {{{ nodeName string
3456
readonly=yes
3557
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
3658
Since:
3759
*/
3860
int dom_node_node_name_read(dom_object *obj, zval *retval)
3961
{
40-
xmlNode *nodep;
41-
xmlNsPtr ns;
42-
char *str = NULL;
43-
xmlChar *qname = NULL;
44-
45-
nodep = dom_object_get_node(obj);
62+
xmlNode *nodep = dom_object_get_node(obj);
4663

4764
if (nodep == NULL) {
4865
php_dom_throw_error(INVALID_STATE_ERR, 1);
@@ -52,66 +69,49 @@ int dom_node_node_name_read(dom_object *obj, zval *retval)
5269
switch (nodep->type) {
5370
case XML_ATTRIBUTE_NODE:
5471
case XML_ELEMENT_NODE:
55-
ns = nodep->ns;
56-
if (ns != NULL && ns->prefix) {
57-
qname = xmlStrdup(ns->prefix);
58-
qname = xmlStrcat(qname, (xmlChar *) ":");
59-
qname = xmlStrcat(qname, nodep->name);
60-
str = (char *) qname;
61-
} else {
62-
str = (char *) nodep->name;
63-
}
72+
ZVAL_STR(retval, dom_node_get_node_name_attribute_or_element(nodep));
6473
break;
65-
case XML_NAMESPACE_DECL:
66-
ns = nodep->ns;
74+
case XML_NAMESPACE_DECL: {
75+
xmlNsPtr ns = nodep->ns;
6776
if (ns != NULL && ns->prefix) {
68-
qname = xmlStrdup((xmlChar *) "xmlns");
77+
xmlChar *qname = xmlStrdup((xmlChar *) "xmlns");
6978
qname = xmlStrcat(qname, (xmlChar *) ":");
7079
qname = xmlStrcat(qname, nodep->name);
71-
str = (char *) qname;
80+
ZVAL_STRING(retval, (const char *) qname);
81+
xmlFree(qname);
7282
} else {
73-
str = (char *) nodep->name;
83+
ZVAL_STRING(retval, (const char *) nodep->name);
7484
}
7585
break;
86+
}
7687
case XML_DOCUMENT_TYPE_NODE:
7788
case XML_DTD_NODE:
7889
case XML_PI_NODE:
7990
case XML_ENTITY_DECL:
8091
case XML_ENTITY_REF_NODE:
8192
case XML_NOTATION_NODE:
82-
str = (char *) nodep->name;
93+
ZVAL_STRING(retval, (char *) nodep->name);
8394
break;
8495
case XML_CDATA_SECTION_NODE:
85-
str = "#cdata-section";
96+
ZVAL_STRING(retval, "#cdata-section");
8697
break;
8798
case XML_COMMENT_NODE:
88-
str = "#comment";
99+
ZVAL_STRING(retval, "#comment");
89100
break;
90101
case XML_HTML_DOCUMENT_NODE:
91102
case XML_DOCUMENT_NODE:
92-
str = "#document";
103+
ZVAL_STRING(retval, "#document");
93104
break;
94105
case XML_DOCUMENT_FRAG_NODE:
95-
str = "#document-fragment";
106+
ZVAL_STRING(retval, "#document-fragment");
96107
break;
97108
case XML_TEXT_NODE:
98-
str = "#text";
109+
ZVAL_STRING(retval, "#text");
99110
break;
100111
EMPTY_SWITCH_DEFAULT_CASE();
101112
}
102113

103-
if (str != NULL) {
104-
ZVAL_STRING(retval, str);
105-
} else {
106-
ZVAL_EMPTY_STRING(retval);
107-
}
108-
109-
if (qname != NULL) {
110-
xmlFree(qname);
111-
}
112-
113114
return SUCCESS;
114-
115115
}
116116

117117
/* }}} */

ext/dom/php_dom.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
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);
150150
void php_dom_get_content_into_zval(const xmlNode *nodep, zval *target, bool default_is_null);
151+
zend_string *dom_node_concatenated_name_helper(size_t name_len, const char *name, size_t prefix_len, const char *prefix);
152+
zend_string *dom_node_get_node_name_attribute_or_element(const xmlNode *nodep);
151153

152154
void dom_parent_node_prepend(dom_object *context, zval *nodes, uint32_t nodesc);
153155
void dom_parent_node_append(dom_object *context, zval *nodes, uint32_t nodesc);

0 commit comments

Comments
 (0)