-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Zend/zend_operators: fix casting underflowed unsigned to signed #8220
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
Conversation
This is incorrect. It's implementation-defined behavior, and all compiler implementations supported by PHP agree on the behavior. In fact, it is your new implementation that has undefined behavior in case the subtraction overflows. That being said, the current code is fishy in that size_t may be larger than int, which means that we might truncate the subtraction to a zero value, reporting equality of strings that are not equal in degenerate cases. As this code is only interested in returning a three-way comparison result, the absolute value of which should not matter, I would recommend adding a helper macro that compares two values and returns 0, 1 or -1. (Along the lines of ZEND_NORMALIZE_BOOL, but that one works on a subtraction result.) |
b9fc40b
to
dd36abe
Compare
I rewrote the commit adding the macro |
That changes requires to adjust some test expectations. |
Will do. |
dd36abe
to
32a877d
Compare
Casting a huge unsigned value to signed is implementation-defined behavior in C. By introducing the ZEND_THREEWAY_COMPARE() macro, we can sidestep this integer overflow/underflow/casting problem.
32a877d
to
3858649
Compare
Another admendment: I had the parantheses around macro parameters wrong. (I hate macros, because they force me to write obscure code like that.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! I'm fine with this, but it might make sense to add some info about the change to UPGRADING(.INTERNALS).
@MaxKellermann This is waiting on you to add info to |
Casting a huge unsigned value to signed is undefined behavior in C.
We need to cast to signed before subtracting.