@@ -1402,7 +1402,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in
14021402/* {{{ php_ldap_do_search */
14031403static void php_ldap_do_search (INTERNAL_FUNCTION_PARAMETERS , int scope )
14041404{
1405- zval * link , * attrs = NULL , * attr , * serverctrls = NULL ;
1405+ zval * link , * attrs = NULL , * serverctrls = NULL ;
14061406 zend_string * base_dn_str , * filter_str ;
14071407 HashTable * base_dn_ht , * filter_ht ;
14081408 zend_long attrsonly , sizelimit , timelimit , deref ;
@@ -1414,7 +1414,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
14141414 LDAPControl * * lserverctrls = NULL ;
14151415 int ldap_attrsonly = 0 , ldap_sizelimit = -1 , ldap_timelimit = -1 , ldap_deref = -1 ;
14161416 int old_ldap_sizelimit = -1 , old_ldap_timelimit = -1 , old_ldap_deref = -1 ;
1417- int num_attribs = 0 , ret = 1 , i , ldap_errno , argcount = ZEND_NUM_ARGS ();
1417+ int ret = 1 , ldap_errno , argcount = ZEND_NUM_ARGS ();
14181418
14191419 ZEND_PARSE_PARAMETERS_START (3 , 9 )
14201420 Z_PARAM_ZVAL (link )
@@ -1444,29 +1444,45 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
14441444 case 5 :
14451445 ldap_attrsonly = attrsonly ;
14461446 ZEND_FALLTHROUGH ;
1447- case 4 :
1448- num_attribs = zend_hash_num_elements ( Z_ARRVAL_P ( attrs )) ;
1449- ldap_attrs = safe_emalloc (( num_attribs + 1 ), sizeof ( char * ), 0 );
1447+ default :
1448+ break ;
1449+ }
14501450
1451- for (i = 0 ; i < num_attribs ; i ++ ) {
1452- if ((attr = zend_hash_index_find (Z_ARRVAL_P (attrs ), i )) == NULL ) {
1453- php_error_docref (NULL , E_WARNING , "Array initialization wrong" );
1454- ret = 0 ;
1455- goto cleanup ;
1456- }
1451+ if (attrs ) {
1452+ const HashTable * attributes = Z_ARRVAL_P (attrs );
1453+ uint32_t num_attribs = zend_hash_num_elements (attributes );
14571454
1458- convert_to_string (attr );
1459- if (EG (exception )) {
1460- ret = 0 ;
1461- goto cleanup ;
1462- }
1463- ldap_attrs [i ] = Z_STRVAL_P (attr );
1455+ if (num_attribs == 0 ) {
1456+ /* We don't allocate ldap_attrs for an empty array */
1457+ goto process ;
1458+ }
1459+ if (!zend_array_is_list (attributes )) {
1460+ zend_argument_value_error (4 , "must be a list" );
1461+ RETURN_THROWS ();
1462+ }
1463+ /* Allocate +1 as we need an extra entry to NULL terminate the list */
1464+ ldap_attrs = safe_emalloc (num_attribs + 1 , sizeof (char * ), 0 );
1465+
1466+ zend_ulong attribute_index = 0 ;
1467+ zval * attribute_zv = NULL ;
1468+ ZEND_HASH_FOREACH_NUM_KEY_VAL (attributes , attribute_index , attribute_zv ) {
1469+ ZVAL_DEREF (attribute_zv );
1470+ if (Z_TYPE_P (attribute_zv ) != IS_STRING ) {
1471+ zend_argument_type_error (4 , "must be a list of strings, %s given" , zend_zval_value_name (attribute_zv ));
1472+ ret = 0 ;
1473+ goto cleanup ;
14641474 }
1465- ldap_attrs [num_attribs ] = NULL ;
1466- ZEND_FALLTHROUGH ;
1467- default :
1468- break ;
1475+ zend_string * attribute = Z_STR_P (attribute_zv );
1476+ if (zend_str_has_nul_byte (attribute )) {
1477+ zend_argument_value_error (4 , "must not contain strings with any null bytes" );
1478+ ret = 0 ;
1479+ goto cleanup ;
1480+ }
1481+ ldap_attrs [attribute_index ] = ZSTR_VAL (attribute );
1482+ } ZEND_HASH_FOREACH_END ();
1483+ ldap_attrs [num_attribs ] = NULL ;
14691484 }
1485+ process :
14701486
14711487 /* parallel search? */
14721488 if (Z_TYPE_P (link ) == IS_ARRAY ) {
0 commit comments