From 1d7f3b5eb27154b5d1ef698b40edfb9f74a9d4d2 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 12 Aug 2013 17:07:53 +0200 Subject: sms: Added result buffer size parameter to 7bit conv funs The 7bit<->8bit encoding/decoding functions didn't check whether there is still enough space in the destination buffer. Therefore a buffer size parameter has been added to each of the functions which is used to truncate the output if the buffer is too small. In addition, the return value of the decoding functions has been changed to number of characters written (excluding \0), so this value is always equal to strlen(decoded). The old functions are still available as wrapper functions. --- tests/sms/sms_test.c | 124 +++++++++++++++++++++++++++--------------------- tests/sms/sms_test.ok | 10 ++++ tests/ussd/ussd_test.c | 50 ++++++++++++++++--- tests/ussd/ussd_test.ok | 11 +++++ 4 files changed, 134 insertions(+), 61 deletions(-) (limited to 'tests') diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c index e48f9a36..3188a187 100644 --- a/tests/sms/sms_test.c +++ b/tests/sms/sms_test.c @@ -116,14 +116,14 @@ static const uint8_t concatenated_part2_enc[] = { static const struct test_case test_multiple_encode[] = { { - .input = concatenated_text, + .input = (const uint8_t *) concatenated_text, .expected = concatenated_part1_enc, .expected_octet_length = sizeof(concatenated_part1_enc), .expected_septet_length = concatenated_part1_septet_length, .ud_hdr_ind = 1, }, { - .input = concatenated_text, + .input = (const uint8_t *) concatenated_text, .expected = concatenated_part2_enc, .expected_octet_length = sizeof(concatenated_part2_enc), .expected_septet_length = concatenated_part2_septet_length, @@ -134,28 +134,28 @@ static const struct test_case test_multiple_encode[] = static const struct test_case test_encode[] = { { - .input = simple_text, + .input = (const uint8_t *) simple_text, .expected = simple_enc, .expected_octet_length = sizeof(simple_enc), .expected_septet_length = simple_septet_length, .ud_hdr_ind = 0, }, { - .input = escape_text, + .input = (const uint8_t *) escape_text, .expected = escape_enc, .expected_octet_length = sizeof(escape_enc), .expected_septet_length = escape_septet_length, .ud_hdr_ind = 0, }, { - .input = enhanced_text, + .input = (const uint8_t *) enhanced_text, .expected = enhanced_enc, .expected_octet_length = sizeof(enhanced_enc), .expected_septet_length = enhanced_septet_length, .ud_hdr_ind = 0, }, { - .input = enhancedV2_text, + .input = (const uint8_t *) enhancedV2_text, .expected = enhancedV2_enc, .expected_octet_length = sizeof(enhancedV2_enc), .expected_septet_length = enhancedV2_septet_length, @@ -168,42 +168,42 @@ static const struct test_case test_decode[] = { .input = simple_enc, .input_length = sizeof(simple_enc), - .expected = simple_text, + .expected = (const uint8_t *) simple_text, .expected_septet_length = simple_septet_length, .ud_hdr_ind = 0, }, { .input = escape_enc, .input_length = sizeof(escape_enc), - .expected = escape_text, + .expected = (const uint8_t *) escape_text, .expected_septet_length = escape_septet_length, .ud_hdr_ind = 0, }, { .input = enhanced_enc, .input_length = sizeof(enhanced_enc), - .expected = enhanced_text, + .expected = (const uint8_t *) enhanced_text, .expected_septet_length = enhanced_septet_length, .ud_hdr_ind = 0, }, { .input = enhancedV2_enc, .input_length = sizeof(enhancedV2_enc), - .expected = enhancedV2_text, + .expected = (const uint8_t *) enhancedV2_text, .expected_septet_length = enhancedV2_septet_length, .ud_hdr_ind = 0, }, { .input = concatenated_part1_enc, .input_length = sizeof(concatenated_part1_enc), - .expected = splitted_text_part1, + .expected = (const uint8_t *) splitted_text_part1, .expected_septet_length = concatenated_part1_septet_length_with_header, .ud_hdr_ind = 1, }, { .input = concatenated_part2_enc, .input_length = sizeof(concatenated_part2_enc), - .expected = splitted_text_part2, + .expected = (const uint8_t *) splitted_text_part2, .expected_septet_length = concatenated_part2_septet_length_with_header, .ud_hdr_ind = 1, }, @@ -216,7 +216,7 @@ static void test_octet_return() printf("Encoding some tests and printing number of septets/octets\n"); - septets = gsm_7bit_encode_oct((uint8_t *) out, "test1234", &oct); + septets = gsm_7bit_encode_n((uint8_t *) out, sizeof(out), "test1234", &oct); printf("SEPTETS: %d OCTETS: %d\n", septets, oct); printf("Done\n"); @@ -227,43 +227,58 @@ int main(int argc, char** argv) printf("SMS testing\n"); struct msgb *msg; uint8_t i; - + uint16_t buffer_size; uint8_t octet_length; + int octets_written; + uint8_t computed_octet_length; uint8_t septet_length; uint8_t gsm_septet_length; uint8_t coded[256]; uint8_t tmp[160]; uint8_t septet_data[256]; uint8_t ud_header[6]; + int nchars; char result[256]; /* test 7-bit encoding */ for (i = 0; i < ARRAY_SIZE(test_encode); ++i) { memset(coded, 0x42, sizeof(coded)); - septet_length = gsm_7bit_encode(coded, test_encode[i].input); - octet_length = gsm_get_octet_len(septet_length); - if (octet_length != test_encode[i].expected_octet_length) { - fprintf(stderr, "Encode case %d: Octet length failure. Got %d, expected %d\n", - i, octet_length, test_encode[i].expected_octet_length); - return -1; - } - - if (septet_length != test_encode[i].expected_septet_length){ - fprintf(stderr, "Encode case %d: Septet length failure. Got %d, expected %d\n", - i, septet_length, test_encode[i].expected_septet_length); - return -1; - } - - if (memcmp(coded, test_encode[i].expected, octet_length) != 0) { - fprintf(stderr, "Encoded content does not match for case %d\n", - i); - return -1; + septet_length = gsm_7bit_encode_n(coded, sizeof(coded), + (const char *) test_encode[i].input, + &octets_written); + computed_octet_length = gsm_get_octet_len(septet_length); + printf("Encode case %d: " + "Octet length %d (expected %d, computed %d), " + "septet length %d (expected %d)\n" + , i + , octets_written, test_encode[i].expected_octet_length, computed_octet_length + , septet_length, test_encode[i].expected_septet_length + ); + + OSMO_ASSERT (octets_written == test_encode[i].expected_octet_length); + OSMO_ASSERT (octets_written == computed_octet_length); + OSMO_ASSERT (memcmp(coded, test_encode[i].expected, octets_written) == 0); + + /* check buffer limiting */ + memset(coded, 0xaa, sizeof(coded)); + + for (buffer_size = 0; + buffer_size < test_encode[i].expected_octet_length + 1 + && buffer_size < sizeof(coded) - 1; + ++buffer_size) + { + gsm_7bit_encode_n(coded, buffer_size, + (const char *) test_encode[i].input, + &octets_written); + + OSMO_ASSERT(octets_written <= buffer_size); + OSMO_ASSERT(coded[buffer_size] == 0xaa); } } /* Test: encode multiple SMS */ - int number_of_septets = gsm_septet_encode(septet_data, test_multiple_encode[0].input); + int number_of_septets = gsm_septet_encode(septet_data, (const char *) test_multiple_encode[0].input); /* SMS part 1 */ memset(tmp, 0x42, sizeof(tmp)); @@ -281,11 +296,7 @@ int main(int argc, char** argv) memset(coded, 0x42, sizeof(coded)); memcpy(coded, tmp, octet_length + 6); - if (memcmp(coded, test_multiple_encode[0].expected, octet_length) != 0) { - fprintf(stderr, "Multiple-SMS encoded content does not match for part 1\n"); - return -1; - } - + OSMO_ASSERT(memcmp(coded, test_multiple_encode[0].expected, octet_length) == 0); /* SMS part 2 */ memset(tmp, 0x42, sizeof(tmp)); @@ -303,27 +314,32 @@ int main(int argc, char** argv) memset(coded, 0x42, sizeof(coded)); memcpy(coded, tmp, octet_length + 6); - if (memcmp(coded, test_multiple_encode[1].expected, octet_length) != 0) { - fprintf(stderr, "Multiple-SMS encoded content does not match for part 2\n"); - return -1; - } - - + OSMO_ASSERT(memcmp(coded, test_multiple_encode[1].expected, octet_length) == 0); /* test 7-bit decoding */ for (i = 0; i < ARRAY_SIZE(test_decode); ++i) { - memset(result, 0x42, sizeof(coded)); - septet_length = gsm_7bit_decode_hdr(result, test_decode[i].input, + memset(result, 0x42, sizeof(result)); + nchars = gsm_7bit_decode_n_hdr(result, sizeof(result), test_decode[i].input, test_decode[i].expected_septet_length, test_decode[i].ud_hdr_ind); + printf("Decode case %d: return value %d (expected %d)\n", i, nchars, strlen(result)); - if (strcmp(result, test_decode[i].expected) != 0) { - fprintf(stderr, "Test case %d failed to decode.\n", i); - return -1; - } - if (septet_length != test_decode[i].expected_septet_length) { - fprintf(stderr, "Decode case %d: Septet length failure. Got %d, expected %d\n", - i, septet_length, test_decode[i].expected_septet_length); - return -1; + OSMO_ASSERT(strcmp(result, (const char *) test_decode[i].expected) == 0); + OSMO_ASSERT(nchars == strlen(result)); + + /* check buffer limiting */ + memset(result, 0xaa, sizeof(result)); + + for (buffer_size = 1; + buffer_size < test_encode[i].expected_septet_length + 1 + && buffer_size < sizeof(result) - 1; + ++buffer_size) + { + nchars = gsm_7bit_decode_n_hdr(result, buffer_size, test_decode[i].input, + test_decode[i].expected_septet_length, test_decode[i].ud_hdr_ind); + + OSMO_ASSERT(nchars <= buffer_size); + OSMO_ASSERT(result[buffer_size] == (char)0xaa); + OSMO_ASSERT(result[nchars] == '\0'); } } diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok index ce6cb178..915a59c8 100644 --- a/tests/sms/sms_test.ok +++ b/tests/sms/sms_test.ok @@ -1,4 +1,14 @@ SMS testing +Encode case 0: Octet length 8 (expected 8, computed 8), septet length 9 (expected 9) +Encode case 1: Octet length 36 (expected 36, computed 36), septet length 41 (expected 41) +Encode case 2: Octet length 35 (expected 35, computed 35), septet length 39 (expected 39) +Encode case 3: Octet length 35 (expected 35, computed 35), septet length 40 (expected 40) +Decode case 0: return value 9 (expected 9) +Decode case 1: return value 40 (expected 40) +Decode case 2: return value 31 (expected 31) +Decode case 3: return value 32 (expected 32) +Decode case 4: return value 153 (expected 153) +Decode case 5: return value 40 (expected 40) Encoding some tests and printing number of septets/octets SEPTETS: 8 OCTETS: 7 Done diff --git a/tests/ussd/ussd_test.c b/tests/ussd/ussd_test.c index e3e8e08a..b04f8e8a 100644 --- a/tests/ussd/ussd_test.c +++ b/tests/ussd/ussd_test.c @@ -73,20 +73,42 @@ static void test_7bit_ussd(const char *text, const char *encoded_hex, const char { uint8_t coded[256]; char decoded[256]; - int y; + int octets_written; + int buffer_size; + int nchars; printf("original = %s\n", osmo_hexdump((uint8_t *)text, strlen(text))); - gsm_7bit_encode_ussd(coded, text, &y); - printf("encoded = %s\n", osmo_hexdump(coded, y)); + gsm_7bit_encode_n_ussd(coded, sizeof(coded), text, &octets_written); + printf("encoded = %s\n", osmo_hexdump(coded, octets_written)); - OSMO_ASSERT(strcmp(encoded_hex, osmo_hexdump_nospc(coded, y)) == 0); + OSMO_ASSERT(strcmp(encoded_hex, osmo_hexdump_nospc(coded, octets_written)) == 0); - gsm_7bit_decode_ussd(decoded, coded, y * 8 / 7); - y = strlen(decoded); - printf("decoded = %s\n\n", osmo_hexdump((uint8_t *)decoded, y)); + gsm_7bit_decode_n_ussd(decoded, sizeof(decoded), coded, octets_written * 8 / 7); + octets_written = strlen(decoded); + printf("decoded = %s\n\n", osmo_hexdump((uint8_t *)decoded, octets_written)); OSMO_ASSERT(strncmp(text, decoded, strlen(text)) == 0); OSMO_ASSERT(strcmp(appended_after_decode, decoded + strlen(text)) == 0); + + /* check buffer limiting */ + memset(decoded, 0xaa, sizeof(decoded)); + + for (buffer_size = 1; buffer_size < sizeof(decoded) - 1; ++buffer_size) + { + nchars = gsm_7bit_decode_n_ussd(decoded, buffer_size, coded, octets_written * 8 / 7); + OSMO_ASSERT(nchars <= buffer_size); + OSMO_ASSERT(decoded[buffer_size] == (char)0xaa); + OSMO_ASSERT(decoded[nchars] == '\0'); + } + + memset(coded, 0xaa, sizeof(coded)); + + for (buffer_size = 0; buffer_size < sizeof(coded) - 1; ++buffer_size) + { + gsm_7bit_encode_n_ussd(coded, buffer_size, text, &octets_written); + OSMO_ASSERT(octets_written <= buffer_size); + OSMO_ASSERT(coded[buffer_size] == 0xaa); + } } int main(int argc, char **argv) @@ -94,6 +116,7 @@ int main(int argc, char **argv) struct ussd_request req; const int size = sizeof(ussd_request); int i; + struct msgb *msg; osmo_init_logging(&info); @@ -122,5 +145,18 @@ int main(int argc, char **argv) test_7bit_ussd("0123456\r", "b0986c46abd91a0d", "\r"); test_7bit_ussd("012345\r", "b0986c46ab351a", ""); + printf("Checking GSM 04.80 USSD message generation.\n"); + + test_7bit_ussd("", "", ""); + msg = gsm0480_create_unstructuredSS_Notify (0x00, ""); + printf ("Created unstructuredSS_Notify (0x00): %s\n", + osmo_hexdump(msgb_data(msg), msgb_length(msg))); + msgb_free (msg); + + test_7bit_ussd("forty-two", "e6b79c9e6fd1ef6f", ""); + msg = gsm0480_create_unstructuredSS_Notify (0x42, "forty-two"); + printf ("Created unstructuredSS_Notify (0x42): %s\n", + osmo_hexdump(msgb_data(msg), msgb_length(msg))); + msgb_free (msg); return 0; } diff --git a/tests/ussd/ussd_test.ok b/tests/ussd/ussd_test.ok index 91f2a315..54d59eef 100644 --- a/tests/ussd/ussd_test.ok +++ b/tests/ussd/ussd_test.ok @@ -72,3 +72,14 @@ original = 30 31 32 33 34 35 0d encoded = b0 98 6c 46 ab 35 1a decoded = 30 31 32 33 34 35 0d +Checking GSM 04.80 USSD message generation. +original = +encoded = +decoded = + +Created unstructuredSS_Notify (0x00): 30 08 04 01 0f 04 00 04 01 00 +original = 66 6f 72 74 79 2d 74 77 6f +encoded = e6 b7 9c 9e 6f d1 ef 6f +decoded = 66 6f 72 74 79 2d 74 77 6f + +Created unstructuredSS_Notify (0x42): 30 10 04 01 0f 04 08 e6 b7 9c 9e 6f d1 ef 6f 04 01 42 -- cgit v1.2.3