From ceeeb463cc1eef97fd62eaee8bf2196ba04bc384 Mon Sep 17 00:00:00 2001 From: V3n3RiX Date: Sat, 29 Feb 2020 18:01:47 +0000 Subject: gentoo (leap year) resync : 29.02.2020 --- dev-libs/glib/Manifest | 4 + dev-libs/glib/files/CVE-2020-6750.patch | 763 ++++++++++++++++++++++++++++++++ dev-libs/glib/glib-2.60.7-r2.ebuild | 280 ++++++++++++ dev-libs/glib/glib-2.62.5.ebuild | 274 ++++++++++++ 4 files changed, 1321 insertions(+) create mode 100644 dev-libs/glib/files/CVE-2020-6750.patch create mode 100644 dev-libs/glib/glib-2.60.7-r2.ebuild create mode 100644 dev-libs/glib/glib-2.62.5.ebuild (limited to 'dev-libs/glib') diff --git a/dev-libs/glib/Manifest b/dev-libs/glib/Manifest index 17a372902e20..734ef4e645ec 100644 --- a/dev-libs/glib/Manifest +++ b/dev-libs/glib/Manifest @@ -1,5 +1,9 @@ AUX 2.60.7-gdbus-fixes.patch 10740 BLAKE2B 0e42e8444c6308aebdeb240c935969015758bef744a21c4fa9d87eec6e52c0422660ad8ce6f2a2c1caf66369b66e8e7979345449a5322f37bed54f607df82473 SHA512 dbee2969935cb3d24d9bd518c78a02b815ff3bb468d1b04acef50ccd8dd5c38b7121a12f69df51d8a6f9944342e3101fe0bf5b3d87e3ae9e65257238769548eb +AUX CVE-2020-6750.patch 29371 BLAKE2B df3061eaa5de4115143d52fac6663c791bd5f1d1d3272d4311f49119896bee94fce9035b315dafd267164664bc9fb11798edb6f98975df2ce26f742acf00b1d6 SHA512 6f3da1db841503072d6f88b188ffa869eb07bfb918286ddbce780f114cae2da0024202a166a4b3913b51aa070cd1a98a9993f2516762e2bc2114122731a9720d DIST glib-2.60.7.tar.xz 4590568 BLAKE2B a3f2a3bd0443a27326e8359c2ad1e6022ca1634f5c7cb4502a8011fbe85df690fff7d67665cf160bf4ed426214b87f6501a69158fb1656bdb86cacdcf076ee15 SHA512 d56d805a5abf6f7aeb8bf5be06b60ad049177ee23f78eacef4ce2ea88a8be49966a95e48fed17c752649f6e80937fd0ebc8f959709f623ec1f2f43ffd42d078a +DIST glib-2.62.5.tar.xz 4702492 BLAKE2B 03e04cb149b3301959013c5db20b1f3606951ed80105e0580d40177586a5834afb975ace0d25d5311fd63d29a48129128bdddf29a808e371f1400c00033be1a3 SHA512 2f99422ff8245524aabdb52f5d388ef4bde0fc075eab24499b4023f6ca143b80a74e265117b9e7a9de68a347b0c7eaa8655c836d7bbb63d54cad5c6dda630371 EBUILD glib-2.60.7-r1.ebuild 10217 BLAKE2B 9e5876c643608eaf57768487a465d4951e208b1b4e636d2bdf13f2b1c846199a049f607911a302a30736dfa9357db26dbbdffc93751ac8a05f063c2df4c4dbe8 SHA512 b5e050362d94e3f7729c0cd05c66535c159224966c952de4310dbd2efbff71925e173277e9da73c5cccb3a43fb8c82c5a550648dc7c3231065c6547726cf495a +EBUILD glib-2.60.7-r2.ebuild 10260 BLAKE2B 2ff6270ad53d0bbc49eab6a9451784d6918d38174522c760153a824e5dd1a597b39b8a59327f3adc48634835c7b0166a1911bfb9abc73a2aaf47e8f66442ce9f SHA512 dcf8db458d27f6e9eb92a43d05033353b86ce05ef21179aa516e87f07b17f46b51fef283ee499c4bc44b2fd32e430f7fd0ffd211996e256ccd810c916822fbe1 EBUILD glib-2.60.7.ebuild 10139 BLAKE2B bed62a53ad8276a891f54acf41ebf6cbced7cd942dd5af0e5a49f3a13057457d9186487a9ea30aafce9c7a04e4d514b3241e41166ef3ddec48a0e580b41f0a7c SHA512 1b3de610aa4102181d8a8c7f0dd47086aa2c51b85a187f002224e5a04d41a0b56510958917c60b3df2f3607ad5f431e322681f1e62ce5b96c1223e23a5eef09f +EBUILD glib-2.62.5.ebuild 9791 BLAKE2B f6ad592e6b12ae7eebbf5a7722467b21b85fdbef82782069466d089e47f1b39b481a6ddb875de755472b4cede6e7b4cb9786aa49cdbfbefcadc5b199a013dc85 SHA512 0b84aa2cf7aa0f6eaa61478343c4e5981c4fb5d0146b443f76684c097dc05172f8c8e42bf822e43f33ec8cb369f31aaac2ef9c3b97da23392c13a1e96683158f MISC metadata.xml 978 BLAKE2B 75f0c12ff1628b7c345b1e85c6baa041973f11555aa520348ca6f347d2241ee0fc9bc26891b25bd34ae512dbaf761b5382d93f094dc0c4ff9a76c3ec852c9583 SHA512 8087f80cbbffb14930b50178559cc4dbde999d4e123475beb04e2d0a25e64b24ee5ab8523f1df1839e82f74272b40cd9a57b78acf34fd64f8b4723bed26573c8 diff --git a/dev-libs/glib/files/CVE-2020-6750.patch b/dev-libs/glib/files/CVE-2020-6750.patch new file mode 100644 index 000000000000..fe39914f9204 --- /dev/null +++ b/dev-libs/glib/files/CVE-2020-6750.patch @@ -0,0 +1,763 @@ +From cc3cf6b8b2ad12d54f3474113f0ccfa7dcf66b7b Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Sat, 4 Jan 2020 20:46:25 -0600 +Subject: [PATCH] gsocketclient: run timeout source on the task's main context + +This shouldn't make any difference, because this code should only ever +be running in the main context that was thread-default at the time the +task was created, so it should already match the task's context. But +let's make sure, just in case. +--- + gio/gsocketclient.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c +index 6adeee299..81721795b 100644 +--- a/gio/gsocketclient.c ++++ b/gio/gsocketclient.c +@@ -1794,7 +1794,7 @@ g_socket_client_enumerator_callback (GObject *object, + attempt->connection = (GIOStream *)g_socket_connection_factory_create_connection (socket); + attempt->timeout_source = g_timeout_source_new (HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS); + g_source_set_callback (attempt->timeout_source, on_connection_attempt_timeout, attempt, NULL); +- g_source_attach (attempt->timeout_source, g_main_context_get_thread_default ()); ++ g_source_attach (attempt->timeout_source, g_task_get_context (data->task)); + data->connection_attempts = g_slist_append (data->connection_attempts, attempt); + + if (g_task_get_cancellable (data->task)) +-- +2.24.1 + +From d4fcf91460696b09bb2b55c352a023f6dd71c7fe Mon Sep 17 00:00:00 2001 +From: Patrick Griffis +Date: Thu, 23 Jan 2020 19:58:41 -0800 +Subject: [PATCH] Refactor g_socket_client_connect_async() + +This is a fairly large refactoring. The highlights are: + +- Removing in-progress connections/addresses from GSocketClientAsyncConnectData: + + This caused issues where multiple ConnectionAttempt's would step over eachother + and modify shared state causing bugs like accidentally bypassing a set proxy. + + Fixes #1871 + Fixes #1989 + Fixes #1902 + +- Cancelling address enumeration on error/completion + +- Queuing successful TCP connections and doing application layer work serially: + + This is more in the spirit of Happy Eyeballs but it also greatly simplifies + the flow of connection handling so fewer tasks are happening in parallel + when they don't need to be. + + The behavior also should more closely match that of g_socket_client_connect(). + +- Better track the state of address enumeration: + + Previously we were over eager to treat enumeration finishing as an error. + + Fixes #1872 + See also #1982 + +- Add more detailed documentation and logging. + +Closes #1995 +--- + gio/gsocketclient.c | 459 ++++++++++++++++++++++++++++---------------- + 1 file changed, 296 insertions(+), 163 deletions(-) + +diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c +index 81721795b..c9943309c 100644 +--- a/gio/gsocketclient.c ++++ b/gio/gsocketclient.c +@@ -1337,13 +1337,15 @@ typedef struct + + GSocketConnectable *connectable; + GSocketAddressEnumerator *enumerator; +- GProxyAddress *proxy_addr; +- GSocket *socket; +- GIOStream *connection; ++ GCancellable *enumeration_cancellable; + + GSList *connection_attempts; ++ GSList *successful_connections; + GError *last_error; + ++ gboolean enumerated_at_least_once; ++ gboolean enumeration_completed; ++ gboolean connection_in_progress; + gboolean completed; + } GSocketClientAsyncConnectData; + +@@ -1355,10 +1357,9 @@ g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data) + data->task = NULL; + g_clear_object (&data->connectable); + g_clear_object (&data->enumerator); +- g_clear_object (&data->proxy_addr); +- g_clear_object (&data->socket); +- g_clear_object (&data->connection); ++ g_clear_object (&data->enumeration_cancellable); + g_slist_free_full (data->connection_attempts, connection_attempt_unref); ++ g_slist_free_full (data->successful_connections, connection_attempt_unref); + + g_clear_error (&data->last_error); + +@@ -1370,6 +1371,7 @@ typedef struct + GSocketAddress *address; + GSocket *socket; + GIOStream *connection; ++ GProxyAddress *proxy_addr; + GSocketClientAsyncConnectData *data; /* unowned */ + GSource *timeout_source; + GCancellable *cancellable; +@@ -1401,6 +1403,7 @@ connection_attempt_unref (gpointer pointer) + g_clear_object (&attempt->socket); + g_clear_object (&attempt->connection); + g_clear_object (&attempt->cancellable); ++ g_clear_object (&attempt->proxy_addr); + if (attempt->timeout_source) + { + g_source_destroy (attempt->timeout_source); +@@ -1418,37 +1421,59 @@ connection_attempt_remove (ConnectionAttempt *attempt) + } + + static void +-g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data) ++cancel_all_attempts (GSocketClientAsyncConnectData *data) + { +- g_assert (data->connection); ++ GSList *l; + +- if (!G_IS_SOCKET_CONNECTION (data->connection)) ++ for (l = data->connection_attempts; l; l = g_slist_next (l)) + { +- GSocketConnection *wrapper_connection; +- +- wrapper_connection = g_tcp_wrapper_connection_new (data->connection, data->socket); +- g_object_unref (data->connection); +- data->connection = (GIOStream *)wrapper_connection; ++ ConnectionAttempt *attempt_entry = l->data; ++ g_cancellable_cancel (attempt_entry->cancellable); ++ connection_attempt_unref (attempt_entry); + } ++ g_slist_free (data->connection_attempts); ++ data->connection_attempts = NULL; + +- if (!data->completed) ++ g_slist_free_full (data->successful_connections, connection_attempt_unref); ++ data->successful_connections = NULL; ++ ++ g_cancellable_cancel (data->enumeration_cancellable); ++} ++ ++static void ++g_socket_client_async_connect_complete (ConnectionAttempt *attempt) ++{ ++ GSocketClientAsyncConnectData *data = attempt->data; ++ GError *error = NULL; ++ g_assert (attempt->connection); ++ g_assert (!data->completed); ++ ++ if (!G_IS_SOCKET_CONNECTION (attempt->connection)) + { +- GError *error = NULL; ++ GSocketConnection *wrapper_connection; + +- if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable (data->task), &error)) +- { +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); +- g_task_return_error (data->task, g_steal_pointer (&error)); +- } +- else +- { +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, data->connection); +- g_task_return_pointer (data->task, g_steal_pointer (&data->connection), g_object_unref); +- } ++ wrapper_connection = g_tcp_wrapper_connection_new (attempt->connection, attempt->socket); ++ g_object_unref (attempt->connection); ++ attempt->connection = (GIOStream *)wrapper_connection; ++ } + +- data->completed = TRUE; ++ data->completed = TRUE; ++ cancel_all_attempts (data); ++ ++ if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable (data->task), &error)) ++ { ++ g_debug ("GSocketClient: Connection cancelled!"); ++ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); ++ g_task_return_error (data->task, g_steal_pointer (&error)); ++ } ++ else ++ { ++ g_debug ("GSocketClient: Connection successful!"); ++ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, attempt->connection); ++ g_task_return_pointer (data->task, g_steal_pointer (&attempt->connection), g_object_unref); + } + ++ connection_attempt_unref (attempt); + g_object_unref (data->task); + } + +@@ -1470,59 +1495,63 @@ static void + enumerator_next_async (GSocketClientAsyncConnectData *data, + gboolean add_task_ref) + { +- /* We need to cleanup the state */ +- g_clear_object (&data->socket); +- g_clear_object (&data->proxy_addr); +- g_clear_object (&data->connection); +- + /* Each enumeration takes a ref. This arg just avoids repeated unrefs when + an enumeration starts another enumeration */ + if (add_task_ref) + g_object_ref (data->task); + + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, data->connectable, NULL); ++ g_debug ("GSocketClient: Starting new address enumeration"); + g_socket_address_enumerator_next_async (data->enumerator, +- g_task_get_cancellable (data->task), ++ data->enumeration_cancellable, + g_socket_client_enumerator_callback, + data); + } + ++static void try_next_connection_or_finish (GSocketClientAsyncConnectData *, gboolean); ++ + static void + g_socket_client_tls_handshake_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) + { +- GSocketClientAsyncConnectData *data = user_data; ++ ConnectionAttempt *attempt = user_data; ++ GSocketClientAsyncConnectData *data = attempt->data; + + if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (object), + result, + &data->last_error)) + { +- g_object_unref (data->connection); +- data->connection = G_IO_STREAM (object); ++ g_object_unref (attempt->connection); ++ attempt->connection = G_IO_STREAM (object); + +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, data->connection); +- g_socket_client_async_connect_complete (data); ++ g_debug ("GSocketClient: TLS handshake succeeded"); ++ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, attempt->connection); ++ g_socket_client_async_connect_complete (attempt); + } + else + { + g_object_unref (object); +- enumerator_next_async (data, FALSE); ++ connection_attempt_unref (attempt); ++ g_debug ("GSocketClient: TLS handshake failed: %s", data->last_error->message); ++ try_next_connection_or_finish (data, TRUE); + } + } + + static void +-g_socket_client_tls_handshake (GSocketClientAsyncConnectData *data) ++g_socket_client_tls_handshake (ConnectionAttempt *attempt) + { ++ GSocketClientAsyncConnectData *data = attempt->data; + GIOStream *tlsconn; + + if (!data->client->priv->tls) + { +- g_socket_client_async_connect_complete (data); ++ g_socket_client_async_connect_complete (attempt); + return; + } + +- tlsconn = g_tls_client_connection_new (data->connection, ++ g_debug ("GSocketClient: Starting TLS handshake"); ++ tlsconn = g_tls_client_connection_new (attempt->connection, + data->connectable, + &data->last_error); + if (tlsconn) +@@ -1534,11 +1563,12 @@ g_socket_client_tls_handshake (GSocketClientAsyncConnectData *data) + G_PRIORITY_DEFAULT, + g_task_get_cancellable (data->task), + g_socket_client_tls_handshake_callback, +- data); ++ attempt); + } + else + { +- enumerator_next_async (data, FALSE); ++ connection_attempt_unref (attempt); ++ try_next_connection_or_finish (data, TRUE); + } + } + +@@ -1547,23 +1577,38 @@ g_socket_client_proxy_connect_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) + { +- GSocketClientAsyncConnectData *data = user_data; ++ ConnectionAttempt *attempt = user_data; ++ GSocketClientAsyncConnectData *data = attempt->data; + +- g_object_unref (data->connection); +- data->connection = g_proxy_connect_finish (G_PROXY (object), +- result, +- &data->last_error); +- if (data->connection) ++ g_object_unref (attempt->connection); ++ attempt->connection = g_proxy_connect_finish (G_PROXY (object), ++ result, ++ &data->last_error); ++ if (attempt->connection) + { +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, data->connection); ++ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, attempt->connection); + } + else + { +- enumerator_next_async (data, FALSE); ++ connection_attempt_unref (attempt); ++ try_next_connection_or_finish (data, TRUE); + return; + } + +- g_socket_client_tls_handshake (data); ++ g_socket_client_tls_handshake (attempt); ++} ++ ++static void ++complete_connection_with_error (GSocketClientAsyncConnectData *data, ++ GError *error) ++{ ++ g_debug ("GSocketClient: Connection failed: %s", error->message); ++ g_assert (!data->completed); ++ ++ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); ++ data->completed = TRUE; ++ cancel_all_attempts (data); ++ g_task_return_error (data->task, error); + } + + static gboolean +@@ -1577,15 +1622,114 @@ task_completed_or_cancelled (GSocketClientAsyncConnectData *data) + return TRUE; + else if (g_cancellable_set_error_if_cancelled (cancellable, &error)) + { +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); +- g_task_return_error (task, g_steal_pointer (&error)); +- data->completed = TRUE; ++ complete_connection_with_error (data, g_steal_pointer (&error)); + return TRUE; + } + else + return FALSE; + } + ++static gboolean ++try_next_successful_connection (GSocketClientAsyncConnectData *data) ++{ ++ ConnectionAttempt *attempt; ++ const gchar *protocol; ++ GProxy *proxy; ++ ++ if (data->connection_in_progress) ++ return FALSE; ++ ++ g_assert (data->successful_connections != NULL); ++ attempt = data->successful_connections->data; ++ g_assert (attempt != NULL); ++ data->successful_connections = g_slist_remove (data->successful_connections, attempt); ++ data->connection_in_progress = TRUE; ++ ++ g_debug ("GSocketClient: Starting application layer connection"); ++ ++ if (!attempt->proxy_addr) ++ { ++ g_socket_client_tls_handshake (g_steal_pointer (&attempt)); ++ return TRUE; ++ } ++ ++ protocol = g_proxy_address_get_protocol (attempt->proxy_addr); ++ ++ /* The connection should not be anything other than TCP, ++ * but let's put a safety guard in case ++ */ ++ if (!G_IS_TCP_CONNECTION (attempt->connection)) ++ { ++ g_critical ("Trying to proxy over non-TCP connection, this is " ++ "most likely a bug in GLib IO library."); ++ ++ g_set_error_literal (&data->last_error, ++ G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, ++ _("Proxying over a non-TCP connection is not supported.")); ++ } ++ else if (g_hash_table_contains (data->client->priv->app_proxies, protocol)) ++ { ++ /* Simply complete the connection, we don't want to do TLS handshake ++ * as the application proxy handling may need proxy handshake first */ ++ g_socket_client_async_connect_complete (g_steal_pointer (&attempt)); ++ return TRUE; ++ } ++ else if ((proxy = g_proxy_get_default_for_protocol (protocol))) ++ { ++ GIOStream *connection = attempt->connection; ++ GProxyAddress *proxy_addr = attempt->proxy_addr; ++ ++ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, attempt->connection); ++ g_debug ("GSocketClient: Starting proxy connection"); ++ g_proxy_connect_async (proxy, ++ connection, ++ proxy_addr, ++ g_task_get_cancellable (data->task), ++ g_socket_client_proxy_connect_callback, ++ g_steal_pointer (&attempt)); ++ g_object_unref (proxy); ++ return TRUE; ++ } ++ else ++ { ++ g_clear_error (&data->last_error); ++ ++ g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, ++ _("Proxy protocol ā€œ%sā€ is not supported."), ++ protocol); ++ } ++ ++ data->connection_in_progress = FALSE; ++ g_clear_pointer (&attempt, connection_attempt_unref); ++ return FALSE; /* All non-return paths are failures */ ++} ++ ++static void ++try_next_connection_or_finish (GSocketClientAsyncConnectData *data, ++ gboolean end_current_connection) ++{ ++ if (end_current_connection) ++ data->connection_in_progress = FALSE; ++ ++ if (data->connection_in_progress) ++ return; ++ ++ /* Keep trying successful connections until one works, each iteration pops one */ ++ while (data->successful_connections) ++ { ++ if (try_next_successful_connection (data)) ++ return; ++ } ++ ++ if (!data->enumeration_completed) ++ { ++ enumerator_next_async (data, FALSE); ++ return; ++ } ++ ++ complete_connection_with_error (data, data->last_error); ++} ++ + static void + g_socket_client_connected_callback (GObject *source, + GAsyncResult *result, +@@ -1593,10 +1737,7 @@ g_socket_client_connected_callback (GObject *source, + { + ConnectionAttempt *attempt = user_data; + GSocketClientAsyncConnectData *data = attempt->data; +- GSList *l; + GError *error = NULL; +- GProxy *proxy; +- const gchar *protocol; + + if (task_completed_or_cancelled (data) || g_cancellable_is_cancelled (attempt->cancellable)) + { +@@ -1618,11 +1759,12 @@ g_socket_client_connected_callback (GObject *source, + { + clarify_connect_error (error, data->connectable, attempt->address); + set_last_error (data, error); ++ g_debug ("GSocketClient: Connection attempt failed: %s", error->message); + connection_attempt_remove (attempt); +- enumerator_next_async (data, FALSE); + connection_attempt_unref (attempt); ++ try_next_connection_or_finish (data, FALSE); + } +- else ++ else /* Silently ignore cancelled attempts */ + { + g_clear_error (&error); + g_object_unref (data->task); +@@ -1632,74 +1774,21 @@ g_socket_client_connected_callback (GObject *source, + return; + } + +- data->socket = g_steal_pointer (&attempt->socket); +- data->connection = g_steal_pointer (&attempt->connection); +- +- for (l = data->connection_attempts; l; l = g_slist_next (l)) +- { +- ConnectionAttempt *attempt_entry = l->data; +- g_cancellable_cancel (attempt_entry->cancellable); +- connection_attempt_unref (attempt_entry); +- } +- g_slist_free (data->connection_attempts); +- data->connection_attempts = NULL; +- connection_attempt_unref (attempt); +- +- g_socket_connection_set_cached_remote_address ((GSocketConnection*)data->connection, NULL); +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, data->connectable, data->connection); ++ g_socket_connection_set_cached_remote_address ((GSocketConnection*)attempt->connection, NULL); ++ g_debug ("GSocketClient: TCP connection successful"); ++ g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, data->connectable, attempt->connection); + + /* wrong, but backward compatible */ +- g_socket_set_blocking (data->socket, TRUE); ++ g_socket_set_blocking (attempt->socket, TRUE); + +- if (!data->proxy_addr) +- { +- g_socket_client_tls_handshake (data); +- return; +- } +- +- protocol = g_proxy_address_get_protocol (data->proxy_addr); +- +- /* The connection should not be anything other than TCP, +- * but let's put a safety guard in case ++ /* This ends the parallel "happy eyeballs" portion of connecting. ++ Now that we have a successful tcp connection we will attempt to connect ++ at the TLS/Proxy layer. If those layers fail we will move on to the next ++ connection. + */ +- if (!G_IS_TCP_CONNECTION (data->connection)) +- { +- g_critical ("Trying to proxy over non-TCP connection, this is " +- "most likely a bug in GLib IO library."); +- +- g_set_error_literal (&data->last_error, +- G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, +- _("Proxying over a non-TCP connection is not supported.")); +- +- enumerator_next_async (data, FALSE); +- } +- else if (g_hash_table_contains (data->client->priv->app_proxies, protocol)) +- { +- /* Simply complete the connection, we don't want to do TLS handshake +- * as the application proxy handling may need proxy handshake first */ +- g_socket_client_async_connect_complete (data); +- } +- else if ((proxy = g_proxy_get_default_for_protocol (protocol))) +- { +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, data->connection); +- g_proxy_connect_async (proxy, +- data->connection, +- data->proxy_addr, +- g_task_get_cancellable (data->task), +- g_socket_client_proxy_connect_callback, +- data); +- g_object_unref (proxy); +- } +- else +- { +- g_clear_error (&data->last_error); +- +- g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, +- _("Proxy protocol ā€œ%sā€ is not supported."), +- protocol); +- +- enumerator_next_async (data, FALSE); +- } ++ connection_attempt_remove (attempt); ++ data->successful_connections = g_slist_append (data->successful_connections, g_steal_pointer (&attempt)); ++ try_next_connection_or_finish (data, FALSE); + } + + static gboolean +@@ -1707,7 +1796,11 @@ on_connection_attempt_timeout (gpointer data) + { + ConnectionAttempt *attempt = data; + +- enumerator_next_async (attempt->data, TRUE); ++ if (!attempt->data->enumeration_completed) ++ { ++ g_debug ("GSocketClient: Timeout reached, trying another enumeration"); ++ enumerator_next_async (attempt->data, TRUE); ++ } + + g_clear_pointer (&attempt->timeout_source, g_source_unref); + return G_SOURCE_REMOVE; +@@ -1717,9 +1810,9 @@ static void + on_connection_cancelled (GCancellable *cancellable, + gpointer data) + { +- GCancellable *attempt_cancellable = data; ++ GCancellable *linked_cancellable = G_CANCELLABLE (data); + +- g_cancellable_cancel (attempt_cancellable); ++ g_cancellable_cancel (linked_cancellable); + } + + static void +@@ -1743,39 +1836,49 @@ g_socket_client_enumerator_callback (GObject *object, + result, &error); + if (address == NULL) + { +- if (data->connection_attempts) ++ if (G_UNLIKELY (data->enumeration_completed)) ++ return; ++ ++ data->enumeration_completed = TRUE; ++ g_debug ("GSocketClient: Address enumeration completed (out of addresses)"); ++ ++ /* As per API docs: We only care about error if its the first call, ++ after that the enumerator is done. ++ ++ Note that we don't care about cancellation errors because ++ task_completed_or_cancelled() above should handle that. ++ ++ If this fails and nothing is in progress then we will complete task here. ++ */ ++ if ((data->enumerated_at_least_once && !data->connection_attempts && !data->connection_in_progress) || ++ !data->enumerated_at_least_once) + { +- g_object_unref (data->task); +- return; ++ g_debug ("GSocketClient: Address enumeration failed: %s", error ? error->message : NULL); ++ if (data->last_error) ++ { ++ g_clear_error (&error); ++ error = data->last_error; ++ data->last_error = NULL; ++ } ++ else if (!error) ++ { ++ g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, ++ _("Unknown error on connect")); ++ } ++ ++ complete_connection_with_error (data, error); + } + +- g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); +- data->completed = TRUE; +- if (!error) +- { +- if (data->last_error) +- { +- error = data->last_error; +- data->last_error = NULL; +- } +- else +- { +- g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, +- _("Unknown error on connect")); +- } +- } +- g_task_return_error (data->task, error); ++ /* Enumeration should never trigger again, drop our ref */ + g_object_unref (data->task); + return; + } + ++ data->enumerated_at_least_once = TRUE; ++ g_debug ("GSocketClient: Address enumeration succeeded"); + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVED, + data->connectable, NULL); + +- if (G_IS_PROXY_ADDRESS (address) && +- data->client->priv->enable_proxy) +- data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address)); +- + g_clear_error (&data->last_error); + + socket = create_socket (data->client, address, &data->last_error); +@@ -1793,6 +1896,10 @@ g_socket_client_enumerator_callback (GObject *object, + attempt->cancellable = g_cancellable_new (); + attempt->connection = (GIOStream *)g_socket_connection_factory_create_connection (socket); + attempt->timeout_source = g_timeout_source_new (HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS); ++ ++ if (G_IS_PROXY_ADDRESS (address) && data->client->priv->enable_proxy) ++ attempt->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address)); ++ + g_source_set_callback (attempt->timeout_source, on_connection_attempt_timeout, attempt, NULL); + g_source_attach (attempt->timeout_source, g_task_get_context (data->task)); + data->connection_attempts = g_slist_append (data->connection_attempts, attempt); +@@ -1802,6 +1909,7 @@ g_socket_client_enumerator_callback (GObject *object, + g_object_ref (attempt->cancellable), g_object_unref); + + g_socket_connection_set_cached_remote_address ((GSocketConnection *)attempt->connection, address); ++ g_debug ("GSocketClient: Starting TCP connection attempt"); + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTING, data->connectable, attempt->connection); + g_socket_connection_connect_async (G_SOCKET_CONNECTION (attempt->connection), + address, +@@ -1854,24 +1962,48 @@ g_socket_client_connect_async (GSocketClient *client, + else + data->enumerator = g_socket_connectable_enumerate (connectable); + +- /* The flow and ownership here isn't quite obvious: +- - The task starts an async attempt to connect. +- - Each attempt holds a single ref on task. +- - Each attempt may create new attempts by timing out (not a failure) so +- there are multiple attempts happening in parallel. +- - Upon failure an attempt will start a new attempt that steals its ref +- until there are no more attempts left and it drops its ref. +- - Upon success it will cancel all other attempts and continue on +- to the rest of the connection (tls, proxies, etc) which do not +- happen in parallel and at the very end drop its ref. +- - Upon cancellation an attempt drops its ref. +- */ ++ /* This function tries to match the behavior of g_socket_client_connect () ++ which is simple enough but much of it is done in parallel to be as responsive ++ as possible as per Happy Eyeballs (RFC 8305). This complicates flow quite a ++ bit but we can describe it in 3 sections: ++ ++ Firstly we have address enumeration (DNS): ++ - This may be triggered multiple times by enumerator_next_async(). ++ - It also has its own cancellable (data->enumeration_cancellable). ++ - Enumeration is done lazily because GNetworkAddressAddressEnumerator ++ also does work in parallel and may lazily add new addresses. ++ - If the first enumeration errors then the task errors. Otherwise all enumerations ++ will potentially be used (until task or enumeration is cancelled). ++ ++ Then we start attempting connections (TCP): ++ - Each connection is independent and kept in a ConnectionAttempt object. ++ - They each hold a ref on the main task and have their own cancellable. ++ - Multiple attempts may happen in parallel as per Happy Eyeballs. ++ - Upon failure or timeouts more connection attempts are made. ++ - If no connections succeed the task errors. ++ - Upon success they are kept in a list of successful connections. ++ ++ Lastly we connect at the application layer (TLS, Proxies): ++ - These are done in serial. ++ - The reasoning here is that Happy Eyeballs is about making bad connections responsive ++ at the IP/TCP layers. Issues at the application layer are generally not due to ++ connectivity issues but rather misconfiguration. ++ - Upon failure it will try the next TCP connection until it runs out and ++ the task errors. ++ - Upon success it cancels everything remaining (enumeration and connections) ++ and returns the connection. ++ */ + + data->task = g_task_new (client, cancellable, callback, user_data); + g_task_set_check_cancellable (data->task, FALSE); /* We handle this manually */ + g_task_set_source_tag (data->task, g_socket_client_connect_async); + g_task_set_task_data (data->task, data, (GDestroyNotify)g_socket_client_async_connect_data_free); + ++ data->enumeration_cancellable = g_cancellable_new (); ++ if (cancellable) ++ g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled), ++ g_object_ref (data->enumeration_cancellable), g_object_unref); ++ + enumerator_next_async (data, FALSE); + } + +@@ -1990,6 +2122,7 @@ g_socket_client_connect_to_uri_async (GSocketClient *client, + } + else + { ++ g_debug("g_socket_client_connect_to_uri_async"); + g_socket_client_connect_async (client, + connectable, cancellable, + callback, user_data); +-- +2.24.1 + diff --git a/dev-libs/glib/glib-2.60.7-r2.ebuild b/dev-libs/glib/glib-2.60.7-r2.ebuild new file mode 100644 index 000000000000..01213e8df288 --- /dev/null +++ b/dev-libs/glib/glib-2.60.7-r2.ebuild @@ -0,0 +1,280 @@ +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 +PYTHON_COMPAT=( python{3_6,3_7} ) + +inherit flag-o-matic gnome.org gnome2-utils linux-info meson multilib multilib-minimal python-any-r1 toolchain-funcs xdg + +DESCRIPTION="The GLib library of C routines" +HOMEPAGE="https://www.gtk.org/" + +LICENSE="LGPL-2.1+" +SLOT="2" +IUSE="dbus debug elibc_glibc fam gtk-doc kernel_linux +mime selinux static-libs systemtap test utils xattr" +RESTRICT="!test? ( test )" + +KEYWORDS="~alpha amd64 ~arm ~arm64 ~hppa ia64 ~m68k ~mips ppc ppc64 ~riscv s390 ~sh sparc x86 ~amd64-linux ~x86-linux" + +# * libelf isn't strictly necessary, but makes gresource tool more useful, and +# the check is automagic in gio/meson.build. gresource is not a multilib tool +# right now, thus it doesn't matter if non-native ABI libelf exists or not +# (non-native binary is overwritten, it doesn't matter if libelf was linked to). +# * Technically static-libs is needed on zlib, util-linux and perhaps more, but +# these are used by GIO, which glib[static-libs] consumers don't really seem +# to need at all, thus not imposing the deps for now and once some consumers +# are actually found to static link libgio-2.0.a, we can revisit and either add +# them or just put the (build) deps in that rare consumer instead of recursive +# RDEPEND here (due to lack of recursive DEPEND). +RDEPEND=" + !=virtual/libiconv-0-r1[${MULTILIB_USEDEP}] + >=dev-libs/libpcre-8.31:3[${MULTILIB_USEDEP},static-libs?] + >=virtual/libffi-3.0.13-r1:=[${MULTILIB_USEDEP}] + >=sys-libs/zlib-1.2.8-r1[${MULTILIB_USEDEP}] + >=virtual/libintl-0-r2[${MULTILIB_USEDEP}] + kernel_linux? ( >=sys-apps/util-linux-2.23[${MULTILIB_USEDEP}] ) + selinux? ( >=sys-libs/libselinux-2.2.2-r5[${MULTILIB_USEDEP}] ) + xattr? ( !elibc_glibc? ( >=sys-apps/attr-2.4.47-r1[${MULTILIB_USEDEP}] ) ) + virtual/libelf:0= + fam? ( >=virtual/fam-0-r1[${MULTILIB_USEDEP}] ) +" +DEPEND="${RDEPEND}" +# libxml2 used for optional tests that get automatically skipped +BDEPEND=" + app-text/docbook-xsl-stylesheets + dev-libs/libxslt + >=sys-devel/gettext-0.19.8 + gtk-doc? ( >=dev-util/gtk-doc-1.20 + app-text/docbook-xml-dtd:4.2 + app-text/docbook-xml-dtd:4.5 ) + systemtap? ( >=dev-util/systemtap-1.3 ) + ${PYTHON_DEPS} + test? ( >=sys-apps/dbus-1.2.14 ) + virtual/pkgconfig[${MULTILIB_USEDEP}] +" +# TODO: >=dev-util/gdbus-codegen-${PV} test dep once we modify gio/tests/meson.build to use external gdbus-codegen + +PDEPEND=" + dbus? ( gnome-base/dconf ) + mime? ( x11-misc/shared-mime-info ) +" +# shared-mime-info needed for gio/xdgmime, bug #409481 +# dconf is needed to be able to save settings, bug #498436 + +MULTILIB_CHOST_TOOLS=( + /usr/bin/gio-querymodules$(get_exeext) +) + +pkg_setup() { + if use kernel_linux ; then + CONFIG_CHECK="~INOTIFY_USER" + if use test ; then + CONFIG_CHECK="~IPV6" + WARNING_IPV6="Your kernel needs IPV6 support for running some tests, skipping them." + fi + linux-info_pkg_setup + fi + python-any-r1_pkg_setup +} + +src_prepare() { + eapply "${FILESDIR}"/${PV}-gdbus-fixes.patch #700538, included in 2.62.3+ + eapply "${FILESDIR}"/CVE-2020-6750.patch + + if use test; then + # TODO: Review the test exclusions, especially now with meson + # Disable tests requiring dev-util/desktop-file-utils when not installed, bug #286629, upstream bug #629163 + if ! has_version dev-util/desktop-file-utils ; then + ewarn "Some tests will be skipped due dev-util/desktop-file-utils not being present on your system," + ewarn "think on installing it to get these tests run." + sed -i -e "/appinfo\/associations/d" gio/tests/appinfo.c || die + sed -i -e "/g_test_add_func/d" gio/tests/desktop-app-info.c || die + fi + + # gdesktopappinfo requires existing terminal (gnome-terminal or any + # other), falling back to xterm if one doesn't exist + #if ! has_version x11-terms/xterm && ! has_version x11-terms/gnome-terminal ; then + # ewarn "Some tests will be skipped due to missing terminal program" + # These tests seem to sometimes fail even with a terminal; skip for now and reevulate with meson + # Also try https://gitlab.gnome.org/GNOME/glib/issues/1601 once ready for backport (or in a bump) and file new issue if still fails + sed -i -e "/appinfo\/launch/d" gio/tests/appinfo.c || die + # desktop-app-info/launch* might fail similarly + sed -i -e "/desktop-app-info\/launch-as-manager/d" gio/tests/desktop-app-info.c || die + #fi + + # https://bugzilla.gnome.org/show_bug.cgi?id=722604 + sed -i -e "/timer\/stop/d" glib/tests/timer.c || die + sed -i -e "/timer\/basic/d" glib/tests/timer.c || die + + ewarn "Tests for search-utils have been skipped" + sed -i -e "/search-utils/d" glib/tests/meson.build || die + + # Play nice with network-sandbox, but this approach would defeat the purpose of the test + #sed -i -e "s/localhost/127.0.0.1/g" gio/tests/gsocketclient-slow.c || die + else + # Don't build tests, also prevents extra deps, bug #512022 + sed -i -e '/subdir.*tests/d' {.,gio,glib}/meson.build || die + fi + + # Don't build fuzzing binaries - not used + sed -i -e '/subdir.*fuzzing/d' meson.build || die + + # gdbus-codegen is a separate package + sed -i -e 's/install.*true/install : false/g' gio/gdbus-2.0/codegen/meson.build || die + # Older than meson-0.50 doesn't know about install kwarg for configure_file; for that we need to remove the install_dir kwarg. + # Upstream will remove the install kwarg in a future version to require only meson-0.49.2 or newer, at which point the + # install_dir removal only should be kept. + sed -i -e '/install_dir/d' gio/gdbus-2.0/codegen/meson.build || die + + # Same kind of meson-0.50 issue with some installed-tests files; will likely be fixed upstream soon + sed -i -e '/install_dir/d' gio/tests/meson.build || die + + cat > "${T}/glib-test-ld-wrapper" <<-EOF + #!/usr/bin/env sh + exec \${LD:-ld} "\$@" + EOF + chmod a+x "${T}/glib-test-ld-wrapper" || die + sed -i -e "s|'ld'|'${T}/glib-test-ld-wrapper'|g" gio/tests/meson.build || die + + xdg_src_prepare + gnome2_environment_reset + # TODO: python_name sedding for correct python shebang? Might be relevant mainly for glib-utils only +} + +multilib_src_configure() { + if use debug; then + append-cflags -DG_ENABLE_DEBUG + else + append-cflags -DG_DISABLE_CAST_CHECKS # https://gitlab.gnome.org/GNOME/glib/issues/1833 + fi + + # TODO: figure a way to pass appropriate values for all cross properties that glib uses (search for get_cross_property) + #if tc-is-cross-compiler ; then + # https://bugzilla.gnome.org/show_bug.cgi?id=756473 + # TODO-meson: This should be in meson cross file as 'growing_stack' property; and more, look at get_cross_property + #case ${CHOST} in + #hppa*|metag*) export glib_cv_stack_grows=yes ;; + #*) export glib_cv_stack_grows=no ;; + #esac + #fi + + local emesonargs=( + -Ddefault_library=$(usex static-libs both shared) + $(meson_feature selinux) + $(meson_use xattr) + -Dlibmount=true # only used if host_system == 'linux' + -Dinternal_pcre=false + -Dman=true + $(meson_use systemtap dtrace) + $(meson_use systemtap) + -Dgtk_doc=$(multilib_native_usex gtk-doc true false) + $(meson_use fam) + -Dinstalled_tests=false + -Dnls=enabled + ) + meson_src_configure +} + +multilib_src_compile() { + meson_src_compile +} + +multilib_src_test() { + export XDG_CONFIG_DIRS=/etc/xdg + export XDG_DATA_DIRS=/usr/local/share:/usr/share + export G_DBUS_COOKIE_SHA1_KEYRING_DIR="${T}/temp" + export LC_TIME=C # bug #411967 + unset GSETTINGS_BACKEND # bug #596380 + python_setup + + # Related test is a bit nitpicking + mkdir "$G_DBUS_COOKIE_SHA1_KEYRING_DIR" + chmod 0700 "$G_DBUS_COOKIE_SHA1_KEYRING_DIR" + + meson_src_test --timeout-multiplier 2 --no-suite flaky +} + +multilib_src_install() { + meson_src_install + keepdir /usr/$(get_libdir)/gio/modules +} + +multilib_src_install_all() { + einstalldocs + + # These are installed by dev-util/glib-utils + # TODO: With patching we might be able to get rid of the python-any deps and removals, and test depend on glib-utils instead; revisit now with meson + rm "${ED}/usr/bin/glib-genmarshal" || die + rm "${ED}/usr/share/man/man1/glib-genmarshal.1" || die + rm "${ED}/usr/bin/glib-mkenums" || die + rm "${ED}/usr/share/man/man1/glib-mkenums.1" || die + rm "${ED}/usr/bin/gtester-report" || die + rm "${ED}/usr/share/man/man1/gtester-report.1" || die + # gdbus-codegen manpage installed by dev-util/gdbus-codegen + rm "${ED}/usr/share/man/man1/gdbus-codegen.1" || die +} + +pkg_preinst() { + xdg_pkg_preinst + + # Make gschemas.compiled belong to glib alone + local cache="/usr/share/glib-2.0/schemas/gschemas.compiled" + + if [[ -e ${EROOT}${cache} ]]; then + cp "${EROOT}"${cache} "${ED}"/${cache} || die + else + touch "${ED}"${cache} || die + fi + + multilib_pkg_preinst() { + # Make giomodule.cache belong to glib alone + local cache="/usr/$(get_libdir)/gio/modules/giomodule.cache" + + if [[ -e ${EROOT}${cache} ]]; then + cp "${EROOT}"${cache} "${ED}"${cache} || die + else + touch "${ED}"${cache} || die + fi + } + + # Don't run the cache ownership when cross-compiling, as it would end up with an empty cache + # file due to inability to create it and GIO might not look at any of the modules there + if ! tc-is-cross-compiler ; then + multilib_foreach_abi multilib_pkg_preinst + fi +} + +pkg_postinst() { + xdg_pkg_postinst + # glib installs no schemas itself, but we force update for fresh install in case + # something has dropped in a schemas file without direct glib dep; and for upgrades + # in case the compiled schema format could have changed + gnome2_schemas_update + + multilib_pkg_postinst() { + gnome2_giomodule_cache_update \ + || die "Update GIO modules cache failed (for ${ABI})" + } + if ! tc-is-cross-compiler ; then + multilib_foreach_abi multilib_pkg_postinst + else + ewarn "Updating of GIO modules cache skipped due to cross-compilation." + ewarn "You might want to run gio-querymodules manually on the target for" + ewarn "your final image for performance reasons and re-run it when packages" + ewarn "installing GIO modules get upgraded or added to the image." + fi +} + +pkg_postrm() { + xdg_pkg_postrm + gnome2_schemas_update + + if [[ -z ${REPLACED_BY_VERSION} ]]; then + multilib_pkg_postrm() { + rm -f "${EROOT}"/usr/$(get_libdir)/gio/modules/giomodule.cache + } + multilib_foreach_abi multilib_pkg_postrm + rm -f "${EROOT}"/usr/share/glib-2.0/schemas/gschemas.compiled + fi +} diff --git a/dev-libs/glib/glib-2.62.5.ebuild b/dev-libs/glib/glib-2.62.5.ebuild new file mode 100644 index 000000000000..33a36d9a2964 --- /dev/null +++ b/dev-libs/glib/glib-2.62.5.ebuild @@ -0,0 +1,274 @@ +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 +PYTHON_COMPAT=( python{3_6,3_7} ) + +inherit flag-o-matic gnome.org gnome2-utils linux-info meson multilib multilib-minimal python-any-r1 toolchain-funcs xdg + +DESCRIPTION="The GLib library of C routines" +HOMEPAGE="https://www.gtk.org/" + +LICENSE="LGPL-2.1+" +SLOT="2" +IUSE="dbus debug elibc_glibc fam gtk-doc kernel_linux +mime selinux static-libs systemtap test utils xattr" +RESTRICT="!test? ( test )" + +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sh ~sparc ~x86 ~amd64-linux ~x86-linux" + +# * libelf isn't strictly necessary, but makes gresource tool more useful, and +# the check is automagic in gio/meson.build. gresource is not a multilib tool +# right now, thus it doesn't matter if non-native ABI libelf exists or not +# (non-native binary is overwritten, it doesn't matter if libelf was linked to). +# * Technically static-libs is needed on zlib, util-linux and perhaps more, but +# these are used by GIO, which glib[static-libs] consumers don't really seem +# to need at all, thus not imposing the deps for now and once some consumers +# are actually found to static link libgio-2.0.a, we can revisit and either add +# them or just put the (build) deps in that rare consumer instead of recursive +# RDEPEND here (due to lack of recursive DEPEND). +RDEPEND=" + !=virtual/libiconv-0-r1[${MULTILIB_USEDEP}] + >=dev-libs/libpcre-8.31:3[${MULTILIB_USEDEP},static-libs?] + >=virtual/libffi-3.0.13-r1:=[${MULTILIB_USEDEP}] + >=sys-libs/zlib-1.2.8-r1[${MULTILIB_USEDEP}] + >=virtual/libintl-0-r2[${MULTILIB_USEDEP}] + kernel_linux? ( >=sys-apps/util-linux-2.23[${MULTILIB_USEDEP}] ) + selinux? ( >=sys-libs/libselinux-2.2.2-r5[${MULTILIB_USEDEP}] ) + xattr? ( !elibc_glibc? ( >=sys-apps/attr-2.4.47-r1[${MULTILIB_USEDEP}] ) ) + virtual/libelf:0= + fam? ( >=virtual/fam-0-r1[${MULTILIB_USEDEP}] ) +" +DEPEND="${RDEPEND}" +# libxml2 used for optional tests that get automatically skipped +BDEPEND=" + app-text/docbook-xsl-stylesheets + dev-libs/libxslt + >=sys-devel/gettext-0.19.8 + gtk-doc? ( >=dev-util/gtk-doc-1.20 + app-text/docbook-xml-dtd:4.2 + app-text/docbook-xml-dtd:4.5 ) + systemtap? ( >=dev-util/systemtap-1.3 ) + ${PYTHON_DEPS} + test? ( >=sys-apps/dbus-1.2.14 ) + virtual/pkgconfig[${MULTILIB_USEDEP}] +" +# TODO: >=dev-util/gdbus-codegen-${PV} test dep once we modify gio/tests/meson.build to use external gdbus-codegen + +PDEPEND=" + dbus? ( gnome-base/dconf ) + mime? ( x11-misc/shared-mime-info ) +" +# shared-mime-info needed for gio/xdgmime, bug #409481 +# dconf is needed to be able to save settings, bug #498436 + +MULTILIB_CHOST_TOOLS=( + /usr/bin/gio-querymodules$(get_exeext) +) + +pkg_setup() { + if use kernel_linux ; then + CONFIG_CHECK="~INOTIFY_USER" + if use test ; then + CONFIG_CHECK="~IPV6" + WARNING_IPV6="Your kernel needs IPV6 support for running some tests, skipping them." + fi + linux-info_pkg_setup + fi + python-any-r1_pkg_setup +} + +src_prepare() { + if use test; then + # TODO: Review the test exclusions, especially now with meson + # Disable tests requiring dev-util/desktop-file-utils when not installed, bug #286629, upstream bug #629163 + if ! has_version dev-util/desktop-file-utils ; then + ewarn "Some tests will be skipped due dev-util/desktop-file-utils not being present on your system," + ewarn "think on installing it to get these tests run." + sed -i -e "/appinfo\/associations/d" gio/tests/appinfo.c || die + sed -i -e "/g_test_add_func/d" gio/tests/desktop-app-info.c || die + fi + + # gdesktopappinfo requires existing terminal (gnome-terminal or any + # other), falling back to xterm if one doesn't exist + #if ! has_version x11-terms/xterm && ! has_version x11-terms/gnome-terminal ; then + # ewarn "Some tests will be skipped due to missing terminal program" + # These tests seem to sometimes fail even with a terminal; skip for now and reevulate with meson + # Also try https://gitlab.gnome.org/GNOME/glib/issues/1601 once ready for backport (or in a bump) and file new issue if still fails + sed -i -e "/appinfo\/launch/d" gio/tests/appinfo.c || die + # desktop-app-info/launch* might fail similarly + sed -i -e "/desktop-app-info\/launch-as-manager/d" gio/tests/desktop-app-info.c || die + #fi + + # https://bugzilla.gnome.org/show_bug.cgi?id=722604 + sed -i -e "/timer\/stop/d" glib/tests/timer.c || die + sed -i -e "/timer\/basic/d" glib/tests/timer.c || die + + ewarn "Tests for search-utils have been skipped" + sed -i -e "/search-utils/d" glib/tests/meson.build || die + + # Play nice with network-sandbox, but this approach would defeat the purpose of the test + #sed -i -e "s/localhost/127.0.0.1/g" gio/tests/gsocketclient-slow.c || die + else + # Don't build tests, also prevents extra deps, bug #512022 + sed -i -e '/subdir.*tests/d' {.,gio,glib}/meson.build || die + fi + + # Don't build fuzzing binaries - not used + sed -i -e '/subdir.*fuzzing/d' meson.build || die + + # gdbus-codegen is a separate package + sed -i -e '/install_dir/d' gio/gdbus-2.0/codegen/meson.build || die + + # Same kind of meson-0.50 issue with some installed-tests files; will likely be fixed upstream soon + sed -i -e '/install_dir/d' gio/tests/meson.build || die + + cat > "${T}/glib-test-ld-wrapper" <<-EOF + #!/usr/bin/env sh + exec \${LD:-ld} "\$@" + EOF + chmod a+x "${T}/glib-test-ld-wrapper" || die + sed -i -e "s|'ld'|'${T}/glib-test-ld-wrapper'|g" gio/tests/meson.build || die + + xdg_src_prepare + gnome2_environment_reset + # TODO: python_name sedding for correct python shebang? Might be relevant mainly for glib-utils only +} + +multilib_src_configure() { + if use debug; then + append-cflags -DG_ENABLE_DEBUG + else + append-cflags -DG_DISABLE_CAST_CHECKS # https://gitlab.gnome.org/GNOME/glib/issues/1833 + fi + + # TODO: figure a way to pass appropriate values for all cross properties that glib uses (search for get_cross_property) + #if tc-is-cross-compiler ; then + # https://bugzilla.gnome.org/show_bug.cgi?id=756473 + # TODO-meson: This should be in meson cross file as 'growing_stack' property; and more, look at get_cross_property + #case ${CHOST} in + #hppa*|metag*) export glib_cv_stack_grows=yes ;; + #*) export glib_cv_stack_grows=no ;; + #esac + #fi + + local emesonargs=( + -Ddefault_library=$(usex static-libs both shared) + $(meson_feature selinux) + $(meson_use xattr) + -Dlibmount=true # only used if host_system == 'linux' + -Dinternal_pcre=false + -Dman=true + $(meson_use systemtap dtrace) + $(meson_use systemtap) + -Dgtk_doc=$(multilib_native_usex gtk-doc true false) + $(meson_use fam) + -Dinstalled_tests=false + -Dnls=enabled + -Doss_fuzz=disabled + ) + meson_src_configure +} + +multilib_src_compile() { + meson_src_compile +} + +multilib_src_test() { + export XDG_CONFIG_DIRS=/etc/xdg + export XDG_DATA_DIRS=/usr/local/share:/usr/share + export G_DBUS_COOKIE_SHA1_KEYRING_DIR="${T}/temp" + export LC_TIME=C # bug #411967 + unset GSETTINGS_BACKEND # bug #596380 + python_setup + + # Related test is a bit nitpicking + mkdir "$G_DBUS_COOKIE_SHA1_KEYRING_DIR" + chmod 0700 "$G_DBUS_COOKIE_SHA1_KEYRING_DIR" + + meson_src_test --timeout-multiplier 2 --no-suite flaky +} + +multilib_src_install() { + meson_src_install + keepdir /usr/$(get_libdir)/gio/modules +} + +multilib_src_install_all() { + einstalldocs + + # These are installed by dev-util/glib-utils + # TODO: With patching we might be able to get rid of the python-any deps and removals, and test depend on glib-utils instead; revisit now with meson + rm "${ED}/usr/bin/glib-genmarshal" || die + rm "${ED}/usr/share/man/man1/glib-genmarshal.1" || die + rm "${ED}/usr/bin/glib-mkenums" || die + rm "${ED}/usr/share/man/man1/glib-mkenums.1" || die + rm "${ED}/usr/bin/gtester-report" || die + rm "${ED}/usr/share/man/man1/gtester-report.1" || die + # gdbus-codegen manpage installed by dev-util/gdbus-codegen + rm "${ED}/usr/share/man/man1/gdbus-codegen.1" || die +} + +pkg_preinst() { + xdg_pkg_preinst + + # Make gschemas.compiled belong to glib alone + local cache="/usr/share/glib-2.0/schemas/gschemas.compiled" + + if [[ -e ${EROOT}${cache} ]]; then + cp "${EROOT}"${cache} "${ED}"/${cache} || die + else + touch "${ED}"${cache} || die + fi + + multilib_pkg_preinst() { + # Make giomodule.cache belong to glib alone + local cache="/usr/$(get_libdir)/gio/modules/giomodule.cache" + + if [[ -e ${EROOT}${cache} ]]; then + cp "${EROOT}"${cache} "${ED}"${cache} || die + else + touch "${ED}"${cache} || die + fi + } + + # Don't run the cache ownership when cross-compiling, as it would end up with an empty cache + # file due to inability to create it and GIO might not look at any of the modules there + if ! tc-is-cross-compiler ; then + multilib_foreach_abi multilib_pkg_preinst + fi +} + +pkg_postinst() { + xdg_pkg_postinst + # glib installs no schemas itself, but we force update for fresh install in case + # something has dropped in a schemas file without direct glib dep; and for upgrades + # in case the compiled schema format could have changed + gnome2_schemas_update + + multilib_pkg_postinst() { + gnome2_giomodule_cache_update \ + || die "Update GIO modules cache failed (for ${ABI})" + } + if ! tc-is-cross-compiler ; then + multilib_foreach_abi multilib_pkg_postinst + else + ewarn "Updating of GIO modules cache skipped due to cross-compilation." + ewarn "You might want to run gio-querymodules manually on the target for" + ewarn "your final image for performance reasons and re-run it when packages" + ewarn "installing GIO modules get upgraded or added to the image." + fi +} + +pkg_postrm() { + xdg_pkg_postrm + gnome2_schemas_update + + if [[ -z ${REPLACED_BY_VERSION} ]]; then + multilib_pkg_postrm() { + rm -f "${EROOT}"/usr/$(get_libdir)/gio/modules/giomodule.cache + } + multilib_foreach_abi multilib_pkg_postrm + rm -f "${EROOT}"/usr/share/glib-2.0/schemas/gschemas.compiled + fi +} -- cgit v1.2.3