!2 glib2: update to 2.62.1

Merge pull request !2 from algorithmofdish/master
This commit is contained in:
openeuler-ci-bot 2020-01-11 18:22:07 +08:00 committed by Gitee
commit 4e88124967
50 changed files with 58 additions and 4104 deletions

View File

@ -1,32 +0,0 @@
From 0f131857babb41eb443a8f7ae843e5990978a719 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Mon, 29 Jul 2019 10:49:45 +0100
Subject: [PATCH 458/493] gapplication: Fix a leaking GRemoteActionGroup member
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix prompted by Ting-Wei Lans similar fix for the inactivity timeout
(!1009).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
gio/gapplication.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 8ad4d0f..ad5826d 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -1395,6 +1395,8 @@ g_application_finalize (GObject *object)
if (application->priv->actions)
g_object_unref (application->priv->actions);
+ g_clear_object (&application->priv->remote_actions);
+
if (application->priv->notifications)
g_object_unref (application->priv->notifications);
--
1.8.3.1

View File

@ -1,53 +0,0 @@
From d8f8f4d637ce43f8699ba94c9b7648beda0ca174 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Thu, 23 May 2019 10:41:53 +0200
Subject: [PATCH] gfile: Limit access to files when copying
file_copy_fallback creates new files with default permissions and
set the correct permissions after the operation is finished. This
might cause that the files can be accessible by more users during
the operation than expected. Use G_FILE_CREATE_PRIVATE for the new
files to limit access to those files.
---
gio/gfile.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/gio/gfile.c b/gio/gfile.c
index 24b136d80..74b58047c 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -3284,12 +3284,12 @@ file_copy_fallback (GFile *source,
out = (GOutputStream*)_g_local_file_output_stream_replace (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
FALSE, NULL,
flags & G_FILE_COPY_BACKUP,
- G_FILE_CREATE_REPLACE_DESTINATION,
- info,
+ G_FILE_CREATE_REPLACE_DESTINATION |
+ G_FILE_CREATE_PRIVATE, info,
cancellable, error);
else
out = (GOutputStream*)_g_local_file_output_stream_create (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
- FALSE, 0, info,
+ FALSE, G_FILE_CREATE_PRIVATE, info,
cancellable, error);
}
else if (flags & G_FILE_COPY_OVERWRITE)
@@ -3297,12 +3297,13 @@ file_copy_fallback (GFile *source,
out = (GOutputStream *)g_file_replace (destination,
NULL,
flags & G_FILE_COPY_BACKUP,
- G_FILE_CREATE_REPLACE_DESTINATION,
+ G_FILE_CREATE_REPLACE_DESTINATION |
+ G_FILE_CREATE_PRIVATE,
cancellable, error);
}
else
{
- out = (GOutputStream *)g_file_create (destination, 0, cancellable, error);
+ out = (GOutputStream *)g_file_create (destination, G_FILE_CREATE_PRIVATE, cancellable, error);
}
if (!out)
--
2.22.0

View File

@ -1,23 +0,0 @@
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
index a37978e..580a0b0 100644
--- a/gio/gkeyfilesettingsbackend.c
+++ b/gio/gkeyfilesettingsbackend.c
@@ -89,7 +89,8 @@ g_keyfile_settings_backend_keyfile_write (GKeyfileSettingsBackend *kfsb)
contents = g_key_file_to_data (kfsb->keyfile, &length, NULL);
g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE,
- G_FILE_CREATE_REPLACE_DESTINATION,
+ G_FILE_CREATE_REPLACE_DESTINATION |
+ G_FILE_CREATE_PRIVATE,
NULL, NULL, NULL);
compute_checksum (kfsb->digest, contents, length);
@@ -640,7 +641,7 @@ g_keyfile_settings_backend_new (const gchar *filename,
kfsb->file = g_file_new_for_path (filename);
kfsb->dir = g_file_get_parent (kfsb->file);
- g_file_make_directory_with_parents (kfsb->dir, NULL, NULL);
+ g_mkdir_with_parents (g_file_peek_path (kfsb->dir), 0700);
kfsb->file_monitor = g_file_monitor (kfsb->file, 0, NULL, NULL);
kfsb->dir_monitor = g_file_monitor (kfsb->dir, 0, NULL, NULL);

View File

@ -1,37 +0,0 @@
From 4cd8fccc11f732ac76bf522562e06fc90ae82144 Mon Sep 17 00:00:00 2001
From: Emmanuel Fleury <emmanuel.fleury@u-bordeaux.fr>
Date: Sun, 27 Jan 2019 03:10:37 +0100
Subject: [PATCH 547/682] Fixing missing initializer in
g_static_rec_mutex_init()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
glib/deprecated/gthread-deprecated.c: In function g_static_rec_mutex_init:
glib/deprecated/gthread-deprecated.c:657:3: error: missing initializer for field depth of GStaticRecMutex {aka const struct _GStaticRecMutex} [-Werror=missing-field-initializers]
static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;
^~~~~~
In file included from glib/deprecated/gthread-deprecated.c:30:
glib/deprecated/gthread.h:161:9: note: depth declared here
guint depth;
^~~~~
---
glib/deprecated/gthread.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/deprecated/gthread.h b/glib/deprecated/gthread.h
index d0814a875..9e1c2ff56 100644
--- a/glib/deprecated/gthread.h
+++ b/glib/deprecated/gthread.h
@@ -171,7 +171,7 @@ struct _GStaticRecMutex
} unused;
};
-#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
+#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT, 0, { 0 } }
GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_init)
void g_static_rec_mutex_init (GStaticRecMutex *mutex);
--
2.19.1

View File

