diff --git a/UPGRADING b/UPGRADING index 596db8fb4267..41d9fd6b97a5 100644 --- a/UPGRADING +++ b/UPGRADING @@ -48,6 +48,12 @@ PHP 8.6 UPGRADE NOTES the integer index is greater than INT_MAX instead of overflowing to a smaller index. +- FTP: + . ftp_nb_fget() and ftp_nb_fput() now throw an Error when the connection is + already transferring, instead of emitting a warning and returning false + against their declared int return type. ftp_close() already throws on the + same condition. + - GD: . imagesetstyle(), imagefilter() and imagecrop() filter the types / values of their array arguments and raise a TypeError / ValueError accordingly. diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index 56938459bb33..36f60f93a049 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -656,8 +656,8 @@ PHP_FUNCTION(ftp_nb_fget) /* configuration */ if (ftp->in_use) { - php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); - RETURN_FALSE; + zend_throw_error(NULL, "Cannot start a transfer while another transfer is in progress"); + RETURN_THROWS(); } ftp->direction = 0; /* recv */ @@ -961,8 +961,8 @@ PHP_FUNCTION(ftp_nb_fput) /* configuration */ if (ftp->in_use) { - php_error_docref(NULL, E_WARNING, "FTP\\Connection is already in use"); - RETURN_FALSE; + zend_throw_error(NULL, "Cannot start a transfer while another transfer is in progress"); + RETURN_THROWS(); } ftp->direction = true; /* send */ diff --git a/ext/ftp/tests/ftp_nb_transfer_during_transfer.phpt b/ext/ftp/tests/ftp_nb_transfer_during_transfer.phpt new file mode 100644 index 000000000000..c15b713d6e4a --- /dev/null +++ b/ext/ftp/tests/ftp_nb_transfer_during_transfer.phpt @@ -0,0 +1,56 @@ +--TEST-- +ftp_nb_fget() and ftp_nb_fput() throw when a transfer is already in progress +--EXTENSIONS-- +ftp +pcntl +--FILE-- +getMessage(), "\n"; + } + return strlen($data); + } + public function stream_close() {} + public function stream_eof() { + return true; + } +} + +stream_wrapper_register('reentrantnb', TransferDuringNbWrite::class); + +$ftp = ftp_connect('127.0.0.1', $port); +var_dump(ftp_login($ftp, 'user', 'pass')); +TransferDuringNbWrite::$ftp = $ftp; + +$sink = fopen('php://memory', 'w+'); + +TransferDuringNbWrite::$call = static function ($ftp) use ($sink) { + ftp_nb_fget($ftp, $sink, 'a story.txt', FTP_BINARY); +}; +@ftp_nb_get($ftp, 'reentrantnb://sink', 'a story.txt', FTP_BINARY); + +TransferDuringNbWrite::$call = static function ($ftp) use ($sink) { + ftp_nb_fput($ftp, 'a story.txt', $sink, FTP_BINARY); +}; +@ftp_nb_get($ftp, 'reentrantnb://sink', 'a story.txt', FTP_BINARY); + +ftp_close($ftp); +echo "closed\n"; +?> +--EXPECT-- +bool(true) +Error: Cannot start a transfer while another transfer is in progress +Error: Cannot start a transfer while another transfer is in progress +closed