-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
[2.7] bpo-36337: Use ssize_t and size_t for socket.send()/sendall() #12397
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
|
I don't think that a test is needed: I cannot find a test on master. Your PR is wrong on Windows. Look at the master branch: On Windows, the type of send() length argument is int, not size_t. |
…ckport the solution from 3.x with Py_ssize_t
| @@ -2797,7 +2797,8 @@ static PyObject * | |||
| sock_send(PySocketSockObject *s, PyObject *args) | |||
| { | |||
| char *buf; | |||
| int len, n = -1, flags = 0, timeout; | |||
| int flags = 0, timeout; | |||
| Py_ssize_t len, n = -1; | |||
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.
return PyInt_FromLong((long)n); below is wrong
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
|
I have made the requested changes; please review again |
|
Thanks for making the requested changes! @vstinner: please review the changes made to this pull request. |
| @@ -2813,12 +2814,18 @@ sock_send(PySocketSockObject *s, PyObject *args) | |||
| BEGIN_SELECT_LOOP(s) | |||
| Py_BEGIN_ALLOW_THREADS | |||
| timeout = internal_select_ex(s, 1, interval); | |||
| if (!timeout) | |||
| if (!timeout) { | |||
| #ifdef __VMS | |||
| n = sendsegmented(s->sock_fd, buf, len, flags); | |||
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.
That's wrong: sendsegmented() len type is int, not Py_ssize_t. Don't forget the VMS! :-)
| @@ -0,0 +1,3 @@ | |||
| Use ssize_t and size_t instead of int for the send() function (see | |||
| http://man7.org/linux/man-pages/man2/send.2.html (Linux) and | |||
| https://nixdoc.net/man-pages/FreeBSD/man2/send.2.html (FreeBSD)). | |||
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 propose:
Fix buffer overflow in :meth:~socket.socket.send and :meth:~socket.socket.sendall methods of :func:socket.socket for data larger than 2 GiB.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
|
I have made the requested changes; please review again |
|
Thanks for making the requested changes! @vstinner: please review the changes made to this pull request. |
Modules/socketmodule.c
Outdated
| #ifdef __VMS | ||
| n = sendsegmented(s->sock_fd, buf, len, flags); | ||
| n = sendsegmented(s->sock_fd, buf, (int)len, flags); |
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.
(int)len is unsafe if len is larger than INT_MAX. You should modify sendsegmented() to accept Py_ssize_t rather than int.
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.
👍 good catch and I was thinking about this problem.
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.
LGTM.
The subtle side effect of this change is that send() and sendall() now always return a Python 'long' object, whereas they always returned a Python 'int' object previously. I think that it's acceptable, but it might be risky to push so change late in 2.7 lifetime (EOL scheduled at the beginning of next year).
On the other side, currently, calling sendall() with more than 2 GiB data loose data. But well, who does that with Python 2.7?
I would prefer to have the review of another core dev.
@benjaminp @serhiy-storchaka @pablogsal: Would you mind to review this change? Do you think that it's ok to change send/sendall return type (int => long, supposed to be compatible)?
|
I have made the requested changes; please review again |
|
Thanks for making the requested changes! @vstinner: please review the changes made to this pull request. |
|
|
||
| while (remaining > 0) { | ||
| unsigned int segment; | ||
|
|
||
| segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining); | ||
| segment = ((size_t)remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : (unsigned int) remaining); |
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.
Wait, is this cast safe? In C99 ssize_t can be an unsigned long, unless I am missing something. I think you need:
Py_SAFE_DOWNCAST(remaining, Py_ssize_t, unsigned int)
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.
SEGMENT_SIZE is 32 KiB: remaining is only casted for values between [0; 32 KiB]:
#define SEGMENT_SIZE (32 * 1024 -1)
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.
LGTM
This PR is not yet completed (missing tests), I have "backported" a patch from 3.x.
https://bugs.python.org/issue36337