Skip to content

Commit 46a35ff

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: ext/ftp: apply the connect timeout ceiling to the remaining entry points
2 parents 9046987 + e193897 commit 46a35ff

3 files changed

Lines changed: 60 additions & 4 deletions

File tree

ext/ftp/php_ftp.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "ftp.h"
3535
#include "ftp_arginfo.h"
3636

37+
#define PHP_FTP_TIMEOUT_SEC_MAX ((uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0))
38+
3739
static zend_class_entry *php_ftp_ce = NULL;
3840
static zend_object_handlers ftp_object_handlers;
3941

@@ -143,15 +145,13 @@ PHP_FUNCTION(ftp_connect)
143145
RETURN_THROWS();
144146
}
145147

146-
const uint64_t timeoutmax = (uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0);
147-
148148
if (timeout_sec <= 0) {
149149
zend_argument_value_error(3, "must be greater than 0");
150150
RETURN_THROWS();
151151
}
152152

153-
if (timeout_sec >= timeoutmax) {
154-
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, timeoutmax);
153+
if (timeout_sec >= PHP_FTP_TIMEOUT_SEC_MAX) {
154+
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, PHP_FTP_TIMEOUT_SEC_MAX);
155155
RETURN_THROWS();
156156
}
157157

@@ -192,6 +192,11 @@ PHP_FUNCTION(ftp_ssl_connect)
192192
RETURN_THROWS();
193193
}
194194

195+
if (timeout_sec >= PHP_FTP_TIMEOUT_SEC_MAX) {
196+
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, PHP_FTP_TIMEOUT_SEC_MAX);
197+
RETURN_THROWS();
198+
}
199+
195200
/* connect */
196201
if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
197202
RETURN_FALSE;
@@ -1284,6 +1289,10 @@ PHP_FUNCTION(ftp_set_option)
12841289
zend_argument_value_error(3, "must be greater than 0 for the FTP_TIMEOUT_SEC option");
12851290
RETURN_THROWS();
12861291
}
1292+
if ((uint64_t) Z_LVAL_P(z_value) >= PHP_FTP_TIMEOUT_SEC_MAX) {
1293+
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT " for the FTP_TIMEOUT_SEC option", PHP_FTP_TIMEOUT_SEC_MAX);
1294+
RETURN_THROWS();
1295+
}
12871296
ftp->timeout_sec = Z_LVAL_P(z_value);
12881297
RETURN_TRUE;
12891298
case PHP_FTP_OPT_AUTOSEEK:
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GH-20601 (ftp_set_option FTP_TIMEOUT_SEC timeout overflow)
3+
--EXTENSIONS--
4+
ftp
5+
pcntl
6+
--SKIPIF--
7+
<?php
8+
if (PHP_INT_SIZE != 8) die("skip: 64-bit only");
9+
if (PHP_OS_FAMILY === 'Windows') die("skip not for windows");
10+
?>
11+
--FILE--
12+
<?php
13+
require 'server.inc';
14+
15+
$ftp = ftp_connect('127.0.0.1', $port);
16+
$ftp or die("Couldn't connect to the server");
17+
ftp_login($ftp, 'user', 'pass');
18+
19+
try {
20+
ftp_set_option($ftp, FTP_TIMEOUT_SEC, PHP_INT_MAX);
21+
} catch (\ValueError $e) {
22+
echo $e->getMessage();
23+
}
24+
?>
25+
--EXPECTF--
26+
ftp_set_option(): Argument #3 ($value) must be less than %d for the FTP_TIMEOUT_SEC option

ext/ftp/tests/gh20601_ssl.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
GH-20601 (ftp_ssl_connect timeout overflow)
3+
--EXTENSIONS--
4+
ftp
5+
openssl
6+
--SKIPIF--
7+
<?php
8+
if (!function_exists("ftp_ssl_connect")) die("skip ftp_ssl is disabled");
9+
if (PHP_INT_SIZE != 8) die("skip: 64-bit only");
10+
if (PHP_OS_FAMILY === 'Windows') die("skip not for windows");
11+
?>
12+
--FILE--
13+
<?php
14+
try {
15+
ftp_ssl_connect('127.0.0.1', 1024, PHP_INT_MAX);
16+
} catch (\ValueError $e) {
17+
echo $e->getMessage();
18+
}
19+
?>
20+
--EXPECTF--
21+
ftp_ssl_connect(): Argument #3 ($timeout) must be less than %d

0 commit comments

Comments
 (0)