Primarily this fixes an off-by-one buffer overwrite (rare but still existing).

I also switched from calloc() to malloc() as a minor performance boost since
the rest of the code fills in the structs fine anyway - and they must for the
case when we use the stack-based auto variable array instead of the allocated
one.

I made the loop filling in poll_fds[] break when poll_nfds is reached as a
minor speed improvement.
This commit is contained in:
Daniel Stenberg 2007-05-26 22:02:29 +00:00
parent ebb5e1db4b
commit 8bd7197a8f

View File

@ -573,7 +573,7 @@ int Curl_select(int nfds,
else if (poll_nfds <= SMALL_POLLNFDS) else if (poll_nfds <= SMALL_POLLNFDS)
poll_fds = small_fds; poll_fds = small_fds;
else { else {
poll_fds = calloc((size_t)poll_nfds, sizeof(struct pollfd)); poll_fds = malloc(poll_nfds * sizeof(struct pollfd));
if (!poll_fds) { if (!poll_fds) {
SET_SOCKERRNO(ENOBUFS); SET_SOCKERRNO(ENOBUFS);
return -1; return -1;
@ -581,20 +581,27 @@ int Curl_select(int nfds,
} }
if (poll_fds) { if (poll_fds) {
int events;
ix = 0; ix = 0;
fd = nfds; fd = nfds;
while (fd--) { while (fd--) {
poll_fds[ix].events = 0; events = 0;
if (fds_read && (0 != FD_ISSET(fd, fds_read))) if (fds_read && (0 != FD_ISSET(fd, fds_read)))
poll_fds[ix].events |= (POLLRDNORM|POLLIN); events |= (POLLRDNORM|POLLIN);
if (fds_write && (0 != FD_ISSET(fd, fds_write))) if (fds_write && (0 != FD_ISSET(fd, fds_write)))
poll_fds[ix].events |= (POLLWRNORM|POLLOUT); events |= (POLLWRNORM|POLLOUT);
if (fds_excep && (0 != FD_ISSET(fd, fds_excep))) if (fds_excep && (0 != FD_ISSET(fd, fds_excep)))
poll_fds[ix].events |= (POLLRDBAND|POLLPRI); events |= (POLLRDBAND|POLLPRI);
if (poll_fds[ix].events) { if (events) {
poll_fds[ix].events = events;
poll_fds[ix].fd = fd; poll_fds[ix].fd = fd;
poll_fds[ix].revents = 0; poll_fds[ix].revents = 0;
ix++; ix++;
if(ix == poll_nfds)
/* since we know this is the total amount of descriptors with
interesting actions, we can skip the rest of the loop at this
point */
break;
} }
} }
} }