summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-modem-helpers.c25
-rw-r--r--src/tests/test-modem-helpers.c15
2 files changed, 32 insertions, 8 deletions
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index c25867120..7e91f4749 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -3514,10 +3514,10 @@ mm_3gpp_parse_iccid (const char *raw_iccid, GError **error)
goto error;
}
- /* BCD encoded ICCIDs are 20 digits long */
- if (len != 20) {
+ /* ICCIDs are 19 or 20 digits long */
+ if (len < 19 || len > 20) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Invalid ICCID response size (was %zd, expected 20)",
+ "Invalid ICCID response size (was %zd, expected 19 or 20)",
len);
goto error;
}
@@ -3526,9 +3526,16 @@ mm_3gpp_parse_iccid (const char *raw_iccid, GError **error)
* should be '89' for telecommunication purposes according to ISO/IEC 7812.
*/
if (buf[0] == '8' && buf[1] == '9') {
- swap = FALSE;
+ swap = FALSE;
} else if (buf[0] == '9' && buf[1] == '8') {
- swap = TRUE;
+ /* swapped digits are only expected in raw +CRSM responses, which must all
+ * be 20-bytes long */
+ if (len != 20) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Invalid ICCID response size while swap needed (expected 20)");
+ goto error;
+ }
+ swap = TRUE;
} else {
/* FIXME: Instead of erroring out, revisit this solution if we find any SIM
* that doesn't use '89' as the major industry identifier of the ICCID.
@@ -3539,9 +3546,10 @@ mm_3gpp_parse_iccid (const char *raw_iccid, GError **error)
}
/* Ensure if there's an 'F' that it's second-to-last if swap = TRUE,
- * otherwise last if swap = FALSE */
+ * otherwise last if swap = FALSE. Also fail if an F is found within a
+ * 19-digit reported ICCID. */
if (f_pos >= 0) {
- if ((swap && (f_pos != len - 2)) || (!swap && (f_pos != len - 1))) {
+ if ((len != 20) || (swap && (f_pos != len - 2)) || (!swap && (f_pos != len - 1))) {
g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Invalid ICCID length (unexpected F position)");
goto error;
@@ -3554,7 +3562,8 @@ mm_3gpp_parse_iccid (const char *raw_iccid, GError **error)
*
* 21436587 -> 12345678
*/
- swapped = g_malloc0 (25);
+ g_assert (len == 20);
+ swapped = g_malloc0 (21);
for (i = 0; i < 10; i++) {
swapped[i * 2] = buf[(i * 2) + 1];
swapped[(i * 2) + 1] = buf[i * 2];
diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c
index 4a044c681..839240512 100644
--- a/src/tests/test-modem-helpers.c
+++ b/src/tests/test-modem-helpers.c
@@ -2091,6 +2091,20 @@ test_iccid_parse_unquoted_unswapped_19_digit (void *f, gpointer d)
}
static void
+test_iccid_parse_unquoted_unswapped_19_digit_no_f (void *f, gpointer d)
+{
+ const char *raw_iccid = "8944200053671052499";
+ const char *expected = "8944200053671052499";
+ char *parsed;
+ GError *error = NULL;
+
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (parsed, ==, expected);
+ g_free (parsed);
+}
+
+static void
test_iccid_parse_quoted_unswapped_20_digit (void *f, gpointer d)
{
const char *raw_iccid = "\"89324102234690160476\"";
@@ -3924,6 +3938,7 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_swap_19_digit, NULL));
g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_swap_20_digit, NULL));
g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_unswapped_19_digit, NULL));
+ g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_unswapped_19_digit_no_f, NULL));
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_unswapped_20_digit, NULL));
g_test_suite_add (suite, TESTCASE (test_iccid_parse_short, NULL));
g_test_suite_add (suite, TESTCASE (test_iccid_parse_invalid_chars, NULL));