@@ -1486,10 +1486,6 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
1486
1486
1487
1487
/* parallel search? */
1488
1488
if (Z_TYPE_P (link ) == IS_ARRAY ) {
1489
- int i , * rcs ;
1490
- ldap_linkdata * * lds ;
1491
- zval * entry , object ;
1492
-
1493
1489
uint32_t num_links = zend_hash_num_elements (Z_ARRVAL_P (link ));
1494
1490
if (num_links == 0 ) {
1495
1491
zend_argument_must_not_be_empty_error (1 );
@@ -1515,7 +1511,6 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
1515
1511
ret = 0 ;
1516
1512
goto cleanup ;
1517
1513
}
1518
- zend_hash_internal_pointer_reset (base_dn_ht );
1519
1514
} else {
1520
1515
if (zend_str_has_nul_byte (base_dn_str )) {
1521
1516
zend_argument_value_error (2 , "must not contain null bytes" );
@@ -1538,7 +1533,6 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
1538
1533
ret = 0 ;
1539
1534
goto cleanup ;
1540
1535
}
1541
- zend_hash_internal_pointer_reset (filter_ht );
1542
1536
} else {
1543
1537
if (zend_str_has_nul_byte (filter_str )) {
1544
1538
zend_argument_value_error (3 , "must not contain null bytes" );
@@ -1548,73 +1542,90 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
1548
1542
ldap_filter = zend_string_copy (filter_str );
1549
1543
}
1550
1544
1545
+ int * rcs ;
1546
+ ldap_linkdata * * lds ;
1551
1547
lds = safe_emalloc (num_links , sizeof (ldap_linkdata ), 0 );
1552
1548
rcs = safe_emalloc (num_links , sizeof (* rcs ), 0 );
1553
1549
1554
- zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( link )) ;
1555
- for ( i = 0 ; i < num_links ; i ++ ) {
1556
- entry = zend_hash_get_current_data (Z_ARRVAL_P (link ));
1557
-
1558
- if (Z_TYPE_P (entry ) != IS_OBJECT || !instanceof_function (Z_OBJCE_P (entry ), ldap_link_ce )) {
1559
- zend_argument_value_error (1 , "must only contain objects of type LDAP" );
1550
+ zend_ulong ldap_link_index = 0 ;
1551
+ zval * link_zv = NULL ;
1552
+ ZEND_HASH_FOREACH_NUM_KEY_VAL (Z_ARRVAL_P (link ), ldap_link_index , link_zv ) {
1553
+ ZVAL_DEREF ( link_zv );
1554
+ if (Z_TYPE_P (link_zv ) != IS_OBJECT || !instanceof_function (Z_OBJCE_P (link_zv ), ldap_link_ce )) {
1555
+ zend_argument_value_error (1 , "must be a list of LDAP\\Connection " );
1560
1556
ret = 0 ;
1561
1557
goto cleanup_parallel ;
1562
1558
}
1563
1559
1564
- ld = Z_LDAP_LINK_P (entry );
1565
- if (!ld -> link ) {
1560
+ ldap_linkdata * current_ld = Z_LDAP_LINK_P (link_zv );
1561
+ if (!current_ld -> link ) {
1566
1562
zend_throw_error (NULL , "LDAP connection has already been closed" );
1567
1563
ret = 0 ;
1568
1564
goto cleanup_parallel ;
1569
1565
}
1570
1566
1571
1567
if (num_base_dns != 0 ) { /* base_dn an array? */
1572
- entry = zend_hash_get_current_data (base_dn_ht );
1573
- zend_hash_move_forward (base_dn_ht );
1574
- ldap_base_dn = zval_get_string (entry );
1575
- if (EG (exception )) {
1568
+ zval * base_dn_zv = zend_hash_index_find (base_dn_ht , ldap_link_index );
1569
+ ZEND_ASSERT (base_dn_zv );
1570
+ ZVAL_DEREF (base_dn_zv );
1571
+ if (Z_TYPE_P (base_dn_zv ) != IS_STRING ) {
1572
+ zend_argument_type_error (2 , "must be a list of strings, %s given" , zend_zval_value_name (base_dn_zv ));
1573
+ ret = 0 ;
1574
+ goto cleanup_parallel ;
1575
+ }
1576
+ ldap_base_dn = zend_string_copy (Z_STR_P (base_dn_zv ));
1577
+ if (zend_str_has_nul_byte (ldap_base_dn )) {
1578
+ zend_argument_value_error (2 , "must not contain null bytes" );
1576
1579
ret = 0 ;
1577
1580
goto cleanup_parallel ;
1578
1581
}
1579
- // TODO check dn does not have any nul bytes
1580
1582
}
1581
1583
if (num_filters != 0 ) { /* filter an array? */
1582
- entry = zend_hash_get_current_data (filter_ht );
1583
- zend_hash_move_forward (filter_ht );
1584
- ldap_filter = zval_get_string (entry );
1585
- if (EG (exception )) {
1584
+ zval * filter_zv = zend_hash_index_find (filter_ht , ldap_link_index );
1585
+ ZEND_ASSERT (filter_zv );
1586
+ ZVAL_DEREF (filter_zv );
1587
+ if (Z_TYPE_P (filter_zv ) != IS_STRING ) {
1588
+ zend_argument_type_error (3 , "must be a list of strings, %s given" , zend_zval_value_name (filter_zv ));
1589
+ ret = 0 ;
1590
+ goto cleanup_parallel ;
1591
+ }
1592
+ ldap_filter = zend_string_copy (Z_STR_P (filter_zv ));
1593
+ if (zend_str_has_nul_byte (ldap_filter )) {
1594
+ zend_argument_value_error (3 , "must not contain null bytes" );
1586
1595
ret = 0 ;
1587
1596
goto cleanup_parallel ;
1588
1597
}
1589
- // TODO check filter does not have any nul bytes
1590
1598
}
1591
1599
1592
1600
if (serverctrls ) {
1593
1601
/* We have to parse controls again for each link as they use it */
1594
1602
_php_ldap_controls_free (& lserverctrls );
1595
- lserverctrls = _php_ldap_controls_from_array (ld -> link , serverctrls , 9 );
1603
+ lserverctrls = _php_ldap_controls_from_array (current_ld -> link , serverctrls , 9 );
1596
1604
if (lserverctrls == NULL ) {
1597
- rcs [i ] = -1 ;
1605
+ rcs [ldap_link_index ] = -1 ;
1606
+ // TODO Throw an exception/cleanup?
1598
1607
continue ;
1599
1608
}
1600
1609
}
1601
1610
1602
- php_set_opts (ld -> link , ldap_sizelimit , ldap_timelimit , ldap_deref , & old_ldap_sizelimit , & old_ldap_timelimit , & old_ldap_deref );
1611
+ php_set_opts (current_ld -> link , ldap_sizelimit , ldap_timelimit , ldap_deref , & old_ldap_sizelimit , & old_ldap_timelimit , & old_ldap_deref );
1603
1612
1604
1613
/* Run the actual search */
1605
- ldap_search_ext (ld -> link , ZSTR_VAL (ldap_base_dn ), scope , ZSTR_VAL (ldap_filter ), ldap_attrs , ldap_attrsonly , lserverctrls , NULL , NULL , ldap_sizelimit , & rcs [i ]);
1606
- lds [i ] = ld ;
1607
- zend_hash_move_forward (Z_ARRVAL_P (link ));
1608
- }
1614
+ ldap_search_ext (current_ld -> link , ZSTR_VAL (ldap_base_dn ), scope , ZSTR_VAL (ldap_filter ), ldap_attrs , ldap_attrsonly , lserverctrls , NULL , NULL , ldap_sizelimit , & rcs [ldap_link_index ]);
1615
+ lds [ldap_link_index ] = current_ld ;
1616
+
1617
+ // TODO Reset the options of the link?
1618
+ } ZEND_HASH_FOREACH_END ();
1609
1619
1610
1620
array_init (return_value );
1611
1621
1612
1622
/* Collect results from the searches */
1613
- for (i = 0 ; i < num_links ; i ++ ) {
1623
+ for (uint32_t i = 0 ; i < num_links ; i ++ ) {
1614
1624
if (rcs [i ] != -1 ) {
1615
1625
rcs [i ] = ldap_result (lds [i ]-> link , LDAP_RES_ANY , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res );
1616
1626
}
1617
1627
if (rcs [i ] != -1 ) {
1628
+ zval object ;
1618
1629
object_init_ex (& object , ldap_result_ce );
1619
1630
result = Z_LDAP_RESULT_P (& object );
1620
1631
result -> result = ldap_res ;
0 commit comments