Skip to content

Commit e193897

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: ext/ftp: apply the connect timeout ceiling to the remaining entry points
2 parents 009a0c2 + c1773a1 commit e193897

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
@@ -36,6 +36,8 @@
3636
#include "ftp.h"
3737
#include "ftp_arginfo.h"
3838

39+
#define PHP_FTP_TIMEOUT_SEC_MAX ((uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0))
40+
3941
static zend_class_entry *php_ftp_ce = NULL;
4042
static zend_object_handlers ftp_object_handlers;
4143

@@ -147,15 +149,13 @@ PHP_FUNCTION(ftp_connect)
147149
RETURN_THROWS();
148150
}
149151

150-
const uint64_t timeoutmax = (uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0);
151-
152152
if (timeout_sec <= 0) {
153153
zend_argument_value_error(3, "must be greater than 0");
154154
RETURN_THROWS();
155155
}
156156

157-
if (timeout_sec >= timeoutmax) {
158-
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, timeoutmax);
157+
if (timeout_sec >= PHP_FTP_TIMEOUT_SEC_MAX) {
158+
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, PHP_FTP_TIMEOUT_SEC_MAX);
159159
RETURN_THROWS();
160160
}
161161

@@ -196,6 +196,11 @@ PHP_FUNCTION(ftp_ssl_connect)
196196
RETURN_THROWS();
197197
}
198198

199+
if (timeout_sec >= PHP_FTP_TIMEOUT_SEC_MAX) {
200+
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, PHP_FTP_TIMEOUT_SEC_MAX);
201+
RETURN_THROWS();
202+
}
203+
199204
/* connect */
200205
if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
201206
RETURN_FALSE;
@@ -1291,6 +1296,10 @@ PHP_FUNCTION(ftp_set_option)
12911296
zend_argument_value_error(3, "must be greater than 0 for the FTP_TIMEOUT_SEC option");
12921297
RETURN_THROWS();
12931298
}
1299+
if ((uint64_t) Z_LVAL_P(z_value) >= PHP_FTP_TIMEOUT_SEC_MAX) {
1300+
zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT " for the FTP_TIMEOUT_SEC option", PHP_FTP_TIMEOUT_SEC_MAX);
1301+
RETURN_THROWS();
1302+
}
12941303
ftp->timeout_sec = Z_LVAL_P(z_value);
12951304
RETURN_TRUE;
12961305
break;
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)