@@ -930,6 +930,18 @@ static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht) /* {{{ */
930930}
931931/* }}} */
932932
933+ static bool soap_class_map_has_only_string_keys (const HashTable * class_map )
934+ {
935+ zend_string * key ;
936+ ZEND_HASH_FOREACH_STR_KEY (class_map , key ) {
937+ if (UNEXPECTED (key == NULL )) {
938+ return false;
939+ }
940+ } ZEND_HASH_FOREACH_END ();
941+
942+ return true;
943+ }
944+
933945/* {{{ SoapServer constructor */
934946PHP_METHOD (SoapServer , __construct )
935947{
@@ -1007,8 +1019,7 @@ PHP_METHOD(SoapServer, __construct)
10071019 zend_argument_type_error (2 , "\"classmap\" option must be of type array, %s given" , zend_zval_type_name (class_map_zv ));
10081020 goto cleanup ;
10091021 }
1010- // TODO: this still accepts mixed keys arrays and not all numerically indexed arrays are packed
1011- if (UNEXPECTED (HT_IS_PACKED (Z_ARRVAL_P (class_map_zv )))) {
1022+ if (UNEXPECTED (!soap_class_map_has_only_string_keys (Z_ARRVAL_P (class_map_zv )))) {
10121023 zend_argument_value_error (2 , "\"classmap\" option must be an associative array" );
10131024 goto cleanup ;
10141025 }
@@ -2104,6 +2115,20 @@ PHP_METHOD(SoapClient, __construct)
21042115 RETURN_THROWS ();
21052116 }
21062117
2118+ if (options != NULL ) {
2119+ zval * classmap = zend_hash_str_find (Z_ARRVAL_P (options ), "classmap" , sizeof ("classmap" )- 1 );
2120+ if (classmap != NULL ) {
2121+ if (UNEXPECTED (Z_TYPE_P (classmap ) != IS_ARRAY )) {
2122+ zend_argument_type_error (2 , "\"classmap\" option must be of type array, %s given" , zend_zval_type_name (classmap ));
2123+ RETURN_THROWS ();
2124+ }
2125+ if (UNEXPECTED (!soap_class_map_has_only_string_keys (Z_ARRVAL_P (classmap )))) {
2126+ zend_argument_value_error (2 , "\"classmap\" option must be an associative array" );
2127+ RETURN_THROWS ();
2128+ }
2129+ }
2130+ }
2131+
21072132 SOAP_CLIENT_BEGIN_CODE ();
21082133
21092134 cache_wsdl = SOAP_GLOBAL (cache_enabled ) ? SOAP_GLOBAL (cache_mode ) : 0 ;
@@ -2134,14 +2159,6 @@ PHP_METHOD(SoapClient, __construct)
21342159 }
21352160 }
21362161
2137- if ((tmp = zend_hash_str_find (ht , "stream_context" , sizeof ("stream_context" )- 1 )) != NULL &&
2138- Z_TYPE_P (tmp ) == IS_RESOURCE ) {
2139- context = php_stream_context_from_zval (tmp , 1 );
2140- Z_ADDREF_P (tmp );
2141- } else {
2142- context = php_stream_context_alloc ();
2143- }
2144-
21452162 if ((tmp = zend_hash_str_find (ht , "location" , sizeof ("location" )- 1 )) != NULL &&
21462163 Z_TYPE_P (tmp ) == IS_STRING ) {
21472164 ZVAL_STR_COPY (Z_CLIENT_LOCATION_P (this_ptr ), Z_STR_P (tmp ));
@@ -2187,17 +2204,6 @@ PHP_METHOD(SoapClient, __construct)
21872204 }
21882205 }
21892206 }
2190- if ((tmp = zend_hash_str_find (ht , "local_cert" , sizeof ("local_cert" )- 1 )) != NULL &&
2191- Z_TYPE_P (tmp ) == IS_STRING ) {
2192- if (!context ) {
2193- context = php_stream_context_alloc ();
2194- }
2195- php_stream_context_set_option (context , "ssl" , "local_cert" , tmp );
2196- if ((tmp = zend_hash_str_find (ht , "passphrase" , sizeof ("passphrase" )- 1 )) != NULL &&
2197- Z_TYPE_P (tmp ) == IS_STRING ) {
2198- php_stream_context_set_option (context , "ssl" , "passphrase" , tmp );
2199- }
2200- }
22012207 if ((tmp = zend_hash_find (ht , ZSTR_KNOWN (ZEND_STR_TRACE ))) != NULL &&
22022208 (Z_TYPE_P (tmp ) == IS_TRUE ||
22032209 (Z_TYPE_P (tmp ) == IS_LONG && Z_LVAL_P (tmp ) == 1 ))) {
@@ -2233,12 +2239,29 @@ PHP_METHOD(SoapClient, __construct)
22332239 }
22342240 if ((tmp = zend_hash_str_find (ht , "classmap" , sizeof ("classmap" )- 1 )) != NULL &&
22352241 Z_TYPE_P (tmp ) == IS_ARRAY ) {
2236- if (UNEXPECTED (HT_IS_PACKED (Z_ARRVAL_P (tmp )))) {
2237- php_error_docref (NULL , E_ERROR , "'classmap' option must be an associative array" );
2238- }
22392242 ZVAL_COPY (Z_CLIENT_CLASSMAP_P (this_ptr ), tmp );
22402243 }
22412244
2245+ if ((tmp = zend_hash_str_find (ht , "stream_context" , sizeof ("stream_context" )- 1 )) != NULL &&
2246+ Z_TYPE_P (tmp ) == IS_RESOURCE ) {
2247+ context = php_stream_context_from_zval (tmp , 1 );
2248+ Z_ADDREF_P (tmp );
2249+ } else {
2250+ context = php_stream_context_alloc ();
2251+ }
2252+
2253+ if ((tmp = zend_hash_str_find (ht , "local_cert" , sizeof ("local_cert" )- 1 )) != NULL &&
2254+ Z_TYPE_P (tmp ) == IS_STRING ) {
2255+ if (!context ) {
2256+ context = php_stream_context_alloc ();
2257+ }
2258+ php_stream_context_set_option (context , "ssl" , "local_cert" , tmp );
2259+ if ((tmp = zend_hash_str_find (ht , "passphrase" , sizeof ("passphrase" )- 1 )) != NULL &&
2260+ Z_TYPE_P (tmp ) == IS_STRING ) {
2261+ php_stream_context_set_option (context , "ssl" , "passphrase" , tmp );
2262+ }
2263+ }
2264+
22422265 if ((tmp = zend_hash_str_find (ht , "typemap" , sizeof ("typemap" )- 1 )) != NULL &&
22432266 Z_TYPE_P (tmp ) == IS_ARRAY &&
22442267 zend_hash_num_elements (Z_ARRVAL_P (tmp )) > 0 ) {
@@ -2313,6 +2336,7 @@ PHP_METHOD(SoapClient, __construct)
23132336 if (typemap_ht ) {
23142337 soap_client_object_fetch (Z_OBJ_P (this_ptr ))-> typemap = soap_create_typemap (sdl , typemap_ht );
23152338 }
2339+
23162340 SOAP_CLIENT_END_CODE ();
23172341}
23182342/* }}} */
0 commit comments