Imported Upstream version 2.66.4 upstream/2.66.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 29 Oct 2021 01:27:09 +0000 (10:27 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 29 Oct 2021 01:27:09 +0000 (10:27 +0900)
NEWS
gio/gio-tool-info.c
glib/garray.c
glib/gdate.c
glib/gdatetime.c
glib/gnulib/gl_cv_func_frexpl_works/meson.build
glib/tests/array-test.c
glib/tests/date.c
glib/tests/gdatetime.c
meson.build

diff --git a/NEWS b/NEWS
index 45692a2..56d27f6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,19 @@
+Overview of changes in GLib 2.66.4
+==================================
+
+* Fix some issues in parsing floating point seconds in `GDateTime` (!1791, !1797)
+
+* Fix some issues in handling invalid UTF-8 when parsing for `GDate` (!1788)
+
+* Bugs fixed:
+ - #2264 GPtrArray might call qsort() with NULL data
+ - !1774 Backport !1771 “macos: fix frexpl checks in cross-compilation” to glib-2-66
+ - !1790 Backport !1788 “gdate: Validate input as UTF-8 before parsing” to glib-2-66
+ - !1793 Backport !1791 “gdatetime: Disallow NAN as a number of seconds in a GDateTime” to glib-2-66
+ - !1799 Backport !1794 “gio-tool-info: Prevent criticals if mount options are not available” to glib-2-66
+ - !1805 Backport !1797 “gdatetime: Improve ISO 8601 parsing to avoid floating point checks” to glib-2-66
+
+
 Overview of changes in GLib 2.66.3
 ==================================
 
index 7cf5683..a062635 100644 (file)
@@ -182,7 +182,8 @@ show_info (GFile *file, GFileInfo *info)
           gchar *root_string = NULL;
           gchar *mount;
           gchar *fs;
-          gchar *options;
+          const gchar *options;
+          gchar *options_string = NULL;
 
           device = g_strescape (g_unix_mount_get_device_path (entry), NULL);
           root = g_unix_mount_get_root_path (entry);
@@ -194,16 +195,22 @@ show_info (GFile *file, GFileInfo *info)
             }
           mount = g_strescape (g_unix_mount_get_mount_path (entry), NULL);
           fs = g_strescape (g_unix_mount_get_fs_type (entry), NULL);
-          options = g_strescape (g_unix_mount_get_options (entry), NULL);
+
+          options = g_unix_mount_get_options (entry);
+          if (options != NULL)
+            {
+              options_string = g_strescape (options, NULL);
+            }
 
           g_print (_("unix mount: %s%s %s %s %s\n"), device,
-                   root_string ? root_string : "", mount, fs, options);
+                   root_string ? root_string : "", mount, fs,
+                   options_string ? options_string : "");
 
           g_free (device);
           g_free (root_string);
           g_free (mount);
           g_free (fs);
-          g_free (options);
+          g_free (options_string);
 
           g_unix_mount_free (entry);
         }
index 3f23b98..4b6de19 100644 (file)
@@ -822,11 +822,12 @@ g_array_sort (GArray       *farray,
   g_return_if_fail (array != NULL);
 
   /* Don't use qsort as we want a guaranteed stable sort */
-  g_qsort_with_data (array->data,
-                     array->len,
-                     array->elt_size,
-                     (GCompareDataFunc)compare_func,
-                     NULL);
+  if (array->len > 0)
+    g_qsort_with_data (array->data,
+                       array->len,
+                       array->elt_size,
+                       (GCompareDataFunc)compare_func,
+                       NULL);
 }
 
 /**
@@ -853,11 +854,12 @@ g_array_sort_with_data (GArray           *farray,
 
   g_return_if_fail (array != NULL);
 
-  g_qsort_with_data (array->data,
-                     array->len,
-                     array->elt_size,
-                     compare_func,
-                     user_data);
+  if (array->len > 0)
+    g_qsort_with_data (array->data,
+                       array->len,
+                       array->elt_size,
+                       compare_func,
+                       user_data);
 }
 
 /**
@@ -1984,11 +1986,12 @@ g_ptr_array_sort (GPtrArray    *array,
   g_return_if_fail (array != NULL);
 
   /* Don't use qsort as we want a guaranteed stable sort */
