mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Backport fix GH-17280: ldap_search() fails when $attributes array has holes
This commit is contained in:
commit
726c96fbef
5 changed files with 82 additions and 43 deletions
4
NEWS
4
NEWS
|
@ -65,6 +65,10 @@ PHP NEWS
|
||||||
- Iconv:
|
- Iconv:
|
||||||
. Fixed bug GH-17047 (UAF on iconv filter failure). (nielsdos)
|
. Fixed bug GH-17047 (UAF on iconv filter failure). (nielsdos)
|
||||||
|
|
||||||
|
- LDAP:
|
||||||
|
. Fixed bug GH-17280 (ldap_search() fails when $attributes array has holes).
|
||||||
|
(nielsdos)
|
||||||
|
|
||||||
- LibXML:
|
- LibXML:
|
||||||
. Fixed bug GH-17223 (Memory leak in libxml encoding handling). (nielsdos)
|
. Fixed bug GH-17223 (Memory leak in libxml encoding handling). (nielsdos)
|
||||||
|
|
||||||
|
|
|
@ -234,6 +234,22 @@ static void ldap_result_entry_free_obj(zend_object *obj)
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool php_ldap_is_numerically_indexed_array(zend_array *arr)
|
||||||
|
{
|
||||||
|
if (zend_hash_num_elements(arr) == 0 || HT_IS_PACKED(arr)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
zend_string *str_key;
|
||||||
|
ZEND_HASH_MAP_FOREACH_STR_KEY(arr, str_key) {
|
||||||
|
if (str_key) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* {{{ Parse controls from and to arrays */
|
/* {{{ Parse controls from and to arrays */
|
||||||
static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, int request)
|
static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, int request)
|
||||||
{
|
{
|
||||||
|
@ -1473,20 +1489,22 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
|
||||||
num_attribs = zend_hash_num_elements(Z_ARRVAL_P(attrs));
|
num_attribs = zend_hash_num_elements(Z_ARRVAL_P(attrs));
|
||||||
ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0);
|
ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0);
|
||||||
|
|
||||||
for (i = 0; i<num_attribs; i++) {
|
if (!php_ldap_is_numerically_indexed_array(Z_ARRVAL_P(attrs))) {
|
||||||
if ((attr = zend_hash_index_find(Z_ARRVAL_P(attrs), i)) == NULL) {
|
php_error_docref(NULL, E_WARNING, "Argument #4 ($attributes) must be an array with numeric keys");
|
||||||
php_error_docref(NULL, E_WARNING, "Array initialization wrong");
|
ret = 0;
|
||||||
ret = 0;
|
goto cleanup;
|
||||||
goto cleanup;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(attrs), attr) {
|
||||||
convert_to_string(attr);
|
convert_to_string(attr);
|
||||||
if (EG(exception)) {
|
if (EG(exception)) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
ldap_attrs[i] = Z_STRVAL_P(attr);
|
ldap_attrs[i++] = Z_STRVAL_P(attr);
|
||||||
}
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
|
||||||
ldap_attrs[num_attribs] = NULL;
|
ldap_attrs[num_attribs] = NULL;
|
||||||
ZEND_FALLTHROUGH;
|
ZEND_FALLTHROUGH;
|
||||||
default:
|
default:
|
||||||
|
@ -2259,14 +2277,16 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
|
||||||
ldap_mods[i]->mod_bvalues[0]->bv_val = Z_STRVAL_P(value);
|
ldap_mods[i]->mod_bvalues[0]->bv_val = Z_STRVAL_P(value);
|
||||||
ldap_mods[i]->mod_bvalues[0]->bv_len = Z_STRLEN_P(value);
|
ldap_mods[i]->mod_bvalues[0]->bv_len = Z_STRLEN_P(value);
|
||||||
} else {
|
} else {
|
||||||
for (j = 0; j < num_values; j++) {
|
if (!php_ldap_is_numerically_indexed_array(Z_ARRVAL_P(value))) {
|
||||||
if ((ivalue = zend_hash_index_find(Z_ARRVAL_P(value), j)) == NULL) {
|
zend_argument_value_error(3, "must be an array with numeric keys");
|
||||||
zend_argument_value_error(3, "must contain arrays with consecutive integer indices starting from 0");
|
RETVAL_FALSE;
|
||||||
num_berval[i] = j;
|
num_berval[i] = 0;
|
||||||
num_attribs = i + 1;
|
num_attribs = i + 1;
|
||||||
RETVAL_FALSE;
|
goto cleanup;
|
||||||
goto cleanup;
|
}
|
||||||
}
|
|
||||||
|
j = 0;
|
||||||
|
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), ivalue) {
|
||||||
convert_to_string(ivalue);
|
convert_to_string(ivalue);
|
||||||
if (EG(exception)) {
|
if (EG(exception)) {
|
||||||
num_berval[i] = j;
|
num_berval[i] = j;
|
||||||
|
@ -2277,7 +2297,8 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
|
||||||
ldap_mods[i]->mod_bvalues[j] = (struct berval *) emalloc (sizeof(struct berval));
|
ldap_mods[i]->mod_bvalues[j] = (struct berval *) emalloc (sizeof(struct berval));
|
||||||
ldap_mods[i]->mod_bvalues[j]->bv_val = Z_STRVAL_P(ivalue);
|
ldap_mods[i]->mod_bvalues[j]->bv_val = Z_STRVAL_P(ivalue);
|
||||||
ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_P(ivalue);
|
ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_P(ivalue);
|
||||||
}
|
j++;
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
}
|
}
|
||||||
ldap_mods[i]->mod_bvalues[num_values] = NULL;
|
ldap_mods[i]->mod_bvalues[num_values] = NULL;
|
||||||
zend_hash_move_forward(Z_ARRVAL_P(entry));
|
zend_hash_move_forward(Z_ARRVAL_P(entry));
|
||||||
|
@ -2545,7 +2566,7 @@ PHP_FUNCTION(ldap_modify_batch)
|
||||||
zval *fetched;
|
zval *fetched;
|
||||||
char *dn;
|
char *dn;
|
||||||
size_t dn_len;
|
size_t dn_len;
|
||||||
int i, j, k;
|
int i, j;
|
||||||
int num_mods, num_modprops, num_modvals;
|
int num_mods, num_modprops, num_modvals;
|
||||||
LDAPMod **ldap_mods;
|
LDAPMod **ldap_mods;
|
||||||
LDAPControl **lserverctrls = NULL;
|
LDAPControl **lserverctrls = NULL;
|
||||||
|
@ -2605,12 +2626,14 @@ PHP_FUNCTION(ldap_modify_batch)
|
||||||
|
|
||||||
num_mods = zend_hash_num_elements(Z_ARRVAL_P(mods));
|
num_mods = zend_hash_num_elements(Z_ARRVAL_P(mods));
|
||||||
|
|
||||||
for (i = 0; i < num_mods; i++) {
|
if (!php_ldap_is_numerically_indexed_array(Z_ARRVAL_P(mods))) {
|
||||||
/* is the numbering consecutive? */
|
zend_argument_value_error(3, "must be an array with numeric keys");
|
||||||
if ((fetched = zend_hash_index_find(Z_ARRVAL_P(mods), i)) == NULL) {
|
RETURN_THROWS();
|
||||||
zend_argument_value_error(3, "must have consecutive integer indices starting from 0");
|
}
|
||||||
RETURN_THROWS();
|
|
||||||
}
|
i = 0;
|
||||||
|
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(mods), fetched) {
|
||||||
|
ZVAL_DEREF(fetched);
|
||||||
mod = fetched;
|
mod = fetched;
|
||||||
|
|
||||||
/* is it an array? */
|
/* is it an array? */
|
||||||
|
@ -2708,19 +2731,10 @@ PHP_FUNCTION(ldap_modify_batch)
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* are its keys integers? */
|
if (!php_ldap_is_numerically_indexed_array(Z_ARRVAL_P(modinfo))) {
|
||||||
if (zend_hash_get_current_key_type(Z_ARRVAL_P(modinfo)) != HASH_KEY_IS_LONG) {
|
zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be an array with numeric keys", get_active_function_name());
|
||||||
zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be integer-indexed", get_active_function_name());
|
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* are the keys consecutive? */
|
|
||||||
for (k = 0; k < num_modvals; k++) {
|
|
||||||
if ((fetched = zend_hash_index_find(Z_ARRVAL_P(modinfo), k)) == NULL) {
|
|
||||||
zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must have consecutive integer indices starting from 0", get_active_function_name());
|
|
||||||
RETURN_THROWS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_hash_move_forward(Z_ARRVAL_P(mod));
|
zend_hash_move_forward(Z_ARRVAL_P(mod));
|
||||||
|
@ -2734,7 +2748,9 @@ PHP_FUNCTION(ldap_modify_batch)
|
||||||
zend_value_error("%s(): Required option \"" LDAP_MODIFY_BATCH_MODTYPE "\" is missing", get_active_function_name());
|
zend_value_error("%s(): Required option \"" LDAP_MODIFY_BATCH_MODTYPE "\" is missing", get_active_function_name());
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
i++;
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
}
|
}
|
||||||
/* validation was successful */
|
/* validation was successful */
|
||||||
|
|
||||||
|
@ -2788,9 +2804,9 @@ PHP_FUNCTION(ldap_modify_batch)
|
||||||
ldap_mods[i]->mod_bvalues = safe_emalloc((num_modvals+1), sizeof(struct berval *), 0);
|
ldap_mods[i]->mod_bvalues = safe_emalloc((num_modvals+1), sizeof(struct berval *), 0);
|
||||||
|
|
||||||
/* for each value */
|
/* for each value */
|
||||||
for (j = 0; j < num_modvals; j++) {
|
j = 0;
|
||||||
|
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(vals), fetched) {
|
||||||
/* fetch it */
|
/* fetch it */
|
||||||
fetched = zend_hash_index_find(Z_ARRVAL_P(vals), j);
|
|
||||||
modval = zval_get_string(fetched);
|
modval = zval_get_string(fetched);
|
||||||
if (EG(exception)) {
|
if (EG(exception)) {
|
||||||
RETVAL_FALSE;
|
RETVAL_FALSE;
|
||||||
|
@ -2806,7 +2822,8 @@ PHP_FUNCTION(ldap_modify_batch)
|
||||||
ldap_mods[i]->mod_bvalues[j]->bv_len = ZSTR_LEN(modval);
|
ldap_mods[i]->mod_bvalues[j]->bv_len = ZSTR_LEN(modval);
|
||||||
ldap_mods[i]->mod_bvalues[j]->bv_val = estrndup(ZSTR_VAL(modval), ZSTR_LEN(modval));
|
ldap_mods[i]->mod_bvalues[j]->bv_val = estrndup(ZSTR_VAL(modval), ZSTR_LEN(modval));
|
||||||
zend_string_release(modval);
|
zend_string_release(modval);
|
||||||
}
|
j++;
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
|
||||||
/* NULL-terminate values */
|
/* NULL-terminate values */
|
||||||
ldap_mods[i]->mod_bvalues[num_modvals] = NULL;
|
ldap_mods[i]->mod_bvalues[num_modvals] = NULL;
|
||||||
|
|
18
ext/ldap/tests/gh17280.phpt
Normal file
18
ext/ldap/tests/gh17280.phpt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
--TEST--
|
||||||
|
GH-17280 (ldap_search() fails when $attributes array has holes)
|
||||||
|
--EXTENSIONS--
|
||||||
|
ldap
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/* We are assuming 3333 is not connectable */
|
||||||
|
$ldap = ldap_connect('ldap://127.0.0.1:3333');
|
||||||
|
|
||||||
|
// Creating an array with a hole in it
|
||||||
|
$attr = array_unique(['cn', 'uid', 'uid', 'mail']);
|
||||||
|
var_dump(ldap_search($ldap, 'ou=people,dc=example,dc=com', 'uid=admin', $attr));
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: ldap_search(): Search: Can't contact LDAP server in %s on line %d
|
||||||
|
bool(false)
|
|
@ -43,7 +43,7 @@ try {
|
||||||
ldap_add($link, "dc=my-domain2,dc=com", array(
|
ldap_add($link, "dc=my-domain2,dc=com", array(
|
||||||
"objectClass" => array(
|
"objectClass" => array(
|
||||||
0 => "top",
|
0 => "top",
|
||||||
2 => "dcObject",
|
"x" => "dcObject",
|
||||||
5 => "organization"),
|
5 => "organization"),
|
||||||
"dc" => "my-domain",
|
"dc" => "my-domain",
|
||||||
"o" => "my-domain",
|
"o" => "my-domain",
|
||||||
|
@ -104,7 +104,7 @@ Warning: ldap_add(): Add: Already exists in %s on line %d
|
||||||
bool(false)
|
bool(false)
|
||||||
string(14) "Already exists"
|
string(14) "Already exists"
|
||||||
int(68)
|
int(68)
|
||||||
ldap_add(): Argument #3 ($entry) must contain arrays with consecutive integer indices starting from 0
|
ldap_add(): Argument #3 ($entry) must be an array with numeric keys
|
||||||
|
|
||||||
Warning: ldap_add(): Add: Undefined attribute type in %s on line %d
|
Warning: ldap_add(): Add: Undefined attribute type in %s on line %d
|
||||||
bool(false)
|
bool(false)
|
||||||
|
|
|
@ -19,7 +19,7 @@ $filter = "(dc=*)";
|
||||||
$result = ldap_search($link, $dn, $filter);
|
$result = ldap_search($link, $dn, $filter);
|
||||||
var_dump($result);
|
var_dump($result);
|
||||||
|
|
||||||
$result = ldap_search($link, $dn, $filter, array(1 => 'top'));
|
$result = ldap_search($link, $dn, $filter, array('foo' => 'top'));
|
||||||
var_dump($result);
|
var_dump($result);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -57,7 +57,7 @@ try {
|
||||||
Warning: ldap_search(): Search: No such object in %s on line %d
|
Warning: ldap_search(): Search: No such object in %s on line %d
|
||||||
bool(false)
|
bool(false)
|
||||||
|
|
||||||
Warning: ldap_search(): Array initialization wrong in %s on line %d
|
Warning: ldap_search(): Argument #4 ($attributes) must be an array with numeric keys in %s on line %d
|
||||||
bool(false)
|
bool(false)
|
||||||
ldap_search(): Argument #1 ($ldap) must not be empty
|
ldap_search(): Argument #1 ($ldap) must not be empty
|
||||||
ldap_search(): Argument #2 ($base) must have the same number of elements as the links array
|
ldap_search(): Argument #2 ($base) must have the same number of elements as the links array
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue