@@ -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 */
258263static 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 }
0 commit comments