diff --git a/ModemManager.spec b/ModemManager.spec index b0853f40ab475d99922a301859b78bff2907f254..ed195c533f0b3694581d90544a56c161f0b51616 100644 --- a/ModemManager.spec +++ b/ModemManager.spec @@ -5,12 +5,22 @@ Name: ModemManager Version: 1.14.8 -Release: 1 +Release: 2 Summary: Mobile broadband modem manager License: GPLv2+ URL: https://www.freedesktop.org/wiki/Software/ModemManager/ Source: https://www.freedesktop.org/software/ModemManager/%{name}-%{version}.tar.xz +Patch0: backport-mtk-fix-task-completion-when-loading-supported-modes.patch +Patch1: backport-sms-prevent-crash-if-date-is-out-of-range.patch +Patch2: backport-core-port-GRegex-GMatchInfo-to-use-autoptr.patch +Patch3: backport-serial-parsers-fix-invalid-EXZ-error-parser.patch +Patch4: backport-test-modem-helpers-add-EOL-to-strings-matched-with-G_REGEX_NEWLINE_CRLF.patch +Patch5: backport-modem-helpers-rework-CGCONTRDP-response-parser.patch +Patch6: backport-modem-helpers-cinterion-rework-CNMI-test-response-parser.patch +Patch7: backport-modem-helpers-ublox-rework-UIPADDR-response-parser.patch +Patch8: backport-modem-helpers-rework-the-CGEV-indication-parser.patch + BuildRequires: automake autoconf dbus gtk-doc libtool vala-tools vala-devel BuildRequires: gettext-devel glib2-devel gobject-introspection-devel libgudev-devel BuildRequires: libqmi-devel libmbim-devel systemd-devel @@ -64,7 +74,7 @@ Vala bindings for ModemManager %package_help %prep -%autosetup -n %{name}-%{version} +%autosetup -n %{name}-%{version} -p1 %build autoreconf -if @@ -138,6 +148,12 @@ make check %{_datadir}/dbus-1/interfaces/*.xml %changelog +* Sat Nov 12 2022 gaihuiying - 1.14.8-2 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC: fix test failure because of glib2 switching to pcre2 + * Wed Jan 27 2021 xihaochen - 1.14.8-1 - Type:requirements - ID:NA diff --git a/backport-core-port-GRegex-GMatchInfo-to-use-autoptr.patch b/backport-core-port-GRegex-GMatchInfo-to-use-autoptr.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ad218421e162b5266cd02cdbdba19e54f94a564 --- /dev/null +++ b/backport-core-port-GRegex-GMatchInfo-to-use-autoptr.patch @@ -0,0 +1,4327 @@ +From 74fc5baca229922b244ad66d5819d6d765e2d9da Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Wed, 24 Aug 2022 12:31:47 +0000 +Subject: [PATCH] core: port GRegex/GMatchInfo to use autoptr() + +The behavior of GRegex changed in 2.73.2 once it was ported from pcre1 +to pcre2. In some cases it was made more strict, which is fine, in +other cases it exposed some change in how it behaves on certain +matches that is not extremely clear whether it's ok or not. + +See https://gitlab.gnome.org/GNOME/glib/-/issues/2729 + +See https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/601 +See https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/621 + +Either way, one thing that was assumed was that initializing all +GRegex/GMatchInfo variables to NULL and making sure they're NULL +before they're initialized by glib (especially the GMatchInfo) was a +good and safer approach. + +So, whenever possible, g_autoptr() is used to cleanup the allocated +GMatchInfo/GRegex variables, and otherwise, g_clear_pointer() is used +to ensure that no free/unref is attempted unless the given variable is +not NULL, and also so that the variable is reseted to NULL after being +disposed. +--- + libmm-glib/mm-location-gps-nmea.c | 10 +- + libmm-glib/mm-location-gps-raw.c | 4 +- + plugins/anydata/mm-broadband-modem-anydata.c | 82 ++- + .../cinterion/mm-modem-helpers-cinterion.c | 62 +- + .../tests/test-modem-helpers-cinterion.c | 42 +- + plugins/huawei/mm-broadband-modem-huawei.c | 19 +- + plugins/huawei/mm-modem-helpers-huawei.c | 329 +++++------ + plugins/icera/mm-broadband-modem-icera.c | 32 +- + plugins/mbm/mm-modem-helpers-mbm.c | 37 +- + plugins/mtk/mm-broadband-modem-mtk.c | 104 ++-- + plugins/novatel/mm-broadband-modem-novatel.c | 45 +- + plugins/option/mm-broadband-modem-option.c | 42 +- + plugins/quectel/mm-shared-quectel.c | 3 +- + plugins/sierra/mm-broadband-modem-sierra.c | 41 +- + plugins/sierra/mm-common-sierra.c | 4 +- + plugins/sierra/mm-modem-helpers-sierra.c | 16 +- + .../tests/test-modem-helpers-simtech.c | 75 +-- + plugins/telit/mm-broadband-modem-telit.c | 9 +- + plugins/telit/mm-common-telit.c | 16 +- + plugins/telit/mm-modem-helpers-telit.c | 13 +- + plugins/ublox/mm-broadband-modem-ublox.c | 11 +- + plugins/ublox/mm-modem-helpers-ublox.c | 152 ++--- + plugins/via/mm-broadband-modem-via.c | 22 +- + plugins/wavecom/mm-broadband-modem-wavecom.c | 7 +- + plugins/x22x/mm-broadband-modem-x22x.c | 17 +- + plugins/xmm/mm-modem-helpers-xmm.c | 51 +- + plugins/zte/mm-broadband-modem-zte.c | 28 +- + src/mm-broadband-modem.c | 187 ++---- + src/mm-modem-helpers.c | 538 +++++++----------- + src/mm-port-serial-at.c | 11 +- + src/mm-port-serial-gps.c | 14 +- + src/mm-serial-parsers.c | 21 +- + src/tests/test-modem-helpers.c | 72 +-- + 33 files changed, 849 insertions(+), 1267 deletions(-) + +diff --git a/libmm-glib/mm-location-gps-nmea.c b/libmm-glib/mm-location-gps-nmea.c +index d23bc1462..b2ef69511 100644 +--- a/libmm-glib/mm-location-gps-nmea.c ++++ b/libmm-glib/mm-location-gps-nmea.c +@@ -54,9 +54,7 @@ static gboolean + check_append_or_replace (MMLocationGpsNmea *self, + const gchar *trace) + { +- /* By default, replace */ +- gboolean append_or_replace = FALSE; +- GMatchInfo *match_info = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + if (G_UNLIKELY (!self->priv->sequence_regex)) + self->priv->sequence_regex = g_regex_new ("\\$GPGSV,(\\d),(\\d).*", +@@ -69,11 +67,11 @@ check_append_or_replace (MMLocationGpsNmea *self, + + /* If we don't have the first element of a sequence, append */ + if (mm_get_uint_from_match_info (match_info, 2, &index) && index != 1) +- append_or_replace = TRUE; ++ return TRUE; + } +- g_match_info_free (match_info); + +- return append_or_replace; ++ /* By default, replace */ ++ return FALSE; + } + + static gboolean +diff --git a/libmm-glib/mm-location-gps-raw.c b/libmm-glib/mm-location-gps-raw.c +index fddc5629b..d776d1ca6 100644 +--- a/libmm-glib/mm-location-gps-raw.c ++++ b/libmm-glib/mm-location-gps-raw.c +@@ -190,7 +190,7 @@ gboolean + mm_location_gps_raw_add_trace (MMLocationGpsRaw *self, + const gchar *trace) + { +- GMatchInfo *match_info = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + /* Current implementation works only with $GPGGA and $GNGGA traces */ + do { +@@ -268,8 +268,6 @@ mm_location_gps_raw_add_trace (MMLocationGpsRaw *self, + mm_get_double_from_match_info (match_info, 9, &self->priv->altitude); + } + +- g_match_info_free (match_info); +- + return TRUE; + } + +diff --git a/plugins/anydata/mm-broadband-modem-anydata.c b/plugins/anydata/mm-broadband-modem-anydata.c +index 95f8cbd27..36d72e56c 100644 +--- a/plugins/anydata/mm-broadband-modem-anydata.c ++++ b/plugins/anydata/mm-broadband-modem-anydata.c +@@ -72,10 +72,10 @@ hstate_ready (MMIfaceModemCdma *self, + GTask *task) + { + DetailedRegistrationStateResults *results; +- GError *error = NULL; +- const gchar *response; +- GRegex *r; +- GMatchInfo *match_info; ++ GError *error = NULL; ++ const gchar *response; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + results = g_task_get_task_data (task); + +@@ -129,9 +129,6 @@ hstate_ready (MMIfaceModemCdma *self, + } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + g_task_return_pointer (task, g_memdup (results, sizeof (*results)), g_free); + g_object_unref (task); + } +@@ -142,10 +139,10 @@ state_ready (MMIfaceModemCdma *self, + GTask *task) + { + DetailedRegistrationStateResults *results; +- GError *error = NULL; +- const gchar *response; +- GRegex *r; +- GMatchInfo *match_info; ++ GError *error = NULL; ++ const gchar *response; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); + if (error) { +@@ -194,9 +191,6 @@ state_ready (MMIfaceModemCdma *self, + } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + /* Try for EVDO state too */ + mm_base_modem_at_command (MM_BASE_MODEM (self), + "*HSTATE?", +@@ -261,9 +255,14 @@ reset (MMIfaceModem *self, + static void + setup_ports (MMBroadbandModem *self) + { +- MMPortSerialAt *ports[2]; +- GRegex *regex; +- guint i; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) active_regex = NULL; ++ g_autoptr(GRegex) inactive_regex = NULL; ++ g_autoptr(GRegex) dormant_regex = NULL; ++ g_autoptr(GRegex) offline_regex = NULL; ++ g_autoptr(GRegex) regreq_regex = NULL; ++ g_autoptr(GRegex) authreq_regex = NULL; ++ guint i; + + /* Call parent's setup ports first always */ + MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_anydata_parent_class)->setup_ports (self); +@@ -271,48 +270,37 @@ setup_ports (MMBroadbandModem *self) + ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); + ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); + ++ /* Data call has connected */ ++ active_regex = g_regex_new ("\\r\\n\\*ACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); ++ /* Data call disconnected */ ++ inactive_regex = g_regex_new ("\\r\\n\\*INACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); ++ /* Modem is now dormant */ ++ dormant_regex = g_regex_new ("\\r\\n\\*DORMANT:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); ++ /* Network acquisition fail */ ++ offline_regex = g_regex_new ("\\r\\n\\*OFFLINE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); ++ /* Registration fail */ ++ regreq_regex = g_regex_new ("\\r\\n\\*REGREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); ++ /* Authentication fail */ ++ authreq_regex = g_regex_new ("\\r\\n\\*AUTHREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); ++ + /* Now reset the unsolicited messages */ + for (i = 0; i < G_N_ELEMENTS (ports); i++) { + if (!ports[i]) + continue; + + /* Data state notifications */ +- +- /* Data call has connected */ +- regex = g_regex_new ("\\r\\n\\*ACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL); +- g_regex_unref (regex); +- +- /* Data call disconnected */ +- regex = g_regex_new ("\\r\\n\\*INACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL); +- g_regex_unref (regex); +- +- /* Modem is now dormant */ +- regex = g_regex_new ("\\r\\n\\*DORMANT:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL); +- g_regex_unref (regex); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), active_regex, NULL, NULL, NULL); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), inactive_regex, NULL, NULL, NULL); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), dormant_regex, NULL, NULL, NULL); + + /* Abnormal state notifications + * + * FIXME: set 1X/EVDO registration state to UNKNOWN when these + * notifications are received? + */ +- +- /* Network acquisition fail */ +- regex = g_regex_new ("\\r\\n\\*OFFLINE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL); +- g_regex_unref (regex); +- +- /* Registration fail */ +- regex = g_regex_new ("\\r\\n\\*REGREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL); +- g_regex_unref (regex); +- +- /* Authentication fail */ +- regex = g_regex_new ("\\r\\n\\*AUTHREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL); +- g_regex_unref (regex); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), offline_regex, NULL, NULL, NULL); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regreq_regex, NULL, NULL, NULL); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), authreq_regex, NULL, NULL, NULL); + } + } + +diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c +index a75eb5304..0bf3a0782 100644 +--- a/plugins/cinterion/mm-modem-helpers-cinterion.c ++++ b/plugins/cinterion/mm-modem-helpers-cinterion.c +@@ -554,14 +554,14 @@ mm_cinterion_parse_cnmi_test (const gchar *response, + GArray **supported_bfr, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- GArray *tmp_supported_mode = NULL; +- GArray *tmp_supported_mt = NULL; +- GArray *tmp_supported_bm = NULL; +- GArray *tmp_supported_ds = NULL; +- GArray *tmp_supported_bfr = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ GArray *tmp_supported_mode = NULL; ++ GArray *tmp_supported_mt = NULL; ++ GArray *tmp_supported_bm = NULL; ++ GArray *tmp_supported_ds = NULL; ++ GArray *tmp_supported_bfr = NULL; + + if (!response) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response"); +@@ -576,57 +576,48 @@ mm_cinterion_parse_cnmi_test (const gchar *response, + g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error); + if (!inner_error && g_match_info_matches (match_info)) { + if (supported_mode) { +- gchar *str; ++ g_autofree gchar *str = NULL; + + str = mm_get_string_unquoted_from_match_info (match_info, 1); + tmp_supported_mode = mm_parse_uint_list (str, &inner_error); +- g_free (str); + if (inner_error) + goto out; + } + if (supported_mt) { +- gchar *str; ++ g_autofree gchar *str = NULL; + + str = mm_get_string_unquoted_from_match_info (match_info, 2); + tmp_supported_mt = mm_parse_uint_list (str, &inner_error); +- g_free (str); + if (inner_error) + goto out; + } + if (supported_bm) { +- gchar *str; ++ g_autofree gchar *str = NULL; + + str = mm_get_string_unquoted_from_match_info (match_info, 3); + tmp_supported_bm = mm_parse_uint_list (str, &inner_error); +- g_free (str); + if (inner_error) + goto out; + } + if (supported_ds) { +- gchar *str; ++ g_autofree gchar *str = NULL; + + str = mm_get_string_unquoted_from_match_info (match_info, 4); + tmp_supported_ds = mm_parse_uint_list (str, &inner_error); +- g_free (str); + if (inner_error) + goto out; + } + if (supported_bfr) { +- gchar *str; ++ g_autofree gchar *str = NULL; + + str = mm_get_string_unquoted_from_match_info (match_info, 5); + tmp_supported_bfr = mm_parse_uint_list (str, &inner_error); +- g_free (str); + if (inner_error) + goto out; + } + } + + out: +- +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_clear_pointer (&tmp_supported_mode, g_array_unref); + g_clear_pointer (&tmp_supported_mt, g_array_unref); +@@ -763,9 +754,9 @@ mm_cinterion_parse_sind_response (const gchar *response, + guint *value, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- guint errors = 0; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ guint errors = 0; + + if (!response) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response"); +@@ -788,9 +779,6 @@ mm_cinterion_parse_sind_response (const gchar *response, + } else + errors++; + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (errors > 0) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Failed parsing ^SIND response"); + return FALSE; +@@ -836,8 +824,8 @@ mm_cinterion_parse_swwan_response (const gchar *response, + gpointer log_object, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + GError *inner_error = NULL; + MMBearerConnectionStatus status; + +@@ -883,9 +871,6 @@ mm_cinterion_parse_swwan_response (const gchar *response, + g_match_info_next (match_info, &inner_error); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN) + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No state returned for CID %u", cid); +@@ -1078,10 +1063,10 @@ mm_cinterion_parse_slcc_list (const gchar *str, + GList **out_list, + GError **error) + { +- GRegex *r; +- GList *list = NULL; +- GError *inner_error = NULL; +- GMatchInfo *match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GList *list = NULL; ++ GError *inner_error = NULL; + + static const MMCallDirection cinterion_call_direction[] = { + [0] = MM_CALL_DIRECTION_OUTGOING, +@@ -1158,9 +1143,6 @@ mm_cinterion_parse_slcc_list (const gchar *str, + } + + out: +- g_clear_pointer (&match_info, g_match_info_free); +- g_regex_unref (r); +- + if (inner_error) { + mm_cinterion_call_info_list_free (list); + g_propagate_error (error, inner_error); +diff --git a/plugins/cinterion/tests/test-modem-helpers-cinterion.c b/plugins/cinterion/tests/test-modem-helpers-cinterion.c +index c3e7e9e5f..8332700b5 100644 +--- a/plugins/cinterion/tests/test-modem-helpers-cinterion.c ++++ b/plugins/cinterion/tests/test-modem-helpers-cinterion.c +@@ -1192,18 +1192,17 @@ test_smong_response_no_match (void) + /* Test ^SLCC URCs */ + + static void +-common_test_slcc_urc (const gchar *urc, ++common_test_slcc_urc (const gchar *urc, + const MMCallInfo *expected_call_info_list, +- guint expected_call_info_list_size) ++ guint expected_call_info_list_size) + { +- GError *error = NULL; +- GRegex *slcc_regex = NULL; +- gboolean result; +- GMatchInfo *match_info = NULL; +- gchar *str; +- GList *call_info_list = NULL; +- GList *l; +- ++ g_autoptr(GRegex) slcc_regex = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *str = NULL; ++ GError *error = NULL; ++ GList *call_info_list = NULL; ++ GList *l; ++ gboolean result; + + slcc_regex = mm_cinterion_get_slcc_regex (); + +@@ -1230,8 +1229,8 @@ common_test_slcc_urc (const gchar *urc, + + for (l = call_info_list; l; l = g_list_next (l)) { + const MMCallInfo *call_info = (const MMCallInfo *)(l->data); +- gboolean found = FALSE; +- guint i; ++ gboolean found = FALSE; ++ guint i; + + g_debug ("call at index %u: direction %s, state %s, number %s", + call_info->index, +@@ -1248,10 +1247,6 @@ common_test_slcc_urc (const gchar *urc, + g_assert (found); + } + +- g_match_info_free (match_info); +- g_regex_unref (slcc_regex); +- g_free (str); +- + mm_cinterion_call_info_list_free (call_info_list); + } + +@@ -1322,12 +1317,12 @@ common_test_ctzu_urc (const gchar *urc, + gint expected_offset, + gint expected_dst_offset) + { +- GError *error = NULL; +- GRegex *ctzu_regex = NULL; +- gboolean result; +- GMatchInfo *match_info = NULL; +- gchar *iso8601; +- MMNetworkTimezone *tz = NULL; ++ g_autoptr(GRegex) ctzu_regex = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *iso8601 = NULL; ++ GError *error = NULL; ++ gboolean result; ++ MMNetworkTimezone *tz = NULL; + + ctzu_regex = mm_cinterion_get_ctzu_regex (); + +@@ -1342,7 +1337,6 @@ common_test_ctzu_urc (const gchar *urc, + + g_assert (iso8601); + g_assert_cmpstr (expected_iso8601, ==, iso8601); +- g_free (iso8601); + + g_assert (tz); + g_assert_cmpint (expected_offset, ==, mm_network_timezone_get_offset (tz)); +@@ -1351,8 +1345,6 @@ common_test_ctzu_urc (const gchar *urc, + g_assert_cmpuint ((guint)expected_dst_offset, ==, mm_network_timezone_get_dst_offset (tz)); + + g_object_unref (tz); +- g_match_info_free (match_info); +- g_regex_unref (ctzu_regex); + } + + static void +diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c +index 866707d63..c7c68b9f3 100644 +--- a/plugins/huawei/mm-broadband-modem-huawei.c ++++ b/plugins/huawei/mm-broadband-modem-huawei.c +@@ -627,12 +627,13 @@ load_unlock_retries_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) + { +- MMUnlockRetries *unlock_retries; +- const gchar *result; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- guint i; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ MMUnlockRetries *unlock_retries; ++ const gchar *result; ++ GError *match_error = NULL; ++ guint i; ++ + MMModemLock locks[4] = { + MM_MODEM_LOCK_SIM_PUK, + MM_MODEM_LOCK_SIM_PIN, +@@ -657,9 +658,6 @@ load_unlock_retries_finish (MMIfaceModem *self, + MM_CORE_ERROR_FAILED, + "Could not parse ^CPIN results: Response didn't match (%s)", + result); +- +- g_match_info_free (match_info); +- g_regex_unref (r); + return NULL; + } + +@@ -683,9 +681,6 @@ load_unlock_retries_finish (MMIfaceModem *self, + mm_unlock_retries_set (unlock_retries, locks[i], num); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + return unlock_retries; + } + +diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c +index 3ded62379..67bb7089b 100644 +--- a/plugins/huawei/mm-modem-helpers-huawei.c ++++ b/plugins/huawei/mm-modem-helpers-huawei.c +@@ -39,8 +39,6 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response, + gboolean *ipv6_connected, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; + GError *inner_error = NULL; + + if (!response || +@@ -71,6 +69,9 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response, + + /* If multiple fields available, try first parsing method */ + if (strchr (response, ',')) { ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ + r = g_regex_new ("\\^NDISSTAT(?:QRY)?(?:Qry)?:\\s*(\\d),([^,]*),([^,]*),([^,\\r\\n]*)(?:\\r\\n)?" + "(?:\\^NDISSTAT:|\\^NDISSTATQRY:)?\\s*,?(\\d)?,?([^,]*)?,?([^,]*)?,?([^,\\r\\n]*)?(?:\\r\\n)?", + G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, +@@ -108,12 +109,12 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response, + ip_type_field += 4; + } + } +- +- g_match_info_free (match_info); +- g_regex_unref (r); + } + /* No separate IPv4/IPv6 info given just connected/not connected */ + else { ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ + r = g_regex_new ("\\^NDISSTAT(?:QRY)?(?:Qry)?:\\s*(\\d)(?:\\r\\n)?", + G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, + 0, NULL); +@@ -134,9 +135,6 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response, + *ipv4_connected = (gboolean)connected; + } + } +- +- g_match_info_free (match_info); +- g_regex_unref (r); + } + + if (!ipv4_available && !ipv6_available) { +@@ -208,10 +206,10 @@ mm_huawei_parse_dhcp_response (const char *reply, + guint *out_dns2, + GError **error) + { +- gboolean matched; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gboolean matched; ++ GError *match_error = NULL; + + g_assert (reply != NULL); + g_assert (out_address != NULL); +@@ -257,8 +255,6 @@ mm_huawei_parse_dhcp_response (const char *reply, + } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); + return matched; + } + +@@ -276,10 +272,10 @@ mm_huawei_parse_sysinfo_response (const char *reply, + guint *out_sys_submode, + GError **error) + { +- gboolean matched; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gboolean matched; ++ GError *match_error = NULL; + + g_assert (out_srv_status != NULL); + g_assert (out_srv_domain != NULL); +@@ -323,8 +319,6 @@ mm_huawei_parse_sysinfo_response (const char *reply, + } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); + return matched; + } + +@@ -341,10 +335,10 @@ mm_huawei_parse_sysinfoex_response (const char *reply, + guint *out_sys_submode, + GError **error) + { +- gboolean matched; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gboolean matched; ++ GError *match_error = NULL; + + g_assert (out_srv_status != NULL); + g_assert (out_srv_domain != NULL); +@@ -387,8 +381,6 @@ mm_huawei_parse_sysinfoex_response (const char *reply, + mm_get_uint_from_match_info (match_info, 8, out_sys_submode); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); + return matched; + } + +@@ -1189,17 +1181,23 @@ mm_huawei_parse_syscfgex_response (const gchar *response, + /*****************************************************************************/ + /* ^NWTIME response parser */ + +-gboolean mm_huawei_parse_nwtime_response (const gchar *response, +- gchar **iso8601p, +- MMNetworkTimezone **tzp, +- GError **error) ++gboolean ++mm_huawei_parse_nwtime_response (const gchar *response, ++ gchar **iso8601p, ++ MMNetworkTimezone **tzp, ++ GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, dt = 0; +- gint tz = 0; +- gboolean ret = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; ++ guint year = 0; ++ guint month = 0; ++ guint day = 0; ++ guint hour = 0; ++ guint minute = 0; ++ guint second = 0; ++ guint dt = 0; ++ gint tz = 0; + + g_assert (iso8601p || tzp); /* at least one */ + +@@ -1211,75 +1209,72 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response, + g_propagate_error (error, match_error); + g_prefix_error (error, "Could not parse ^NWTIME results: "); + } else { +- g_set_error_literal (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, ++ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't match ^NWTIME reply"); + } +- } else { +- /* Remember that g_match_info_get_match_count() includes match #0 */ +- g_assert (g_match_info_get_match_count (match_info) >= 9); +- +- if (mm_get_uint_from_match_info (match_info, 1, &year) && +- mm_get_uint_from_match_info (match_info, 2, &month) && +- mm_get_uint_from_match_info (match_info, 3, &day) && +- mm_get_uint_from_match_info (match_info, 4, &hour) && +- mm_get_uint_from_match_info (match_info, 5, &minute) && +- mm_get_uint_from_match_info (match_info, 6, &second) && +- mm_get_int_from_match_info (match_info, 7, &tz) && +- mm_get_uint_from_match_info (match_info, 8, &dt)) { +- +- ret = TRUE; +- +- /* adjust year */ +- if (year < 100) +- year += 2000; +- /* +- * tz = timezone offset in 15 minute intervals +- * dt = daylight adjustment, 0 = none, 1 = 1 hour, 2 = 2 hours +- * other values are marked reserved. +- */ +- if (iso8601p) { +- /* Return ISO-8601 format date/time string */ +- *iso8601p = mm_new_iso8601_time (year, month, day, hour, +- minute, second, +- TRUE, (tz * 15) + (dt * 60), +- error); +- ret = (*iso8601p != NULL); +- } +- if (tzp) { +- *tzp = mm_network_timezone_new (); +- mm_network_timezone_set_offset (*tzp, tz * 15); +- mm_network_timezone_set_dst_offset (*tzp, dt * 60); +- } ++ return FALSE; ++ } + +- } else { +- g_set_error_literal (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, +- "Failed to parse ^NWTIME reply"); ++ /* Remember that g_match_info_get_match_count() includes match #0 */ ++ g_assert (g_match_info_get_match_count (match_info) >= 9); ++ ++ if (mm_get_uint_from_match_info (match_info, 1, &year) && ++ mm_get_uint_from_match_info (match_info, 2, &month) && ++ mm_get_uint_from_match_info (match_info, 3, &day) && ++ mm_get_uint_from_match_info (match_info, 4, &hour) && ++ mm_get_uint_from_match_info (match_info, 5, &minute) && ++ mm_get_uint_from_match_info (match_info, 6, &second) && ++ mm_get_int_from_match_info (match_info, 7, &tz) && ++ mm_get_uint_from_match_info (match_info, 8, &dt)) { ++ ++ /* adjust year */ ++ if (year < 100) ++ year += 2000; ++ /* ++ * tz = timezone offset in 15 minute intervals ++ * dt = daylight adjustment, 0 = none, 1 = 1 hour, 2 = 2 hours ++ * other values are marked reserved. ++ */ ++ if (tzp) { ++ *tzp = mm_network_timezone_new (); ++ mm_network_timezone_set_offset (*tzp, tz * 15); ++ mm_network_timezone_set_dst_offset (*tzp, dt * 60); ++ } ++ if (iso8601p) { ++ /* Return ISO-8601 format date/time string */ ++ *iso8601p = mm_new_iso8601_time (year, month, day, hour, ++ minute, second, ++ TRUE, (tz * 15) + (dt * 60), ++ error); ++ return (*iso8601p != NULL); + } +- } + +- g_match_info_free (match_info); +- g_regex_unref (r); ++ return TRUE; ++ } + +- return ret; ++ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, ++ "Failed to parse ^NWTIME reply"); ++ return FALSE; + } + + /*****************************************************************************/ + /* ^TIME response parser */ + +-gboolean mm_huawei_parse_time_response (const gchar *response, +- gchar **iso8601p, +- MMNetworkTimezone **tzp, +- GError **error) ++gboolean ++mm_huawei_parse_time_response (const gchar *response, ++ gchar **iso8601p, ++ MMNetworkTimezone **tzp, ++ GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- guint year, month, day, hour, minute, second; +- gboolean ret = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; ++ guint year = 0; ++ guint month = 0; ++ guint day = 0; ++ guint hour = 0; ++ guint minute = 0; ++ guint second = 0; + + g_assert (iso8601p || tzp); /* at least one */ + +@@ -1306,41 +1301,35 @@ gboolean mm_huawei_parse_time_response (const gchar *response, + MM_CORE_ERROR_FAILED, + "Couldn't match ^TIME reply"); + } +- } else { +- /* Remember that g_match_info_get_match_count() includes match #0 */ +- g_assert (g_match_info_get_match_count (match_info) >= 7); +- +- if (mm_get_uint_from_match_info (match_info, 1, &year) && +- mm_get_uint_from_match_info (match_info, 2, &month) && +- mm_get_uint_from_match_info (match_info, 3, &day) && +- mm_get_uint_from_match_info (match_info, 4, &hour) && +- mm_get_uint_from_match_info (match_info, 5, &minute) && +- mm_get_uint_from_match_info (match_info, 6, &second)) { +- ret = TRUE; +- +- /* adjust year */ +- if (year < 100) +- year += 2000; ++ return FALSE; ++ } + +- /* Return ISO-8601 format date/time string */ +- if (iso8601p) { +- *iso8601p = mm_new_iso8601_time (year, month, day, hour, +- minute, second, FALSE, 0, +- error); +- ret = (*iso8601p != NULL); +- } +- } else { +- g_set_error_literal (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, +- "Failed to parse ^TIME reply"); ++ /* Remember that g_match_info_get_match_count() includes match #0 */ ++ g_assert (g_match_info_get_match_count (match_info) >= 7); ++ ++ if (mm_get_uint_from_match_info (match_info, 1, &year) && ++ mm_get_uint_from_match_info (match_info, 2, &month) && ++ mm_get_uint_from_match_info (match_info, 3, &day) && ++ mm_get_uint_from_match_info (match_info, 4, &hour) && ++ mm_get_uint_from_match_info (match_info, 5, &minute) && ++ mm_get_uint_from_match_info (match_info, 6, &second)) { ++ /* adjust year */ ++ if (year < 100) ++ year += 2000; ++ ++ /* Return ISO-8601 format date/time string */ ++ if (iso8601p) { ++ *iso8601p = mm_new_iso8601_time (year, month, day, hour, ++ minute, second, FALSE, 0, ++ error); ++ return (*iso8601p != NULL); + } ++ return TRUE; + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- +- return ret; ++ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, ++ "Failed to parse ^TIME reply"); ++ return FALSE; + } + + /*****************************************************************************/ +@@ -1356,11 +1345,9 @@ mm_huawei_parse_hcsq_response (const gchar *response, + guint *out_value5, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- gboolean ret = FALSE; +- char *s; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; + + r = g_regex_new ("\\^HCSQ:\\s*\"?([a-zA-Z]*)\"?,(\\d+),?(\\d+)?,?(\\d+)?,?(\\d+)?,?(\\d+)?$", 0, 0, NULL); + g_assert (r != NULL); +@@ -1370,27 +1357,24 @@ mm_huawei_parse_hcsq_response (const gchar *response, + g_propagate_error (error, match_error); + g_prefix_error (error, "Could not parse ^HCSQ results: "); + } else { +- g_set_error_literal (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, ++ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't match ^HCSQ reply"); + } +- goto done; ++ return FALSE; + } + + /* Remember that g_match_info_get_match_count() includes match #0 */ + if (g_match_info_get_match_count (match_info) < 3) { +- g_set_error_literal (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, ++ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Not enough elements in ^HCSQ reply"); +- goto done; ++ return FALSE; + } + + if (out_act) { ++ g_autofree gchar *s = NULL; ++ + s = g_match_info_fetch (match_info, 1); + *out_act = mm_string_to_access_tech (s); +- g_free (s); + } + + if (out_value1) +@@ -1404,13 +1388,7 @@ mm_huawei_parse_hcsq_response (const gchar *response, + if (out_value5) + mm_get_uint_from_match_info (match_info, 6, out_value5); + +- ret = TRUE; +- +-done: +- g_match_info_free (match_info); +- g_regex_unref (r); +- +- return ret; ++ return TRUE; + } + + /*****************************************************************************/ +@@ -1422,11 +1400,12 @@ mm_huawei_parse_cvoice_response (const gchar *response, + guint *out_bits, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- guint supported = 0, hz = 0, bits = 0; +- gboolean ret = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; ++ guint supported = 0; ++ guint hz = 0; ++ guint bits = 0; + + /* ^CVOICE: <0=supported,1=unsupported>,,, */ + r = g_regex_new ("\\^CVOICE:\\s*(\\d)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)$", 0, 0, NULL); +@@ -1442,35 +1421,29 @@ mm_huawei_parse_cvoice_response (const gchar *response, + MM_CORE_ERROR_FAILED, + "Couldn't match ^CVOICE reply"); + } +- } else { +- /* Remember that g_match_info_get_match_count() includes match #0 */ +- g_assert (g_match_info_get_match_count (match_info) >= 5); +- +- if (mm_get_uint_from_match_info (match_info, 1, &supported) && +- mm_get_uint_from_match_info (match_info, 2, &hz) && +- mm_get_uint_from_match_info (match_info, 3, &bits)) { +- if (supported == 0) { +- if (out_hz) +- *out_hz = hz; +- if (out_bits) +- *out_bits = bits; +- ret = TRUE; +- } else { +- g_set_error_literal (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_UNSUPPORTED, +- "^CVOICE not supported by this device"); +- } +- } else { +- g_set_error_literal (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, +- "Failed to parse ^CVOICE reply"); +- } ++ return FALSE; + } + +- g_match_info_free (match_info); +- g_regex_unref (r); ++ /* Remember that g_match_info_get_match_count() includes match #0 */ ++ g_assert (g_match_info_get_match_count (match_info) >= 5); ++ ++ if (mm_get_uint_from_match_info (match_info, 1, &supported) && ++ mm_get_uint_from_match_info (match_info, 2, &hz) && ++ mm_get_uint_from_match_info (match_info, 3, &bits)) { ++ if (supported == 0) { ++ if (out_hz) ++ *out_hz = hz; ++ if (out_bits) ++ *out_bits = bits; ++ return TRUE; ++ } ++ ++ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, ++ "^CVOICE not supported by this device"); ++ return FALSE; ++ } + +- return ret; ++ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, ++ "Failed to parse ^CVOICE reply"); ++ return FALSE; + } +diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c +index 897d25626..759985e00 100644 +--- a/plugins/icera/mm-broadband-modem-icera.c ++++ b/plugins/icera/mm-broadband-modem-icera.c +@@ -123,12 +123,12 @@ load_supported_modes_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) + { +- GArray *combinations = NULL; +- const gchar *response; +- gchar **split = NULL; +- GMatchInfo *match_info; +- GRegex *r; +- guint i; ++ GArray *combinations = NULL; ++ const gchar *response; ++ gchar **split = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ guint i; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); + if (!response) +@@ -145,18 +145,13 @@ load_supported_modes_finish (MMIfaceModem *self, + + g_regex_match (r, response, 0, &match_info); + if (g_match_info_matches (match_info)) { +- gchar *aux; ++ g_autofree gchar *aux = NULL; + + aux = mm_get_string_unquoted_from_match_info (match_info, 1); +- if (aux) { ++ if (aux) + split = g_strsplit (aux, ",", -1); +- g_free (aux); +- } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (!split) { + g_set_error (error, + MM_CORE_ERROR, +@@ -1122,11 +1117,12 @@ icera_band_to_mm (const char *icera) + } + + static GSList * +-parse_bands (const gchar *response, guint32 *out_len) ++parse_bands (const gchar *response, ++ guint32 *out_len) + { +- GRegex *r; +- GMatchInfo *info; +- GSList *bands = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) info = NULL; ++ GSList *bands = NULL; + + g_return_val_if_fail (out_len != NULL, NULL); + +@@ -1163,8 +1159,6 @@ parse_bands (const gchar *response, guint32 *out_len) + g_free (enabled); + g_match_info_next (info, NULL); + } +- g_match_info_free (info); +- g_regex_unref (r); + + return bands; + } +diff --git a/plugins/mbm/mm-modem-helpers-mbm.c b/plugins/mbm/mm-modem-helpers-mbm.c +index 31fbb3763..846cc4d66 100644 +--- a/plugins/mbm/mm-modem-helpers-mbm.c ++++ b/plugins/mbm/mm-modem-helpers-mbm.c +@@ -55,15 +55,17 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response, + MMBearerIpConfig **out_ip6_config, + GError **error) + { +- MMBearerIpConfig **ip_config = NULL; +- gboolean got_address = FALSE, got_gw = FALSE, got_dns = FALSE; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- gchar *dns[3] = { 0 }; +- guint dns_idx = 0; +- int family = AF_INET; +- MMBearerIpMethod method = MM_BEARER_IP_METHOD_STATIC; ++ MMBearerIpConfig **ip_config = NULL; ++ gboolean got_address = FALSE; ++ gboolean got_gw = FALSE; ++ gboolean got_dns = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; ++ gchar *dns[3] = { 0 }; ++ guint dns_idx = 0; ++ int family = AF_INET; ++ MMBearerIpMethod method = MM_BEARER_IP_METHOD_STATIC; + + g_return_val_if_fail (out_ip4_config, FALSE); + g_return_val_if_fail (out_ip6_config, FALSE); +@@ -108,14 +110,17 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response, + MM_CORE_ERROR_FAILED, + "Couldn't match " E2IPCFG_TAG " reply"); + } +- goto done; ++ return FALSE; + } + + *ip_config = mm_bearer_ip_config_new (); + mm_bearer_ip_config_set_method (*ip_config, method); + while (g_match_info_matches (match_info)) { +- char *id = g_match_info_fetch (match_info, 1); +- char *str = g_match_info_fetch (match_info, 2); ++ g_autofree gchar *id = NULL; ++ g_autofree gchar *str = NULL; ++ ++ id = g_match_info_fetch (match_info, 1); ++ str = g_match_info_fetch (match_info, 2); + + switch (atoi (id)) { + case 1: +@@ -140,8 +145,6 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response, + default: + break; + } +- g_free (id); +- g_free (str); + g_match_info_next (match_info, NULL); + } + +@@ -156,12 +159,10 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response, + *ip_config = NULL; + g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Got incomplete IP configuration from " E2IPCFG_TAG); ++ return FALSE; + } + +-done: +- g_match_info_free (match_info); +- g_regex_unref (r); +- return !!*ip_config; ++ return TRUE; + } + + /*****************************************************************************/ +diff --git a/plugins/mtk/mm-broadband-modem-mtk.c b/plugins/mtk/mm-broadband-modem-mtk.c +index 0ceca795f..869784f30 100644 +--- a/plugins/mtk/mm-broadband-modem-mtk.c ++++ b/plugins/mtk/mm-broadband-modem-mtk.c +@@ -67,13 +67,16 @@ load_unlock_retries_ready (MMBaseModem *self, + GAsyncResult *res, + GTask *task) + { +- const gchar *response; +- GError *error = NULL; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- GRegex *r = NULL; +- gint pin1, puk1, pin2, puk2; +- MMUnlockRetries *retries; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ const gchar *response; ++ GError *error = NULL; ++ GError *match_error = NULL; ++ gint pin1; ++ gint puk1; ++ gint pin2; ++ gint puk2; ++ MMUnlockRetries *retries; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); + if (!response) { +@@ -91,14 +94,11 @@ load_unlock_retries_ready (MMBaseModem *self, + g_assert (r != NULL); + + if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &match_error)){ +- if (match_error) { +- g_propagate_error (&error, match_error); +- } else { +- g_set_error (&error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, +- "Failed to match EPINC response: %s", response); +- } ++ if (match_error) ++ g_task_return_error (task, match_error); ++ else ++ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, ++ "Failed to match EPINC response: %s", response); + g_task_return_error (task, error); + } else if (!mm_get_int_from_match_info (match_info, 1, &pin1) || + !mm_get_int_from_match_info (match_info, 2, &pin2) || +@@ -120,9 +120,6 @@ load_unlock_retries_ready (MMBaseModem *self, + g_task_return_pointer (task, retries, g_object_unref); + } + g_object_unref (task); +- +- g_match_info_free (match_info); +- g_regex_unref (r); + } + + static void +@@ -178,14 +175,14 @@ get_supported_modes_ready (MMBaseModem *self, + GTask *task) + + { +- const gchar *response; +- GError *error = NULL; +- GMatchInfo *match_info = NULL; +- MMModemModeCombination mode; +- GArray *combinations; +- GRegex *r; +- GError *match_error = NULL; +- gint device_type; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ const gchar *response; ++ GError *error = NULL; ++ MMModemModeCombination mode; ++ GArray *combinations; ++ GError *match_error = NULL; ++ gint device_type; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); + if (!response) { +@@ -205,9 +202,6 @@ get_supported_modes_ready (MMBaseModem *self, + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Failed to match EGMR response: %s", response); + g_object_unref (task); +- +- g_match_info_free (match_info); +- g_regex_unref (r); + return; + } + +@@ -216,9 +210,6 @@ get_supported_modes_ready (MMBaseModem *self, + "Failed to parse the allowed mode response: '%s'", + response); + g_object_unref (task); +- +- g_regex_unref (r); +- g_match_info_free (match_info); + return; + } + +@@ -271,9 +262,6 @@ get_supported_modes_ready (MMBaseModem *self, + */ + g_task_return_pointer (task, combinations, (GDestroyNotify)g_array_unref); + g_object_unref (task); +- +- g_regex_unref (r); +- g_match_info_free (match_info); + } + + static void +@@ -307,17 +295,16 @@ load_current_modes_finish (MMIfaceModem *self, + MMModemMode *preferred, + GError **error) + { +- const gchar *response; +- GMatchInfo *match_info = NULL; +- GRegex *r; +- gint erat_mode = -1; +- gint erat_pref = -1; +- GError *match_error = NULL; +- gboolean result = FALSE; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ const gchar *response; ++ gint erat_mode = -1; ++ gint erat_pref = -1; ++ GError *match_error = NULL; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); + if (!response) +- return result; ++ return FALSE; + + r = g_regex_new ( + "\\+ERAT:\\s*[0-9]+,\\s*[0-9]+,\\s*([0-9]+),\\s*([0-9]+)", +@@ -329,30 +316,22 @@ load_current_modes_finish (MMIfaceModem *self, + if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &match_error)) { + if (match_error) + g_propagate_error (error, match_error); +- else { +- g_set_error (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, ++ else ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't parse +ERAT response: '%s'", + response); +- +- } +- goto done; ++ return FALSE; + } + + if (!mm_get_int_from_match_info (match_info, 1, &erat_mode) || + !mm_get_int_from_match_info (match_info, 2, &erat_pref)) { +- g_set_error (error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Failed to parse the ERAT response: m=%d p=%d", + erat_mode, erat_pref); +- goto done; ++ return FALSE; + } + + /* Correctly parsed! */ +- result = TRUE; +- + switch (erat_mode) { + case 0: + *allowed = MM_MODEM_MODE_2G; +@@ -376,9 +355,8 @@ load_current_modes_finish (MMIfaceModem *self, + *allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G; + break; + default: +- result = FALSE; + mm_obj_dbg (self, "unsupported allowed mode reported in +ERAT: %d", erat_mode); +- goto done; ++ return FALSE; + } + + switch (erat_pref) { +@@ -395,17 +373,11 @@ load_current_modes_finish (MMIfaceModem *self, + *preferred = MM_MODEM_MODE_4G; + break; + default: +- result = FALSE; + mm_obj_dbg (self, "unsupported preferred mode %d", erat_pref); +- goto done; ++ return FALSE; + } + +-done: +- if (r) +- g_regex_unref (r); +- g_match_info_free (match_info); +- +- return result; ++ return TRUE; + } + + static void +diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c +index 1cc88e906..46bf438a2 100644 +--- a/plugins/novatel/mm-broadband-modem-novatel.c ++++ b/plugins/novatel/mm-broadband-modem-novatel.c +@@ -159,12 +159,12 @@ nwrat_query_ready (MMBaseModem *self, + GTask *task) + { + LoadCurrentModesResult *result; +- GError *error = NULL; +- const gchar *response; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- gint a = -1; +- gint b = -1; ++ GError *error = NULL; ++ const gchar *response; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gint a = -1; ++ gint b = -1; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); + if (!response) { +@@ -187,8 +187,6 @@ nwrat_query_ready (MMBaseModem *self, + "Couldn't match NWRAT reply: %s", + response); + g_object_unref (task); +- g_match_info_free (match_info); +- g_regex_unref (r); + return; + } + +@@ -203,8 +201,6 @@ nwrat_query_ready (MMBaseModem *self, + "Failed to parse mode/tech response '%s': invalid modes reported", + response); + g_object_unref (task); +- g_match_info_free (match_info); +- g_regex_unref (r); + return; + } + +@@ -239,9 +235,6 @@ nwrat_query_ready (MMBaseModem *self, + break; + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + g_task_return_pointer (task, result, g_free); + g_object_unref (task); + } +@@ -1396,13 +1389,18 @@ parse_nwltime_reply (const char *response, + MMNetworkTimezone **out_tz, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- guint year, month, day, hour, minute, second; +- gchar *result = NULL; +- gint utc_offset = 0; +- gboolean success = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; ++ guint year; ++ guint month; ++ guint day; ++ guint hour; ++ guint minute; ++ guint second; ++ g_autofree gchar *result = NULL; ++ gint utc_offset = 0; ++ gboolean success = FALSE; + + /* Sample reply: 2013.3.27.15.47.19.2.-5 */ + r = g_regex_new ("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.([\\-\\+\\d]+)$", 0, 0, NULL); +@@ -1447,12 +1444,8 @@ parse_nwltime_reply (const char *response, + } + + if (out_iso_8601) +- *out_iso_8601 = result; +- else +- g_free (result); ++ *out_iso_8601 = g_steal_pointer (&result); + +- g_match_info_free (match_info); +- g_regex_unref (r); + return success; + } + +diff --git a/plugins/option/mm-broadband-modem-option.c b/plugins/option/mm-broadband-modem-option.c +index 5919364da..dcecd5b08 100644 +--- a/plugins/option/mm-broadband-modem-option.c ++++ b/plugins/option/mm-broadband-modem-option.c +@@ -362,12 +362,10 @@ static gboolean + parse_ossys_response (const gchar *response, + MMModemAccessTechnology *access_technology) + { +- MMModemAccessTechnology current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; +- const gchar *p; +- GRegex *r; +- GMatchInfo *match_info; +- gchar *str; +- gboolean success = FALSE; ++ MMModemAccessTechnology current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; ++ const gchar *p; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + p = mm_strip_tag (response, "_OSSYS:"); + r = g_regex_new ("(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL); +@@ -375,17 +373,15 @@ parse_ossys_response (const gchar *response, + + g_regex_match (r, p, 0, &match_info); + if (g_match_info_matches (match_info)) { ++ g_autofree gchar *str = NULL; ++ + str = g_match_info_fetch (match_info, 2); + if (str && ossys_to_mm (str[0], ¤t)) { + *access_technology = current; +- success = TRUE; +- } +- g_free (str); ++ return TRUE; ++ } + } +- g_match_info_free (match_info); +- g_regex_unref (r); +- +- return success; ++ return FALSE; + } + + static void +@@ -445,12 +441,10 @@ static gboolean + parse_octi_response (const gchar *response, + MMModemAccessTechnology *access_technology) + { +- MMModemAccessTechnology current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; +- const gchar *p; +- GRegex *r; +- GMatchInfo *match_info; +- gchar *str; +- gboolean success = FALSE; ++ MMModemAccessTechnology current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; ++ const gchar *p; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + p = mm_strip_tag (response, "_OCTI:"); + r = g_regex_new ("(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL); +@@ -458,17 +452,15 @@ parse_octi_response (const gchar *response, + + g_regex_match (r, p, 0, &match_info); + if (g_match_info_matches (match_info)) { ++ g_autofree gchar *str = NULL; ++ + str = g_match_info_fetch (match_info, 2); + if (str && octi_to_mm (str[0], ¤t)) { + *access_technology = current; +- success = TRUE; ++ return TRUE; + } +- g_free (str); + } +- g_match_info_free (match_info); +- g_regex_unref (r); +- +- return success; ++ return FALSE; + } + + static void +diff --git a/plugins/quectel/mm-shared-quectel.c b/plugins/quectel/mm-shared-quectel.c +index ab079436d..c383dc05a 100644 +--- a/plugins/quectel/mm-shared-quectel.c ++++ b/plugins/quectel/mm-shared-quectel.c +@@ -440,7 +440,7 @@ mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self, + MMPortSerialAt *port_primary; + MMPortSerialAt *port_secondary; + GTask *task; +- GRegex *pattern; ++ g_autoptr(GRegex) pattern = NULL; + + task = g_task_new (self, NULL, callback, user_data); + +@@ -464,7 +464,6 @@ mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self, + self, + NULL); + +- g_regex_unref (pattern); + mm_obj_dbg (self, "+QUSIM detection set up"); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c +index 3ac20808f..bae8e3449 100644 +--- a/plugins/sierra/mm-broadband-modem-sierra.c ++++ b/plugins/sierra/mm-broadband-modem-sierra.c +@@ -624,7 +624,7 @@ load_current_modes_finish (MMIfaceModem *self, + MMModemMode *preferred, + GError **error) + { +- LoadCurrentModesResult *result; ++ g_autofree LoadCurrentModesResult *result = NULL; + + result = g_task_propagate_pointer (G_TASK (res), error); + if (!result) +@@ -632,7 +632,6 @@ load_current_modes_finish (MMIfaceModem *self, + + *allowed = result->allowed; + *preferred = result->preferred; +- g_free (result); + return TRUE; + } + +@@ -641,11 +640,11 @@ selrat_query_ready (MMBaseModem *self, + GAsyncResult *res, + GTask *task) + { +- LoadCurrentModesResult *result; +- const gchar *response; +- GError *error = NULL; +- GRegex *r = NULL; +- GMatchInfo *match_info = NULL; ++ g_autofree LoadCurrentModesResult *result = NULL; ++ const gchar *response; ++ GError *error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + response = mm_base_modem_at_command_full_finish (self, res, &error); + if (!response) { +@@ -727,15 +726,10 @@ selrat_query_ready (MMBaseModem *self, + "Could not parse allowed mode response: Response didn't match: '%s'", + response); + +- g_match_info_free (match_info); +- g_regex_unref (r); +- +- if (error) { +- g_free (result); ++ if (error) + g_task_return_error (task, error); +- } else +- g_task_return_pointer (task, result, g_free); +- ++ else ++ g_task_return_pointer (task, g_steal_pointer (&result), g_free); + g_object_unref (task); + } + +@@ -1630,11 +1624,16 @@ parse_time (const gchar *response, + const gchar *tag, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- guint year, month, day, hour, minute, second; +- gchar *result = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; ++ guint year; ++ guint month; ++ guint day; ++ guint hour; ++ guint minute; ++ guint second; ++ gchar *result = NULL; + + r = g_regex_new (regex, 0, 0, NULL); + g_assert (r != NULL); +@@ -1665,8 +1664,6 @@ parse_time (const gchar *response, + } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); + return result; + } + +diff --git a/plugins/sierra/mm-common-sierra.c b/plugins/sierra/mm-common-sierra.c +index 341006d6a..72cbc34f0 100644 +--- a/plugins/sierra/mm-common-sierra.c ++++ b/plugins/sierra/mm-common-sierra.c +@@ -480,7 +480,7 @@ mm_common_sierra_setup_ports (MMBroadbandModem *self) + { + MMPortSerialAt *ports[2]; + guint i; +- GRegex *pacsp_regex; ++ g_autoptr(GRegex) pacsp_regex = NULL; + + pacsp_regex = g_regex_new ("\\r\\n\\+PACSP.*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + +@@ -505,8 +505,6 @@ mm_common_sierra_setup_ports (MMBroadbandModem *self) + pacsp_regex, + NULL, NULL, NULL); + } +- +- g_regex_unref (pacsp_regex); + } + + /*****************************************************************************/ +diff --git a/plugins/sierra/mm-modem-helpers-sierra.c b/plugins/sierra/mm-modem-helpers-sierra.c +index ac07c9eeb..821be1994 100644 +--- a/plugins/sierra/mm-modem-helpers-sierra.c ++++ b/plugins/sierra/mm-modem-helpers-sierra.c +@@ -23,16 +23,15 @@ GList * + mm_sierra_parse_scact_read_response (const gchar *reply, + GError **error) + { +- GError *inner_error = NULL; +- GRegex *r; +- GMatchInfo *match_info; +- GList *list; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ GList *list = NULL; + + if (!reply || !reply[0]) + /* Nothing configured, all done */ + return NULL; + +- list = NULL; + r = g_regex_new ("!SCACT:\\s*(\\d+),(\\d+)", + G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, 0, &inner_error); + g_assert (r); +@@ -66,9 +65,6 @@ mm_sierra_parse_scact_read_response (const gchar *reply, + g_match_info_next (match_info, &inner_error); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + mm_3gpp_pdp_context_active_list_free (list); + g_propagate_error (error, inner_error); +@@ -76,7 +72,5 @@ mm_sierra_parse_scact_read_response (const gchar *reply, + return NULL; + } + +- list = g_list_sort (list, (GCompareFunc) mm_3gpp_pdp_context_active_cmp); +- +- return list; ++ return g_list_sort (list, (GCompareFunc) mm_3gpp_pdp_context_active_cmp); + } +diff --git a/plugins/simtech/tests/test-modem-helpers-simtech.c b/plugins/simtech/tests/test-modem-helpers-simtech.c +index d5d774f24..ba6532cca 100644 +--- a/plugins/simtech/tests/test-modem-helpers-simtech.c ++++ b/plugins/simtech/tests/test-modem-helpers-simtech.c +@@ -33,13 +33,13 @@ common_test_clcc_urc (const gchar *urc, + const MMCallInfo *expected_call_info_list, + guint expected_call_info_list_size) + { +- GError *error = NULL; +- GRegex *clcc_regex = NULL; +- gboolean result; +- GMatchInfo *match_info = NULL; +- gchar *str; +- GList *call_info_list = NULL; +- GList *l; ++ g_autoptr(GRegex) clcc_regex = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *str = NULL; ++ GError *error = NULL; ++ GList *call_info_list = NULL; ++ GList *l; ++ gboolean result; + + clcc_regex = mm_simtech_get_clcc_urc_regex (); + +@@ -84,10 +84,6 @@ common_test_clcc_urc (const gchar *urc, + g_assert (found); + } + +- g_match_info_free (match_info); +- g_regex_unref (clcc_regex); +- g_free (str); +- + mm_simtech_call_info_list_free (call_info_list); + } + +@@ -148,12 +144,12 @@ common_test_voice_call_urc (const gchar *urc, + gboolean expected_start_or_stop, + guint expected_duration) + { +- GError *error = NULL; +- gboolean start_or_stop = FALSE; /* start = TRUE, stop = FALSE */ +- guint duration = 0; +- GRegex *voice_call_regex = NULL; +- gboolean result; +- GMatchInfo *match_info = NULL; ++ g_autoptr(GRegex) voice_call_regex = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *error = NULL; ++ gboolean start_or_stop = FALSE; /* start = TRUE, stop = FALSE */ ++ guint duration = 0; ++ gboolean result; + + voice_call_regex = mm_simtech_get_voice_call_urc_regex (); + +@@ -168,9 +164,6 @@ common_test_voice_call_urc (const gchar *urc, + + g_assert_cmpuint (expected_start_or_stop, ==, start_or_stop); + g_assert_cmpuint (expected_duration, ==, duration); +- +- g_match_info_free (match_info); +- g_regex_unref (voice_call_regex); + } + + static void +@@ -197,11 +190,11 @@ static void + common_test_missed_call_urc (const gchar *urc, + const gchar *expected_details) + { +- GError *error = NULL; +- gchar *details = NULL; +- GRegex *missed_call_regex = NULL; +- gboolean result; +- GMatchInfo *match_info = NULL; ++ g_autoptr(GRegex) missed_call_regex = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *details = NULL; ++ GError *error = NULL; ++ gboolean result; + + missed_call_regex = mm_simtech_get_missed_call_urc_regex (); + +@@ -215,10 +208,6 @@ common_test_missed_call_urc (const gchar *urc, + g_assert (result); + + g_assert_cmpstr (expected_details, ==, details); +- g_free (details); +- +- g_match_info_free (match_info); +- g_regex_unref (missed_call_regex); + } + + static void +@@ -233,11 +222,11 @@ static void + common_test_cring_urc (const gchar *urc, + const gchar *expected_type) + { +- GError *error = NULL; +- GRegex *cring_regex = NULL; +- GMatchInfo *match_info = NULL; +- gchar *type; +- gboolean result; ++ g_autoptr(GRegex) cring_regex = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *type = NULL; ++ GError *error = NULL; ++ gboolean result; + + cring_regex = mm_simtech_get_cring_urc_regex (); + +@@ -250,10 +239,6 @@ common_test_cring_urc (const gchar *urc, + g_assert (type); + + g_assert_cmpstr (type, ==, expected_type); +- +- g_match_info_free (match_info); +- g_regex_unref (cring_regex); +- g_free (type); + } + + static void +@@ -274,11 +259,11 @@ static void + common_test_rxdtmf_urc (const gchar *urc, + const gchar *expected_str) + { +- GError *error = NULL; +- GRegex *rxdtmf_regex = NULL; +- GMatchInfo *match_info = NULL; +- gchar *type; +- gboolean result; ++ g_autoptr(GRegex) rxdtmf_regex = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *type = NULL; ++ GError *error = NULL; ++ gboolean result; + + rxdtmf_regex = mm_simtech_get_rxdtmf_urc_regex (); + +@@ -291,10 +276,6 @@ common_test_rxdtmf_urc (const gchar *urc, + g_assert (type); + + g_assert_cmpstr (type, ==, expected_str); +- +- g_match_info_free (match_info); +- g_regex_unref (rxdtmf_regex); +- g_free (type); + } + + static void +diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c +index 49e48247c..bbf3f7603 100644 +--- a/plugins/telit/mm-broadband-modem-telit.c ++++ b/plugins/telit/mm-broadband-modem-telit.c +@@ -501,10 +501,10 @@ telit_qss_enable_ready (MMBaseModem *self, + GAsyncResult *res, + GTask *task) + { +- QssSetupContext *ctx; +- MMPortSerialAt *port; +- GError **error; +- GRegex *pattern; ++ QssSetupContext *ctx; ++ MMPortSerialAt *port; ++ GError **error; ++ g_autoptr(GRegex) pattern = NULL; + + ctx = g_task_get_task_data (task); + +@@ -530,7 +530,6 @@ telit_qss_enable_ready (MMBaseModem *self, + (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler, + self, + NULL); +- g_regex_unref (pattern); + + next_step: + ctx->step++; +diff --git a/plugins/telit/mm-common-telit.c b/plugins/telit/mm-common-telit.c +index 2e0b38015..911c605b2 100644 +--- a/plugins/telit/mm-common-telit.c ++++ b/plugins/telit/mm-common-telit.c +@@ -112,12 +112,12 @@ cache_port_mode (MMPortProbe *probe, + MMDevice *device, + const gchar *reply) + { +- GRegex *r = NULL; +- GRegexCompileFlags flags = G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW; +- GMatchInfo *match_info = NULL; +- GError *error = NULL; +- gboolean ret = FALSE; +- guint portcfg_current; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GRegexCompileFlags flags = G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW; ++ GError *error = NULL; ++ gboolean ret = FALSE; ++ guint portcfg_current; + + /* #PORTCFG: , */ + r = g_regex_new ("#PORTCFG:\\s*(\\d+),(\\d+)", flags, 0, NULL); +@@ -173,9 +173,7 @@ cache_port_mode (MMPortProbe *probe, + ret = TRUE; + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- if (error != NULL) { ++ if (error) { + mm_obj_dbg (probe, "error while matching #PORTCFG: %s", error->message); + g_error_free (error); + } +diff --git a/plugins/telit/mm-modem-helpers-telit.c b/plugins/telit/mm-modem-helpers-telit.c +index c2061fcd5..54cd6a0cf 100644 +--- a/plugins/telit/mm-modem-helpers-telit.c ++++ b/plugins/telit/mm-modem-helpers-telit.c +@@ -701,10 +701,10 @@ common_parse_bnd_response (const gchar *response, + gpointer log_object, + GError **error) + { +- GError *inner_error = NULL; +- GArray *bands = NULL; +- GMatchInfo *match_info = NULL; +- GRegex *r; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ GError *inner_error = NULL; ++ GArray *bands = NULL; + + static const gchar *load_bands_regex[] = { + [LOAD_BANDS_TYPE_SUPPORTED] = "#BND:\\s*\\((?P[0-9\\-,]*)\\)(,\\s*\\((?P[0-9\\-,]*)\\))?(,\\s*\\((?P[0-9\\-,]*)\\))?", +@@ -761,9 +761,6 @@ common_parse_bnd_response (const gchar *response, + goto out; + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + g_clear_pointer (&bands, g_array_unref); +diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c +index bb0e02ac9..5cc035422 100644 +--- a/plugins/ublox/mm-modem-helpers-ublox.c ++++ b/plugins/ublox/mm-modem-helpers-ublox.c +@@ -31,14 +31,14 @@ mm_ublox_parse_upincnt_response (const gchar *response, + guint *out_puk2_attempts, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint pin_attempts = 0; +- guint pin2_attempts = 0; +- guint puk_attempts = 0; +- guint puk2_attempts = 0; +- gboolean success = TRUE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint pin_attempts = 0; ++ guint pin2_attempts = 0; ++ guint puk_attempts = 0; ++ guint puk2_attempts = 0; ++ gboolean success = TRUE; + + g_assert (out_pin_attempts); + g_assert (out_pin2_attempts); +@@ -78,9 +78,6 @@ mm_ublox_parse_upincnt_response (const gchar *response, + + out: + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -107,10 +104,10 @@ mm_ublox_parse_uusbconf_response (const gchar *response, + MMUbloxUsbProfile *out_profile, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- MMUbloxUsbProfile profile = MM_UBLOX_USB_PROFILE_UNKNOWN; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ MMUbloxUsbProfile profile = MM_UBLOX_USB_PROFILE_UNKNOWN; + + g_assert (out_profile != NULL); + +@@ -127,7 +124,7 @@ mm_ublox_parse_uusbconf_response (const gchar *response, + + g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error); + if (!inner_error && g_match_info_matches (match_info)) { +- gchar *profile_name; ++ g_autofree gchar *profile_name = NULL; + + profile_name = mm_get_string_unquoted_from_match_info (match_info, 2); + if (profile_name && profile_name[0]) { +@@ -140,12 +137,8 @@ mm_ublox_parse_uusbconf_response (const gchar *response, + "Unknown USB profile: '%s'", profile_name); + } else + profile = MM_UBLOX_USB_PROFILE_BACK_COMPATIBLE; +- g_free (profile_name); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -169,10 +162,10 @@ mm_ublox_parse_ubmconf_response (const gchar *response, + MMUbloxNetworkingMode *out_mode, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- MMUbloxNetworkingMode mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ MMUbloxNetworkingMode mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN; + + g_assert (out_mode != NULL); + +@@ -203,9 +196,6 @@ mm_ublox_parse_ubmconf_response (const gchar *response, + } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -234,15 +224,15 @@ mm_ublox_parse_uipaddr_response (const gchar *response, + gchar **out_ipv6_link_local_address, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint cid = 0; +- gchar *if_name = NULL; +- gchar *ipv4_address = NULL; +- gchar *ipv4_subnet = NULL; +- gchar *ipv6_global_address = NULL; +- gchar *ipv6_link_local_address = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint cid = 0; ++ gchar *if_name = NULL; ++ gchar *ipv4_address = NULL; ++ gchar *ipv4_subnet = NULL; ++ gchar *ipv6_global_address = NULL; ++ gchar *ipv6_link_local_address = NULL; + + /* Response may be e.g.: + * +UIPADDR: 1,"ccinet0","5.168.120.13","255.255.255.0","","" +@@ -288,10 +278,6 @@ mm_ublox_parse_uipaddr_response (const gchar *response, + ipv6_link_local_address = mm_get_string_unquoted_from_match_info (match_info, 6); + + out: +- +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_free (if_name); + g_free (ipv4_address); +@@ -1550,11 +1536,11 @@ GArray * + mm_ublox_parse_uact_response (const gchar *response, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- GArray *nums = NULL; +- GArray *bands = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ GArray *nums = NULL; ++ GArray *bands = NULL; + + /* + * AT+UACT? +@@ -1566,16 +1552,12 @@ mm_ublox_parse_uact_response (const gchar *response, + + g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error); + if (!inner_error && g_match_info_matches (match_info)) { +- gchar *bandstr; ++ g_autofree gchar *bandstr = NULL; + + bandstr = mm_get_string_unquoted_from_match_info (match_info, 4); + nums = mm_parse_uint_list (bandstr, &inner_error); +- g_free (bandstr); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return NULL; +@@ -1632,16 +1614,16 @@ mm_ublox_parse_uact_test (const gchar *response, + GArray **bands4g_out, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- const gchar *bands2g_str = NULL; +- const gchar *bands3g_str = NULL; +- const gchar *bands4g_str = NULL; +- GArray *bands2g = NULL; +- GArray *bands3g = NULL; +- GArray *bands4g = NULL; +- gchar **split = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_auto(GStrv) split = NULL; ++ GError *inner_error = NULL; ++ const gchar *bands2g_str = NULL; ++ const gchar *bands3g_str = NULL; ++ const gchar *bands4g_str = NULL; ++ GArray *bands2g = NULL; ++ GArray *bands3g = NULL; ++ GArray *bands4g = NULL; + + g_assert (bands2g_out && bands3g_out && bands4g_out); + +@@ -1658,8 +1640,8 @@ mm_ublox_parse_uact_test (const gchar *response, + goto out; + + if (g_match_info_matches (match_info)) { +- gchar *aux; +- guint n_groups; ++ g_autofree gchar *aux = NULL; ++ guint n_groups; + + aux = mm_get_string_unquoted_from_match_info (match_info, 4); + split = mm_split_string_groups (aux); +@@ -1670,7 +1652,6 @@ mm_ublox_parse_uact_test (const gchar *response, + bands3g_str = split[1]; + if (n_groups >= 3) + bands4g_str = split[2]; +- g_free (aux); + } + + if (!bands2g_str && !bands3g_str && !bands4g_str) { +@@ -1692,10 +1673,6 @@ mm_ublox_parse_uact_test (const gchar *response, + /* success */ + + out: +- g_strfreev (split); +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + if (bands2g) + g_array_unref (bands2g); +@@ -1760,13 +1737,13 @@ mm_ublox_parse_urat_read_response (const gchar *response, + MMModemMode *out_preferred, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- MMModemMode allowed = MM_MODEM_MODE_NONE; +- MMModemMode preferred = MM_MODEM_MODE_NONE; +- gchar *allowed_str = NULL; +- gchar *preferred_str = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ MMModemMode allowed = MM_MODEM_MODE_NONE; ++ MMModemMode preferred = MM_MODEM_MODE_NONE; ++ g_autofree gchar *allowed_str = NULL; ++ g_autofree gchar *preferred_str = NULL; + + g_assert (out_allowed != NULL && out_preferred != NULL); + +@@ -1821,13 +1798,6 @@ mm_ublox_parse_urat_read_response (const gchar *response, + } + + out: +- +- g_free (allowed_str); +- g_free (preferred_str); +- +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -1981,14 +1951,14 @@ mm_ublox_parse_ugcntrd_response_for_cid (const gchar *response, + guint64 *out_total_rx_bytes, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *inner_error = NULL; +- guint64 session_tx_bytes = 0; +- guint64 session_rx_bytes = 0; +- guint64 total_tx_bytes = 0; +- guint64 total_rx_bytes = 0; +- gboolean matched = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint64 session_tx_bytes = 0; ++ guint64 session_rx_bytes = 0; ++ guint64 total_tx_bytes = 0; ++ guint64 total_rx_bytes = 0; ++ gboolean matched = FALSE; + + /* Response may be e.g.: + * +UGCNTRD: 31,2704,1819,2724,1839 +@@ -2044,10 +2014,6 @@ mm_ublox_parse_ugcntrd_response_for_cid (const gchar *response, + } + + out: +- +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +diff --git a/plugins/via/mm-broadband-modem-via.c b/plugins/via/mm-broadband-modem-via.c +index 6a8b45081..896db8cd4 100644 +--- a/plugins/via/mm-broadband-modem-via.c ++++ b/plugins/via/mm-broadband-modem-via.c +@@ -153,7 +153,7 @@ get_detailed_registration_state_finish (MMIfaceModemCdma *self, + MMModemCdmaRegistrationState *detailed_evdo_state, + GError **error) + { +- DetailedRegistrationStateResults *results; ++ g_autofree DetailedRegistrationStateResults *results = NULL; + + results = g_task_propagate_pointer (G_TASK (res), error); + if (!results) +@@ -161,7 +161,6 @@ get_detailed_registration_state_finish (MMIfaceModemCdma *self, + + *detailed_cdma1x_state = results->detailed_cdma1x_state; + *detailed_evdo_state = results->detailed_evdo_state; +- g_free (results); + return TRUE; + } + +@@ -171,13 +170,13 @@ sysinfo_ready (MMBaseModem *self, + GTask *task) + + { +- DetailedRegistrationStateResults *ctx; +- DetailedRegistrationStateResults *results; +- const gchar *response; +- GRegex *r; +- GMatchInfo *match_info; +- MMModemCdmaRegistrationState reg_state; +- guint val = 0; ++ DetailedRegistrationStateResults *ctx; ++ g_autofree DetailedRegistrationStateResults *results = NULL; ++ const gchar *response; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ MMModemCdmaRegistrationState reg_state; ++ guint val = 0; + + ctx = g_task_get_task_data (task); + +@@ -236,11 +235,8 @@ sysinfo_ready (MMBaseModem *self, + results->detailed_cdma1x_state = reg_state; + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + out: +- g_task_return_pointer (task, results, NULL); ++ g_task_return_pointer (task, g_steal_pointer (&results), g_free); + g_object_unref (task); + } + +diff --git a/plugins/wavecom/mm-broadband-modem-wavecom.c b/plugins/wavecom/mm-broadband-modem-wavecom.c +index 8659e1c46..521e72de2 100644 +--- a/plugins/wavecom/mm-broadband-modem-wavecom.c ++++ b/plugins/wavecom/mm-broadband-modem-wavecom.c +@@ -1223,9 +1223,9 @@ modem_power_off (MMIfaceModem *self, + static void + setup_ports (MMBroadbandModem *self) + { +- gpointer parser; +- MMPortSerialAt *primary; +- GRegex *regex; ++ gpointer parser; ++ MMPortSerialAt *primary; ++ g_autoptr(GRegex) regex = NULL; + + /* Call parent's setup ports first always */ + MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_wavecom_parent_class)->setup_ports (self); +@@ -1242,7 +1242,6 @@ setup_ports (MMBroadbandModem *self) + G_REGEX_RAW | G_REGEX_OPTIMIZE, + 0, NULL); + mm_serial_parser_v1_set_custom_regex (parser, regex, NULL); +- g_regex_unref (regex); + + mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (primary), + mm_serial_parser_v1_parse, +diff --git a/plugins/x22x/mm-broadband-modem-x22x.c b/plugins/x22x/mm-broadband-modem-x22x.c +index c47442628..1ce32f57a 100644 +--- a/plugins/x22x/mm-broadband-modem-x22x.c ++++ b/plugins/x22x/mm-broadband-modem-x22x.c +@@ -120,12 +120,12 @@ load_current_modes_finish (MMIfaceModem *self, + MMModemMode *preferred, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- const gchar *response; +- gchar *str; +- gint mode = -1; +- GError *match_error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ const gchar *response; ++ gchar *str; ++ gint mode = -1; ++ GError *match_error = NULL; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); + if (!response) +@@ -143,17 +143,12 @@ load_current_modes_finish (MMIfaceModem *self, + MM_CORE_ERROR_FAILED, + "Couldn't match +SYSSEL reply: %s", response); + } +- +- g_match_info_free (match_info); +- g_regex_unref (r); + return FALSE; + } + + str = g_match_info_fetch (match_info, 3); + mode = atoi (str); + g_free (str); +- g_match_info_free (match_info); +- g_regex_unref (r); + + switch (mode) { + case 0: +diff --git a/plugins/xmm/mm-modem-helpers-xmm.c b/plugins/xmm/mm-modem-helpers-xmm.c +index 9b3933d2a..70e02a8f5 100644 +--- a/plugins/xmm/mm-modem-helpers-xmm.c ++++ b/plugins/xmm/mm-modem-helpers-xmm.c +@@ -364,11 +364,11 @@ mm_xmm_parse_xact_query_response (const gchar *response, + GArray **bands_out, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- GArray *bands = NULL; +- guint i; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ GArray *bands = NULL; ++ guint i; + + MMModemModeCombination mode = { + .allowed = MM_MODEM_MODE_NONE, +@@ -450,9 +450,6 @@ mm_xmm_parse_xact_query_response (const gchar *response, + /* success */ + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + if (bands) + g_array_unref (bands); +@@ -609,17 +606,17 @@ mm_xmm_parse_xcesq_query_response (const gchar *response, + gint *out_rssnr, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint rxlev = 99; +- guint ber = 99; +- guint rscp = 255; +- guint ecn0 = 255; +- guint rsrq = 255; +- guint rsrp = 255; +- gint rssnr = 255; +- gboolean success = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint rxlev = 99; ++ guint ber = 99; ++ guint rscp = 255; ++ guint ecn0 = 255; ++ guint rsrq = 255; ++ guint rsrp = 255; ++ gint rssnr = 255; ++ gboolean success = FALSE; + + g_assert (out_rxlev); + g_assert (out_ber); +@@ -672,9 +669,6 @@ mm_xmm_parse_xcesq_query_response (const gchar *response, + } + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -959,11 +953,11 @@ mm_xmm_parse_xlcsslp_query_response (const gchar *response, + gchar **supl_address, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- gchar *address = NULL; +- guint port = 0; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ gchar *address = NULL; ++ guint port = 0; + + /* + * E.g.: +@@ -996,9 +990,6 @@ mm_xmm_parse_xlcsslp_query_response (const gchar *response, + } + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +diff --git a/plugins/zte/mm-broadband-modem-zte.c b/plugins/zte/mm-broadband-modem-zte.c +index f4cb774d3..352835318 100644 +--- a/plugins/zte/mm-broadband-modem-zte.c ++++ b/plugins/zte/mm-broadband-modem-zte.c +@@ -339,22 +339,20 @@ load_current_modes_finish (MMIfaceModem *self, + MMModemMode *preferred, + GError **error) + { +- const gchar *response; +- GMatchInfo *match_info = NULL; +- GRegex *r; +- gint cm_mode = -1; +- gint pref_acq = -1; +- gboolean result; +- GError *match_error = NULL; ++ const gchar *response; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ gint cm_mode = -1; ++ gint pref_acq = -1; ++ GError *match_error = NULL; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); + if (!response) + return FALSE; + +- r = g_regex_new ("\\+ZSNT:\\s*(\\d),(\\d),(\\d)", G_REGEX_UNGREEDY, 0, error); ++ r = g_regex_new ("\\+ZSNT:\\s*(\\d),(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL); + g_assert (r != NULL); + +- result = FALSE; + if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &match_error)) { + if (match_error) + g_propagate_error (error, match_error); +@@ -364,7 +362,7 @@ load_current_modes_finish (MMIfaceModem *self, + MM_CORE_ERROR_FAILED, + "Couldn't parse +ZSNT response: '%s'", + response); +- goto done; ++ return FALSE; + } + + if (!mm_get_int_from_match_info (match_info, 1, &cm_mode) || +@@ -376,11 +374,10 @@ load_current_modes_finish (MMIfaceModem *self, + MM_CORE_ERROR_FAILED, + "Failed to parse the allowed mode response: '%s'", + response); +- goto done; ++ return FALSE; + } + + /* Correctly parsed! */ +- result = TRUE; + if (cm_mode == 0) { + /* Both 2G, 3G and LTE allowed. For LTE modems, no 2G/3G preference supported. */ + if (pref_acq == 0 || mm_iface_modem_is_3gpp_lte (self)) { +@@ -410,12 +407,7 @@ load_current_modes_finish (MMIfaceModem *self, + } else + g_assert_not_reached (); + +-done: +- g_match_info_free (match_info); +- if (r) +- g_regex_unref (r); +- +- return result; ++ return TRUE; + } + + static void +diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c +index c30021cb0..12b77649e 100644 +--- a/src/mm-broadband-modem.c ++++ b/src/mm-broadband-modem.c +@@ -3169,9 +3169,9 @@ static void + set_cgev_unsolicited_events_handlers (MMBroadbandModem *self, + gboolean enable) + { +- MMPortSerialAt *ports[2]; +- GRegex *cgev_regex; +- guint i; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) cgev_regex = NULL; ++ guint i; + + cgev_regex = mm_3gpp_cgev_regex_get (); + ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); +@@ -3193,8 +3193,6 @@ set_cgev_unsolicited_events_handlers (MMBroadbandModem *self, + enable ? self : NULL, + NULL); + } +- +- g_regex_unref (cgev_regex); + } + + static void +@@ -3245,9 +3243,9 @@ static void + set_ciev_unsolicited_events_handlers (MMBroadbandModem *self, + gboolean enable) + { +- MMPortSerialAt *ports[2]; +- GRegex *ciev_regex; +- guint i; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) ciev_regex = NULL; ++ guint i; + + ciev_regex = mm_3gpp_ciev_regex_get (); + ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); +@@ -3269,8 +3267,6 @@ set_ciev_unsolicited_events_handlers (MMBroadbandModem *self, + enable ? self : NULL, + NULL); + } +- +- g_regex_unref (ciev_regex); + } + + static void +@@ -5160,20 +5156,20 @@ registration_status_check_ready (MMBroadbandModem *self, + GAsyncResult *res, + GTask *task) + { ++ g_autoptr(GMatchInfo) match_info = NULL; + RunRegistrationChecksContext *ctx; +- const gchar *response; +- GError *error = NULL; +- GMatchInfo *match_info = NULL; +- guint i; +- gboolean parsed; +- gboolean cgreg = FALSE; +- gboolean cereg = FALSE; +- gboolean c5greg = FALSE; +- MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; +- MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; +- gulong lac = 0; +- gulong tac = 0; +- gulong cid = 0; ++ const gchar *response; ++ GError *error = NULL; ++ guint i; ++ gboolean parsed; ++ gboolean cgreg = FALSE; ++ gboolean cereg = FALSE; ++ gboolean c5greg = FALSE; ++ MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; ++ MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; ++ gulong lac = 0; ++ gulong tac = 0; ++ gulong cid = 0; + + ctx = g_task_get_task_data (task); + +@@ -5205,8 +5201,7 @@ registration_status_check_ready (MMBroadbandModem *self, + 0, + &match_info)) + break; +- g_match_info_free (match_info); +- match_info = NULL; ++ g_clear_pointer (&match_info, g_match_info_free); + } + + if (!match_info) { +@@ -5229,7 +5224,6 @@ registration_status_check_ready (MMBroadbandModem *self, + &cereg, + &c5greg, + &error); +- g_match_info_free (match_info); + + if (!parsed) { + if (!error) +@@ -6306,10 +6300,10 @@ set_unsolicited_result_code_handlers (MMIfaceModem3gppUssd *self, + GAsyncReadyCallback callback, + gpointer user_data) + { +- MMPortSerialAt *ports[2]; +- GRegex *cusd_regex; +- guint i; +- GTask *task; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) cusd_regex = NULL; ++ guint i; ++ GTask *task; + + cusd_regex = mm_3gpp_cusd_regex_get (); + ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); +@@ -6331,8 +6325,6 @@ set_unsolicited_result_code_handlers (MMIfaceModem3gppUssd *self, + NULL); + } + +- g_regex_unref (cusd_regex); +- + task = g_task_new (self, NULL, callback, user_data); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +@@ -7233,11 +7225,11 @@ set_messaging_unsolicited_events_handlers (MMIfaceModemMessaging *self, + GAsyncReadyCallback callback, + gpointer user_data) + { +- MMPortSerialAt *ports[2]; +- GRegex *cmti_regex; +- GRegex *cds_regex; +- guint i; +- GTask *task; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) cmti_regex = NULL; ++ g_autoptr(GRegex) cds_regex = NULL; ++ guint i; ++ GTask *task; + + cmti_regex = mm_3gpp_cmti_regex_get (); + cds_regex = mm_3gpp_cds_regex_get (); +@@ -7267,9 +7259,6 @@ set_messaging_unsolicited_events_handlers (MMIfaceModemMessaging *self, + NULL); + } + +- g_regex_unref (cmti_regex); +- g_regex_unref (cds_regex); +- + task = g_task_new (self, NULL, callback, user_data); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +@@ -7486,11 +7475,11 @@ sms_text_part_list_ready (MMBroadbandModem *self, + GAsyncResult *res, + GTask *task) + { +- ListPartsContext *ctx; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- const gchar *response; +- GError *error = NULL; ++ ListPartsContext *ctx; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ const gchar *response; ++ GError *error = NULL; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); + if (error) { +@@ -7510,8 +7499,6 @@ sms_text_part_list_ready (MMBroadbandModem *self, + MM_CORE_ERROR_INVALID_ARGS, + "Couldn't parse SMS list response"); + g_object_unref (task); +- g_match_info_free (match_info); +- g_regex_unref (r); + return; + } + +@@ -7597,8 +7584,6 @@ sms_text_part_list_ready (MMBroadbandModem *self, + next: + g_match_info_next (match_info, NULL); + } +- g_match_info_free (match_info); +- g_regex_unref (r); + + /* We consider all done */ + g_task_return_boolean (task, TRUE); +@@ -7929,9 +7914,9 @@ set_voice_in_call_unsolicited_events_handlers (MMBroadbandModem *self, + PortsContext *ports_ctx, + gboolean enable) + { +- MMPortSerialAt *ports[2]; +- GRegex *in_call_event_regex; +- guint i; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) in_call_event_regex = NULL; ++ guint i; + + in_call_event_regex = g_regex_new ("\\r\\n(NO CARRIER|BUSY|NO ANSWER|NO DIALTONE)(\\r)?\\r\\n$", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +@@ -7954,8 +7939,6 @@ set_voice_in_call_unsolicited_events_handlers (MMBroadbandModem *self, + enable ? self : NULL, + NULL); + } +- +- g_regex_unref (in_call_event_regex); + } + + static void +@@ -8146,13 +8129,13 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, + GAsyncReadyCallback callback, + gpointer user_data) + { +- MMPortSerialAt *ports[2]; +- GRegex *cring_regex; +- GRegex *ring_regex; +- GRegex *clip_regex; +- GRegex *ccwa_regex; +- guint i; +- GTask *task; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) cring_regex = NULL; ++ g_autoptr(GRegex) ring_regex = NULL; ++ g_autoptr(GRegex) clip_regex = NULL; ++ g_autoptr(GRegex) ccwa_regex = NULL; ++ guint i; ++ GTask *task; + + cring_regex = mm_voice_cring_regex_get (); + ring_regex = mm_voice_ring_regex_get (); +@@ -8196,11 +8179,6 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, + NULL); + } + +- g_regex_unref (ccwa_regex); +- g_regex_unref (clip_regex); +- g_regex_unref (cring_regex); +- g_regex_unref (ring_regex); +- + task = g_task_new (self, NULL, callback, user_data); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +@@ -9264,8 +9242,8 @@ css_query_ready (MMIfaceModemCdma *self, + band = 'Z'; + success = TRUE; + } else { +- GRegex *r; +- GMatchInfo *match_info; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + /* Format is ",," */ + r = g_regex_new ("\\s*([^,]*?)\\s*,\\s*([^,]*?)\\s*,\\s*(\\d+)", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +@@ -9296,9 +9274,6 @@ css_query_ready (MMIfaceModemCdma *self, + + success = TRUE; + } +- +- g_match_info_free (match_info); +- g_regex_unref (r); + } + + if (!success) { +@@ -10914,10 +10889,13 @@ static const gchar *secondary_init_sequence[] = { + static void + setup_ports (MMBroadbandModem *self) + { +- MMPortSerialAt *ports[2]; +- GRegex *regex; +- GPtrArray *array; +- guint i, j; ++ MMPortSerialAt *ports[2]; ++ g_autoptr(GRegex) ciev_regex = NULL; ++ g_autoptr(GRegex) cmti_regex = NULL; ++ g_autoptr(GRegex) cusd_regex = NULL; ++ GPtrArray *array; ++ guint i; ++ guint j; + + ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); + ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); +@@ -10933,64 +10911,23 @@ setup_ports (MMBroadbandModem *self) + NULL); + + /* Cleanup all unsolicited message handlers in all AT ports */ +- +- /* Set up CREG unsolicited message handlers, with NULL callbacks */ + array = mm_3gpp_creg_regex_get (FALSE); +- for (i = 0; i < 2; i++) { +- if (!ports[i]) +- continue; +- +- for (j = 0; j < array->len; j++) { +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), +- (GRegex *)g_ptr_array_index (array, j), +- NULL, +- NULL, +- NULL); +- } +- } +- mm_3gpp_creg_regex_destroy (array); +- +- /* Set up CIEV unsolicited message handler, with NULL callback */ +- regex = mm_3gpp_ciev_regex_get (); +- for (i = 0; i < 2; i++) { +- if (!ports[i]) +- continue; +- +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), +- regex, +- NULL, +- NULL, +- NULL); +- } +- g_regex_unref (regex); ++ ciev_regex = mm_3gpp_ciev_regex_get (); ++ cmti_regex = mm_3gpp_cmti_regex_get (); ++ cusd_regex = mm_3gpp_cusd_regex_get (); + +- /* Set up CMTI unsolicited message handler, with NULL callback */ +- regex = mm_3gpp_cmti_regex_get (); + for (i = 0; i < 2; i++) { + if (!ports[i]) + continue; + +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), +- regex, +- NULL, +- NULL, +- NULL); ++ for (j = 0; j < array->len; j++) ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), (GRegex *)g_ptr_array_index (array, j), NULL, NULL, NULL); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), ciev_regex, NULL, NULL, NULL); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), cmti_regex, NULL, NULL, NULL); ++ mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), cusd_regex, NULL, NULL, NULL); + } +- g_regex_unref (regex); + +- /* Set up CUSD unsolicited message handler, with NULL callback */ +- regex = mm_3gpp_cusd_regex_get (); +- for (i = 0; i < 2; i++) { +- if (!ports[i]) +- continue; +- +- mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), +- regex, +- NULL, +- NULL, +- NULL); +- } +- g_regex_unref (regex); ++ mm_3gpp_creg_regex_destroy (array); + } + + /*****************************************************************************/ +diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c +index 5e58ba9dd..58207bb15 100644 +--- a/src/mm-modem-helpers.c ++++ b/src/mm-modem-helpers.c +@@ -528,10 +528,10 @@ mm_3gpp_parse_clcc_response (const gchar *str, + GList **out_list, + GError **error) + { +- GRegex *r; +- GList *list = NULL; +- GError *inner_error = NULL; +- GMatchInfo *match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GList *list = NULL; ++ GError *inner_error = NULL; + + static const MMCallDirection call_direction[] = { + [0] = MM_CALL_DIRECTION_OUTGOING, +@@ -641,9 +641,6 @@ mm_3gpp_parse_clcc_response (const gchar *str, + } + + out: +- g_clear_pointer (&match_info, g_match_info_free); +- g_regex_unref (r); +- + if (inner_error) { + mm_3gpp_call_info_list_free (list); + g_propagate_error (error, inner_error); +@@ -736,12 +733,12 @@ mm_parse_ifc_test_response (const gchar *response, + gpointer log_object, + GError **error) + { +- GRegex *r; +- GError *inner_error = NULL; +- GMatchInfo *match_info = NULL; +- MMFlowControl te_mask = MM_FLOW_CONTROL_UNKNOWN; +- MMFlowControl ta_mask = MM_FLOW_CONTROL_UNKNOWN; +- MMFlowControl mask = MM_FLOW_CONTROL_UNKNOWN; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ MMFlowControl te_mask = MM_FLOW_CONTROL_UNKNOWN; ++ MMFlowControl ta_mask = MM_FLOW_CONTROL_UNKNOWN; ++ MMFlowControl mask = MM_FLOW_CONTROL_UNKNOWN; + + r = g_regex_new ("(?:\\+IFC:)?\\s*\\((.*)\\),\\((.*)\\)(?:\\r\\n)?", 0, 0, NULL); + g_assert (r != NULL); +@@ -767,10 +764,6 @@ mm_parse_ifc_test_response (const gchar *response, + mask = te_mask & ta_mask; + + out: +- +- g_clear_pointer (&match_info, g_match_info_free); +- g_regex_unref (r); +- + if (inner_error) + g_propagate_error (error, inner_error); + +@@ -982,21 +975,21 @@ mm_3gpp_parse_ws46_test_response (const gchar *response, + mm_3gpp_parse_ws46_test_response (const gchar *response, + GError **error) + { +- GArray *modes = NULL; +- GArray *tech_values = NULL; +- GRegex *r; +- GError *inner_error = NULL; +- GMatchInfo *match_info = NULL; +- gchar *full_list = NULL; +- guint val; +- guint i; +- guint j; +- gboolean supported_5g = FALSE; +- gboolean supported_4g = FALSE; +- gboolean supported_3g = FALSE; +- gboolean supported_2g = FALSE; +- gboolean supported_mode_25 = FALSE; +- gboolean supported_mode_29 = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GArray *modes = NULL; ++ GArray *tech_values = NULL; ++ GError *inner_error = NULL; ++ gchar *full_list = NULL; ++ guint val; ++ guint i; ++ guint j; ++ gboolean supported_5g = FALSE; ++ gboolean supported_4g = FALSE; ++ gboolean supported_3g = FALSE; ++ gboolean supported_2g = FALSE; ++ gboolean supported_mode_25 = FALSE; ++ gboolean supported_mode_29 = FALSE; + + r = g_regex_new ("(?:\\+WS46:)?\\s*\\((.*)\\)(?:\\r\\n)?", 0, 0, NULL); + g_assert (r != NULL); +@@ -1095,9 +1088,6 @@ out: + + g_free (full_list); + +- g_clear_pointer (&match_info, g_match_info_free); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return NULL; +@@ -1190,10 +1180,10 @@ mm_3gpp_parse_cops_test_response (const gchar *reply, + gpointer log_object, + GError **error) + { +- GRegex *r; +- GList *info_list = NULL; +- GMatchInfo *match_info; +- gboolean umts_format = TRUE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GList *info_list = NULL; ++ gboolean umts_format = TRUE; + + g_return_val_if_fail (reply != NULL, NULL); + if (error) +@@ -1227,9 +1217,8 @@ mm_3gpp_parse_cops_test_response (const gchar *reply, + + /* If we didn't get any hits, try the pre-UMTS format match */ + if (!g_regex_match (r, reply, 0, &match_info)) { +- g_regex_unref (r); +- g_match_info_free (match_info); +- match_info = NULL; ++ g_clear_pointer (&r, g_regex_unref); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* Pre-UMTS format doesn't include the cell access technology after + * the numeric operator element. +@@ -1320,9 +1309,6 @@ mm_3gpp_parse_cops_test_response (const gchar *reply, + g_match_info_next (match_info, NULL); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + return info_list; + } + +@@ -1337,14 +1323,14 @@ mm_3gpp_parse_cops_read_response (const gchar *response, + MMModemAccessTechnology *out_act, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint mode = 0; +- guint format = 0; +- gchar *operator = NULL; +- guint actval = 0; +- MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint mode = 0; ++ guint format = 0; ++ gchar *operator = NULL; ++ guint actval = 0; ++ MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; + + g_assert (out_mode || out_format || out_operator || out_act); + +@@ -1390,9 +1376,6 @@ mm_3gpp_parse_cops_read_response (const gchar *response, + } + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_free (operator); + g_propagate_error (error, inner_error); +@@ -1725,10 +1708,10 @@ mm_3gpp_parse_cgdcont_test_response (const gchar *response, + gpointer log_object, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- GList *list = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ GList *list = NULL; + + if (!response || !g_str_has_prefix (response, "+CGDCONT:")) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing +CGDCONT prefix"); +@@ -1776,9 +1759,6 @@ mm_3gpp_parse_cgdcont_test_response (const gchar *response, + g_match_info_next (match_info, &inner_error); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + mm_obj_warn (log_object, "unexpected error matching +CGDCONT response: '%s'", inner_error->message); + g_error_free (inner_error); +@@ -1813,52 +1793,46 @@ GList * + mm_3gpp_parse_cgdcont_read_response (const gchar *reply, + GError **error) + { +- GError *inner_error = NULL; +- GRegex *r; +- GMatchInfo *match_info; +- GList *list; ++ GError *inner_error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GList *list = NULL; + + if (!reply || !reply[0]) + /* No APNs configured, all done */ + return NULL; + +- list = NULL; + r = g_regex_new ("\\+CGDCONT:\\s*(\\d+)\\s*,([^, \\)]*)\\s*,([^, \\)]*)\\s*,([^, \\)]*)", + G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, +- 0, &inner_error); +- if (r) { +- g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, &inner_error); +- +- while (!inner_error && +- g_match_info_matches (match_info)) { +- gchar *str; +- MMBearerIpFamily ip_family; +- +- str = mm_get_string_unquoted_from_match_info (match_info, 2); +- ip_family = mm_3gpp_get_ip_family_from_pdp_type (str); +- if (ip_family != MM_BEARER_IP_FAMILY_NONE) { +- MM3gppPdpContext *pdp; +- +- pdp = g_slice_new0 (MM3gppPdpContext); +- if (!mm_get_uint_from_match_info (match_info, 1, &pdp->cid)) { +- inner_error = g_error_new (MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, +- "Couldn't parse CID from reply: '%s'", +- reply); +- break; +- } +- pdp->pdp_type = ip_family; +- pdp->apn = mm_get_string_unquoted_from_match_info (match_info, 3); ++ 0, NULL); ++ g_assert (r); + +- list = g_list_prepend (list, pdp); ++ g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, &inner_error); ++ while (!inner_error && g_match_info_matches (match_info)) { ++ gchar *str; ++ MMBearerIpFamily ip_family; ++ ++ str = mm_get_string_unquoted_from_match_info (match_info, 2); ++ ip_family = mm_3gpp_get_ip_family_from_pdp_type (str); ++ if (ip_family != MM_BEARER_IP_FAMILY_NONE) { ++ MM3gppPdpContext *pdp; ++ ++ pdp = g_slice_new0 (MM3gppPdpContext); ++ if (!mm_get_uint_from_match_info (match_info, 1, &pdp->cid)) { ++ inner_error = g_error_new (MM_CORE_ERROR, ++ MM_CORE_ERROR_FAILED, ++ "Couldn't parse CID from reply: '%s'", ++ reply); ++ break; + } ++ pdp->pdp_type = ip_family; ++ pdp->apn = mm_get_string_unquoted_from_match_info (match_info, 3); + +- g_free (str); +- g_match_info_next (match_info, &inner_error); ++ list = g_list_prepend (list, pdp); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); ++ g_free (str); ++ g_match_info_next (match_info, &inner_error); + } + + if (inner_error) { +@@ -1868,9 +1842,7 @@ mm_3gpp_parse_cgdcont_read_response (const gchar *reply, + return NULL; + } + +- list = g_list_sort (list, (GCompareFunc)mm_3gpp_pdp_context_cmp); +- +- return list; ++ return g_list_sort (list, (GCompareFunc)mm_3gpp_pdp_context_cmp); + } + + /*************************************************************************/ +@@ -1898,16 +1870,15 @@ GList * + mm_3gpp_parse_cgact_read_response (const gchar *reply, + GError **error) + { +- GError *inner_error = NULL; +- GRegex *r; +- GMatchInfo *match_info; +- GList *list; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ GList *list = NULL; + + if (!reply || !reply[0]) + /* Nothing configured, all done */ + return NULL; + +- list = NULL; + r = g_regex_new ("\\+CGACT:\\s*(\\d+),(\\d+)", + G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, 0, &inner_error); + g_assert (r); +@@ -1941,9 +1912,6 @@ mm_3gpp_parse_cgact_read_response (const gchar *reply, + g_match_info_next (match_info, &inner_error); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + mm_3gpp_pdp_context_active_list_free (list); + g_propagate_error (error, inner_error); +@@ -2142,10 +2110,11 @@ mm_3gpp_parse_cmgf_test_response (const gchar *reply, + gboolean *sms_text_supported, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- gchar *s; +- guint32 min = -1, max = -1; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gchar *s; ++ guint32 min = -1; ++ guint32 max = -1; + + /* Strip whitespace and response tag */ + if (g_str_has_prefix (reply, CMGF_TAG)) +@@ -2163,8 +2132,6 @@ mm_3gpp_parse_cmgf_test_response (const gchar *reply, + MM_CORE_ERROR_FAILED, + "Failed to parse CMGF query result '%s'", + reply); +- g_match_info_free (match_info); +- g_regex_unref (r); + return FALSE; + } + +@@ -2184,8 +2151,6 @@ mm_3gpp_parse_cmgf_test_response (const gchar *reply, + /* CMGF=1 for Text mode */ + *sms_text_supported = (max >= 1); + +- g_match_info_free (match_info); +- g_regex_unref (r); + return TRUE; + } + +@@ -2196,12 +2161,12 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply, + guint index, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- gint count; +- gint status; +- gchar *pdu; +- MM3gppPduInfo *info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gint count; ++ gint status; ++ gchar *pdu; ++ MM3gppPduInfo *info = NULL; + + /* +CMGR: ,,(whitespace) */ + /* The and fields are matched, but not currently used */ +@@ -2214,7 +2179,7 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply, + MM_CORE_ERROR_FAILED, + "Failed to parse CMGR read result: response didn't match '%s'", + reply); +- goto done; ++ return NULL; + } + + /* g_match_info_get_match_count includes match #0 */ +@@ -2225,7 +2190,7 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply, + "Failed to match CMGR fields (matched %d) '%s'", + count, + reply); +- goto done; ++ return NULL; + } + + if (!mm_get_int_from_match_info (match_info, 1, &status)) { +@@ -2234,7 +2199,7 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply, + MM_CORE_ERROR_FAILED, + "Failed to extract CMGR status field '%s'", + reply); +- goto done; ++ return NULL; + } + + +@@ -2245,18 +2210,13 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply, + MM_CORE_ERROR_FAILED, + "Failed to extract CMGR pdu field '%s'", + reply); +- goto done; ++ return NULL; + } + + info = g_new0 (MM3gppPduInfo, 1); + info->index = index; + info->status = status; + info->pdu = pdu; +- +-done: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + return info; + } + +@@ -2270,8 +2230,8 @@ mm_3gpp_parse_crsm_response (const gchar *reply, + gchar **hex, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + g_assert (sw1 != NULL); + g_assert (sw2 != NULL); +@@ -2292,11 +2252,9 @@ mm_3gpp_parse_crsm_response (const gchar *reply, + + if (g_regex_match (r, reply, 0, &match_info) && + mm_get_uint_from_match_info (match_info, 1, sw1) && +- mm_get_uint_from_match_info (match_info, 2, sw2)) ++ mm_get_uint_from_match_info (match_info, 2, sw2)) { + *hex = mm_get_string_unquoted_from_match_info (match_info, 3); +- +- g_match_info_free (match_info); +- g_regex_unref (r); ++ } + + if (*hex == NULL) { + g_set_error (error, +@@ -2372,19 +2330,19 @@ mm_3gpp_parse_cgcontrdp_response (const gchar *response, + gchar **out_dns_secondary_address, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint cid = 0; +- guint bearer_id = 0; +- gchar *apn = NULL; +- gchar *local_address_and_subnet = NULL; +- gchar *local_address = NULL; +- gchar *subnet = NULL; +- gchar *gateway_address = NULL; +- gchar *dns_primary_address = NULL; +- gchar *dns_secondary_address = NULL; +- guint field_format_extra_index = 0; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint cid = 0; ++ guint bearer_id = 0; ++ gchar *apn = NULL; ++ gchar *local_address_and_subnet = NULL; ++ gchar *local_address = NULL; ++ gchar *subnet = NULL; ++ gchar *gateway_address = NULL; ++ gchar *dns_primary_address = NULL; ++ gchar *dns_secondary_address = NULL; ++ guint field_format_extra_index = 0; + + /* Response may be e.g.: + * +CGCONTRDP: 4,5,"ibox.tim.it.mnc001.mcc222.gprs","2.197.17.49.255.255.255.255","2.197.17.49","10.207.43.46","10.206.56.132","0.0.0.0","0.0.0.0",0 +@@ -2462,9 +2420,6 @@ mm_3gpp_parse_cgcontrdp_response (const gchar *response, + dns_secondary_address = mm_get_string_unquoted_from_match_info (match_info, 7 + field_format_extra_index); + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + g_free (local_address_and_subnet); + + if (inner_error) { +@@ -2513,10 +2468,10 @@ mm_3gpp_parse_cfun_query_response (const gchar *response, + guint *out_state, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint state = G_MAXUINT; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint state = G_MAXUINT; + + g_assert (out_state != NULL); + +@@ -2546,9 +2501,6 @@ mm_3gpp_parse_cfun_query_response (const gchar *response, + *out_state = state; + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -2570,16 +2522,16 @@ mm_3gpp_parse_cesq_response (const gchar *response, + guint *out_rsrp, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint rxlev = 99; +- guint ber = 99; +- guint rscp = 255; +- guint ecn0 = 255; +- guint rsrq = 255; +- guint rsrp = 255; +- gboolean success = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint rxlev = 99; ++ guint ber = 99; ++ guint rscp = 255; ++ guint ecn0 = 255; ++ guint rsrq = 255; ++ guint rsrp = 255; ++ gboolean success = FALSE; + + g_assert (out_rxlev); + g_assert (out_ber); +@@ -2624,9 +2576,6 @@ mm_3gpp_parse_cesq_response (const gchar *response, + } + + out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -2883,10 +2832,10 @@ mm_3gpp_parse_ccwa_service_query_response (const gchar *response, + gboolean *status, + GError **error) + { +- GRegex *r; +- GError *inner_error = NULL; +- GMatchInfo *match_info = NULL; +- gint class_1_status = -1; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ gint class_1_status = -1; + + /* + * AT+CCWA=[,] +@@ -2928,9 +2877,6 @@ mm_3gpp_parse_ccwa_service_query_response (const gchar *response, + } + + out: +- g_clear_pointer (&match_info, g_match_info_free); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -3035,8 +2981,8 @@ mm_3gpp_parse_cpms_test_response (const gchar *reply, + g_assert (r); + + for (i = 0; i < N_EXPECTED_GROUPS; i++) { +- GMatchInfo *match_info = NULL; +- GArray *array; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GArray *array; + + /* We always return a valid array, even if it may be empty */ + array = g_array_new (FALSE, FALSE, sizeof (MMSmsStorage)); +@@ -3058,7 +3004,6 @@ mm_3gpp_parse_cpms_test_response (const gchar *reply, + g_match_info_next (match_info, NULL); + } + } +- g_match_info_free (match_info); + + if (!tmp1) + tmp1 = array; +@@ -3100,43 +3045,31 @@ mm_3gpp_parse_cpms_query_response (const gchar *reply, + MMSmsStorage *memw, + GError **error) + { +- GRegex *r = NULL; +- gboolean ret = FALSE; +- GMatchInfo *match_info = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + r = g_regex_new (CPMS_QUERY_REGEX, G_REGEX_RAW, 0, NULL); +- + g_assert (r); + + if (!g_regex_match (r, reply, 0, &match_info)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not parse CPMS query response '%s'", reply); +- goto end; ++ return FALSE; + } + + if (!g_match_info_matches (match_info)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not find matches in CPMS query reply '%s'", reply); +- goto end; +- } +- +- if (!mm_3gpp_get_cpms_storage_match (match_info, "memr", memr, error)) { +- goto end; +- } +- +- if (!mm_3gpp_get_cpms_storage_match (match_info, "memw", memw, error)) { +- goto end; ++ return FALSE; + } + +- ret = TRUE; +- +-end: +- if (r != NULL) +- g_regex_unref (r); ++ if (!mm_3gpp_get_cpms_storage_match (match_info, "memr", memr, error)) ++ return FALSE; + +- g_match_info_free (match_info); ++ if (!mm_3gpp_get_cpms_storage_match (match_info, "memw", memw, error)) ++ return FALSE; + +- return ret; ++ return TRUE; + } + + gboolean +@@ -3168,11 +3101,12 @@ gboolean + mm_3gpp_parse_cscs_test_response (const gchar *reply, + MMModemCharset *out_charsets) + { +- MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN; +- GRegex *r; +- GMatchInfo *match_info; +- gchar *p, *str; +- gboolean success = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN; ++ gchar *p; ++ gchar *str; ++ gboolean success = FALSE; + + g_return_val_if_fail (reply != NULL, FALSE); + g_return_val_if_fail (out_charsets != NULL, FALSE); +@@ -3194,8 +3128,7 @@ mm_3gpp_parse_cscs_test_response (const gchar *reply, + + /* Now parse each charset */ + r = g_regex_new ("\\s*([^,\\)]+)\\s*", 0, 0, NULL); +- if (!r) +- return FALSE; ++ g_assert (r); + + if (g_regex_match (r, p, 0, &match_info)) { + while (g_match_info_matches (match_info)) { +@@ -3207,8 +3140,6 @@ mm_3gpp_parse_cscs_test_response (const gchar *reply, + success = TRUE; + } + } +- g_match_info_free (match_info); +- g_regex_unref (r); + + if (success) + *out_charsets = charsets; +@@ -3222,8 +3153,8 @@ gboolean + mm_3gpp_parse_clck_test_response (const gchar *reply, + MMModem3gppFacility *out_facilities) + { +- GRegex *r; +- GMatchInfo *match_info; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + g_return_val_if_fail (reply != NULL, FALSE); + g_return_val_if_fail (out_facilities != NULL, FALSE); +@@ -3252,8 +3183,6 @@ mm_3gpp_parse_clck_test_response (const gchar *reply, + g_match_info_next (match_info, NULL); + } + } +- g_match_info_free (match_info); +- g_regex_unref (r); + + return (*out_facilities != MM_MODEM_3GPP_FACILITY_NONE); + } +@@ -3264,9 +3193,8 @@ gboolean + mm_3gpp_parse_clck_write_response (const gchar *reply, + gboolean *enabled) + { +- GRegex *r; +- GMatchInfo *match_info; +- gboolean success = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; + + g_return_val_if_fail (reply != NULL, FALSE); + g_return_val_if_fail (enabled != NULL, FALSE); +@@ -3277,7 +3205,7 @@ mm_3gpp_parse_clck_write_response (const gchar *reply, + g_assert (r != NULL); + + if (g_regex_match (r, reply, 0, &match_info)) { +- gchar *str; ++ g_autofree gchar *str = NULL; + + str = g_match_info_fetch (match_info, 1); + if (str) { +@@ -3289,15 +3217,11 @@ mm_3gpp_parse_clck_write_response (const gchar *reply, + *enabled = TRUE; + else + g_assert_not_reached (); +- +- g_free (str); +- success = TRUE; ++ return TRUE; + } + } +- g_match_info_free (match_info); +- g_regex_unref (r); + +- return success; ++ return FALSE; + } + + /*************************************************************************/ +@@ -3530,10 +3454,10 @@ GHashTable * + mm_3gpp_parse_cind_test_response (const gchar *reply, + GError **error) + { +- GHashTable *hash; +- GRegex *r; +- GMatchInfo *match_info; +- guint idx = 1; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GHashTable *hash; ++ guint idx = 1; + + g_return_val_if_fail (reply != NULL, NULL); + +@@ -3544,12 +3468,7 @@ mm_3gpp_parse_cind_test_response (const gchar *reply, + reply++; + + r = g_regex_new ("\\(([^,]*),\\((\\d+)[-,](\\d+).*\\)", G_REGEX_UNGREEDY, 0, NULL); +- if (!r) { +- g_set_error_literal (error, +- MM_CORE_ERROR, MM_CORE_ERROR_FAILED, +- "Could not parse scan results."); +- return NULL; +- } ++ g_assert (r); + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cind_response_free); + +@@ -3578,8 +3497,6 @@ mm_3gpp_parse_cind_test_response (const gchar *reply, + g_match_info_next (match_info, NULL); + } + } +- g_match_info_free (match_info); +- g_regex_unref (r); + + return hash; + } +@@ -3590,11 +3507,11 @@ GByteArray * + mm_3gpp_parse_cind_read_response (const gchar *reply, + GError **error) + { +- GByteArray *array = NULL; +- GRegex *r = NULL; +- GMatchInfo *match_info; +- GError *inner_error = NULL; +- guint8 t; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GByteArray *array = NULL; ++ GError *inner_error = NULL; ++ guint8 t; + + g_return_val_if_fail (reply != NULL, NULL); + +@@ -3614,7 +3531,7 @@ mm_3gpp_parse_cind_read_response (const gchar *reply, + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not parse the +CIND response '%s': didn't match", + reply); +- goto done; ++ return NULL; + } + + array = g_byte_array_sized_new (g_match_info_get_match_count (match_info)); +@@ -3625,10 +3542,9 @@ mm_3gpp_parse_cind_read_response (const gchar *reply, + t = 0; + g_byte_array_append (array, &t, 1); + +- while (!inner_error && +- g_match_info_matches (match_info)) { +- gchar *str; +- guint val = 0; ++ while (!inner_error && g_match_info_matches (match_info)) { ++ g_autofree gchar *str = NULL; ++ guint val = 0; + + str = g_match_info_fetch (match_info, 1); + if (mm_get_uint_from_str (str, &val) && val < 255) { +@@ -3639,21 +3555,14 @@ mm_3gpp_parse_cind_read_response (const gchar *reply, + "Could not parse the +CIND response: invalid index '%s'", + str); + } +- +- g_free (str); + g_match_info_next (match_info, NULL); + } + + if (inner_error) { + g_propagate_error (error, inner_error); +- g_byte_array_unref (array); +- array = NULL; ++ g_clear_pointer (&array, g_byte_array_unref); + } + +-done: +- g_match_info_free (match_info); +- g_regex_unref (r); +- + return array; + } + +@@ -3755,12 +3664,12 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar *str, + guint *out_cid, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *inner_error = NULL; +- gchar *pdp_type = NULL; +- gchar *pdp_addr = NULL; +- guint cid = 0; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ gchar *pdp_type = NULL; ++ gchar *pdp_addr = NULL; ++ guint cid = 0; + + g_assert (type == MM_3GPP_CGEV_REJECT || + type == MM_3GPP_CGEV_NW_REACT || +@@ -3772,6 +3681,7 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar *str, + "NW REACT|" + "NW DEACT|ME DEACT" + ")\\s*([^,]*),\\s*([^,]*)(?:,\\s*([0-9]+))?", 0, 0, NULL); ++ g_assert (r); + + str = mm_strip_tag (str, "+CGEV:"); + g_regex_match_full (r, str, strlen (str), 0, 0, &match_info, &inner_error); +@@ -3802,10 +3712,6 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar *str, + } + + out: +- if (match_info) +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_free (pdp_type); + g_free (pdp_addr); +@@ -3841,10 +3747,10 @@ mm_3gpp_parse_cgev_indication_primary (const gchar *str, + guint *out_cid, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *inner_error = NULL; +- guint cid = 0; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint cid = 0; + + g_assert ((type == MM_3GPP_CGEV_NW_ACT_PRIMARY) || + (type == MM_3GPP_CGEV_ME_ACT_PRIMARY) || +@@ -3872,10 +3778,6 @@ mm_3gpp_parse_cgev_indication_primary (const gchar *str, + } + + out: +- if (match_info) +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -3900,12 +3802,12 @@ mm_3gpp_parse_cgev_indication_secondary (const gchar *str, + guint *out_event_type, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *inner_error = NULL; +- guint p_cid = 0; +- guint cid = 0; +- guint event_type = 0; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ guint p_cid = 0; ++ guint cid = 0; ++ guint event_type = 0; + + g_assert (type == MM_3GPP_CGEV_NW_ACT_SECONDARY || + type == MM_3GPP_CGEV_ME_ACT_SECONDARY || +@@ -3943,10 +3845,6 @@ mm_3gpp_parse_cgev_indication_secondary (const gchar *str, + } + + out: +- if (match_info) +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; +@@ -3980,10 +3878,10 @@ GList * + mm_3gpp_parse_pdu_cmgl_response (const gchar *str, + GError **error) + { +- GError *inner_error = NULL; +- GList *list = NULL; +- GMatchInfo *match_info; +- GRegex *r; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *inner_error = NULL; ++ GList *list = NULL; + + /* + * +CMGL: , , [], +@@ -4016,9 +3914,6 @@ mm_3gpp_parse_pdu_cmgl_response (const gchar *str, + } + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + if (inner_error) { + g_propagate_error (error, inner_error); + mm_3gpp_pdu_info_list_free (list); +@@ -4754,10 +4649,10 @@ mm_cdma_parse_crm_test_response (const gchar *reply, + MMModemCdmaRmProtocol *max, + GError **error) + { +- gboolean result = FALSE; +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gboolean result = FALSE; ++ GError *match_error = NULL; + + /* Expected reply format is: + * ---> AT+CRM=? +@@ -4810,9 +4705,6 @@ mm_cdma_parse_crm_test_response (const gchar *reply, + reply); + } + +- g_match_info_free (match_info); +- g_regex_unref (r); +- + return result; + } + +@@ -5039,12 +4931,16 @@ mm_parse_cclk_response (const char *response, + MMNetworkTimezone **tzp, + GError **error) + { +- GRegex *r; +- GMatchInfo *match_info = NULL; +- GError *match_error = NULL; +- guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0; +- gint tz = 0; +- gboolean ret = FALSE; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ GError *match_error = NULL; ++ guint year = 0; ++ guint month = 0; ++ guint day = 0; ++ guint hour = 0; ++ guint minute = 0; ++ guint second = 0; ++ gint tz = 0; + + g_assert (iso8601p || tzp); /* at least one */ + +@@ -5065,7 +4961,7 @@ mm_parse_cclk_response (const char *response, + MM_CORE_ERROR_FAILED, + "Couldn't match +CCLK reply: %s", response); + } +- goto out; ++ return FALSE; + } + + /* Remember that g_match_info_get_match_count() includes match #0 */ +@@ -5082,7 +4978,7 @@ mm_parse_cclk_response (const char *response, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Failed to parse +CCLK reply: %s", response); +- goto out; ++ return FALSE; + } + + /* Read optional time zone offset; if not given assume UTC (tz = 0). +@@ -5094,7 +4990,7 @@ mm_parse_cclk_response (const char *response, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Failed to parse timezone in +CCLK reply: %s", response); +- goto out; ++ return FALSE; + } + + /* Adjust year to support YYYY format, as per +CSDF in 3GPP TS 27.007. Also, +@@ -5112,22 +5008,16 @@ mm_parse_cclk_response (const char *response, + mm_network_timezone_set_offset (*tzp, tz * 15); + } + +- ret = TRUE; +- + if (iso8601p) { + /* Return ISO-8601 format date/time string */ + *iso8601p = mm_new_iso8601_time (year, month, day, hour, + minute, second, + TRUE, (tz * 15), + error); +- ret = (*iso8601p != NULL); ++ return (*iso8601p != NULL); + } + +- out: +- g_match_info_free (match_info); +- g_regex_unref (r); +- +- return ret; ++ return TRUE; + } + + /*****************************************************************************/ +@@ -5139,12 +5029,12 @@ gint + mm_parse_csim_response (const gchar *response, + GError **error) + { +- GMatchInfo *match_info = NULL; +- GRegex *r = NULL; +- gchar *str_code = NULL; +- gint retries = -1; +- guint hex_code; +- GError *inner_error = NULL; ++ g_autoptr(GRegex) r = NULL; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *str_code = NULL; ++ gint retries = -1; ++ guint hex_code; ++ GError *inner_error = NULL; + + r = g_regex_new ("\\+CSIM:\\s*[0-9]+,\\s*\".*([0-9a-fA-F]{4})\"", G_REGEX_RAW, 0, NULL); + g_regex_match (r, response, 0, &match_info); +@@ -5202,10 +5092,6 @@ mm_parse_csim_response (const gchar *response, + retries = (gint)(hex_code - MM_MIN_SIM_RETRY_HEX); + + out: +- g_regex_unref (r); +- g_match_info_free (match_info); +- g_free (str_code); +- + if (inner_error) { + g_propagate_error (error, inner_error); + return -1; +diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c +index 44c0fc92e..88d01cf48 100644 +--- a/src/mm-port-serial-at.c ++++ b/src/mm-port-serial-at.c +@@ -269,8 +269,8 @@ parse_unsolicited (MMPortSerial *port, GByteArray *response) + + for (iter = self->priv->unsolicited_msg_handlers; iter; iter = iter->next) { + MMAtUnsolicitedMsgHandler *handler = (MMAtUnsolicitedMsgHandler *) iter->data; +- GMatchInfo *match_info; +- gboolean matches; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gboolean matches; + + if (!handler->enable) + continue; +@@ -286,12 +286,10 @@ parse_unsolicited (MMPortSerial *port, GByteArray *response) + } + } + +- g_match_info_free (match_info); +- + if (matches) { + /* Remove matches */ +- char *str; +- int result_len = response->len; ++ g_autofree gchar *str = NULL; ++ gint result_len = response->len; + + str = g_regex_replace_eval (handler->regex, + (const char *) response->data, +@@ -301,7 +299,6 @@ parse_unsolicited (MMPortSerial *port, GByteArray *response) + + g_byte_array_remove_range (response, 0, response->len); + g_byte_array_append (response, (const guint8 *) str, result_len); +- g_free (str); + } + } + } +diff --git a/src/mm-port-serial-gps.c b/src/mm-port-serial-gps.c +index ea4049946..fe8ec6a84 100644 +--- a/src/mm-port-serial-gps.c ++++ b/src/mm-port-serial-gps.c +@@ -74,12 +74,12 @@ parse_response (MMPortSerial *port, + GByteArray **parsed_response, + GError **error) + { +- MMPortSerialGps *self = MM_PORT_SERIAL_GPS (port); +- gboolean matches; +- GMatchInfo *match_info; +- gchar *str; +- gint result_len; +- guint i; ++ MMPortSerialGps *self = MM_PORT_SERIAL_GPS (port); ++ g_autoptr(GMatchInfo) match_info = NULL; ++ gboolean matches; ++ gchar *str; ++ gint result_len; ++ guint i; + + for (i = 0; i < response->len; i++) { + /* If there is any content before the first $, +@@ -110,8 +110,6 @@ parse_response (MMPortSerial *port, + } + } + +- g_match_info_free (match_info); +- + if (!matches) + return MM_PORT_SERIAL_RESPONSE_NONE; + +diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c +index fd01537d7..a577faee7 100644 +--- a/src/mm-serial-parsers.c ++++ b/src/mm-serial-parsers.c +@@ -167,7 +167,7 @@ mm_serial_parser_v1_parse (gpointer data, + GError **error) + { + MMSerialParserV1 *parser = (MMSerialParserV1 *) data; +- GMatchInfo *match_info; ++ GMatchInfo *match_info = NULL; + GError *local_error = NULL; + gboolean found = FALSE; + char *str = NULL; +@@ -242,7 +242,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_mobile_equipment_error_for_code (atoi (str), log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + } + + /* Numeric CME errors */ +@@ -255,7 +255,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_mobile_equipment_error_for_code (atoi (str), log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* Numeric CMS errors */ + found = g_regex_match_full (parser->regex_cms_error, +@@ -267,7 +267,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_message_error_for_code (atoi (str), log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* String CME errors */ + found = g_regex_match_full (parser->regex_cme_error_str, +@@ -279,7 +279,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_mobile_equipment_error_for_string (str, log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* String CMS errors */ + found = g_regex_match_full (parser->regex_cms_error_str, +@@ -291,7 +291,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_message_error_for_string (str, log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* Motorola EZX errors */ + found = g_regex_match_full (parser->regex_ezx_error, +@@ -303,7 +303,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* Last resort; unknown error */ + found = g_regex_match_full (parser->regex_unknown_error, +@@ -313,7 +313,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* Connection failures */ + found = g_regex_match_full (parser->regex_connect_failed, +@@ -341,7 +341,7 @@ mm_serial_parser_v1_parse (gpointer data, + local_error = mm_connection_error_for_code (code, log_object); + goto done; + } +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); + + /* NA error */ + found = g_regex_match_full (parser->regex_na, +@@ -357,7 +357,8 @@ mm_serial_parser_v1_parse (gpointer data, + + done: + g_free (str); +- g_match_info_free (match_info); ++ g_clear_pointer (&match_info, g_match_info_free); ++ + if (found) + response_clean (response); + +diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c +index 21ed2f207..01f4c910b 100644 +--- a/src/tests/test-modem-helpers.c ++++ b/src/tests/test-modem-helpers.c +@@ -1129,15 +1129,19 @@ test_creg_match (const char *test, + RegTestData *data, + const CregResult *result) + { +- guint i; +- GMatchInfo *info = NULL; +- MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; +- MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; +- gulong lac = 0, ci = 0; +- GError *error = NULL; +- gboolean success, cgreg = FALSE, cereg = FALSE, c5greg = FALSE; +- guint regex_num = 0; +- GPtrArray *array; ++ g_autoptr(GMatchInfo) info = NULL; ++ guint i; ++ MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; ++ MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; ++ gulong lac = 0; ++ gulong ci = 0; ++ GError *error = NULL; ++ gboolean success; ++ gboolean cgreg = FALSE; ++ gboolean cereg = FALSE; ++ gboolean c5greg = FALSE; ++ guint regex_num = 0; ++ GPtrArray *array; + + g_assert (reply); + g_assert (test); +@@ -1158,8 +1162,7 @@ test_creg_match (const char *test, + regex_num = i; + break; + } +- g_match_info_free (info); +- info = NULL; ++ g_clear_pointer (&info, g_match_info_free); + } + + g_debug (" regex_num (%u) == result->regex_num (%u)", +@@ -1171,7 +1174,6 @@ test_creg_match (const char *test, + + success = mm_3gpp_parse_creg_response (info, NULL, &state, &lac, &ci, &access_tech, &cgreg, &cereg, &c5greg, &error); + +- g_match_info_free (info); + g_assert (success); + g_assert_no_error (error); + g_assert_cmpuint (state, ==, result->state); +@@ -3351,10 +3353,10 @@ common_parse_cds (const gchar *str, + guint expected_pdu_len, + const gchar *expected_pdu) + { +- GMatchInfo *match_info; +- GRegex *regex; +- gchar *pdu_len_str; +- gchar *pdu; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GRegex) regex = NULL; ++ g_autofree gchar *pdu_len_str = NULL; ++ g_autofree gchar *pdu = NULL; + + regex = mm_3gpp_cds_regex_get (); + g_regex_match (regex, str, 0, &match_info); +@@ -3368,12 +3370,6 @@ common_parse_cds (const gchar *str, + g_assert (pdu != NULL); + + g_assert_cmpstr (pdu, ==, expected_pdu); +- +- g_free (pdu); +- g_free (pdu_len_str); +- +- g_match_info_free (match_info); +- g_regex_unref (regex); + } + + static void +@@ -4143,15 +4139,15 @@ static const ClipUrcTest clip_urc_tests[] = { + static void + test_clip_indication (void) + { +- GRegex *r; +- guint i; ++ g_autoptr(GRegex) r = NULL; ++ guint i; + + r = mm_voice_clip_regex_get (); + + for (i = 0; i < G_N_ELEMENTS (clip_urc_tests); i++) { +- GMatchInfo *match_info = NULL; +- gchar *number; +- guint type; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *number = NULL; ++ guint type; + + g_assert (g_regex_match (r, clip_urc_tests[i].str, 0, &match_info)); + g_assert (g_match_info_matches (match_info)); +@@ -4161,12 +4157,7 @@ test_clip_indication (void) + + g_assert (mm_get_uint_from_match_info (match_info, 2, &type)); + g_assert_cmpuint (type, ==, clip_urc_tests[i].type); +- +- g_free (number); +- g_match_info_free (match_info); + } +- +- g_regex_unref (r); + } + + /*****************************************************************************/ +@@ -4188,16 +4179,16 @@ static const CcwaUrcTest ccwa_urc_tests[] = { + static void + test_ccwa_indication (void) + { +- GRegex *r; +- guint i; ++ g_autoptr(GRegex) r = NULL; ++ guint i; + + r = mm_voice_ccwa_regex_get (); + + for (i = 0; i < G_N_ELEMENTS (ccwa_urc_tests); i++) { +- GMatchInfo *match_info = NULL; +- gchar *number; +- guint type; +- guint class; ++ g_autoptr(GMatchInfo) match_info = NULL; ++ g_autofree gchar *number = NULL; ++ guint type; ++ guint class; + + g_assert (g_regex_match (r, ccwa_urc_tests[i].str, 0, &match_info)); + g_assert (g_match_info_matches (match_info)); +@@ -4210,12 +4201,7 @@ test_ccwa_indication (void) + + g_assert (mm_get_uint_from_match_info (match_info, 3, &class)); + g_assert_cmpuint (class, ==, ccwa_urc_tests[i].class); +- +- g_free (number); +- g_match_info_free (match_info); + } +- +- g_regex_unref (r); + } + + /*****************************************************************************/ +-- +GitLab + diff --git a/backport-modem-helpers-cinterion-rework-CNMI-test-response-parser.patch b/backport-modem-helpers-cinterion-rework-CNMI-test-response-parser.patch new file mode 100644 index 0000000000000000000000000000000000000000..fc5e1049f310b6d9692101e4c4416c3124aca5dc --- /dev/null +++ b/backport-modem-helpers-cinterion-rework-CNMI-test-response-parser.patch @@ -0,0 +1,66 @@ +From e6c40349b81ac2915ce90b7e399eb33719a1fd24 Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Wed, 24 Aug 2022 16:42:45 +0000 +Subject: [PATCH] modem-helpers-cinterion: rework CNMI test response parser + +We setup all output variables with g_autoptr() and then use +g_steal_pointer() to return the needed ones. +--- + .../cinterion/mm-modem-helpers-cinterion.c | 25 ++++++++----------- + 1 file changed, 10 insertions(+), 15 deletions(-) + +diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c +index 0bf3a0782..9219bff4d 100644 +--- a/plugins/cinterion/mm-modem-helpers-cinterion.c ++++ b/plugins/cinterion/mm-modem-helpers-cinterion.c +@@ -556,12 +556,12 @@ mm_cinterion_parse_cnmi_test (const gchar *response, + { + g_autoptr(GRegex) r = NULL; + g_autoptr(GMatchInfo) match_info = NULL; ++ g_autoptr(GArray) tmp_supported_mode = NULL; ++ g_autoptr(GArray) tmp_supported_mt = NULL; ++ g_autoptr(GArray) tmp_supported_bm = NULL; ++ g_autoptr(GArray) tmp_supported_ds = NULL; ++ g_autoptr(GArray) tmp_supported_bfr = NULL; + GError *inner_error = NULL; +- GArray *tmp_supported_mode = NULL; +- GArray *tmp_supported_mt = NULL; +- GArray *tmp_supported_bm = NULL; +- GArray *tmp_supported_ds = NULL; +- GArray *tmp_supported_bfr = NULL; + + if (!response) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response"); +@@ -619,25 +619,20 @@ mm_cinterion_parse_cnmi_test (const gchar *response, + + out: + if (inner_error) { +- g_clear_pointer (&tmp_supported_mode, g_array_unref); +- g_clear_pointer (&tmp_supported_mt, g_array_unref); +- g_clear_pointer (&tmp_supported_bm, g_array_unref); +- g_clear_pointer (&tmp_supported_ds, g_array_unref); +- g_clear_pointer (&tmp_supported_bfr, g_array_unref); + g_propagate_error (error, inner_error); + return FALSE; + } + + if (supported_mode) +- *supported_mode = tmp_supported_mode; ++ *supported_mode = g_steal_pointer (&tmp_supported_mode); + if (supported_mt) +- *supported_mt = tmp_supported_mt; ++ *supported_mt = g_steal_pointer (&tmp_supported_mt); + if (supported_bm) +- *supported_bm = tmp_supported_bm; ++ *supported_bm = g_steal_pointer (&tmp_supported_bm); + if (supported_ds) +- *supported_ds = tmp_supported_ds; ++ *supported_ds = g_steal_pointer (&tmp_supported_ds); + if (supported_bfr) +- *supported_bfr = tmp_supported_bfr; ++ *supported_bfr = g_steal_pointer (&tmp_supported_bfr); + + return TRUE; + } +-- +GitLab diff --git a/backport-modem-helpers-rework-CGCONTRDP-response-parser.patch b/backport-modem-helpers-rework-CGCONTRDP-response-parser.patch new file mode 100644 index 0000000000000000000000000000000000000000..05eec7536570822926b461f2ebc270e002ca7619 --- /dev/null +++ b/backport-modem-helpers-rework-CGCONTRDP-response-parser.patch @@ -0,0 +1,156 @@ +From 845667c7b3d36f0e776d5a0e582ad62d48cdeb02 Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Wed, 24 Aug 2022 16:41:36 +0000 +Subject: [PATCH] modem-helpers: rework +CGCONTRDP response parser + +We setup all output variables with g_autofree and then use +g_steal_pointer() to return the needed ones. +--- + src/mm-modem-helpers.c | 87 +++++++++++++++--------------------------- + 1 file changed, 31 insertions(+), 56 deletions(-) + +diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c +index 58207bb15..9c3b0ccdc 100644 +--- a/src/mm-modem-helpers.c ++++ b/src/mm-modem-helpers.c +@@ -2335,13 +2335,13 @@ mm_3gpp_parse_cgcontrdp_response (const gchar *response, + GError *inner_error = NULL; + guint cid = 0; + guint bearer_id = 0; +- gchar *apn = NULL; +- gchar *local_address_and_subnet = NULL; +- gchar *local_address = NULL; +- gchar *subnet = NULL; +- gchar *gateway_address = NULL; +- gchar *dns_primary_address = NULL; +- gchar *dns_secondary_address = NULL; ++ g_autofree gchar *apn = NULL; ++ g_autofree gchar *local_address_and_subnet = NULL; ++ g_autofree gchar *local_address = NULL; ++ g_autofree gchar *subnet = NULL; ++ g_autofree gchar *gateway_address = NULL; ++ g_autofree gchar *dns_primary_address = NULL; ++ g_autofree gchar *dns_secondary_address = NULL; + guint field_format_extra_index = 0; + + /* Response may be e.g.: +@@ -2371,28 +2371,28 @@ mm_3gpp_parse_cgcontrdp_response (const gchar *response, + g_assert (r != NULL); + + g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error); +- if (inner_error) +- goto out; ++ if (inner_error) { ++ g_propagate_error (error, inner_error); ++ return FALSE; ++ } + + if (!g_match_info_matches (match_info)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, "Couldn't match +CGCONTRDP response"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, "Couldn't match +CGCONTRDP response"); ++ return FALSE; + } + + if (out_cid && !mm_get_uint_from_match_info (match_info, 1, &cid)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing cid"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing cid"); ++ return FALSE; + } + + if (out_bearer_id && !mm_get_uint_from_match_info (match_info, 2, &bearer_id)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing bearer id"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing bearer id"); ++ return FALSE; + } + + /* Remaining strings are optional or empty allowed */ +- +- if (out_apn) +- apn = mm_get_string_unquoted_from_match_info (match_info, 3); ++ apn = mm_get_string_unquoted_from_match_info (match_info, 3); + + /* + * The +CGCONTRDP=[cid] response format before version TS 27.007 v9.4.0 had +@@ -2400,64 +2400,39 @@ mm_3gpp_parse_cgcontrdp_response (const gchar *response, + */ + local_address_and_subnet = mm_get_string_unquoted_from_match_info (match_info, 4); + if (local_address_and_subnet && !split_local_address_and_subnet (local_address_and_subnet, &local_address, &subnet)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing local address and subnet"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing local address and subnet"); ++ return FALSE; + } ++ + /* If we don't have a subnet in field 4, we're using the old format with subnet in an extra field */ + if (!subnet) { +- if (out_subnet) +- subnet = mm_get_string_unquoted_from_match_info (match_info, 5); ++ subnet = mm_get_string_unquoted_from_match_info (match_info, 5); + field_format_extra_index = 1; + } + +- if (out_gateway_address) +- gateway_address = mm_get_string_unquoted_from_match_info (match_info, 5 + field_format_extra_index); +- +- if (out_dns_primary_address) +- dns_primary_address = mm_get_string_unquoted_from_match_info (match_info, 6 + field_format_extra_index); +- +- if (out_dns_secondary_address) +- dns_secondary_address = mm_get_string_unquoted_from_match_info (match_info, 7 + field_format_extra_index); +- +-out: +- g_free (local_address_and_subnet); +- +- if (inner_error) { +- g_free (apn); +- g_free (local_address); +- g_free (subnet); +- g_free (gateway_address); +- g_free (dns_primary_address); +- g_free (dns_secondary_address); +- g_propagate_error (error, inner_error); +- return FALSE; +- } ++ gateway_address = mm_get_string_unquoted_from_match_info (match_info, 5 + field_format_extra_index); ++ dns_primary_address = mm_get_string_unquoted_from_match_info (match_info, 6 + field_format_extra_index); ++ dns_secondary_address = mm_get_string_unquoted_from_match_info (match_info, 7 + field_format_extra_index); + + if (out_cid) + *out_cid = cid; + if (out_bearer_id) + *out_bearer_id = bearer_id; + if (out_apn) +- *out_apn = apn; +- ++ *out_apn = g_steal_pointer (&apn); + /* Local address and subnet may always be retrieved, even if not requested + * by the caller, as we need them to know which +CGCONTRDP=[cid] response is + * being parsed. So make sure we free them if not needed. */ + if (out_local_address) +- *out_local_address = local_address; +- else +- g_free (local_address); ++ *out_local_address = g_steal_pointer (&local_address); + if (out_subnet) +- *out_subnet = subnet; +- else +- g_free (subnet); +- ++ *out_subnet = g_steal_pointer (&subnet); + if (out_gateway_address) +- *out_gateway_address = gateway_address; ++ *out_gateway_address = g_steal_pointer (&gateway_address); + if (out_dns_primary_address) +- *out_dns_primary_address = dns_primary_address; ++ *out_dns_primary_address = g_steal_pointer (&dns_primary_address); + if (out_dns_secondary_address) +- *out_dns_secondary_address = dns_secondary_address; ++ *out_dns_secondary_address = g_steal_pointer (&dns_secondary_address); + return TRUE; + } + +-- +GitLab diff --git a/backport-modem-helpers-rework-the-CGEV-indication-parser.patch b/backport-modem-helpers-rework-the-CGEV-indication-parser.patch new file mode 100644 index 0000000000000000000000000000000000000000..348a65c633b33f1d787329213850a511fc52b7cb --- /dev/null +++ b/backport-modem-helpers-rework-the-CGEV-indication-parser.patch @@ -0,0 +1,86 @@ +From 9bbc768666e8ca77abdda325c46588cbf8a4df64 Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Wed, 24 Aug 2022 16:50:34 +0000 +Subject: [PATCH] modem-helpers: rework the +CGEV indication parser + +We setup all output variables with g_autofree and then use +g_steal_pointer() to return the needed ones. +--- + src/mm-modem-helpers.c | 36 +++++++++++++++--------------------- + 1 file changed, 15 insertions(+), 21 deletions(-) + +diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c +index 9c3b0ccdc..d71e1082c 100644 +--- a/src/mm-modem-helpers.c ++++ b/src/mm-modem-helpers.c +@@ -3642,8 +3642,8 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar *str, + g_autoptr(GRegex) r = NULL; + g_autoptr(GMatchInfo) match_info = NULL; + GError *inner_error = NULL; +- gchar *pdp_type = NULL; +- gchar *pdp_addr = NULL; ++ g_autofree gchar *pdp_type = NULL; ++ g_autofree gchar *pdp_addr = NULL; + guint cid = 0; + + g_assert (type == MM_3GPP_CGEV_REJECT || +@@ -3660,44 +3660,38 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar *str, + + str = mm_strip_tag (str, "+CGEV:"); + g_regex_match_full (r, str, strlen (str), 0, 0, &match_info, &inner_error); +- if (inner_error) +- goto out; ++ if (inner_error) { ++ g_propagate_error (error, inner_error); ++ return FALSE; ++ } + + if (!g_match_info_matches (match_info)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Couldn't match response"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Couldn't match response"); ++ return FALSE; + } + + if (out_pdp_type && !(pdp_type = mm_get_string_unquoted_from_match_info (match_info, 1))) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing PDP type"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing PDP type"); ++ return FALSE; + } + + if (out_pdp_addr && !(pdp_addr = mm_get_string_unquoted_from_match_info (match_info, 2))) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing PDP addr"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing PDP addr"); ++ return FALSE; + } + + /* CID is optional */ + if (out_cid && + (g_match_info_get_match_count (match_info) >= 4) && + !mm_get_uint_from_match_info (match_info, 3, &cid)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing CID"); +- goto out; +- } +- +-out: +- if (inner_error) { +- g_free (pdp_type); +- g_free (pdp_addr); +- g_propagate_error (error, inner_error); ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing CID"); + return FALSE; + } + + if (out_pdp_type) +- *out_pdp_type = pdp_type; ++ *out_pdp_type = g_steal_pointer (&pdp_type); + if (out_pdp_addr) +- *out_pdp_addr = pdp_addr; ++ *out_pdp_addr = g_steal_pointer (&pdp_addr); + if (out_cid) + *out_cid = cid; + return TRUE; +-- +GitLab diff --git a/backport-modem-helpers-ublox-rework-UIPADDR-response-parser.patch b/backport-modem-helpers-ublox-rework-UIPADDR-response-parser.patch new file mode 100644 index 0000000000000000000000000000000000000000..2e4ef02aa55029336498beea3330d63018840b3a --- /dev/null +++ b/backport-modem-helpers-ublox-rework-UIPADDR-response-parser.patch @@ -0,0 +1,115 @@ +From 8eeaba188272de496671763bc31f7fd592cb5ce0 Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Wed, 24 Aug 2022 16:55:41 +0000 +Subject: [PATCH] modem-helpers-ublox: rework +UIPADDR response parser + +We setup all output variables with g_autofree and then use +g_steal_pointer() to return the needed ones. +--- + plugins/ublox/mm-modem-helpers-ublox.c | 65 ++++++++++---------------- + 1 file changed, 24 insertions(+), 41 deletions(-) + +diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c +index 5cc035422..84a7cf272 100644 +--- a/plugins/ublox/mm-modem-helpers-ublox.c ++++ b/plugins/ublox/mm-modem-helpers-ublox.c +@@ -228,11 +228,11 @@ mm_ublox_parse_uipaddr_response (const gchar *response, + g_autoptr(GMatchInfo) match_info = NULL; + GError *inner_error = NULL; + guint cid = 0; +- gchar *if_name = NULL; +- gchar *ipv4_address = NULL; +- gchar *ipv4_subnet = NULL; +- gchar *ipv6_global_address = NULL; +- gchar *ipv6_link_local_address = NULL; ++ g_autofree gchar *if_name = NULL; ++ g_autofree gchar *ipv4_address = NULL; ++ g_autofree gchar *ipv4_subnet = NULL; ++ g_autofree gchar *ipv6_global_address = NULL; ++ g_autofree gchar *ipv6_link_local_address = NULL; + + /* Response may be e.g.: + * +UIPADDR: 1,"ccinet0","5.168.120.13","255.255.255.0","","" +@@ -245,61 +245,44 @@ mm_ublox_parse_uipaddr_response (const gchar *response, + g_assert (r != NULL); + + g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error); +- if (inner_error) +- goto out; ++ if (inner_error) { ++ g_propagate_error (error, inner_error); ++ return FALSE; ++ } + + if (!g_match_info_matches (match_info)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, "Couldn't match +UIPADDR response"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, "Couldn't match +UIPADDR response"); ++ return FALSE; + } + + if (out_cid && !mm_get_uint_from_match_info (match_info, 1, &cid)) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing cid"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing cid"); ++ return FALSE; + } + + if (out_if_name && !(if_name = mm_get_string_unquoted_from_match_info (match_info, 2))) { +- inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing interface name"); +- goto out; ++ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing interface name"); ++ return FALSE; + } + + /* Remaining strings are optional */ +- +- if (out_ipv4_address) +- ipv4_address = mm_get_string_unquoted_from_match_info (match_info, 3); +- +- if (out_ipv4_subnet) +- ipv4_subnet = mm_get_string_unquoted_from_match_info (match_info, 4); +- +- if (out_ipv6_global_address) +- ipv6_global_address = mm_get_string_unquoted_from_match_info (match_info, 5); +- +- if (out_ipv6_link_local_address) +- ipv6_link_local_address = mm_get_string_unquoted_from_match_info (match_info, 6); +- +-out: +- if (inner_error) { +- g_free (if_name); +- g_free (ipv4_address); +- g_free (ipv4_subnet); +- g_free (ipv6_global_address); +- g_free (ipv6_link_local_address); +- g_propagate_error (error, inner_error); +- return FALSE; +- } ++ ipv4_address = mm_get_string_unquoted_from_match_info (match_info, 3); ++ ipv4_subnet = mm_get_string_unquoted_from_match_info (match_info, 4); ++ ipv6_global_address = mm_get_string_unquoted_from_match_info (match_info, 5); ++ ipv6_link_local_address = mm_get_string_unquoted_from_match_info (match_info, 6); + + if (out_cid) + *out_cid = cid; + if (out_if_name) +- *out_if_name = if_name; ++ *out_if_name = g_steal_pointer (&if_name); + if (out_ipv4_address) +- *out_ipv4_address = ipv4_address; ++ *out_ipv4_address = g_steal_pointer (&ipv4_address); + if (out_ipv4_subnet) +- *out_ipv4_subnet = ipv4_subnet; ++ *out_ipv4_subnet = g_steal_pointer (&ipv4_subnet); + if (out_ipv6_global_address) +- *out_ipv6_global_address = ipv6_global_address; ++ *out_ipv6_global_address = g_steal_pointer (&ipv6_global_address); + if (out_ipv6_link_local_address) +- *out_ipv6_link_local_address = ipv6_link_local_address; ++ *out_ipv6_link_local_address = g_steal_pointer (&ipv6_link_local_address); + return TRUE; + } + +-- +GitLab diff --git a/backport-mtk-fix-task-completion-when-loading-supported-modes.patch b/backport-mtk-fix-task-completion-when-loading-supported-modes.patch new file mode 100644 index 0000000000000000000000000000000000000000..e486c1471c5fd4846f1f3a3601e14921efba3a7c --- /dev/null +++ b/backport-mtk-fix-task-completion-when-loading-supported-modes.patch @@ -0,0 +1,52 @@ +From ff7e062e94fb779cae18be33d8d81f888033c98a Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Wed, 24 Aug 2022 13:51:12 +0000 +Subject: [PATCH] mtk: fix task completion when loading supported modes + +--- + plugins/mtk/mm-broadband-modem-mtk.c | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +diff --git a/plugins/mtk/mm-broadband-modem-mtk.c b/plugins/mtk/mm-broadband-modem-mtk.c +index 131f8daa4..0ceca795f 100644 +--- a/plugins/mtk/mm-broadband-modem-mtk.c ++++ b/plugins/mtk/mm-broadband-modem-mtk.c +@@ -199,14 +199,12 @@ get_supported_modes_ready (MMBaseModem *self, + g_assert (r != NULL); + + if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &match_error)) { +- if (match_error) { +- g_propagate_error (&error, match_error); +- } else { +- g_set_error (&error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, +- "Failed to match EGMR response: %s", response); +- } ++ if (match_error) ++ g_task_return_error (task, error); ++ else ++ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, ++ "Failed to match EGMR response: %s", response); ++ g_object_unref (task); + + g_match_info_free (match_info); + g_regex_unref (r); +@@ -214,11 +212,10 @@ get_supported_modes_ready (MMBaseModem *self, + } + + if (!mm_get_int_from_match_info (match_info, 1, &device_type)) { +- g_set_error (&error, +- MM_CORE_ERROR, +- MM_CORE_ERROR_FAILED, +- "Failed to parse the allowed mode response: '%s'", +- response); ++ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, ++ "Failed to parse the allowed mode response: '%s'", ++ response); ++ g_object_unref (task); + + g_regex_unref (r); + g_match_info_free (match_info); +-- +GitLab diff --git a/backport-serial-parsers-fix-invalid-EXZ-error-parser.patch b/backport-serial-parsers-fix-invalid-EXZ-error-parser.patch new file mode 100644 index 0000000000000000000000000000000000000000..95cdfcdf4e7ef09ae4c1964f76c61b6ddd1e07fc --- /dev/null +++ b/backport-serial-parsers-fix-invalid-EXZ-error-parser.patch @@ -0,0 +1,33 @@ +From 79a5a4eed2189ea87d25cbe00bc824a2572cad66 Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Thu, 1 Sep 2022 15:00:03 +0200 +Subject: [PATCH] serial-parsers: fix invalid EXZ error parser +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Passed undetected when glib2 was using pcre1, it triggers an error now +with pcre2. + +See https://gitlab.gnome.org/GNOME/glib/-/issues/2729#note_1542038 + +Reported and fix suggested by: Marco Trevisan (Treviċ¸½o) +--- + src/mm-serial-parsers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c +index 0b60d607d..fd01537d7 100644 +--- a/src/mm-serial-parsers.c ++++ b/src/mm-serial-parsers.c +@@ -115,7 +115,7 @@ mm_serial_parser_v1_new (void) + parser->regex_cms_error = g_regex_new ("\\r\\n\\+CMS ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); + parser->regex_cme_error_str = g_regex_new ("\\r\\n\\+CME ERROR:\\s*([^\\n\\r]+)\\r\\n$", flags, 0, NULL); + parser->regex_cms_error_str = g_regex_new ("\\r\\n\\+CMS ERROR:\\s*([^\\n\\r]+)\\r\\n$", flags, 0, NULL); +- parser->regex_ezx_error = g_regex_new ("\\r\\n\\MODEM ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); ++ parser->regex_ezx_error = g_regex_new ("\\r\\nMODEM ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); + parser->regex_unknown_error = g_regex_new ("\\r\\n(ERROR)|(COMMAND NOT SUPPORT)\\r\\n$", flags, 0, NULL); + parser->regex_connect_failed = g_regex_new ("\\r\\n(NO CARRIER)|(BUSY)|(NO ANSWER)|(NO DIALTONE)\\r\\n$", flags, 0, NULL); + /* Samsung Z810 may reply "NA" to report a not-available error */ +-- +GitLab diff --git a/backport-sms-prevent-crash-if-date-is-out-of-range.patch b/backport-sms-prevent-crash-if-date-is-out-of-range.patch new file mode 100644 index 0000000000000000000000000000000000000000..7825491814708197f8b788630a331af8600a852a --- /dev/null +++ b/backport-sms-prevent-crash-if-date-is-out-of-range.patch @@ -0,0 +1,309 @@ +From ac243f94676695d88e861d225e98ec5bb3c2861e Mon Sep 17 00:00:00 2001 +From: Carlo Lobrano +Date: Fri, 8 Apr 2022 11:46:11 +0200 +Subject: [PATCH] sms: prevent crash if date is out of range + +g_date_time_new, and g_date_time_new_utc return NULL if inputs are out +of range, and currently mm_new_iso8601_time passes the GDateTime created +by those two functions to date_time_format_iso8601 without checking for +NULL values, causing a g_date_time_format_iso8601 crash if PDU data is +corrupted with wrong date. + +To prevent this, mm_new_iso8601_time now can return NULL and set a new +GError if GDateTime created by g_date_time_new is NULL. + +Fixes #546 +--- + .../cinterion/mm-modem-helpers-cinterion.c | 7 +++-- + plugins/huawei/mm-modem-helpers-huawei.c | 19 ++++++++---- + plugins/icera/mm-broadband-modem-icera.c | 7 +++-- + plugins/novatel/mm-broadband-modem-novatel.c | 4 +-- + plugins/sierra/mm-broadband-modem-sierra.c | 2 +- + src/mm-modem-helpers.c | 8 +++-- + src/mm-sms-part-3gpp.c | 30 ++++++++++++++----- + 7 files changed, 91 insertions(+), 26 deletions(-) + +diff --git a/src/mm-common-helpers.c b/src/mm-common-helpers.c +index b7883b265..085177b7b 100644 +--- a/src/mm-modem-helpers.c ++++ b/src/mm-modem-helpers.c +@@ -1769,7 +1769,8 @@ mm_new_iso8601_time (guint year, + guint minute, + guint second, + gboolean have_offset, +- gint offset_minutes) ++ gint offset_minutes, ++ GError **error) + { + GString *str; + +diff --git a/libmm-glib/mm-common-helpers.h b/libmm-glib/mm-common-helpers.h +index d444012c0..490f882da 100644 +--- a/src/mm-modem-helpers.h ++++ b/src/mm-modem-helpers.h +@@ -216,7 +216,8 @@ gchar *mm_new_iso8601_time (guint year, + guint minute, + guint second, + gboolean have_offset, +- gint offset_minutes); ++ gint offset_minutes, ++ GError **error); + + GArray *mm_filter_supported_modes (const GArray *all, + const GArray *supported_combinations, +diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c +index f8cec8258..a75eb5304 100644 +--- a/plugins/cinterion/mm-modem-helpers-cinterion.c ++++ b/plugins/cinterion/mm-modem-helpers-cinterion.c +@@ -1201,6 +1201,7 @@ mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info, + MMNetworkTimezone **tzp, + GError **error) + { ++ gboolean ret = TRUE; + guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, dst = 0; + gint tz = 0; + +@@ -1229,7 +1230,9 @@ mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info, + /* Return ISO-8601 format date/time string */ + *iso8601p = mm_new_iso8601_time (year, month, day, hour, + minute, second, +- TRUE, tz * 15); ++ TRUE, tz * 15, ++ error); ++ ret = (*iso8601p != NULL); + } + + if (tzp) { +@@ -1245,7 +1248,7 @@ mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info, + if (tzp && mm_get_uint_from_match_info (match_info, 8, &dst)) + mm_network_timezone_set_dst_offset (*tzp, dst * 60); + +- return TRUE; ++ return ret; + } + + /*****************************************************************************/ +diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c +index b85484183..3ded62379 100644 +--- a/plugins/huawei/mm-modem-helpers-huawei.c ++++ b/plugins/huawei/mm-modem-helpers-huawei.c +@@ -1228,6 +1228,9 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response, + mm_get_uint_from_match_info (match_info, 6, &second) && + mm_get_int_from_match_info (match_info, 7, &tz) && + mm_get_uint_from_match_info (match_info, 8, &dt)) { ++ ++ ret = TRUE; ++ + /* adjust year */ + if (year < 100) + year += 2000; +@@ -1240,7 +1243,9 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response, + /* Return ISO-8601 format date/time string */ + *iso8601p = mm_new_iso8601_time (year, month, day, hour, + minute, second, +- TRUE, (tz * 15) + (dt * 60)); ++ TRUE, (tz * 15) + (dt * 60), ++ error); ++ ret = (*iso8601p != NULL); + } + if (tzp) { + *tzp = mm_network_timezone_new (); +@@ -1248,7 +1253,6 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response, + mm_network_timezone_set_dst_offset (*tzp, dt * 60); + } + +- ret = TRUE; + } else { + g_set_error_literal (error, + MM_CORE_ERROR, +@@ -1312,14 +1316,19 @@ gboolean mm_huawei_parse_time_response (const gchar *response, + mm_get_uint_from_match_info (match_info, 4, &hour) && + mm_get_uint_from_match_info (match_info, 5, &minute) && + mm_get_uint_from_match_info (match_info, 6, &second)) { ++ ret = TRUE; ++ + /* adjust year */ + if (year < 100) + year += 2000; ++ + /* Return ISO-8601 format date/time string */ +- if (iso8601p) ++ if (iso8601p) { + *iso8601p = mm_new_iso8601_time (year, month, day, hour, +- minute, second, FALSE, 0); +- ret = TRUE; ++ minute, second, FALSE, 0, ++ error); ++ ret = (*iso8601p != NULL); ++ } + } else { + g_set_error_literal (error, + MM_CORE_ERROR, +diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c +index 26016c4c4..96cb45fa4 100644 +--- a/plugins/icera/mm-broadband-modem-icera.c ++++ b/plugins/icera/mm-broadband-modem-icera.c +@@ -1569,6 +1569,7 @@ parse_tlts_query_reply (const gchar *response, + MMNetworkTimezone **tz, + GError **error) + { ++ gboolean ret = TRUE; + gint year; + gint month; + gint day; +@@ -1649,11 +1650,13 @@ parse_tlts_query_reply (const gchar *response, + g_date_time_get_minute (adjusted), + g_date_time_get_second (adjusted), + TRUE, +- offset); ++ offset, ++ error); ++ ret = (*iso8601 != NULL); + } + + g_date_time_unref (adjusted); +- return TRUE; ++ return ret; + } + + static MMNetworkTimezone * +diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c +index 4eba0e168..1cc88e906 100644 +--- a/plugins/novatel/mm-broadband-modem-novatel.c ++++ b/plugins/novatel/mm-broadband-modem-novatel.c +@@ -1431,13 +1431,13 @@ parse_nwltime_reply (const char *response, + mm_get_int_from_match_info (match_info, 8, &utc_offset)) { + + result = mm_new_iso8601_time (year, month, day, hour, minute, second, +- TRUE, utc_offset * 60); ++ TRUE, utc_offset * 60, error); + if (out_tz) { + *out_tz = mm_network_timezone_new (); + mm_network_timezone_set_offset (*out_tz, utc_offset * 60); + } + +- success = TRUE; ++ success = (result != NULL); + } else { + g_set_error_literal (error, + MM_CORE_ERROR, +diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c +index 518f8adbc..3ac20808f 100644 +--- a/plugins/sierra/mm-broadband-modem-sierra.c ++++ b/plugins/sierra/mm-broadband-modem-sierra.c +@@ -1656,7 +1656,7 @@ parse_time (const gchar *response, + mm_get_uint_from_match_info (match_info, 4, &hour) && + mm_get_uint_from_match_info (match_info, 5, &minute) && + mm_get_uint_from_match_info (match_info, 6, &second)) { +- result = mm_new_iso8601_time (year, month, day, hour, minute, second, FALSE, 0); ++ result = mm_new_iso8601_time (year, month, day, hour, minute, second, FALSE, 0, error); + } else { + g_set_error (error, + MM_CORE_ERROR, +diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c +index 72714ab9a..5e58ba9dd 100644 +--- a/src/mm-modem-helpers.c ++++ b/src/mm-modem-helpers.c +@@ -5112,15 +5112,17 @@ mm_parse_cclk_response (const char *response, + mm_network_timezone_set_offset (*tzp, tz * 15); + } + ++ ret = TRUE; ++ + if (iso8601p) { + /* Return ISO-8601 format date/time string */ + *iso8601p = mm_new_iso8601_time (year, month, day, hour, + minute, second, +- TRUE, (tz * 15)); ++ TRUE, (tz * 15), ++ error); ++ ret = (*iso8601p != NULL); + } + +- ret = TRUE; +- + out: + g_match_info_free (match_info); + g_regex_unref (r); +diff --git a/src/mm-sms-part-3gpp.c b/src/mm-sms-part-3gpp.c +index bfae03a84..aeb9decb0 100644 +--- a/src/mm-sms-part-3gpp.c ++++ b/src/mm-sms-part-3gpp.c +@@ -161,7 +161,8 @@ sms_decode_address (const guint8 *address, + } + + static gchar * +-sms_decode_timestamp (const guint8 *timestamp) ++sms_decode_timestamp (const guint8 *timestamp, ++ GError **error) + { + /* ISO8601 format: YYYY-MM-DDTHH:MM:SS+HHMM */ + guint year, month, day, hour, minute, second; +@@ -179,7 +180,7 @@ sms_decode_timestamp (const guint8 *timestamp) + offset_minutes = -1 * offset_minutes; + + return mm_new_iso8601_time (year, month, day, hour, +- minute, second, TRUE, offset_minutes); ++ minute, second, TRUE, offset_minutes, error); + } + + static MMSmsEncoding +@@ -509,6 +510,7 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index, + /* Get timestamps and indexes for TP-PID, TP-DCS and TP-UDL/TP-UD */ + + if (pdu_type == SMS_TP_MTI_SMS_DELIVER) { ++ gchar *str = NULL; + PDU_SIZE_CHECK (offset + 9, + "cannot read PID/DCS/Timestamp"); /* 1+1+7=9 */ + +@@ -519,8 +521,13 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index, + tp_dcs_offset = offset++; + + /* ------ Timestamp (7 bytes) ------ */ ++ str = sms_decode_timestamp (&pdu[offset], error); ++ if (!str) { ++ mm_sms_part_free (sms_part); ++ return NULL; ++ } + mm_sms_part_take_timestamp (sms_part, +- sms_decode_timestamp (&pdu[offset])); ++ str); + offset += 7; + + tp_user_data_len_offset = offset; +@@ -564,6 +571,7 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index, + tp_user_data_len_offset = offset; + } + else if (pdu_type == SMS_TP_MTI_SMS_STATUS_REPORT) { ++ gchar *str = NULL; + /* We have 2 timestamps in status report PDUs: + * first, the timestamp for when the PDU was received in the SMSC + * second, the timestamp for when the PDU was forwarded by the SMSC +@@ -571,13 +579,21 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index, + PDU_SIZE_CHECK (offset + 15, "cannot read Timestamps/TP-STATUS"); /* 7+7+1=15 */ + + /* ------ Timestamp (7 bytes) ------ */ +- mm_sms_part_take_timestamp (sms_part, +- sms_decode_timestamp (&pdu[offset])); ++ str = sms_decode_timestamp (&pdu[offset], error); ++ if (!str) { ++ mm_sms_part_free (sms_part); ++ return NULL; ++ } ++ mm_sms_part_take_timestamp (sms_part, str); + offset += 7; + + /* ------ Discharge Timestamp (7 bytes) ------ */ +- mm_sms_part_take_discharge_timestamp (sms_part, +- sms_decode_timestamp (&pdu[offset])); ++ str = sms_decode_timestamp (&pdu[offset], error); ++ if (!str) { ++ mm_sms_part_free (sms_part); ++ return NULL; ++ } ++ mm_sms_part_take_discharge_timestamp (sms_part, str); + offset += 7; + + /* ----- TP-STATUS (1 byte) ------ */ +-- +GitLab diff --git a/backport-test-modem-helpers-add-EOL-to-strings-matched-with-G_REGEX_NEWLINE_CRLF.patch b/backport-test-modem-helpers-add-EOL-to-strings-matched-with-G_REGEX_NEWLINE_CRLF.patch new file mode 100644 index 0000000000000000000000000000000000000000..8929863e66822a3f64d77588726eb3e0050a2a56 --- /dev/null +++ b/backport-test-modem-helpers-add-EOL-to-strings-matched-with-G_REGEX_NEWLINE_CRLF.patch @@ -0,0 +1,64 @@ +From 68af7f28c0d3bb1088dc58b9e6408d9941c9614c Mon Sep 17 00:00:00 2001 +From: Aleksander Morgado +Date: Fri, 2 Sep 2022 17:13:29 +0200 +Subject: [PATCH] test-modem-helpers: add EOL to strings matched with + G_REGEX_NEWLINE_CRLF + +Looks like pcre2 (used since glib 2.73.2) requires EOLs to match if +G_REGEX_NEWLINE_CRLF is explicitly used. The tests are updated +accordingly, because the modem responses will anyway have the EOLs +as well. + +See https://gitlab.gnome.org/GNOME/glib/-/issues/2729#note_1544130 + +Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/601 + +(cherry picked from commit 51a333cd9a6707de7c623fd4c94cb6032477572f) +--- + src/tests/test-modem-helpers.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c +index dc22fbde7..d8cef0816 100644 +--- a/src/tests/test-modem-helpers.c ++++ b/src/tests/test-modem-helpers.c +@@ -4228,8 +4228,8 @@ typedef struct { + } TestCcwa; + + static TestCcwa test_ccwa[] = { +- { "+CCWA: 0,255", FALSE, FALSE }, /* all disabled */ +- { "+CCWA: 1,255", TRUE, FALSE }, /* all enabled */ ++ { "+CCWA: 0,255\r\n", FALSE, FALSE }, /* all disabled */ ++ { "+CCWA: 1,255\r\n", TRUE, FALSE }, /* all enabled */ + { "+CCWA: 0,1\r\n" + "+CCWA: 0,4\r\n", FALSE, FALSE }, /* voice and fax disabled */ + { "+CCWA: 1,1\r\n" +@@ -4304,7 +4304,7 @@ common_test_clcc_response (const gchar *str, + static void + test_clcc_response_empty (void) + { +- const gchar *response = ""; ++ const gchar *response = "\r\n"; + + common_test_clcc_response (response, NULL, 0); + } +@@ -4317,7 +4317,7 @@ test_clcc_response_single (void) + }; + + const gchar *response = +- "+CLCC: 1,1,0,0,0,\"123456789\",161"; ++ "+CLCC: 1,1,0,0,0,\"123456789\",161\r\n"; + + common_test_clcc_response (response, expected_call_info_list, G_N_ELEMENTS (expected_call_info_list)); + } +@@ -4331,7 +4331,7 @@ test_clcc_response_single_long (void) + + /* NOTE: priority field is EMPTY */ + const gchar *response = +- "+CLCC: 1,1,4,0,0,\"123456789\",129,\"\",,0"; ++ "+CLCC: 1,1,4,0,0,\"123456789\",129,\"\",,0\r\n"; + + common_test_clcc_response (response, expected_call_info_list, G_N_ELEMENTS (expected_call_info_list)); + } +-- +GitLab