1// SPDX-License-Identifier: GPL-2.1+ 2/* 3 * Copyright (C) 2021 Sean Anderson <seanga2@gmail.com> 4 * Copyright (C) 2011-2021 Free Software Foundation, Inc. 5 * 6 * These tests adapted from glibc's string/test-strncat.c 7 */ 8 9#include <common.h> 10#include <test/lib.h> 11#include <test/test.h> 12#include <test/ut.h> 13 14#define BUF_SIZE 4096 15char buf1[BUF_SIZE], buf2[BUF_SIZE]; 16 17static int do_test_strlcat(struct unit_test_state *uts, int line, size_t align1, 18 size_t align2, size_t len1, size_t len2, size_t n) 19{ 20 char *s1, *s2; 21 size_t i, len, expected, actual; 22 23 align1 &= 7; 24 if (align1 + len1 >= BUF_SIZE) 25 return 0; 26 if (align1 + n > BUF_SIZE) 27 return 0; 28 29 align2 &= 7; 30 if (align2 + len1 + len2 >= BUF_SIZE) 31 return 0; 32 if (align2 + len1 + n > BUF_SIZE) 33 return 0; 34 35 s1 = buf1 + align1; 36 s2 = buf2 + align2; 37 38 for (i = 0; i < len1 - 1; i++) 39 s1[i] = 32 + 23 * i % (127 - 32); 40 s1[len1 - 1] = '\0'; 41 42 for (i = 0; i < len2 - 1; i++) 43 s2[i] = 32 + 23 * i % (127 - 32); 44 s2[len2 - 1] = '\0'; 45 46 expected = min(strlen(s2), n) + strlen(s1); 47 actual = strlcat(s2, s1, n); 48 if (expected != actual) { 49 ut_failf(uts, __FILE__, line, __func__, 50 "strlcat(s2, s1, n) == min(len2, n) + len1", 51 "Expected %#zx (%zd), got %#zx (%zd)", 52 expected, expected, actual, actual); 53 return CMD_RET_FAILURE; 54 } 55 56 len = min3(len1, n - len2, (size_t)0); 57 if (memcmp(s2 + len2, s1, len)) { 58 ut_failf(uts, __FILE__, line, __func__, 59 "s2 + len1 == s1", 60 "Expected \"%.*s\", got \"%.*s\"", 61 (int)len, s1, (int)len, s2 + len2); 62 return CMD_RET_FAILURE; 63 } 64 65 i = min(n, len1 + len2 - 1) - 1; 66 if (len2 < n && s2[i] != '\0') { 67 ut_failf(uts, __FILE__, line, __func__, 68 "n < len1 && s2[len2 + n] == '\\0'", 69 "Expected s2[%zd] = '\\0', got %d ('%c')", 70 i, s2[i], s2[i]); 71 return CMD_RET_FAILURE; 72 } 73 74 return 0; 75} 76 77#define test_strlcat(align1, align2, len1, len2, n) do { \ 78 int ret = do_test_strlcat(uts, __LINE__, align1, align2, len1, len2, \ 79 n); \ 80 if (ret) \ 81 return ret; \ 82} while (0) 83 84static int lib_test_strlcat(struct unit_test_state *uts) 85{ 86 size_t i, n; 87 88 test_strlcat(0, 2, 2, 2, SIZE_MAX); 89 test_strlcat(0, 0, 4, 4, SIZE_MAX); 90 test_strlcat(4, 0, 4, 4, SIZE_MAX); 91 test_strlcat(0, 0, 8, 8, SIZE_MAX); 92 test_strlcat(0, 8, 8, 8, SIZE_MAX); 93 94 for (i = 1; i < 8; i++) { 95 test_strlcat(0, 0, 8 << i, 8 << i, SIZE_MAX); 96 test_strlcat(8 - i, 2 * i, 8 << i, 8 << i, SIZE_MAX); 97 test_strlcat(0, 0, 8 << i, 2 << i, SIZE_MAX); 98 test_strlcat(8 - i, 2 * i, 8 << i, 2 << i, SIZE_MAX); 99 100 test_strlcat(i, 2 * i, 8 << i, 1, SIZE_MAX); 101 test_strlcat(2 * i, i, 8 << i, 1, SIZE_MAX); 102 test_strlcat(i, i, 8 << i, 10, SIZE_MAX); 103 } 104 105 for (n = 2; n <= 2048; n *= 4) { 106 test_strlcat(0, 2, 2, 2, n); 107 test_strlcat(0, 0, 4, 4, n); 108 test_strlcat(4, 0, 4, 4, n); 109 test_strlcat(0, 0, 8, 8, n); 110 test_strlcat(0, 8, 8, 8, n); 111 112 for (i = 1; i < 8; i++) { 113 test_strlcat(0, 0, 8 << i, 8 << i, n); 114 test_strlcat(8 - i, 2 * i, 8 << i, 8 << i, n); 115 test_strlcat(0, 0, 8 << i, 2 << i, n); 116 test_strlcat(8 - i, 2 * i, 8 << i, 2 << i, n); 117 118 test_strlcat(i, 2 * i, 8 << i, 1, n); 119 test_strlcat(2 * i, i, 8 << i, 1, n); 120 test_strlcat(i, i, 8 << i, 10, n); 121 } 122 } 123 124 return 0; 125} 126LIB_TEST(lib_test_strlcat, 0); 127