@@ -1402,7 +1402,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in
1402
1402
/* {{{ php_ldap_do_search */
1403
1403
static void php_ldap_do_search (INTERNAL_FUNCTION_PARAMETERS , int scope )
1404
1404
{
1405
- zval * link , * attrs = NULL , * attr , * serverctrls = NULL ;
1405
+ zval * link , * attrs = NULL , * serverctrls = NULL ;
1406
1406
zend_string * base_dn_str , * filter_str ;
1407
1407
HashTable * base_dn_ht , * filter_ht ;
1408
1408
zend_long attrsonly , sizelimit , timelimit , deref ;
@@ -1414,7 +1414,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
1414
1414
LDAPControl * * lserverctrls = NULL ;
1415
1415
int ldap_attrsonly = 0 , ldap_sizelimit = -1 , ldap_timelimit = -1 , ldap_deref = -1 ;
1416
1416
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 ();
1418
1418
1419
1419
ZEND_PARSE_PARAMETERS_START (3 , 9 )
1420
1420
Z_PARAM_ZVAL (link )
@@ -1444,29 +1444,45 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
1444
1444
case 5 :
1445
1445
ldap_attrsonly = attrsonly ;
1446
1446
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
+ }
1450
1450
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 );
1457
1454
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 ;
1464
1474
}
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 ;
1469
1484
}
1485
+ process :
1470
1486
1471
1487
/* parallel search? */
1472
1488
if (Z_TYPE_P (link ) == IS_ARRAY ) {
0 commit comments