1 /*- 2 * Copyright (c) 2011 Tim Kientzle 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 #include "test.h" 26 __FBSDID("$FreeBSD$"); 27 28 #define __LIBARCHIVE_TEST 29 #include "archive_string.h" 30 31 #define EXTENT 32 32 33 #define assertStringSizes(strlen, buflen, as) \ 34 assertEqualInt(strlen, (as).length); \ 35 assertEqualInt(buflen, (as).buffer_length); 36 37 #define assertExactString(strlen, buflen, data, as) \ 38 do { \ 39 assertStringSizes(strlen, buflen, as); \ 40 assertEqualString(data, (as).s); \ 41 } while (0) 42 43 #define assertNonNULLString(strlen, buflen, as) \ 44 do { \ 45 assertStringSizes(strlen, buflen, as); \ 46 assert(NULL != (as).s); \ 47 } while (0) 48 49 static void 50 test_archive_string_ensure(void) 51 { 52 struct archive_string s; 53 54 archive_string_init(&s); 55 assertExactString(0, 0, NULL, s); 56 57 /* single-extent allocation */ 58 assert(&s == archive_string_ensure(&s, 5)); 59 assertNonNULLString(0, EXTENT, s); 60 61 /* what happens around extent boundaries? */ 62 assert(&s == archive_string_ensure(&s, EXTENT - 1)); 63 assertNonNULLString(0, EXTENT, s); 64 65 assert(&s == archive_string_ensure(&s, EXTENT)); 66 assertNonNULLString(0, EXTENT, s); 67 68 assert(&s == archive_string_ensure(&s, EXTENT + 1)); 69 assertNonNULLString(0, 2 * EXTENT, s); 70 } 71 72 static void 73 test_archive_strcat(void) 74 { 75 struct archive_string s; 76 77 archive_string_init(&s); 78 assertExactString(0, 0, NULL, s); 79 80 /* null target, empty source */ 81 assert(&s == archive_strcat(&s, "")); 82 assertExactString(0, EXTENT, "", s); 83 84 /* empty target, empty source */ 85 assert(&s == archive_strcat(&s, "")); 86 assertExactString(0, EXTENT, "", s); 87 88 /* empty target, non-empty source */ 89 assert(&s == archive_strcat(&s, "fubar")); 90 assertExactString(5, EXTENT, "fubar", s); 91 92 /* non-empty target, non-empty source */ 93 assert(&s == archive_strcat(&s, "baz")); 94 assertExactString(8, EXTENT, "fubarbaz", s); 95 } 96 97 static void 98 test_archive_strappend_char(void) 99 { 100 struct archive_string s; 101 102 archive_string_init(&s); 103 assertExactString(0, 0, NULL, s); 104 105 /* null target */ 106 archive_strappend_char(&s, 'X'); 107 assertExactString(1, EXTENT, "X", s); 108 109 /* non-empty target */ 110 archive_strappend_char(&s, 'Y'); 111 assertExactString(2, EXTENT, "XY", s); 112 } 113 114 /* archive_strnXXX() tests focus on length handling. 115 * other behaviors are tested by proxy through archive_strXXX() 116 */ 117 118 static void 119 test_archive_strncat(void) 120 { 121 struct archive_string s; 122 123 archive_string_init(&s); 124 assertExactString(0, 0, NULL, s); 125 126 /* perfect length */ 127 assert(&s == archive_strncat(&s, "snafu", 5)); 128 assertExactString(5, EXTENT, "snafu", s); 129 130 /* short read */ 131 assert(&s == archive_strncat(&s, "barbazqux", 3)); 132 assertExactString(8, EXTENT, "snafubar", s); 133 134 /* long read is ok too! */ 135 assert(&s == archive_strncat(&s, "snafu", 8)); 136 assertExactString(13, EXTENT, "snafubarsnafu", s); 137 } 138 139 static void 140 test_archive_strncpy(void) 141 { 142 struct archive_string s; 143 144 archive_string_init(&s); 145 assertExactString(0, 0, NULL, s); 146 147 /* perfect length */ 148 assert(&s == archive_strncpy(&s, "fubar", 5)); 149 assertExactString(5, EXTENT, "fubar", s); 150 151 /* short read */ 152 assert(&s == archive_strncpy(&s, "snafubar", 5)); 153 assertExactString(5, EXTENT, "snafu", s); 154 155 /* long read is ok too! */ 156 assert(&s == archive_strncpy(&s, "snafu", 8)); 157 assertExactString(5, EXTENT, "snafu", s); 158 } 159 160 static void 161 test_archive_strcpy(void) 162 { 163 struct archive_string s; 164 165 archive_string_init(&s); 166 assertExactString(0, 0, NULL, s); 167 168 /* null target */ 169 assert(&s == archive_strcpy(&s, "snafu")); 170 assertExactString(5, EXTENT, "snafu", s); 171 172 /* dirty target */ 173 assert(&s == archive_strcpy(&s, "foo")); 174 assertExactString(3, EXTENT, "foo", s); 175 176 /* dirty target, empty source */ 177 assert(&s == archive_strcpy(&s, "")); 178 assertExactString(0, EXTENT, "", s); 179 } 180 181 static void 182 test_archive_string_concat(void) 183 { 184 struct archive_string s, t, u, v; 185 186 archive_string_init(&s); 187 assertExactString(0, 0, NULL, s); 188 archive_string_init(&t); 189 assertExactString(0, 0, NULL, t); 190 archive_string_init(&u); 191 assertExactString(0, 0, NULL, u); 192 archive_string_init(&v); 193 assertExactString(0, 0, NULL, v); 194 195 /* null target, null source */ 196 archive_string_concat(&t, &s); 197 assertExactString(0, 0, NULL, s); 198 assertExactString(0, EXTENT, "", t); 199 200 /* null target, empty source */ 201 assert(&s == archive_strcpy(&s, "")); 202 archive_string_concat(&u, &s); 203 assertExactString(0, EXTENT, "", s); 204 assertExactString(0, EXTENT, "", u); 205 206 /* null target, non-empty source */ 207 assert(&s == archive_strcpy(&s, "foo")); 208 archive_string_concat(&v, &s); 209 assertExactString(3, EXTENT, "foo", s); 210 assertExactString(3, EXTENT, "foo", v); 211 212 /* empty target, empty source */ 213 assert(&s == archive_strcpy(&s, "")); 214 assert(&t == archive_strcpy(&t, "")); 215 archive_string_concat(&t, &s); 216 assertExactString(0, EXTENT, "", s); 217 assertExactString(0, EXTENT, "", t); 218 219 /* empty target, non-empty source */ 220 assert(&s == archive_strcpy(&s, "snafu")); 221 assert(&t == archive_strcpy(&t, "")); 222 archive_string_concat(&t, &s); 223 assertExactString(5, EXTENT, "snafu", s); 224 assertExactString(5, EXTENT, "snafu", t); 225 } 226 227 static void 228 test_archive_string_copy(void) 229 { 230 struct archive_string s, t, u, v; 231 232 archive_string_init(&s); 233 assertExactString(0, 0, NULL, s); 234 archive_string_init(&t); 235 assertExactString(0, 0, NULL, t); 236 archive_string_init(&u); 237 assertExactString(0, 0, NULL, u); 238 archive_string_init(&v); 239 assertExactString(0, 0, NULL, v); 240 241 /* null target, null source */ 242 archive_string_copy(&t, &s); 243 assertExactString(0, 0, NULL, s); 244 assertExactString(0, EXTENT, "", t); 245 246 /* null target, empty source */ 247 archive_string_copy(&u, &t); 248 assertExactString(0, EXTENT, "", t); 249 assertExactString(0, EXTENT, "", u); 250 251 /* empty target, empty source */ 252 archive_string_copy(&u, &t); 253 assertExactString(0, EXTENT, "", t); 254 assertExactString(0, EXTENT, "", u); 255 256 /* null target, non-empty source */ 257 assert(NULL != archive_strcpy(&s, "snafubar")); 258 assertExactString(8, EXTENT, "snafubar", s); 259 260 archive_string_copy(&v, &s); 261 assertExactString(8, EXTENT, "snafubar", s); 262 assertExactString(8, EXTENT, "snafubar", v); 263 264 /* empty target, non-empty source */ 265 assertExactString(0, EXTENT, "", t); 266 archive_string_copy(&t, &s); 267 assertExactString(8, EXTENT, "snafubar", s); 268 assertExactString(8, EXTENT, "snafubar", t); 269 270 /* non-empty target, non-empty source */ 271 assert(NULL != archive_strcpy(&s, "fubar")); 272 assertExactString(5, EXTENT, "fubar", s); 273 274 archive_string_copy(&t, &s); 275 assertExactString(5, EXTENT, "fubar", s); 276 assertExactString(5, EXTENT, "fubar", t); 277 } 278 279 static void 280 test_archive_string_sprintf(void) 281 { 282 struct archive_string s; 283 #define S16 "0123456789abcdef" 284 #define S32 S16 S16 285 #define S64 S32 S32 286 #define S128 S64 S64 287 const char *s32 = S32; 288 const char *s33 = S32 "0"; 289 const char *s64 = S64; 290 const char *s65 = S64 "0"; 291 const char *s128 = S128; 292 const char *s129 = S128 "0"; 293 #undef S16 294 #undef S32 295 #undef S64 296 #undef S128 297 298 archive_string_init(&s); 299 assertExactString(0, 0, NULL, s); 300 301 archive_string_sprintf(&s, "%s", ""); 302 assertExactString(0, 2 * EXTENT, "", s); 303 304 archive_string_empty(&s); 305 archive_string_sprintf(&s, "%s", s32); 306 assertExactString(32, 2 * EXTENT, s32, s); 307 308 archive_string_empty(&s); 309 archive_string_sprintf(&s, "%s", s33); 310 assertExactString(33, 2 * EXTENT, s33, s); 311 312 archive_string_empty(&s); 313 archive_string_sprintf(&s, "%s", s64); 314 assertExactString(64, 4 * EXTENT, s64, s); 315 316 archive_string_empty(&s); 317 archive_string_sprintf(&s, "%s", s65); 318 assertExactString(65, 4 * EXTENT, s65, s); 319 320 archive_string_empty(&s); 321 archive_string_sprintf(&s, "%s", s128); 322 assertExactString(128, 8 * EXTENT, s128, s); 323 324 archive_string_empty(&s); 325 archive_string_sprintf(&s, "%s", s129); 326 assertExactString(129, 8 * EXTENT, s129, s); 327 328 archive_string_empty(&s); 329 archive_string_sprintf(&s, "%d", 1234567890); 330 assertExactString(10, 8 * EXTENT, "1234567890", s); 331 } 332 333 DEFINE_TEST(test_archive_string) 334 { 335 test_archive_string_ensure(); 336 test_archive_strcat(); 337 test_archive_strappend_char(); 338 test_archive_strncat(); 339 test_archive_strncpy(); 340 test_archive_strcpy(); 341 test_archive_string_concat(); 342 test_archive_string_copy(); 343 test_archive_string_sprintf(); 344 } 345 346 static const char *strings[] = 347 { 348 "dir/path", 349 "dir/path2", 350 "dir/path3", 351 "dir/path4", 352 "dir/path5", 353 "dir/path6", 354 "dir/path7", 355 "dir/path8", 356 "dir/path9", 357 "dir/subdir/path", 358 "dir/subdir/path2", 359 "dir/subdir/path3", 360 "dir/subdir/path4", 361 "dir/subdir/path5", 362 "dir/subdir/path6", 363 "dir/subdir/path7", 364 "dir/subdir/path8", 365 "dir/subdir/path9", 366 "dir2/path", 367 "dir2/path2", 368 "dir2/path3", 369 "dir2/path4", 370 "dir2/path5", 371 "dir2/path6", 372 "dir2/path7", 373 "dir2/path8", 374 "dir2/path9", 375 NULL 376 }; 377 378 DEFINE_TEST(test_archive_string_sort) 379 { 380 unsigned int i, j, size; 381 char **test_strings, *tmp; 382 383 srand((unsigned int)time(NULL)); 384 size = sizeof(strings) / sizeof(char *); 385 assert((test_strings = (char **)calloc(1, sizeof(strings))) != NULL); 386 for (i = 0; i < (size - 1); i++) 387 assert((test_strings[i] = strdup(strings[i])) != NULL); 388 389 /* Shuffle the test strings */ 390 for (i = 0; i < (size - 1); i++) 391 { 392 j = rand() % ((size - 1) - i); 393 j += i; 394 tmp = test_strings[i]; 395 test_strings[i] = test_strings[j]; 396 test_strings[j] = tmp; 397 } 398 399 /* Sort and test */ 400 assertEqualInt(ARCHIVE_OK, archive_utility_string_sort(test_strings)); 401 for (i = 0; i < (size - 1); i++) 402 assertEqualString(test_strings[i], strings[i]); 403 404 for (i = 0; i < (size - 1); i++) 405 free(test_strings[i]); 406 free(test_strings); 407 } 408