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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-