@@ -2194,27 +2194,26 @@ PHP_FUNCTION(ldap_dn2ufn)
21942194static void php_ldap_do_modify (INTERNAL_FUNCTION_PARAMETERS , int oper , int ext )
21952195{
21962196 zval * serverctrls = NULL ;
2197- zval * link , * entry ;
2197+ zval * link ;
21982198 ldap_linkdata * ld ;
21992199 char * dn ;
2200+ HashTable * attributes_ht ;
22002201 LDAPMod * * ldap_mods ;
22012202 LDAPControl * * lserverctrls = NULL ;
22022203 ldap_resultdata * result ;
22032204 LDAPMessage * ldap_res ;
2204- int i , num_attribs , msgid ;
2205+ int i , msgid ;
22052206 size_t dn_len ;
2206- zend_string * attribute ;
2207- zend_ulong index ;
22082207 int is_full_add = 0 ; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */
22092208
2210- if (zend_parse_parameters (ZEND_NUM_ARGS (), "Opa /|a!" , & link , ldap_link_ce , & dn , & dn_len , & entry , & serverctrls ) != SUCCESS ) {
2209+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "Oph /|a!" , & link , ldap_link_ce , & dn , & dn_len , & attributes_ht , & serverctrls ) != SUCCESS ) {
22112210 RETURN_THROWS ();
22122211 }
22132212
22142213 ld = Z_LDAP_LINK_P (link );
22152214 VERIFY_LDAP_LINK_CONNECTED (ld );
22162215
2217- num_attribs = zend_hash_num_elements (Z_ARRVAL_P ( entry ) );
2216+ uint32_t num_attribs = zend_hash_num_elements (attributes_ht );
22182217 if (num_attribs == 0 ) {
22192218 zend_argument_must_not_be_empty_error (3 );
22202219 RETURN_THROWS ();
@@ -2223,7 +2222,6 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22232222 ldap_mods = safe_emalloc ((num_attribs + 1 ), sizeof (LDAPMod * ), 0 );
22242223 /* Zero out the list */
22252224 memset (ldap_mods , 0 , sizeof (LDAPMod * ) * (num_attribs + 1 ));
2226- zend_hash_internal_pointer_reset (Z_ARRVAL_P (entry ));
22272225
22282226 /* added by gerrit thomson to fix ldap_add using ldap_mod_add */
22292227 if (oper == PHP_LD_FULL_ADD ) {
@@ -2232,74 +2230,70 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22322230 }
22332231 /* end additional , gerrit thomson */
22342232
2235- for (i = 0 ; i < num_attribs ; i ++ ) {
2236- ldap_mods [i ] = emalloc (sizeof (LDAPMod ));
2237- ldap_mods [i ]-> mod_op = oper | LDAP_MOD_BVALUES ;
2238- ldap_mods [i ]-> mod_type = NULL ;
2239-
2240- if (zend_hash_get_current_key (Z_ARRVAL_P (entry ), & attribute , & index ) == HASH_KEY_IS_STRING ) {
2241- ldap_mods [i ]-> mod_type = estrndup (ZSTR_VAL (attribute ), ZSTR_LEN (attribute ));
2242- } else {
2233+ const zend_string * attribute = NULL ;
2234+ zval * attribute_values = NULL ;
2235+ unsigned int attribute_index = 0 ;
2236+ ZEND_HASH_FOREACH_STR_KEY_VAL (attributes_ht , attribute , attribute_values ) {
2237+ if (attribute == NULL ) {
22432238 php_error_docref (NULL , E_WARNING , "Unknown attribute in the data" );
22442239 RETVAL_FALSE ;
2245- ldap_mods [i ]-> mod_bvalues = NULL ;
22462240 goto cleanup ;
22472241 }
22482242
2249- zval * value = zend_hash_get_current_data (Z_ARRVAL_P (entry ));
2243+ ldap_mods [attribute_index ] = emalloc (sizeof (LDAPMod ));
2244+ ldap_mods [attribute_index ]-> mod_op = oper | LDAP_MOD_BVALUES ;
2245+ ldap_mods [attribute_index ]-> mod_type = estrndup (ZSTR_VAL (attribute ), ZSTR_LEN (attribute ));
2246+ ldap_mods [attribute_index ]-> mod_bvalues = NULL ;
22502247
2251- ZVAL_DEREF (value );
2248+ ZVAL_DEREF (attribute_values );
22522249 /* If the attribute takes a single value it can be passed directly instead of as a list with one element */
22532250 /* allow for arrays with one element, no allowance for arrays with none but probably not required, gerrit thomson. */
2254- if (Z_TYPE_P (value ) != IS_ARRAY ) {
2255- convert_to_string (value );
2251+ if (Z_TYPE_P (attribute_values ) != IS_ARRAY ) {
2252+ convert_to_string (attribute_values );
22562253 if (EG (exception )) {
22572254 RETVAL_FALSE ;
2258- ldap_mods [i ]-> mod_bvalues = NULL ;
22592255 goto cleanup ;
22602256 }
2261- ldap_mods [i ]-> mod_bvalues = safe_emalloc (2 , sizeof (struct berval * ), 0 );
2262- ldap_mods [i ]-> mod_bvalues [0 ] = (struct berval * ) emalloc (sizeof (struct berval ));
2263- ldap_mods [i ]-> mod_bvalues [0 ]-> bv_val = Z_STRVAL_P (value );
2264- ldap_mods [i ]-> mod_bvalues [0 ]-> bv_len = Z_STRLEN_P (value );
2265- ldap_mods [i ]-> mod_bvalues [1 ] = NULL ;
2257+ ldap_mods [attribute_index ]-> mod_bvalues = safe_emalloc (2 , sizeof (struct berval * ), 0 );
2258+ ldap_mods [attribute_index ]-> mod_bvalues [0 ] = (struct berval * ) emalloc (sizeof (struct berval ));
2259+ ldap_mods [attribute_index ]-> mod_bvalues [0 ]-> bv_val = Z_STRVAL_P (attribute_values );
2260+ ldap_mods [attribute_index ]-> mod_bvalues [0 ]-> bv_len = Z_STRLEN_P (attribute_values );
2261+ ldap_mods [attribute_index ]-> mod_bvalues [1 ] = NULL ;
22662262 } else {
2267- SEPARATE_ARRAY (value );
2268- int num_values = zend_hash_num_elements (Z_ARRVAL_P (value ));
2263+ SEPARATE_ARRAY (attribute_values );
2264+ uint32_t num_values = zend_hash_num_elements (Z_ARRVAL_P (attribute_values ));
22692265 if (num_values == 0 ) {
22702266 zend_argument_value_error (3 , "list of attribute values must not be empty" );
22712267 RETVAL_FALSE ;
2272- ldap_mods [i ]-> mod_bvalues = NULL ;
22732268 goto cleanup ;
22742269 }
2275- if (!zend_array_is_list (Z_ARRVAL_P (value ))) {
2270+ if (!zend_array_is_list (Z_ARRVAL_P (attribute_values ))) {
22762271 zend_argument_value_error (3 , "must be a list of attribute values" );
22772272 RETVAL_FALSE ;
2278- ldap_mods [i ]-> mod_bvalues = NULL ;
22792273 goto cleanup ;
22802274 }
22812275
2282- ldap_mods [i ]-> mod_bvalues = safe_emalloc ((num_values + 1 ), sizeof (struct berval * ), 0 );
2276+ ldap_mods [attribute_index ]-> mod_bvalues = safe_emalloc ((num_values + 1 ), sizeof (struct berval * ), 0 );
22832277 /* Zero out the list */
2284- memset (ldap_mods [i ]-> mod_bvalues , 0 , sizeof (struct berval * ) * (num_values + 1 ));
2278+ memset (ldap_mods [attribute_index ]-> mod_bvalues , 0 , sizeof (struct berval * ) * (num_values + 1 ));
22852279
22862280 zend_ulong attribute_value_index = 0 ;
22872281 zval * attribute_value = NULL ;
2288- ZEND_HASH_FOREACH_NUM_KEY_VAL (Z_ARRVAL_P (value ), attribute_value_index , attribute_value ) {
2282+ ZEND_HASH_FOREACH_NUM_KEY_VAL (Z_ARRVAL_P (attribute_values ), attribute_value_index , attribute_value ) {
22892283 convert_to_string (attribute_value );
22902284 if (EG (exception )) {
22912285 RETVAL_FALSE ;
22922286 goto cleanup ;
22932287 }
2294- ldap_mods [i ]-> mod_bvalues [attribute_value_index ] = (struct berval * ) emalloc (sizeof (struct berval ));
2295- ldap_mods [i ]-> mod_bvalues [attribute_value_index ]-> bv_val = Z_STRVAL_P (attribute_value );
2296- ldap_mods [i ]-> mod_bvalues [attribute_value_index ]-> bv_len = Z_STRLEN_P (attribute_value );
2288+ ldap_mods [attribute_index ]-> mod_bvalues [attribute_value_index ] = (struct berval * ) emalloc (sizeof (struct berval ));
2289+ ldap_mods [attribute_index ]-> mod_bvalues [attribute_value_index ]-> bv_val = Z_STRVAL_P (attribute_value );
2290+ ldap_mods [attribute_index ]-> mod_bvalues [attribute_value_index ]-> bv_len = Z_STRLEN_P (attribute_value );
22972291 } ZEND_HASH_FOREACH_END ();
2298- ldap_mods [i ]-> mod_bvalues [num_values ] = NULL ;
2292+ ldap_mods [attribute_index ]-> mod_bvalues [num_values ] = NULL ;
22992293 }
23002294
2301- zend_hash_move_forward ( Z_ARRVAL_P ( entry )) ;
2302- }
2295+ attribute_index ++ ;
2296+ } ZEND_HASH_FOREACH_END ();
23032297 ldap_mods [num_attribs ] = NULL ;
23042298
23052299 if (serverctrls ) {
@@ -2360,9 +2354,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
23602354cleanup :
23612355 for (LDAPMod * * ptr = ldap_mods ; * ptr != NULL ; ptr ++ ) {
23622356 LDAPMod * mod = * ptr ;
2363- if (mod -> mod_type ) {
2364- efree (mod -> mod_type );
2365- }
2357+ efree (mod -> mod_type );
23662358 if (mod -> mod_bvalues != NULL ) {
23672359 for (struct berval * * bval_ptr = mod -> mod_bvalues ; * bval_ptr != NULL ; bval_ptr ++ ) {
23682360 efree (* bval_ptr );
0 commit comments