summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2019-05-15 17:15:10 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-05-15 18:15:10 +0200
commitd0b8724aa2b52e3b8c6da8f592341dfb1a9b836a (patch)
tree7f0b7a5ebc29e9cf0e6dad84df77600e5cc1eb2a
parent2339542832f754cffda5905b3ed6fdbf8766cad7 (diff)
downloadNim-d0b8724aa2b52e3b8c6da8f592341dfb1a9b836a.tar.gz
Fixes crashes when asyncdispatch.adjustTimeout returns a negative value. (#11231)
-rw-r--r--lib/pure/asyncdispatch.nim5
-rw-r--r--lib/pure/ioselects/ioselectors_epoll.nim2
-rw-r--r--lib/pure/ioselects/ioselectors_kqueue.nim10
-rw-r--r--lib/pure/ioselects/ioselectors_poll.nim2
-rw-r--r--lib/pure/ioselects/ioselectors_select.nim2
-rw-r--r--lib/pure/selectors.nim8
6 files changed, 22 insertions, 7 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index 3cc574afd..dee40d3cb 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -211,11 +211,10 @@ proc processPendingCallbacks(p: PDispatcherBase; didSomeWork: var bool) =
     didSomeWork = true
 
 proc adjustTimeout(pollTimeout: int, nextTimer: Option[int]): int {.inline.} =
-  if nextTimer.isNone():
+  if nextTimer.isNone() or pollTimeout == -1:
     return pollTimeout
 
-  result = nextTimer.get()
-  if pollTimeout == -1: return
+  result = max(nextTimer.get(), 0)
   result = min(pollTimeout, result)
 
 proc callSoon*(cbproc: proc () {.gcsafe.}) {.gcsafe.}
diff --git a/lib/pure/ioselects/ioselectors_epoll.nim b/lib/pure/ioselects/ioselectors_epoll.nim
index ffd60120e..c01a69583 100644
--- a/lib/pure/ioselects/ioselectors_epoll.nim
+++ b/lib/pure/ioselects/ioselectors_epoll.nim
@@ -378,6 +378,8 @@ proc selectInto*[T](s: Selector[T], timeout: int,
   if maxres > len(results):
     maxres = len(results)
 
+  verifySelectParams(timeout)
+
   let count = epoll_wait(s.epollFD, addr(resTable[0]), maxres.cint,
                          timeout.cint)
   if count < 0:
diff --git a/lib/pure/ioselects/ioselectors_kqueue.nim b/lib/pure/ioselects/ioselectors_kqueue.nim
index 5ea1cc7ae..16301e1d5 100644
--- a/lib/pure/ioselects/ioselectors_kqueue.nim
+++ b/lib/pure/ioselects/ioselectors_kqueue.nim
@@ -44,8 +44,8 @@ elif defined(netbsd) or defined(openbsd):
 when hasThreadSupport:
   type
     SelectorImpl[T] = object
-      kqFD : cint
-      maxFD : int
+      kqFD: cint
+      maxFD: int
       changes: ptr SharedArray[KEvent]
       fds: ptr SharedArray[SelectorKey[T]]
       count: int
@@ -57,8 +57,8 @@ when hasThreadSupport:
 else:
   type
     SelectorImpl[T] = object
-      kqFD : cint
-      maxFD : int
+      kqFD: cint
+      maxFD: int
       changes: seq[KEvent]
       fds: seq[SelectorKey[T]]
       count: int
@@ -447,6 +447,8 @@ proc selectInto*[T](s: Selector[T], timeout: int,
     ptv = addr tv
     maxres = MAX_KQUEUE_EVENTS
 
+  verifySelectParams(timeout)
+
   if timeout != -1:
     if timeout >= 1000:
       tv.tv_sec = posix.Time(timeout div 1_000)
diff --git a/lib/pure/ioselects/ioselectors_poll.nim b/lib/pure/ioselects/ioselectors_poll.nim
index 103a2242c..1af2a46db 100644
--- a/lib/pure/ioselects/ioselectors_poll.nim
+++ b/lib/pure/ioselects/ioselectors_poll.nim
@@ -214,6 +214,8 @@ proc selectInto*[T](s: Selector[T], timeout: int,
   if maxres > len(results):
     maxres = len(results)
 
+  verifySelectParams(timeout)
+
   s.withPollLock():
     let count = posix.poll(addr(s.pollfds[0]), Tnfds(s.pollcnt), timeout)
     if count < 0:
diff --git a/lib/pure/ioselects/ioselectors_select.nim b/lib/pure/ioselects/ioselectors_select.nim
index 521b31a64..99d8caefd 100644
--- a/lib/pure/ioselects/ioselectors_select.nim
+++ b/lib/pure/ioselects/ioselectors_select.nim
@@ -309,6 +309,8 @@ proc selectInto*[T](s: Selector[T], timeout: int,
   var ptv = addr tv
   var rset, wset, eset: FdSet
 
+  verifySelectParams(timeout)
+
   if timeout != -1:
     when defined(genode):
       tv.tv_sec = Time(timeout div 1_000)
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index b9c834127..e2ab98ba8 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -314,6 +314,14 @@ else:
     key.events = {}
     key.data = empty
 
+  proc verifySelectParams(timeout: int) =
+    # Timeout of -1 means: wait forever
+    # Anything higher is the time to wait in miliseconds.
+    if timeout < -1:
+      raise newException(
+        ValueError, "Cannot select with a negative value, got " & $timeout
+      )
+
   when defined(linux):
     include ioselects/ioselectors_epoll
   elif bsdPlatform: