Skip to content

Fixed GH-15547: curl_multi_wait expects a signed int for timeout. #15548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ext/curl/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,12 @@ PHP_FUNCTION(curl_multi_select)

mh = Z_CURL_MULTI_P(z_mh);

error = curl_multi_wait(mh->multi, NULL, 0, (unsigned long) (timeout * 1000.0), &numfds);
if (!(timeout >= ((double)INT_MIN / 1000.0) && timeout <= ((double)INT_MAX / 1000.0))) {
php_error_docref(NULL, E_WARNING, "timeout must be between %d and %d", (INT_MIN / 1000), (INT_MAX / 1000));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be slightly off due to rounding. Should probably be something like (int) fceil((double) INT_MAX/1000)`, but maybe that's overkill.

And I think zend_argument_value_error() could be used here, although that wouldn't show the docref. Maybe something that should generally be addressed (unless there is already something for this).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! Of course, throwing a ValueError would be something completely different, but still this may be an option for master, and generally, zend_argument_value_error() doesn't look right, since it hasn't the docref. @Girgias and @kocsismate may have something to say about that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to add support for docrefs for all argument exceptions and ZPP failures.
But the docref param is only useful for INI settings, and I don't think we throw exceptions for INI settings (yet?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to add support for docrefs for all argument exceptions and ZPP failures.

There is a problem, though, since ZPP is part of the Zend engine, and php_error_docref() is part of PHP, and the engine shouldn't rely on PHP. I guess that is the reason why zend_error() has been used for this.

But the docref param is only useful for INI settings, […]

Yeah, but I didn't mean the docref param, but was referring to the general mechanism, which is nice, e.g. https://3v4l.org/deO0B.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right... I agree that Zend shouldn't rely on main/ (although I recently learnt that Zend does require ext/standard/ext/hash :|)

Maybe we should introduce a function pointer API similar to zend_autoload ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, already forgot about the Zend -> ext/hash dependency. We should fix this (keeping BC seems to be possible, on the first glance).

And yes, a function pointer could solve the issue nicely.

And we should probably use some tooling to detect such circular dependencies.

RETURN_LONG(-1);
}

error = curl_multi_wait(mh->multi, NULL, 0, (int) (timeout * 1000.0), &numfds);
if (CURLM_OK != error) {
SAVE_CURLM_ERROR(mh, error);
RETURN_LONG(-1);
Expand Down
19 changes: 19 additions & 0 deletions ext/curl/tests/gh15547.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
GH-15547 - overflow on timeout argument
--EXTENSIONS--
curl
--FILE--
<?php

$mh = curl_multi_init();
var_dump(curl_multi_select($mh, -2500000));
var_dump(curl_multi_select($mh, 2500000));
var_dump(curl_multi_select($mh, 1000000));
?>
--EXPECTF--
Warning: curl_multi_select(): timeout must be between %s and %s in %s on line %d
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
Warning: curl_multi_select(): timeout must be between %s and %s in %s on line %d
Warning: curl_multi_select(): timeout must be between %d and %d in %s on line %d

int(-1)

Warning: curl_multi_select(): timeout must be between %s and %s in %s on line %d
int(-1)
int(0)
Loading