diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 36a0d1697eca..ca5e05ead81b 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -946,7 +946,7 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_t pat #else while (e > ptr && (s = memchr(ptr, '\r', (e - ptr)))) { php_stream_write(outstream, ptr, (s - ptr)); - if (*(s + 1) == '\n') { + if (s + 1 < e && *(s + 1) == '\n') { s++; php_stream_putc(outstream, '\n'); } diff --git a/ext/ftp/tests/ftp_get_ascii_crlf_boundary.phpt b/ext/ftp/tests/ftp_get_ascii_crlf_boundary.phpt new file mode 100644 index 000000000000..4c3a70b647c6 --- /dev/null +++ b/ext/ftp/tests/ftp_get_ascii_crlf_boundary.phpt @@ -0,0 +1,25 @@ +--TEST-- +ftp_get() ASCII mode: CRLF straddling the FTP_BUFSIZE read boundary +--EXTENSIONS-- +ftp +pcntl +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index c2c8449a0686..4c9d2a754bff 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -391,6 +391,13 @@ if ($pid) { // Just a side channel for getting the received file size. fputs($s, "425 Can't open data connection (".$GLOBALS['rest_pos'].").\r\n"); break; + case "crlf_boundary": + // A CRLF whose CR lands on the final byte of the first + // FTP_BUFSIZE (4096) read, so the LF arrives in the next read. + fputs($s, "150 File status okay; about to open data connection.\r\n"); + fputs($fs, str_repeat("A", 4095) . "\r\n" . str_repeat("B", 10)); + fputs($s, "226 Closing data Connection.\r\n"); + break; default: fputs($s, "550 {$matches[1]}: No such file or directory \r\n");