-  g_qsort_with_data (array->pdata,
-                     array->len,
-                     sizeof (gpointer),
-                     (GCompareDataFunc)compare_func,
-                     NULL);
+  if (array->len > 0)
+    g_qsort_with_data (array->pdata,
+                       array->len,
+                       sizeof (gpointer),
+                       (GCompareDataFunc)compare_func,
+                       NULL);
 }
 
 /* Please keep this doc-comment in sync with
@@ -2060,11 +2063,12 @@ g_ptr_array_sort_with_data (GPtrArray        *array,
 {
   g_return_if_fail (array != NULL);
 
-  g_qsort_with_data (array->pdata,
-                     array->len,
-                     sizeof (gpointer),
-                     compare_func,
-                     user_data);
+  if (array->len > 0)
+    g_qsort_with_data (array->pdata,
+                       array->len,
+                       sizeof (gpointer),
+                       compare_func,
+                       user_data);
 }
 
 /**
index c896c22..391b142 100644 (file)
@@ -1234,7 +1234,11 @@ g_date_set_parse (GDate       *d,
   
   /* set invalid */
   g_date_clear (d, 1);
-  
+
+  /* The input has to be valid UTF-8. */
+  if (!g_utf8_validate (str, -1, NULL))
+    return;
+
   G_LOCK (g_date_global);
 
   g_date_prepare_to_parse (str, &pt);
index 1755257..02cc3bd 100644 (file)
@@ -52,6 +52,7 @@
 #define _GNU_SOURCE 1
 #endif
 
+#include <math.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -1180,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;
@@ -1207,13 +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;
     }
 
-  *value = v / divisor;
+  *value = (gdouble) v / divisor;
   return TRUE;
 }
 
@@ -1585,6 +1588,7 @@ g_date_time_new (GTimeZone *tz,
       day < 1 || day > days_in_months[GREGORIAN_LEAP (year)][month] ||
       hour < 0 || hour > 23 ||
       minute < 0 || minute > 59 ||
+      isnan (seconds) ||
       seconds < 0.0 || seconds >= 60.0)
     return NULL;
 
index 303ec63..50e614e 100644 (file)
@@ -120,7 +120,6 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
 else
   if (host_system.startswith ('aix') or
       host_system.startswith ('beos') or
-      host_system.startswith ('darwin') or
       host_system.startswith ('irix'))
     gl_cv_func_frexpl_works = false
     gl_cv_func_frexpl_broken_beyond_repair = true
index 745cf8b..e6d6059 100644 (file)
@@ -590,6 +590,10 @@ array_sort (gconstpointer test_data)
   gint prev, cur;
 
   garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
