@@ -73,7 +73,7 @@ void ldap_memvfree(void **v)
7373typedef struct {
7474 LDAP * link ;
7575#if defined(LDAP_API_FEATURE_X_OPENLDAP ) && defined(HAVE_3ARG_SETREBINDPROC )
76- zval rebindproc ;
76+ zend_fcall_info_cache rebind_proc_fcc ;
7777#endif
7878 zend_object std ;
7979} ldap_linkdata ;
@@ -131,7 +131,9 @@ static void ldap_link_free(ldap_linkdata *ld)
131131 ld -> link = NULL ;
132132
133133#if defined(LDAP_API_FEATURE_X_OPENLDAP ) && defined(HAVE_3ARG_SETREBINDPROC )
134- zval_ptr_dtor (& ld -> rebindproc );
134+ if (ZEND_FCC_INITIALIZED (ld -> rebind_proc_fcc )) {
135+ zend_fcc_dtor (& ld -> rebind_proc_fcc );
136+ }
135137#endif
136138
137139 LDAPG (num_links )-- ;
@@ -3711,19 +3713,20 @@ int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgi
37113713 }
37123714
37133715 /* link exists and callback set? */
3714- if (Z_ISUNDEF (ld -> rebindproc )) {
3716+ if (! ZEND_FCC_INITIALIZED (ld -> rebind_proc_fcc )) {
37153717 php_error_docref (NULL , E_WARNING , "No callback set" );
37163718 return LDAP_OTHER ;
37173719 }
37183720
37193721 /* callback */
37203722 ZVAL_COPY_VALUE (& cb_args [0 ], cb_link );
37213723 ZVAL_STRING (& cb_args [1 ], url );
3722- if (call_user_function (EG (function_table ), NULL , & ld -> rebindproc , & cb_retval , 2 , cb_args ) == SUCCESS && !Z_ISUNDEF (cb_retval )) {
3724+ zend_call_known_fcc (& ld -> rebind_proc_fcc , & cb_retval , 2 , cb_args , NULL );
3725+ if (EXPECTED (!Z_ISUNDEF (cb_retval ))) {
3726+ // TODO Use zval_try_get_long()
37233727 retval = zval_get_long (& cb_retval );
37243728 zval_ptr_dtor (& cb_retval );
37253729 } else {
3726- php_error_docref (NULL , E_WARNING , "rebind_proc PHP callback failed" );
37273730 retval = LDAP_OTHER ;
37283731 }
37293732 zval_ptr_dtor (& cb_args [1 ]);
@@ -3735,35 +3738,35 @@ int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgi
37353738PHP_FUNCTION (ldap_set_rebind_proc )
37363739{
37373740 zval * link ;
3738- zend_fcall_info fci ;
3739- zend_fcall_info_cache fcc ;
3741+ zend_fcall_info dummy_fci ;
3742+ zend_fcall_info_cache fcc = empty_fcall_info_cache ;
37403743 ldap_linkdata * ld ;
37413744
3742- if (zend_parse_parameters (ZEND_NUM_ARGS (), "Of !" , & link , ldap_link_ce , & fci , & fcc ) == FAILURE ) {
3745+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "OF !" , & link , ldap_link_ce , & dummy_fci , & fcc ) == FAILURE ) {
37433746 RETURN_THROWS ();
37443747 }
37453748
37463749 ld = Z_LDAP_LINK_P (link );
3747- VERIFY_LDAP_LINK_CONNECTED (ld );
3748-
3749- if (!ZEND_FCI_INITIALIZED (fci )) {
3750- /* unregister rebind procedure */
3751- if (!Z_ISUNDEF (ld -> rebindproc )) {
3752- zval_ptr_dtor (& ld -> rebindproc );
3753- ZVAL_UNDEF (& ld -> rebindproc );
3754- ldap_set_rebind_proc (ld -> link , NULL , NULL );
3755- }
3756- RETURN_TRUE ;
3750+ /* Inline VERIFY_LDAP_LINK_CONNECTED(ld); as we need to free trampoline */
3751+ if (!ld -> link ) {
3752+ zend_release_fcall_info_cache (& fcc );
3753+ zend_throw_error (NULL , "LDAP connection has already been closed" );
3754+ RETURN_THROWS ();
37573755 }
37583756
3759- /* register rebind procedure */
3760- if (Z_ISUNDEF (ld -> rebindproc )) {
3757+ /* Free old FCC */
3758+ if (!ZEND_FCC_INITIALIZED (ld -> rebind_proc_fcc )) {
3759+ zend_fcc_dtor (& ld -> rebind_proc_fcc );
3760+ }
3761+ if (ZEND_FCC_INITIALIZED (fcc )) {
3762+ /* register rebind procedure */
37613763 ldap_set_rebind_proc (ld -> link , _ldap_rebind_proc , (void * ) link );
3764+ zend_fcc_dup (& ld -> rebind_proc_fcc , & fcc );
37623765 } else {
3763- zval_ptr_dtor (& ld -> rebindproc );
3764- }
3766+ /* unregister rebind procedure */
3767+ ldap_set_rebind_proc (ld -> link , NULL , NULL );
3768+ }
37653769
3766- ZVAL_COPY (& ld -> rebindproc , & fci .function_name );
37673770 RETURN_TRUE ;
37683771}
37693772/* }}} */
0 commit comments