From 879987f5dd7c2026dba829d29ba074c0261abc80 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 6 Feb 2023 22:53:29 +0100 Subject: [PATCH] Fix GH-10521: ftp_get/ftp_nb_get resumepos offset is maximum 10GB The char arrays were too small for a long on 64-bit systems, which resulted in cutting off the string at the end with a NUL byte. Use a size of MAX_LENGTH_OF_LONG to fix this issue instead of a fixed size of 11 chars. --- ext/ftp/ftp.c | 8 ++++---- ext/ftp/tests/gh10521.phpt | 39 ++++++++++++++++++++++++++++++++++++++ ext/ftp/tests/server.inc | 4 ++++ 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 ext/ftp/tests/gh10521.phpt diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index ef91fdec97988..09367097cdb5d 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -867,7 +867,7 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_t pat { databuf_t *data = NULL; size_t rcvd; - char arg[11]; + char arg[MAX_LENGTH_OF_LONG]; if (ftp == NULL) { return 0; @@ -964,7 +964,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream *inst zend_long size; char *ptr; int ch; - char arg[11]; + char arg[MAX_LENGTH_OF_LONG]; if (ftp == NULL) { return 0; @@ -2057,7 +2057,7 @@ int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_t path_len, ftptype_t type, zend_long resumepos) { databuf_t *data = NULL; - char arg[11]; + char arg[MAX_LENGTH_OF_LONG]; if (ftp == NULL) { return PHP_FTP_FAILED; @@ -2176,7 +2176,7 @@ int ftp_nb_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream *instream, ftptype_t type, zend_long startpos) { databuf_t *data = NULL; - char arg[11]; + char arg[MAX_LENGTH_OF_LONG]; if (ftp == NULL) { return 0; diff --git a/ext/ftp/tests/gh10521.phpt b/ext/ftp/tests/gh10521.phpt new file mode 100644 index 0000000000000..1dc40d4004271 --- /dev/null +++ b/ext/ftp/tests/gh10521.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-10521 (ftp_get/ftp_nb_get resumepos offset is maximum 10GB) +--EXTENSIONS-- +ftp +pcntl +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +bool(true) + +%s: ftp_fget(): Can't open data connection (12345678910). in %s on line %d + +%s: ftp_fget(): Can't open data connection (9223372036854775807). in %s on line %d diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index afbfd88f73579..bdae0278793f7 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -386,6 +386,10 @@ if ($pid) { case "/bug73457": fputs($s, "150 File status okay; about to open data connection.\r\n"); break; + case "gh10521": + // Just a side channel for getting the received file size. + fputs($s, "425 Can't open data connection (".$GLOBALS['rest_pos'].").\r\n"); + break; default: fputs($s, "550 {$matches[1]}: No such file or directory \r\n");