From cc0464268d00a39e344e70f62fef91dfd22ef753 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Sep 2024 22:41:45 +0200 Subject: [PATCH] Avoid copying the local name in SOAP's parse_namespace() (#15862) The local name is either the entire input or is the last part, so we never need to make a copy. --- ext/soap/php_encoding.c | 16 ++++++------- ext/soap/php_schema.c | 52 ++++++++++++++++++++--------------------- ext/soap/php_sdl.c | 8 +++---- ext/soap/php_xml.c | 15 ++++++------ ext/soap/php_xml.h | 2 +- 5 files changed, 46 insertions(+), 47 deletions(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 13df7afbc10..c56b6a0978a 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -538,7 +538,8 @@ static zval *master_to_zval_int(zval *ret, encodePtr encode, xmlNodePtr data) if (type_attr != NULL) { encodePtr new_enc; xmlNsPtr nsptr; - char *ns, *cptype; + const char *cptype; + char *ns; smart_str nscat = {0}; parse_namespace(type_attr->children->content, &cptype, &ns); @@ -549,7 +550,6 @@ static zval *master_to_zval_int(zval *ret, encodePtr encode, xmlNodePtr data) } smart_str_appends(&nscat, cptype); smart_str_0(&nscat); - efree(cptype); if (ns) {efree(ns);} if ((new_enc = zend_hash_find_ptr(SOAP_GLOBAL(typemap), nscat.s)) != NULL) { encode = new_enc; @@ -2466,7 +2466,8 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) if (data && (attr = get_attribute(data->properties,"arrayType")) && attr->children && attr->children->content) { - char *type, *end, *ns; + const char *type; + char *end, *ns; xmlNsPtr nsptr; parse_namespace(attr->children->content, &type, &ns); @@ -2481,13 +2482,13 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) if (nsptr != NULL) { enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type); } - efree(type); if (ns) {efree(ns);} } else if ((attr = get_attribute(data->properties,"itemType")) && attr->children && attr->children->content) { - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(attr->children->content, &type, &ns); @@ -2495,7 +2496,6 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) if (nsptr != NULL) { enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type); } - efree(type); if (ns) {efree(ns);} if ((attr = get_attribute(data->properties,"arraySize")) && @@ -2828,7 +2828,8 @@ static zval *guess_zval_convert(zval *ret, encodeTypePtr type, xmlNodePtr data) master_to_zval_int(ret, enc, data); if (SOAP_GLOBAL(sdl) && type_name && enc->details.sdl_type) { zval soapvar; - char *ns, *cptype; + const char *cptype; + char *ns; xmlNsPtr nsptr; object_init_ex(&soapvar, soap_var_class_entry); @@ -2840,7 +2841,6 @@ static zval *guess_zval_convert(zval *ret, encodeTypePtr type, xmlNodePtr data) if (nsptr) { ZVAL_STRING(Z_VAR_ENC_NS_P(&soapvar), (char*)nsptr->href); } - efree(cptype); if (ns) {efree(ns);} ZVAL_COPY_VALUE(ret, &soapvar); } diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index 4f5a3a59086..e1bf37686ac 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -435,7 +435,8 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP itemType = get_attribute(listType->properties, "itemType"); if (itemType != NULL) { - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(itemType->children->content, &type, &ns); @@ -457,7 +458,6 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP } zend_hash_next_index_insert_ptr(cur_type->elements, newType); } - if (type) {efree(type);} if (ns) {efree(ns);} } @@ -519,7 +519,8 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp memberTypes = get_attribute(unionType->properties, "memberTypes"); if (memberTypes != NULL) { char *str, *start, *end, *next; - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; str = estrdup((char*)memberTypes->children->content); @@ -553,7 +554,6 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp } zend_hash_next_index_insert_ptr(cur_type->elements, newType); } - if (type) {efree(type);} if (ns) {efree(ns);} start = next; @@ -662,7 +662,8 @@ static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodeP base = get_attribute(restType->properties, "base"); if (base != NULL) { - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(base->children->content, &type, &ns); @@ -670,7 +671,6 @@ static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodeP if (nsptr != NULL) { cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type)); } - if (type) {efree(type);} if (ns) {efree(ns);} } else if (!simpleType) { soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute"); @@ -767,7 +767,8 @@ static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNode base = get_attribute(restType->properties, "base"); if (base != NULL) { - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(base->children->content, &type, &ns); @@ -775,7 +776,6 @@ static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNode if (nsptr != NULL) { cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type)); } - if (type) {efree(type);} if (ns) {efree(ns);} } else { soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute"); @@ -892,7 +892,8 @@ static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr base = get_attribute(extType->properties, "base"); if (base != NULL) { - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(base->children->content, &type, &ns); @@ -900,7 +901,6 @@ static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr if (nsptr != NULL) { cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type)); } - if (type) {efree(type);} if (ns) {efree(ns);} } else { soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute"); @@ -947,7 +947,8 @@ static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePt base = get_attribute(extType->properties, "base"); if (base != NULL) { - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(base->children->content, &type, &ns); @@ -955,7 +956,6 @@ static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePt if (nsptr != NULL) { cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type)); } - if (type) {efree(type);} if (ns) {efree(ns);} } else { soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute"); @@ -1096,7 +1096,8 @@ static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTyp smart_str key = {0}; if (ref) { - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(ref->children->content, &type, &ns); @@ -1120,7 +1121,6 @@ static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTyp newModel->kind = XSD_CONTENT_GROUP_REF; newModel->u.group_ref = estrndup(ZSTR_VAL(key.s), ZSTR_LEN(key.s)); - if (type) {efree(type);} if (ns) {efree(ns);} } else { newModel = emalloc(sizeof(sdlContentModel)); @@ -1534,7 +1534,8 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp if (ref) { smart_str nscat = {0}; - char *type, *ns; + const char *type; + char *ns; xmlNsPtr nsptr; parse_namespace(ref->children->content, &type, &ns); @@ -1555,7 +1556,6 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp smart_str_appends(&nscat, type); newType->name = estrdup(type); smart_str_0(&nscat); - if (type) {efree(type);} if (ns) {efree(ns);} newType->ref = estrndup(ZSTR_VAL(nscat.s), ZSTR_LEN(nscat.s)); smart_str_free(&nscat); @@ -1679,7 +1679,8 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp /* type = QName */ type = get_attribute(attrs, "type"); if (type) { - char *cptype, *str_ns; + const char *cptype; + char *str_ns; xmlNsPtr nsptr; if (ref != NULL) { @@ -1691,7 +1692,6 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype)); } if (str_ns) {efree(str_ns);} - if (cptype) {efree(cptype);} } trav = element->children; @@ -1766,7 +1766,8 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl memset(newAttr, 0, sizeof(sdlAttribute)); if (ref) { - char *attr_name, *ns; + const char *attr_name; + char *ns; xmlNsPtr nsptr; parse_namespace(ref->children->content, &attr_name, &ns); @@ -1787,7 +1788,6 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl smart_str_appends(&key, attr_name); smart_str_0(&key); newAttr->ref = estrndup(ZSTR_VAL(key.s), ZSTR_LEN(key.s)); - if (attr_name) {efree(attr_name);} if (ns) {efree(ns);} } else { xmlAttrPtr ns; @@ -1827,7 +1827,8 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl /* type = QName */ type = get_attribute(attrType->properties, "type"); if (type) { - char *cptype, *str_ns; + const char *cptype; + char *str_ns; xmlNsPtr nsptr; if (ref != NULL) { @@ -1839,7 +1840,6 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl newAttr->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype)); } if (str_ns) {efree(str_ns);} - if (cptype) {efree(cptype);} } attr = attrType->properties; @@ -1881,7 +1881,8 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl smart_str key2 = {0}; sdlExtraAttributePtr ext; xmlNsPtr nsptr; - char *value, *ns; + const char *value; + char *ns; ext = emalloc(sizeof(sdlExtraAttribute)); memset(ext, 0, sizeof(sdlExtraAttribute)); @@ -1894,7 +1895,6 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl ext->val = estrdup((char*)attr->children->content); } if (ns) {efree(ns);} - efree(value); if (!newAttr->extraAttributes) { newAttr->extraAttributes = emalloc(sizeof(HashTable)); @@ -2007,7 +2007,8 @@ static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGrou smart_str_free(&key); } else if (ref) { sdlAttributePtr newAttr; - char *group_name, *ns; + const char *group_name; + char *ns; smart_str key = {0}; xmlNsPtr nsptr; @@ -2027,7 +2028,6 @@ static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGrou smart_str_appends(&key, group_name); smart_str_0(&key); newAttr->ref = estrndup(ZSTR_VAL(key.s), ZSTR_LEN(key.s)); - if (group_name) {efree(group_name);} if (ns) {efree(ns);} smart_str_free(&key); diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index c9beaa79aae..a44fc16f971 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -48,7 +48,8 @@ encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const xmlChar *ty { encodePtr enc = NULL; xmlNsPtr nsptr; - char *ns, *cptype; + const char *cptype; + char *ns; parse_namespace(type, &cptype, &ns); nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns)); @@ -60,7 +61,6 @@ encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const xmlChar *ty } else { enc = get_encoder_ex(sdl, (char*)type, xmlStrlen(type)); } - efree(cptype); if (ns) {efree(ns);} return enc; } @@ -71,7 +71,8 @@ static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type) if (sdl->elements) { xmlNsPtr nsptr; - char *ns, *cptype; + const char *cptype; + char *ns; sdlTypePtr sdl_type; parse_namespace(type, &cptype, &ns); @@ -99,7 +100,6 @@ static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type) } } - efree(cptype); if (ns) {efree(ns);} } return ret; diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index 78e92899666..d39688b59b5 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -315,17 +315,16 @@ xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, cha return NULL; } -int parse_namespace(const xmlChar *inval, char **value, char **namespace) +/* namespace is either a copy or NULL, value is never NULL and never a copy. */ +void parse_namespace(const xmlChar *inval, const char **value, char **namespace) { - char *found = strrchr((char*)inval, ':'); + const char *found = strrchr((const char *) inval, ':'); - if (found != NULL && found != (char*)inval) { - (*namespace) = estrndup((char*)inval, found - (char*)inval); - (*value) = estrdup(++found); + if (found != NULL && found != (const char *) inval) { + (*namespace) = estrndup((const char *) inval, found - (const char *) inval); + (*value) = ++found; } else { - (*value) = estrdup((char*)inval); + (*value) = (const char *) inval; (*namespace) = NULL; } - - return FALSE; } diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index ac56003083f..8bbb8f31606 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -39,7 +39,7 @@ xmlNodePtr get_node_ex(xmlNodePtr node,char *name, char *ns); xmlNodePtr get_node_recursive_ex(xmlNodePtr node,char *name, char *ns); xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns); xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns); -int parse_namespace(const xmlChar *inval,char **value,char **namespace); +void parse_namespace(const xmlChar *inval, const char **value, char **namespace); #define FOREACHATTRNODE(n,c,i) FOREACHATTRNODEEX(n,c,NULL,i) #define FOREACHATTRNODEEX(n,c,ns,i) \