aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/tests/gprs
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-04 14:22:13 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-04 15:00:54 +0200
commitce1b22e817584d512f82a711c02b67d12346c202 (patch)
tree5318c4557958272364f66e954359b6bbb7a36edb /openbsc/tests/gprs
parent4d9fc422d2dd17118d70a2ed25ab383614a81ede (diff)
gprs: Add testcases for the APN string/octet conversion and fix it
Create a testcase for the gprs_str_to_apn and gprs_apn_to_str routines. While writing the testcase we noticed it is possible to write more bytes than should have been allowed. This is fixed by checking that the max_len is at least 1 (needed to write the first length octet) and to do the size check before writing to the output. Modify the signature of gprs_str_to_apn to put the length/size next to the parameter that requires a size. Done with Jacob
Diffstat (limited to 'openbsc/tests/gprs')
-rw-r--r--openbsc/tests/gprs/Makefile.am3
-rw-r--r--openbsc/tests/gprs/gprs_test.c97
2 files changed, 99 insertions, 1 deletions
diff --git a/openbsc/tests/gprs/Makefile.am b/openbsc/tests/gprs/Makefile.am
index 904d567c1..193655fa4 100644
--- a/openbsc/tests/gprs/Makefile.am
+++ b/openbsc/tests/gprs/Makefile.am
@@ -5,4 +5,5 @@ EXTRA_DIST = gprs_test.ok
noinst_PROGRAMS = gprs_test
-gprs_test_SOURCES = gprs_test.c
+gprs_test_SOURCES = gprs_test.c $(top_srcdir)/src/gprs/gprs_utils.c
+gprs_test_LDADD = $(LIBOSMOCORE_LIBS)
diff --git a/openbsc/tests/gprs/gprs_test.c b/openbsc/tests/gprs/gprs_test.c
index 7b0e64113..30e900f61 100644
--- a/openbsc/tests/gprs/gprs_test.c
+++ b/openbsc/tests/gprs/gprs_test.c
@@ -3,6 +3,7 @@
#include <inttypes.h>
#include <openbsc/gprs_llc.h>
+#include <openbsc/gprs_utils.h>
#define ASSERT_FALSE(x) if (x) { printf("Should have returned false.\n"); abort(); }
#define ASSERT_TRUE(x) if (!x) { printf("Should have returned true.\n"); abort(); }
@@ -42,9 +43,105 @@ static void test_8_4_2()
ASSERT_FALSE(nu_is_retransmission(479, 511)); // wrapped
}
+static void apn_round_trip(const uint8_t *input, size_t len, const char *wanted_output)
+{
+ char output[len ? len : 1];
+ uint8_t encoded[len + 50];
+ char *out_str;
+ int enc_len;
+
+ /* decode and verify we have what we want */
+ out_str = gprs_apn_to_str(output, input, len);
+ OSMO_ASSERT(out_str);
+ OSMO_ASSERT(out_str == &output[0]);
+ OSMO_ASSERT(strlen(out_str) == strlen(wanted_output));
+ OSMO_ASSERT(strcmp(out_str, wanted_output) == 0);
+
+ /* encode and verify it */
+ if (len != 0) {
+ enc_len = gprs_str_to_apn(encoded, ARRAY_SIZE(encoded), wanted_output);
+ OSMO_ASSERT(enc_len == len);
+ OSMO_ASSERT(memcmp(encoded, input, enc_len) == 0);
+ } else {
+ enc_len = gprs_str_to_apn(encoded, 0, wanted_output);
+ OSMO_ASSERT(enc_len == -1);
+ }
+}
+
+static void test_gsm_03_03_apn(void)
+{
+
+ {
+ /* test invalid writes */
+ const uint8_t ref[10] = { 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF };
+ uint8_t output[10];
+ int enc_len;
+
+ memcpy(output, ref, ARRAY_SIZE(output));
+ enc_len = gprs_str_to_apn(output, 0, "");
+ OSMO_ASSERT(enc_len == -1);
+ OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0);
+
+ memcpy(output, ref, ARRAY_SIZE(output));
+ enc_len = gprs_str_to_apn(output, 0, "foo");
+ OSMO_ASSERT(enc_len == -1);
+ OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0);
+
+ memcpy(output, ref, ARRAY_SIZE(output));
+ enc_len = gprs_str_to_apn(output, 1, "foo");
+ OSMO_ASSERT(enc_len == -1);
+ OSMO_ASSERT(memcmp(ref + 1, output + 1, ARRAY_SIZE(ref) - 1) == 0);
+
+ memcpy(output, ref, ARRAY_SIZE(output));
+ enc_len = gprs_str_to_apn(output, 2, "foo");
+ OSMO_ASSERT(enc_len == -1);
+ OSMO_ASSERT(memcmp(ref + 2, output + 2, ARRAY_SIZE(ref) - 2) == 0);
+
+ memcpy(output, ref, ARRAY_SIZE(output));
+ enc_len = gprs_str_to_apn(output, 3, "foo");
+ OSMO_ASSERT(enc_len == -1);
+ OSMO_ASSERT(memcmp(ref + 3, output + 3, ARRAY_SIZE(ref) - 3) == 0);
+ }
+
+ {
+ /* single empty label */
+ uint8_t input[] = { 0x0 };
+ const char *output = "";
+ apn_round_trip(input, ARRAY_SIZE(input), output);
+ }
+
+ {
+ /* no label */
+ uint8_t input[] = { };
+ const char *output = "";
+ apn_round_trip(input, ARRAY_SIZE(input), output);
+ }
+
+ {
+ /* single label with A */
+ uint8_t input[] = { 0x1, 65 };
+ const char *output = "A";
+ apn_round_trip(input, ARRAY_SIZE(input), output);
+ OSMO_ASSERT(gprs_apn_to_str(NULL, input, ARRAY_SIZE(input) - 1) == NULL);
+ }
+
+ {
+ uint8_t input[] = { 0x3, 65, 66, 67, 0x2, 90, 122 };
+ const char *output = "ABC.Zz";
+ char tmp[strlen(output) + 1];
+ apn_round_trip(input, ARRAY_SIZE(input), output);
+ OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 1) == NULL);
+ OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 2) == NULL);
+ OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 4) == NULL);
+ OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 5) == NULL);
+ OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 6) == NULL);
+ }
+}
+
int main(int argc, char **argv)
{
test_8_4_2();
+ test_gsm_03_03_apn();
printf("Done.\n");
return EXIT_SUCCESS;