Commit 34a9a439043 for php.net
commit 34a9a4390435c6bb27094419cd68bbcda605a7cd
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Sat Jun 20 20:58:24 2026 -0400
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).
Closes GH-22377
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
index ca5e05ead81..17a3e10e0d6 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 e2a58fa0668..a1c0e479c6a 100644
--- a/ext/ftp/tests/bug80901.phpt
+++ b/ext/ftp/tests/bug80901.phpt
@@ -16,4 +16,4 @@
--EXPECTF--
bool(true)
-Warning: ftp_systype(): **************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** in %s on line %d
+Warning: ftp_systype(): *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** in %s on line %d