poll: use GetTickCount64() to avoid wrap-around issues

The value of timeout starts as an int value, and for this reason it cannot overflow unsigned long long aka ULONGLONG. The unsigned version of this initial value is available in orig_timeout. The difference (orig_timeout - elapsed) cannot wrap around because it is protected by a conditional (as can be seen in the patch text). Hence, the ULONGLONG difference can only have values that are smaller than the initial timeout value and truncation to int cannot overflow. Signed-off-by: Steve Hoelzer <shoelzer@gmail.com> [j6t: improved both implementation and log message] Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Steve Hoelzer committed Oct 31, 2018 at 14:11 UTC e8dfcace316aaaca226c2ae2d268bcc4d3131b38
1 file changed +8 -4
compat/poll/poll.c
+8 -4
@@ -18,6 +18,9 @@
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, see <http://www.gnu.org/licenses/>. */
20
21 +/* To bump the minimum Windows version to Windows Vista */
22 +#include "git-compat-util.h"
23 +
24 /* Tell gcc not to warn about the (nfd < 0) tests, below. */
25 #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
26 # pragma GCC diagnostic ignored "-Wtype-limits"
@@ -449,7 +452,8 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
452 static HANDLE hEvent;
453 WSANETWORKEVENTS ev;
454 HANDLE h, handle_array[FD_SETSIZE + 2];
452 - DWORD ret, wait_timeout, nhandles, start = 0, elapsed, orig_timeout = 0;
455 + DWORD ret, wait_timeout, nhandles, orig_timeout = 0;
456 + ULONGLONG start = 0;
457 fd_set rfds, wfds, xfds;
458 BOOL poll_again;
459 MSG msg;
@@ -465,7 +469,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
469 if (timeout != INFTIM)
470 {
471 orig_timeout = timeout;
468 - start = GetTickCount();
472 + start = GetTickCount64();
473 }
474
475 if (!hEvent)
@@ -614,8 +618,8 @@ restart:
618
619 if (!rc && orig_timeout && timeout != INFTIM)
620 {
617 - elapsed = GetTickCount() - start;
618 - timeout = elapsed >= orig_timeout ? 0 : orig_timeout - elapsed;
621 + ULONGLONG elapsed = GetTickCount64() - start;
622 + timeout = elapsed >= orig_timeout ? 0 : (int)(orig_timeout - elapsed);
623 }
624
625 if (!rc && timeout)