commit:     872333a27243d0c9973daaaa6270e8418a21cc38
Author:     Thibaud CANALE <thican <AT> thican <DOT> net>
AuthorDate: Wed Dec 24 13:30:09 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Dec 30 13:42:39 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=872333a2

dev-libs/libmateweather: add 1.28.1

Closes: https://bugs.gentoo.org/965885
Signed-off-by: Thibaud CANALE <thican <AT> thican.net>
Part-of: https://github.com/gentoo/gentoo/pull/45148
Closes: https://github.com/gentoo/gentoo/pull/45148
Signed-off-by: Sam James <sam <AT> gentoo.org>

 dev-libs/libmateweather/Manifest                   |   1 +
 .../libmateweather-1.28.1-SPECI_report_data.patch  |  58 ++
 .../files/libmateweather-1.28.1-libsoup3.patch     | 642 +++++++++++++++++++++
 .../files/libmateweather-1.28.1-location.patch     | 114 ++++
 .../libmateweather/libmateweather-1.28.1.ebuild    |  59 ++
 5 files changed, 874 insertions(+)

diff --git a/dev-libs/libmateweather/Manifest b/dev-libs/libmateweather/Manifest
index 974a7baa5c7b..5c727113a020 100644
--- a/dev-libs/libmateweather/Manifest
+++ b/dev-libs/libmateweather/Manifest
@@ -1 +1,2 @@
 DIST libmateweather-1.28.0.tar.xz 2221808 BLAKE2B 
edd5a00e020a0dcb1edaee08720a70ac3d1c1e6e08d5a0fc8247f1cb3e44bc1c47b350a1bcaf23db23994ac9b0a077cc489b94f82c9922e407edea1fe7c2722c
 SHA512 
ee89bd159beba2893b334fb603de2b852d97c382670628d8892eb2a74907950afe485455218ae4c6dc41338218b67dc78003da8ace61d1952451ae55e7e5e6d0
+DIST libmateweather-1.28.1.gh.tar.gz 6965691 BLAKE2B 
a278e881b9dd2939d809bf03d239222b3df1fdab32aea1d27278151a999326e57be1e86ab5eff4cdf848c462b065aaf611015b40b2cd4993c2d6b38dcc8e4976
 SHA512 
d53f57e56945a51bf8bab2eb2e9caea5ea4cdfec95898267a56fc5935a3153e15865763ca1ae4abfb548af3eaa527675a0c2ac16a578bcc0df37254cec49abc9

