@@ -235,6 +235,22 @@ static void ldap_result_entry_free_obj(zend_object *obj)
235235 } \
236236}
237237
238+ static bool php_ldap_is_numerically_indexed_array (zend_array * arr )
239+ {
240+ if (zend_hash_num_elements (arr ) == 0 || HT_IS_PACKED (arr )) {
241+ return true;
242+ }
243+
244+ zend_string * str_key ;
245+ ZEND_HASH_MAP_FOREACH_STR_KEY (arr , str_key ) {
246+ if (str_key ) {
247+ return false;
248+ }
249+ } ZEND_HASH_FOREACH_END ();
250+
251+ return false;
252+ }
253+
238254/* {{{ Parse controls from and to arrays */
239255static void _php_ldap_control_to_array (LDAP * ld , LDAPControl * ctrl , zval * array , int request )
240256{
@@ -1471,20 +1487,22 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
14711487 num_attribs = zend_hash_num_elements (Z_ARRVAL_P (attrs ));
14721488 ldap_attrs = safe_emalloc ((num_attribs + 1 ), sizeof (char * ), 0 );
14731489
1474- for (i = 0 ; i < num_attribs ; i ++ ) {
1475- if ((attr = zend_hash_index_find (Z_ARRVAL_P (attrs ), i )) == NULL ) {
1476- php_error_docref (NULL , E_WARNING , "Array initialization wrong" );
1477- ret = 0 ;
1478- goto cleanup ;
1479- }
1490+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (attrs ))) {
1491+ php_error_docref (NULL , E_WARNING , "Argument #4 ($attributes) must be an array with numeric keys" );
1492+ ret = 0 ;
1493+ goto cleanup ;
1494+ }
14801495
1496+ i = 0 ;
1497+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (attrs ), attr ) {
14811498 convert_to_string (attr );
14821499 if (EG (exception )) {
14831500 ret = 0 ;
14841501 goto cleanup ;
14851502 }
1486- ldap_attrs [i ] = Z_STRVAL_P (attr );
1487- }
1503+ ldap_attrs [i ++ ] = Z_STRVAL_P (attr );
1504+ } ZEND_HASH_FOREACH_END ();
1505+
14881506 ldap_attrs [num_attribs ] = NULL ;
14891507 ZEND_FALLTHROUGH ;
14901508 default :
@@ -2257,14 +2275,16 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22572275 ldap_mods [i ]-> mod_bvalues [0 ]-> bv_val = Z_STRVAL_P (value );
22582276 ldap_mods [i ]-> mod_bvalues [0 ]-> bv_len = Z_STRLEN_P (value );
22592277 } else {
2260- for (j = 0 ; j < num_values ; j ++ ) {
2261- if ((ivalue = zend_hash_index_find (Z_ARRVAL_P (value ), j )) == NULL ) {
2262- zend_argument_value_error (3 , "must contain arrays with consecutive integer indices starting from 0" );
2263- num_berval [i ] = j ;
2264- num_attribs = i + 1 ;
2265- RETVAL_FALSE ;
2266- goto cleanup ;
2267- }
2278+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (value ))) {
2279+ zend_argument_value_error (3 , "must be an array with numeric keys" );
2280+ RETVAL_FALSE ;
2281+ num_berval [i ] = 0 ;
2282+ num_attribs = i + 1 ;
2283+ goto cleanup ;
2284+ }
2285+
2286+ j = 0 ;
2287+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (value ), ivalue ) {
22682288 convert_to_string (ivalue );
22692289 if (EG (exception )) {
22702290 num_berval [i ] = j ;
@@ -2275,7 +2295,8 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22752295 ldap_mods [i ]-> mod_bvalues [j ] = (struct berval * ) emalloc (sizeof (struct berval ));
22762296 ldap_mods [i ]-> mod_bvalues [j ]-> bv_val = Z_STRVAL_P (ivalue );
22772297 ldap_mods [i ]-> mod_bvalues [j ]-> bv_len = Z_STRLEN_P (ivalue );
2278- }
2298+ j ++ ;
2299+ } ZEND_HASH_FOREACH_END ();
22792300 }
22802301 ldap_mods [i ]-> mod_bvalues [num_values ] = NULL ;
22812302 zend_hash_move_forward (Z_ARRVAL_P (entry ));
@@ -2543,7 +2564,7 @@ PHP_FUNCTION(ldap_modify_batch)
25432564 zval * fetched ;
25442565 char * dn ;
25452566 size_t dn_len ;
2546- int i , j , k ;
2567+ int i , j ;
25472568 int num_mods , num_modprops , num_modvals ;
25482569 LDAPMod * * ldap_mods ;
25492570 LDAPControl * * lserverctrls = NULL ;
@@ -2603,12 +2624,14 @@ PHP_FUNCTION(ldap_modify_batch)
26032624
26042625 num_mods = zend_hash_num_elements (Z_ARRVAL_P (mods ));
26052626
2606- for (i = 0 ; i < num_mods ; i ++ ) {
2607- /* is the numbering consecutive? */
2608- if ((fetched = zend_hash_index_find (Z_ARRVAL_P (mods ), i )) == NULL ) {
2609- zend_argument_value_error (3 , "must have consecutive integer indices starting from 0" );
2610- RETURN_THROWS ();
2611- }
2627+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (mods ))) {
2628+ zend_argument_value_error (3 , "must be an array with numeric keys" );
2629+ RETURN_THROWS ();
2630+ }
2631+
2632+ i = 0 ;
2633+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (mods ), fetched ) {
2634+ ZVAL_DEREF (fetched );
26122635 mod = fetched ;
26132636
26142637 /* is it an array? */
@@ -2706,19 +2729,10 @@ PHP_FUNCTION(ldap_modify_batch)
27062729 RETURN_THROWS ();
27072730 }
27082731
2709- /* are its keys integers? */
2710- if (zend_hash_get_current_key_type (Z_ARRVAL_P (modinfo )) != HASH_KEY_IS_LONG ) {
2711- zend_value_error ("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be integer-indexed" , get_active_function_name ());
2732+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (modinfo ))) {
2733+ zend_value_error ("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be an array with numeric keys" , get_active_function_name ());
27122734 RETURN_THROWS ();
27132735 }
2714-
2715- /* are the keys consecutive? */
2716- for (k = 0 ; k < num_modvals ; k ++ ) {
2717- if ((fetched = zend_hash_index_find (Z_ARRVAL_P (modinfo ), k )) == NULL ) {
2718- zend_value_error ("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must have consecutive integer indices starting from 0" , get_active_function_name ());
2719- RETURN_THROWS ();
2720- }
2721- }
27222736 }
27232737
27242738 zend_hash_move_forward (Z_ARRVAL_P (mod ));
@@ -2732,7 +2746,9 @@ PHP_FUNCTION(ldap_modify_batch)
27322746 zend_value_error ("%s(): Required option \"" LDAP_MODIFY_BATCH_MODTYPE "\" is missing" , get_active_function_name ());
27332747 RETURN_THROWS ();
27342748 }
2735- }
2749+
2750+ i ++ ;
2751+ } ZEND_HASH_FOREACH_END ();
27362752 }
27372753 /* validation was successful */
27382754
@@ -2786,9 +2802,9 @@ PHP_FUNCTION(ldap_modify_batch)
27862802 ldap_mods [i ]-> mod_bvalues = safe_emalloc ((num_modvals + 1 ), sizeof (struct berval * ), 0 );
27872803
27882804 /* for each value */
2789- for (j = 0 ; j < num_modvals ; j ++ ) {
2805+ j = 0 ;
2806+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (vals ), fetched ) {
27902807 /* fetch it */
2791- fetched = zend_hash_index_find (Z_ARRVAL_P (vals ), j );
27922808 modval = zval_get_string (fetched );
27932809 if (EG (exception )) {
27942810 RETVAL_FALSE ;
@@ -2804,7 +2820,8 @@ PHP_FUNCTION(ldap_modify_batch)
28042820 ldap_mods [i ]-> mod_bvalues [j ]-> bv_len = ZSTR_LEN (modval );
28052821 ldap_mods [i ]-> mod_bvalues [j ]-> bv_val = estrndup (ZSTR_VAL (modval ), ZSTR_LEN (modval ));
28062822 zend_string_release (modval );
2807- }
2823+ j ++ ;
2824+ } ZEND_HASH_FOREACH_END ();
28082825
28092826 /* NULL-terminate values */
28102827 ldap_mods [i ]-> mod_bvalues [num_modvals ] = NULL ;
0 commit comments