diff --git a/NEWS b/NEWS index 48afd654b2ef..4ab0b10164d1 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,8 @@ PHP NEWS - FTP: . Fix double free in ext/ftp data_accept() on accept failure. (alepacheco) + . Fixed crash in ftp_nb_continue() after ftp_nb_get() failed to abort a + pending transfer. (Jakub Kozub) - MBString: . Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela) diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index fd0f295500b8..e5ed836a186d 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -2239,6 +2239,7 @@ ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_t return (ftp_nb_continue_read(ftp)); bail: + ftp->nb = 0; data_close(ftp); return PHP_FTP_FAILED; } diff --git a/ext/ftp/tests/ftp_nb_get_rejected_abort.phpt b/ext/ftp/tests/ftp_nb_get_rejected_abort.phpt new file mode 100644 index 000000000000..8faa7f486fa0 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_get_rejected_abort.phpt @@ -0,0 +1,39 @@ +--TEST-- +ftp_nb_get() must clear ftp->nb when aborting a pending transfer fails +--EXTENSIONS-- +ftp +pcntl +--FILE-- +nb was still + * set here, so this reached php_stream_close() on an already cleared + * ftp->stream and crashed. */ +var_dump(@ftp_nb_continue($ftp) === FTP_FAILED); + +ftp_close($ftp); +echo "closed\n"; +?> +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +closed diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 2d9697e4d35d..cb1dad82cf18 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -404,6 +404,15 @@ if ($pid) { fputs($s, "226 Closing data Connection.\r\n"); break; + case "abort_rejected": + // Opens the data connection, then answers the transfer with + // something other than 226/250, so that a client aborting it + // from ftp_nb_get() takes the error path. + fputs($s, "150 File status okay; about to open data connection.\r\n"); + fputs($fs, "partial"); + fputs($s, "451 Requested action aborted: local error in processing.\r\n"); + break; + default: fputs($s, "550 {$matches[1]}: No such file or directory \r\n"); break;