Files
ModemManager/plugins/sierra/mm-modem-helpers-sierra.c
T
Aleksander Morgado 74fc5baca2 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.
2022-09-05 17:33:11 +00:00

77 lines
2.8 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* Copyright (C) 2018 Aleksander Morgado <aleksander@aleksander.es>
*/
#include <glib.h>
#include <string.h>
#include "mm-modem-helpers.h"
#include "mm-modem-helpers-sierra.h"
GList *
mm_sierra_parse_scact_read_response (const gchar *reply,
GError **error)
{
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;
r = g_regex_new ("!SCACT:\\s*(\\d+),(\\d+)",
G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, 0, &inner_error);
g_assert (r);
g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, &inner_error);
while (!inner_error && g_match_info_matches (match_info)) {
MM3gppPdpContextActive *pdp_active;
guint cid = 0;
guint aux = 0;
if (!mm_get_uint_from_match_info (match_info, 1, &cid)) {
inner_error = g_error_new (MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Couldn't parse CID from reply: '%s'",
reply);
break;
}
if (!mm_get_uint_from_match_info (match_info, 2, &aux) || (aux != 0 && aux != 1)) {
inner_error = g_error_new (MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Couldn't parse context status from reply: '%s'",
reply);
break;
}
pdp_active = g_slice_new0 (MM3gppPdpContextActive);
pdp_active->cid = cid;
pdp_active->active = (gboolean) aux;
list = g_list_prepend (list, pdp_active);
g_match_info_next (match_info, &inner_error);
}
if (inner_error) {
mm_3gpp_pdp_context_active_list_free (list);
g_propagate_error (error, inner_error);
g_prefix_error (error, "Couldn't properly parse list of active/inactive PDP contexts. ");
return NULL;
}
return g_list_sort (list, (GCompareFunc) mm_3gpp_pdp_context_active_cmp);
}