Move dom_attr_value() into ext/libxml

This commit is contained in:
Niels Dossche 2024-05-04 13:57:07 +02:00
parent 70acd6e9ad
commit fae25ca2df
5 changed files with 34 additions and 33 deletions

View file

@ -199,40 +199,10 @@ PHP_METHOD(DOMAttr, isId)
} }
/* }}} end dom_attr_is_id */ /* }}} end dom_attr_is_id */
xmlChar *dom_attr_value(const xmlAttr *attr, bool *free)
{
/* For attributes we can have an optimized fast-path.
* This fast-path is only possible in the (common) case where the attribute
* has a single text child. Note that if the child or the content is NULL, this
* is equivalent to not having content (i.e. the attribute has the empty string as value). */
*free = false;
if (attr->children == NULL) {
return BAD_CAST "";
}
if (attr->children->type == XML_TEXT_NODE && attr->children->next == NULL) {
if (attr->children->content == NULL) {
return BAD_CAST "";
} else {
return attr->children->content;
}
}
xmlChar *value = xmlNodeGetContent((const xmlNode *) attr);
if (UNEXPECTED(value == NULL)) {
return BAD_CAST "";
}
*free = true;
return value;
}
bool dom_compare_value(const xmlAttr *attr, const xmlChar *value) bool dom_compare_value(const xmlAttr *attr, const xmlChar *value)
{ {
bool free; bool free;
xmlChar *attr_value = dom_attr_value(attr, &free); xmlChar *attr_value = php_libxml_attr_value(attr, &free);
bool result = xmlStrEqual(attr_value, value); bool result = xmlStrEqual(attr_value, value);
if (free) { if (free) {
xmlFree(attr_value); xmlFree(attr_value);

View file

@ -2245,7 +2245,7 @@ void php_dom_get_content_into_zval(const xmlNode *nodep, zval *return_value, boo
case XML_ATTRIBUTE_NODE: { case XML_ATTRIBUTE_NODE: {
bool free; bool free;
xmlChar *value = dom_attr_value((const xmlAttr *) nodep, &free); xmlChar *value = php_libxml_attr_value((const xmlAttr *) nodep, &free);
RETURN_STRING_FAST((const char *) value); RETURN_STRING_FAST((const char *) value);
if (free) { if (free) {
xmlFree(value); xmlFree(value);

View file

@ -175,7 +175,6 @@ dom_object *php_dom_instantiate_object_helper(zval *return_value, zend_class_ent
xmlDocPtr php_dom_create_html_doc(void); xmlDocPtr php_dom_create_html_doc(void);
xmlEntityPtr dom_entity_reference_fetch_and_sync_declaration(xmlNodePtr reference); xmlEntityPtr dom_entity_reference_fetch_and_sync_declaration(xmlNodePtr reference);
xmlChar *dom_attr_value(const xmlAttr *attr, bool *free);
bool dom_compare_value(const xmlAttr *attr, const xmlChar *value); bool dom_compare_value(const xmlAttr *attr, const xmlChar *value);
typedef enum { typedef enum {

View file

@ -1438,6 +1438,36 @@ PHP_LIBXML_API void php_libxml_node_decrement_resource(php_libxml_node_object *o
} }
/* }}} */ /* }}} */
PHP_LIBXML_API xmlChar *php_libxml_attr_value(const xmlAttr *attr, bool *free)
{
/* For attributes we can have an optimized fast-path.
* This fast-path is only possible in the (common) case where the attribute
* has a single text child. Note that if the child or the content is NULL, this
* is equivalent to not having content (i.e. the attribute has the empty string as value). */
*free = false;
if (attr->children == NULL) {
return BAD_CAST "";
}
if (attr->children->type == XML_TEXT_NODE && attr->children->next == NULL) {
if (attr->children->content == NULL) {
return BAD_CAST "";
} else {
return attr->children->content;
}
}
xmlChar *value = xmlNodeGetContent((const xmlNode *) attr);
if (UNEXPECTED(value == NULL)) {
return BAD_CAST "";
}
*free = true;
return value;
}
#if defined(PHP_WIN32) && defined(COMPILE_DL_LIBXML) #if defined(PHP_WIN32) && defined(COMPILE_DL_LIBXML)
PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ {

View file

@ -172,6 +172,8 @@ PHP_LIBXML_API void php_libxml_set_old_ns(xmlDocPtr doc, xmlNsPtr ns);
PHP_LIBXML_API php_stream_context *php_libxml_get_stream_context(void); PHP_LIBXML_API php_stream_context *php_libxml_get_stream_context(void);
PHP_LIBXML_API bool php_libxml_uses_internal_errors(void); PHP_LIBXML_API bool php_libxml_uses_internal_errors(void);
PHP_LIBXML_API xmlChar *php_libxml_attr_value(const xmlAttr *attr, bool *free);
PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_string(const char *start, const char *end); PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_string(const char *start, const char *end);
PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_stream(const php_stream *s); PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_stream(const php_stream *s);