+
+  /* Sort empty array */
+  g_array_sort (garray, int_compare);
+
   for (i = 0; i < 10000; i++)
     {
       cur = g_random_int_range (0, 10000);
@@ -622,6 +626,10 @@ array_sort_with_data (gconstpointer test_data)
   gint prev, cur;
 
   garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
+
+  /* Sort empty array */
+  g_array_sort_with_data (garray, int_compare_data, NULL);
+
   for (i = 0; i < 10000; i++)
     {
       cur = g_random_int_range (0, 10000);
@@ -1334,6 +1342,10 @@ pointer_array_sort (void)
   gint prev, cur;
 
   gparray = g_ptr_array_new ();
+
+  /* Sort empty array */
+  g_ptr_array_sort (gparray, ptr_compare);
+
   for (i = 0; i < 10000; i++)
     {
       val = g_random_int_range (0, 10000);
@@ -1505,6 +1517,10 @@ pointer_array_sort_with_data (void)
   gint prev, cur;
 
   gparray = g_ptr_array_new ();
+
+  /* Sort empty array */
+  g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
+
   for (i = 0; i < 10000; i++)
     g_ptr_array_add (gparray, GINT_TO_POINTER (g_random_int_range (0, 10000)));
 
index e49ec34..38de1d9 100644 (file)
@@ -185,6 +185,29 @@ test_parse (void)
 }
 
 static void
+test_parse_invalid (void)
+{
+  const gchar * const strs[] =
+    {
+      /* Incomplete UTF-8 sequence */
+      "\xfd",
+    };
+  gsize i;
+
+  for (i = 0; i < G_N_ELEMENTS (strs); i++)
+    {
+      GDate *d = g_date_new ();
+
+      g_test_message ("Test %" G_GSIZE_FORMAT, i);
+      g_date_set_parse (d, strs[i]);
+
+      g_assert_false (g_date_valid (d));
+
+      g_date_free (d);
+    }
+}
+
+static void
 test_parse_locale_change (void)
 {
   /* Checks that g_date_set_parse correctly changes locale specific data as
@@ -770,6 +793,7 @@ main (int argc, char** argv)
   g_test_add_func ("/date/julian", test_julian_constructor);
   g_test_add_func ("/date/dates", test_dates);
   g_test_add_func ("/date/parse", test_parse);
+  g_test_add_func ("/date/parse/invalid", test_parse_invalid);
   g_test_add_func ("/date/parse_locale_change", test_parse_locale_change);
   g_test_add_func ("/date/month_substring", test_month_substring);
   g_test_add_func ("/date/month_names", test_month_names);
index 4ea0fc6..0203dd0 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "config.h"
 
+#include <math.h>
 #include <string.h>
 #include <time.h>
 #include <gi18n.h>
@@ -740,6 +741,14 @@ test_GDateTime_new_from_iso8601 (void)
   dt = g_date_time_new_from_iso8601 ("--0824T22:10:42Z", NULL);
   g_assert_null (dt);
 
+  /* Seconds must be two digits. */
+  dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:4Z", NULL);
+  g_assert_null (dt);
+
+  /* Seconds must all be digits. */
+  dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:4aZ", NULL);
+  g_assert_null (dt);
+
   /* Check subseconds work */
   dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42.123456Z", NULL);
   ASSERT_DATE (dt, 2016, 8, 24);
@@ -756,6 +765,28 @@ test_GDateTime_new_from_iso8601 (void)
   ASSERT_TIME (dt, 22, 10, 42, 123456);
   g_date_time_unref (dt);
 
+  /* Subseconds must all be digits. */
+  dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:42.5aZ", NULL);
+  g_assert_null (dt);
+
+  /* Subseconds can be an arbitrary length, but must not overflow.
+   * The ASSERT_TIME() comparisons are constrained by only comparing up to
+   * microsecond granularity. */
+  dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:09.222222222222222222Z", NULL);
+  ASSERT_DATE (dt, 2016, 8, 10);
+  ASSERT_TIME (dt, 22, 10, 9, 222222);
+  g_date_time_unref (dt);
+  dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:09.2222222222222222222Z", NULL);
+  g_assert_null (dt);
+
+  /* Small numerator, large divisor when parsing the subseconds. */
+  dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:00.0000000000000000001Z", NULL);
+  ASSERT_DATE (dt, 2016, 8, 10);
+  ASSERT_TIME (dt, 22, 10, 0, 0);
+  g_date_time_unref (dt);
+  dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:00.00000000000000000001Z", NULL);
+  g_assert_null (dt);
+
   /* We don't support times without minutes / seconds (valid ISO 8601) */
   dt = g_date_time_new_from_iso8601 ("2016-08-24T22Z", NULL);
   g_assert_null (dt);
@@ -797,6 +828,12 @@ test_GDateTime_new_from_iso8601 (void)
   /* Timezone hours two digits */
   dt = g_date_time_new_from_iso8601 ("2016-08-24T22-2Z", NULL);
   g_assert_null (dt);
+
+  /* Ordinal date (YYYYDDD), space separator, and then time as HHMMSS,SSS
+   * The interesting bit is that the seconds field is so long as to parse as
+   * NaN */
+  dt = g_date_time_new_from_iso8601 ("0005306 000001,666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666600080000-00", NULL);
+  g_assert_null (dt);
 }
 
 typedef struct {
@@ -1270,6 +1307,18 @@ test_GDateTime_new_full (void)
   g_date_time_unref (dt);
   dt = g_date_time_new_utc (2016, 12, 32, 22, 10, 42);
   g_assert_null (dt);
+
+  /* Seconds limits. */
+  dt = g_date_time_new_utc (2020, 12, 9, 14, 49, NAN);
+  g_assert_null (dt);
+  dt = g_date_time_new_utc (2020, 12, 9, 14, 49, -0.1);
+  g_assert_null (dt);
+  dt = g_date_time_new_utc (2020, 12, 9, 14, 49, 60.0);
+  g_assert_null (dt);
+
+  /* Year limits */
+  dt = g_date_time_new_utc (10000, 1, 1, 0, 0, 0);
+  dt = g_date_time_new_utc (0, 1, 1, 0, 0, 0);
 }
 
 static void
index a493c51..d938ddf 100644 (file)
@@ -1,5 +1,5 @@
 project('glib', 'c', 'cpp',
-  version : '2.66.3',
+  version : '2.66.4',
   # NOTE: We keep this pinned at 0.49 because that's what Debian 10 ships
   meson_version : '>= 0.49.2',
   default_options : [