diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 9913a07745f..13df7afbc10 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -457,8 +457,11 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml zend_string *type_name; ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(SOAP_GLOBAL(class_map), type_name, tmp) { - if (ZSTR_LEN(ce->name) == Z_STRLEN_P(tmp) && - zend_binary_strncasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), Z_STRVAL_P(tmp), ZSTR_LEN(ce->name), ZSTR_LEN(ce->name)) == 0) { + ZVAL_DEREF(tmp); + if (Z_TYPE_P(tmp) == IS_STRING && + ZSTR_LEN(ce->name) == Z_STRLEN_P(tmp) && + zend_binary_strncasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), Z_STRVAL_P(tmp), ZSTR_LEN(ce->name), ZSTR_LEN(ce->name)) == 0 && + type_name) { /* TODO: namespace isn't stored */ encodePtr enc = NULL; @@ -1392,6 +1395,7 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z classname = zend_hash_str_find_deref(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str)); } if (classname != NULL && + Z_TYPE_P(classname) == IS_STRING && (tmp = zend_fetch_class(Z_STR_P(classname), ZEND_FETCH_CLASS_AUTO)) != NULL) { ce = tmp; } @@ -3669,48 +3673,3 @@ void delete_encoder_persistent(zval *zv) assert(t->details.map == NULL); free(t); } - -/* Normalize leading backslash similarly to how the engine strips it away. */ -static inline zend_string *drop_leading_backslash(zend_string *str) { - if (ZSTR_VAL(str)[0] == '\\') { - return zend_string_init(ZSTR_VAL(str) + 1, ZSTR_LEN(str) - 1, false); - } else { - return zend_string_copy(str); - } -} - -static HashTable *create_normalized_classmap_copy(HashTable *class_map) -{ - HashTable *normalized = zend_new_array(zend_hash_num_elements(class_map)); - - zend_string *key; - zval *value; - ZEND_HASH_FOREACH_STR_KEY_VAL(class_map, key, value) { - ZVAL_DEREF(value); - - if (key != NULL && Z_TYPE_P(value) == IS_STRING) { - zval zv; - ZVAL_STR(&zv, drop_leading_backslash(Z_STR_P(value))); - zend_hash_add_new(normalized, key, &zv); - } - } ZEND_HASH_FOREACH_END(); - - return normalized; -} - -void create_normalized_classmap(zval *return_value, zval *class_map) -{ - /* Check if we need to make a copy. */ - zend_string *key; - zval *value; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARR_P(class_map), key, value) { - if (key == NULL || Z_TYPE_P(value) != IS_STRING || ZSTR_VAL(Z_STR_P(value))[0] == '\\') { - /* TODO: should probably throw in some of these cases to indicate programmer error, - * e.g. in the case where a non-string (after dereferencing) is provided. */ - RETURN_ARR(create_normalized_classmap_copy(Z_ARR_P(class_map))); - } - } ZEND_HASH_FOREACH_END(); - - /* We didn't have to make an actual copy, just increment the refcount. */ - RETURN_COPY(class_map); -} diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index 33b64d391b3..67023a81d82 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -215,8 +215,6 @@ encodePtr get_conversion(int encode); void delete_encoder(zval *zv); void delete_encoder_persistent(zval *zv); -void create_normalized_classmap(zval *return_value, zval *class_map); - extern encode defaultEncoding[]; extern int numDefaultEncodings; diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 639e0cd1249..715af76faf5 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -94,7 +94,7 @@ struct _soapService { char *actor; char *uri; xmlCharEncodingHandlerPtr encoding; - zval class_map; + HashTable *class_map; int features; int send_errors; struct _soapHeader **soap_headers_ptr; diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 0d496eb13f9..7ecd6a905da 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -954,7 +954,7 @@ PHP_METHOD(SoapServer, __construct) if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL && Z_TYPE_P(tmp) == IS_ARRAY) { - create_normalized_classmap(&service->class_map, tmp); + service->class_map = zend_array_dup(Z_ARRVAL_P(tmp)); } if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL && @@ -1402,7 +1402,7 @@ PHP_METHOD(SoapServer, handle) old_encoding = SOAP_GLOBAL(encoding); SOAP_GLOBAL(encoding) = service->encoding; old_class_map = SOAP_GLOBAL(class_map); - SOAP_GLOBAL(class_map) = Z_ARR(service->class_map); + SOAP_GLOBAL(class_map) = service->class_map; old_typemap = SOAP_GLOBAL(typemap); SOAP_GLOBAL(typemap) = service->typemap; old_features = SOAP_GLOBAL(features); @@ -2087,7 +2087,7 @@ PHP_METHOD(SoapClient, __construct) } if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL && Z_TYPE_P(tmp) == IS_ARRAY) { - create_normalized_classmap(Z_CLIENT_CLASSMAP_P(this_ptr), tmp); + ZVAL_COPY(Z_CLIENT_CLASSMAP_P(this_ptr), tmp); } if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL && @@ -4524,7 +4524,10 @@ static void delete_service(soapServicePtr service) /* {{{ */ if (service->encoding) { xmlCharEncCloseFunc(service->encoding); } - zval_ptr_dtor(&service->class_map); + if (service->class_map) { + zend_hash_destroy(service->class_map); + FREE_HASHTABLE(service->class_map); + } zval_ptr_dtor(&service->soap_object); efree(service); } diff --git a/ext/soap/tests/bug69280.phpt b/ext/soap/tests/bug69280.phpt deleted file mode 100644 index ce1ce6b95a6..00000000000 --- a/ext/soap/tests/bug69280.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -Bug #69280 (SoapClient classmap doesn't support fully qualified class name) ---EXTENSIONS-- -soap ---INI-- -soap.wsdl_cache_enabled=0 ---CREDITS-- -champetier dot etienne at gmail dot com ---FILE-- -__soapCall('TestMethod', [$parameters], [ - 'uri' => 'http://tempuri.org/', - 'soapaction' => '' - ] - ); - } - - public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false): never { - die($request); - } -} - -$a = new TestWS(__DIR__ . '/bug69280.wsdl', ['classmap' => [ - 'AbstractClass' => '\AbstractClass', - 'RealClass1' => '\RealClass1', -]]); -$r1 = new \RealClass1(); -$r1->prop = "prop"; -$r1->prop1 = "prop1"; -$a->TestMethod($r1); -?> ---EXPECT-- - -propprop1 diff --git a/ext/soap/tests/bug69280.wsdl b/ext/soap/tests/bug69280.wsdl deleted file mode 100644 index 8615ac77cdc..00000000000 --- a/ext/soap/tests/bug69280.wsdl +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -