[glib: 5/7] gmain: clamp over-large timeouts



commit cdc2dd8eb15627a6c52724dcc2930300153fbfd4
Author: Will Thompson <will willthompson co uk>
Date:   Mon Nov 26 20:38:55 2018 +0000

    gmain: clamp over-large timeouts
    
    g_main_context_prepare() needs to calculate the timeout to pass to
    poll(), expressed in milliseconds as a gint.  But since the ready time
    for a GSource is represented by gint64 microseconds, it's possible that
    it could be more than G_MAXINT * 1000 microseconds in the future, and so
    can't be represented as a gint. This conversion to a narrower signed
    type is implementation-defined, but there are two possible outcomes:
    
    * the result is >= 0, in which case poll() will time out earlier than we
      might hope (with no adverse consequences besides an unwanted wakeup)
    * the result is < 0, in which case, if there are no other sources,
      poll() will block forever
    
    This is extremely unlikely to happen in practice, but can be avoided by
    clamping the gint64 value, which we know to be positive, to G_MAXINT.
    
    Thanks to Tomasz Miąsko for pointing this out on !496.

 glib/gmain.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index 347882551..c24690e44 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -3525,13 +3525,13 @@ g_main_context_prepare (GMainContext *context,
                 }
               else
                 {
-                  gint timeout;
+                  gint64 timeout;
 
                   /* rounding down will lead to spinning, so always round up */
                   timeout = (source->priv->ready_time - context->time + 999) / 1000;
 
                   if (source_timeout < 0 || timeout < source_timeout)
-                    source_timeout = timeout;
+                    source_timeout = MIN (timeout, G_MAXINT);
                 }
             }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]