@@ -234,6 +234,22 @@ static void ldap_result_entry_free_obj(zend_object *obj)
234234 } \
235235}
236236
237+ static bool php_ldap_is_numerically_indexed_array (zend_array * arr )
238+ {
239+ if (zend_hash_num_elements (arr ) == 0 || HT_IS_PACKED (arr )) {
240+ return true;
241+ }
242+
243+ zend_string * str_key ;
244+ ZEND_HASH_MAP_FOREACH_STR_KEY (arr , str_key ) {
245+ if (str_key ) {
246+ return false;
247+ }
248+ } ZEND_HASH_FOREACH_END ();
249+
250+ return false;
251+ }
252+
237253/* {{{ Parse controls from and to arrays */
238254static void _php_ldap_control_to_array (LDAP * ld , LDAPControl * ctrl , zval * array , int request )
239255{
@@ -1473,20 +1489,22 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
14731489 num_attribs = zend_hash_num_elements (Z_ARRVAL_P (attrs ));
14741490 ldap_attrs = safe_emalloc ((num_attribs + 1 ), sizeof (char * ), 0 );
14751491
1476- for (i = 0 ; i < num_attribs ; i ++ ) {
1477- if ((attr = zend_hash_index_find (Z_ARRVAL_P (attrs ), i )) == NULL ) {
1478- php_error_docref (NULL , E_WARNING , "Array initialization wrong" );
1479- ret = 0 ;
1480- goto cleanup ;
1481- }
1492+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (attrs ))) {
1493+ php_error_docref (NULL , E_WARNING , "Argument #4 ($attributes) must be an array with numeric keys" );
1494+ ret = 0 ;
1495+ goto cleanup ;
1496+ }
14821497
1498+ i = 0 ;
1499+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (attrs ), attr ) {
14831500 convert_to_string (attr );
14841501 if (EG (exception )) {
14851502 ret = 0 ;
14861503 goto cleanup ;
14871504 }
1488- ldap_attrs [i ] = Z_STRVAL_P (attr );
1489- }
1505+ ldap_attrs [i ++ ] = Z_STRVAL_P (attr );
1506+ } ZEND_HASH_FOREACH_END ();
1507+
14901508 ldap_attrs [num_attribs ] = NULL ;
14911509 ZEND_FALLTHROUGH ;
14921510 default :
@@ -2259,14 +2277,16 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22592277 ldap_mods [i ]-> mod_bvalues [0 ]-> bv_val = Z_STRVAL_P (value );
22602278 ldap_mods [i ]-> mod_bvalues [0 ]-> bv_len = Z_STRLEN_P (value );
22612279 } else {
2262- for (j = 0 ; j < num_values ; j ++ ) {
2263- if ((ivalue = zend_hash_index_find (Z_ARRVAL_P (value ), j )) == NULL ) {
2264- zend_argument_value_error (3 , "must contain arrays with consecutive integer indices starting from 0" );
2265- num_berval [i ] = j ;
2266- num_attribs = i + 1 ;
2267- RETVAL_FALSE ;
2268- goto cleanup ;
2269- }
2280+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (value ))) {
2281+ zend_argument_value_error (3 , "must be an array with numeric keys" );
2282+ RETVAL_FALSE ;
2283+ num_berval [i ] = 0 ;
2284+ num_attribs = i + 1 ;
2285+ goto cleanup ;
2286+ }
2287+
2288+ j = 0 ;
2289+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (value ), ivalue ) {
22702290 convert_to_string (ivalue );
22712291 if (EG (exception )) {
22722292 num_berval [i ] = j ;
@@ -2277,7 +2297,8 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22772297 ldap_mods [i ]-> mod_bvalues [j ] = (struct berval * ) emalloc (sizeof (struct berval ));
22782298 ldap_mods [i ]-> mod_bvalues [j ]-> bv_val = Z_STRVAL_P (ivalue );
22792299 ldap_mods [i ]-> mod_bvalues [j ]-> bv_len = Z_STRLEN_P (ivalue );
2280- }
2300+ j ++ ;
2301+ } ZEND_HASH_FOREACH_END ();
22812302 }
22822303 ldap_mods [i ]-> mod_bvalues [num_values ] = NULL ;
22832304 zend_hash_move_forward (Z_ARRVAL_P (entry ));
@@ -2545,7 +2566,7 @@ PHP_FUNCTION(ldap_modify_batch)
25452566 zval * fetched ;
25462567 char * dn ;
25472568 size_t dn_len ;
2548- int i , j , k ;
2569+ int i , j ;
25492570 int num_mods , num_modprops , num_modvals ;
25502571 LDAPMod * * ldap_mods ;
25512572 LDAPControl * * lserverctrls = NULL ;
@@ -2605,12 +2626,14 @@ PHP_FUNCTION(ldap_modify_batch)
26052626
26062627 num_mods = zend_hash_num_elements (Z_ARRVAL_P (mods ));
26072628
2608- for (i = 0 ; i < num_mods ; i ++ ) {
2609- /* is the numbering consecutive? */
2610- if ((fetched = zend_hash_index_find (Z_ARRVAL_P (mods ), i )) == NULL ) {
2611- zend_argument_value_error (3 , "must have consecutive integer indices starting from 0" );
2612- RETURN_THROWS ();
2613- }
2629+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (mods ))) {
2630+ zend_argument_value_error (3 , "must be an array with numeric keys" );
2631+ RETURN_THROWS ();
2632+ }
2633+
2634+ i = 0 ;
2635+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (mods ), fetched ) {
2636+ ZVAL_DEREF (fetched );
26142637 mod = fetched ;
26152638
26162639 /* is it an array? */
@@ -2708,19 +2731,10 @@ PHP_FUNCTION(ldap_modify_batch)
27082731 RETURN_THROWS ();
27092732 }
27102733
2711- /* are its keys integers? */
2712- if (zend_hash_get_current_key_type (Z_ARRVAL_P (modinfo )) != HASH_KEY_IS_LONG ) {
2713- zend_value_error ("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be integer-indexed" , get_active_function_name ());
2734+ if (!php_ldap_is_numerically_indexed_array (Z_ARRVAL_P (modinfo ))) {
2735+ zend_value_error ("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be an array with numeric keys" , get_active_function_name ());
27142736 RETURN_THROWS ();
27152737 }
2716-
2717- /* are the keys consecutive? */
2718- for (k = 0 ; k < num_modvals ; k ++ ) {
2719- if ((fetched = zend_hash_index_find (Z_ARRVAL_P (modinfo ), k )) == NULL ) {
2720- zend_value_error ("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must have consecutive integer indices starting from 0" , get_active_function_name ());
2721- RETURN_THROWS ();
2722- }
2723- }
27242738 }
27252739
27262740 zend_hash_move_forward (Z_ARRVAL_P (mod ));
@@ -2734,7 +2748,9 @@ PHP_FUNCTION(ldap_modify_batch)
27342748 zend_value_error ("%s(): Required option \"" LDAP_MODIFY_BATCH_MODTYPE "\" is missing" , get_active_function_name ());
27352749 RETURN_THROWS ();
27362750 }
2737- }
2751+
2752+ i ++ ;
2753+ } ZEND_HASH_FOREACH_END ();
27382754 }
27392755 /* validation was successful */
27402756
@@ -2788,9 +2804,9 @@ PHP_FUNCTION(ldap_modify_batch)
27882804 ldap_mods [i ]-> mod_bvalues = safe_emalloc ((num_modvals + 1 ), sizeof (struct berval * ), 0 );
27892805
27902806 /* for each value */
2791- for (j = 0 ; j < num_modvals ; j ++ ) {
2807+ j = 0 ;
2808+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (vals ), fetched ) {
27922809 /* fetch it */
2793- fetched = zend_hash_index_find (Z_ARRVAL_P (vals ), j );
27942810 modval = zval_get_string (fetched );
27952811 if (EG (exception )) {
27962812 RETVAL_FALSE ;
@@ -2806,7 +2822,8 @@ PHP_FUNCTION(ldap_modify_batch)
28062822 ldap_mods [i ]-> mod_bvalues [j ]-> bv_len = ZSTR_LEN (modval );
28072823 ldap_mods [i ]-> mod_bvalues [j ]-> bv_val = estrndup (ZSTR_VAL (modval ), ZSTR_LEN (modval ));
28082824 zend_string_release (modval );
2809- }
2825+ j ++ ;
2826+ } ZEND_HASH_FOREACH_END ();
28102827
28112828 /* NULL-terminate values */
28122829 ldap_mods [i ]-> mod_bvalues [num_modvals ] = NULL ;
0 commit comments