[glib/backport-1797-freebsd-date-parsing-glib-2-66: 1/3] gdatetime: Remove floating point from seconds parsing code




commit e470dca95f7ec6515807c0b4a54ab35d1c1deb8f
Author: Philip Withnall <pwithnall endlessos org>
Date:   Fri Dec 11 15:36:56 2020 +0000

    gdatetime: Remove floating point from seconds parsing code
    
    Rather than parsing the seconds in an ISO 8601 date/time using a pair of
    floating point numbers (numerator and denominator), use two integers
    instead. This avoids issues around floating point precision, and also
    makes it easier to check for potential overflow from overlong inputs.
    
    This last point means that the `isfinite()` check can be removed, as it
    was covering the case where a NAN was generated, which isn’t now
    possible using integer arithmetic.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>

 glib/gdatetime.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
---
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index 6f71e99cf..db54aed50 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -1181,7 +1181,7 @@ static gboolean
 get_iso8601_seconds (const gchar *text, gsize length, gdouble *value)
 {
   gsize i;
-  gdouble divisor = 1, v = 0;
+  guint64 divisor = 1, v = 0;
 
   if (length < 2)
     return FALSE;
@@ -1208,17 +1208,15 @@ get_iso8601_seconds (const gchar *text, gsize length, gdouble *value)
   for (; i < length; i++)
     {
       const gchar c = text[i];
-      if (c < '0' || c > '9')
+      if (c < '0' || c > '9' ||
+          v > (G_MAXUINT64 - (c - '0')) / 10 ||
+          divisor > G_MAXUINT64 / 10)
         return FALSE;
       v = v * 10 + (c - '0');
       divisor *= 10;
     }
 
-  v = v / divisor;
-  if (!isfinite (v))
-    return FALSE;
-
-  *value = v;
+  *value = (gdouble) v / divisor;
   return TRUE;
 }
 


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