diff options
Diffstat (limited to 'test-str.c')
| -rw-r--r-- | test-str.c | 911 |
1 files changed, 837 insertions, 74 deletions
@@ -2,6 +2,9 @@ /* * test-str.c - test our string functions. */ +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic error "-Wnonnull" +#pragma GCC diagnostic error "-Wunused-function" #ifndef SHIM_UNIT_TEST #define SHIM_UNIT_TEST @@ -10,43 +13,448 @@ #include <stdio.h> -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic error "-Wnonnull" - -int -test_strchrnul_helper(__typeof__(strchrnul) fn) +static int +test_strlen(void) { - const char s0[] = "abcd\0fghi"; + const char s1[] = "abcd"; + const char s2[] = ""; - assert_equal_return(fn(s0, 'a'), &s0[0], -1, "got %p expected %p\n"); - assert_equal_return(fn(s0, 'd'), &s0[3], -1, "got %p expected %p\n"); - assert_equal_return(fn(s0, '\000'), &s0[4], -1, "got %p expected %p\n"); - assert_equal_return(fn(s0, 'i'), &s0[4], -1, "got %p expected %p\n"); + assert_equal_return(shim_strlen(s1), 4, -1, "got %d expected %d\n"); + assert_equal_return(strlen(s1), 4, -1, "got %d expected %d\n"); + assert_equal_return(shim_strlen(s2), 0, -1, "got %d expected %d\n"); + assert_equal_return(strlen(s2), 0, -1, "got %d expected %d\n"); return 0; } -int -test_strchrnul(void) +static int +test_strnlen(void) { - const char s0[] = "abcd\0fghi"; + const char s1[] = "abcd"; + const char s2[] = ""; + + assert_equal_return(shim_strnlen(s1, 0), 0, -1, "got %d expected %d\n"); + assert_equal_return(strnlen(s1, 0), 0, -1, "got %d expected %d\n"); + assert_equal_return(shim_strnlen(s1, 1), 1, -1, "got %d expected %d\n"); + assert_equal_return(strnlen(s1, 1), 1, -1, "got %d expected %d\n"); + assert_equal_return(shim_strnlen(s1, 3), 3, -1, "got %d expected %d\n"); + assert_equal_return(strnlen(s1, 3), 3, -1, "got %d expected %d\n"); + assert_equal_return(shim_strnlen(s1, 4), 4, -1, "got %d expected %d\n"); + assert_equal_return(strnlen(s1, 4), 4, -1, "got %d expected %d\n"); + assert_equal_return(shim_strnlen(s1, 5), 4, -1, "got %d expected %d\n"); + assert_equal_return(strnlen(s1, 5), 4, -1, "got %d expected %d\n"); + assert_equal_return(shim_strnlen(s2, 0), 0, -1, "got %d expected %d\n"); + assert_equal_return(strnlen(s2, 0), 0, -1, "got %d expected %d\n"); + assert_equal_return(shim_strnlen(s2, 1), 0, -1, "got %d expected %d\n"); + assert_equal_return(strnlen(s2, 1), 0, -1, "got %d expected %d\n"); - assert_equal_return(test_strchrnul_helper(shim_strchrnul), - test_strchrnul_helper(strchrnul), - -1, "got %d expected %d\n"); + return 0; +} - 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"); - assert_equal_return(strnchrnul(s0, 2, 'b'), &s0[1], -1, "got %p expected %p\n"); - assert_equal_return(strnchrnul(s0, 4, 'f'), &s0[3], -1, "got %p expected %p\n"); - assert_equal_return(strnchrnul(s0, 5, 'f'), &s0[4], -1, "got %p expected %p\n"); - assert_equal_return(strnchrnul(s0, 8, 'f'), &s0[4], -1, "got %p expected %p\n"); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" - assert_equal_return(strnchrnul(&s0[4], 1, 'f'), &s0[4], -1, "got %p expected %p\n"); +/* + * 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 +#define s4 "sbat\314\234\014," +#define s4sz 9 +#define s4len 8 +/* + * same as s4 but with a UTF8 encoding error; one bit is cleared. + */ +#define s5 "sbat\314\034\014," +#define s5sz 9 +#define s5len 8 - return 0; +#define test_strcmp_helper(fn, invert_sign_errors, invert_encoding_errors) \ + ({ \ + printf("testing %s\n", #fn); \ + int status_ = 0, rc_; \ + \ + rc_ = assert_zero_as_expr(fn(s0, s0), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s0, s1), -1, "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s0, s1), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_positive_as_expr(fn(s1, s0), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + rc_ = assert_positive_as_expr(fn(s1, s2), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s2, s1), -1, "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s2, s1), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s2, s3), -1, "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s2, s3), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_positive_as_expr(fn(s3, s2), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (invert_encoding_errors) \ + rc_ = assert_negative_as_expr(fn(s4, s5), -1, "\n"); \ + else \ + rc_ = assert_positive_as_expr(fn(s4, s5), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (status_ < 0) \ + printf("%s failed\n", #fn); \ + status_; \ + }) + +static int +test_strcmp(void) +{ + int status = 0; + int rc; + + /* + * shim's strcmp + */ + rc = test_strcmp_helper(shim_strcmp, false, false); + status = MIN(rc, status); + + /* + * libc's strcmp + */ + rc = test_strcmp_helper(strcmp, false, false); + status = MIN(rc, status); + + return status; +} + +#undef s0 +#undef s0sz +#undef s0len +#undef s1 +#undef s1sz +#undef s1len +#undef s2 +#undef s2sz +#undef s2len +#undef s3 +#undef s3sz +#undef s3len +#undef s4 +#undef s4sz +#undef s4len +#undef s5 +#undef s5sz +#undef s5len + +/* + * 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 +#define s4 "sbat\314\234\014," +#define s4sz 9 +#define s4len 8 +/* + * same as s4 but with a UTF8 encoding error; one bit is cleared. + */ +#define s5 "sbat\314\034\014," +#define s5sz 9 +#define s5len 8 + +#define test_strcasecmp_helper(fn, invert_sign_errors, invert_encoding_errors) \ + ({ \ + printf("testing %s\n", #fn); \ + int status_ = 0, rc_; \ + \ + rc_ = assert_zero_as_expr(fn(s0, s0), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s0, s1), -1, "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s0, s1), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_positive_as_expr(fn(s1, s0), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + rc_ = assert_positive_as_expr(fn(s1, s2), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s2, s1), -1, "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s2, s1), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s2, s3), -1, "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s2, s3), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_positive_as_expr(fn(s3, s2), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (invert_encoding_errors) \ + rc_ = assert_negative_as_expr(fn(s4, s5), -1, "\n"); \ + else \ + rc_ = assert_positive_as_expr(fn(s4, s5), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (status_ < 0) \ + printf("%s failed\n", #fn); \ + status_; \ + }) + +static int +test_strcasecmp(void) +{ + int status = 0; + int rc; + + /* + * shim's strcasecmp + */ + rc = test_strcasecmp_helper(shim_strcasecmp, false, false); + status = MIN(rc, status); + + /* + * libc's strcasecmp + */ + rc = test_strcasecmp_helper(strcasecmp, false, false); + status = MIN(rc, status); + + return status; +} + +#undef s0 +#undef s0sz +#undef s0len +#undef s1 +#undef s1sz +#undef s1len +#undef s2 +#undef s2sz +#undef s2len +#undef s3 +#undef s3sz +#undef s3len +#undef s4 +#undef s4sz +#undef s4len +#undef s5 +#undef s5sz +#undef s5len + +/* + * 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 +#define s4 "sbat\314\234\014," +#define s4sz 9 +#define s4len 8 +/* + * same as s4 but with a UTF8 encoding error; one bit is cleared. + */ +#define s5 "sbat\314\034\014," +#define s5sz 9 +#define s5len 8 + +#define test_strncasecmp_helper(fn, test_cmp_magnitude, invert_sign_errors, \ + invert_encoding_errors) \ + ({ \ + printf("testing %s\n", #fn); \ + int status_ = 0, rc_; \ + \ + rc_ = assert_zero_as_expr(fn(s0, s0, s0len), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_zero_as_expr(fn(s0, s0, s0sz), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + rc_ = assert_zero_as_expr(fn(s0, s1, s0len), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s0, s1, s0sz), -1, \ + "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s0, s1, s0sz), -1, \ + "\n"); \ + status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s0, s1, s0sz), \ + s0[s0len] - s1[s0len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ + rc_ = assert_positive_as_expr(fn(s1, s0, s0sz), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s1, s0, s0sz), \ + s1[s0len] - s0[s0len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ + \ + rc_ = assert_positive_as_expr(fn(s1, s2, s1sz), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ + s1[s2len] - s2[s2len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ + rc_ = assert_positive_as_expr(fn(s1, s2, s1len), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr( \ + fn(s1, s2, s2len), \ + s1[s2len - 1] - s2[s2len - 1], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s2, s1, s1sz), -1, \ + "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s2, s1, s1sz), -1, \ + "\n"); \ + status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s2, s1, s1sz), \ + s2[s2len] - s1[s2len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ + \ + rc_ = assert_zero_as_expr(fn(s1, s2, s2len), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_positive_as_expr(fn(s1, s2, s2sz), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ + s1[s2len] - s2[s2len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ + \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s2, s3, s2sz), -1, \ + "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s2, s3, s2sz), -1, \ + "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_equal_as_expr(fn(s2, s3, s2sz), \ + s2[s2len - 1] - s3[s2len - 1], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_equal_as_expr(fn(s2, s3, s2len), \ + s2[s2len - 1] - s3[s2len - 1], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + if (invert_sign_errors) \ + rc_ = assert_positive_as_expr(fn(s2, s3, s2len), -1, \ + "\n"); \ + else \ + rc_ = assert_negative_as_expr(fn(s2, s3, s2len), -1, \ + "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_zero_as_expr(fn(s2, s3, s2len - 1), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_false_as_expr(fn(s1, s2, s2len), -1, "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (invert_encoding_errors) \ + rc_ = assert_negative_as_expr(fn(s4, s5, s4sz), -1, \ + "\n"); \ + else \ + rc_ = assert_positive_as_expr(fn(s4, s5, s4sz), -1, \ + "\n"); \ + status_ = MIN(status_, rc_); \ + \ + if (status_ < 0) \ + printf("%s failed\n", #fn); \ + status_; \ + }) + +static int +test_strncasecmp(void) +{ + int status = 0; + int rc; + + /* + * shim's strncasecmp + */ + rc = test_strncasecmp_helper(shim_strncasecmp, true, false, false); + status = MIN(rc, status); + + /* + * libc's strncasecmp + */ + rc = test_strncasecmp_helper(strncasecmp, false, false, false); + status = MIN(rc, status); + + return status; } +#undef s0 +#undef s0sz +#undef s0len +#undef s1 +#undef s1sz +#undef s1len +#undef s2 +#undef s2sz +#undef s2len +#undef s3 +#undef s3sz +#undef s3len +#undef s4 +#undef s4sz +#undef s4len +#undef s5 +#undef s5sz +#undef s5len + /* * copy-pasta from gnu-efi */ @@ -113,7 +521,6 @@ gnuefi_good_strncmp ( return len ? *s1 - *s2 : 0; } - /* * these are constants so that the failures are readable if you get * it wrong. @@ -140,7 +547,8 @@ gnuefi_good_strncmp ( #define s5sz 9 #define s5len 8 -#define test_strncmp_helper(fn, invert_sign_errors, invert_encoding_errors) \ +#define test_strncmp_helper(fn, test_cmp_magnitude, invert_sign_errors, \ + invert_encoding_errors) \ ({ \ printf("testing %s\n", #fn); \ int status_ = 0, rc_; \ @@ -159,29 +567,38 @@ gnuefi_good_strncmp ( rc_ = assert_negative_as_expr(fn(s0, s1, s0sz), -1, \ "\n"); \ status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s0, s1, s0sz), \ - s0[s0len] - s1[s0len], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s0, s1, s0sz), \ + s0[s0len] - s1[s0len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ rc_ = assert_positive_as_expr(fn(s1, s0, s0sz), -1, "\n"); \ status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s1, s0, s0sz), \ - s1[s0len] - s0[s0len], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s1, s0, s0sz), \ + s1[s0len] - s0[s0len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ \ rc_ = assert_positive_as_expr(fn(s1, s2, s1sz), -1, "\n"); \ status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ - s1[s2len] - s2[s2len], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ + s1[s2len] - s2[s2len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ rc_ = assert_positive_as_expr(fn(s1, s2, s1len), -1, "\n"); \ status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s1, s2, s2len), \ - s1[s2len - 1] - s2[s2len - 1], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr( \ + fn(s1, s2, s2len), \ + s1[s2len - 1] - s2[s2len - 1], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ if (invert_sign_errors) \ rc_ = assert_positive_as_expr(fn(s2, s1, s1sz), -1, \ "\n"); \ @@ -189,19 +606,23 @@ gnuefi_good_strncmp ( rc_ = assert_negative_as_expr(fn(s2, s1, s1sz), -1, \ "\n"); \ status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s2, s1, s1sz), \ - s2[s2len] - s1[s2len], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s2, s1, s1sz), \ + s2[s2len] - s1[s2len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ \ rc_ = assert_zero_as_expr(fn(s1, s2, s2len), -1, "\n"); \ status_ = MIN(status_, rc_); \ rc_ = assert_positive_as_expr(fn(s1, s2, s2sz), -1, "\n"); \ status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ - s1[s2len] - s2[s2len], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ + s1[s2len] - s2[s2len], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ \ if (invert_sign_errors) \ rc_ = assert_positive_as_expr(fn(s2, s3, s2sz), -1, \ @@ -210,14 +631,18 @@ gnuefi_good_strncmp ( rc_ = assert_negative_as_expr(fn(s2, s3, s2sz), -1, \ "\n"); \ status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s2, s3, s2sz), \ - s2[s2len - 1] - s3[s2len - 1], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ - rc_ = assert_equal_as_expr(fn(s2, s3, s2len), \ - s2[s2len - 1] - s3[s2len - 1], -1, \ - "expected %d got %d\n"); \ - status_ = MIN(status_, rc_); \ + if (test_cmp_magnitude) { \ + rc_ = assert_equal_as_expr( \ + fn(s2, s3, s2sz), \ + s2[s2len - 1] - s3[s2len - 1], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + rc_ = assert_equal_as_expr( \ + fn(s2, s3, s2len), \ + s2[s2len - 1] - s3[s2len - 1], -1, \ + "expected %d got %d\n"); \ + status_ = MIN(status_, rc_); \ + } \ if (invert_sign_errors) \ rc_ = assert_positive_as_expr(fn(s2, s3, s2len), -1, \ "\n"); \ @@ -243,7 +668,7 @@ gnuefi_good_strncmp ( status_; \ }) -int +static int test_strncmp(void) { int status = 0; @@ -252,36 +677,47 @@ test_strncmp(void) /* * shim's strncmp */ - rc = test_strncmp_helper(shim_strncmp, false, false); + rc = test_strncmp_helper(shim_strncmp, true, false, false); status = MIN(rc, status); /* * libc's strncmp */ - rc = test_strncmp_helper(strncmp, false, false); + /* + * Deliberately not testing the difference between these two + * comparisons for the symbol named "strncmp": + * strncmp("b", "a", 1) + * strncmp("c", "a", 1) + * glibc, shim_strncmp(), and even the gnuefi ones will give you 1 + * and 2, respectively, as will glibc's, but valgrind swaps in its + * own implementation, in case you're doing something that's both + * clever and dumb with the result, and it'll return 1 for both of + * them. + */ + rc = test_strncmp_helper(strncmp, false, false, false); status = MIN(rc, status); /* * gnu-efi's broken strncmpa */ +#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wtype-limits" #pragma GCC diagnostic ignored "-Wsign-compare" - rc = test_strncmp_helper(gnuefi_strncmp, true, false); + rc = test_strncmp_helper(gnuefi_strncmp, true, true, false); status = MIN(rc, status); -#pragma GCC diagnostic error "-Wsign-compare" -#pragma GCC diagnostic error "-Wtype-limits" +#pragma GCC diagnostic pop /* * gnu-efi's broken strncmpa with the return type fixed */ - rc = test_strncmp_helper(gnuefi_signed_strncmp, false, true); + rc = test_strncmp_helper(gnuefi_signed_strncmp, true, false, true); status = MIN(rc, status); /* * gnu-efi's strncmpa with the return type fixed and unsigned * comparisons internally */ - rc = test_strncmp_helper(gnuefi_good_strncmp, false, false); + rc = test_strncmp_helper(gnuefi_good_strncmp, true, false, false); status = MIN(rc, status); return status; @@ -299,8 +735,322 @@ test_strncmp(void) #undef s3 #undef s3sz #undef s3len +#undef s4 +#undef s4sz +#undef s4len +#undef s5 +#undef s5sz +#undef s5len -int +/* + * Put -Wshadow back how it was + */ +#pragma GCC diagnostic pop + +static int +test_strchr(void) +{ + char s0[] = "abcbdbeb\0fbgb"; + + assert_equal_return(strchr(s0, 'a'), s0, -1, "got %p expected %p\n"); + assert_equal_return(strchr(s0, 'b'), &s0[1], -1, "got %p expected %p\n"); + assert_equal_return(strchr(&s0[1], 'b'), &s0[1], -1, "got %p expected %p\n"); + assert_equal_return(strchr(&s0[2], 'b'), &s0[3], -1, "got %p expected %p\n"); + assert_equal_return(strchr(&s0[4], 'b'), &s0[5], -1, "got %p expected %p\n"); + assert_equal_return(strchr(&s0[6], 'b'), &s0[7], -1, "got %p expected %p\n"); + assert_equal_return(strchr(&s0[8], 'b'), NULL, -1, "got %p expected %p\n"); + + assert_equal_return(shim_strchr(s0, 'a'), s0, -1, "got %p expected %p\n"); + assert_equal_return(shim_strchr(s0, 'b'), &s0[1], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchr(&s0[1], 'b'), &s0[1], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchr(&s0[2], 'b'), &s0[3], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchr(&s0[4], 'b'), &s0[5], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchr(&s0[6], 'b'), &s0[7], -1, "got %p expected %p\n"); + assert_equal_return(shim_strchr(&s0[8], 'b'), NULL, -1, "got %p expected %p\n"); + return 0; +} + +static int +test_stpcpy(void) +{ + char s0[] = "0123456789abcdef"; + char s1[] = "xxxxxxxxxxxxxxxx"; + char *s; + + s0[0xa] = 0; + assert_equal_return(stpcpy(s1, s0), &s1[0xa], -1, "got %p expected %p\n"); + assert_zero_return(memcmp(s0, s1, 11), -1, "\n"); + assert_zero_return(memcmp(&s1[11], "xxxxx", sizeof("xxxxx")), -1, "\n"); + + memset(s1, 'x', sizeof(s1)); + s1[16] = 0; + assert_equal_return(shim_stpcpy(s1, s0), &s1[0xa], -1, "got %p expected %p\n"); + assert_zero_return(memcmp(s0, s1, 11), -1, "\n"); + assert_zero_return(memcmp(&s1[11], "xxxxx", sizeof("xxxxx")), -1, "\n"); + + return 0; +} + +static int +test_strdup(void) +{ + char s0[] = "0123456789abcdef"; + char *s = NULL; + + s = strdup(s0); + assert_equal_goto(strcmp(s0, s), 0, err, "\n"); + free(s); + + s = shim_strdup(s0); + assert_equal_goto(strcmp(s0, s), 0, err, "\n"); + free(s); + + return 0; +err: + if (s) + free(s); + return -1; +} + +static int +test_strndup(void) +{ + char s0[] = "0123456789abcdef"; + char *s = NULL; + + s = strndup(s0, 18); + assert_equal_goto(strcmp(s0, s), 0, err, "\n"); + free(s); + s = strndup(s0, 15); + assert_positive_goto(strcmp(s0, s), err, "\n"); + free(s); + + s = shim_strndup(s0, 18); + assert_equal_goto(strcmp(s0, s), 0, err, "\n"); + free(s); + s = strndup(s0, 15); + assert_positive_goto(shim_strcmp(s0, s), err, "\n"); + free(s); + + return 0; +err: + if (s) + free(s); + return -1; +} + +static int +test_strchrnul_helper(__typeof__(strchrnul) fn) +{ + const char s0[] = "abcd\0fghi"; + + assert_equal_return(fn(s0, 'a'), &s0[0], -1, "got %p expected %p\n"); + assert_equal_return(fn(s0, 'd'), &s0[3], -1, "got %p expected %p\n"); + assert_equal_return(fn(s0, '\000'), &s0[4], -1, "got %p expected %p\n"); + assert_equal_return(fn(s0, 'i'), &s0[4], -1, "got %p expected %p\n"); + + return 0; +} + +static int +test_strchrnul(void) +{ + const char s0[] = "abcd\0fghi"; + + assert_equal_return(test_strchrnul_helper(shim_strchrnul), + test_strchrnul_helper(strchrnul), + -1, "got %d expected %d\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"); + assert_equal_return(strnchrnul(s0, 2, 'b'), &s0[1], -1, "got %p expected %p\n"); + assert_equal_return(strnchrnul(s0, 4, 'f'), &s0[3], -1, "got %p expected %p\n"); + assert_equal_return(strnchrnul(s0, 5, 'f'), &s0[4], -1, "got %p expected %p\n"); + assert_equal_return(strnchrnul(s0, 8, 'f'), &s0[4], -1, "got %p expected %p\n"); + + assert_equal_return(strnchrnul(&s0[4], 1, 'f'), &s0[4], -1, "got %p expected %p\n"); + + return 0; +} + +static int +test_strrchr(void) { + char s0[] = "abcbebfb"; + + assert_equal_return(shim_strrchr(s0, '\n'), NULL, -1, "got %p expected %p\n"); + assert_equal_return(strrchr(s0, '\n'), NULL, -1, "got %p expected %p\n"); + assert_equal_return(shim_strrchr(s0, 'b'), &s0[7], -1, "got %p expected %p\n"); + assert_equal_return(strrchr(s0, 'b'), &s0[7], -1, "got %p expected %p\n"); + assert_equal_return(shim_strrchr(s0, 'c'), &s0[2], -1, "got %p expected %p\n"); + assert_equal_return(strrchr(s0, 'c'), &s0[2], -1, "got %p expected %p\n"); + + return 0; +} + +static int +test_strcpy(void) +{ + char s0[] = "0123456789abcdef\0000"; + char s1[sizeof(s0)]; + + memset(s1, 0, sizeof(s1)); + assert_equal_return(strcpy(s1, s0), s1, -1, "got %p expected %p\n"); + assert_equal_return(strlen(s0), strlen(s1), -1, "got %d expected %d\n"); + + memset(s1, 0, sizeof(s1)); + assert_equal_return(shim_strcpy(s1, s0), s1, -1, "got %p expected %p\n"); + assert_equal_return(strlen(s0), strlen(s1), -1, "got %d expected %d\n"); + + memset(s1, 0, sizeof(s1)); + assert_equal_return(shim_strcpy(s1, s0), s1, -1, "got %p expected %p\n"); + assert_equal_return(strlen(s0), strlen(s1), -1, "got %d expected %d\n"); + + return 0; +} + +static int +test_strncpy(void) +{ + char s[] = "0123456789abcdef\0000"; + char s0[4096+4096]; + char *s1 = &s0[4096]; + + memset(s0, 0, sizeof(s0)); + memcpy(s0, s, sizeof(s)); + + memset(s1, 0, 4096); + assert_equal_return(strncpy(s1, s0, 0), s1, -1, "got %p expected %p\n"); + assert_equal_return(strlen(s1), 0, -1, "got %d expected %d\n"); + memset(s1, 0, 4096); + assert_equal_return(shim_strncpy(s1, s0, 0), s1, -1, "got %p expected %p\n"); + assert_equal_return(strlen(s1), 0, -1, "got %d expected %d\n"); + + memset(s1, 0, 4096); + assert_equal_return(strncpy(s1, s0, 1), s1, -1, "got %p expected %p\n"); + assert_equal_return(strlen(s1), 1, -1, "got %d expected %d\n"); + assert_equal_return(s1[0], s0[0], -1, "got %#02hhx, expected %#02hhx\n"); + assert_equal_return(s0[1], '1', -1, "got %#02hhx, expected %#02hhx\n"); + assert_equal_return(s1[1], '\0', -1, "got %#02hhx, expected %#02hhx\n"); + memset(s1, 0, 4096); + assert_equal_return(shim_strncpy(s1, s0, 1), s1, -1, "got %p expected %p\n"); + assert_equal_return(strlen(s1), 1, -1, "got %d expected %d\n"); + assert_equal_return(s1[0], s0[0], -1, "got %#02hhx, expected %#02hhx\n"); + assert_equal_return(s0[1], '1', -1, "got %#02hhx, expected %#02hhx\n"); + assert_equal_return(s1[1], '\0', -1, "got %#02hhx, expected %#02hhx\n"); + + memset(s1, 0, 4096); + assert_equal_return(strncpy(s1, s0, 15), s1, -1, "got %p expected %p\n"); + assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[15], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + memset(s1, 0, 4096); + assert_equal_return(shim_strncpy(s1, s0, 15), s1, -1, "got %p expected %p\n"); + assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[15], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + + memset(s1, 0, 4096); + assert_equal_return(strncpy(s1, s0, 16), s1, -1, "got %p expected %p\n"); + assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + memset(s1, 0, 4096); + assert_equal_return(shim_strncpy(s1, s0, 16), s1, -1, "got %p expected %p\n"); + assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + + memset(s1, 0, 4096); + s1[17] = '0'; + s1[18] = '1'; + assert_equal_return(strncpy(s1, s0, 4096), s1, -1, "got %p expected %p\n"); + assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + memset(s1, 0, 4096); + s1[17] = '0'; + s1[18] = '1'; + assert_equal_return(shim_strncpy(s1, s0, 4096), s1, -1, "got %p expected %p\n"); + assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[17], '0', -1, "got %#02hhx expected %02hhx\n"); + assert_equal_return(s1[18], '1', -1, "got %#02hhx expected %02hhx\n"); + + return 0; +} + +static int +test_strcat(void) +{ + char s[] = "0123456789abcdef\0000"; + char s0[8192]; + char *s1 = &s0[4096]; + char *s2; + char s3[] = "0123456789abcdef0123456789abcdef\000\000\000\000\000"; + + memset(s0, 0, 8192); + memcpy(s0, s, sizeof(s)); + + memset(s1, 0, 4096); + assert_equal_return(strcat(s1, s0), s1, -1, "got %p expected %p\n"); + assert_zero_return(strncmp(s1, s0, sizeof(s)-1), 0, -1, "\n"); + assert_negative_return(memcmp(s1, s0, sizeof(s)), 0, -1, "\n"); + + memset(s1, 0, 4096); + assert_equal_return(strcat(s1, s0), s1, -1, "got %p expected %p\n"); + s2 = s1 + strlen(s1); + assert_equal_return(s2, &s1[16], -1, "got %p expected %p\n"); + assert_equal_return(strcat(s2, s0), s2, -1, "got %p expected %p\n"); + assert_zero_return(strncmp(s1, s0, strlen(s)), -1, "got %p expected %p\n"); + assert_zero_return(strncmp(s2, s0, 2*(sizeof(s)-1)), -1, "\n"); + assert_positive_return(memcmp(s1, s0, 2*sizeof(s)-2), -1, "\n"); + assert_equal_return(memcmp(s1, s3, sizeof(s3)), 0, -1, "expected %d got %d\n"); + + return 0; +} + +static int test_strntoken_null(void) { bool ret; char *token = NULL; @@ -314,7 +1064,7 @@ test_strntoken_null(void) { return 0; } -int +static int test_strntoken_size_0(void) { const char s1[] = "abc,def,.,gh,"; @@ -334,7 +1084,7 @@ test_strntoken_size_0(void) return 0; } -int +static int test_strntoken_empty_size_1(void) { char s1[] = ""; @@ -367,7 +1117,7 @@ test_strntoken_empty_size_1(void) return 0; } -int +static int test_strntoken_size_1(void) { char s1[] = ","; @@ -401,7 +1151,7 @@ test_strntoken_size_1(void) return 0; } -int +static int test_strntoken_size_2(void) { char s1[] = ","; @@ -444,7 +1194,7 @@ test_strntoken_size_2(void) return 0; } -int +static int test_strntoken_no_ascii_nul(void) { const char s1[] = "abc,def,.,gh,"; @@ -557,7 +1307,7 @@ test_strntoken_no_ascii_nul(void) return 0; } -int +static int test_strntoken_with_ascii_nul(void) { const char s1[] = "abc,def,.,gh,"; @@ -680,8 +1430,21 @@ int main(void) { int status = 0; - test(test_strchrnul); + test(test_strlen); + test(test_strnlen); + test(test_strcmp); test(test_strncmp); + test(test_strcasecmp); + test(test_strncasecmp); + test(test_strrchr); + test(test_strcpy); + test(test_strncpy); + test(test_strcat); + test(test_stpcpy); + test(test_strdup); + test(test_strndup); + test(test_strchr); + test(test_strchrnul); test(test_strntoken_null); test(test_strntoken_size_0); test(test_strntoken_empty_size_1); |
