From c202e80bb31b26aec1765350180f2a6d82a88457 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 9 Jan 2025 23:03:58 +0000 Subject: [PATCH 1/3] ext/ldap: ldap_read/ldap_list/ldap_search update. checks sizelimit/timelimit checks and attrsonly from int to bool. --- ext/ldap/ldap.c | 22 +++++++++++++++++++--- ext/ldap/ldap.stub.php | 6 +++--- ext/ldap/ldap_arginfo.h | 4 ++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 90f3ba6a54f98..762bad2c56ded 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1448,7 +1448,8 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) zend_string *base_dn_str = NULL; HashTable *filter_ht = NULL; zend_string *filter_str = NULL; - zend_long attrsonly, sizelimit, timelimit, deref; + zend_long sizelimit = 0, timelimit = 0, deref = LDAP_DEREF_NEVER; + bool attrsonly = false; HashTable *server_controls_ht = NULL; char **ldap_attrs = NULL; ldap_linkdata *ld = NULL; @@ -1465,13 +1466,28 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) Z_PARAM_ARRAY_HT_OR_STR(filter_ht, filter_str) Z_PARAM_OPTIONAL Z_PARAM_ARRAY_EX(attrs, 0, 1) - Z_PARAM_LONG(attrsonly) + Z_PARAM_BOOL(attrsonly) Z_PARAM_LONG(sizelimit) Z_PARAM_LONG(timelimit) Z_PARAM_LONG(deref) Z_PARAM_ARRAY_HT_EX(server_controls_ht, 1, 1) ZEND_PARSE_PARAMETERS_END(); + if (sizelimit < -1 || sizelimit > INT_MAX) { + zend_argument_value_error(6, "must be between -1 and %d", INT_MAX); + RETURN_THROWS(); + } + + if (timelimit < -1 || timelimit > INT_MAX) { + zend_argument_value_error(7, "must be between -1 and %d", INT_MAX); + RETURN_THROWS(); + } + + if (deref < LDAP_DEREF_NEVER || deref > LDAP_DEREF_ALWAYS) { + zend_argument_value_error(8, "must be one of the LDAP_DEREF_* constants"); + RETURN_THROWS(); + } + /* Reverse -> fall through */ switch (argcount) { case 9: @@ -1485,7 +1501,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ldap_sizelimit = sizelimit; ZEND_FALLTHROUGH; case 5: - ldap_attrsonly = attrsonly; + ldap_attrsonly = attrsonly ? 1 : 0; ZEND_FALLTHROUGH; default: break; diff --git a/ext/ldap/ldap.stub.php b/ext/ldap/ldap.stub.php index f3615e4d42cc0..a329db3273c90 100644 --- a/ext/ldap/ldap.stub.php +++ b/ext/ldap/ldap.stub.php @@ -646,13 +646,13 @@ function ldap_sasl_bind(LDAP\Connection $ldap, ?string $dn = null, #[\SensitiveP #endif /** @param LDAP\Connection|array $ldap */ - function ldap_read($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} + function ldap_read($ldap, array|string $base, array|string $filter, array $attributes = [], bool $attributes_only = false, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} /** @param LDAP\Connection|array $ldap */ - function ldap_list($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} + function ldap_list($ldap, array|string $base, array|string $filter, array $attributes = [], bool $attributes_only = false, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} /** @param LDAP\Connection|array $ldap */ - function ldap_search($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} + function ldap_search($ldap, array|string $base, array|string $filter, array $attributes = [], bool $attributes_only = false, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} function ldap_free_result(LDAP\Result $result): bool {} diff --git a/ext/ldap/ldap_arginfo.h b/ext/ldap/ldap_arginfo.h index 01e08540142b4..359c0c089ba6a 100644 --- a/ext/ldap/ldap_arginfo.h +++ b/ext/ldap/ldap_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7415695a7ae90e6abd45617baf8a9ecf9232b801 */ + * Stub hash: 3e12935bcfe9031bb9645892407582c322eaca3d */ #if defined(HAVE_ORALDAP) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_ldap_connect, 0, 0, LDAP\\Connection, MAY_BE_FALSE) @@ -64,7 +64,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_ldap_read, 0, 3, LDAP\\Resul ZEND_ARG_TYPE_MASK(0, base, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_MASK(0, filter, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes, IS_ARRAY, 0, "[]") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes_only, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes_only, _IS_BOOL, 0, "false") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sizelimit, IS_LONG, 0, "-1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timelimit, IS_LONG, 0, "-1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deref, IS_LONG, 0, "LDAP_DEREF_NEVER") From 108c4680967fe10d43f30c80f0fcd79a245108d7 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 10 Jan 2025 07:04:31 +0000 Subject: [PATCH 2/3] adding test cases --- ext/ldap/tests/ldap_search_error.phpt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ext/ldap/tests/ldap_search_error.phpt b/ext/ldap/tests/ldap_search_error.phpt index 10906a44afc00..53e492ad48f13 100644 --- a/ext/ldap/tests/ldap_search_error.phpt +++ b/ext/ldap/tests/ldap_search_error.phpt @@ -26,6 +26,24 @@ try { echo $exception->getMessage() . "\n"; } +try { + ldap_search($link, $dn, $filter, array('option'), false, PHP_INT_MIN); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + ldap_search($link, $dn, $filter, array('option'), false, -1, PHP_INT_MIN); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + ldap_search($link, $dn, $filter, array('option'), false, -1, -1, -1); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + try { ldap_search(array(), $dn, $filter, array('top')); } catch (ValueError $exception) { @@ -61,6 +79,9 @@ try { Warning: ldap_search(): Search: No such object in %s on line %d bool(false) ldap_search(): Argument #4 ($attributes) must be an array with numeric keys +ldap_search(): Argument #6 ($sizelimit) must be between -1 and %d +ldap_search(): Argument #7 ($timelimit) must be between -1 and %d +ldap_search(): Argument #8 ($deref) must be one of the LDAP_DEREF_* constants ldap_search(): Argument #1 ($ldap) must not be empty ldap_search(): Argument #2 ($base) must be the same size as argument #1 ldap_search(): Argument #3 ($filter) must be the same size as argument #1 From 8623c731b1b67eb9eeca2e5ed20022f0538cd81a Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 4 Feb 2025 19:44:27 +0000 Subject: [PATCH 3/3] changes from review --- ext/ldap/ldap.c | 38 +++++++++----------------------------- ext/ldap/ldap.stub.php | 6 +++--- ext/ldap/ldap_arginfo.h | 4 ++-- 3 files changed, 14 insertions(+), 34 deletions(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 762bad2c56ded..36af9812fd323 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1448,17 +1448,16 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) zend_string *base_dn_str = NULL; HashTable *filter_ht = NULL; zend_string *filter_str = NULL; - zend_long sizelimit = 0, timelimit = 0, deref = LDAP_DEREF_NEVER; - bool attrsonly = false; + zend_long sizelimit = -1, timelimit = -1, deref = LDAP_DEREF_NEVER; + zend_long attrsonly = 0; HashTable *server_controls_ht = NULL; char **ldap_attrs = NULL; ldap_linkdata *ld = NULL; ldap_resultdata *result; LDAPMessage *ldap_res = NULL; LDAPControl **lserverctrls = NULL; - int ldap_attrsonly = 0, ldap_sizelimit = -1, ldap_timelimit = -1, ldap_deref = -1; int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1; - int ret = 1, ldap_errno, argcount = ZEND_NUM_ARGS(); + int ret = 1, ldap_errno; ZEND_PARSE_PARAMETERS_START(3, 9) Z_PARAM_ZVAL(link) @@ -1466,7 +1465,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) Z_PARAM_ARRAY_HT_OR_STR(filter_ht, filter_str) Z_PARAM_OPTIONAL Z_PARAM_ARRAY_EX(attrs, 0, 1) - Z_PARAM_BOOL(attrsonly) + Z_PARAM_LONG(attrsonly) Z_PARAM_LONG(sizelimit) Z_PARAM_LONG(timelimit) Z_PARAM_LONG(deref) @@ -1488,25 +1487,6 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) RETURN_THROWS(); } - /* Reverse -> fall through */ - switch (argcount) { - case 9: - case 8: - ldap_deref = deref; - ZEND_FALLTHROUGH; - case 7: - ldap_timelimit = timelimit; - ZEND_FALLTHROUGH; - case 6: - ldap_sizelimit = sizelimit; - ZEND_FALLTHROUGH; - case 5: - ldap_attrsonly = attrsonly ? 1 : 0; - ZEND_FALLTHROUGH; - default: - break; - } - if (attrs) { const HashTable *attributes = Z_ARRVAL_P(attrs); uint32_t num_attribs = zend_hash_num_elements(attributes); @@ -1669,10 +1649,10 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) } } - php_set_opts(current_ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); + php_set_opts(current_ld->link, (int)sizelimit, (int)timelimit, (int)deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); /* Run the actual search */ - 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]); + ldap_search_ext(current_ld->link, ZSTR_VAL(ldap_base_dn), scope, ZSTR_VAL(ldap_filter), ldap_attrs, (int)attrsonly, lserverctrls, NULL, NULL, (int)sizelimit, &rcs[ldap_link_index]); lds[ldap_link_index] = current_ld; // TODO Reset the options of the link? @@ -1727,10 +1707,10 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) } } - php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); + php_set_opts(ld->link, (int)sizelimit, (int)timelimit, (int)deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); /* Run the actual search */ - ldap_errno = ldap_search_ext_s(ld->link, ZSTR_VAL(base_dn_str), scope, ZSTR_VAL(filter_str), ldap_attrs, ldap_attrsonly, lserverctrls, NULL, NULL, ldap_sizelimit, &ldap_res); + ldap_errno = ldap_search_ext_s(ld->link, ZSTR_VAL(base_dn_str), scope, ZSTR_VAL(filter_str), ldap_attrs, (int)attrsonly, lserverctrls, NULL, NULL, (int)sizelimit, &ldap_res); if (ldap_errno != LDAP_SUCCESS && ldap_errno != LDAP_SIZELIMIT_EXCEEDED @@ -1768,7 +1748,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) cleanup: if (ld) { /* Restoring previous options */ - php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref); + php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, (int *)&sizelimit, (int *)&timelimit, (int *)&deref); } if (ldap_attrs != NULL) { efree(ldap_attrs); diff --git a/ext/ldap/ldap.stub.php b/ext/ldap/ldap.stub.php index a329db3273c90..f3615e4d42cc0 100644 --- a/ext/ldap/ldap.stub.php +++ b/ext/ldap/ldap.stub.php @@ -646,13 +646,13 @@ function ldap_sasl_bind(LDAP\Connection $ldap, ?string $dn = null, #[\SensitiveP #endif /** @param LDAP\Connection|array $ldap */ - function ldap_read($ldap, array|string $base, array|string $filter, array $attributes = [], bool $attributes_only = false, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} + function ldap_read($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} /** @param LDAP\Connection|array $ldap */ - function ldap_list($ldap, array|string $base, array|string $filter, array $attributes = [], bool $attributes_only = false, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} + function ldap_list($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} /** @param LDAP\Connection|array $ldap */ - function ldap_search($ldap, array|string $base, array|string $filter, array $attributes = [], bool $attributes_only = false, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} + function ldap_search($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} function ldap_free_result(LDAP\Result $result): bool {} diff --git a/ext/ldap/ldap_arginfo.h b/ext/ldap/ldap_arginfo.h index 359c0c089ba6a..01e08540142b4 100644 --- a/ext/ldap/ldap_arginfo.h +++ b/ext/ldap/ldap_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3e12935bcfe9031bb9645892407582c322eaca3d */ + * Stub hash: 7415695a7ae90e6abd45617baf8a9ecf9232b801 */ #if defined(HAVE_ORALDAP) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_ldap_connect, 0, 0, LDAP\\Connection, MAY_BE_FALSE) @@ -64,7 +64,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_ldap_read, 0, 3, LDAP\\Resul ZEND_ARG_TYPE_MASK(0, base, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_MASK(0, filter, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes, IS_ARRAY, 0, "[]") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes_only, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes_only, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sizelimit, IS_LONG, 0, "-1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timelimit, IS_LONG, 0, "-1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deref, IS_LONG, 0, "LDAP_DEREF_NEVER")