!2 glib2: update to 2.62.1
Merge pull request !2 from algorithmofdish/master
This commit is contained in:
commit
4e88124967
@ -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 Lan’s 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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. It’s 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
|
||||
|
||||
@ -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 it’s 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
|
||||
|
||||
@ -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);
|
||||
@ -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
|
||||
|
||||
@ -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", "23∶15");
|
||||
+
|
||||
+ 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
BIN
glib-2.62.1.tar.xz
Normal file
Binary file not shown.
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>
|
||||
@ -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
|
||||
|
||||
154
glib2.spec
154
glib2.spec
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 we’re 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
|
||||
|
||||
@ -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
|
||||
didn’t. 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
+
|
||||
+ /* Don’t 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 can’t just check GTask.result_set, as that’s actually an indicator
|
||||
for whether the GTask.result member is filled — when
|
||||
g_task_propagate_*() is called, it’s 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
it’s 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, it’s 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
|
||||
|
||||
@ -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 shouldn’t 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;
|
||||
@ -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 it’s
|
||||
+ * not correct, but that’s 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
|
||||
@ -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
|
||||
|
||||
@ -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* = (doesn’t 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
|
||||
|
||||
@ -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 wasn’t 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. We’re especially interested in the handling of the most
|
||||
+ * negative numbers, since those can’t 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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user