From 8bd7197a8fb6d4a49df7efa25361c95ebdfc1d9c Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 26 May 2007 22:02:29 +0000
Subject: 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.
---
 lib/select.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

(limited to 'lib')

diff --git a/lib/select.c b/lib/select.c
index 3bfffa9c8..daa591eae 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -573,7 +573,7 @@ int Curl_select(int nfds,
   else if (poll_nfds <= SMALL_POLLNFDS)
     poll_fds = small_fds;
   else {
-    poll_fds = calloc((size_t)poll_nfds, sizeof(struct pollfd));
+    poll_fds = malloc(poll_nfds * sizeof(struct pollfd));
     if (!poll_fds) {
       SET_SOCKERRNO(ENOBUFS);
       return -1;
@@ -581,20 +581,27 @@ int Curl_select(int nfds,
   }
 
   if (poll_fds) {
+    int events;
     ix = 0;
     fd = nfds;
     while (fd--) {
-      poll_fds[ix].events = 0;
+      events = 0;
       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)))
-        poll_fds[ix].events |= (POLLWRNORM|POLLOUT);
+        events |= (POLLWRNORM|POLLOUT);
       if (fds_excep && (0 != FD_ISSET(fd, fds_excep)))
-        poll_fds[ix].events |= (POLLRDBAND|POLLPRI);
-      if (poll_fds[ix].events) {
+        events |= (POLLRDBAND|POLLPRI);
+      if (events) {
+        poll_fds[ix].events = events;
         poll_fds[ix].fd = fd;
         poll_fds[ix].revents = 0;
         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;
       }
     }
   }
-- 
cgit v1.2.3