@ -1,35 +0,0 @@
From 821d28024bf2bc4287163f5001fb902820933e37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Mon, 5 Nov 2018 17:15:32 -0600
Subject: [PATCH 230/682] bookmarkfile: Don't move an item if the uri has not
changed
This was causing a crash, because we were first removing an item, freeing
both the instance itself and the key, and then trying to reuse those.
So, in this case, instead of reassigning an item, we can just return TRUE
as we have already the item at the right place, while it's not needed to
update the modified timestamp, since no modification happened in reality.
Fixes #1588
---
glib/gbookmarkfile.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/glib/gbookmarkfile.c b/glib/gbookmarkfile.c
index ffd7ea0b1..f75f261b1 100644
--- a/glib/gbookmarkfile.c
+++ b/glib/gbookmarkfile.c
@@ -3584,6 +3584,9 @@ g_bookmark_file_move_item (GBookmarkFile *bookmark,
if (new_uri && new_uri[0] != '\0')
{
+ if (g_strcmp0 (old_uri, new_uri) == 0)
+ return TRUE;
+
if (g_bookmark_file_has_item (bookmark, new_uri))
{
if (!g_bookmark_file_remove_item (bookmark, new_uri, error))
--
2.19.1

View File

@ -1,82 +0,0 @@
From 4ff3734ff5748cbc53f7b89c7148a4e3daba3230 Mon Sep 17 00:00:00 2001
From: Will Thompson <will@willthompson.co.uk>
Date: Mon, 26 Nov 2018 16:04:10 +0000
Subject: [PATCH 307/682] g_timeout_*_seconds: don't overflow for large
intervals
Previously, the `guint interval` parameter, measured in seconds, was
multiplied by 1000 and stored in another `guint` field. For intervals
greater than (G_MAXUINT / 1000) seconds, this would overflow; the
timeout would fire much sooner than intended.
Since GTimeoutSource already keeps track of whether it was created at
millisecond or second resolution, always store the passed interval
directly. We later convert the interval to microseconds, stored in a
gint64, so can move the `* 1000` to there.
The eagle-eyed reader might notice that there is no obvious guarantee
that the source's expiration time in microseconds won't overflow the
gint64, but I don't think this is a new problem. Previously, the
monotonic time would have to reach (2 ** 63 - 2 ** 32) microseconds for
this overflow to occur; now it would have to reach approximately (2 **
63 - 2 ** 42) microseconds. Both of these are 292.47 millennia to 5
significant figures.
Fixes #1600.
---
glib/gmain.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/glib/gmain.c b/glib/gmain.c
index 5e849b9ac..347882551 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -315,6 +315,7 @@ struct _GMainLoop
struct _GTimeoutSource
{
GSource source;
+ /* Measured in seconds if 'seconds' is TRUE, or milliseconds otherwise. */
guint interval;
gboolean seconds;
};
@@ -4615,8 +4616,6 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source,
{
gint64 expiration;
- expiration = current_time + (guint64) timeout_source->interval * 1000;
-
if (timeout_source->seconds)
{
gint64 remainder;
@@ -4638,6 +4637,8 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source,
timer_perturb = 0;
}
+ expiration = current_time + (guint64) timeout_source->interval * 1000 * 1000;
+
/* We want the microseconds part of the timeout to land on the
* 'timer_perturb' mark, but we need to make sure we don't try to
* set the timeout in the past. We do this by ensuring that we
@@ -4653,6 +4654,10 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source,
expiration -= remainder;
expiration += timer_perturb;
}
+ else
+ {
+ expiration = current_time + (guint64) timeout_source->interval * 1000;
+ }
g_source_set_ready_time ((GSource *) timeout_source, expiration);
}
@@ -4735,7 +4740,7 @@ g_timeout_source_new_seconds (guint interval)
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
- timeout_source->interval = 1000 * interval;
+ timeout_source->interval = interval;
timeout_source->seconds = TRUE;
g_timeout_set_expiration (timeout_source, g_get_monotonic_time ());
--
2.19.1

View File

@ -1,125 +0,0 @@
From ff76f6920e36f5befff270ba318bc612d1585839 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Wed, 27 Feb 2019 10:26:47 +0000
Subject: [PATCH 638/682] gbase64: Allow g_base64_encode (NULL, 0) and
g_base64_decode ("", *)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Relax a precondition in g_base64_encode_step() to allow this. Its valid
to base64 encode an empty string, as per RFC 4648.
Similarly for g_base64_decode(), although calling it with a NULL string
has never been allowed. Instead, clarify the case of calling it with an
empty string.
This includes a unit test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1698
---
glib/gbase64.c | 8 ++++----
glib/tests/base64.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/glib/gbase64.c b/glib/gbase64.c
index d3416e310..baddae098 100644
--- a/glib/gbase64.c
+++ b/glib/gbase64.c
@@ -100,7 +100,7 @@ g_base64_encode_step (const guchar *in,
char *outptr;
const guchar *inptr;
- g_return_val_if_fail (in != NULL, 0);
+ g_return_val_if_fail (in != NULL || len == 0, 0);
g_return_val_if_fail (out != NULL, 0);
g_return_val_if_fail (state != NULL, 0);
g_return_val_if_fail (save != NULL, 0);
@@ -244,7 +244,7 @@ g_base64_encode_close (gboolean break_lines,
/**
* g_base64_encode:
- * @data: (array length=len) (element-type guint8): the binary data to encode
+ * @data: (array length=len) (element-type guint8) (nullable): the binary data to encode
* @len: the length of @data
*
* Encode a sequence of binary data into its Base-64 stringified
@@ -334,7 +334,7 @@ g_base64_decode_step (const gchar *in,
unsigned int v;
int i;
- g_return_val_if_fail (in != NULL, 0);
+ g_return_val_if_fail (in != NULL || len == 0, 0);
g_return_val_if_fail (out != NULL, 0);
g_return_val_if_fail (state != NULL, 0);
g_return_val_if_fail (save != NULL, 0);
@@ -390,7 +390,7 @@ g_base64_decode_step (const gchar *in,
/**
* g_base64_decode:
- * @text: zero-terminated string with base64 text to decode
+ * @text: (not nullable): zero-terminated string with base64 text to decode
* @out_len: (out): The length of the decoded data is written here
*
* Decode a sequence of Base-64 encoded text into binary data. Note
diff --git a/glib/tests/base64.c b/glib/tests/base64.c
index 86875a29b..6091d1eed 100644
--- a/glib/tests/base64.c
+++ b/glib/tests/base64.c
@@ -406,6 +406,42 @@ test_base64_decode_smallblock (gconstpointer blocksize_p)
}
}
+/* Test that calling g_base64_encode (NULL, 0) returns correct output. This is
+ * as per the first test vector in RFC 4648 §10.
+ * https://tools.ietf.org/html/rfc4648#section-10 */
+static void
+test_base64_encode_empty (void)
+{
+ gchar *encoded = NULL;
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1698");
+
+ encoded = g_base64_encode (NULL, 0);
+ g_assert_cmpstr (encoded, ==, "");
+ g_free (encoded);
+
+ encoded = g_base64_encode ((const guchar *) "", 0);
+ g_assert_cmpstr (encoded, ==, "");
+ g_free (encoded);
+}
+
+/* Test that calling g_base64_decode ("", *) returns correct output. This is
+ * as per the first test vector in RFC 4648 §10. Note that calling
+ * g_base64_decode (NULL, *) is not allowed.
+ * https://tools.ietf.org/html/rfc4648#section-10 */
+static void
+test_base64_decode_empty (void)
+{
+ guchar *decoded = NULL;
+ gsize decoded_len;
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1698");
+
+ decoded = g_base64_decode ("", &decoded_len);
+ g_assert_cmpstr ((gchar *) decoded, ==, "");
+ g_assert_cmpuint (decoded_len, ==, 0);
+ g_free (decoded);
+}
int
main (int argc, char *argv[])
@@ -455,5 +491,8 @@ main (int argc, char *argv[])
g_test_add_data_func ("/base64/incremental/smallblock/4", GINT_TO_POINTER(4),
test_base64_decode_smallblock);
+ g_test_add_func ("/base64/encode/empty", test_base64_encode_empty);
+ g_test_add_func ("/base64/decode/empty", test_base64_decode_empty);
+
return g_test_run ();
}
--
2.19.1

View File

@ -1,40 +0,0 @@
From f9dfddf8eb4952fc5e0a77fffeff70c7cea37b68 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Wed, 27 Feb 2019 10:27:43 +0000
Subject: [PATCH 639/682] gbase64: Fix an impossible condition
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
len is unsigned, so its not possible for it to be less than zero.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gbase64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/glib/gbase64.c b/glib/gbase64.c
index baddae098..ef6a39832 100644
--- a/glib/gbase64.c
+++ b/glib/gbase64.c
@@ -105,7 +105,7 @@ g_base64_encode_step (const guchar *in,
g_return_val_if_fail (state != NULL, 0);
g_return_val_if_fail (save != NULL, 0);
- if (len <= 0)
+ if (len == 0)
return 0;
inptr = in;
@@ -339,7 +339,7 @@ g_base64_decode_step (const gchar *in,
g_return_val_if_fail (state != NULL, 0);
g_return_val_if_fail (save != NULL, 0);
- if (len <= 0)
+ if (len == 0)
return 0;
inend = (const guchar *)in+len;
--
2.19.1

View File

@ -1,135 +0,0 @@
From ba18822f358c49f15435197dba7c11f6753396f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Tue, 30 Oct 2018 00:00:00 +0000
Subject: [PATCH 258/682] gdate: Use longest matching month name in
g_date_set_parse
There are languages where a name of one month is a substring of another.
Instead of stopping search on the first match use the month that
constitutes the longest match.
Fixes #1343.
---
glib/gdate.c | 75 ++++++++++++++++++++---------------------------
glib/tests/date.c | 34 +++++++++++++++++++++
2 files changed, 65 insertions(+), 44 deletions(-)
diff --git a/glib/gdate.c b/glib/gdate.c
index 4925818b3..5457a3b8c 100644
--- a/glib/gdate.c
+++ b/glib/gdate.c
@@ -931,6 +931,27 @@ struct _GDateParseTokens {
typedef struct _GDateParseTokens GDateParseTokens;
+static inline gboolean
+update_month_match (gsize *longest,
+ const gchar *haystack,
+ const gchar *needle)
+{
+ gsize length;
+
+ if (needle == NULL)
+ return FALSE;
+
+ length = strlen (needle);
+ if (*longest >= length)
+ return FALSE;
+
+ if (strstr (haystack, needle) == NULL)
+ return FALSE;
+
+ *longest = length;
+ return TRUE;
+}
+
#define NUM_LEN 10
/* HOLDS: g_date_global_lock */
@@ -978,6 +999,7 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
if (pt->num_ints < 3)
{
+ gsize longest = 0;
gchar *casefold;
gchar *normalized;
@@ -985,8 +1007,7 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
normalized = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL);
g_free (casefold);
- i = 1;
- while (i < 13)
+ for (i = 1; i < 13; ++i)
{
/* Here month names may be in a genitive case if the language
* grammatical rules require it.
@@ -997,60 +1018,26 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
* genitive case here so they use nominative everywhere.
* For example, English always uses "January".
*/
- if (long_month_names[i] != NULL)
- {
- const gchar *found = strstr (normalized, long_month_names[i]);
-
- if (found != NULL)
- {
- pt->month = i;
- break;
- }
- }
+ if (update_month_match (&longest, normalized, long_month_names[i]))
+ pt->month = i;
/* Here month names will be in a nominative case.
* Examples of how January may look in some languages:
* Catalan: "gener", Croatian: "Siječanj", Polish: "styczeń",
* Upper Sorbian: "Januar".
*/
- if (long_month_names_alternative[i] != NULL)
- {
- const gchar *found = strstr (normalized, long_month_names_alternative[i]);
-
- if (found != NULL)
- {
- pt->month = i;
- break;
- }
- }
+ if (update_month_match (&longest, normalized, long_month_names_alternative[i]))
+ pt->month = i;
/* Differences between abbreviated nominative and abbreviated
* genitive month names are visible in very few languages but
* let's handle them.
*/
- if (short_month_names[i] != NULL)
- {
- const gchar *found = strstr (normalized, short_month_names[i]);
-
- if (found != NULL)
- {
- pt->month = i;
- break;
- }
- }
+ if (update_month_match (&longest, normalized, short_month_names[i]))
+ pt->month = i;
- if (short_month_names_alternative[i] != NULL)
- {
- const gchar *found = strstr (normalized, short_month_names_alternative[i]);
-
- if (found != NULL)
- {
- pt->month = i;
- break;
- }
- }
-
- ++i;
+ if (update_month_match (&longest, normalized, short_month_names_alternative[i]))
+ pt->month = i;
}
g_free (normalized);

View File

@ -1,104 +0,0 @@
From 54c394a73f95eb225fd748aef9a7205d45ff16fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Wed, 31 Oct 2018 00:00:00 +0000
Subject: [PATCH 205/682] gdatetime: Fix formatting of time zones offsets in
range -01:00 to +00:00
Formatting code for `%z` specifier incorrectly assumed that sign of
offset from UTC can be recovered from the number of hours alone, which
is not true for offsets between -01:00 and +00:00.
Extract and format sign separately to avoid the problem.
Issue #1337.
---
glib/gdatetime.c | 17 +++++++++++------
glib/tests/gdatetime.c | 22 ++++++++++++++++++++++
2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index 1bd916587..32fd501aa 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -2721,34 +2721,39 @@ format_z (GString *outstr,
gint hours;
gint minutes;
gint seconds;
+ gchar sign = offset >= 0 ? '+' : '-';
+ offset = ABS (offset);
hours = offset / 3600;
- minutes = ABS (offset) / 60 % 60;
- seconds = ABS (offset) % 60;
+ minutes = offset / 60 % 60;
+ seconds = offset % 60;
switch (colons)
{
case 0:
- g_string_append_printf (outstr, "%+03d%02d",
+ g_string_append_printf (outstr, "%c%02d%02d",
+ sign,
hours,
minutes);
break;
case 1:
- g_string_append_printf (outstr, "%+03d:%02d",
+ g_string_append_printf (outstr, "%c%02d:%02d",
+ sign,
hours,
minutes);
break;
case 2:
- g_string_append_printf (outstr, "%+03d:%02d:%02d",
+ g_string_append_printf (outstr, "%c%02d:%02d:%02d",
+ sign,
hours,
minutes,
seconds);
break;
case 3:
- g_string_append_printf (outstr, "%+03d", hours);
+ g_string_append_printf (outstr, "%c%02d", sign, hours);
if (minutes != 0 || seconds != 0)
{
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index a028f6d20..f4000d96c 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -1986,6 +1986,28 @@ test_z (void)
g_free (p);
g_date_time_unref (dt);
g_time_zone_unref (tz);
+
+ tz = g_time_zone_new ("-00:15");
+ dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0);
+
+ p = g_date_time_format (dt, "%z");
+ g_assert_cmpstr (p, ==, "-0015");
+ g_free (p);
+
+ p = g_date_time_format (dt, "%:z");
+ g_assert_cmpstr (p, ==, "-00:15");
+ g_free (p);
+
+ p = g_date_time_format (dt, "%::z");
+ g_assert_cmpstr (p, ==, "-00:15:00");
+ g_free (p);
+
+ p = g_date_time_format (dt, "%:::z");
+ g_assert_cmpstr (p, ==, "-00:15");
+ g_free (p);
+
+ g_date_time_unref (dt);
+ g_time_zone_unref (tz);
}
#pragma GCC diagnostic push
--
2.19.1

View File

@ -1,568 +0,0 @@
From bc59892b1af2a8f4374a1ad2054ff9444151732b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Fri, 30 Nov 2018 00:00:00 +0000
Subject: [PATCH 320/682] gdatetime: Store intermediate result of
g_date_time_format in UTF-8
In date time formatting routine, instead of converting from UTF-8 to
locale charset and then from locale charset to UTF-8, store all
intermediate result in UTF-8.
This solves the issue where user provided UTF-8 format string might be
unrepresentable in the current locale charset.
Fixes issue #1605.
---
glib/gdatetime.c | 320 +++++++++++++++++++++--------------------
glib/tests/gdatetime.c | 18 +++
2 files changed, 179 insertions(+), 159 deletions(-)
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index 32fd501aa..6afe14438 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -4,6 +4,7 @@
* Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
* Copyright (C) 2010 Emmanuele Bassi <ebassi@linux.intel.com>
* Copyright © 2010 Codethink Limited
+ * Copyright © 2018 Tomasz Miąsko
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
@@ -2771,6 +2772,51 @@ format_z (GString *outstr,
return TRUE;
}
+#ifdef HAVE_LANGINFO_OUTDIGIT
+/** Initializes the array with UTF-8 encoded alternate digits suibtable for use
+ * in current locale. Returns NULL when current locale does not use alternate
+ * digits or there was an error converting them to UTF-8.
+ */
+static const gchar * const *
+initialize_alt_digits (void)
+{
+ guint i;
+ gsize digit_len;
+ gchar *digit;
+ const gchar *locale_digit;
+#define N_DIGITS 10
+#define MAX_UTF8_ENCODING_LEN 4
+ static gchar buffer[N_DIGITS * (MAX_UTF8_ENCODING_LEN + 1 /* null separator */)];
+#undef N_DIGITS
+#undef MAX_UTF8_ENCODING_LEN
+ gchar *buffer_end = buffer;
+ static const gchar *alt_digits[10];
+
+ for (i = 0; i != 10; ++i)
+ {
+ locale_digit = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB + i);
+
+ if (g_strcmp0 (locale_digit, "") == 0)
+ return NULL;
+
+ digit = g_locale_to_utf8 (locale_digit, -1, NULL, &digit_len, NULL);
+ if (digit == NULL)
+ return NULL;
+
+ g_assert (digit_len < buffer + sizeof (buffer) - buffer_end);
+
+ alt_digits[i] = buffer_end;
+ buffer_end = g_stpcpy (buffer_end, digit);
+ /* skip trailing null byte */
+ buffer_end += 1;
+
+ g_free (digit);
+ }
+
+ return alt_digits;
+}
+#endif /* HAVE_LANGINFO_OUTDIGIT */
+
static void
format_number (GString *str,
gboolean use_alt_digits,
@@ -2781,7 +2827,7 @@ format_number (GString *str,
const gchar *ascii_digits[10] = {
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
};
- const gchar **digits = ascii_digits;
+ const gchar * const *digits = ascii_digits;
const gchar *tmp[10];
gint i = 0;
@@ -2790,17 +2836,16 @@ format_number (GString *str,
#ifdef HAVE_LANGINFO_OUTDIGIT
if (use_alt_digits)
{
- static const gchar *alt_digits[10];
+ static const gchar * const *alt_digits = NULL;
static gsize initialised;
- /* 2^32 has 10 digits */
if G_UNLIKELY (g_once_init_enter (&initialised))
{
-#define DO_DIGIT(n) \
- alt_digits[n] = nl_langinfo (_NL_CTYPE_OUTDIGIT## n ##_MB)
- DO_DIGIT(0); DO_DIGIT(1); DO_DIGIT(2); DO_DIGIT(3); DO_DIGIT(4);
- DO_DIGIT(5); DO_DIGIT(6); DO_DIGIT(7); DO_DIGIT(8); DO_DIGIT(9);
-#undef DO_DIGIT
+ alt_digits = initialize_alt_digits ();
+
+ if (alt_digits == NULL)
+ alt_digits = ascii_digits;
+
g_once_init_leave (&initialised, TRUE);
}
@@ -2833,7 +2878,6 @@ format_ampm (GDateTime *datetime,
{
const gchar *ampm;
gchar *tmp = NULL, *ampm_dup;
- gsize len;
ampm = GET_AMPM (datetime);
@@ -2844,104 +2888,107 @@ format_ampm (GDateTime *datetime,
{
/* This assumes that locale encoding can't have embedded NULs */
ampm = tmp = g_locale_to_utf8 (ampm, -1, NULL, NULL, NULL);
- if (!tmp)
+ if (tmp == NULL)
return FALSE;
}
if (uppercase)
ampm_dup = g_utf8_strup (ampm, -1);
else
ampm_dup = g_utf8_strdown (ampm, -1);
- len = strlen (ampm_dup);
- if (!locale_is_utf8 && GET_AMPM_IS_LOCALE)
- {
- g_free (tmp);
- tmp = g_locale_from_utf8 (ampm_dup, -1, NULL, &len, NULL);
- g_free (ampm_dup);
- if (!tmp)
- return FALSE;
- ampm_dup = tmp;
- }
- g_string_append_len (outstr, ampm_dup, len);
+ g_free (tmp);
+
+ g_string_append (outstr, ampm_dup);
g_free (ampm_dup);
return TRUE;
}
-static gboolean g_date_time_format_locale (GDateTime *datetime,
- const gchar *format,
- GString *outstr,
- gboolean locale_is_utf8);
+static gboolean g_date_time_format_utf8 (GDateTime *datetime,
+ const gchar *format,
+ GString *outstr,
+ gboolean locale_is_utf8);
/* g_date_time_format() subroutine that takes a locale-encoded format
- * string and produces a locale-encoded date/time string.
+ * string and produces a UTF-8 encoded date/time string.
*/
static gboolean
-g_date_time_locale_format_locale (GDateTime *datetime,
- const gchar *format,
- GString *outstr,
- gboolean locale_is_utf8)
+g_date_time_format_locale (GDateTime *datetime,
+ const gchar *locale_format,
+ GString *outstr,
+ gboolean locale_is_utf8)
{
gchar *utf8_format;
gboolean success;
if (locale_is_utf8)
- return g_date_time_format_locale (datetime, format, outstr,
- locale_is_utf8);
+ return g_date_time_format_utf8 (datetime, locale_format, outstr, locale_is_utf8);
- utf8_format = g_locale_to_utf8 (format, -1, NULL, NULL, NULL);
- if (!utf8_format)
+ utf8_format = g_locale_to_utf8 (locale_format, -1, NULL, NULL, NULL);
+ if (utf8_format == NULL)
return FALSE;
- success = g_date_time_format_locale (datetime, utf8_format, outstr,
- locale_is_utf8);
+ success = g_date_time_format_utf8 (datetime, utf8_format, outstr,
+ locale_is_utf8);
g_free (utf8_format);
return success;
}
-/* g_date_time_format() subroutine that takes a UTF-8 format
- * string and produces a locale-encoded date/time string.
+static inline gboolean
+string_append (GString *string,
+ const gchar *s,
+ gboolean s_is_utf8)
+{
+ gchar *utf8;
+ gsize utf8_len;
+
+ if (s_is_utf8)
+ {
+ g_string_append (string, s);
+ }
+ else
+ {
+ utf8 = g_locale_to_utf8 (s, -1, NULL, &utf8_len, NULL);
+ if (utf8 == NULL)
+ return FALSE;
+ g_string_append_len (string, utf8, utf8_len);
+ g_free (utf8);
+ }
+
+ return TRUE;
+}
+
+/* g_date_time_format() subroutine that takes a UTF-8 encoded format
+ * string and produces a UTF-8 encoded date/time string.
*/
static gboolean
-g_date_time_format_locale (GDateTime *datetime,
- const gchar *format,
- GString *outstr,
- gboolean locale_is_utf8)
+g_date_time_format_utf8 (GDateTime *datetime,
+ const gchar *utf8_format,
+ GString *outstr,
+ gboolean locale_is_utf8)
{
guint len;
guint colons;
- gchar *tmp;
- gsize tmp_len;
gunichar c;
gboolean alt_digits = FALSE;
gboolean pad_set = FALSE;
+ gboolean name_is_utf8;
const gchar *pad = "";
const gchar *name;
const gchar *tz;
- while (*format)
+ while (*utf8_format)
{
- len = strcspn (format, "%");
+ len = strcspn (utf8_format, "%");
if (len)
- {
- if (locale_is_utf8)
- g_string_append_len (outstr, format, len);
- else
- {
- tmp = g_locale_from_utf8 (format, len, NULL, &tmp_len, NULL);
- if (!tmp)
- return FALSE;
- g_string_append_len (outstr, tmp, tmp_len);
- g_free (tmp);
- }
- }
+ g_string_append_len (outstr, utf8_format, len);
- format += len;
- if (!*format)
+ utf8_format += len;
+ if (!*utf8_format)
break;
- g_assert (*format == '%');
- format++;
- if (!*format)
+ g_assert (*utf8_format == '%');
+ utf8_format++;
+ if (!*utf8_format)
break;
colons = 0;
@@ -2949,91 +2996,67 @@ g_date_time_format_locale (GDateTime *datetime,
pad_set = FALSE;
next_mod:
- c = g_utf8_get_char (format);
- format = g_utf8_next_char (format);
+ c = g_utf8_get_char (utf8_format);
+ utf8_format = g_utf8_next_char (utf8_format);
switch (c)
{
case 'a':
name = WEEKDAY_ABBR (datetime);
if (g_strcmp0 (name, "") == 0)
return FALSE;
- if (!locale_is_utf8 && !WEEKDAY_ABBR_IS_LOCALE)
- {
- tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
- if (!tmp)
- return FALSE;
- g_string_append_len (outstr, tmp, tmp_len);
- g_free (tmp);
- }
- else
- {
- g_string_append (outstr, name);
- }
+
+ name_is_utf8 = locale_is_utf8 || !WEEKDAY_ABBR_IS_LOCALE;
+
+ if (!string_append (outstr, name, name_is_utf8))
+ return FALSE;
+
break;
case 'A':
name = WEEKDAY_FULL (datetime);
if (g_strcmp0 (name, "") == 0)
return FALSE;
- if (!locale_is_utf8 && !WEEKDAY_FULL_IS_LOCALE)
- {
- tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
- if (!tmp)
- return FALSE;
- g_string_append_len (outstr, tmp, tmp_len);
- g_free (tmp);
- }
- else
- {
- g_string_append (outstr, name);
- }
+
+ name_is_utf8 = locale_is_utf8 || !WEEKDAY_FULL_IS_LOCALE;
+
+ if (!string_append (outstr, name, name_is_utf8))
+ return FALSE;
+
break;
case 'b':
name = alt_digits ? MONTH_ABBR_STANDALONE (datetime)
: MONTH_ABBR_WITH_DAY (datetime);
if (g_strcmp0 (name, "") == 0)
return FALSE;
- if (!locale_is_utf8 &&
- ((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) ||
- (!alt_digits && !MONTH_ABBR_WITH_DAY_IS_LOCALE)))
- {
- tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
- if (!tmp)
- return FALSE;
- g_string_append_len (outstr, tmp, tmp_len);
- g_free (tmp);
- }
- else
- {
- g_string_append (outstr, name);
- }
+
+ name_is_utf8 = locale_is_utf8 ||
+ ((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) ||
+ (!alt_digits && !MONTH_ABBR_WITH_DAY_IS_LOCALE));
+
+ if (!string_append (outstr, name, name_is_utf8))
+ return FALSE;
+
break;
case 'B':
name = alt_digits ? MONTH_FULL_STANDALONE (datetime)
: MONTH_FULL_WITH_DAY (datetime);
if (g_strcmp0 (name, "") == 0)
return FALSE;
- if (!locale_is_utf8 &&
- ((alt_digits && !MONTH_FULL_STANDALONE_IS_LOCALE) ||
- (!alt_digits && !MONTH_FULL_WITH_DAY_IS_LOCALE)))
- {
- tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
- if (!tmp)
- return FALSE;
- g_string_append_len (outstr, tmp, tmp_len);
- g_free (tmp);
- }
- else
- {
- g_string_append (outstr, name);
- }
+
+ name_is_utf8 = locale_is_utf8 ||
+ ((alt_digits && !MONTH_FULL_STANDALONE_IS_LOCALE) ||
+ (!alt_digits && !MONTH_FULL_WITH_DAY_IS_LOCALE));
+
+ if (!string_append (outstr, name, name_is_utf8))
+ return FALSE;
+
break;
case 'c':
{
if (g_strcmp0 (PREFERRED_DATE_TIME_FMT, "") == 0)
return FALSE;
- if (!g_date_time_locale_format_locale (datetime, PREFERRED_DATE_TIME_FMT,
- outstr, locale_is_utf8))
- return FALSE;
+ if (!g_date_time_format_locale (datetime, PREFERRED_DATE_TIME_FMT,
+ outstr, locale_is_utf8))
+ return FALSE;
}
break;
case 'C':
@@ -3067,20 +3090,14 @@ g_date_time_format_locale (GDateTime *datetime,
: MONTH_ABBR_WITH_DAY (datetime);
if (g_strcmp0 (name, "") == 0)
return FALSE;
- if (!locale_is_utf8 &&
- ((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) ||
- (!alt_digits && !MONTH_ABBR_WITH_DAY_IS_LOCALE)))
- {
- tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
- if (!tmp)
- return FALSE;
- g_string_append_len (outstr, tmp, tmp_len);
- g_free (tmp);
- }
- else
- {
- g_string_append (outstr, name);
- }
+
+ name_is_utf8 = locale_is_utf8 ||
+ ((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) ||
+ (!alt_digits && !MONTH_ABBR_WITH_DAY_IS_LOCALE));
+
+ if (!string_append (outstr, name, name_is_utf8))
+ return FALSE;
+
break;
case 'H':
format_number (outstr, alt_digits, pad_set ? pad : "0", 2,
@@ -3128,8 +3145,8 @@ g_date_time_format_locale (GDateTime *datetime,
{
if (g_strcmp0 (PREFERRED_12HR_TIME_FMT, "") == 0)
return FALSE;
- if (!g_date_time_locale_format_locale (datetime, PREFERRED_12HR_TIME_FMT,
- outstr, locale_is_utf8))
+ if (!g_date_time_format_locale (datetime, PREFERRED_12HR_TIME_FMT,
+ outstr, locale_is_utf8))
return FALSE;
}
break;
@@ -3170,8 +3187,8 @@ g_date_time_format_locale (GDateTime *datetime,
{
if (g_strcmp0 (PREFERRED_DATE_FMT, "") == 0)
return FALSE;
- if (!g_date_time_locale_format_locale (datetime, PREFERRED_DATE_FMT,
- outstr, locale_is_utf8))
+ if (!g_date_time_format_locale (datetime, PREFERRED_DATE_FMT,
+ outstr, locale_is_utf8))
return FALSE;
}
break;
@@ -3179,8 +3196,8 @@ g_date_time_format_locale (GDateTime *datetime,
{
if (g_strcmp0 (PREFERRED_TIME_FMT, "") == 0)
return FALSE;
- if (!g_date_time_locale_format_locale (datetime, PREFERRED_TIME_FMT,
- outstr, locale_is_utf8))
+ if (!g_date_time_format_locale (datetime, PREFERRED_TIME_FMT,
+ outstr, locale_is_utf8))
return FALSE;
}
break;
@@ -3202,16 +3219,7 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'Z':
tz = g_date_time_get_timezone_abbreviation (datetime);
- tmp = NULL;
- tmp_len = strlen (tz);
- if (!locale_is_utf8)
- {
- tz = tmp = g_locale_from_utf8 (tz, -1, NULL, &tmp_len, NULL);
- if (!tmp)
- return FALSE;
- }
- g_string_append_len (outstr, tz, tmp_len);
- g_free (tmp);
+ g_string_append (outstr, tz);
break;
case '%':
g_string_append_c (outstr, '%');
@@ -3230,7 +3238,7 @@ g_date_time_format_locale (GDateTime *datetime,
goto next_mod;
case ':':
/* Colons are only allowed before 'z' */
- if (*format && *format != 'z' && *format != ':')
+ if (*utf8_format && *utf8_format != 'z' && *utf8_format != ':')
return FALSE;
colons++;
goto next_mod;
@@ -3355,7 +3363,6 @@ g_date_time_format (GDateTime *datetime,
const gchar *format)
{
GString *outstr;
- gchar *utf8;
gboolean locale_is_utf8 = g_get_charset (NULL);
g_return_val_if_fail (datetime != NULL, NULL);
@@ -3364,18 +3371,13 @@ g_date_time_format (GDateTime *datetime,
outstr = g_string_sized_new (strlen (format) * 2);
- if (!g_date_time_format_locale (datetime, format, outstr, locale_is_utf8))
+ if (!g_date_time_format_utf8 (datetime, format, outstr, locale_is_utf8))
{
g_string_free (outstr, TRUE);
return NULL;
}
- if (locale_is_utf8)
- return g_string_free (outstr, FALSE);
-
- utf8 = g_locale_to_utf8 (outstr->str, outstr->len, NULL, NULL, NULL);
- g_string_free (outstr, TRUE);
- return utf8;
+ return g_string_free (outstr, FALSE);
}
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index 09f84cb21..1a46cf55a 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -1525,6 +1525,23 @@ test_non_utf8_printf (void)
g_free (oldlocale);
}
+/* Checks that it is possible to use format string that
+ * is unrepresentable in current locale charset. */
+static void
+test_format_unrepresentable (void)
+{
+ gchar *oldlocale = g_strdup (setlocale (LC_ALL, NULL));
+ setlocale (LC_ALL, "POSIX");
+
+ TEST_PRINTF ("ąśćł", "ąśćł");
+
+ /* We are using Unicode ratio symbol here, which is outside ASCII. */
+ TEST_PRINTF_TIME (23, 15, 0, "%H%M", "2315");
+
+ setlocale (LC_ALL, oldlocale);
+ g_free (oldlocale);
+}
+
static void
test_modifiers (void)
{
@@ -2493,6 +2510,7 @@ main (gint argc,
g_test_add_func ("/GDateTime/now", test_GDateTime_now);
g_test_add_func ("/GDateTime/printf", test_GDateTime_printf);
g_test_add_func ("/GDateTime/non_utf8_printf", test_non_utf8_printf);
+ g_test_add_func ("/GDateTime/format_unrepresentable", test_format_unrepresentable);
g_test_add_func ("/GDateTime/strftime", test_strftime);
g_test_add_func ("/GDateTime/strftime/error_handling", test_GDateTime_strftime_error_handling);
g_test_add_func ("/GDateTime/modifiers", test_modifiers);
--
2.19.1

View File

@ -1,71 +0,0 @@
From 566e1d61a500267c7849ad0b2552feec9c9a29a6 Mon Sep 17 00:00:00 2001
From: Ernestas Kulik <ekulik@redhat.com>
Date: Tue, 29 Jan 2019 09:50:46 +0100
Subject: [PATCH 539/682] gdbus: Avoid printing null strings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This mostly affects the 2.56 branch, but, given that GCC 9 is being
stricter about passing null string pointers to printf-like functions, it
might make sense to proactively fix such calls.
gdbusauth.c: In function '_g_dbus_auth_run_server':
gdbusauth.c:1302:11: error: '%s' directive argument is null
[-Werror=format-overflow=]
1302 | debug_print ("SERVER: WaitingForBegin, read '%s'",
line);
|
gdbusmessage.c: In function g_dbus_message_to_blob:
gdbusmessage.c:2730:30: error: %s directive argument is null [-Werror=format-overflow=]
2730 | tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
|
---
gio/gdbusauth.c | 2 +-
gio/gdbusmessage.c | 5 ++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
index 1f8ea8057..752ec23fc 100644
--- a/gio/gdbusauth.c
+++ b/gio/gdbusauth.c
@@ -1272,9 +1272,9 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
&line_length,
cancellable,
error);
- debug_print ("SERVER: WaitingForBegin, read '%s'", line);
if (line == NULL)
goto out;
+ debug_print ("SERVER: WaitingForBegin, read '%s'", line);
if (g_strcmp0 (line, "BEGIN") == 0)
{
/* YAY, done! */
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index 3221b925d..3a1a1f9e9 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -2731,7 +2731,6 @@ g_dbus_message_to_blob (GDBusMessage *message,
if (message->body != NULL)
{
gchar *tupled_signature_str;
- tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
if (signature == NULL)
{
g_set_error (error,
@@ -2739,10 +2738,10 @@ g_dbus_message_to_blob (GDBusMessage *message,
G_IO_ERROR_INVALID_ARGUMENT,
_("Message body has signature “%s” but there is no signature header"),
signature_str);
- g_free (tupled_signature_str);
goto out;
}
- else if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->body)) != 0)
+ tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
+ if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->body)) != 0)
{
g_set_error (error,
G_IO_ERROR,
--
2.19.1

View File

@ -1,43 +0,0 @@
From 067992f8dedd11651e624921129cd0ffb099180f Mon Sep 17 00:00:00 2001
From: Christoph Reiter <creiter@src.gnome.org>
Date: Thu, 14 Feb 2019 04:16:18 +0100
Subject: [PATCH 605/682] gdbus: Fix a potential use-after-free on connection
close. Fixes #1686
512e9b3b34d added a call to schedule_pending_close() in the read
callback after the reference to the worker is already gone. In case this was
the last reference to the worker this resulted in a use-after-free.
6f3d57d2ee2 made this more likely to happen because on connection close
the worker cancel action is now async while the reference to the worker
gets dropped right away.
Move the call to schedule_pending_close() before the unref.
Fixes #1686
---
gio/gdbusprivate.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c
index c2a04ae12..1e8e1d64b 100644
--- a/gio/gdbusprivate.c
+++ b/gio/gdbusprivate.c
@@ -809,11 +809,11 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
out:
g_mutex_unlock (&worker->read_lock);
- /* gives up the reference acquired when calling g_input_stream_read_async() */
- _g_dbus_worker_unref (worker);
-
/* check if there is any pending close */
schedule_pending_close (worker);
+
+ /* gives up the reference acquired when calling g_input_stream_read_async() */
+ _g_dbus_worker_unref (worker);
}
/* called in private thread shared by all GDBusConnection instances (with read-lock held) */
--
2.19.1

View File

@ -1,99 +0,0 @@
From faa3c319ba4021372a3bcc1829f357007419124e Mon Sep 17 00:00:00 2001
From: Will Thompson <will@willthompson.co.uk>
Date: Wed, 5 Dec 2018 21:32:05 +0000
Subject: [PATCH 331/682] gdbus-codegen: make --interface-info-{header,body}
not crash
Since 1217b1bc4f242c14d6eabbee0c688c320eab2e4d, LICENSE_STR has taken two
parameters, not one. Without this change, running either mode fails
with a traceback like:
Traceback (most recent call last):
File "../gdbus-codegen", line 55, in <module>
sys.exit(codegen_main.codegen_main())
File ".../codegen_main.py", line 294, in codegen_main
gen.generate()
File ".../codegen.py", line 896, in generate
self.generate_body_preamble()
File ".../codegen.py", line 682, in generate_body_preamble
self.outfile.write(LICENSE_STR.format(config.VERSION))
IndexError: tuple index out of range
8916874ee6f3ff0f887dbe1eda55c23c2c0097ee, which introduced these flags,
was actually merged after that commit, but I assume it was written
beforehand.
---
gio/gdbus-2.0/codegen/codegen.py | 12 ++++++++----
gio/gdbus-2.0/codegen/codegen_main.py | 2 ++
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py
index 9d2b904c7..9220176a8 100644
--- a/gio/gdbus-2.0/codegen/codegen.py
+++ b/gio/gdbus-2.0/codegen/codegen.py
@@ -619,17 +619,19 @@ class HeaderCodeGenerator:
# ----------------------------------------------------------------------------------------------------
class InterfaceInfoHeaderCodeGenerator:
- def __init__(self, ifaces, namespace, header_name, use_pragma, outfile):
+ def __init__(self, ifaces, namespace, header_name, input_files_basenames, use_pragma, outfile):
self.ifaces = ifaces
self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
self.header_guard = header_name.upper().replace('.', '_').replace('-', '_').replace('/', '_').replace(':', '_')
+ self.input_files_basenames = input_files_basenames
self.use_pragma = use_pragma
self.outfile = outfile
# ----------------------------------------------------------------------------------------------------
def generate_header_preamble(self):
- self.outfile.write(LICENSE_STR.format(config.VERSION))
+ basenames = ', '.join(self.input_files_basenames)
+ self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
self.outfile.write('\n')
if self.use_pragma:
@@ -670,16 +672,18 @@ class InterfaceInfoHeaderCodeGenerator:
# ----------------------------------------------------------------------------------------------------
class InterfaceInfoBodyCodeGenerator:
- def __init__(self, ifaces, namespace, header_name, outfile):
+ def __init__(self, ifaces, namespace, header_name, input_files_basenames, outfile):
self.ifaces = ifaces
self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace)
self.header_name = header_name
+ self.input_files_basenames = input_files_basenames
self.outfile = outfile
# ----------------------------------------------------------------------------------------------------
def generate_body_preamble(self):
- self.outfile.write(LICENSE_STR.format(config.VERSION))
+ basenames = ', '.join(self.input_files_basenames)
+ self.outfile.write(LICENSE_STR.format(config.VERSION, basenames))
self.outfile.write('\n')
self.outfile.write('#ifdef HAVE_CONFIG_H\n'
'# include "config.h"\n'
diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py
index 03de1d107..880ff3932 100644
--- a/gio/gdbus-2.0/codegen/codegen_main.py
+++ b/gio/gdbus-2.0/codegen/codegen_main.py
@@ -281,6 +281,7 @@ def codegen_main():
gen = codegen.InterfaceInfoHeaderCodeGenerator(all_ifaces,
args.c_namespace,
header_name,
+ input_files_basenames,
args.pragma_once,
outfile)
gen.generate()
@@ -290,6 +291,7 @@ def codegen_main():
gen = codegen.InterfaceInfoBodyCodeGenerator(all_ifaces,
args.c_namespace,
header_name,
+ input_files_basenames,
outfile)
gen.generate()
--
2.19.1

View File

@ -1,121 +0,0 @@
From 31b0ba18c190d2508ac4266e5e2e4cf167fada4c Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Mon, 28 Jan 2019 14:36:42 +0000
Subject: [PATCH 533/682] gdbusmessage: Fix check on upper limit of message
size
There was a typo in the figure checked against. Add a unit test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1642
---
gio/gdbusmessage.c | 2 +-
gio/tests/gdbus-message.c | 72 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index b9f32e921..3221b925d 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -1984,7 +1984,7 @@ g_dbus_message_bytes_needed (guchar *blob,
"Unable to determine message blob length - given blob is malformed");
}
- if (ret > (2<<27))
+ if (ret > (1<<27))
{
g_set_error (error,
G_IO_ERROR,
diff --git a/gio/tests/gdbus-message.c b/gio/tests/gdbus-message.c
index 278ccc474..5cb141d94 100644
--- a/gio/tests/gdbus-message.c
+++ b/gio/tests/gdbus-message.c
@@ -141,6 +141,74 @@ message_copy (void)
/* ---------------------------------------------------------------------------------------------------- */
+/* Test g_dbus_message_bytes_needed() returns correct results for a variety of
+ * arbitrary binary inputs.*/
+static void
+message_bytes_needed (void)
+{
+ const struct
+ {
+ const guint8 blob[16];
+ gssize expected_bytes_needed;
+ }
+ vectors[] =
+ {
+ /* Little endian with header rounding */
+ { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */
+ 50, 0, 0, 0, /* body length */
+ 1, 0, 0, 0, /* message serial */
+ 7, 0, 0, 0 /* header length */}, 74 },
+ /* Little endian without header rounding */
+ { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */
+ 50, 0, 0, 0, /* body length */
+ 1, 0, 0, 0, /* message serial */
+ 8, 0, 0, 0 /* header length */}, 74 },
+ /* Big endian with header rounding */
+ { { 'B', 0, 0, 1, /* endianness, message type, flags, protocol version */
+ 0, 0, 0, 50, /* body length */
+ 0, 0, 0, 1, /* message serial */
+ 0, 0, 0, 7 /* header length */}, 74 },
+ /* Big endian without header rounding */
+ { { 'B', 0, 0, 1, /* endianness, message type, flags, protocol version */
+ 0, 0, 0, 50, /* body length */
+ 0, 0, 0, 1, /* message serial */
+ 0, 0, 0, 8 /* header length */}, 74 },
+ /* Invalid endianness */
+ { { '!', 0, 0, 1, /* endianness, message type, flags, protocol version */
+ 0, 0, 0, 50, /* body length */
+ 0, 0, 0, 1, /* message serial */
+ 0, 0, 0, 8 /* header length */}, -1 },
+ /* Oversized */
+ { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */
+ 0, 0, 0, 0x08, /* body length (128MiB) */
+ 1, 0, 0, 0, /* message serial */
+ 7, 0, 0, 0 /* header length */}, -1 },
+ };
+ gsize i;
+
+ for (i = 0; i < G_N_ELEMENTS (vectors); i++)
+ {
+ gssize bytes_needed;
+ GError *local_error = NULL;
+
+ g_test_message ("Vector: %" G_GSIZE_FORMAT, i);
+
+ bytes_needed = g_dbus_message_bytes_needed ((guchar *) vectors[i].blob,
+ G_N_ELEMENTS (vectors[i].blob),
+ &local_error);
+
+ if (vectors[i].expected_bytes_needed < 0)
+ g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
+ else
+ g_assert_no_error (local_error);
+ g_assert_cmpint (bytes_needed, ==, vectors[i].expected_bytes_needed);
+
+ g_clear_error (&local_error);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
int
main (int argc,
char *argv[])
@@ -151,6 +219,8 @@ main (int argc,
g_test_add_func ("/gdbus/message/lock", message_lock);
g_test_add_func ("/gdbus/message/copy", message_copy);
- return g_test_run();
+ g_test_add_func ("/gdbus/message/bytes-needed", message_bytes_needed);
+
+ return g_test_run ();
}
--
2.19.1

View File

@ -1,307 +0,0 @@
From 47be0f7a233e673a74566e9fb668955cc76fbdab Mon Sep 17 00:00:00 2001
From: Cosimo Cecchi <cosimoc@gnome.org>
Date: Wed, 6 Dec 2017 10:34:17 -0800
Subject: [PATCH 244/682] gdbusproxy: make g-name-owner property useful with
unique names
Currently, GDBusProxy:g-name-owner only notifies changes to the unique
name owner of the remote object in case the proxy was constructed for a
well-known name.
That sounds like an artificial restriction, and it's convenient to
connect to notify::g-name-owner if a proxy instance has already been
created for an unique name, instead of additionally using
g_bus_watch_name() to track the owner.
To fix this, always connect to NameOwnerChanged after the proxy is
initialized, instead of only doing so when the proxy was constructed for
a well-known name.
https://bugzilla.gnome.org/show_bug.cgi?id=791316
https://gitlab.gnome.org/GNOME/glib/issues/1310
---
gio/gdbusproxy.c | 5 +-
gio/tests/Makefile.am | 2 +
gio/tests/gdbus-proxy-unique-name.c | 215 ++++++++++++++++++++++++++++
gio/tests/meson.build | 1 +
4 files changed, 220 insertions(+), 3 deletions(-)
create mode 100644 gio/tests/gdbus-proxy-unique-name.c
diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
index 6d84deced..9cfb82d70 100644
--- a/gio/gdbusproxy.c
+++ b/gio/gdbusproxy.c
@@ -59,8 +59,7 @@
* well-known name, the property cache is flushed when the name owner
* vanishes and reloaded when a name owner appears.
*
- * If a #GDBusProxy is used for a well-known name, the owner of the
- * name is tracked and can be read from
+ * The unique name owner of the proxy's name is tracked and can be read from
* #GDBusProxy:g-name-owner. Connect to the #GObject::notify signal to
* get notified of changes. Additionally, only signals and property
* changes emitted from the current name owner are considered and
@@ -1769,7 +1768,7 @@ async_initable_init_first (GAsyncInitable *initable)
(GDestroyNotify) signal_subscription_unref);
}
- if (proxy->priv->name != NULL && !g_dbus_is_unique_name (proxy->priv->name))
+ if (proxy->priv->name != NULL)
{
proxy->priv->name_owner_changed_subscription_id =
g_dbus_connection_signal_subscribe (proxy->priv->connection,
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index b8a414954..8efb1eaa0 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -449,6 +449,7 @@ test_programs += \
gdbus-peer \
gdbus-proxy \
gdbus-proxy-threads \
+ gdbus-proxy-unique-name \
gdbus-proxy-well-known-name \
gdbus-test-codegen \
gdbus-test-codegen-old \
@@ -483,6 +484,7 @@ gdbus_introspection_SOURCES = $(gdbus_sessionbus_sources) gdbus-int
gdbus_names_SOURCES = $(gdbus_sessionbus_sources) gdbus-names.c
gdbus_proxy_SOURCES = $(gdbus_sessionbus_sources) gdbus-proxy.c
gdbus_proxy_threads_SOURCES = $(gdbus_sessionbus_sources) gdbus-proxy-threads.c
+gdbus_proxy_unique_name_SOURCES = $(gdbus_sessionbus_sources) gdbus-proxy-unique-name.c
gdbus_proxy_well_known_name_SOURCES = $(gdbus_sessionbus_sources) gdbus-proxy-well-known-name.c
gdbus_test_codegen_SOURCES = $(gdbus_sessionbus_sources) gdbus-test-codegen.c
nodist_gdbus_test_codegen_SOURCES = gdbus-test-codegen-generated.c gdbus-test-codegen-generated.h
diff --git a/gio/tests/gdbus-proxy-unique-name.c b/gio/tests/gdbus-proxy-unique-name.c
new file mode 100644
index 000000000..eacb0219c
--- /dev/null
+++ b/gio/tests/gdbus-proxy-unique-name.c
@@ -0,0 +1,215 @@
+/* GLib testing framework examples and tests
+ *
+ * Copyright (C) 2008-2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Cosimo Cecchi <cosimoc@gnome.org>
+ */
+
+#include <gio/gio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "gdbus-tests.h"
+
+/* all tests rely on a shared mainloop */
+static GMainLoop *loop = NULL;
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+proxy_new_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GDBusProxy **ret = user_data;
+ GError *error;
+
+ error = NULL;
+ *ret = g_dbus_proxy_new_finish (res, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (ret);
+
+ g_main_loop_quit (loop);
+}
+
+static void
+test_proxy_unique_name (void)
+{
+ GDBusProxy *wp;
+ GDBusProxy *p;
+ GDBusProxy *ap;
+ GDBusConnection *c;
+ GError *error;
+ gchar *name_owner;
+ gchar **property_names;
+ GVariant *variant;
+ GVariant *result;
+ char *unique_name;
+
+ session_bus_up ();
+
+ error = NULL;
+ c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (c);
+
+ /* use a proxy to the well-known name to set things up */
+ wp = g_dbus_proxy_new_sync (c,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* GDBusInterfaceInfo* */
+ "com.example.TestService", /* name */
+ "/com/example/TestObject", /* object path */
+ "com.example.Frob", /* interface name */
+ NULL, /* GCancellable */
+ &error);
+ g_assert_no_error (error);
+
+ /* this is safe; testserver will exit once the bus goes away */
+ g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL));
+
+ /* check that we get the notify::g-name-owner signal */
+ _g_assert_property_notify (wp, "g-name-owner");
+
+ /* now get the unique name of testserver's connection */
+ unique_name = g_dbus_proxy_get_name_owner (wp);
+
+ /* if we create another a proxy with the service being available, check that
+ * it has a name owner and properties
+ */
+ error = NULL;
+ p = g_dbus_proxy_new_sync (c,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* GDBusInterfaceInfo* */
+ unique_name, /* name */
+ "/com/example/TestObject", /* object path */
+ "com.example.Frob", /* interface name */
+ NULL, /* GCancellable */
+ &error);
+ g_assert_no_error (error);
+ name_owner = g_dbus_proxy_get_name_owner (p);
+ property_names = g_dbus_proxy_get_cached_property_names (p);
+ g_assert_true (g_dbus_is_unique_name (name_owner));
+ g_assert_nonnull (property_names);
+ g_assert_cmpint (g_strv_length (property_names), >, 0);
+ g_free (name_owner);
+ g_strfreev (property_names);
+
+ /* also for async: we should have a name owner and cached properties */
+ g_dbus_proxy_new (c,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* GDBusInterfaceInfo* */
+ unique_name, /* name */
+ "/com/example/TestObject", /* object path */
+ "com.example.Frob", /* interface name */
+ NULL, /* GCancellable */
+ (GAsyncReadyCallback) proxy_new_cb,
+ &ap);
+ g_main_loop_run (loop);
+ name_owner = g_dbus_proxy_get_name_owner (ap);
+ property_names = g_dbus_proxy_get_cached_property_names (ap);
+ g_assert_true (g_dbus_is_unique_name (name_owner));
+ g_assert_nonnull (property_names);
+ g_assert_cmpint (g_strv_length (property_names), >, 0);
+ g_free (name_owner);
+ g_strfreev (property_names);
+
+ /* Check property value is the initial value */
+ variant = g_dbus_proxy_get_cached_property (p, "y");
+ g_assert_nonnull (variant);
+ g_assert_cmpint (g_variant_get_byte (variant), ==, 1);
+ g_variant_unref (variant);
+ variant = g_dbus_proxy_get_cached_property (ap, "y");
+ g_assert_nonnull (variant);
+ g_assert_cmpint (g_variant_get_byte (variant), ==, 1);
+ g_variant_unref (variant);
+
+ /* Check that properties are updated on p */
+ result = g_dbus_proxy_call_sync (p,
+ "FrobSetProperty",
+ g_variant_new ("(sv)",
+ "y",
+ g_variant_new_byte (42)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (result);
+ g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
+ g_variant_unref (result);
+ _g_assert_signal_received (p, "g-properties-changed");
+ variant = g_dbus_proxy_get_cached_property (p, "y");
+ g_assert_nonnull (variant);
+ g_assert_cmpint (g_variant_get_byte (variant), ==, 42);
+ g_variant_unref (variant);
+ variant = g_dbus_proxy_get_cached_property (ap, "y");
+ g_assert_nonnull (variant);
+ g_assert_cmpint (g_variant_get_byte (variant), ==, 42);
+ g_variant_unref (variant);
+
+ /* Nuke the service and check that we get the signal and then don't
+ * have a name owner nor any cached properties
+ */
+ result = g_dbus_proxy_call_sync (p,
+ "Quit",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (result);
+ g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
+ g_variant_unref (result);
+ /* and wait... */
+ _g_assert_property_notify (p, "g-name-owner");
+ /* now we shouldn't have a name owner nor any cached properties */
+ g_assert_cmpstr (g_dbus_proxy_get_name_owner (p), ==, NULL);
+ g_assert_null (g_dbus_proxy_get_cached_property_names (p));
+ g_assert_null (g_dbus_proxy_get_cached_property (p, "y"));
+
+ g_object_unref (p);
+ g_object_unref (ap);
+
+ g_object_unref (wp);
+ g_free (unique_name);
+
+ g_object_unref (c);
+
+ /* tear down bus */
+ session_bus_down ();
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+int
+main (int argc,
+ char *argv[])
+{
+ gint ret;
+
+ g_test_init (&argc, &argv, NULL);
+
+ /* all the tests rely on a shared main loop */
+ loop = g_main_loop_new (NULL, FALSE);
+
+ g_test_dbus_unset ();
+
+ g_test_add_func ("/gdbus/proxy-unique-name", test_proxy_unique_name);
+
+ ret = g_test_run();
+ return ret;
+}
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index b71f61704..61c6be096 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -221,6 +221,7 @@ if host_machine.system() != 'windows'
'extra_sources' : extra_sources,
'dependencies' : [dbus1_dep],
},
+ 'gdbus-proxy-unique-name' : {'extra_sources' : extra_sources},
'gdbus-proxy-well-known-name' : {'extra_sources' : extra_sources},
'gdbus-test-codegen' : {
'extra_sources' : [extra_sources, gdbus_test_codegen_generated],
--
2.19.1

View File

@ -1,27 +0,0 @@
From 0a1730d7ea486d07a10b238d7f6fdaa41218c5e4 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Mon, 28 Jan 2019 15:18:37 +0100
Subject: [PATCH 534/682] gfile: Fix leak in g_file_query_default_handler()
Add missing `g_free (uri_scheme)` to fix leak when `uri_scheme[0]`
is equal to `\0`.
---
gio/gfile.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gio/gfile.c b/gio/gfile.c
index a5709a4cc..e6b468b55 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -6851,6 +6851,8 @@ g_file_query_default_handler (GFile *file,
if (appinfo != NULL)
return appinfo;
}
+ else
+ g_free (uri_scheme);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
--
2.19.1

View File

@ -1,55 +0,0 @@
From e244a78fbcbba3ab116f5a62f724a8f6cd926570 Mon Sep 17 00:00:00 2001
From: James Henstridge <james@jamesh.id.au>
Date: Tue, 15 Jan 2019 15:59:46 +0800
Subject: [PATCH 455/682] gio: don't use O_PATH file descriptors with OpenURI
portal
This change relates to https://github.com/flatpak/xdg-desktop-portal/issues/167
The OpenURI portal requires the caller to pass a file descriptor as
proof of access for local files. Old versions required this file
descriptor to use the O_PATH mode. However, this does not prove access
since you can create O_PATH descriptors for files that you can't read.
Since xdg-desktop-portal 1.0.1, regular file descriptors are also
accepted with O_PATH descriptors restricted to flatpaks for the
transition.
---
gio/gopenuriportal.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c
index 38d60bf68..b798d7cd1 100644
--- a/gio/gopenuriportal.c
+++ b/gio/gopenuriportal.c
@@ -31,9 +31,6 @@
#include "gunixfdlist.h"
#endif
-#ifndef O_PATH
-#define O_PATH 0
-#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#else
@@ -107,7 +104,7 @@ g_openuri_portal_open_uri (const char *uri,
path = g_file_get_path (file);
- fd = g_open (path, O_PATH | O_CLOEXEC);
+ fd = g_open (path, O_RDONLY | O_CLOEXEC);
errsv = errno;
if (fd == -1)
{
@@ -318,7 +315,7 @@ g_openuri_portal_open_uri_async (const char *uri,
g_object_set_data (G_OBJECT (task), "open-file", GINT_TO_POINTER (TRUE));
path = g_file_get_path (file);
- fd = g_open (path, O_PATH | O_CLOEXEC);
+ fd = g_open (path, O_RDONLY | O_CLOEXEC);
errsv = errno;
if (fd == -1)
{
--
2.19.1

Binary file not shown.

BIN
glib-2.62.1.tar.xz Normal file

Binary file not shown.

View File

@ -1,29 +0,0 @@
From 7321f240f914fa07f58c8789e219045d7282beae Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Fri, 22 Feb 2019 14:47:46 +0000
Subject: [PATCH 623/682] glib-compile-resources: Fix a minor leak
Spotted by oss-fuzz using asan.
oss-fuzz#13271
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
gio/glib-compile-resources.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c
index f04ea488b..399c567d2 100644
--- a/gio/glib-compile-resources.c
+++ b/gio/glib-compile-resources.c
@@ -999,6 +999,7 @@ main (int argc, char **argv)
}
+ g_free (base);
c_name = g_string_free (s, FALSE);
}
}
--
2.19.1

View File

@ -1,32 +0,0 @@
From 0985e70488cede2e856381fd2185d8aaf305b72d Mon Sep 17 00:00:00 2001
From: vmlobanov78 <vmlobanov78@gmail.com>
Date: Tue, 18 Sep 2018 10:34:23 +0000
Subject: [PATCH 239/682] glib-compile-resources: Fix size allocation for
compressed streams
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The length of the stolen data from a memory output stream is given by
get_data_size() — get_size() can be larger, and hence cause unnecessary
overallocation.
---
gio/glib-compile-resources.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c
index 6ce5aec4a..7e318b254 100644
--- a/gio/glib-compile-resources.c
+++ b/gio/glib-compile-resources.c
@@ -483,7 +483,7 @@ end_element (GMarkupParseContext *context,
}
g_free (data->content);
- data->content_size = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (out));
+ data->content_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (out));
data->content = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out));
g_object_unref (compressor);
--
2.19.1

View File

@ -1,38 +0,0 @@
From 45655b8265349d8e94b7472b6deb54adb3a63f38 Mon Sep 17 00:00:00 2001
From: Felix Potthast <mail@ninjakoa.la>
Date: Wed, 20 Feb 2019 10:38:29 +0000
Subject: [PATCH 614/682] glib-compile-resources: Fixes #1675
---
gio/glib-compile-resources.c | 2 +-
gio/tests/111_digit_test.gresource.xml | 6 +++++
gio/tests/meson.build | 25 ++++++++++++++++--
gio/tests/resources.c | 35 ++++++++++++++++++++++++++
4 files changed, 65 insertions(+), 3 deletions(-)
create mode 100644 gio/tests/111_digit_test.gresource.xml
diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c
index 60ccdbf81..f04ea488b 100644
--- a/gio/glib-compile-resources.c
+++ b/gio/glib-compile-resources.c
@@ -992,7 +992,7 @@ main (int argc, char **argv)
{
const char *first = G_CSET_A_2_Z G_CSET_a_2_z "_";
const char *rest = G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_";
- if (strchr ((i == 0) ? first : rest, base[i]) != NULL)
+ if (strchr ((s->len == 0) ? first : rest, base[i]) != NULL)
g_string_append_c (s, base[i]);
else if (base[i] == '-')
g_string_append_c (s, '_');
diff --git a/gio/tests/111_digit_test.gresource.xml b/gio/tests/111_digit_test.gresource.xml
new file mode 100644
index 000000000..00efcc315
--- /dev/null
+++ b/gio/tests/111_digit_test.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/digit_test">
+ <file>test1.txt</file>
+ </gresource>
+</gresources>

View File

@ -1,69 +0,0 @@
From 1f6db2a5c5822a55a83bfdc830f1548908b3c75c Mon Sep 17 00:00:00 2001
From: Mikhail Fludkov <fludkov.me@gmail.com>
Date: Thu, 20 Sep 2018 16:08:19 +0200
Subject: [PATCH 079/682] glib/gcharset: fix leaking
g_get_language_names_with_category
---
glib/gcharset.c | 7 ++++---
glib/tests/charset.c | 13 +++++++++++++
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/glib/gcharset.c b/glib/gcharset.c
index bfcd12590..a97b33a03 100644
--- a/glib/gcharset.c
+++ b/glib/gcharset.c
@@ -576,15 +576,16 @@ g_get_language_names (void)
*
* g_get_language_names() returns g_get_language_names_with_category("LC_MESSAGES").
*
- * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib
- * that must not be modified or freed.
+ * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by
+ * the thread g_get_language_names_with_category was called from.
+ * It must not be modified or freed. It must be copied if planned to be used in another thread.
*
* Since: 2.58
*/
const gchar * const *
g_get_language_names_with_category (const gchar *category_name)
{
- static GPrivate cache_private = G_PRIVATE_INIT ((void (*)(gpointer)) g_hash_table_remove_all);
+ static GPrivate cache_private = G_PRIVATE_INIT ((void (*)(gpointer)) g_hash_table_unref);
GHashTable *cache = g_private_get (&cache_private);
const gchar *languages;
GLanguageNamesCache *name_cache;
diff --git a/glib/tests/charset.c b/glib/tests/charset.c
index 0a1c8ce3f..363eedfd1 100644
--- a/glib/tests/charset.c
+++ b/glib/tests/charset.c
@@ -59,6 +59,18 @@ test_language_names_with_category (void)
}
}
+static void
+test_language_names_with_category_async (void)
+{
+ g_thread_join (g_thread_new (
+ NULL, (GThreadFunc)g_get_language_names_with_category, "LC_CTYPE"));
+
+ /* g_get_language_names_with_category returns a pointer to a memory
+ which is owned by a thread it has been called from. The thread is dead now,
+ therefore returned pointer can't be used at this stage.
+ */
+}
+
int
main (int argc, char *argv[])
{
@@ -67,6 +79,7 @@ main (int argc, char *argv[])
g_test_bug_base ("http://bugs.gnome.org/");
g_test_add_func ("/charset/language_names_with_category", test_language_names_with_category);
+ g_test_add_func ("/charset/language_names_with_category_async", test_language_names_with_category_async);
return g_test_run ();
}
--
2.19.1

View File

@ -1,89 +1,49 @@
Name: glib2
Version: 2.58.1
Release: 6
Version: 2.62.1
Release: 1
Summary: The core library that forms the basis for projects such as GTK+ and GNOME
License: LGPLv2+
URL: http://www.gtk.org
Source0: http://download.gnome.org/sources/glib/2.58/glib-%{version}.tar.xz
Source0: http://download.gnome.org/sources/glib/2.62/glib-%{version}.tar.xz
Patch6000: gnetworkmonitornm-Set-a-GError-properly-on-an-error-.patch
Patch6001: glib-gcharset-fix-leaking-g_get_language_names_with_.patch
Patch6002: gtask-Check-an-error-hasn-t-been-returned-when-calli.patch
Patch6003: gmacros-Fix-G_-UN-LIKELY-to-not-mask-Wparentheses.patch
Patch6004: grefcount-add-missing-gatomic.h.patch
Patch6005: glocalfile-Fix-access-can-trash-if-parent-is-symlink.patch
Patch6006: gvariant-Fix-checking-arithmetic-for-tuple-element-e.patch
Patch6007: gmarkup-Fix-validation-of-element-names.patch
Patch6008: gdatetime-Fix-formatting-of-time-zones-offsets-in-ra.patch
Patch6009: gobject-genums.c-fix-flags-validation.patch
Patch6010: bookmarkfile-Don-t-move-an-item-if-the-uri-has-not-c.patch
Patch6011: gvariant-Realign-data-on-construction-if-it-s-not-pr.patch
Patch6012: glib-compile-resources-Fix-size-allocation-for-compr.patch
Patch6013: gdbusproxy-make-g-name-owner-property-useful-with-un.patch
Patch6014: gmessages-don-t-memoize-in-g_log_writer_is_journald.patch
Patch6015: gdate-Use-longest-matching-month-name-in-g_date_set_.patch
Patch6016: gmain-Make-GChildWatchSource-child_exited-field-atom.patch
Patch6017: gmain-Make-GUnixSignalWatchSource-pending-field-atom.patch
Patch6018: gspawn-Fix-g_spawn-deadlock-in-a-multi-threaded-prog.patch
Patch6019: gunixmounts-Don-t-treat-ZFS-as-a-system-internal-fs.patch
Patch6020: g_timeout_-_seconds-don-t-overflow-for-large-interva.patch
Patch6021: gdatetime-Store-intermediate-result-of-g_date_time_f.patch
Patch6022: gvariant-Fix-error-handling-for-parsing-Unicode-esca.patch
Patch6023: gdbus-codegen-make-interface-info-header-body-not-cr.patch
Patch6024: gtlscertificate-Fix-bug-in-PEM-private-key-parser.patch
Patch6025: gtask-Ensure-to-return-1-or-0-from-getters-rather-th.patch
Patch6026: list-store-Fix-overflow-issues.patch
Patch6027: gio-don-t-use-O_PATH-file-descriptors-with-OpenURI-p.patch
Patch6028: gdbusmessage-Fix-check-on-upper-limit-of-message-siz.patch
Patch6029: gfile-Fix-leak-in-g_file_query_default_handler.patch
Patch6030: gdbus-Avoid-printing-null-strings.patch
Patch6031: gsettingsbackend-Fix-a-minor-memory-leak.patch
Patch6032: Fixing-missing-initializer-in-g_static_rec_mutex_ini.patch
Patch6033: gobject-Change-assertions-to-read-values-via-atomics.patch
Patch6034: gvariant-parser-Add-explicit-unsigned-to-signed-cast.patch
Patch6035: gvariant-parser-Fix-parsing-of-G_MININT-values-in-GV.patch
Patch6036: gvariant-parser-Fix-error-handling-when-type-coalesc.patch
Patch6037: gsocketlistener-Fix-multiple-returns-of-GTask-when-a.patch
Patch6038: gdbus-Fix-a-potential-use-after-free-on-connection-c.patch
Patch6039: glib-compile-resources-Fixes-1675.patch
Patch6040: glib-compile-resources-Fix-a-minor-leak.patch
Patch6041: glocalfilemonitor-Fix-data-race-in-local-file-monito.patch
Patch6042: gbase64-Allow-g_base64_encode-NULL-0-and-g_base64_de.patch
Patch6043: gbase64-Fix-an-impossible-condition.patch
Patch6044: CVE-2019-12450.patch
Patch6045: CVE-2019-13012.patch
Patch6046: 0458-gapplication-Fix-a-leaking-GRemoteActionGroup-member.patch
BuildRequires: chrpath gcc gcc-c++ gettext gtk-doc perl-interpreter
BUildRequires: glibc-devel libattr-devel libselinux-devel meson
BuildRequires: systemtap-sdt-devel pkgconfig(libelf) pkgconfig(libffi)
BuildRequires: pkgconfig(libpcre) pkgconfig(mount) pkgconfig(zlib)
BuildRequires: python3-devel gamin-devel
BuildRequires: automake chrpath autoconf gtk-doc libtool gettext perl-interpreter gamin-devel
BUildRequires: glibc-devel python3-devel libattr-devel libselinux-devel systemtap-sdt-devel libxslt
BuildRequires: pkgconfig(libelf) pkgconfig(libffi) pkgconfig(libpcre) pkgconfig(mount) pkgconfig(zlib)
provides: glib2-fam
Obsoletes: glib2-fam
Provides: %{name}-fam = %{version}-%{release}
Obsoletes: %{name}-fam < %{version}-%{release}
Recommends: shared-mime-info
Conflicts: gcr < 3.28.1
%description
GLib is a bundle of three (formerly five) low-level system libraries
written in C and developed mainly by GNOME. GLib's code was separated
from GTK, so it can be used by software other than GNOME and has been
developed in parallel ever since.
%package devel
Summary: Development and test files for the GLib library
Requires: %{name} = %{version}-%{release}
provides: glib2-static glib2-tests
Obsoletes: glib2-static glib2-tests
%package devel
Summary: Development and test files for the GLib library
Requires: %{name} = %{version}-%{release}
%description devel
Provides: %{name}-static = %{version}-%{release}
Provides: %{name}-tests = %{version}-%{release}
Obsoletes: %{name}-static < %{version}-%{release}
Obsoletes: %{name}-tests < %{version}-%{release}
%description devel
Development and test files for the GLib library.
%package help
Summary: help document for the glib2 package
Buildarch: noarch
provides: glib2-doc
Obsoletes: glib2-doc
%package help
Summary: help document for the glib2 package
Buildarch: noarch
Provides: %{name}-doc = %{version}-%{release}
Obsoletes: %{name}-doc < %{version}-%{release}
%description help
%description help
help document for the glib2 package.
%prep
@ -91,21 +51,21 @@ help document for the glib2 package.
%build
rm glib/pcre/*.[ch]
(if ! test -x configure; then NOCONFIGURE=1 ./autogen.sh; CONFIGFLAGS=--enable-gtk-doc; fi;
%configure $CONFIGFLAGS --disable-silent-rules --with-python=%{__python3} --with-pcre=system --enable-systemtap --enable-static --enable-installed-tests
)
%meson --default-library=both -Dman=true -Ddtrace=true \
-Dsystemtap=true -Dgtk_doc=true -Dfam=true -Dinstalled_tests=true
%make_build
%meson_build
%install
%make_install
touch -r gio/gdbus-2.0/codegen/config.py.in $RPM_BUILD_ROOT/%{_datadir}/glib-2.0/codegen/config.py
touch -r gio/gdbus-2.0/codegen/config.py.in $RPM_BUILD_ROOT/%{_datadir}/glib-2.0/codegen/codegen_main.py
chrpath --delete $RPM_BUILD_ROOT%{_libdir}/*.so
%meson_install
touch -r gio/gdbus-2.0/codegen/config.py.in %{buildroot}%{_datadir}/glib-2.0/codegen/*.py
chrpath --delete %{buildroot}%{_libdir}/*.so
mv $RPM_BUILD_ROOT%{_bindir}/gio-querymodules $RPM_BUILD_ROOT%{_bindir}/gio-querymodules-%{__isa_bits}
touch $RPM_BUILD_ROOT%{_libdir}/gio/modules/giomodule.cache
chmod 644 $RPM_BUILD_ROOT%{_datadir}/bash-completion/completions/*
export PYTHONHASHSEED=0
%py_byte_compile %{__python3} %{buildroot}%{_datadir}
mv %{buildroot}%{_bindir}/gio-querymodules %{buildroot}%{_bindir}/gio-querymodules-%{__isa_bits}
touch %{buildroot}%{_libdir}/gio/modules/giomodule.cache
%find_lang glib20
%transfiletriggerin -- %{_libdir}/gio/modules
@ -125,13 +85,17 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%doc AUTHORS NEWS README
%license COPYING
%{_libdir}/*.so.*
%{_libdir}/gio/modules/libgiofam.so
%dir %{_libdir}/gio
%ghost %{_libdir}/gio/modules/giomodule.cache
%dir %{_datadir}/glib-2.0
%dir %{_datadir}/bash-completion
%{_datadir}/bash-completion/completions/gapplication
%{_datadir}/bash-completion/completions/gdbus
%{_datadir}/bash-completion/completions/gio
%{_datadir}/bash-completion/completions/gsettings
%dir %{_datadir}/glib-2.0/schemas
%dir %{_libdir}/gio/modules
%ghost %{_libdir}/gio/modules/giomodule.cache
%{_bindir}/gio
%{_bindir}/gio-launch-desktop
%{_bindir}/gio-querymodules*
@ -139,17 +103,23 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%{_bindir}/gsettings
%{_bindir}/gdbus
%{_bindir}/gapplication
%{_libdir}/gio/modules/libgiofam.so
%files devel
%defattr(-,root,root)
%{_libdir}/lib*.so
%{_libdir}/glib-2.0
%{_includedir}/*
%{_datadir}/aclocal/*
%{_libdir}/pkgconfig/*
%{_libdir}/*.a
%{_includedir}/*
%{_libexecdir}/installed-tests
%{_datadir}/aclocal/*
%{_datadir}/glib-2.0/*
%{_datadir}/bash-completion/completions/gresource
%{_datadir}/gdb/
%{_datadir}/gettext/
%{_datadir}/systemtap/
%{_datadir}/installed-tests
%{_bindir}/glib-genmarshal
%{_bindir}/glib-gettextize
%{_bindir}/glib-mkenums
@ -158,18 +128,7 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%{_bindir}/gdbus-codegen
%{_bindir}/glib-compile-resources
%{_bindir}/gresource
%{_datadir}/glib-2.0/codegen
%attr (0755, root, root) %{_bindir}/gtester-report
%{_datadir}/gdb/
%{_datadir}/gettext/
%{_datadir}/systemtap/
%{_libdir}/*.a
%{_libexecdir}/installed-tests
%{_datadir}/installed-tests
%exclude %{_libdir}/*.la
%exclude %{_libdir}/gio/modules/*.{a,la}
%exclude %{_datadir}/glib-2.0/gdb/*.{pyc,pyo}
%exclude %{_datadir}/glib-2.0/codegen/*.{pyc,pyo}
%files help
%defattr(-,root,root)
@ -177,6 +136,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%doc %{_datadir}/gtk-doc/html/*
%changelog
* Thu Jan 9 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.62.1-1
- update to 2.62.1
* Tue Dec 24 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.58.1-6
- change the path of files

View File

@ -1,205 +0,0 @@
From 0f5017fb701b221846f04fa610c8429bbaa49136 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Thu, 13 Sep 2018 17:33:59 +0200
Subject: [PATCH 152/682] glocalfile: Fix access::can-trash if parent is
symlink
G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH can be set to a wrong value if
its parent dir is a symlink. This is because the find_mountpoint_for()
function tries to find mountpoint for a filepath and expands symlinks
only in parent dirs. But in this case the path is already parent dir
and needs to be expanded first...
Closes: https://gitlab.gnome.org/GNOME/glib/issues/1522
---
gio/glocalfile.c | 104 +++++++++++++++++++++++++++++------------------
1 file changed, 65 insertions(+), 39 deletions(-)
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 30fa2281c..33b5ba3da 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -109,7 +109,7 @@ G_DEFINE_TYPE_WITH_CODE (GLocalFile, g_local_file, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_FILE,
g_local_file_file_iface_init))
-static char *find_mountpoint_for (const char *file, dev_t dev);
+static char *find_mountpoint_for (const char *file, dev_t dev, gboolean resolve_basename_symlink);
static void
g_local_file_finalize (GObject *object)
@@ -791,7 +791,7 @@ get_mount_info (GFileInfo *fs_info,
{
mount_info = 0;
- mountpoint = find_mountpoint_for (path, buf.st_dev);
+ mountpoint = find_mountpoint_for (path, buf.st_dev, FALSE);
if (mountpoint == NULL)
mountpoint = g_strdup ("/");
@@ -886,7 +886,7 @@ get_volume_for_path (const char *path)
}
static char *
-find_mountpoint_for (const char *file, dev_t dev)
+find_mountpoint_for (const char *file, dev_t dev, gboolean resolve_basename_symlink)
{
wchar_t *wpath;
char *utf8_path;
@@ -1132,7 +1132,7 @@ g_local_file_find_enclosing_mount (GFile *file,
if (g_lstat (local->filename, &buf) != 0)
goto error;
- mountpoint = find_mountpoint_for (local->filename, buf.st_dev);
+ mountpoint = find_mountpoint_for (local->filename, buf.st_dev, FALSE);
if (mountpoint == NULL)
goto error;
@@ -1584,12 +1584,51 @@ expand_symlink (const char *link)
}
static char *
-get_parent (const char *path,
- dev_t *parent_dev)
+expand_symlinks (const char *path,
+ dev_t *dev)
{
- char *parent, *tmp;
- GStatBuf parent_stat;
+ char *tmp, *target;
+ GStatBuf target_stat;
int num_recursions;
+
+ target = g_strdup (path);
+
+ num_recursions = 0;
+ do
+ {
+ if (g_lstat (target, &target_stat) != 0)
+ {
+ g_free (target);
+ return NULL;
+ }
+
+ if (S_ISLNK (target_stat.st_mode))
+ {
+ tmp = target;
+ target = expand_symlink (target);
+ g_free (tmp);
+ }
+
+ num_recursions++;
+ if (num_recursions > 12)
+ {
+ g_free (target);
+ return NULL;
+ }
+ }
+ while (S_ISLNK (target_stat.st_mode));
+
+ if (dev)
+ *dev = target_stat.st_dev;
+
+ return target;
+}
+
+static char *
+get_parent (const char *path,
+ dev_t *parent_dev)
+{
+ char *parent, *res;
char *path_copy;
path_copy = strip_trailing_slashes (path);
@@ -1604,32 +1643,10 @@ get_parent (const char *path,
}
g_free (path_copy);
- num_recursions = 0;
- do {
- if (g_lstat (parent, &parent_stat) != 0)
- {
- g_free (parent);
- return NULL;
- }
-
- if (S_ISLNK (parent_stat.st_mode))
- {
- tmp = parent;
- parent = expand_symlink (parent);
- g_free (tmp);
- }
-
- num_recursions++;
- if (num_recursions > 12)
- {
- g_free (parent);
- return NULL;
- }
- } while (S_ISLNK (parent_stat.st_mode));
+ res = expand_symlinks (parent, parent_dev);
+ g_free (parent);
- *parent_dev = parent_stat.st_dev;
-
- return parent;
+ return res;
}
static char *
@@ -1656,13 +1673,22 @@ expand_all_symlinks (const char *path)
}
static char *
-find_mountpoint_for (const char *file,
- dev_t dev)
+find_mountpoint_for (const char *file,
+ dev_t dev,
+ gboolean resolve_basename_symlink)
{
char *dir, *parent;
dev_t dir_dev, parent_dev;
- dir = g_strdup (file);
+ if (resolve_basename_symlink)
+ {
+ dir = expand_symlinks (file, NULL);
+ if (dir == NULL)
+ return g_strdup (file);
+ }
+ else
+ dir = g_strdup (file);
+
dir_dev = dev;
while (1)
@@ -1693,7 +1719,7 @@ _g_local_file_find_topdir_for (const char *file)
if (dir == NULL)
return NULL;
- mountpoint = find_mountpoint_for (dir, dir_dev);
+ mountpoint = find_mountpoint_for (dir, dir_dev, TRUE);
g_free (dir);
return mountpoint;
@@ -1789,7 +1815,7 @@ _g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev)
if (dir_dev == home_dev)
return TRUE;
- topdir = find_mountpoint_for (dirname, dir_dev);
+ topdir = find_mountpoint_for (dirname, dir_dev, TRUE);
if (topdir == NULL)
return FALSE;
@@ -1856,7 +1882,7 @@ _g_local_file_is_lost_found_dir (const char *path, dev_t path_dev)
if (!g_str_has_suffix (path, "/lost+found"))
goto out;
- mount_dir = find_mountpoint_for (path, path_dev);
+ mount_dir = find_mountpoint_for (path, path_dev, FALSE);
if (mount_dir == NULL)
goto out;
--
2.19.1

View File

@ -1,37 +0,0 @@
From 6336864171d0d14297de5af2aba0a5de00a8d257 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Fri, 22 Feb 2019 00:00:00 +0000
Subject: [PATCH 628/682] glocalfilemonitor: Fix data race in local file
monitor
Ensure that source is attached to the context before it migth be used
from another thread, since otherwise operation on source are
unsynchronized and not thread-safe.
In particular there was a data race between g_source_attach and
g_source_set_ready_time (used from g_file_monitor_source_handle_event).
---
gio/glocalfilemonitor.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c
index 8a4c4ec43..278d9a492 100644
--- a/gio/glocalfilemonitor.c
+++ b/gio/glocalfilemonitor.c
@@ -788,11 +788,11 @@ g_local_file_monitor_start (GLocalFileMonitor *local_monitor,
#endif
}
+ g_source_attach ((GSource *) source, context);
+
G_LOCAL_FILE_MONITOR_GET_CLASS (local_monitor)->start (local_monitor,
source->dirname, source->basename, source->filename,
source);
-
- g_source_attach ((GSource *) source, context);
}
static void
--
2.19.1

View File

@ -1,36 +0,0 @@
From 0e7ebf794fdbdeb2a156c2e2aebcd78725793dba Mon Sep 17 00:00:00 2001
From: Mohammed Sadiq <sadiq@sadiqpk.org>
Date: Thu, 4 Oct 2018 17:38:27 +0530
Subject: [PATCH 139/682] gmacros: Fix G_[UN]LIKELY to not mask -Wparentheses
A double paren forces the compiler to assume that the
statement is right. That may not be the case.
This is essentially reverting b44fba25fbad89c105795a10a569fe422e4d1c44.
See https://bugzilla.gnome.org/show_bug.cgi?id=760215.
It's more morth to allow find common mistakes (= instead of ==
in conditionals) than masking them to make some rarely used
code work.
---
glib/gmacros.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/glib/gmacros.h b/glib/gmacros.h
index 0432d9cad..8ef65dad2 100644
--- a/glib/gmacros.h
+++ b/glib/gmacros.h
@@ -427,8 +427,8 @@
_g_boolean_var_ = 0; \
_g_boolean_var_; \
})
-#define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1))
-#define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 0))
+#define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 1))
+#define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 0))
#else
#define G_LIKELY(expr) (expr)
#define G_UNLIKELY(expr) (expr)
--
2.19.1

View File

@ -1,66 +0,0 @@
From d2fd53df036af9a931a39b6d28d42fea9f6b5d18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Thu, 1 Nov 2018 00:00:00 +0000
Subject: [PATCH 260/682] gmain: Make GChildWatchSource child_exited field
atomic
Ensure synchronization between prepare / check of GChildWatchsource and
UNIX signal dispatcher by making operations on `child_exited` field
atomic. Use `child_exited` as publication flag for `child_status`.
Issue #1312.
---
glib/gmain.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/glib/gmain.c b/glib/gmain.c
index e1a680433..ad57b4927 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -5107,7 +5107,7 @@ dispatch_unix_signals_unlocked (void)
{
GChildWatchSource *source = node->data;
- if (!source->child_exited)
+ if (!g_atomic_int_get (&source->child_exited))
{
pid_t pid;
do
@@ -5117,14 +5117,14 @@ dispatch_unix_signals_unlocked (void)
pid = waitpid (source->pid, &source->child_status, WNOHANG);
if (pid > 0)
{
- source->child_exited = TRUE;
+ g_atomic_int_set (&source->child_exited, TRUE);
wake_source ((GSource *) source);
}
else if (pid == -1 && errno == ECHILD)
{
g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). See the documentation of g_child_watch_source_new() for possible causes.");
- source->child_exited = TRUE;
source->child_status = 0;
+ g_atomic_int_set (&source->child_exited, TRUE);
wake_source ((GSource *) source);
}
}
@@ -5167,7 +5167,7 @@ g_child_watch_prepare (GSource *source,
child_watch_source = (GChildWatchSource *) source;
- return child_watch_source->child_exited;
+ return g_atomic_int_get (&child_watch_source->child_exited);
}
static gboolean
@@ -5177,7 +5177,7 @@ g_child_watch_check (GSource *source)
child_watch_source = (GChildWatchSource *) source;
- return child_watch_source->child_exited;
+ return g_atomic_int_get (&child_watch_source->child_exited);
}
static gboolean
--
2.19.1

View File

@ -1,67 +0,0 @@
From 9e652f94d285b1722ea82a0465c6724eee346738 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Thu, 1 Nov 2018 00:00:00 +0000
Subject: [PATCH 261/682] gmain: Make GUnixSignalWatchSource pending field
atomic
Ensure synchronization between prepare / check /dispatch of
GUnixSignalWatchSource and UNIX signal dispatcher by making operations
on `pending` field atomic.
Issue #1312.
---
glib/gmain.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/glib/gmain.c b/glib/gmain.c
index ad57b4927..07ec867bc 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -5138,14 +5138,10 @@ dispatch_unix_signals_unlocked (void)
{
GUnixSignalWatchSource *source = node->data;
- if (!source->pending)
+ if (pending[source->signum] &&
+ g_atomic_int_compare_and_exchange (&source->pending, FALSE, TRUE))
{
- if (pending[source->signum])
- {
- source->pending = TRUE;
-
- wake_source ((GSource *) source);
- }
+ wake_source ((GSource *) source);
}
}
@@ -5188,7 +5184,7 @@ g_unix_signal_watch_prepare (GSource *source,
unix_signal_source = (GUnixSignalWatchSource *) source;
- return unix_signal_source->pending;
+ return g_atomic_int_get (&unix_signal_source->pending);
}
static gboolean
@@ -5198,7 +5194,7 @@ g_unix_signal_watch_check (GSource *source)
unix_signal_source = (GUnixSignalWatchSource *) source;
- return unix_signal_source->pending;
+ return g_atomic_int_get (&unix_signal_source->pending);
}
static gboolean
@@ -5220,7 +5216,7 @@ g_unix_signal_watch_dispatch (GSource *source,
again = (callback) (user_data);
- unix_signal_source->pending = FALSE;
+ g_atomic_int_set (&unix_signal_source->pending, FALSE);
return again;
}
--
2.19.1

View File

@ -1,37 +0,0 @@
From 2187b1bec481b4d87310792c46d7d9ea59957f07 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Fri, 26 Oct 2018 23:21:46 +1300
Subject: [PATCH 190/682] gmarkup: Fix validation of element names
Previously, the element name validation only happened if a start_element
callback was specified on the context. Element name validation should be
unconditional.
This was causing test-5.gmarkup to fail when run against the improved
tests in the following commit.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gmarkup.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/glib/gmarkup.c b/glib/gmarkup.c
index f85c00ab4..7093a6790 100644
--- a/glib/gmarkup.c
+++ b/glib/gmarkup.c
@@ -1050,8 +1050,10 @@ emit_start_element (GMarkupParseContext *context,
tmp_error = NULL;
start_name = current_element (context);
- if (context->parser->start_element &&
- name_validate (context, start_name, error))
+ if (!name_validate (context, start_name, error))
+ return;
+
+ if (context->parser->start_element)
(* context->parser->start_element) (context,
start_name,
(const gchar **)attr_names,
--
2.19.1

View File

@ -1,96 +0,0 @@
From f1175704b6c48672e480a7006f05944ad6a1e2f8 Mon Sep 17 00:00:00 2001
From: Will Thompson <will@willthompson.co.uk>
Date: Mon, 12 Nov 2018 11:20:49 +0000
Subject: [PATCH 247/682] gmessages: don't memoize in
g_log_writer_is_journald()
Previously, g_log_writer_is_journald() would cache the result for the
first (non-negative) FD it was called on, and return that result for
all future (non-negative) FDs. While unlikely, it's possible that
applications might call this function on something other than
fileno(stderr).
Move the memoization into g_log_writer_default(), which always passes
fileno(stderr).
Fixes #1589.
---
glib/gmessages.c | 42 ++++++++++++++++++++++--------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/glib/gmessages.c b/glib/gmessages.c
index 569fe2cf8..a43ff0e58 100644
--- a/glib/gmessages.c
+++ b/glib/gmessages.c
@@ -2165,31 +2165,24 @@ g_log_writer_is_journald (gint output_fd)
/* FIXME: Use the new journal API for detecting whether were writing to the
* journal. See: https://github.com/systemd/systemd/issues/2473
*/
- static gsize initialized;
- static gboolean fd_is_journal = FALSE;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ struct sockaddr_un un;
+ } addr;
+ socklen_t addr_len;
+ int err;
if (output_fd < 0)
return FALSE;
- if (g_once_init_enter (&initialized))
- {
- union {
- struct sockaddr_storage storage;
- struct sockaddr sa;
- struct sockaddr_un un;
- } addr;
- socklen_t addr_len = sizeof(addr);
- int err = getpeername (output_fd, &addr.sa, &addr_len);
- if (err == 0 && addr.storage.ss_family == AF_UNIX)
- fd_is_journal = g_str_has_prefix (addr.un.sun_path, "/run/systemd/journal/");
-
- g_once_init_leave (&initialized, TRUE);
- }
+ addr_len = sizeof(addr);
+ err = getpeername (output_fd, &addr.sa, &addr_len);
+ if (err == 0 && addr.storage.ss_family == AF_UNIX)
+ return g_str_has_prefix (addr.un.sun_path, "/run/systemd/journal/");
+#endif
- return fd_is_journal;
-#else
return FALSE;
-#endif
}
static void escape_string (GString *string);
@@ -2620,6 +2613,9 @@ g_log_writer_default (GLogLevelFlags log_level,
gsize n_fields,
gpointer user_data)
{
+ static gsize initialized = 0;
+ static gboolean stderr_is_journal = FALSE;
+
g_return_val_if_fail (fields != NULL, G_LOG_WRITER_UNHANDLED);
g_return_val_if_fail (n_fields > 0, G_LOG_WRITER_UNHANDLED);
@@ -2656,7 +2652,13 @@ g_log_writer_default (GLogLevelFlags log_level,
log_level |= G_LOG_FLAG_FATAL;
/* Try logging to the systemd journal as first choice. */
- if (g_log_writer_is_journald (fileno (stderr)) &&
+ if (g_once_init_enter (&initialized))
+ {
+ stderr_is_journal = g_log_writer_is_journald (fileno (stderr));
+ g_once_init_leave (&initialized, TRUE);
+ }
+
+ if (stderr_is_journal &&
g_log_writer_journald (log_level, fields, n_fields, user_data) ==
G_LOG_WRITER_HANDLED)
goto handled;
--
2.19.1

View File

@ -1,36 +0,0 @@
From c5761146bc063a2defd9934cd0151b5e5766ab73 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Thu, 13 Sep 2018 10:25:05 +0100
Subject: [PATCH 066/682] gnetworkmonitornm: Set a GError properly on an error
handling path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
All the other initialisation failure paths set a GError, but this one
didnt. Set a GError to avoid breaking the invariant that returning
FALSE should always have a GError set.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1523
---
gio/gnetworkmonitornm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c
index 20a86571f..5bc8c925a 100644
--- a/gio/gnetworkmonitornm.c
+++ b/gio/gnetworkmonitornm.c
@@ -309,6 +309,8 @@ g_network_monitor_nm_initable_init (GInitable *initable,
if (!name_owner)
{
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("NetworkManager not running"));
g_object_unref (proxy);
return FALSE;
}
--
2.19.1

View File

@ -1,61 +0,0 @@
From 4631cd892da2ad7ea54912b7f20af33ee2c72744 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 17 Nov 2016 15:43:26 -0500
Subject: [PATCH 549/682] gobject: Change assertions to read values via atomics
I'm trying to use `-fsanitize=thread` for OSTree, and some of
these issues seem to go into GLib. Also, the sanitizers work better if
the userspace libraries are built with them too.
This fix is similar to
https://github.com/ostreedev/ostree/pull/582/commits/b6814bb37cacd7a36715cf91766eb760b1b33c66
Mixing atomic and non-atomic reads trips TSAN, so let's change the
assertions to operate on the local values returned from atomic
read/writes.
Without this change I couldn't even *build* GLib with TSAN, since we
use gresources during compilation, which uses GSubprocess, which hits
this code.
(Minor review fixes made by Philip Withnall <withnall@endlessm.com>.)
https://gitlab.gnome.org/GNOME/glib/issues/1224
---
gobject/gobject.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 3f8ad9273..de61a0481 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -3210,9 +3210,9 @@ gpointer
gint old_val;
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
- g_return_val_if_fail (object->ref_count > 0, NULL);
old_val = g_atomic_int_add (&object->ref_count, 1);
+ g_return_val_if_fail (old_val > 0, NULL);
if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object))
toggle_refs_notify (object, FALSE);
@@ -3241,7 +3241,6 @@ g_object_unref (gpointer _object)
gint old_ref;
g_return_if_fail (G_IS_OBJECT (object));
- g_return_if_fail (object->ref_count > 0);
/* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */
retry_atomic_decrement1:
@@ -3336,6 +3335,7 @@ g_object_unref (gpointer _object)
/* decrement the last reference */
old_ref = g_atomic_int_add (&object->ref_count, -1);
+ g_return_if_fail (old_ref > 0);
TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref));
--
2.19.1

View File

@ -1,32 +0,0 @@
From 1d6c7843caebdeac72f80ecb0f9807afc853affc Mon Sep 17 00:00:00 2001
From: Arthur Demchenkov <spinal.by@gmail.com>
Date: Sun, 14 Oct 2018 05:03:42 +0300
Subject: [PATCH 213/682] gobject/genums.c: fix flags validation
gint -> glong conversion causes flags to be invalid if the highest bit
is set.
Closes #1572
---
gobject/genums.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/gobject/genums.c b/gobject/genums.c
index 8212dd99d..aa27c6bb4 100644
--- a/gobject/genums.c
+++ b/gobject/genums.c
@@ -152,7 +152,10 @@ value_flags_enum_collect_value (GValue *value,
GTypeCValue *collect_values,
guint collect_flags)
{
- value->data[0].v_long = collect_values[0].v_int;
+ if (G_VALUE_HOLDS_ENUM (value))
+ value->data[0].v_long = collect_values[0].v_int;
+ else
+ value->data[0].v_ulong = (guint) collect_values[0].v_int;
return NULL;
}
--
2.19.1

View File

@ -1,37 +0,0 @@
From 09c149453ac969dedb1cb2d15d489d1dd81412bf Mon Sep 17 00:00:00 2001
From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Date: Sat, 13 Oct 2018 23:10:33 +0200
Subject: [PATCH 150/682] grefcount: add missing gatomic.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Without gatomic.h, build fails on:
In file included from garcbox.c:24:0:
garcbox.c: In function g_atomic_rc_box_acquire:
grefcount.h:101:13: error: implicit declaration of function g_atomic_int_get; did you mean __atomic_store? [-Werror=implicit-function-declaration]
(void) (g_atomic_int_get (rc) == G_MAXINT ? 0 : g_atomic_int_inc ((rc))); \
^
garcbox.c:292:3: note: in expansion of macro g_atomic_ref_count_inc
g_atomic_ref_count_inc (&real_box->ref_count);
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
---
glib/grefcount.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/glib/grefcount.h b/glib/grefcount.h
index dec9a5ffb..b6eced1b7 100644
--- a/glib/grefcount.h
+++ b/glib/grefcount.h
@@ -23,6 +23,7 @@
#error "Only <glib.h> can be included directly."
#endif
+#include <glib/gatomic.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS
--
2.19.1

View File

@ -1,28 +0,0 @@
From caf5103d4befbaf7a2fdc01ef01484ae168e7657 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Wed, 23 Jan 2019 15:59:17 +0000
Subject: [PATCH 545/682] gsettingsbackend: Fix a minor memory leak
This never caused any problems because the default GSettingsBackend is
cached forever by GIOModule anyway.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
gio/gsettingsbackend.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
index ca9b908a5..18026ae56 100644
--- a/gio/gsettingsbackend.c
+++ b/gio/gsettingsbackend.c
@@ -1052,5 +1052,7 @@ g_settings_backend_sync_default (void)
if (class->sync)
class->sync (backend);
+
+ g_object_unref (backend);
}
}
--
2.19.1

View File

@ -1,107 +0,0 @@
From 30ccfac9cf594c7bb224ff38ce109b442fb10a3c Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Fri, 8 Feb 2019 00:05:52 +0000
Subject: [PATCH 575/682] gsocketlistener: Fix multiple returns of GTask when
accepting sockets
When calling g_socket_listener_accept_socket_async() on a
GSocketListener with multiple sockets, the accept_ready() callback is
called for the first incoming connection on each socket. It will return
success/failure for the entire accept_socket_async() GTask, and then
free the GSources for listening for incoming connections on the other
sockets in the GSocketListener. The GSources are freed when the GTask is
finalised.
However, if incoming connections arrive for multiple sockets within the
same GMainContext iteration, accept_ready() will be called multiple
times, and will call g_task_return_*() multiple times, before the GTask
is finalised. Calling g_task_return_*() multiple times is not allowed.
Propagate the first success/failure, as before, but then ignore all
subsequent incoming connections until the GTask is finalised.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
gio/gsocketlistener.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c
index ab17678a9..a2c879d9c 100644
--- a/gio/gsocketlistener.c
+++ b/gio/gsocketlistener.c
@@ -773,6 +773,19 @@ g_socket_listener_accept (GSocketListener *listener,
return connection;
}
+typedef struct
+{
+ GList *sources; /* (element-type GSource) */
+ gboolean returned_yet;
+} AcceptSocketAsyncData;
+
+static void
+accept_socket_async_data_free (AcceptSocketAsyncData *data)
+{
+ free_sources (data->sources);
+ g_free (data);
+}
+
static gboolean
accept_ready (GSocket *accept_socket,
GIOCondition condition,
@@ -782,6 +795,12 @@ accept_ready (GSocket *accept_socket,
GError *error = NULL;
GSocket *socket;
GObject *source_object;
+ AcceptSocketAsyncData *data = g_task_get_task_data (task);
+
+ /* Dont call g_task_return_*() multiple times if we have multiple incoming
+ * connections in the same #GMainContext iteration. */
+ if (data->returned_yet)
+ return G_SOURCE_REMOVE;
socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
if (socket)
@@ -798,8 +817,10 @@ accept_ready (GSocket *accept_socket,
g_task_return_error (task, error);
}
+ data->returned_yet = TRUE;
g_object_unref (task);
- return FALSE;
+
+ return G_SOURCE_REMOVE;
}
/**
@@ -824,8 +845,8 @@ g_socket_listener_accept_socket_async (GSocketListener *listener,
gpointer user_data)
{
GTask *task;
- GList *sources;
GError *error = NULL;
+ AcceptSocketAsyncData *data = NULL;
task = g_task_new (listener, cancellable, callback, user_data);
g_task_set_source_tag (task, g_socket_listener_accept_socket_async);
@@ -837,12 +858,15 @@ g_socket_listener_accept_socket_async (GSocketListener *listener,
return;
}
- sources = add_sources (listener,
+ data = g_new0 (AcceptSocketAsyncData, 1);
+ data->returned_yet = FALSE;
+ data->sources = add_sources (listener,
accept_ready,
task,
cancellable,
g_main_context_get_thread_default ());
- g_task_set_task_data (task, sources, (GDestroyNotify) free_sources);
+ g_task_set_task_data (task, g_steal_pointer (&data),
+ (GDestroyNotify) accept_socket_async_data_free);
}
/**
--
2.19.1

View File

@ -1,149 +0,0 @@
From f2917459f745bebf931bccd5cc2c33aa81ef4d12 Mon Sep 17 00:00:00 2001
From: Peter Wu <peter@lekensteyn.nl>
Date: Sat, 24 Nov 2018 13:22:57 +0100
Subject: [PATCH 301/682] gspawn: Fix g_spawn deadlock in a multi-threaded
program on Linux
opendir and closedir are not async-signal-safe, these may call malloc
under the hood and cause a deadlock in a multi-threaded program.
This only affected Linux when /proc is mounted, other systems use a
slower path that iterates through all potential file descriptors.
Fixes a long-standing problem (since GLib 2.14.2).
Closes #945 and #1014
---
glib/gspawn.c | 94 +++++++++++++++++++++++++++++++++++----------------
1 file changed, 65 insertions(+), 29 deletions(-)
diff --git a/glib/gspawn.c b/glib/gspawn.c
index 23ade06ae..69d3fec10 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -47,6 +47,10 @@
#include <sys/resource.h>
#endif /* HAVE_SYS_RESOURCE_H */
+#ifdef __linux__
+#include <sys/syscall.h> /* for syscall and SYS_getdents64 */
+#endif
+
#include "gspawn.h"
#include "gspawn-private.h"
#include "gthread.h"
@@ -1125,6 +1129,44 @@ set_cloexec (void *data, gint fd)
}
#ifndef HAVE_FDWALK
+#ifdef __linux__
+struct linux_dirent64
+{
+ guint64 d_ino; /* 64-bit inode number */
+ guint64 d_off; /* 64-bit offset to next structure */
+ unsigned short d_reclen; /* Size of this dirent */
+ unsigned char d_type; /* File type */
+ char d_name[]; /* Filename (null-terminated) */
+};
+
+static gint
+filename_to_fd (const char *p)
+{
+ char c;
+ int fd = 0;
+ const int cutoff = G_MAXINT / 10;
+ const int cutlim = G_MAXINT % 10;
+
+ if (*p == '\0')
+ return -1;
+
+ while ((c = *p++) != '\0')
+ {
+ if (!g_ascii_isdigit (c))
+ return -1;
+ c -= '0';
+
+ /* Check for overflow. */
+ if (fd > cutoff || (fd == cutoff && c > cutlim))
+ return -1;
+
+ fd = fd * 10 + c;
+ }
+
+ return fd;
+}
+#endif
+
static int
fdwalk (int (*cb)(void *data, int fd), void *data)
{
@@ -1136,45 +1178,39 @@ fdwalk (int (*cb)(void *data, int fd), void *data)
struct rlimit rl;
#endif
-#ifdef __linux__
- DIR *d;
-
- if ((d = opendir("/proc/self/fd"))) {
- struct dirent *de;
-
- while ((de = readdir(d))) {
- glong l;
- gchar *e = NULL;
-
- if (de->d_name[0] == '.')
- continue;
-
- errno = 0;
- l = strtol(de->d_name, &e, 10);
- if (errno != 0 || !e || *e)
- continue;
-
- fd = (gint) l;
+#ifdef __linux__
+ /* Avoid use of opendir/closedir since these are not async-signal-safe. */
+ int dir_fd = open ("/proc/self/fd", O_RDONLY | O_DIRECTORY);
+ if (dir_fd >= 0)
+ {
+ char buf[4096];
+ int pos, nread;
+ struct linux_dirent64 *de;
- if ((glong) fd != l)
- continue;
+ while ((nread = syscall (SYS_getdents64, dir_fd, buf, sizeof(buf))) > 0)
+ {
+ for (pos = 0; pos < nread; pos += de->d_reclen)
+ {
+ de = (struct linux_dirent64 *)(buf + pos);
- if (fd == dirfd(d))
- continue;
+ fd = filename_to_fd (de->d_name);
+ if (fd < 0 || fd == dir_fd)
+ continue;
- if ((res = cb (data, fd)) != 0)
- break;
+ if ((res = cb (data, fd)) != 0)
+ break;
+ }
}
-
- closedir(d);
+
+ close (dir_fd);
return res;
- }
+ }
/* If /proc is not mounted or not accessible we fall back to the old
* rlimit trick */
#endif
-
+
#ifdef HAVE_SYS_RESOURCE_H
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY)
--
2.19.1

View File

@ -1,96 +0,0 @@
From bea37709353533e4abb1c652a655f483e6f9aeac Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Wed, 21 Mar 2018 14:47:52 +0000
Subject: [PATCH 121/682] =?UTF-8?q?gtask:=20Check=20an=20error=20hasn?=
=?UTF-8?q?=E2=80=99t=20been=20returned=20when=20calling=20g=5Ftask=5Fretu?=
=?UTF-8?q?rn*()?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These functions already check to see if a successful result has already
been returned; expand them to also check to see if an error has been
returned.
We cant just check GTask.result_set, as thats actually an indicator
for whether the GTask.result member is filled — when
g_task_propagate_*() is called, its cleared again. We need a new state
bit.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1525
---
gio/gtask.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/gio/gtask.c b/gio/gtask.c
index 4087543e6..a31bd613a 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -575,6 +575,7 @@ struct _GTask {
GDestroyNotify result_destroy;
gboolean had_error;
gboolean result_set;
+ gboolean ever_returned;
};
#define G_TASK_IS_THREADED(task) ((task)->task_func != NULL)
@@ -1176,6 +1177,9 @@ g_task_return (GTask *task,
{
GSource *source;
+ if (type != G_TASK_RETURN_FROM_THREAD)
+ task->ever_returned = TRUE;
+
if (type == G_TASK_RETURN_SUCCESS)
task->result_set = TRUE;
@@ -1596,7 +1600,7 @@ g_task_return_pointer (GTask *task,
GDestroyNotify result_destroy)
{
g_return_if_fail (G_IS_TASK (task));
- g_return_if_fail (task->result_set == FALSE);
+ g_return_if_fail (!task->ever_returned);
task->result.pointer = result;
task->result_destroy = result_destroy;
@@ -1654,7 +1658,7 @@ g_task_return_int (GTask *task,
gssize result)
{
g_return_if_fail (G_IS_TASK (task));
- g_return_if_fail (task->result_set == FALSE);
+ g_return_if_fail (!task->ever_returned);
task->result.size = result;
@@ -1709,7 +1713,7 @@ g_task_return_boolean (GTask *task,
gboolean result)
{
g_return_if_fail (G_IS_TASK (task));
- g_return_if_fail (task->result_set == FALSE);
+ g_return_if_fail (!task->ever_returned);
task->result.boolean = result;
@@ -1772,7 +1776,7 @@ g_task_return_error (GTask *task,
GError *error)
{
g_return_if_fail (G_IS_TASK (task));
- g_return_if_fail (task->result_set == FALSE);
+ g_return_if_fail (!task->ever_returned);
g_return_if_fail (error != NULL);
task->error = error;
@@ -1833,7 +1837,7 @@ g_task_return_error_if_cancelled (GTask *task)
GError *error = NULL;
g_return_val_if_fail (G_IS_TASK (task), FALSE);
- g_return_val_if_fail (task->result_set == FALSE, FALSE);
+ g_return_val_if_fail (!task->ever_returned, FALSE);
if (g_cancellable_set_error_if_cancelled (task->cancellable, &error))
{
--
2.19.1

View File

@ -1,77 +0,0 @@
From ae381d795e178740915defb23a4e54eb7791d8c6 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Sat, 5 Jan 2019 07:51:14 +0000
Subject: [PATCH 438/682] gtask: Ensure to return 1 or 0 from getters rather
than truthy ints
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since commit 290bb0dd, where various members of GTask were converted to
a bitfield, some of the getters:
• g_task_get_check_cancellable()
• g_task_get_return_on_cancel()
• g_task_get_completed()
have been returning truthy ints (zero or an arbitrary non-zero integer)
as boolean values, rather than the canonical boolean ints of 1 and 0.
This broke the `yield` statement in Vala, whose generated C code
compares `g_task_get_completed (…) != TRUE`. i.e. Whether the
`completed` field has a value not equal to 1.
Fix this by explicitly converting truthy ints to canonical boolean ints
in all getters.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1636
---
gio/gtask.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/gio/gtask.c b/gio/gtask.c
index a2f316d2e..aa98f752c 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -1132,7 +1132,8 @@ g_task_get_check_cancellable (GTask *task)
{
g_return_val_if_fail (G_IS_TASK (task), FALSE);
- return task->check_cancellable;
+ /* Convert from a bit field to a boolean. */
+ return task->check_cancellable ? TRUE : FALSE;
}
/**
@@ -1149,7 +1150,8 @@ g_task_get_return_on_cancel (GTask *task)
{
g_return_val_if_fail (G_IS_TASK (task), FALSE);
- return task->return_on_cancel;
+ /* Convert from a bit field to a boolean. */
+ return task->return_on_cancel ? TRUE : FALSE;
}
/**
@@ -1952,7 +1954,8 @@ g_task_get_completed (GTask *task)
{
g_return_val_if_fail (G_IS_TASK (task), FALSE);
- return task->completed;
+ /* Convert from a bit field to a boolean. */
+ return task->completed ? TRUE : FALSE;
}
/**
@@ -2055,7 +2058,7 @@ g_task_get_property (GObject *object,
switch ((GTaskProperty) prop_id)
{
case PROP_COMPLETED:
- g_value_set_boolean (value, task->completed);
+ g_value_set_boolean (value, g_task_get_completed (task));
break;
}
}
--
2.19.1

View File

@ -1,71 +0,0 @@
From feff178c3f5dadeff47228500a212a9be5688ba2 Mon Sep 17 00:00:00 2001
From: Fredrik Ternerot <fredrikt@axis.com>
Date: Fri, 14 Dec 2018 11:46:27 +0100
Subject: [PATCH 355/682] gtlscertificate: Fix bug in PEM private key parser
Make sure to not go outside of PEM data buffer when looking for private
key.
Also adding test case that triggers this bug.
---
gio/gtlscertificate.c | 2 +-
gio/tests/tls-certificate.c | 13 +++++++++++--
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index 9e497c58b..1ec48f118 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -258,7 +258,7 @@ parse_private_key (const gchar *data,
}
}
- end = g_strstr_len (start, data_len - (data - start), footer);
+ end = g_strstr_len (start, data_len - (start - data), footer);
if (!end)
{
g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c
index 4cc15d2d7..db2511f59 100644
--- a/gio/tests/tls-certificate.c
+++ b/gio/tests/tls-certificate.c
@@ -36,14 +36,16 @@ pem_parser (const Reference *ref)
{
GTlsCertificate *cert;
gchar *pem;
+ gsize pem_len = 0;
gchar *parsed_cert_pem = NULL;
const gchar *parsed_key_pem = NULL;
GError *error = NULL;
/* Check PEM parsing in certificate, private key order. */
- g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-key.pem", NULL), &pem, NULL, &error);
+ g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-key.pem", NULL), &pem, &pem_len, &error);
g_assert_no_error (error);
g_assert (pem);
+ g_assert_cmpuint (pem_len, >=, 10);
cert = g_tls_certificate_new_from_pem (pem, -1, &error);
g_assert_no_error (error);
@@ -61,10 +63,17 @@ pem_parser (const Reference *ref)
g_object_unref (cert);
- /* Make sure length is respected and parser detect invalid (truncated) PEM. */
+ /* Make sure length is respected and parser detect invalid PEM
+ * when cert is truncated. */
cert = g_tls_certificate_new_from_pem (pem, 10, &error);
g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
g_clear_error (&error);
+
+ /* Make sure length is respected and parser detect invalid PEM
+ * when cert exists but key is truncated. */
+ cert = g_tls_certificate_new_from_pem (pem, pem_len - 10, &error);
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
+ g_clear_error (&error);
g_free (pem);
/* Check PEM parsing in private key, certificate order */
--
2.19.1

View File

@ -1,35 +0,0 @@
From 624e99b9d6fa990a5b9afda771837aca7edadf8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ant=C3=B3nio=20Fernandes?= <antoniojpfernandes@gmail.com>
Date: Mon, 26 Nov 2018 12:27:59 +0000
Subject: [PATCH 306/682] gunixmounts: Don't treat ZFS as a system internal fs
ZFS was originally added to the list of system internal filesystems by
commit 4cafadc955d1c37118ca269ea22bbd37f8f2a2ce.
The rationale from https://bugzilla.gnome.org/show_bug.cgi?id=542156
doesn't seem very solid, and now we have x-gvfs-hide for this.
Also, this may contribute for trash:/// ignoring `{zfs mount path}/.Trash/`
So, remove zfs from the ignore_fs array.
Closes https://gitlab.gnome.org/GNOME/glib/issues/1599
---
gio/gunixmounts.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index 3c32d0e89..cc905f2fc 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -344,7 +344,6 @@ g_unix_is_system_fs_type (const char *fs_type)
"sysfs",
"tmpfs",
"usbfs",
- "zfs",
NULL
};
--
2.19.1

View File

@ -1,97 +0,0 @@
From eb7c9adc3b2570f6b82110b52a24609d124f38de Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Thu, 16 Aug 2018 20:12:02 +0100
Subject: [PATCH 160/682] gvariant: Fix checking arithmetic for tuple element
ends
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When checking whether a serialised GVariant tuple is in normal form,
its possible for `offset_ptr -= offset_size` to underflow and wrap
around, resulting in gvs_read_unaligned_le() reading memory outside the
serialised GVariant bounds.
See §(Tuples) in gvariant-serialiser.c for the documentation on how
tuples are serialised. Briefly, all variable-length elements in the
tuple have an offset to their end stored in an array of offsets at the
end of the tuple. The width of each offset is in offset_size. offset_ptr
is added to the start of the serialised tuple to get the offset which is
currently being examined. The offset array is in reverse order compared
to the tuple elements, hence the subtraction.
The bug can be triggered if a tuple contains a load of variable-length
elements, each of whose length is actually zero (i.e. empty arrays).
Includes a unit test.
oss-fuzz#9801
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gvariant-serialiser.c | 3 +++
glib/tests/gvariant.c | 28 ++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index 69f183121..96df54e23 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -1065,6 +1065,9 @@ gvs_tuple_is_normal (GVariantSerialised value)
break;
case G_VARIANT_MEMBER_ENDING_OFFSET:
+ if (offset_ptr < offset_size)
+ return FALSE;
+
offset_ptr -= offset_size;
if (offset_ptr < offset)
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index de8e42d0b..a5095a380 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4631,6 +4631,30 @@ test_stack_dict_init (void)
g_variant_unref (variant);
}
+/* Test checking arbitrary binary data for normal form. This time, its a tuple
+ * with invalid element ends. */
+static void
+test_normal_checking_tuples (void)
+{
+ const guint8 data[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 'a', '(', 'a', 'o', 'a', 'o', 'a', 'a', 'o', 'a', 'a', 'o', ')'
+ };
+ gsize size = sizeof (data);
+ GVariant *variant = NULL;
+ GVariant *normal_variant = NULL;
+
+ variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size,
+ FALSE, NULL, NULL);
+ g_assert_nonnull (variant);
+
+ normal_variant = g_variant_get_normal_form (variant);
+ g_assert_nonnull (normal_variant);
+
+ g_variant_unref (normal_variant);
+ g_variant_unref (variant);
+}
+
int
main (int argc, char **argv)
{
@@ -4692,5 +4716,9 @@ main (int argc, char **argv)
g_test_add_func ("/gvariant/stack-builder-init", test_stack_builder_init);
g_test_add_func ("/gvariant/stack-dict-init", test_stack_dict_init);
+
+ g_test_add_func ("/gvariant/normal-checking/tuples",
+ test_normal_checking_tuples);
+
return g_test_run ();
}
--
2.19.1

View File

@ -1,76 +0,0 @@
From d2224b475d20b544cf782ce046183209d419a012 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 4 Dec 2018 12:55:21 +0000
Subject: [PATCH 325/682] gvariant: Fix error handling for parsing Unicode
escapes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When parsing an escaped Unicode character in a text format GVariant
string, such as '\U0001F415', the code uses g_ascii_strtoull(). This,
unexpectedly, accepts minus signs, which can cause an assertion failure
when input like '\u-FF4' is presented for parsing.
Validate that there are no leading sign characters when parsing.
This shouldnt be considered a security bug, because the GVariant text
format parser should not be used on untrusted input.
oss-fuzz#11576
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gvariant-parser.c | 20 +++++++++++++++++---
glib/tests/gvariant.c | 20 ++++++++++++++++++--
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c
index 44e341965..b860d42f4 100644
--- a/glib/gvariant-parser.c
+++ b/glib/gvariant-parser.c
@@ -1528,6 +1528,8 @@ string_free (AST *ast)
g_slice_free (String, string);
}
+/* Accepts exactly @length hexadecimal digits. No leading sign or `0x`/`0X` prefix allowed.
+ * No leading/trailing space allowed. */
static gboolean
unicode_unescape (const gchar *src,
gint *src_ofs,
@@ -1538,8 +1540,9 @@ unicode_unescape (const gchar *src,
GError **error)
{
gchar buffer[9];
- guint64 value;
+ guint64 value = 0;
gchar *end;
+ gsize n_valid_chars;
(*src_ofs)++;
@@ -1547,11 +1550,22 @@ unicode_unescape (const gchar *src,
strncpy (buffer, src + *src_ofs, length);
buffer[length] = '\0';
- value = g_ascii_strtoull (buffer, &end, 0x10);
+ for (n_valid_chars = 0; n_valid_chars < length; n_valid_chars++)
+ if (!g_ascii_isxdigit (buffer[n_valid_chars]))
+ break;
+
+ if (n_valid_chars == length)
+ value = g_ascii_strtoull (buffer, &end, 0x10);
if (value == 0 || end != buffer + length)
{
- parser_set_error (error, ref, NULL,
+ SourceRef escape_ref;
+
+ escape_ref = *ref;
+ escape_ref.start += *src_ofs;
+ escape_ref.end = escape_ref.start + n_valid_chars;
+
+ parser_set_error (error, &escape_ref, NULL,
G_VARIANT_PARSE_ERROR_INVALID_CHARACTER,
"invalid %d-character unicode escape", length);
return FALSE;

View File

@ -1,134 +0,0 @@
From 0f2a6c61c9c5e34d57293fb6987b21f3d1feb1cb Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 13 Feb 2018 13:29:23 +0000
Subject: [PATCH 232/682] =?UTF-8?q?gvariant:=20Realign=20data=20on=20const?=
=?UTF-8?q?ruction=20if=20it=E2=80=99s=20not=20properly=20aligned?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Otherwise the GVariant would later fail internal alignment checks,
aborting the program.
If unaligned data is provided to (for example)
g_variant_new_from_data(), it will copy the data into a new aligned
allocation. This is slow, but better than crashing. If callers want
better performance, they should provide aligned data in their call, and
it will not be copied or reallocated.
Includes a unit test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1342
---
glib/gvariant-core.c | 46 +++++++++++++++++++++++++++++++++++++++--
glib/gvariant.c | 10 +++++++++
glib/tests/gvariant.c | 48 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+), 2 deletions(-)
diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
index 815bdf9e0..ef59c7049 100644
--- a/glib/gvariant-core.c
+++ b/glib/gvariant-core.c
@@ -506,6 +506,10 @@ g_variant_alloc (const GVariantType *type,
*
* A reference is taken on @bytes.
*
+ * The data in @bytes must be aligned appropriately for the @type being loaded.
+ * Otherwise this function will internally create a copy of the memory (since
+ * GLib 2.60) or (in older versions) fail and exit the process.
+ *
* Returns: (transfer none): a new #GVariant with a floating reference
*
* Since: 2.36
@@ -518,14 +522,50 @@ g_variant_new_from_bytes (const GVariantType *type,
GVariant *value;
guint alignment;
gsize size;
+ GBytes *owned_bytes = NULL;
value = g_variant_alloc (type, TRUE, trusted);
- value->contents.serialised.bytes = g_bytes_ref (bytes);
-
g_variant_type_info_query (value->type_info,
&alignment, &size);
+ /* Ensure the alignment is correct. This is a huge performance hit if its
+ * not correct, but thats better than aborting if a caller provides data
+ * with the wrong alignment (which is likely to happen very occasionally, and
+ * only cause an abort on some architectures — so is unlikely to be caught
+ * in testing). Callers can always actively ensure they use the correct
+ * alignment to avoid the performance hit. */
+ if ((alignment & (gsize) g_bytes_get_data (bytes, NULL)) != 0)
+ {
+#ifdef HAVE_POSIX_MEMALIGN
+ gpointer aligned_data = NULL;
+ gsize aligned_size = g_bytes_get_size (bytes);
+
+ /* posix_memalign() requires the alignment to be a multiple of
+ * sizeof(void*), and a power of 2. See g_variant_type_info_query() for
+ * details on the alignment format. */
+ if (posix_memalign (&aligned_data, MAX (sizeof (void *), alignment + 1),
+ aligned_size) != 0)
+ g_error ("posix_memalign failed");
+
+ memcpy (aligned_data, g_bytes_get_data (bytes, NULL), aligned_size);
+
+ bytes = owned_bytes = g_bytes_new_with_free_func (aligned_data,
+ aligned_size,
+ free, aligned_data);
+ aligned_data = NULL;
+#else
+ /* NOTE: there may be platforms that lack posix_memalign() and also
+ * have malloc() that returns non-8-aligned. if so, we need to try
+ * harder here.
+ */
+ bytes = owned_bytes = g_bytes_new (g_bytes_get_data (bytes, NULL),
+ g_bytes_get_size (bytes));
+#endif
+ }
+
+ value->contents.serialised.bytes = g_bytes_ref (bytes);
+
if (size && g_bytes_get_size (bytes) != size)
{
/* Creating a fixed-sized GVariant with a bytes of the wrong
@@ -543,6 +583,8 @@ g_variant_new_from_bytes (const GVariantType *type,
value->contents.serialised.data = g_bytes_get_data (bytes, &value->size);
}
+ g_clear_pointer (&owned_bytes, g_bytes_unref);
+
return value;
}
diff --git a/glib/gvariant.c b/glib/gvariant.c
index d45b487ad..983d4704c 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -307,6 +307,11 @@
* Constructs a new trusted #GVariant instance from the provided data.
* This is used to implement g_variant_new_* for all the basic types.
*
+ * Note: @data must be backed by memory that is aligned appropriately for the
+ * @type being loaded. Otherwise this function will internally create a copy of
+ * the memory (since GLib 2.60) or (in older versions) fail and exit the
+ * process.
+ *
* Returns: a new floating #GVariant
*/
static GVariant *
@@ -5986,6 +5991,11 @@ g_variant_byteswap (GVariant *value)
* needed. The exact time of this call is unspecified and might even be
* before this function returns.
*
+ * Note: @data must be backed by memory that is aligned appropriately for the
+ * @type being loaded. Otherwise this function will internally create a copy of
+ * the memory (since GLib 2.60) or (in older versions) fail and exit the
+ * process.
+ *
* Returns: (transfer none): a new floating #GVariant of type @type
*
* Since: 2.24

View File

@ -1,62 +0,0 @@
From e3e4a09716bca4e748a0156ee8cc50adb5cf8ec5 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Sat, 19 Jan 2019 01:07:57 +0000
Subject: [PATCH 482/682] gvariant-parser: Add explicit unsigned-to-signed
casts
Rather than prefixing unsigned numbers with unary minus operators and
expecting the implicit cast to carry the correct value through, add an
explicit cast to a signed type before the unary minus is applied.
In all four cases, an overflow check has already been done.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1655
---
glib/gvariant-parser.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c
index b860d42f4..2b02ec90f 100644
--- a/glib/gvariant-parser.c
+++ b/glib/gvariant-parser.c
@@ -1921,7 +1921,7 @@ number_get_value (AST *ast,
case 'n':
if (abs_val - negative > G_MAXINT16)
return number_overflow (ast, type, error);
- return g_variant_new_int16 (negative ? -abs_val : abs_val);
+ return g_variant_new_int16 (negative ? -((gint16) abs_val) : abs_val);
case 'q':
if (negative || abs_val > G_MAXUINT16)
@@ -1931,7 +1931,7 @@ number_get_value (AST *ast,
case 'i':
if (abs_val - negative > G_MAXINT32)
return number_overflow (ast, type, error);
- return g_variant_new_int32 (negative ? -abs_val : abs_val);
+ return g_variant_new_int32 (negative ? -((gint32) abs_val) : abs_val);
case 'u':
if (negative || abs_val > G_MAXUINT32)
@@ -1941,7 +1941,7 @@ number_get_value (AST *ast,
case 'x':
if (abs_val - negative > G_MAXINT64)
return number_overflow (ast, type, error);
- return g_variant_new_int64 (negative ? -abs_val : abs_val);
+ return g_variant_new_int64 (negative ? -((gint64) abs_val) : abs_val);
case 't':
if (negative)
@@ -1951,7 +1951,7 @@ number_get_value (AST *ast,
case 'h':
if (abs_val - negative > G_MAXINT32)
return number_overflow (ast, type, error);
- return g_variant_new_handle (negative ? -abs_val : abs_val);
+ return g_variant_new_handle (negative ? -((gint32) abs_val) : abs_val);
default:
return ast_type_error (ast, type, error);
--
2.19.1

View File

@ -1,88 +0,0 @@
From c927c59a8426be62f9e9b19e40c862f88b4c17be Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 5 Feb 2019 15:50:15 +0000
Subject: [PATCH 563/682] gvariant-parser: Fix error handling when type
coalescing fails
When parsing GVariant text format strings, we do a limited form of type
inference. The algorithm for type inference for nested array child types
is not complete, however (and making it complete, at least with a naive
implementation, would make it O(N^2), which is not worth it) and so some
text format arrays were triggering an assertion failure in the error
handling code.
Fix that by making the error handling code a little more relaxed, in the
knowledge that our type inference algorithm is not complete. See the
comment added to the code.
This includes a test case, provided by oss-fuzz.
oss-fuzz#11578
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gvariant-parser.c | 28 ++++++++++++++++++++++++++--
glib/tests/gvariant.c | 1 +
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c
index 2b02ec90f..3b4956a9c 100644
--- a/glib/gvariant-parser.c
+++ b/glib/gvariant-parser.c
@@ -671,6 +671,20 @@ ast_array_get_pattern (AST **array,
gchar *pattern;
gint i;
+ /* Find the pattern which applies to all children in the array, by l-folding a
+ * coalesce operation. This will not always work: for example, the GVariant:
+ * [[0], [], [nothing]]
+ * has patterns:
+ * MaMN, Ma*, Mam*
+ * which pairwise coalesce as:
+ * MaMN + Ma* = MaN
+ * MaN + Mam* = (doesnt coalesce)
+ *
+ * However, the pattern MamN coalesces with all three child patterns. Finding
+ * this pattern would require trying all O(n_items^2) pairs, though, which is
+ * expensive. Just let it fail, and require the user to provide type
+ * annotations.
+ */
pattern = ast_get_pattern (array[0], error);
if (pattern == NULL)
@@ -705,8 +719,18 @@ ast_array_get_pattern (AST **array,
gchar *tmp2;
gchar *m;
- /* if 'j' reaches 'i' then we failed to find the pair */
- g_assert (j < i);
+ /* if 'j' reaches 'i' then we failed to find the pair, which can
+ * happen due to only trying pairwise coalesces in order rather
+ * than between all pairs (see above). so just report an error
+ * for i. */
+ if (j >= i)
+ {
+ ast_set_error (array[i], error, NULL,
+ G_VARIANT_PARSE_ERROR_NO_COMMON_TYPE,
+ "unable to find a common type");
+ g_free (tmp);
+ return NULL;
+ }
tmp2 = ast_get_pattern (array[j], NULL);
g_assert (tmp2 != NULL);
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index 33caaf04a..80bc7caf4 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -3943,6 +3943,7 @@ test_parse_failures (void)
"[4, 5, '']", "1-2,7-9:", "common type",
"[[4], [], ['']]", "1-4,10-14:", "common type",
"[[], [4], ['']]", "5-8,10-14:", "common type",
+ "[[0], [], [nothing]]", "10-19:", "common type",
"just", "4:", "expected value",
"nothing", "0-7:", "unable to infer",
"just [4, '']", "6-7,9-11:", "common type",
--
2.19.1

View File

@ -1,117 +0,0 @@
From 0fcd5ac89d442845254939870107cef40bafceef Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 5 Feb 2019 13:47:25 +0000
Subject: [PATCH 562/682] gvariant-parser: Fix parsing of G_MININT* values in
GVariant text format
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
And add tests.
There wasnt actually a bug on x86_64 before, but it was making use of
undefined behaviour, and hence triggering ubsan warnings. Make the code
more explicit, and avoid undefined behaviour.
oss-fuzz#12686
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gvariant-parser.c | 8 ++++++++
glib/tests/gvariant.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c
index 2b02ec90f..ea1ca22e4 100644
--- a/glib/gvariant-parser.c
+++ b/glib/gvariant-parser.c
@@ -1921,6 +1921,8 @@ number_get_value (AST *ast,
case 'n':
if (abs_val - negative > G_MAXINT16)
return number_overflow (ast, type, error);
+ if (negative && abs_val > G_MAXINT16)
+ return g_variant_new_int16 (G_MININT16);
return g_variant_new_int16 (negative ? -((gint16) abs_val) : abs_val);
case 'q':
@@ -1931,6 +1933,8 @@ number_get_value (AST *ast,
case 'i':
if (abs_val - negative > G_MAXINT32)
return number_overflow (ast, type, error);
+ if (negative && abs_val > G_MAXINT32)
+ return g_variant_new_int32 (G_MININT32);
return g_variant_new_int32 (negative ? -((gint32) abs_val) : abs_val);
case 'u':
@@ -1941,6 +1945,8 @@ number_get_value (AST *ast,
case 'x':
if (abs_val - negative > G_MAXINT64)
return number_overflow (ast, type, error);
+ if (negative && abs_val > G_MAXINT64)
+ return g_variant_new_int64 (G_MININT64);
return g_variant_new_int64 (negative ? -((gint64) abs_val) : abs_val);
case 't':
@@ -1951,6 +1957,8 @@ number_get_value (AST *ast,
case 'h':
if (abs_val - negative > G_MAXINT32)
return number_overflow (ast, type, error);
+ if (negative && abs_val > G_MAXINT32)
+ return g_variant_new_handle (G_MININT32);
return g_variant_new_handle (negative ? -((gint32) abs_val) : abs_val);
default:
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index 33caaf04a..4a3aa771f 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4097,6 +4097,38 @@ test_parse_failures (void)
}
}
+/* Test that parsing GVariant text format integers works at the boundaries of
+ * those integer types. Were especially interested in the handling of the most
+ * negative numbers, since those cant be represented in sign + absolute value
+ * form. */
+static void
+test_parser_integer_bounds (void)
+{
+ GVariant *value = NULL;
+ GError *local_error = NULL;
+
+#define test_bound(TYPE, type, text, expected_value) \
+ value = g_variant_parse (G_VARIANT_TYPE_##TYPE, text, NULL, NULL, &local_error); \
+ g_assert_no_error (local_error); \
+ g_assert_nonnull (value); \
+ g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_##TYPE)); \
+ g_assert_cmpint (g_variant_get_##type (value), ==, expected_value); \
+ g_variant_unref (value)
+
+ test_bound (BYTE, byte, "0", 0);
+ test_bound (BYTE, byte, "255", G_MAXUINT8);
+ test_bound (INT16, int16, "-32768", G_MININT16);
+ test_bound (INT16, int16, "32767", G_MAXINT16);
+ test_bound (INT32, int32, "-2147483648", G_MININT32);
+ test_bound (INT32, int32, "2147483647", G_MAXINT32);
+ test_bound (INT64, int64, "-9223372036854775808", G_MININT64);
+ test_bound (INT64, int64, "9223372036854775807", G_MAXINT64);
+ test_bound (HANDLE, handle, "-2147483648", G_MININT32);
+ test_bound (HANDLE, handle, "2147483647", G_MAXINT32);
+
+#undef test_bound
+}
+
static void
test_parse_bad_format_char (void)
{
@@ -5068,6 +5100,7 @@ main (int argc, char **argv)
g_test_add_func ("/gvariant/hashing", test_hashing);
g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
g_test_add_func ("/gvariant/parser", test_parses);
+ g_test_add_func ("/gvariant/parser/integer-bounds", test_parser_integer_bounds);
g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
g_test_add_func ("/gvariant/parse/subprocess/bad-format-char", test_parse_bad_format_char);
--
2.19.1

View File

@ -1,36 +0,0 @@
From d8a0dcb11e92d3237f5f4e90a4916df518bdc53d Mon Sep 17 00:00:00 2001
From: Matthias Clasen <mclasen@redhat.com>
Date: Sun, 6 Jan 2019 14:17:30 -0500
Subject: [PATCH 441/682] list store: Fix overflow issues
Check for over- and underflow when manipulating positions.
This makes the sequence
g_list_model_get_item (store, 0);
g_list_model_get_item (store, -1u);
return NULL for the second call, as it should.
Closes: #1639
---
gio/gliststore.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gio/gliststore.c b/gio/gliststore.c
index ae8e2c1d8..8d87159d5 100644
--- a/gio/gliststore.c
+++ b/gio/gliststore.c
@@ -181,9 +181,9 @@ g_list_store_get_item (GListModel *list,
if (store->last_position != -1u)
{
- if (store->last_position == position + 1)
+ if (position < G_MAXUINT && store->last_position == position + 1)
it = g_sequence_iter_prev (store->last_iter);
- else if (store->last_position == position - 1)
+ else if (position > 0 && store->last_position == position - 1)
it = g_sequence_iter_next (store->last_iter);
else if (store->last_position == position)
it = store->last_iter;
--
2.19.1