diff --git 
a/dev-libs/libmateweather/files/libmateweather-1.28.1-SPECI_report_data.patch 
b/dev-libs/libmateweather/files/libmateweather-1.28.1-SPECI_report_data.patch
new file mode 100644
index 000000000000..2939c53e7111
--- /dev/null
+++ 
b/dev-libs/libmateweather/files/libmateweather-1.28.1-SPECI_report_data.patch
@@ -0,0 +1,58 @@
+From 622b98934153cc655e95626ffbbc7de53f0de890 Mon Sep 17 00:00:00 2001
+From: Victor Kareh <[email protected]>
+Date: Thu, 25 Sep 2025 13:10:59 -0400
+Subject: [PATCH] metar: Support SPECI report data
+
+Since AviationWeather updated their API, they now return two report
+types: METAR (standard hourly repors) and SPECI (special intermediate
+reports). We can parse those out from the response since the format is
+similar, and the only thing that changes is the prefix.
+
+Signed-off-by: Thibaud CANALE <[email protected]>
+---
+ libmateweather/weather-metar.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/libmateweather/weather-metar.c b/libmateweather/weather-metar.c
+index dabca3a2..d25a4323 100644
+--- a/libmateweather/weather-metar.c
++++ b/libmateweather/weather-metar.c
+@@ -523,15 +523,20 @@ metar_finish (GObject *source, GAsyncResult *result, 
gpointer data)
+ 
+     loc = info->location;
+ 
+-    searchkey = g_strdup_printf ("<raw_text>METAR %s", loc->code);
+-
+     response_body = g_bytes_get_data (bytes, &len);
+     end = response_body + len;
+ 
++    /* Try METAR first, then SPECI */
++    searchkey = g_strdup_printf ("<raw_text>METAR %s", loc->code);
+     p = xstrnstr (response_body, len, searchkey);
++    if (!p) {
++        g_free (searchkey);
++        searchkey = g_strdup_printf ("<raw_text>SPECI %s", loc->code);
++        p = xstrnstr (response_body, len, searchkey);
++    }
++
+     if (p) {
+         p += WEATHER_LOCATION_CODE_LEN + 11;
+-        endtag = strstr (p, "</raw_text>");
+         endtag = xstrnstr (p, end - p, "</raw_text>");
+         if (endtag)
+             metar = g_strndup (p, endtag - p);
+@@ -539,7 +544,10 @@ metar_finish (GObject *source, GAsyncResult *result, 
gpointer data)
+             metar = g_strndup (p, end - p);
+         success = metar_parse (metar, info);
+         g_free (metar);
+-    } else if (!xstrnstr (response_body, len, "aviationweather.gov")) {
++    }
++    g_free (searchkey);
++
++    if (!success && !xstrnstr (response_body, len, "aviationweather.gov")) {
+         /* The response doesn't even seem to have come from NOAA...
+          * most likely it is a wifi hotspot login page. Call that a
+          * network error.
+-- 
+2.51.2
+

diff --git a/dev-libs/libmateweather/files/libmateweather-1.28.1-libsoup3.patch 
b/dev-libs/libmateweather/files/libmateweather-1.28.1-libsoup3.patch
new file mode 100644
index 000000000000..5a4bde73ff2b
--- /dev/null
+++ b/dev-libs/libmateweather/files/libmateweather-1.28.1-libsoup3.patch
@@ -0,0 +1,642 @@
+From 4455561d5107a73fb95c53f2d7c2016b3b58a609 Mon Sep 17 00:00:00 2001
+From: https://github.com/mate-desktop/libmateweather/pull/133
+From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=
+ <[email protected]>
+Date: Mon, 4 Mar 2024 23:47:37 +0700
+Subject: [PATCH] Port to libsoup-3.0
+
+Signed-off-by: Thibaud CANALE <[email protected]>
+---
+ .build.yml                                   | 10 ++--
+ configure.ac                                 |  6 ++-
+ libmateweather/mateweather-uninstalled.pc.in |  2 +-
+ libmateweather/mateweather.pc.in             |  2 +-
+ libmateweather/weather-bom.c                 | 36 ++++++++-----
+ libmateweather/weather-iwin.c                | 37 ++++++++-----
+ libmateweather/weather-met.c                 | 34 ++++++++----
+ libmateweather/weather-metar.c               | 56 ++++++++++++++------
+ libmateweather/weather-priv.h                |  6 ++-
+ libmateweather/weather-wx.c                  | 53 +++++++++---------
+ libmateweather/weather.c                     |  7 +--
+ 11 files changed, 156 insertions(+), 93 deletions(-)
+
+diff --git a/.build.yml b/.build.yml
+index 622db502..024b8f4a 100644
+--- a/.build.yml
++++ b/.build.yml
+@@ -9,7 +9,7 @@ requires:
+     - gcc
+     - git
+     - gtk3
+-    - libsoup
++    - libsoup3
+     - make
+     - mate-common
+     - tzdata
+@@ -27,8 +27,7 @@ requires:
+     - gtk-doc-tools
+     - libglib2.0-dev
+     - libgtk-3-dev
+-    - libsoup-gnome2.4-dev
+-    - libsoup2.4-dev
++    - libsoup-3.0-dev
+     - libxml2-dev
+     - libxml2-utils
+     - make
+@@ -44,7 +43,7 @@ requires:
+     - gcc
+     - git
+     - gtk3-devel
+-    - libsoup-devel
++    - libsoup3-devel
+     - libxml2-devel
+     - make
+     - mate-common
+@@ -60,8 +59,7 @@ requires:
+     - gtk-doc-tools
+     - libglib2.0-dev
+     - libgtk-3-dev
+-    - libsoup-gnome2.4-dev
+-    - libsoup2.4-dev
++    - libsoup-3.0-dev
+     - libxml2-dev
+     - libxml2-utils
+     - make
+diff --git a/configure.ac b/configure.ac
+index e0ca7be1..0e8b9ad1 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -8,6 +8,7 @@ AC_CONFIG_AUX_DIR([build-aux])
+ AM_INIT_AUTOMAKE([1.9 no-dist-gzip dist-xz tar-ustar check-news])
+ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+ 
++AC_USE_SYSTEM_EXTENSIONS
+ # Before making a release, the LT_VERSION string should be modified.
+ # The string is of the form C:R:A.
+ # - If interfaces have been changed or added, but binary compatibility has
+@@ -23,7 +24,7 @@ AC_CANONICAL_HOST
+ 
+ GLIB_REQUIRED=2.56.0
+ GTK_REQUIRED=3.22.0
+-LIBSOUP_REQUIRED=2.34.0
++LIBSOUP_REQUIRED=3.0.0
+ GIO_REQUIRED=2.25.0
+ LIBXML_REQUIRED=2.6.0
+ 
+@@ -65,7 +66,7 @@ dnl -- Check for libxml (required) 
------------------------------------------
+ PKG_CHECK_MODULES(LIBXML, libxml-2.0 >= $LIBXML_REQUIRED)
+ 
+ dnl -- check for libsoup (required) -----------------------------------------
+-PKG_CHECK_MODULES(LIBSOUP, [libsoup-2.4 >= $LIBSOUP_REQUIRED])
++PKG_CHECK_MODULES(LIBSOUP, [libsoup-3.0 >= $LIBSOUP_REQUIRED])
+ 
+ dnl -- check for gio (required) -----------------------------------------
+ PKG_CHECK_MODULES(GIO,
+@@ -100,6 +101,7 @@ AC_CHECK_FUNCS(regexec,,[AC_CHECK_LIB(regex,regexec,
+                [AC_MSG_ERROR([No regex library found])])])
+ AC_SUBST(REGEX_LIBS)
+ 
++AC_CHECK_FUNC(memmem,[],[AC_MSG_ERROR([memmem is required])])
+ 
+ dnl 
***************************************************************************
+ dnl *** Check for presence of tm.tm_gmtoff on the system                    
***
+diff --git a/libmateweather/mateweather-uninstalled.pc.in 
b/libmateweather/mateweather-uninstalled.pc.in
+index 03e74617..c692842a 100644
+--- a/libmateweather/mateweather-uninstalled.pc.in
++++ b/libmateweather/mateweather-uninstalled.pc.in
+@@ -8,6 +8,6 @@ Name: MateWeather
+ Description: MateWeather shared library
+ Version: @VERSION@
+ Requires: glib-2.0 gobject-2.0 gdk-pixbuf-2.0 gtk+-3.0 gio-2.0
+-Requires.private: libxml-2.0 libsoup-2.4
++Requires.private: libxml-2.0 libsoup-3.0
+ Libs: ${pc_top_builddir}/${pcfiledir}/libmateweather.la
+ Cflags: -I${pc_top_builddir}/${pcfiledir}/..
+diff --git a/libmateweather/mateweather.pc.in 
b/libmateweather/mateweather.pc.in
+index a617c334..bea024dd 100644
+--- a/libmateweather/mateweather.pc.in
++++ b/libmateweather/mateweather.pc.in
+@@ -8,7 +8,7 @@ Name: MateWeather
+ Description: MateWeather shared library
+ Version: @VERSION@
+ Requires: glib-2.0 gobject-2.0 gdk-pixbuf-2.0 gtk+-3.0 gio-2.0
+-Requires.private: libxml-2.0 libsoup-2.4
++Requires.private: libxml-2.0 libsoup-3.0
+ Libs: -L${libdir} -lmateweather
+ Libs.private: -lm
+ Cflags: -I${includedir}
+diff --git a/libmateweather/weather-bom.c b/libmateweather/weather-bom.c
+index 47b2d0b9..f5c7a87d 100644
+--- a/libmateweather/weather-bom.c
++++ b/libmateweather/weather-bom.c
+@@ -27,34 +27,45 @@
+ #include "weather-priv.h"
+ 
+ static void
+-bom_finish (SoupSession *session, SoupMessage *msg, gpointer data)
++bom_finish (GObject *source, GAsyncResult *result, gpointer data)
+ {
+     char *p, *rp;
+     WeatherInfo *info = (WeatherInfo *)data;
++    GError *error = NULL;
++    GBytes *bytes;
++    const char *response_body = NULL;
++    gsize len = 0;
+ 
+     g_return_if_fail (info != NULL);
+ 
+-    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+-        g_warning ("Failed to get BOM forecast data: %d %s.\n",
+-                 msg->status_code, msg->reason_phrase);
+-        request_done (info, FALSE);
+-      return;
++    bytes = soup_session_send_and_read_finish (SOUP_SESSION(source),
++                                               result, &error);
++
++    if (error != NULL) {
++        g_warning ("Failed to get BOM forecast data: %s.\n", error->message);
++        request_done (info, error);
++        g_error_free (error);
++        return;
+     }
+ 
+-    p = strstr (msg->response_body->data, "Forecast for the rest");
++    response_body = g_bytes_get_data (bytes, &len);
++
++    p = xstrnstr (response_body, len, "Forecast for the rest");
+     if (p != NULL) {
+-        rp = strstr (p, "The next routine forecast will be issued");
++        rp = xstrnstr (p, len - (p - response_body),
++                     "The next routine forecast will be issued");
+         if (rp == NULL)
+-            info->forecast = g_strdup (p);
++            info->forecast = g_strndup (p, len - (p - response_body));
+         else
+             info->forecast = g_strndup (p, rp - p);
+     }
+ 
+     if (info->forecast == NULL)
+-        info->forecast = g_strdup (msg->response_body->data);
++        info->forecast = g_strndup (response_body, len);
+ 
++    g_bytes_unref (bytes);
+     g_print ("%s\n",  info->forecast);
+-    request_done (info, TRUE);
++    request_done (info, NULL);
+ }
+ 
+ void
+@@ -70,7 +81,8 @@ bom_start_open (WeatherInfo *info)
+                          loc->zone + 1);
+ 
+     msg = soup_message_new ("GET", url);
+-    soup_session_queue_message (info->session, msg, bom_finish, info);
++    soup_session_send_and_read_async (info->session, msg, G_PRIORITY_DEFAULT,
++                                      NULL, bom_finish, info);
+     g_free (url);
+ 
+     info->requests_pending++;
+diff --git a/libmateweather/weather-iwin.c b/libmateweather/weather-iwin.c
+index 9f7ff380..b1dc1ffa 100644
+--- a/libmateweather/weather-iwin.c
++++ b/libmateweather/weather-iwin.c
+@@ -93,7 +93,7 @@ hasAttr (xmlNode *node, const char *attr_name, const char 
*attr_value)
+ }
+ 
+ static GSList *
+-parseForecastXml (const char *buff, WeatherInfo *master_info)
++parseForecastXml (const char *buff, gsize len, WeatherInfo *master_info)
+ {
+     GSList *res = NULL;
+     xmlDocPtr doc;
+@@ -107,7 +107,7 @@ parseForecastXml (const char *buff, WeatherInfo 
*master_info)
+     #define XC (const xmlChar *)
+     #define isElem(_node,_name) g_str_equal ((const char *)_node->name, _name)
+ 
+-    doc = xmlParseMemory (buff, strlen (buff));
++    doc = xmlParseMemory (buff, len);
+     if (!doc)
+         return NULL;
+ 
+@@ -380,26 +380,36 @@ parseForecastXml (const char *buff, WeatherInfo 
*master_info)
+ }
+ 
+ static void
+-iwin_finish (SoupSession *session, SoupMessage *msg, gpointer data)
++iwin_finish (GObject *source, GAsyncResult *result, gpointer data)
+ {
+     WeatherInfo *info = (WeatherInfo *)data;
++    GError *error = NULL;
++    GBytes *bytes;
++    const char *response_body = NULL;
++    gsize len = 0;
+ 
+     g_return_if_fail (info != NULL);
+ 
+-    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
++    bytes = soup_session_send_and_read_finish (SOUP_SESSION(source),
++                                               result, &error);
++
++    if (error != NULL) {
+         /* forecast data is not really interesting anyway ;) */
+-        g_warning ("Failed to get IWIN forecast data: %d %s\n",
+-                   msg->status_code, msg->reason_phrase);
+-        request_done (info, FALSE);
++        g_warning ("Failed to get IWIN forecast data: %s\n",
++                   error->message);
++        request_done (info, error);
++        g_error_free (error);
+         return;
+     }
+ 
++    response_body = g_bytes_get_data (bytes, &len);
+     if (info->forecast_type == FORECAST_LIST)
+-        info->forecast_list = parseForecastXml (msg->response_body->data, 
info);
++        info->forecast_list = parseForecastXml (response_body, len, info);
+     else
+-        info->forecast = formatWeatherMsg (g_strdup 
(msg->response_body->data));
++        info->forecast = formatWeatherMsg (g_strndup (response_body, len));
+ 
+-    request_done (info, TRUE);
++    g_bytes_unref (bytes);
++    request_done (info, NULL);
+ }
+ 
+ /* Get forecast into newly alloc'ed string */
+@@ -439,7 +449,9 @@ iwin_start_open (WeatherInfo *info)
+ 
+             msg = soup_message_new ("GET", url);
+             g_free (url);
+-            soup_session_queue_message (info->session, msg, iwin_finish, 
info);
++            soup_session_send_and_read_async (info->session, msg,
++                                              G_PRIORITY_DEFAULT,
++                                              NULL, iwin_finish, info);
+ 
+             info->requests_pending++;
+         }
+@@ -470,7 +482,8 @@ iwin_start_open (WeatherInfo *info)
+ 
+     msg = soup_message_new ("GET", url);
+     g_free (url);
+-    soup_session_queue_message (info->session, msg, iwin_finish, info);
++    soup_session_send_and_read_async (info->session, msg, G_PRIORITY_DEFAULT,
++                                      NULL, iwin_finish, info);
+ 
+     info->requests_pending++;
+ }
+diff --git a/libmateweather/weather-met.c b/libmateweather/weather-met.c
+index 164e9f23..7022abb2 100644
+--- a/libmateweather/weather-met.c
++++ b/libmateweather/weather-met.c
+@@ -119,19 +119,20 @@ met_reprocess (char *x, int len)
+  */
+ 
+ static gchar *
+-met_parse (const gchar *meto)
++met_parse (const gchar *meto, gsize len)
+ {
+     gchar *p;
+     gchar *rp;
+     gchar *r = g_strdup ("Met Office Forecast\n");
+     gchar *t;
++    const gchar *end = meto + len;
+ 
+     g_return_val_if_fail (meto != NULL, r);
+ 
+-    p = strstr (meto, "Summary: </b>");
++    p = xstrnstr (meto, len, "Summary: </b>");
+     g_return_val_if_fail (p != NULL, r);
+ 
+-    rp = strstr (p, "Text issued at:");
++    rp = xstrnstr (p, end - p, "Text issued at:");
+     g_return_val_if_fail (rp != NULL, r);
+ 
+     p += 13;
+@@ -143,21 +144,31 @@ met_parse (const gchar *meto)
+ }
+ 
+ static void
+-met_finish (SoupSession *session, SoupMessage *msg, gpointer data)
++met_finish (GObject *source, GAsyncResult *result, gpointer data)
+ {
+     WeatherInfo *info = (WeatherInfo *)data;
++    GError *error = NULL;
++    GBytes *bytes;
++    const char *response_body = NULL;
++    gsize len = 0;
+ 
+     g_return_if_fail (info != NULL);
+ 
+-    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+-      g_warning ("Failed to get Met Office forecast data: %d %s.\n",
+-                 msg->status_code, msg->reason_phrase);
+-        request_done (info, FALSE);
++    bytes = soup_session_send_and_read_finish (SOUP_SESSION(source),
++                                               result, &error);
++
++    if (error != NULL) {
++        g_warning ("Failed to get Met Office forecast data: %s.\n",
++                   error->message);
++        request_done (info, error);
++        g_error_free (error);
+         return;
+     }
+ 
+-    info->forecast = met_parse (msg->response_body->data);
+-    request_done (info, TRUE);
++    response_body = g_bytes_get_data (bytes, &len);
++    info->forecast = met_parse (response_body, len);
++    g_bytes_unref (bytes);
++    request_done (info, NULL);
+ }
+ 
+ void
+@@ -171,7 +182,8 @@ metoffice_start_open (WeatherInfo *info)
+     url = g_strdup_printf 
("http://www.metoffice.gov.uk/weather/europe/uk/%s.html";, loc->zone + 1);
+ 
+     msg = soup_message_new ("GET", url);
+-    soup_session_queue_message (info->session, msg, met_finish, info);
++    soup_session_send_and_read_async (info->session, msg, G_PRIORITY_DEFAULT,
++                                      NULL, met_finish, info);
+     g_free (url);
+ 
+     info->requests_pending++;
+diff --git a/libmateweather/weather-metar.c b/libmateweather/weather-metar.c
+index 4698a077..dabca3a2 100644
+--- a/libmateweather/weather-metar.c
++++ b/libmateweather/weather-metar.c
+@@ -486,43 +486,60 @@ metar_parse (gchar *metar, WeatherInfo *info)
+ }
+ 
+ static void
+-metar_finish (SoupSession *session, SoupMessage *msg, gpointer data)
++metar_finish (GObject *source, GAsyncResult *result, gpointer data)
+ {
+     WeatherInfo *info = (WeatherInfo *)data;
+     WeatherLocation *loc;
+-    const gchar *p, *endtag;
++    const gchar *p, *end, *endtag;
+     gchar *searchkey, *metar;
+     gboolean success = FALSE;
++    GError *error = NULL;
++    GBytes *bytes;
++    const char *response_body = NULL;
++    gsize len = 0;
+ 
+     g_return_if_fail (info != NULL);
+ 
+-    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+-        if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
++    bytes = soup_session_send_and_read_finish (SOUP_SESSION(source),
++                                               result, &error);
++
++    if (error != NULL) {
++        /* 
https://libsoup.org/libsoup-3.0/migrating-from-libsoup-2.html#status-codes-no-longer-used-for-internal-errors
 */
++        switch (error->code) {
++        case SOUP_SESSION_ERROR_PARSING:
++        case SOUP_SESSION_ERROR_ENCODING:
++        case SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS:
+             info->network_error = TRUE;
+-        else {
+-            /* Translators: %d is an error code, and %s the error string */
+-            g_warning (_("Failed to get METAR data: %d %s.\n"),
+-                       msg->status_code, msg->reason_phrase);
++            break;
++        default:
++            break;
+         }
+-        request_done (info, FALSE);
++        g_warning (_("Failed to get METAR data: %s.\n"),
++                   error->message);
++        request_done (info, error);
++        g_error_free (error);
+         return;
+     }
+ 
+     loc = info->location;
+ 
+     searchkey = g_strdup_printf ("<raw_text>METAR %s", loc->code);
+-    p = strstr (msg->response_body->data, searchkey);
+-    g_free (searchkey);
++
++    response_body = g_bytes_get_data (bytes, &len);
++    end = response_body + len;
++
++    p = xstrnstr (response_body, len, searchkey);
+     if (p) {
+         p += WEATHER_LOCATION_CODE_LEN + 11;
+         endtag = strstr (p, "</raw_text>");
++        endtag = xstrnstr (p, end - p, "</raw_text>");
+         if (endtag)
+             metar = g_strndup (p, endtag - p);
+         else
+-            metar = g_strdup (p);
++            metar = g_strndup (p, end - p);
+         success = metar_parse (metar, info);
+         g_free (metar);
+-    } else if (!strstr (msg->response_body->data, "aviationweather.gov")) {
++    } else if (!xstrnstr (response_body, len, "aviationweather.gov")) {
+         /* The response doesn't even seem to have come from NOAA...
+          * most likely it is a wifi hotspot login page. Call that a
+          * network error.
+@@ -531,7 +548,8 @@ metar_finish (SoupSession *session, SoupMessage *msg, 
gpointer data)
+     }
+ 
+     info->valid = success;
+-    request_done (info, TRUE);
++    request_done (info, NULL);
++    g_bytes_unref(bytes);
+ }
+ 
+ /* Read current conditions and fill in info structure */
+@@ -540,6 +558,7 @@ metar_start_open (WeatherInfo *info)
+ {
+     WeatherLocation *loc;
+     SoupMessage *msg;
++    char *query;
+ 
+     g_return_if_fail (info != NULL);
+     info->valid = info->network_error = FALSE;
+@@ -549,8 +568,7 @@ metar_start_open (WeatherInfo *info)
+         return;
+     }
+ 
+-    msg = soup_form_request_new (
+-        "GET", "https://aviationweather.gov/api/data/dataserver";,
++    query = soup_form_encode (
+         "dataSource", "metars",
+         "requestType", "retrieve",
+         "format", "xml",
+@@ -559,7 +577,11 @@ metar_start_open (WeatherInfo *info)
+         "fields", "raw_text",
+         "stationString", loc->code,
+         NULL);
+-    soup_session_queue_message (info->session, msg, metar_finish, info);
++    msg = soup_message_new_from_encoded_form (
++        "GET", "https://aviationweather.gov/api/data/dataserver";,
++        query);
++    soup_session_send_and_read_async (info->session, msg, G_PRIORITY_DEFAULT,
++                                      NULL, metar_finish, info);
+ 
+     info->requests_pending++;
+ }
+diff --git a/libmateweather/weather-priv.h b/libmateweather/weather-priv.h
+index 817f13c5..03cdcbd9 100644
+--- a/libmateweather/weather-priv.h
++++ b/libmateweather/weather-priv.h
+@@ -21,6 +21,7 @@
+ 
+ #include "config.h"
+ 
++#include <string.h>
+ #include <time.h>
+ #include <libintl.h>
+ #include <math.h>
+@@ -34,6 +35,8 @@ const char *mateweather_dpgettext (const char *context, 
const char *str) G_GNUC_
+ #define _(str) (mateweather_gettext (str))
+ #define C_(context, str) (mateweather_dpgettext (context, str))
+ #define N_(str) (str)
++#define xstrnstr(haystack, hlen, needle) \
++      memmem(haystack, hlen, needle, strlen(needle))
+ 
+ #define WEATHER_LOCATION_CODE_LEN 4
+ 
+@@ -95,7 +98,6 @@ struct _WeatherInfo {
+     GSList *forecast_list; /* list of WeatherInfo* for the forecast, NULL if 
not available */
+     gchar *radar_buffer;
+     gchar *radar_url;
+-    GdkPixbufLoader *radar_loader;
+     GdkPixbufAnimation *radar;
+     SoupSession *session;
+     gint requests_pending;
+@@ -167,7 +169,7 @@ gboolean   metar_parse             (gchar *metar,
+ 
+ gboolean      requests_init           (WeatherInfo *info);
+ void          request_done            (WeatherInfo *info,
+-                                       gboolean     ok);
++                                       GError      *error);
+ 
+ void          ecl2equ                 (gdouble t,
+                                        gdouble eclipLon,
+diff --git a/libmateweather/weather-wx.c b/libmateweather/weather-wx.c
+index e29ceccd..11f73368 100644
+--- a/libmateweather/weather-wx.c
++++ b/libmateweather/weather-wx.c
+@@ -25,48 +25,51 @@
+ #include "weather-priv.h"
+ 
+ static void
+-wx_finish (SoupSession *session, SoupMessage *msg, gpointer data)
++wx_finish (GObject *source, GAsyncResult *result, gpointer data)
+ {
+     WeatherInfo *info = (WeatherInfo *)data;
+     GdkPixbufAnimation *animation;
++    GError *error = NULL;
+ 
+     g_return_if_fail (info != NULL);
+ 
+-    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+-      g_warning ("Failed to get radar map image: %d %s.\n",
+-                 msg->status_code, msg->reason_phrase);
+-      g_object_unref (info->radar_loader);
+-      request_done (info, FALSE);
+-      return;
+-    }
++    animation = gdk_pixbuf_animation_new_from_stream_finish (result, &error);
+ 
+-    gdk_pixbuf_loader_close (info->radar_loader, NULL);
+-    animation = gdk_pixbuf_loader_get_animation (info->radar_loader);
++    if (error != NULL) {
++        g_warning ("Failed to get radar map image: %s.\n", error->message);
++        request_done (info, error);
++        g_error_free (error);
++        return;
++    }
+     if (animation != NULL) {
+-      if (info->radar)
+-          g_object_unref (info->radar);
+-      info->radar = animation;
+-      g_object_ref (info->radar);
++        if (info->radar)
++            g_object_unref (info->radar);
++        info->radar = animation;
++        g_object_ref (info->radar);
+     }
+-    g_object_unref (info->radar_loader);
+ 
+-    request_done (info, TRUE);
++    request_done (info, NULL);
+ }
+ 
+ static void
+-wx_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer data)
++wx_got_chunk (GObject *source, GAsyncResult *result, gpointer data)
+ {
+     WeatherInfo *info = (WeatherInfo *)data;
+     GError *error = NULL;
++    GInputStream *istream;
+ 
+     g_return_if_fail (info != NULL);
+ 
+-    gdk_pixbuf_loader_write (info->radar_loader, (guchar *)chunk->data,
+-                           chunk->length, &error);
+-    if (error) {
+-      g_print ("%s \n", error->message);
+-      g_error_free (error);
++    istream = soup_session_send_finish (SOUP_SESSION (source), result, 
&error);
++
++    if (error != NULL) {
++        g_warning ("Failed to get radar map image: %s.\n", error->message);
++        g_error_free (error);
++        request_done (info, error);
++        return;
+     }
++
++    gdk_pixbuf_animation_new_from_stream_async (istream, NULL, wx_finish, 
data);
+ }
+ 
+ /* Get radar map and into newly allocated pixmap */
+@@ -79,7 +82,6 @@ wx_start_open (WeatherInfo *info)
+ 
+     g_return_if_fail (info != NULL);
+     info->radar = NULL;
+-    info->radar_loader = gdk_pixbuf_loader_new ();
+     loc = info->location;
+     g_return_if_fail (loc != NULL);
+ 
+@@ -98,9 +100,8 @@ wx_start_open (WeatherInfo *info)
+       return;
+     }
+ 
+-    g_signal_connect (msg, "got-chunk", G_CALLBACK (wx_got_chunk), info);
+-    soup_message_body_set_accumulate (msg->response_body, FALSE);
+-    soup_session_queue_message (info->session, msg, wx_finish, info);
++    soup_session_send_async (info->session, msg, G_PRIORITY_DEFAULT, NULL,
++                             wx_got_chunk, info);
+     g_free (url);
+ 
+     info->requests_pending++;
+diff --git a/libmateweather/weather.c b/libmateweather/weather.c
+index 86453fc5..1d7533a6 100644
+--- a/libmateweather/weather.c
++++ b/libmateweather/weather.c
+@@ -348,12 +348,13 @@ requests_init (WeatherInfo *info)
+     return TRUE;
+ }
+ 
+-void request_done (WeatherInfo *info, gboolean ok)
++void request_done (WeatherInfo *info, GError *error)
+ {
+-    if (ok) {
++    if (error == NULL) {
+       (void) calc_sun (info);
+       info->moonValid = info->valid && calc_moon (info);
+-    }
++    } else if (error->code == G_IO_ERROR_CANCELLED)
++        return; /* Caused by soup_session_abort */
+     if (!--info->requests_pending)
+         info->finish_cb (info, info->cb_data);
+ }
+-- 
+2.51.2
+

diff --git a/dev-libs/libmateweather/files/libmateweather-1.28.1-location.patch 
b/dev-libs/libmateweather/files/libmateweather-1.28.1-location.patch
new file mode 100644
index 000000000000..25400c4d0f8a
--- /dev/null
+++ b/dev-libs/libmateweather/files/libmateweather-1.28.1-location.patch
@@ -0,0 +1,114 @@
+From a262101b0468452b4fff25bf19bcd992f21bd1d8 Mon Sep 17 00:00:00 2001
+From: https://github.com/mate-desktop/libmateweather/pull/143
+From: Thibaud CANALE <[email protected]>
+Date: Mon, 10 Nov 2025 02:06:20 +0100
+Subject: [PATCH] location: provide extra checks to avoid SEGFAULT
+
+Bug report in Gentoo: https://bugs.gentoo.org/965885
+
+Signed-off-by: Thibaud CANALE <[email protected]>
+---
+ libmateweather/location-entry.c       | 66 ++++++++++++++-------------
+ libmateweather/mateweather-location.c |  2 +-
+ 2 files changed, 35 insertions(+), 33 deletions(-)
+
+diff --git a/libmateweather/location-entry.c b/libmateweather/location-entry.c
+index 7b922b0e..f88cbbbd 100644
+--- a/libmateweather/location-entry.c
++++ b/libmateweather/location-entry.c
+@@ -223,16 +223,17 @@ mateweather_location_entry_set_location 
(MateWeatherLocationEntry *entry,
+     completion = gtk_entry_get_completion (GTK_ENTRY (entry));
+     model = gtk_entry_completion_get_model (completion);
+ 
+-    gtk_tree_model_get_iter_first (model, &iter);
+-    do {
+-      gtk_tree_model_get (model, &iter,
+-                          MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, &cmploc,
+-                          -1);
+-      if (loc == cmploc) {
+-          set_location_internal (entry, model, &iter);
+-          return;
+-      }
+-    } while (gtk_tree_model_iter_next (model, &iter));
++    if (gtk_tree_model_get_iter_first (model, &iter)) {
++        do {
++            gtk_tree_model_get (model, &iter,
++                                MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, 
&cmploc,
++                                -1);
++            if (loc == cmploc) {
++                set_location_internal (entry, model, &iter);
++                return;
++            }
++        } while (gtk_tree_model_iter_next (model, &iter));
++    }
+ 
+     set_location_internal (entry, model, NULL);
+ }
+@@ -309,28 +310,29 @@ mateweather_location_entry_set_city 
(MateWeatherLocationEntry *entry,
+     completion = gtk_entry_get_completion (GTK_ENTRY (entry));
+     model = gtk_entry_completion_get_model (completion);
+ 
+-    gtk_tree_model_get_iter_first (model, &iter);
+-    do {
+-      gtk_tree_model_get (model, &iter,
+-                          MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, &cmploc,
+-                          -1);
+-
+-      cmpcode = mateweather_location_get_code (cmploc);
+-      if (!cmpcode || strcmp (cmpcode, code) != 0)
+-          continue;
+-
+-      if (city_name) {
+-          cmpname = mateweather_location_get_city_name (cmploc);
+-          if (!cmpname || strcmp (cmpname, city_name) != 0) {
+-              g_free (cmpname);
+-              continue;
+-          }
+-          g_free (cmpname);
+-      }
+-
+-      set_location_internal (entry, model, &iter);
+-      return TRUE;
+-    } while (gtk_tree_model_iter_next (model, &iter));
++    if (gtk_tree_model_get_iter_first (model, &iter)) {
++        do {
++            gtk_tree_model_get (model, &iter,
++                                MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, 
&cmploc,
++                                -1);
++
++            cmpcode = mateweather_location_get_code (cmploc);
++            if (!cmpcode || strcmp (cmpcode, code) != 0)
++                continue;
++
++            if (city_name) {
++                cmpname = mateweather_location_get_city_name (cmploc);
++                if (!cmpname || strcmp (cmpname, city_name) != 0) {
++                    g_free (cmpname);
++                    continue;
++                }
++                g_free (cmpname);
++            }
++
++            set_location_internal (entry, model, &iter);
++            return TRUE;
++        } while (gtk_tree_model_iter_next (model, &iter));
++    }
+ 
+     set_location_internal (entry, model, NULL);
+ 
+diff --git a/libmateweather/mateweather-location.c 
b/libmateweather/mateweather-location.c
+index 9c13c130..e5fd5114 100644
+--- a/libmateweather/mateweather-location.c
++++ b/libmateweather/mateweather-location.c
+@@ -494,7 +494,7 @@ mateweather_location_get_children (MateWeatherLocation 
*loc)
+ {
+     static MateWeatherLocation *no_children = NULL;
+ 
+-    g_return_val_if_fail (loc != NULL, NULL);
++    g_return_val_if_fail (loc != NULL, &no_children);
+ 
+     if (loc->children)
+       return loc->children;
+-- 
+2.51.2
+

diff --git a/dev-libs/libmateweather/libmateweather-1.28.1.ebuild 
b/dev-libs/libmateweather/libmateweather-1.28.1.ebuild
new file mode 100644
index 000000000000..30738835669c
--- /dev/null
+++ b/dev-libs/libmateweather/libmateweather-1.28.1.ebuild
@@ -0,0 +1,59 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MATE_LA_PUNT="yes"
+
+inherit mate
+
+MINOR=$(($(ver_cut 2) % 2))
+if [[ ${MINOR} -eq 0 ]]; then
+       KEYWORDS="~amd64 ~arm ~arm64 ~loong ~riscv ~x86"
+       # Release archive not pushed in main website (?)
+       SRC_URI="
+               
https://github.com/mate-desktop/libmateweather/archive/refs/tags/v${PV}.tar.gz
+                       -> ${P}.gh.tar.gz
+       "
+fi
+
+DESCRIPTION="MATE library to access weather information from online services"
+LICENSE="LGPL-2.1+ GPL-2+"
+SLOT="0"
+
+IUSE="debug"
+
+COMMON_DEPEND=">=dev-libs/glib-2.56:2
+       >=dev-libs/libxml2-2.6:2=
+       net-libs/libsoup:3.0
+       >=sys-libs/timezone-data-2010k:0
+       x11-libs/gdk-pixbuf:2
+       >=x11-libs/gtk+-3.22:3
+"
+
+RDEPEND="${COMMON_DEPEND}
+       virtual/libintl
+"
+
+DEPEND="${RDEPEND}"
+
+BDEPEND="
+       dev-util/gtk-doc
+       dev-build/gtk-doc-am
+       >=sys-devel/gettext-0.19.8
+       >=dev-build/libtool-2.2.6:2
+       virtual/pkgconfig
+"
+
+PATCHES=(
+       "${FILESDIR}"/${P}-libsoup3.patch
+       "${FILESDIR}"/${P}-location.patch # in upstream’s branch 1.28, not in 
tag yet
+       "${FILESDIR}"/${P}-SPECI_report_data.patch
+)
+
+src_configure() {
+       mate_src_configure \
+               --enable-locations-compression \
+               --disable-all-translations-in-one-xml \
+               --disable-icon-update
+}

Reply via email to