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.
This commit is contained in:
Aleksander Morgado
2022-09-05 17:33:11 +00:00
parent b2a186b5c8
commit 74fc5baca2
33 changed files with 850 additions and 1268 deletions
+63 -126
View File
@@ -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 "<band_class>,<band>,<sid>" */
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);
ciev_regex = mm_3gpp_ciev_regex_get ();
cmti_regex = mm_3gpp_cmti_regex_get ();
cusd_regex = mm_3gpp_cusd_regex_get ();
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);
}
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);
}
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);
/* 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);
}
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);
}
/*****************************************************************************/
+210 -324
View File
File diff suppressed because it is too large Load Diff
+4 -7
View File
@@ -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);
}
}
}
+6 -8
View File
@@ -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;
+11 -10
View File
@@ -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);
+29 -43
View File
@@ -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);
}
/*****************************************************************************/