]> sigrok.org Git - libserialport.git/commitdiff
sp_wait: Avoid overflow of timeout parameter to poll().
authorMartin Ling <redacted>
Tue, 13 Oct 2015 14:04:03 +0000 (15:04 +0100)
committerMartin Ling <redacted>
Tue, 13 Oct 2015 14:04:03 +0000 (15:04 +0100)
libserialport_internal.h
serialport.c

index a5fc7bc54bcebdcc639a9dbdf8470461eb612143..a0d872bb8ed8bd8f9f2b854470965a694a107089 100644 (file)
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <limits.h>
 #ifdef _WIN32
 #include <windows.h>
 #include <tchar.h>
index 7b45229cca8281abf2cd9b1173ad031376ed8a76..2f7618e8e4a1778bc1abee0c640b17972fd86d24 100644 (file)
@@ -1421,7 +1421,9 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
        RETURN_OK();
 #else
        struct timeval start, delta, now, end = {0, 0};
-       int started = 0;
+       const struct timeval max_delta = {
+               (INT_MAX / 1000), (INT_MAX % 1000) * 1000};
+       int started = 0, timeout_overflow = 0;
        int result, timeout_remaining_ms;
        struct pollfd *pollfds;
        unsigned int i;
@@ -1461,7 +1463,8 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
                if (!timeout_ms) {
                        timeout_remaining_ms = -1;
                } else if (!started) {
-                       timeout_remaining_ms = timeout_ms;
+                       timeout_overflow = (timeout_ms > INT_MAX);
+                       timeout_remaining_ms = timeout_overflow ? INT_MAX : timeout_ms;
                } else {
                        gettimeofday(&now, NULL);
                        if (timercmp(&now, &end, >)) {
@@ -1469,6 +1472,8 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
                                break;
                        }
                        timersub(&end, &now, &delta);
+                       if ((timeout_overflow = timercmp(&delta, &max_delta, >)))
+                               delta = max_delta;
                        timeout_remaining_ms = delta.tv_sec * 1000 + delta.tv_usec / 1000;
                }
 
@@ -1485,7 +1490,8 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
                        }
                } else if (result == 0) {
                        DEBUG("poll() timed out");
-                       break;
+                       if (!timeout_overflow)
+                               break;
                } else {
                        DEBUG("poll() completed");
                        break;