diff options
| -rw-r--r-- | include/console.h | 6 | ||||
| -rw-r--r-- | include/system/string.h | 17 | ||||
| -rw-r--r-- | include/test.h | 47 | ||||
| -rw-r--r-- | include/test.mk | 1 | ||||
| -rw-r--r-- | lib/string.c | 17 | ||||
| -rw-r--r-- | shim.h | 4 | ||||
| -rw-r--r-- | test-sbat.c | 47 | ||||
| -rw-r--r-- | test-str.c | 170 |
8 files changed, 283 insertions, 26 deletions
diff --git a/include/console.h b/include/console.h index 00982744..036262ef 100644 --- a/include/console.h +++ b/include/console.h @@ -92,6 +92,7 @@ struct _EFI_CONSOLE_CONTROL_PROTOCOL { extern VOID console_fini(VOID); extern VOID setup_verbosity(VOID); extern UINT32 verbose; +#ifndef SHIM_UNIT_TEST #define dprint_(fmt, ...) ({ \ UINTN __dprint_ret = 0; \ if (verbose) \ @@ -101,6 +102,11 @@ extern UINT32 verbose; #define dprint(fmt, ...) \ dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__ - 1, __func__, \ ##__VA_ARGS__) +#else +#define dprint_(...) +#define dprint(fmt, ...) +#endif + extern EFI_STATUS EFIAPI vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, va_list args); #define vdprint(fmt, ...) \ diff --git a/include/system/string.h b/include/system/string.h index 822e28fa..66e7d93e 100644 --- a/include/system/string.h +++ b/include/system/string.h @@ -1,6 +1,23 @@ // SPDX-License-Identifier: BSD-2-Clause-Patent #ifdef SHIM_UNIT_TEST #include_next <string.h> + +__typeof__(strlen) shim_strlen; +__typeof__(strcmp) shim_strcmp; +__typeof__(strncmp) shim_strncmp; +__typeof__(strncasecmp) shim_strncasecmp; +__typeof__(strcasecmp) shim_strcasecmp; +__typeof__(strrchr) shim_strrchr; +__typeof__(strrchr) shim_strrchr; +__typeof__(strnlen) shim_strnlen; +__typeof__(strcpy) shim_strcpy; +__typeof__(strncpy) shim_strncpy; +__typeof__(strdup) shim_strdup; +__typeof__(strndup) shim_strndup; +__typeof__(stpcpy) shim_stpcpy; +__typeof__(strchrnul) shim_strchrnul; +__typeof__(strchr) shim_strchr; + #else #ifndef _STRING_H #define _STRING_H diff --git a/include/test.h b/include/test.h index 8a970fd2..4441f969 100644 --- a/include/test.h +++ b/include/test.h @@ -63,6 +63,53 @@ extern int debug; assert(cond); \ }) +#define assert_true_return(a, status, fmt, ...) \ + ({ \ + if (!(a)) { \ + printf("%s:%d:got %lld, expected nonzero " fmt, \ + __func__, __LINE__, (long long)(a), \ + ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify(!(a))); \ + return status; \ + } \ + }) +#define assert_nonzero_return(a, ...) assert_true_return(a, ##__VA_ARGS__) + +#define assert_false_return(a, status, fmt, ...) \ + ({ \ + if (a) { \ + printf("%s:%d:got %lld, expected zero " fmt, __func__, \ + __LINE__, (long long)(a), ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify(a)); \ + return status; \ + } \ + }) +#define assert_zero_return(a, ...) assert_false_return(a, ##__VA_ARGS__) + +#define assert_positive_return(a, status, fmt, ...) \ + ({ \ + if ((a) <= 0) { \ + printf("%s:%d:got %lld, expected > 0 " fmt, __func__, \ + __LINE__, (long long)(a), ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify((a) <= 0)); \ + return status; \ + } \ + }) + +#define assert_negative_return(a, status, fmt, ...) \ + ({ \ + if ((a) >= 0) { \ + printf("%s:%d:got %lld, expected < 0 " fmt, __func__, \ + __LINE__, (long long)(a), ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify((a) >= 0)); \ + return status; \ + } \ + }) + #define assert_equal_return(a, b, status, fmt, ...) \ ({ \ if (!((a) == (b))) { \ diff --git a/include/test.mk b/include/test.mk index 735d0dc5..542be176 100644 --- a/include/test.mk +++ b/include/test.mk @@ -35,6 +35,7 @@ test-random.h: xxd -i random.bin test-random.h test-sbat_FILES = csv.c +test-str_FILES = lib/string.c tests := $(patsubst %.c,%,$(wildcard test-*.c)) diff --git a/lib/string.c b/lib/string.c index 1f58f3ec..3dc6f1cd 100644 --- a/lib/string.c +++ b/lib/string.c @@ -5,6 +5,23 @@ #define SHIM_STRING_C_ #include "shim.h" +#ifdef SHIM_UNIT_TEST +#define strlen shim_strlen +#define strcmp shim_strcmp +#define strncmp shim_strncmp +#define strncasecmp shim_strncasecmp +#define strcasecmp shim_strcasecmp +#define strrchr shim_strrchr +#define strlen shim_strlen +#define strcpy shim_strcpy +#define strncpy shim_strncpy +#define strdup shim_strdup +#define strndup shim_strndup +#define stpcpy shim_stpcpy +#define strchrnul shim_strchrnul +#define strchr shim_strchr +#endif + size_t strlen(const char *s1) { @@ -3,6 +3,10 @@ #ifndef SHIM_H_ #define SHIM_H_ +#ifdef SHIM_UNIT_TEST +#define _GNU_SOURCE +#endif + #if defined __GNUC__ && defined __GNUC_MINOR__ # define GNUC_PREREQ(maj, min) \ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) diff --git a/test-sbat.c b/test-sbat.c index c671f03e..780e5cbe 100644 --- a/test-sbat.c +++ b/test-sbat.c @@ -427,26 +427,29 @@ test_parse_sbat_var_data(void) return 0; } -#if 0 /* * verify_sbat() tests * Note: verify_sbat also frees the underlying "sbat_entries" memory. */ int -test_verify_sbat_null_sbat(void) +test_verify_sbat_null_sbat_section(void) { - list_t *test_sbat_entries; - test_sbat_entries = create_mock_sbat_entries_one_entry("test1", "1"); - if (!test_sbat_entries) - return -1; + char sbat_var_data[] = "test1,1"; EFI_STATUS status; + list_t test_sbat_var; + size_t n = 0; + struct sbat_section_entry **entries = NULL; - status = verify_sbat(NULL, test_sbat_entries); + INIT_LIST_HEAD(&test_sbat_var); + status = parse_sbat_var_data(&test_sbat_var, sbat_var_data, sizeof(sbat_var_data)); + assert_equal_return(status, EFI_SUCCESS, -1, "got %#x expected %#x\n"); - assert(status == EFI_INVALID_PARAMETER); + status = verify_sbat_helper(&sbat_var, n, entries); + assert_equal_return(status, EFI_SUCCESS, -1, "got %#x expected %#x\n"); return 0; } +#if 0 int test_verify_sbat_null_sbat_entries(void) { @@ -969,22 +972,22 @@ main(void) test(test_parse_sbat_var_data_null_data); test(test_parse_sbat_var_data_zero_size); -#if 0 // verify_sbat tests - //test_verify_sbat_null_sbat(); - test_verify_sbat_null_sbat_entries(); - test_verify_sbat_match_one_exact(); - test_verify_sbat_match_one_higher(); - test_verify_sbat_reject_one(); - test_verify_sbat_reject_many(); - test_verify_sbat_match_many_higher(); - test_verify_sbat_match_many_exact(); - test_verify_sbat_reject_many_all(); - test_verify_sbat_match_diff_name(); - test_verify_sbat_match_diff_name_mixed(); - test_verify_sbat_reject_diff_name_mixed(); + test(test_verify_sbat_null_sbat_section); +#if 0 + test(test_verify_sbat_null_sbat_entries); + test(test_verify_sbat_match_one_exact); + test(test_verify_sbat_match_one_higher); + test(test_verify_sbat_reject_one); + test(test_verify_sbat_reject_many); + test(test_verify_sbat_match_many_higher); + test(test_verify_sbat_match_many_exact); + test(test_verify_sbat_reject_many_all); + test(test_verify_sbat_match_diff_name); + test(test_verify_sbat_match_diff_name_mixed); + test(test_verify_sbat_reject_diff_name_mixed); #endif - test_parse_and_verify(); + test(test_parse_and_verify); return 0; } @@ -13,15 +13,39 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic error "-Wnonnull" +/* + * copy-pasta from gnu-efi + */ +static inline UINTN +strncmpa ( + IN CONST CHAR8 *s1, + IN CONST CHAR8 *s2, + IN UINTN len + ) +// compare strings +{ + while (*s1 && len) { + if (*s1 != *s2) { + break; + } + + s1 += 1; + s2 += 1; + len -= 1; + } + + return len ? *s1 - *s2 : 0; +} + int test_strchrnul(void) { const char s0[] = "abcd\0fghi"; - assert_equal_return(strchrnul(s0, 'a'), &s0[0], -1, "got %p expected %p\n"); - assert_equal_return(strchrnul(s0, 'd'), &s0[3], -1, "got %p expected %p\n"); - assert_equal_return(strchrnul(s0, '\000'), &s0[4], -1, "got %p expected %p\n"); - assert_equal_return(strchrnul(s0, 'i'), &s0[4], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchrnul(s0, 'a'), &s0[0], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchrnul(s0, 'd'), &s0[3], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchrnul(s0, '\000'), &s0[4], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchrnul(s0, 'i'), &s0[4], -1, "got %p expected %p\n"); assert_equal_return(strnchrnul(s0, 0, 'b'), &s0[0], -1, "got %p expected %p\n"); assert_equal_return(strnchrnul(s0, -1, 'b'), &s0[1], 1, "got %p expected %p\n"); @@ -36,6 +60,143 @@ test_strchrnul(void) } int +test_strncmp(void) +{ + /* + * these are constants so that the failures are readable if you get + * it wrong. + */ +#define s0 "sbat," +#define s0sz 6 +#define s0len 5 +#define s1 "sbat,1,2021030218" +#define s1sz 18 +#define s1len 17 +#define s2 "sbat,1,20210302" +#define s2sz 16 +#define s2len 15 +#define s3 "sbat,1,20210303" +#define s3sz 16 +#define s3len 15 + + int diff; + + assert_zero_return(strncmp(s0, s0, s0len), -1, "\n"); + assert_zero_return(strncmp(s0, s0, s0sz), -1, "\n"); + + assert_zero_return(strncmp(s0, s1, s0len), -1, "\n"); + assert_negative_return(strncmp(s0, s1, s0sz), -1, "\n"); + assert_equal_return(strncmp(s0, s1, s0sz), s0[s0len] - s1[s0len] , -1, "expected %d got %d\n"); + assert_positive_return(strncmp(s1, s0, s0sz), -1, "\n"); + assert_equal_return(strncmp(s1, s0, s0sz), s1[s0len] - s0[s0len] , -1, "expected %d got %d\n"); + + assert_positive_return(strncmp(s1, s2, s1sz), -1, "\n"); + assert_equal_return(strncmp(s1, s2, s2sz), s1[s2len] - s2[s2len] , -1, "expected %d got %d\n"); + assert_positive_return(strncmp(s1, s2, s1len), -1, "\n"); + assert_equal_return(strncmp(s1, s2, s2len), s1[s2len-1] - s2[s2len-1] , -1, "expected %d got %d\n"); + assert_negative_return(strncmp(s2, s1, s1sz), -1, "\n"); + assert_equal_return(strncmp(s2, s1, s1sz), s2[s2len] - s1[s2len] , -1, "expected %d got %d\n"); + + assert_zero_return(strncmp(s1, s2, s2len), -1, "\n"); + assert_positive_return(strncmp(s1, s2, s2sz), -1, "\n"); + assert_equal_return(strncmp(s1, s2, s2sz), s1[s2len] - s2[s2len] , -1, "expected %d got %d\n"); + + assert_negative_return(strncmp(s2, s3, s2sz), -1, "\n"); + assert_equal_return(strncmp(s2, s3, s2sz), s2[s2len-1] - s3[s2len-1] , -1, "expected %d got %d\n"); + assert_equal_return(strncmp(s2, s3, s2len), s2[s2len-1] - s3[s2len-1] , -1, "expected %d got %d\n"); + assert_negative_return(strncmp(s2, s3, s2len), -1, "\n"); + assert_zero_return(strncmp(s2, s3, s2len - 1), -1, "\n"); + assert_false_return(strncmp(s1, s2, s2len), -1, "\n"); + + /* + * Now test gnu-efi's version, but with a cast back to a sane type + */ +#define strncmpa(a, b, c) ((INTN)strncmpa(a, b, c)) + + assert_zero_return(strncmpa(s0, s0, s0len), -1, "\n"); + assert_zero_return(strncmpa(s0, s0, s0sz), -1, "\n"); + + assert_zero_return(strncmpa(s0, s1, s0len), -1, "\n"); + assert_negative_return(strncmpa(s0, s1, s0sz), -1, "\n"); + assert_equal_return(strncmpa(s0, s1, s0sz), s0[s0len] - s1[s0len] , -1, "expected %d got %d\n"); + assert_positive_return(strncmpa(s1, s0, s0sz), -1, "\n"); + assert_equal_return(strncmpa(s1, s0, s0sz), s1[s0len] - s0[s0len] , -1, "expected %d got %d\n"); + + assert_positive_return(strncmpa(s1, s2, s1sz), -1, "\n"); + assert_equal_return(strncmpa(s1, s2, s2sz), s1[s2len] - s2[s2len] , -1, "expected %d got %d\n"); + assert_positive_return(strncmpa(s1, s2, s1len), -1, "\n"); + assert_equal_return(strncmpa(s1, s2, s2len), s1[s2len-1] - s2[s2len-1] , -1, "expected %d got %d\n"); + assert_negative_return(strncmpa(s2, s1, s1sz), -1, "\n"); + assert_equal_return(strncmpa(s2, s1, s1sz), s2[s2len] - s1[s2len] , -1, "expected %d got %d\n"); + + assert_zero_return(strncmpa(s1, s2, s2len), -1, "\n"); + assert_positive_return(strncmpa(s1, s2, s2sz), -1, "\n"); + assert_equal_return(strncmpa(s1, s2, s2sz), s1[s2len] - s2[s2len] , -1, "expected %d got %d\n"); + + assert_negative_return(strncmpa(s2, s3, s2sz), -1, "\n"); + assert_equal_return(strncmpa(s2, s3, s2sz), s2[s2len-1] - s3[s2len-1] , -1, "expected %d got %d\n"); + assert_equal_return(strncmpa(s2, s3, s2len), s2[s2len-1] - s3[s2len-1] , -1, "expected %d got %d\n"); + assert_negative_return(strncmpa(s2, s3, s2len), -1, "\n"); + assert_zero_return(strncmpa(s2, s3, s2len - 1), -1, "\n"); + assert_false_return(strncmpa(s1, s2, s2len), -1, "\n"); + + + /* + * Once more, but with the casting /and the warnings/ turned off + * + * The ones marked with XXX I've inverted the test to make it work + * "correctly", because UINTN is what makes positive. + */ +#undef strncmpa +#pragma GCC diagnostic ignored "-Wtype-limits" +#pragma GCC diagnostic ignored "-Wsign-compare" + + assert_zero_return(strncmpa(s0, s0, s0len), -1, "\n"); + assert_zero_return(strncmpa(s0, s0, s0sz), -1, "\n"); + + assert_zero_return(strncmpa(s0, s1, s0len), -1, "\n"); + /*XXX*/assert_positive_return(strncmpa(s0, s1, s0sz), -1, "\n");/*XXX*/ + assert_equal_return(strncmpa(s0, s1, s0sz), s0[s0len] - s1[s0len] , -1, "expected %d got %d\n"); + assert_positive_return(strncmpa(s1, s0, s0sz), -1, "\n"); + assert_equal_return(strncmpa(s1, s0, s0sz), s1[s0len] - s0[s0len] , -1, "expected %d got %d\n"); + + assert_positive_return(strncmpa(s1, s2, s1sz), -1, "\n"); + assert_equal_return(strncmpa(s1, s2, s2sz), s1[s2len] - s2[s2len] , -1, "expected %d got %d\n"); + assert_positive_return(strncmpa(s1, s2, s1len), -1, "\n"); + assert_equal_return(strncmpa(s1, s2, s2len), s1[s2len-1] - s2[s2len-1] , -1, "expected %d got %d\n"); + /*XXX*/ assert_positive_return(strncmpa(s2, s1, s1sz), -1, "\n");/*XXX*/ + assert_equal_return(strncmpa(s2, s1, s1sz), s2[s2len] - s1[s2len] , -1, "expected %d got %d\n"); + + assert_zero_return(strncmpa(s1, s2, s2len), -1, "\n"); + assert_positive_return(strncmpa(s1, s2, s2sz), -1, "\n"); + assert_equal_return(strncmpa(s1, s2, s2sz), s1[s2len] - s2[s2len] , -1, "expected %d got %d\n"); + + assert_positive_return(strncmpa(s2, s3, s2sz), -1, "\n"); + assert_equal_return(strncmpa(s2, s3, s2sz), s2[s2len-1] - s3[s2len-1] , -1, "expected %d got %d\n"); + assert_equal_return(strncmpa(s2, s3, s2len), s2[s2len-1] - s3[s2len-1] , -1, "expected %d got %d\n"); + /*XXX*/assert_positive_return(strncmpa(s2, s3, s2len), -1,"\n");/*XXX*/ + assert_zero_return(strncmpa(s2, s3, s2len - 1), -1, "\n"); + assert_false_return(strncmpa(s1, s2, s2len), -1, "\n"); + +#pragma GCC diagnostic error "-Wsign-compare" +#pragma GCC diagnostic error "-Wtype-limits" + return 0; + +#undef s0 +#undef s0sz +#undef s0len +#undef s1 +#undef s1sz +#undef s1len +#undef s2 +#undef s2sz +#undef s2len +#undef s3 +#undef s3sz +#undef s3len +} + +int test_strntoken_null(void) { bool ret; char *token = NULL; @@ -416,6 +577,7 @@ main(void) { int status = 0; test(test_strchrnul); + test(test_strncmp); test(test_strntoken_null); test(test_strntoken_size_0); test(test_strntoken_empty_size_1); |
