Skip to content

Commit cc67220

Browse files
committed
Fixed GH-15547: curl_multi_wait expects a signed int for timeout.
confusion might come from the previous argument type. PHP expects ms so we check it fits integer boundaries before the cast. raising a warning at least for stable branches. close GH-15548
1 parent 5947db6 commit cc67220

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ PHP NEWS
1212
. Fixed bug GH-15587 (CRC32 API build error on arm 32-bit).
1313
(Bernd Kuhls, Thomas Petazzoni)
1414

15+
- Curl:
16+
. FIxed bug GH-15547 (curl_multi_select overflow on timeout argument).
17+
(David Carlier)
18+
1519
- DOM:
1620
. Fixed bug GH-15551 (Segmentation fault (access null pointer) in
1721
ext/dom/xml_common.h). (nielsdos)

ext/curl/multi.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,15 @@ PHP_FUNCTION(curl_multi_select)
187187

188188
mh = Z_CURL_MULTI_P(z_mh);
189189

190-
error = curl_multi_wait(mh->multi, NULL, 0, (unsigned long) (timeout * 1000.0), &numfds);
190+
if (!(timeout >= 0.0 && timeout <= ((double)INT_MAX / 1000.0))) {
191+
php_error_docref(NULL, E_WARNING, "timeout must be between 0 and %d", (int)ceilf((double)INT_MAX / 1000));
192+
#ifdef CURLM_BAD_FUNCTION_ARGUMENT
193+
SAVE_CURLM_ERROR(mh, CURLM_BAD_FUNCTION_ARGUMENT);
194+
#endif
195+
RETURN_LONG(-1);
196+
}
197+
198+
error = curl_multi_wait(mh->multi, NULL, 0, (int) (timeout * 1000.0), &numfds);
191199
if (CURLM_OK != error) {
192200
SAVE_CURLM_ERROR(mh, error);
193201
RETURN_LONG(-1);

ext/curl/tests/gh15547.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GH-15547 - curl_multi_select overflow on timeout argument
3+
--EXTENSIONS--
4+
curl
5+
--FILE--
6+
<?php
7+
8+
$mh = curl_multi_init();
9+
var_dump(curl_multi_select($mh, -2500000));
10+
var_dump(curl_multi_strerror(curl_multi_errno($mh)));
11+
curl_multi_close($mh);
12+
$mh = curl_multi_init();
13+
var_dump(curl_multi_select($mh, 2500000));
14+
var_dump(curl_multi_strerror(curl_multi_errno($mh)));
15+
curl_multi_close($mh);
16+
$mh = curl_multi_init();
17+
var_dump(curl_multi_select($mh, 1000000));
18+
var_dump(curl_multi_strerror(curl_multi_errno($mh)));
19+
?>
20+
--EXPECTF--
21+
Warning: curl_multi_select(): timeout must be between 0 and %d in %s on line %d
22+
int(-1)
23+
%s
24+
25+
Warning: curl_multi_select(): timeout must be between 0 and %d in %s on line %d
26+
int(-1)
27+
%s
28+
int(0)
29+
string(8) "No error"

0 commit comments

Comments
 (0)