From 4395f617c71013754033526baaea756a557d146f Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sat, 20 Jun 2026 20:58:24 -0400 Subject: [PATCH] ext/ftp: fix off-by-one terminator write in ftp_readline() The bug80901 fix (09696eee9d43) terminates an over-long response with *data = 0, but when the line fills the whole FTP_BUFSIZE inbuf without a CR/LF, data points at inbuf[FTP_BUFSIZE] and the terminator is written one byte past the buffer, into the adjacent ftpbuf_t::extra field. Reserve the final byte for the terminator so it always lands inside inbuf. A buffer-filling response loses its last character (bug80901's SYST reply is now 4095 visible chars, with the terminator taking the 4096th slot). --- ext/ftp/ftp.c | 2 +- ext/ftp/tests/bug80901.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index ca5e05ead81b..17a3e10e0d61 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -1359,7 +1359,7 @@ ftp_readline(ftpbuf_t *ftp) } data = eol; - if ((rcvd = my_recv(ftp, ftp->fd, data, size)) < 1) { + if (size < 2 || (rcvd = my_recv(ftp, ftp->fd, data, size - 1)) < 1) { *data = 0; return 0; } diff --git a/ext/ftp/tests/bug80901.phpt b/ext/ftp/tests/bug80901.phpt index e2a58fa0668a..a1c0e479c6ae 100644 --- a/ext/ftp/tests/bug80901.phpt +++ b/ext/ftp/tests/bug80901.phpt @@ -16,4 +16,4 @@ ftp_systype($ftp); --EXPECTF-- bool(true) -Warning: ftp_systype(): **************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** in %s on line %d +Warning: ftp_systype(): *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** in %s on line %d