Skip to content

Commit 5c69b2e

Browse files
committed
Factor out reading an attribute value
1 parent 4829b8f commit 5c69b2e

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

ext/dom/attr.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,34 @@ PHP_METHOD(DOMAttr, isId)
199199
}
200200
/* }}} end dom_attr_is_id */
201201

202+
xmlChar *dom_attr_value(const xmlAttr *attr, bool *free)
203+
{
204+
/* For attributes we can have an optimized fast-path.
205+
* This fast-path is only possible in the (common) case where the attribute
206+
* has a single text child. Note that if the child or the content is NULL, this
207+
* is equivalent to not having content (i.e. the attribute has the empty string as value). */
208+
209+
*free = false;
210+
211+
if (attr->children == NULL) {
212+
return BAD_CAST "";
213+
}
214+
215+
if (attr->children->type == XML_TEXT_NODE && attr->children->next == NULL) {
216+
if (attr->children->content == NULL) {
217+
return BAD_CAST "";
218+
} else {
219+
return attr->children->content;
220+
}
221+
}
222+
223+
xmlChar *value = xmlNodeGetContent((const xmlNode *) attr);
224+
if (UNEXPECTED(value == NULL)) {
225+
return BAD_CAST "";
226+
}
227+
228+
*free = true;
229+
return value;
230+
}
231+
202232
#endif

ext/dom/php_dom.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,24 +2273,13 @@ void php_dom_get_content_into_zval(const xmlNode *nodep, zval *return_value, boo
22732273
}
22742274

22752275
case XML_ATTRIBUTE_NODE: {
2276-
/* For attributes we can also have an optimized fast-path.
2277-
* This fast-path is only possible in the (common) case where the attribute
2278-
* has a single text child. Note that if the child or the content is NULL, this
2279-
* is equivalent to not having content (i.e. the attribute has the empty string as value). */
2280-
2281-
if (nodep->children == NULL) {
2282-
RETURN_EMPTY_STRING();
2283-
}
2284-
2285-
if (nodep->children->type == XML_TEXT_NODE && nodep->children->next == NULL) {
2286-
if (nodep->children->content == NULL) {
2287-
RETURN_EMPTY_STRING();
2288-
} else {
2289-
RETURN_STRING((const char *) nodep->children->content);
2290-
}
2276+
bool free;
2277+
xmlChar *value = dom_attr_value((const xmlAttr *) nodep, &free);
2278+
RETURN_STRING_FAST((const char *) value);
2279+
if (free) {
2280+
xmlFree(value);
22912281
}
2292-
2293-
ZEND_FALLTHROUGH;
2282+
return;
22942283
}
22952284

22962285
default: {

ext/dom/php_dom.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ void dom_document_convert_to_modern(php_libxml_ref_obj *document, xmlDocPtr lxml
174174
dom_object *php_dom_instantiate_object_helper(zval *return_value, zend_class_entry *ce, xmlNodePtr obj, dom_object *parent);
175175
xmlDocPtr php_dom_create_html_doc(void);
176176

177+
xmlChar *dom_attr_value(const xmlAttr *attr, bool *free);
178+
177179
typedef enum {
178180
DOM_LOAD_STRING = 0,
179181
DOM_LOAD_FILE = 1,

0 commit comments

Comments
 (0)