Skip to content

Conversation

devnexen
Copy link
Member

No description provided.

@devnexen devnexen requested a review from cmb69 December 18, 2024 05:11
@devnexen devnexen marked this pull request as ready for review December 18, 2024 05:11
Copy link
Member

@cmb69 cmb69 left a comment

Choose a reason for hiding this comment

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

Thank you!

tv.tv_usec = timeout.tv_usec;
#else
tv.tv_sec = timeout ? (long)(timeout / 1000) : 0;
tv.tv_usec = timeout ? (long)((timeout * 1000) % 1000000) : 0;
Copy link
Member

Choose a reason for hiding this comment

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

This looks not quite correct. If we get a large timeout (DWORD can be up to 2^32) and multiply by 1000, we can overflow (since unsigned no UB, but still not desireable, I think). Is there a reason not to do:

Suggested change
tv.tv_usec = timeout ? (long)((timeout * 1000) % 1000000) : 0;
tv.tv_usec = timeout ? (long)((timeout % 1000) * 1000) : 0;

Copy link
Member Author

Choose a reason for hiding this comment

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

I did not change the windows part as I can't test (I should set up a php build in my windows laptop :)) but I ll have a look at your suggestion later.

Copy link
Member

Choose a reason for hiding this comment

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

I didn't test either; and no need for Windows for this one. :)

#include <stdio.h>
#include <limits.h>

int main()
{
    unsigned int timeout = UINT_MAX;
    printf("%u\n", timeout);
    printf("%d\n", (long)((timeout * 1000) % 1000000));
    printf("%d\n", (long)((timeout % 1000) * 1000));
    return 0;
}

outputs:

4294967295
966296
295000

Copy link
Member Author

Choose a reason for hiding this comment

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

fair fair, you got a point :)


timeout = valsec * 1000;

if (valusec < 0 || timeout > ULONG_MAX - (valusec / 1000)) {
Copy link
Member

Choose a reason for hiding this comment

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

It seems to me that ULONG_MAX - (valusec / 1000) can yield a negative result, in which case we would throw. If we're fine with this (I think we are), the code is good as is.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe add a comment that valuesec / 1000 > ULONG_MAX is indeed considered a programmer error (i.e. throwing is deliberate here). Note that this code is only for Windows, where ULONG_MAX is 2^32, but ZEND_LONG_MAX is 2^63 for 64bit architectures.

@devnexen devnexen requested a review from cmb69 December 20, 2024 21:21
Copy link
Member

@cmb69 cmb69 left a comment

Choose a reason for hiding this comment

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

Looks good to me now.


timeout = valsec * 1000;

if (valusec < 0 || timeout > ULONG_MAX - (valusec / 1000)) {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add a comment that valuesec / 1000 > ULONG_MAX is indeed considered a programmer error (i.e. throwing is deliberate here). Note that this code is only for Windows, where ULONG_MAX is 2^32, but ZEND_LONG_MAX is 2^63 for 64bit architectures.

@devnexen devnexen force-pushed the socket_set_option_timeout_refact branch from 1a45f36 to c0cf208 Compare December 20, 2024 21:58
@devnexen devnexen merged commit c4bb6e6 into php:master Dec 20, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants