From 1ee3a443b12703fd69d7ff5e93d4f330231303b0 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 29 Jun 2026 16:49:48 +0000 Subject: [PATCH 1/6] sms: sanitize decoded alphanumeric SMS addresses Alphanumeric SMS addresses decoded from GSM-7 could contain control characters (like CR/LF), which could lead to AT command injection if the address is later spliced into an AT+CMGS command during stored SMS send fallback. Sanitize the decoded address by removing all control characters. Introduce a common helper mm_utils_remove_control_characters() to remove control characters from a string in-place, and add unit tests for it. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1062 Signed-off-by: Aleksander Morgado --- src/mm-modem-helpers.c | 21 +++++++++++++++++++++ src/mm-modem-helpers.h | 2 ++ src/mm-sms-part-3gpp.c | 3 +++ src/tests/test-modem-helpers.c | 20 ++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index ed04a329..e243e6ea 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -5936,3 +5936,24 @@ mm_dtmf_split (const gchar *dtmf) return array; } + +/*****************************************************************************/ + +void +mm_utils_remove_control_characters (gchar *str) +{ + gchar *src = str; + gchar *dst = str; + + if (!str) + return; + + while (*src) { + if (((guint8)*src) >= 0x20) { + *dst = *src; + dst++; + } + src++; + } + *dst = '\0'; +} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 1e3dbb12..46d3f695 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -571,6 +571,8 @@ gboolean mm_parse_supl_address (const gchar *supl, guint16 *out_port, GError **error); +void mm_utils_remove_control_characters (gchar *str); + gboolean mm_validate_cbs_channels (GArray *channels, GError **error); diff --git a/src/mm-sms-part-3gpp.c b/src/mm-sms-part-3gpp.c index d91946c7..f746079e 100644 --- a/src/mm-sms-part-3gpp.c +++ b/src/mm-sms-part-3gpp.c @@ -28,6 +28,7 @@ #include "mm-sms-part-3gpp.h" #include "mm-charsets.h" #include "mm-log.h" +#include "mm-modem-helpers.h" #define PDU_SIZE 200 @@ -141,6 +142,8 @@ sms_decode_address (const guint8 *address, unpacked = mm_charset_gsm_unpack (address, (len_digits * 4) / 7, 0, &unpacked_len); unpacked_array = g_byte_array_new_take (unpacked, unpacked_len); utf8 = mm_modem_charset_bytearray_to_utf8 (unpacked_array, MM_MODEM_CHARSET_GSM, FALSE, error); + if (utf8) + mm_utils_remove_control_characters (utf8); } else if (addrtype == SMS_NUMBER_TYPE_INTL && addrplan == SMS_NUMBER_PLAN_TELEPHONE) { /* International telphone number, format as "+1234567890" */ diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index 7684fce7..ec820802 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -4872,6 +4872,25 @@ test_at_quote_string (void *f, gpointer d) } } +static void +test_remove_control_characters (void *f, gpointer d) +{ + gchar str1[] = "hello\r\nworld"; + gchar str2[] = "no_controls"; + gchar str3[] = "\r\n\t"; + + mm_utils_remove_control_characters (str1); + g_assert_cmpstr (str1, ==, "helloworld"); + + mm_utils_remove_control_characters (str2); + g_assert_cmpstr (str2, ==, "no_controls"); + + mm_utils_remove_control_characters (str3); + g_assert_cmpstr (str3, ==, ""); + + mm_utils_remove_control_characters (NULL); +} + /*****************************************************************************/ typedef struct { @@ -5418,6 +5437,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_bcd_to_string, NULL)); g_test_suite_add (suite, TESTCASE (test_at_quote_string, NULL)); + g_test_suite_add (suite, TESTCASE (test_remove_control_characters, NULL)); g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL)); From a39d46c63737ae26e531df0e47b687b4f62a4379 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 29 Jun 2026 16:54:27 +0000 Subject: [PATCH 2/6] location: validate SUPL host as FQDN or IP When parsing a SUPL address, if the host is not a valid IPv4 address, validate it as a FQDN (allowing only alphanumeric characters, dots, and hyphens). This prevents injecting AT command delimiters (like CR or semicolon) into the host string, which is later spliced into modem-specific AT commands (+XLCSSLP). Introduce a common helper mm_utils_is_valid_fqdn() to validate FQDNs, and add unit tests for it. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1063 Signed-off-by: Aleksander Morgado --- src/mm-modem-helpers.c | 20 ++++++++++++++++++++ src/mm-modem-helpers.h | 1 + src/tests/test-modem-helpers.c | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index e243e6ea..bbb9606f 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -5554,6 +5554,11 @@ mm_parse_supl_address (const gchar *supl, /* Try to parse first item as IP */ if (inet_pton (AF_INET, split[0], &ip) <= 0) { /* Otherwise, assume it's a domain name */ + if (!mm_utils_is_valid_fqdn (split[0])) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "Invalid SUPL host: not a valid FQDN or IP: %s", split[0]); + goto out; + } if (out_fqdn) *out_fqdn = g_strdup (split[0]); if (out_ip) @@ -5957,3 +5962,18 @@ mm_utils_remove_control_characters (gchar *str) } *dst = '\0'; } + +gboolean +mm_utils_is_valid_fqdn (const gchar *fqdn) +{ + const gchar *c; + + if (!fqdn || !fqdn[0]) + return FALSE; + + for (c = fqdn; *c; c++) { + if (!g_ascii_isalnum (*c) && *c != '-' && *c != '.') + return FALSE; + } + return TRUE; +} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 46d3f695..bf102251 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -572,6 +572,7 @@ gboolean mm_parse_supl_address (const gchar *supl, GError **error); void mm_utils_remove_control_characters (gchar *str); +gboolean mm_utils_is_valid_fqdn (const gchar *fqdn); gboolean mm_validate_cbs_channels (GArray *channels, GError **error); diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index ec820802..03785791 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -4891,6 +4891,23 @@ test_remove_control_characters (void *f, gpointer d) mm_utils_remove_control_characters (NULL); } +static void +test_is_valid_fqdn (void *f, gpointer d) +{ + g_assert (mm_utils_is_valid_fqdn ("google.com")); + g_assert (mm_utils_is_valid_fqdn ("a.b.c.d")); + g_assert (mm_utils_is_valid_fqdn ("valid-host.com")); + g_assert (mm_utils_is_valid_fqdn ("123.com")); + g_assert (mm_utils_is_valid_fqdn ("a")); + + g_assert (!mm_utils_is_valid_fqdn (NULL)); + g_assert (!mm_utils_is_valid_fqdn ("")); + g_assert (!mm_utils_is_valid_fqdn ("invalid host.com")); + g_assert (!mm_utils_is_valid_fqdn ("host;com")); + g_assert (!mm_utils_is_valid_fqdn ("host\rcom")); + g_assert (!mm_utils_is_valid_fqdn ("host/com")); +} + /*****************************************************************************/ typedef struct { @@ -5438,6 +5455,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_at_quote_string, NULL)); g_test_suite_add (suite, TESTCASE (test_remove_control_characters, NULL)); + g_test_suite_add (suite, TESTCASE (test_is_valid_fqdn, NULL)); g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL)); From dd54145d71d7b8d1092afc1821ca6a91764a0dff Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 29 Jun 2026 16:54:46 +0000 Subject: [PATCH 3/6] ussd: quote USSD command to prevent AT injection When sending an unencoded USSD command, the user-supplied string was spliced directly into the +CUSD AT command. If the string contained CR or semicolons, it could lead to AT command injection. Use mm_at_quote_string() to properly quote and escape the USSD command before sending it. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1064 Signed-off-by: Aleksander Morgado --- src/mm-broadband-modem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 9364a20b..b8d9c84e 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -6419,6 +6419,7 @@ modem_3gpp_ussd_context_send_unencoded (MMBroadbandModem *self) { Modem3gppUssdSendContext *ctx; gchar *at_command = NULL; + gchar *quoted_command; g_assert (self->priv->pending_ussd_action); ctx = g_task_get_task_data (self->priv->pending_ussd_action); @@ -6426,9 +6427,11 @@ modem_3gpp_ussd_context_send_unencoded (MMBroadbandModem *self) /* Build AT command with action unencoded */ ctx->unencoded_used = TRUE; ctx->current_is_unencoded = TRUE; - at_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", - ctx->command, - MM_MODEM_GSM_USSD_SCHEME_7BIT); + quoted_command = mm_at_quote_string (ctx->command); + at_command = g_strdup_printf ("+CUSD=1,%s,%d", + quoted_command, + MM_MODEM_GSM_USSD_SCHEME_7BIT); + g_free (quoted_command); mm_base_modem_at_command (MM_BASE_MODEM (self), at_command, From 50202ad76a3fbc150236552da610d77b9f47aa0c Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 29 Jun 2026 17:21:10 +0000 Subject: [PATCH 4/6] sim: validate PIN and PUK codes Validate PIN and PUK codes in the SIM D-Bus interface handlers to ensure they are numeric. This prevents injecting AT command delimiters (like CR) into these fields, which are later spliced into AT commands (+CPWD, +CLCK, +CPIN). Introduce a common helper mm_utils_is_numeric() to check if a string contains only digits, and add unit tests for it. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1065 Signed-off-by: Aleksander Morgado --- src/mm-base-sim.c | 28 ++++++++++++++++++++++++++++ src/mm-modem-helpers.c | 15 +++++++++++++++ src/mm-modem-helpers.h | 1 + src/tests/test-modem-helpers.c | 16 ++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/src/mm-base-sim.c b/src/mm-base-sim.c index 1498fb0f..6740c585 100644 --- a/src/mm-base-sim.c +++ b/src/mm-base-sim.c @@ -261,6 +261,13 @@ handle_change_pin_auth_ready (MMAuthProvider *authp, return; } + if (!mm_utils_is_numeric (ctx->old_pin) || !mm_utils_is_numeric (ctx->new_pin)) { + mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "PIN must be numeric"); + handle_change_pin_context_free (ctx); + return; + } + /* If changing PIN is not implemented, report an error */ if (!MM_BASE_SIM_GET_CLASS (ctx->self)->change_pin || !MM_BASE_SIM_GET_CLASS (ctx->self)->change_pin_finish) { @@ -445,6 +452,13 @@ handle_enable_pin_auth_ready (MMAuthProvider *authp, return; } + if (!mm_utils_is_numeric (ctx->pin)) { + mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "PIN must be numeric"); + handle_enable_pin_context_free (ctx); + return; + } + /* If changing PIN is not implemented, report an error */ if (!MM_BASE_SIM_GET_CLASS (ctx->self)->enable_pin || !MM_BASE_SIM_GET_CLASS (ctx->self)->enable_pin_finish) { @@ -869,6 +883,13 @@ handle_send_pin_auth_ready (MMAuthProvider *authp, return; } + if (!mm_utils_is_numeric (ctx->pin)) { + mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "PIN must be numeric"); + handle_send_pin_context_free (ctx); + return; + } + if (!mm_gdbus_sim_get_active (MM_GDBUS_SIM (ctx->self))) { mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot send PIN: SIM not currently active"); @@ -974,6 +995,13 @@ handle_send_puk_auth_ready (MMAuthProvider *authp, return; } + if (!mm_utils_is_numeric (ctx->puk) || !mm_utils_is_numeric (ctx->new_pin)) { + mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "PIN/PUK must be numeric"); + handle_send_puk_context_free (ctx); + return; + } + if (!mm_gdbus_sim_get_active (MM_GDBUS_SIM (ctx->self))) { mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot send PUK: SIM not currently active"); diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index bbb9606f..8be5fb63 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -5977,3 +5977,18 @@ mm_utils_is_valid_fqdn (const gchar *fqdn) } return TRUE; } + +gboolean +mm_utils_is_numeric (const gchar *str) +{ + const gchar *c; + + if (!str || !str[0]) + return FALSE; + + for (c = str; *c; c++) { + if (!g_ascii_isdigit (*c)) + return FALSE; + } + return TRUE; +} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index bf102251..e21ec7eb 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -573,6 +573,7 @@ gboolean mm_parse_supl_address (const gchar *supl, void mm_utils_remove_control_characters (gchar *str); gboolean mm_utils_is_valid_fqdn (const gchar *fqdn); +gboolean mm_utils_is_numeric (const gchar *str); gboolean mm_validate_cbs_channels (GArray *channels, GError **error); diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index 03785791..556d9606 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -4908,6 +4908,21 @@ test_is_valid_fqdn (void *f, gpointer d) g_assert (!mm_utils_is_valid_fqdn ("host/com")); } +static void +test_is_numeric (void *f, gpointer d) +{ + g_assert (mm_utils_is_numeric ("123456")); + g_assert (mm_utils_is_numeric ("0")); + g_assert (mm_utils_is_numeric ("0123456789")); + + g_assert (!mm_utils_is_numeric (NULL)); + g_assert (!mm_utils_is_numeric ("")); + g_assert (!mm_utils_is_numeric ("123a45")); + g_assert (!mm_utils_is_numeric ("123 45")); + g_assert (!mm_utils_is_numeric ("123\r45")); + g_assert (!mm_utils_is_numeric ("+123")); +} + /*****************************************************************************/ typedef struct { @@ -5456,6 +5471,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_at_quote_string, NULL)); g_test_suite_add (suite, TESTCASE (test_remove_control_characters, NULL)); g_test_suite_add (suite, TESTCASE (test_is_valid_fqdn, NULL)); + g_test_suite_add (suite, TESTCASE (test_is_numeric, NULL)); g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL)); From 3291e7dd1c444065fb1bf9b6393c3451cd7d5370 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 29 Jun 2026 17:21:11 +0000 Subject: [PATCH 5/6] sim: validate preferred networks operator codes Validate preferred network operator codes in the SIM D-Bus interface handler to ensure they are numeric. This prevents injecting AT command delimiters (like CR) into this field, which is later spliced into AT commands (+CPOL). This change also plugs the network list leak, that was a problem on its own. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1065 Signed-off-by: Aleksander Morgado --- src/mm-base-sim.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/mm-base-sim.c b/src/mm-base-sim.c index 6740c585..efedba02 100644 --- a/src/mm-base-sim.c +++ b/src/mm-base-sim.c @@ -1546,12 +1546,34 @@ handle_set_preferred_networks_ready (MMBaseSim *self, handle_set_preferred_networks_context_free (ctx); } +static gboolean +validate_networks_list (GList *networks_list, + GError **error) +{ + GList *l; + + for (l = networks_list; l; l = g_list_next (l)) { + MMSimPreferredNetwork *network = (MMSimPreferredNetwork *)l->data; + const gchar *operator_code; + + operator_code = mm_sim_preferred_network_get_operator_code (network); + if (!mm_utils_is_numeric (operator_code)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "Invalid operator code: '%s'", operator_code); + return FALSE; + } + } + + return TRUE; +} + static void handle_set_preferred_networks_auth_ready (MMAuthProvider *authp, GAsyncResult *res, HandleSetPreferredNetworksContext *ctx) { GError *error = NULL; + GList *networks_list = NULL; if (!mm_auth_provider_authorize_finish (authp, res, &error)) { mm_dbus_method_invocation_take_error (ctx->invocation, error); @@ -1581,12 +1603,22 @@ handle_set_preferred_networks_auth_ready (MMAuthProvider *authp, return; } + networks_list = mm_sim_preferred_network_list_new_from_variant (ctx->networks); + if (!validate_networks_list (networks_list, &error)) { + g_list_free_full (networks_list, g_object_unref); + mm_dbus_method_invocation_take_error (ctx->invocation, error); + handle_set_preferred_networks_context_free (ctx); + return; + } + mm_obj_info (ctx->self, "processing user request to set preferred networks..."); MM_BASE_SIM_GET_CLASS (ctx->self)->set_preferred_networks ( ctx->self, - mm_sim_preferred_network_list_new_from_variant (ctx->networks), + networks_list, (GAsyncReadyCallback)handle_set_preferred_networks_ready, ctx); + + g_list_free_full (networks_list, g_object_unref); } static gboolean From 6b3682ed65244c6c23ca54ccca6d12b3dd2a8f77 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 29 Jun 2026 17:01:28 +0000 Subject: [PATCH 6/6] voice: validate outgoing and deflect call numbers Validate the number parameter in Voice.CreateCall and Call.Deflect D-Bus methods to ensure they do not contain control characters or semicolons. This prevents AT command injection when the number is later spliced into ATD or +CTFR commands. Introduce a common helper mm_utils_is_valid_dial_number() to validate dial numbers, and add unit tests for it. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1067 Signed-off-by: Aleksander Morgado --- src/mm-base-call.c | 7 ++++ src/mm-iface-modem-voice.c | 10 ++---- src/mm-modem-helpers.c | 22 +++++++++++++ src/mm-modem-helpers.h | 2 ++ src/tests/test-modem-helpers.c | 58 ++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/mm-base-call.c b/src/mm-base-call.c index bf13bedc..e1fd60af 100644 --- a/src/mm-base-call.c +++ b/src/mm-base-call.c @@ -440,6 +440,13 @@ handle_deflect_auth_ready (MMAuthProvider *authp, return; } + /* Validate input number */ + if (!mm_utils_is_valid_dial_number (ctx->number, &error)) { + mm_dbus_method_invocation_take_error (ctx->invocation, error); + handle_deflect_context_free (ctx); + return; + } + state = mm_gdbus_call_get_state (MM_GDBUS_CALL (ctx->self)); /* We can only deflect incoming call in ringing or waiting state */ diff --git a/src/mm-iface-modem-voice.c b/src/mm-iface-modem-voice.c index 69f53cdc..b3907e53 100644 --- a/src/mm-iface-modem-voice.c +++ b/src/mm-iface-modem-voice.c @@ -23,6 +23,7 @@ #include "mm-call-list.h" #include "mm-error-helpers.h" #include "mm-log-object.h" +#include "mm-modem-helpers.h" #define CALL_LIST_POLLING_CONTEXT_TAG "voice-call-list-polling-context-tag" #define IN_CALL_EVENT_CONTEXT_TAG "voice-in-call-event-context-tag" @@ -176,14 +177,9 @@ create_outgoing_call_from_properties (MMIfaceModemVoice *self, guint dtmf_tone_duration; /* Don't create CALL from properties if either number is missing */ - number = mm_call_properties_get_number (properties) ; - if (!number) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_INVALID_ARGS, - "Cannot create call: mandatory parameter 'number' is missing"); + number = mm_call_properties_get_number (properties); + if (!mm_utils_is_valid_dial_number (number, error)) return NULL; - } dtmf_tone_duration = mm_call_properties_get_dtmf_tone_duration (properties) ; diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index 8be5fb63..ef129db5 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -5992,3 +5992,25 @@ mm_utils_is_numeric (const gchar *str) } return TRUE; } + +gboolean +mm_utils_is_valid_dial_number (const gchar *str, + GError **error) +{ + const gchar *c; + + if (!str || !str[0]) { + g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "missing number"); + return FALSE; + } + + for (c = str; *c; c++) { + if (((guint8)*c) < 0x20 || *c == ';') { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "invalid character '0x%02x' in number", (guint8)*c); + return FALSE; + } + } + return TRUE; +} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index e21ec7eb..482809e2 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -574,6 +574,8 @@ gboolean mm_parse_supl_address (const gchar *supl, void mm_utils_remove_control_characters (gchar *str); gboolean mm_utils_is_valid_fqdn (const gchar *fqdn); gboolean mm_utils_is_numeric (const gchar *str); +gboolean mm_utils_is_valid_dial_number (const gchar *str, + GError **error); gboolean mm_validate_cbs_channels (GArray *channels, GError **error); diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index 556d9606..c8583c63 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -4923,6 +4923,63 @@ test_is_numeric (void *f, gpointer d) g_assert (!mm_utils_is_numeric ("+123")); } +static void +test_is_valid_dial_number (void *f, gpointer d) +{ + GError *error = NULL; + gboolean r; + + r = mm_utils_is_valid_dial_number ("123456", &error); + g_assert (r); + g_assert_no_error (error); + + r = mm_utils_is_valid_dial_number ("+123456", &error); + g_assert (r); + g_assert_no_error (error); + + r = mm_utils_is_valid_dial_number ("*123#", &error); + g_assert (r); + g_assert_no_error (error); + + r = mm_utils_is_valid_dial_number ("123,456", &error); + g_assert (r); + g_assert_no_error (error); + + r = mm_utils_is_valid_dial_number ("123W456", &error); + g_assert (r); + g_assert_no_error (error); + + r = mm_utils_is_valid_dial_number (NULL, &error); + g_assert (!r); + g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS); + g_clear_error (&error); + + r = mm_utils_is_valid_dial_number ("", &error); + g_assert (!r); + g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS); + g_clear_error (&error); + + r = mm_utils_is_valid_dial_number ("123;456", &error); + g_assert (!r); + g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS); + g_clear_error (&error); + + r = mm_utils_is_valid_dial_number ("123\r456", &error); + g_assert (!r); + g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS); + g_clear_error (&error); + + r = mm_utils_is_valid_dial_number ("123\n456", &error); + g_assert (!r); + g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS); + g_clear_error (&error); + + r = mm_utils_is_valid_dial_number ("123\x01" "456", &error); + g_assert (!r); + g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS); + g_clear_error (&error); +} + /*****************************************************************************/ typedef struct { @@ -5472,6 +5529,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_remove_control_characters, NULL)); g_test_suite_add (suite, TESTCASE (test_is_valid_fqdn, NULL)); g_test_suite_add (suite, TESTCASE (test_is_numeric, NULL)); + g_test_suite_add (suite, TESTCASE (test_is_valid_dial_number, NULL)); g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL));