summaryrefslogtreecommitdiff
path: root/test-str.c
diff options
context:
space:
mode:
Diffstat (limited to 'test-str.c')
-rw-r--r--test-str.c911
1 files changed, 837 insertions, 74 deletions
diff --git a/test-str.c b/test-str.c
index deb753d9..d0d6832b 100644
--- a/test-str.c
+++ b/test-str.c
@@ -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);