Skip to content

Commit 636b6a1

Browse files
committed
ext/ldap: Parse attribute value via new API in do_modify
Add a new API to free a zend_string via its char*
1 parent 495837b commit 636b6a1

File tree

3 files changed

+23
-22
lines changed

3 files changed

+23
-22
lines changed

ext/ldap/ldap.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,11 @@ static zend_string* php_ldap_try_get_ldap_value_from_zval(zval *zv) {
254254
}
255255
}
256256

257+
/* The char pointer MUST refer to the char* of a zend_string struct */
258+
static void php_ldap_zend_string_release_from_char_pointer(char *ptr) {
259+
zend_string_release((zend_string*) (ptr - XtOffsetOf(zend_string, val)));
260+
}
261+
257262
/* {{{ Parse controls from and to arrays */
258263
static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, int request)
259264
{
@@ -2278,15 +2283,16 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22782283
/* If the attribute takes a single value it can be passed directly instead of as a list with one element */
22792284
/* allow for arrays with one element, no allowance for arrays with none but probably not required, gerrit thomson. */
22802285
if (Z_TYPE_P(attribute_values) != IS_ARRAY) {
2281-
convert_to_string(attribute_values);
2282-
if (EG(exception)) {
2286+
zend_string *value = php_ldap_try_get_ldap_value_from_zval(attribute_values);
2287+
if (UNEXPECTED(value == NULL)) {
22832288
RETVAL_FALSE;
22842289
goto cleanup;
22852290
}
22862291
ldap_mods[attribute_index]->mod_bvalues = safe_emalloc(2, sizeof(struct berval *), 0);
22872292
ldap_mods[attribute_index]->mod_bvalues[0] = (struct berval *) emalloc (sizeof(struct berval));
2288-
ldap_mods[attribute_index]->mod_bvalues[0]->bv_val = Z_STRVAL_P(attribute_values);
2289-
ldap_mods[attribute_index]->mod_bvalues[0]->bv_len = Z_STRLEN_P(attribute_values);
2293+
/* The string will be free by php_ldap_zend_string_release_from_char_pointer() during cleanup */
2294+
ldap_mods[attribute_index]->mod_bvalues[0]->bv_val = ZSTR_VAL(value);
2295+
ldap_mods[attribute_index]->mod_bvalues[0]->bv_len = ZSTR_LEN(value);
22902296
ldap_mods[attribute_index]->mod_bvalues[1] = NULL;
22912297
} else {
22922298
SEPARATE_ARRAY(attribute_values);
@@ -2309,14 +2315,15 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
23092315
zend_ulong attribute_value_index = 0;
23102316
zval *attribute_value = NULL;
23112317
ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(attribute_values), attribute_value_index, attribute_value) {
2312-
convert_to_string(attribute_value);
2313-
if (EG(exception)) {
2318+
zend_string *value = php_ldap_try_get_ldap_value_from_zval(attribute_value);
2319+
if (UNEXPECTED(value == NULL)) {
23142320
RETVAL_FALSE;
23152321
goto cleanup;
23162322
}
23172323
ldap_mods[attribute_index]->mod_bvalues[attribute_value_index] = (struct berval *) emalloc (sizeof(struct berval));
2318-
ldap_mods[attribute_index]->mod_bvalues[attribute_value_index]->bv_val = Z_STRVAL_P(attribute_value);
2319-
ldap_mods[attribute_index]->mod_bvalues[attribute_value_index]->bv_len = Z_STRLEN_P(attribute_value);
2324+
/* The string will be free by php_ldap_zend_string_release_from_char_pointer() during cleanup */
2325+
ldap_mods[attribute_index]->mod_bvalues[attribute_value_index]->bv_val = ZSTR_VAL(value);
2326+
ldap_mods[attribute_index]->mod_bvalues[attribute_value_index]->bv_len = ZSTR_LEN(value);
23202327
} ZEND_HASH_FOREACH_END();
23212328
ldap_mods[attribute_index]->mod_bvalues[num_values] = NULL;
23222329
}
@@ -2388,7 +2395,9 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
23882395
efree(mod->mod_type);
23892396
if (mod->mod_bvalues != NULL) {
23902397
for (struct berval **bval_ptr = mod->mod_bvalues; *bval_ptr != NULL; bval_ptr++) {
2391-
efree(*bval_ptr);
2398+
struct berval *bval = *bval_ptr;
2399+
php_ldap_zend_string_release_from_char_pointer(bval->bv_val);
2400+
efree(bval);
23922401
}
23932402
efree(mod->mod_bvalues);
23942403
}

ext/ldap/tests/ldap_add_modify_delete_programming_errors.phpt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,13 @@ try {
131131
/* We don't check that values have nul bytes as the length of the string is passed to LDAP */
132132

133133
?>
134-
--EXPECTF--
134+
--EXPECT--
135135
ValueError: ldap_add(): Argument #3 ($entry) must not be empty
136136
ValueError: ldap_add(): Argument #3 ($entry) must be an associative array of attribute => values
137137
ValueError: ldap_add(): Argument #3 ($entry) key must not be empty
138138
ValueError: ldap_add(): Argument #3 ($entry) key must not contain any null bytes
139139
Error: Object of class stdClass could not be converted to string
140140
ValueError: ldap_add(): Argument #3 ($entry) list of attribute values must not be empty
141141
ValueError: ldap_add(): Argument #3 ($entry) must be a list of attribute values
142-
143-
Warning: Array to string conversion in %s on line %d
144-
145-
Warning: ldap_add(): Add: Can't contact LDAP server in %s on line %d
146-
bool(false)
142+
TypeError: LDAP value must be of type string|int|bool, array given
147143
Error: Object of class stdClass could not be converted to string

ext/ldap/tests/ldap_add_modify_delete_references_programming_errors.phpt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,8 @@ try {
7474
/* We don't check that values have nul bytes as the length of the string is passed to LDAP */
7575

7676
?>
77-
--EXPECTF--
77+
--EXPECT--
7878
Error: Object of class stdClass could not be converted to string
7979
ValueError: ldap_add(): Argument #3 ($entry) list of attribute values must not be empty
80-
81-
Warning: Array to string conversion in %s on line %d
82-
83-
Warning: ldap_add(): Add: Can't contact LDAP server in %s on line %d
84-
bool(false)
85-
Error: Object of class stdClass could not be converted to string
80+
TypeError: LDAP value must be of type string|int|bool, array given
81+
TypeError: LDAP value must be of type string|int|bool, stdClass given

0 commit comments

Comments
 (0)