From a084dfa02d28a9372a7e406c9b101a43308a4937 Mon Sep 17 00:00:00 2001 From: axtloss Date: Mon, 24 Jun 2024 21:50:48 +0200 Subject: Add new function memvcmp and unit tests --- Makefile | 7 +-- src/extlib.c | 18 ++++++-- src/extlib.h | 6 ++- test.c | 27 ----------- tests/Makefile | 10 +++++ tests/test.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 173 insertions(+), 34 deletions(-) delete mode 100644 test.c create mode 100644 tests/Makefile create mode 100644 tests/test.c diff --git a/Makefile b/Makefile index 3713824..5a2eaaf 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ install: extlib extlib.pc install -Dm655 src/extlib.h $(PREFIX)/include/ install -Dm655 extlib.pc $(PREFIX)/share/pkgconfig/ -test: - $(CC) $(TESTCFLAGS) $(TESTLDFLAGS) test.c -o test - ./test +test: FORCE + cd tests && make test + +FORCE: ; # PHONY is a non standard extension diff --git a/src/extlib.c b/src/extlib.c index ee20d3e..151a74f 100644 --- a/src/extlib.c +++ b/src/extlib.c @@ -27,10 +27,11 @@ #undef malloc void -free_secure(void *__ptr, size_t ptrlen) +free_secure(void **__ptr, size_t ptrlen) { - memset (__ptr, 0, ptrlen); - free (__ptr); + memset (*__ptr, 0, ptrlen); + free (*__ptr); + *__ptr = NULL; return; } @@ -42,6 +43,16 @@ malloc_secure (size_t len) return mem; } +int +memvcmp (void *str, + char val, + size_t n) +{ + char str2[n]; + memset (str2, val, n); + return memcmp (str, str2, n); +} + void fcopy(FILE *f1, FILE *f2) { @@ -54,5 +65,6 @@ fcopy(FILE *f1, FILE *f2) fprintf (stderr, "Failed to copy data"); return; } + fflush (f2); } } diff --git a/src/extlib.h b/src/extlib.h index 1948352..15903c3 100644 --- a/src/extlib.h +++ b/src/extlib.h @@ -25,7 +25,7 @@ #define malloc(x) error - use malloc_secure /// Automatically zero out a pointer before freeing it -void free_secure (void *__ptr, size_t ptrlen); +void free_secure (void **__ptr, size_t ptrlen); /// Automatically initialise the allocated memory with zeros void *malloc_secure (size_t len); @@ -33,6 +33,10 @@ void *malloc_secure (size_t len); /// Copy the data of one filestream to another void fcopy(FILE *f1, FILE *f2); +/// Compare the first n bytes of a memory area str to the value val. +/// Returns 0 if the values the same, any other value if they are not the same. +int memvcmp (void *str, char val, size_t n); + /// Convert a string to lowercase char *strlwr(char *s); diff --git a/test.c b/test.c deleted file mode 100644 index 807b417..0000000 --- a/test.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include - -void print_hex(const char *s) -{ - while(*s) - printf("%02x", (unsigned int) *s++); - printf("\n"); -} - -int -main(void) { - char *test = malloc_secure (9); - sprintf (test, "meowmeow"); - assert (strcmp (test, "meowmeow") == 0); - puts ("Test 1 passed"); - char *upper = strupr (test); - assert (strcmp (upper, "MEOWMEOW") == 0); - puts ("Test 2 passed"); - char *lower = strlwr (test); - assert (strcmp (lower, "meowmeow") == 0); - puts ("Test 3 passed"); - free_secure (lower, strlen (lower)); -} diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..660a20f --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,10 @@ +.POSIX: + +CC = cc +CFLAGS = -g -fsanitize=address,undefined + +test: FORCE + $(CC) test.c ../src/extlib.c ../src/extstring.c $(CFLAGS) -o test + ./test + +FORCE: ; # PHONY is a non standard extension diff --git a/tests/test.c b/tests/test.c new file mode 100644 index 0000000..a58602a --- /dev/null +++ b/tests/test.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include +#include "../src/extlib.h" + +int +test_malloc_free_secure (size_t size) +{ + char *mall_test = malloc_secure (size); + if (!mall_test) + return 1; + if (memvcmp (mall_test, 0, size) != 0) + return 2; + free_secure ((void **)&mall_test, size); + if (mall_test) + return 3; + return 0; +} + +int +test_fcopy() +{ + char *buf_a; + char *buf_b; + size_t len_a; + size_t len_b; + FILE *file_test_a = open_memstream (&buf_a, &len_a); + FILE *file_test_b = open_memstream (&buf_b, &len_b); + + fprintf (file_test_a, "hello"); + fflush (file_test_a); + fclose (file_test_a); + file_test_a = fmemopen(buf_a, len_a, "r"); + + fcopy (file_test_a, file_test_b); + fclose (file_test_b); + + if (memcmp(buf_a, buf_b, len_a) != 0) { + free_secure ((void**)&buf_a, len_a); + free_secure ((void **)&buf_b, len_b); + return 1; + } + free_secure ((void**)&buf_a, len_a); + free_secure ((void **)&buf_b, len_b); + return 0; +} + +int +test_strlwr_strupr () +{ + char *test_string = strdup ("hello"); + char *uppr_string = strupr (test_string); + char *lower_string = strlwr (uppr_string); + + if (strcmp (uppr_string, "HELLO") != 0) { + free_secure ((void **)&test_string, strlen (test_string)); + return 1; + } + if (strcmp (lower_string, "hello") != 0) { + free_secure ((void **)&test_string, strlen (test_string)); + return 2; + } + free_secure ((void **)&test_string, strlen (test_string)); + return 0; +} + +int +test_trim() +{ + char *test_string = strdup ("\t\thi\t\t"); + char *trimmed_string = trim (test_string); + if (strstr (trimmed_string, "\t") != NULL) { + free_secure ((void**)&test_string, strlen (test_string)); + return 1; + } + free_secure ((void**)&test_string, strlen (test_string)); + return 0; +} + +int +test_replace_str () +{ + char *test_string = strdup ("replace world!"); + char *replaced_string = replace_str (test_string, "replace", "hello"); + if (strcmp (replaced_string, "hello world!") != 0) { + free_secure ((void**)&test_string, strlen (test_string)); + free_secure ((void**)&replaced_string, strlen (replaced_string)); + return 1; + } + free_secure ((void**)&test_string, strlen (test_string)); + free_secure ((void**)&replaced_string, strlen (replaced_string)); + return 0; +} + + +int +main (void) +{ + printf ("=== extlib unit tests ===\n"); + printf ("\n"); + + printf ("Test Case 1: test_malloc_free_secure -- malloc_secure free_secure memvcmp\n"); + int test_1_result = test_malloc_free_secure (12); + if (test_1_result == 0) + printf ("Test Case 1: test_malloc_free_secure -- SUCCESS\n\n"); + else + printf ("Test Case 1: test_malloc_free_secure -- FAILED %d\n\n", test_1_result); + + printf ("Test Case 2: test_fcopy -- fcopy\n"); + int test_2_result = test_fcopy (); + if (test_2_result == 0) + printf ("Test Case 2: test_fcopy -- SUCCESS\n\n"); + else + printf ("Test Case 2: test_fcopy -- FAILED %d\n\n", test_2_result); + + printf ("Test Case 3: test_strlwr_strupr -- strlwr strupr\n"); + int test_3_result = test_strlwr_strupr (); + if (test_2_result == 0) + printf ("Test Case 3: test_strlwr_strupr -- SUCCESS\n\n"); + else + printf ("Test Case 3: test_strlwr_strupr -- FAILED %d\n\n", test_3_result); + + printf ("Test Case 4: test_trim -- trim\n"); + int test_4_result = test_trim (); + if (test_4_result == 0) + printf ("Test Case 4: test_trim -- SUCCESS\n\n"); + else + printf ("Test Case 4: test_trim -- FAILED %d\n\n", test_4_result); + + printf ("Test Case 5: test_replace_str -- replace_str\n"); + int test_5_result = test_replace_str(); + if (test_5_result == 0) + printf ("Test Case 5: test_replace_str -- SUCCESS\n\n"); + else + printf ("Test Case 5: test_replace_str -- FAILED %d\n\n", test_5_result); + return 0; +} -- cgit v1.2.3