@@ -183,8 +183,8 @@ static const unsigned char php_openssl_tls13_aes256gcmsha384_id[] = { 0x13, 0x02
183183/* Holds PSK callbacks */
184184typedef struct _php_openssl_psk_callbacks_t {
185185 int refcount ;
186- zval client_cb ;
187- zval server_cb ;
186+ zend_fcall_info_cache client_cb ;
187+ zend_fcall_info_cache server_cb ;
188188} php_openssl_psk_callbacks_t ;
189189
190190/* Holds session callback */
@@ -1621,7 +1621,7 @@ static SSL_SESSION *php_openssl_psk_build_session(SSL *ssl,
16211621/**
16221622 * Invoke a user PHP callback (psk_client_cb or psk_server_cb).
16231623 */
1624- static zend_result php_openssl_call_psk_cb (php_stream * stream , zval * cb ,
1624+ static zend_result php_openssl_call_psk_cb (php_stream * stream , zend_fcall_info_cache * fcc ,
16251625 const unsigned char * identity , size_t identity_len ,
16261626 zval * result )
16271627{
@@ -1639,13 +1639,14 @@ static zend_result php_openssl_call_psk_cb(php_stream *stream, zval *cb,
16391639 }
16401640
16411641 ZVAL_UNDEF (& retval );
1642- call_user_function (NULL , NULL , cb , & retval , argc , args );
1642+
1643+ zend_call_known_fcc (fcc , & retval , argc , args , NULL );
16431644
16441645 if (identity != NULL ) {
16451646 zval_ptr_dtor (& args [1 ]);
16461647 }
16471648
1648- if (EG ( exception )) {
1649+ if (Z_ISUNDEF ( retval )) {
16491650 ZVAL_UNDEF (result );
16501651 return FAILURE ;
16511652 }
@@ -1686,7 +1687,7 @@ static unsigned int php_openssl_psk_client_cb(SSL *ssl, const char *hint,
16861687 php_openssl_netstream_data_t * sslsock =
16871688 (php_openssl_netstream_data_t * )stream -> abstract ;
16881689 if (sslsock == NULL || sslsock -> psk_callbacks == NULL
1689- || Z_ISUNDEF (sslsock -> psk_callbacks -> client_cb )) {
1690+ || ! ZEND_FCC_INITIALIZED (sslsock -> psk_callbacks -> client_cb )) {
16901691 return 0 ;
16911692 }
16921693
@@ -1737,7 +1738,7 @@ static unsigned int php_openssl_psk_server_cb(SSL *ssl, const char *identity,
17371738 php_openssl_netstream_data_t * sslsock =
17381739 (php_openssl_netstream_data_t * )stream -> abstract ;
17391740 if (sslsock == NULL || sslsock -> psk_callbacks == NULL
1740- || Z_ISUNDEF (sslsock -> psk_callbacks -> server_cb )) {
1741+ || ! ZEND_FCC_INITIALIZED (sslsock -> psk_callbacks -> server_cb )) {
17411742 return 0 ;
17421743 }
17431744
@@ -1793,7 +1794,7 @@ static int php_openssl_psk_use_session_cb(SSL *ssl, const EVP_MD *md,
17931794 php_openssl_netstream_data_t * sslsock =
17941795 (php_openssl_netstream_data_t * )stream -> abstract ;
17951796 if (sslsock == NULL || sslsock -> psk_callbacks == NULL
1796- || Z_ISUNDEF (sslsock -> psk_callbacks -> client_cb )) {
1797+ || ! ZEND_FCC_INITIALIZED (sslsock -> psk_callbacks -> client_cb )) {
17971798 return 1 ;
17981799 }
17991800
@@ -1860,7 +1861,7 @@ static int php_openssl_psk_find_session_cb(SSL *ssl, const unsigned char *identi
18601861
18611862 php_openssl_netstream_data_t * sslsock = (php_openssl_netstream_data_t * )stream -> abstract ;
18621863 if (sslsock == NULL || sslsock -> psk_callbacks == NULL
1863- || Z_ISUNDEF (sslsock -> psk_callbacks -> server_cb )) {
1864+ || ! ZEND_FCC_INITIALIZED (sslsock -> psk_callbacks -> server_cb )) {
18641865 return 1 ;
18651866 }
18661867
@@ -1896,17 +1897,19 @@ static int php_openssl_psk_find_session_cb(SSL *ssl, const unsigned char *identi
18961897/* PSK setup */
18971898
18981899static zend_result php_openssl_validate_and_allocate_psk_callback (
1899- php_openssl_netstream_data_t * sslsock , zval * callable ,
1900- const char * callback_name , bool is_persistent )
1900+ php_openssl_netstream_data_t * sslsock , const zval * callable ,
1901+ bool is_client , bool is_persistent )
19011902{
1903+ const char * callback_name = is_client ? "psk_client_cb" : "psk_server_cb" ;
19021904 if (is_persistent ) {
19031905 php_error_docref (NULL , E_WARNING ,
19041906 "%s is not supported for persistent streams" , callback_name );
19051907 return FAILURE ;
19061908 }
19071909
19081910 char * is_callable_error = NULL ;
1909- if (!zend_is_callable_ex (callable , NULL , 0 , NULL , NULL , & is_callable_error )) {
1911+ zend_fcall_info_cache fcc = {0 };
1912+ if (!zend_is_callable_ex (callable , NULL , 0 , NULL , & fcc , & is_callable_error )) {
19101913 if (is_callable_error ) {
19111914 zend_type_error ("%s must be a valid callback, %s" ,
19121915 callback_name , is_callable_error );
@@ -1918,12 +1921,16 @@ static zend_result php_openssl_validate_and_allocate_psk_callback(
19181921 }
19191922
19201923 if (!sslsock -> psk_callbacks ) {
1921- sslsock -> psk_callbacks = (php_openssl_psk_callbacks_t * )pemalloc (
1922- sizeof (php_openssl_psk_callbacks_t ), is_persistent );
1923- ZVAL_UNDEF (& sslsock -> psk_callbacks -> client_cb );
1924- ZVAL_UNDEF (& sslsock -> psk_callbacks -> server_cb );
1924+ sslsock -> psk_callbacks = (php_openssl_psk_callbacks_t * )pecalloc (
1925+ 1 , sizeof (php_openssl_psk_callbacks_t ), is_persistent );
19251926 sslsock -> psk_callbacks -> refcount = 1 ;
19261927 }
1928+ zend_fcc_addref (& fcc );
1929+ if (is_client ) {
1930+ sslsock -> psk_callbacks -> client_cb = fcc ;
1931+ } else {
1932+ sslsock -> psk_callbacks -> server_cb = fcc ;
1933+ }
19271934
19281935 return SUCCESS ;
19291936}
@@ -1938,12 +1945,10 @@ static zend_result php_openssl_setup_client_psk(php_stream *stream,
19381945 }
19391946
19401947 if (FAILURE == php_openssl_validate_and_allocate_psk_callback (
1941- sslsock , val , "psk_client_cb" , php_stream_is_persistent (stream ))) {
1948+ sslsock , val , true , php_stream_is_persistent (stream ))) {
19421949 return FAILURE ;
19431950 }
19441951
1945- ZVAL_COPY (& sslsock -> psk_callbacks -> client_cb , val );
1946-
19471952#ifndef OPENSSL_NO_PSK
19481953 SSL_CTX_set_psk_client_callback (sslsock -> ctx , php_openssl_psk_client_cb );
19491954#endif
@@ -1962,12 +1967,10 @@ static zend_result php_openssl_setup_server_psk(php_stream *stream,
19621967 }
19631968
19641969 if (FAILURE == php_openssl_validate_and_allocate_psk_callback (
1965- sslsock , val , "psk_server_cb" , php_stream_is_persistent (stream ))) {
1970+ sslsock , val , false , php_stream_is_persistent (stream ))) {
19661971 return FAILURE ;
19671972 }
19681973
1969- ZVAL_COPY (& sslsock -> psk_callbacks -> server_cb , val );
1970-
19711974#ifndef OPENSSL_NO_PSK
19721975 SSL_CTX_set_psk_server_callback (sslsock -> ctx , php_openssl_psk_server_cb );
19731976#endif
@@ -3092,8 +3095,13 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle) /* {{{
30923095 }
30933096
30943097 if (sslsock -> psk_callbacks && -- sslsock -> psk_callbacks -> refcount == 0 ) {
3095- zval_ptr_dtor (& sslsock -> psk_callbacks -> client_cb );
3096- zval_ptr_dtor (& sslsock -> psk_callbacks -> server_cb );
3098+ if (ZEND_FCC_INITIALIZED (sslsock -> psk_callbacks -> client_cb )) {
3099+ zend_fcc_dtor (& sslsock -> psk_callbacks -> client_cb );
3100+ }
3101+
3102+ if (ZEND_FCC_INITIALIZED (sslsock -> psk_callbacks -> server_cb )) {
3103+ zend_fcc_dtor (& sslsock -> psk_callbacks -> server_cb );
3104+ }
30973105 pefree (sslsock -> psk_callbacks , php_stream_is_persistent (stream ));
30983106 }
30993107
0 commit comments