From c0214e49d2636794be3bb88a2e5e79b85f8e15b1 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 26 Oct 2025 18:28:40 +0000 Subject: [PATCH 1/2] Zend: remove zend_make_callable() function (#20269) The name of this function is confusing, it doesn't make a zval callable just normalizes strings to an array pair if the string references a static method. In general, to store a userland function it is encouraged to store the resolved FCC rather than the zval. Moreover, a sourcegraph search shows no usage of this API in external open source code. --- UPGRADING.INTERNALS | 4 ++++ Zend/zend_API.c | 18 ------------------ Zend/zend_API.h | 1 - 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 15f6620496d45..f14a4d1b0c9f8 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -35,6 +35,10 @@ PHP 8.6 INTERNALS UPGRADE NOTES . The zval_dtor() alias of zval_ptr_dtor_nogc() has been removed. Call zval_ptr_dtor_nogc() directly instead. . The internal zend_copy_parameters_array() function is no longer exposed. + . The zend_make_callable() function has been removed, if a callable zval + needs to be obtained use the zend_get_callable_zval_from_fcc() function + instead. If this was used to store a callable, then an FCC should be + stored instead. ======================== 2. Build system changes diff --git a/Zend/zend_API.c b/Zend/zend_API.c index e05cc7e506f68..d9c951c928896 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -4232,24 +4232,6 @@ ZEND_API bool zend_is_callable(zval *callable, uint32_t check_flags, zend_string } /* }}} */ -ZEND_API bool zend_make_callable(zval *callable, zend_string **callable_name) /* {{{ */ -{ - zend_fcall_info_cache fcc; - - if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, callable_name, &fcc, NULL)) { - if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) { - zval_ptr_dtor_str(callable); - array_init(callable); - add_next_index_str(callable, zend_string_copy(fcc.calling_scope->name)); - add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name)); - } - zend_release_fcall_info_cache(&fcc); - return 1; - } - return 0; -} -/* }}} */ - ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error) /* {{{ */ { if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, fcc, error)) { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 24e686b721efd..440a1874adff1 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -417,7 +417,6 @@ ZEND_API bool zend_is_callable_at_frame( uint32_t check_flags, zend_fcall_info_cache *fcc, char **error); ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error); ZEND_API bool zend_is_callable(zval *callable, uint32_t check_flags, zend_string **callable_name); -ZEND_API bool zend_make_callable(zval *callable, zend_string **callable_name); ZEND_API const char *zend_get_module_version(const char *module_name); ZEND_API zend_result zend_get_module_started(const char *module_name); From 8761c4e5075cdc0dd9986c16f939941304d451ac Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 25 Oct 2025 22:06:42 +0200 Subject: [PATCH 2/2] Fix GH-20240: FTP with SSL: ftp_fput(): Connection timed out on successful writes Looking at the strace, the timeout is only 1s which may be too low anyway for checking for a response, but some servers also don't end up replying finally anyway and close the connection already. `data_available` was originally used for non-blocking downloads/uploads and then reused for the shutdown sequence, but its error handling was never adjusted to be silent. Closes GH-20294. --- NEWS | 4 ++++ ext/ftp/ftp.c | 11 ++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 01b077a7b8378..79b4fe2bc03b7 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,10 @@ PHP NEWS . Fixed bug GH-19974 (fpm_status_export_to_zval segfault for parallel execution). (Jakub Zelenka, txuna) +- FTP: + . Fixed bug GH-20240 (FTP with SSL: ftp_fput(): Connection timed out on + successful writes). (nielsdos) + - GD: . Fixed bug GH-20070 (Return type violation in imagefilter when an invalid filter is provided). (Girgias) diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 3f9a78a81f0f4..7ccb13ffa77f4 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -1605,7 +1605,7 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) /* {{{ data_available */ int -data_available(ftpbuf_t *ftp, php_socket_t s) +data_available(ftpbuf_t *ftp, php_socket_t s, bool silent) { int n; @@ -1613,6 +1613,9 @@ data_available(ftpbuf_t *ftp, php_socket_t s) if (n < 1) { char buf[256]; if (n == 0) { + if (silent) { + return 0; + } #ifdef PHP_WIN32 _set_errno(ETIMEDOUT); #else @@ -1938,7 +1941,9 @@ static void ftp_ssl_shutdown(ftpbuf_t *ftp, php_socket_t fd, SSL *ssl_handle) { done = 0; } - while (!done && data_available(ftp, fd)) { + /* Don't report timeouts on the control channel if we're negotiating a shutdown already. + * Some servers don't put a final response. */ + while (!done && data_available(ftp, fd, true)) { ERR_clear_error(); nread = SSL_read(ssl_handle, buf, sizeof(buf)); if (nread <= 0) { @@ -2198,7 +2203,7 @@ ftp_nb_continue_read(ftpbuf_t *ftp) data = ftp->data; /* check if there is already more data */ - if (!data_available(ftp, data->fd)) { + if (!data_available(ftp, data->fd, false)) { return PHP_FTP_MOREDATA; }