-
Notifications
You must be signed in to change notification settings - Fork 8k
ext/sockets: socket_strerror follow-up on GH-16267 fix. #16981
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
ext/sockets/sockets.c
Outdated
if (ZEND_LONG_EXCEEDS_INT(arg1)) { | ||
zend_argument_value_error(1, "must be between %d and %d", INT_MIN, INT_MAX); | ||
if (arg1 <= INT_MIN || arg1 > INT_MAX) { | ||
zend_argument_value_error(1, "must be greater than %d and lower than %d", INT_MIN, INT_MAX); |
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.
zend_argument_value_error(1, "must be greater than %d and lower than %d", INT_MIN, INT_MAX); | |
zend_argument_value_error(1, "must be greater than %d and less than %d", INT_MIN, INT_MAX); |
ext/sockets/tests/gh16267.phpt
Outdated
<?php | ||
try { | ||
socket_strerror(PHP_INT_MIN); | ||
socket_strerror(-2147483648); |
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.
This has basically the same problem (32bit systems) as the bug we're trying to fix; the number 2147483648
overflows there.
Did you try:
ext/sockets/sockets.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index 08b8d8406d..5cc66f2d8f 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -370,7 +370,7 @@ char *sockets_strerror(int error) /* {{{ */
#ifndef PHP_WIN32
if (error < -10000) {
- error = -error - 10000;
+ error = (int)(unsigned int) error - 10000;
#ifdef HAVE_HSTRERROR
buf = hstrerror(error);
PS: no need to try: suggestion is nonsense. Disregard.
ext/sockets/sockets.c
Outdated
if (ZEND_LONG_EXCEEDS_INT(arg1)) { | ||
zend_argument_value_error(1, "must be between %d and %d", INT_MIN, INT_MAX); | ||
if (arg1 <= INT_MIN || arg1 > INT_MAX) { | ||
zend_argument_value_error(1, "must be greater than %d and lower than %d", INT_MIN, INT_MAX); |
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.
The standard wording is:
zend_argument_value_error(1, "must be greater than %d and lower than %d", INT_MIN, INT_MAX); | |
zend_argument_value_error(1, "must be between %d and %d", INT_MIN, INT_MAX); |
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.
Yeah, but in this case INT_MIN
is no longer supported, so should be:
zend_argument_value_error(1, "must be greater than %d and lower than %d", INT_MIN, INT_MAX); | |
zend_argument_value_error(1, "must be between %d and %d", INT_MIN + 1, INT_MAX); |
But I'm still not convinced that we need to constrain the allowed range.
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.
I'm just pointing out the wording :)
ce026fb
to
f119df3
Compare
ext/sockets/tests/gh16267.phpt
Outdated
socket_strerror(): Argument #1 ($error_code) must be between %s and %d | ||
socket_strerror(): Argument #1 ($error_code) must be between %s and %d |
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.
socket_strerror(): Argument #1 ($error_code) must be between %s and %d | |
socket_strerror(): Argument #1 ($error_code) must be between %s and %d | |
socket_strerror(): Argument #1 ($error_code) must be between %d and %d | |
socket_strerror(): Argument #1 ($error_code) must be between %d and %d |
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.
sorry does not work for me, I guess because it s a negative.
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.
Right, use %i
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.
The fix looks okay to me, but why not fix the root cause? My previous suggestion was nonsense, but we could special case INT_MIN
:
ext/sockets/sockets.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index 48221479a7..eab26737e6 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -370,7 +370,11 @@ char *sockets_strerror(int error) /* {{{ */
#ifndef PHP_WIN32
if (error < -10000) {
- error = -error - 10000;
+ if (error = INT_MIN) {
+ error = 2147473648;
+ } else {
+ error = -error - 10000;
+ }
#ifdef HAVE_HSTRERROR
buf = hstrerror(error);
That may not matter in practice, in which case we can go with this fix, but I would add an assertion (basically a precondition) in sockets_strerror()
that error > INT_MIN
.
It s mainly because socket_strerror is the only call using user supplied error code for sockets_strerror. But yes I can put an assert sure. |
378b307
to
dc1127e
Compare
ext/sockets/sockets.c
Outdated
if (ZEND_LONG_EXCEEDS_INT(arg1)) { | ||
zend_argument_value_error(1, "must be between %d and %d", INT_MIN, INT_MAX); | ||
if (arg1 <= INT_MIN || arg1 > INT_MAX) { | ||
zend_argument_value_error(1, "must be between %d and %d", (INT_MIN + 1), INT_MAX); |
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.
If we support INT_MIN
, we can revert this change.
ext/sockets/sockets.c
Outdated
{ | ||
const char *buf; | ||
|
||
ZEND_ASSERT(error >= INT_MIN); |
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.
Superfluous assertion; since error is of type int
it is always >= INT_MIN
.
Other than that the patch looks good to me.
boundaries should be INT_MIN <= val < INT_MAX in fact.
closed with 3bea6a2. |
boundaries should be INT_MIN <= val < INT_MAX in fact.