Hello community, here is the log from the commit of package glib2 for openSUSE:Factory checked in at 2020-01-02 14:40:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/glib2 (Old) and /work/SRC/openSUSE:Factory/.glib2.new.6675 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "glib2" Thu Jan 2 14:40:00 2020 rev:220 rq:758495 version:2.62.4 Changes: -------- --- /work/SRC/openSUSE:Factory/glib2/glib2.changes 2019-11-29 15:56:51.784973540 +0100 +++ /work/SRC/openSUSE:Factory/.glib2.new.6675/glib2.changes 2020-01-02 14:40:05.744882258 +0100 @@ -1,0 +2,9 @@ +Thu Dec 19 17:45:31 UTC 2019 - Bjørn Lie <[email protected]> + +- Update to version 2.62.4: + + Apply recursion depth limits to variants in D-Bus messages. + + Bugs fixed: glgo#GNOME/GLib#1938, glgo#GNOME/GLib!1240, + glgo#GNOME/GLib!1257, glgo#GNOME/GLib!1266, + glgo#GNOME/GLib!1276, glgo#GNOME/GLib!1290. + +------------------------------------------------------------------- Old: ---- glib-2.62.3.tar.xz New: ---- glib-2.62.4.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ glib2.spec ++++++ --- /var/tmp/diff_new_pack.2y9q3G/_old 2020-01-02 14:40:06.408882521 +0100 +++ /var/tmp/diff_new_pack.2y9q3G/_new 2020-01-02 14:40:06.412882523 +0100 @@ -1,7 +1,7 @@ # # spec file for package glib2 # -# Copyright (c) 2019 SUSE LLC. +# Copyright (c) 2019 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %bcond_without systemtap Name: glib2 -Version: 2.62.3 +Version: 2.62.4 Release: 0 Summary: General-Purpose Utility Library License: LGPL-2.1-or-later ++++++ glib-2.62.3.tar.xz -> glib-2.62.4.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/NEWS new/glib-2.62.4/NEWS --- old/glib-2.62.3/NEWS 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/NEWS 2019-12-19 17:33:15.000000000 +0100 @@ -1,3 +1,17 @@ +Overview of changes in GLib 2.62.4 +================================== + +* Apply recursion depth limits to variants in D-Bus messages (!1290) + +* Bugs fixed: + - #1938 GDateTime doesn't support leap seconds + - !1240 Backport !1233 “gdatetime: Handle leap seconds in ISO8601 dates” to glib-2-62 + - !1257 Backport !1232 “kqueue: Do not return early from _kqsub_cancel” to glib-2-62 + - !1266 Backport !1265 “build: don't check for protected visibility” to glib-2-62 + - !1276 Backport !1274 “trash portal: Don't follow symlinks” to glib-2-62 + - !1290 Backport !1201 “gdbusmessage: Limit recursion of variants in D-Bus messages” to glib-2-62 + + Overview of changes in GLib 2.62.3 ================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/gio/gdbusmessage.c new/glib-2.62.4/gio/gdbusmessage.c --- old/glib-2.62.3/gio/gdbusmessage.c 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/gio/gdbusmessage.c 2019-12-19 17:33:15.000000000 +0100 @@ -58,6 +58,10 @@ #include "glibintl.h" +/* See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature + * This is 64 containers plus 1 value within them. */ +#define G_DBUS_MAX_TYPE_DEPTH (64 + 1) + typedef struct _GMemoryBuffer GMemoryBuffer; struct _GMemoryBuffer { @@ -1439,17 +1443,27 @@ static GVariant * parse_value_from_blob (GMemoryBuffer *buf, const GVariantType *type, + guint max_depth, gboolean just_align, guint indent, GError **error) { - GVariant *ret; - GError *local_error; + GVariant *ret = NULL; + GError *local_error = NULL; #ifdef DEBUG_SERIALIZER gboolean is_leaf; #endif /* DEBUG_SERIALIZER */ const gchar *type_string; + if (max_depth == 0) + { + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Value nested too deeply")); + goto fail; + } + type_string = g_variant_type_peek_string (type); #ifdef DEBUG_SERIALIZER @@ -1465,12 +1479,9 @@ } #endif /* DEBUG_SERIALIZER */ - ret = NULL; - #ifdef DEBUG_SERIALIZER is_leaf = TRUE; #endif /* DEBUG_SERIALIZER */ - local_error = NULL; switch (type_string[0]) { case 'b': /* G_VARIANT_TYPE_BOOLEAN */ @@ -1690,6 +1701,17 @@ goto fail; } + if (max_depth == 1) + { + /* If we had recursed into parse_value_from_blob() again to + * parse the array values, this would have been emitted. */ + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Value nested too deeply")); + goto fail; + } + ensure_input_padding (buf, fixed_size); array_data = read_bytes (buf, array_len, &local_error); if (array_data == NULL) @@ -1717,6 +1739,7 @@ GVariant *item G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; item = parse_value_from_blob (buf, element_type, + max_depth - 1, TRUE, indent + 2, NULL); @@ -1731,6 +1754,7 @@ GVariant *item; item = parse_value_from_blob (buf, element_type, + max_depth - 1, FALSE, indent + 2, &local_error); @@ -1770,6 +1794,7 @@ key_type = g_variant_type_key (type); key = parse_value_from_blob (buf, key_type, + max_depth - 1, FALSE, indent + 2, &local_error); @@ -1778,6 +1803,7 @@ value_type = g_variant_type_value (type); value = parse_value_from_blob (buf, value_type, + max_depth - 1, FALSE, indent + 2, &local_error); @@ -1812,6 +1838,7 @@ GVariant *item; item = parse_value_from_blob (buf, element_type, + max_depth - 1, FALSE, indent + 2, &local_error); @@ -1858,9 +1885,26 @@ sig); goto fail; } + + if (max_depth <= g_variant_type_string_get_depth_ (sig)) + { + /* Catch the type nesting being too deep without having to + * parse the data. We don’t have to check this for static + * container types (like arrays and tuples, above) because + * the g_variant_type_string_is_valid() check performed before + * the initial parse_value_from_blob() call should check the + * static type nesting. */ + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Value nested too deeply")); + goto fail; + } + variant_type = g_variant_type_new (sig); value = parse_value_from_blob (buf, variant_type, + max_depth - 1, FALSE, indent + 2, &local_error); @@ -2098,6 +2142,7 @@ #endif /* DEBUG_SERIALIZER */ headers = parse_value_from_blob (&mbuf, G_VARIANT_TYPE ("a{yv}"), + G_DBUS_MAX_TYPE_DEPTH + 2 /* for the a{yv} */, FALSE, 2, error); @@ -2169,6 +2214,7 @@ #endif /* DEBUG_SERIALIZER */ message->body = parse_value_from_blob (&mbuf, variant_type, + G_DBUS_MAX_TYPE_DEPTH + 1 /* for the surrounding tuple */, FALSE, 2, error); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/gio/gtrashportal.c new/glib-2.62.4/gio/gtrashportal.c --- old/glib-2.62.3/gio/gtrashportal.c 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/gio/gtrashportal.c 2019-12-19 17:33:15.000000000 +0100 @@ -86,10 +86,10 @@ path = g_file_get_path (file); - fd = g_open (path, O_RDWR | O_CLOEXEC); + fd = g_open (path, O_RDWR | O_CLOEXEC | O_NOFOLLOW); if (fd == -1 && errno == EISDIR) /* If it is a directory, fall back to O_PATH */ - fd = g_open (path, O_PATH | O_CLOEXEC | O_RDONLY); + fd = g_open (path, O_PATH | O_CLOEXEC | O_RDONLY | O_NOFOLLOW); errsv = errno; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/gio/kqueue/gkqueuefilemonitor.c new/glib-2.62.4/gio/kqueue/gkqueuefilemonitor.c --- old/glib-2.62.3/gio/kqueue/gkqueuefilemonitor.c 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/gio/kqueue/gkqueuefilemonitor.c 2019-12-19 17:33:15.000000000 +0100 @@ -122,7 +122,7 @@ static kqueue_sub *_kqsub_new (gchar *, gchar *, GKqueueFileMonitor *, GFileMonitorSource *); static void _kqsub_free (kqueue_sub *); -static gboolean _kqsub_cancel (kqueue_sub *); +static void _kqsub_cancel (kqueue_sub *); #ifndef O_EVTONLY @@ -547,7 +547,7 @@ g_slice_free (kqueue_sub, sub); } -static gboolean +static void _kqsub_cancel (kqueue_sub *sub) { /* WARNING: Before calling this function, you must hold a lock on kq_lock @@ -563,7 +563,6 @@ if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1) { g_warning ("Unable to remove event for %s: %s", sub->filename, g_strerror (errno)); - return FALSE; } close (sub->fd); sub->fd = -1; @@ -576,8 +575,6 @@ dl_free (sub->deps); sub->deps = NULL; } - - return TRUE; } gboolean diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/gio/tests/gdbus-serialization.c new/glib-2.62.4/gio/tests/gdbus-serialization.c --- old/glib-2.62.3/gio/tests/gdbus-serialization.c 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/gio/tests/gdbus-serialization.c 2019-12-19 17:33:15.000000000 +0100 @@ -514,9 +514,8 @@ } /* If @value is floating, this assumes ownership. */ -static void -check_serialization (GVariant *value, - const gchar *expected_dbus_1_output) +static gchar * +get_and_check_serialization (GVariant *value) { guchar *blob; gsize blob_size; @@ -525,7 +524,7 @@ GDBusMessage *recovered_message; GError *error; DBusError dbus_error; - gchar *s; + gchar *s = NULL; guint n; message = g_dbus_message_new (); @@ -597,9 +596,6 @@ s = dbus_1_message_print (dbus_1_message); dbus_message_unref (dbus_1_message); - g_assert_cmpstr (s, ==, expected_dbus_1_output); - g_free (s); - /* Then serialize back and check that the body is identical */ error = NULL; @@ -624,10 +620,22 @@ } g_object_unref (message); + + return g_steal_pointer (&s); } +/* If @value is floating, this assumes ownership. */ static void -message_serialize_basic (void) +check_serialization (GVariant *value, + const gchar *expected_dbus_1_output) +{ + gchar *s = get_and_check_serialization (value); + g_assert_cmpstr (s, ==, expected_dbus_1_output); + g_free (s); +} + +static void +test_message_serialize_basic (void) { check_serialization (NULL, ""); @@ -661,10 +669,12 @@ /* ---------------------------------------------------------------------------------------------------- */ static void -message_serialize_complex (void) +test_message_serialize_complex (void) { GError *error; GVariant *value; + guint i; + gchar *serialization = NULL; error = NULL; @@ -724,6 +734,37 @@ " unix-fd: (not extracted)\n"); g_variant_unref (value); #endif + + /* Deep nesting of variants (just below the recursion limit). */ + value = g_variant_new_string ("buried"); + for (i = 0; i < 64; i++) + value = g_variant_new_variant (value); + value = g_variant_new_tuple (&value, 1); + + serialization = get_and_check_serialization (value); + g_assert_nonnull (serialization); + g_assert_true (g_str_has_prefix (serialization, + "value 0: variant:\n" + " variant:\n" + " variant:\n")); + g_free (serialization); + + /* Deep nesting of arrays and structs (just below the recursion limit). + * See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature */ + value = g_variant_new_string ("hello"); + for (i = 0; i < 32; i++) + value = g_variant_new_tuple (&value, 1); + for (i = 0; i < 32; i++) + value = g_variant_new_array (NULL, &value, 1); + value = g_variant_new_tuple (&value, 1); + + serialization = get_and_check_serialization (value); + g_assert_nonnull (serialization); + g_assert_true (g_str_has_prefix (serialization, + "value 0: array:\n" + " array:\n" + " array:\n")); + g_free (serialization); } @@ -749,7 +790,7 @@ } static void -message_serialize_invalid (void) +test_message_serialize_invalid (void) { guint n; @@ -842,7 +883,7 @@ /* ---------------------------------------------------------------------------------------------------- */ static void -message_serialize_header_checks (void) +test_message_serialize_header_checks (void) { GDBusMessage *message; GDBusMessage *reply; @@ -996,7 +1037,7 @@ /* ---------------------------------------------------------------------------------------------------- */ static void -message_parse_empty_arrays_of_arrays (void) +test_message_parse_empty_arrays_of_arrays (void) { GVariant *body; GError *error = NULL; @@ -1052,7 +1093,7 @@ /* ---------------------------------------------------------------------------------------------------- */ static void -test_double_array (void) +test_message_serialize_double_array (void) { GVariantBuilder builder; GVariant *body; @@ -1252,6 +1293,126 @@ /* ---------------------------------------------------------------------------------------------------- */ +/* Test that an invalid header in a D-Bus message (specifically, containing too + * many levels of nested variant) is gracefully handled with an error rather + * than a crash. The set of bytes here come almost directly from fuzzer output. */ +static void +test_message_parse_deep_header_nesting (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x20, /* message type */ + 0x20, /* message flags */ + 0x01, /* major protocol version */ + 0x20, 0x20, 0x20, 0x00, /* body length (invalid) */ + 0x20, 0x20, 0x20, 0x20, /* message serial */ + /* a{yv} of header fields: + * (things start to be even more invalid below here) */ + 0x20, 0x20, 0x20, 0x00, /* array length (in bytes) */ + 0x20, /* array key (this is not currently a valid header field) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'v', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + /* Critically, this contains 64 nested variants (minus two for the + * ‘arbitrary valid content’ below, but ignoring two for the `a{yv}` + * above), which in total exceeds %G_DBUS_MAX_TYPE_DEPTH. */ + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, + /* Some arbitrary valid content inside the innermost variant: */ + 0x01, 'y', 0x00, 0xcc, + /* (message body length missing) */ + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test that an invalid body in a D-Bus message (specifically, containing too + * many levels of nested variant) is gracefully handled with an error rather + * than a crash. The set of bytes here are a modified version of the bytes from + * test_message_parse_deep_header_nesting(). */ +static void +test_message_parse_deep_body_nesting (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x20, /* message type */ + 0x20, /* message flags */ + 0x01, /* major protocol version */ + 0x20, 0x20, 0x20, 0x00, /* body length (invalid) */ + 0x20, 0x20, 0x20, 0x20, /* message serial */ + /* a{yv} of header fields: */ + 0x07, 0x00, 0x00, 0x00, /* array length (in bytes) */ + 0x08, /* array key (signature field) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'g', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x01, 'v', 0x00, + /* End-of-header padding to reach an 8-byte boundary: */ + 0x00, + /* Message body: over 64 levels of nested variant, which is not valid: */ + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + /* Some arbitrary valid content inside the innermost variant: */ + 0x01, 'y', 0x00, 0xcc, + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + int main (int argc, char *argv[]) @@ -1262,15 +1423,19 @@ g_test_init (&argc, &argv, NULL); g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id="); - g_test_add_func ("/gdbus/message-serialize-basic", message_serialize_basic); - g_test_add_func ("/gdbus/message-serialize-complex", message_serialize_complex); - g_test_add_func ("/gdbus/message-serialize-invalid", message_serialize_invalid); - g_test_add_func ("/gdbus/message-serialize-header-checks", message_serialize_header_checks); - - g_test_add_func ("/gdbus/message-parse-empty-arrays-of-arrays", - message_parse_empty_arrays_of_arrays); + g_test_add_func ("/gdbus/message-serialize/basic", + test_message_serialize_basic); + g_test_add_func ("/gdbus/message-serialize/complex", + test_message_serialize_complex); + g_test_add_func ("/gdbus/message-serialize/invalid", + test_message_serialize_invalid); + g_test_add_func ("/gdbus/message-serialize/header-checks", + test_message_serialize_header_checks); + g_test_add_func ("/gdbus/message-serialize/double-array", + test_message_serialize_double_array); - g_test_add_func ("/gdbus/message-serialize/double-array", test_double_array); + g_test_add_func ("/gdbus/message-parse/empty-arrays-of-arrays", + test_message_parse_empty_arrays_of_arrays); g_test_add_func ("/gdbus/message-parse/non-signature-header", test_message_parse_non_signature_header); g_test_add_func ("/gdbus/message-parse/empty-signature-header", @@ -1279,6 +1444,10 @@ test_message_parse_multiple_signature_header); g_test_add_func ("/gdbus/message-parse/over-long-signature-header", test_message_parse_over_long_signature_header); + g_test_add_func ("/gdbus/message-parse/deep-header-nesting", + test_message_parse_deep_header_nesting); + g_test_add_func ("/gdbus/message-parse/deep-body-nesting", + test_message_parse_deep_body_nesting); return g_test_run(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/glib/gdatetime.c new/glib-2.62.4/glib/gdatetime.c --- old/glib-2.62.3/glib/gdatetime.c 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/glib/gdatetime.c 2019-12-19 17:33:15.000000000 +0100 @@ -1194,6 +1194,11 @@ if (length > 2 && !(text[i] == '.' || text[i] == ',')) return FALSE; + + /* Ignore leap seconds, see g_date_time_new_from_iso8601() */ + if (v >= 60.0 && v <= 61.0) + v = 59.0; + i++; if (i == length) return FALSE; @@ -1431,6 +1436,10 @@ * [ISO 8601 formatted string](https://en.wikipedia.org/wiki/ISO_8601) * @text. ISO 8601 strings of the form <date><sep><time><tz> are supported. * + * Note that as #GDateTime "is oblivious to leap seconds", leap seconds information + * in an ISO-8601 string will be ignored, so a `23:59:60` time would be parsed as + * `23:59:59`. + * * <sep> is the separator and can be either 'T', 't' or ' '. * * <date> is in the form: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/glib/tests/gdatetime.c new/glib-2.62.4/glib/tests/gdatetime.c --- old/glib-2.62.3/glib/tests/gdatetime.c 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/glib/tests/gdatetime.c 2019-12-19 17:33:15.000000000 +0100 @@ -818,6 +818,7 @@ { TRUE, "1970-01-01T00:00:17.1234Z", 1970, 1, 1, 0, 0, 17, 123400, 0 }, { TRUE, "1970-01-01T00:00:17.123456Z", 1970, 1, 1, 0, 0, 17, 123456, 0 }, { TRUE, "1980-02-22T12:36:00+02:00", 1980, 2, 22, 12, 36, 0, 0, 2 * G_TIME_SPAN_HOUR }, + { TRUE, "1990-12-31T15:59:60-08:00", 1990, 12, 31, 15, 59, 59, 0, -8 * G_TIME_SPAN_HOUR }, { FALSE, " ", 0, 0, 0, 0, 0, 0, 0, 0 }, { FALSE, "x", 0, 0, 0, 0, 0, 0, 0, 0 }, { FALSE, "123x", 0, 0, 0, 0, 0, 0, 0, 0 }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/glib-2.62.3/meson.build new/glib-2.62.4/meson.build --- old/glib-2.62.3/meson.build 2019-11-19 18:51:31.000000000 +0100 +++ new/glib-2.62.4/meson.build 2019-12-19 17:33:15.000000000 +0100 @@ -1,5 +1,5 @@ project('glib', 'c', 'cpp', - version : '2.62.3', + version : '2.62.4', # NOTE: We keep this pinned at 0.49 because that's what Debian 10 ships meson_version : '>= 0.49.2', default_options : [ @@ -142,11 +142,6 @@ { } void - __attribute__ ((visibility ("protected"))) - f_protected (void) - { - } - void __attribute__ ((visibility ("default"))) f_default (void) { @@ -155,7 +150,6 @@ { f_hidden(); f_internal(); - f_protected(); f_default(); return 0; }
