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 archive_string_free(&s); 72 } 73 74 static void 75 test_archive_strcat(void) 76 { 77 struct archive_string s; 78 79 archive_string_init(&s); 80 assertExactString(0, 0, NULL, s); 81 82 /* null target, empty source */ 83 assert(&s == archive_strcat(&s, "")); 84 assertExactString(0, EXTENT, "", s); 85 86 /* empty target, empty source */ 87 assert(&s == archive_strcat(&s, "")); 88 assertExactString(0, EXTENT, "", s); 89 90 /* empty target, non-empty source */ 91 assert(&s == archive_strcat(&s, "fubar")); 92 assertExactString(5, EXTENT, "fubar", s); 93 94 /* non-empty target, non-empty source */ 95 assert(&s == archive_strcat(&s, "baz")); 96 assertExactString(8, EXTENT, "fubarbaz", s); 97 98 archive_string_free(&s); 99 } 100 101 static void 102 test_archive_strappend_char(void) 103 { 104 struct archive_string s; 105 106 archive_string_init(&s); 107 assertExactString(0, 0, NULL, s); 108 109 /* null target */ 110 archive_strappend_char(&s, 'X'); 111 assertExactString(1, EXTENT, "X", s); 112 113 /* non-empty target */ 114 archive_strappend_char(&s, 'Y'); 115 assertExactString(2, EXTENT, "XY", s); 116 117 archive_string_free(&s); 118 } 119 120 /* archive_strnXXX() tests focus on length handling. 121 * other behaviors are tested by proxy through archive_strXXX() 122 */ 123 124 static void 125 test_archive_strncat(void) 126 { 127 struct archive_string s; 128 129 archive_string_init(&s); 130 assertExactString(0, 0, NULL, s); 131 132 /* perfect length */ 133 assert(&s == archive_strncat(&s, "snafu", 5)); 134 assertExactString(5, EXTENT, "snafu", s); 135 136 /* short read */ 137 assert(&s == archive_strncat(&s, "barbazqux", 3)); 138 assertExactString(8, EXTENT, "snafubar", s); 139 140 /* long read is ok too! */ 141 assert(&s == archive_strncat(&s, "snafu", 8)); 142 assertExactString(13, EXTENT, "snafubarsnafu", s); 143 144 archive_string_free(&s); 145 } 146 147 static void 148 test_archive_strncpy(void) 149 { 150 struct archive_string s; 151 152 archive_string_init(&s); 153 assertExactString(0, 0, NULL, s); 154 155 /* perfect length */ 156 assert(&s == archive_strncpy(&s, "fubar", 5)); 157 assertExactString(5, EXTENT, "fubar", s); 158 159 /* short read */ 160 assert(&s == archive_strncpy(&s, "snafubar", 5)); 161 assertExactString(5, EXTENT, "snafu", s); 162 163 /* long read is ok too! */ 164 assert(&s == archive_strncpy(&s, "snafu", 8)); 165 assertExactString(5, EXTENT, "snafu", s); 166 167 archive_string_free(&s); 168 } 169 170 static void 171 test_archive_strcpy(void) 172 { 173 struct archive_string s; 174 175 archive_string_init(&s); 176 assertExactString(0, 0, NULL, s); 177 178 /* null target */ 179 assert(&s == archive_strcpy(&s, "snafu")); 180 assertExactString(5, EXTENT, "snafu", s); 181 182 /* dirty target */ 183 assert(&s == archive_strcpy(&s, "foo")); 184 assertExactString(3, EXTENT, "foo", s); 185 186 /* dirty target, empty source */ 187 assert(&s == archive_strcpy(&s, "")); 188 assertExactString(0, EXTENT, "", s); 189 190 archive_string_free(&s); 191 } 192 193 static void 194 test_archive_string_concat(void) 195 { 196 struct archive_string s, t, u, v; 197 198 archive_string_init(&s); 199 assertExactString(0, 0, NULL, s); 200 archive_string_init(&t); 201 assertExactString(0, 0, NULL, t); 202 archive_string_init(&u); 203 assertExactString(0, 0, NULL, u); 204 archive_string_init(&v); 205 assertExactString(0, 0, NULL, v); 206 207 /* null target, null source */ 208 archive_string_concat(&t, &s); 209 assertExactString(0, 0, NULL, s); 210 assertExactString(0, EXTENT, "", t); 211 212 /* null target, empty source */ 213 assert(&s == archive_strcpy(&s, "")); 214 archive_string_concat(&u, &s); 215 assertExactString(0, EXTENT, "", s); 216 assertExactString(0, EXTENT, "", u); 217 218 /* null target, non-empty source */ 219 assert(&s == archive_strcpy(&s, "foo")); 220 archive_string_concat(&v, &s); 221 assertExactString(3, EXTENT, "foo", s); 222 assertExactString(3, EXTENT, "foo", v); 223 224 /* empty target, empty source */ 225 assert(&s == archive_strcpy(&s, "")); 226 assert(&t == archive_strcpy(&t, "")); 227 archive_string_concat(&t, &s); 228 assertExactString(0, EXTENT, "", s); 229 assertExactString(0, EXTENT, "", t); 230 231 /* empty target, non-empty source */ 232 assert(&s == archive_strcpy(&s, "snafu")); 233 assert(&t == archive_strcpy(&t, "")); 234 archive_string_concat(&t, &s); 235 assertExactString(5, EXTENT, "snafu", s); 236 assertExactString(5, EXTENT, "snafu", t); 237 238 archive_string_free(&v); 239 archive_string_free(&u); 240 archive_string_free(&t); 241 archive_string_free(&s); 242 } 243 244 static void 245 test_archive_string_copy(void) 246 { 247 struct archive_string s, t, u, v; 248 249 archive_string_init(&s); 250 assertExactString(0, 0, NULL, s); 251 archive_string_init(&t); 252 assertExactString(0, 0, NULL, t); 253 archive_string_init(&u); 254 assertExactString(0, 0, NULL, u); 255 archive_string_init(&v); 256 assertExactString(0, 0, NULL, v); 257 258 /* null target, null source */ 259 archive_string_copy(&t, &s); 260 assertExactString(0, 0, NULL, s); 261 assertExactString(0, EXTENT, "", t); 262 263 /* null target, empty source */ 264 archive_string_copy(&u, &t); 265 assertExactString(0, EXTENT, "", t); 266 assertExactString(0, EXTENT, "", u); 267 268 /* empty target, empty source */ 269 archive_string_copy(&u, &t); 270 assertExactString(0, EXTENT, "", t); 271 assertExactString(0, EXTENT, "", u); 272 273 /* null target, non-empty source */ 274 assert(NULL != archive_strcpy(&s, "snafubar")); 275 assertExactString(8, EXTENT, "snafubar", s); 276 277 archive_string_copy(&v, &s); 278 assertExactString(8, EXTENT, "snafubar", s); 279 assertExactString(8, EXTENT, "snafubar", v); 280 281 /* empty target, non-empty source */ 282 assertExactString(0, EXTENT, "", t); 283 archive_string_copy(&t, &s); 284 assertExactString(8, EXTENT, "snafubar", s); 285 assertExactString(8, EXTENT, "snafubar", t); 286 287 /* non-empty target, non-empty source */ 288 assert(NULL != archive_strcpy(&s, "fubar")); 289 assertExactString(5, EXTENT, "fubar", s); 290 291 archive_string_copy(&t, &s); 292 assertExactString(5, EXTENT, "fubar", s); 293 assertExactString(5, EXTENT, "fubar", t); 294 295 archive_string_free(&v); 296 archive_string_free(&u); 297 archive_string_free(&t); 298 archive_string_free(&s); 299 } 300 301 static void 302 test_archive_string_sprintf(void) 303 { 304 struct archive_string s; 305 #define S16 "0123456789abcdef" 306 #define S32 S16 S16 307 #define S64 S32 S32 308 #define S128 S64 S64 309 const char *s32 = S32; 310 const char *s33 = S32 "0"; 311 const char *s64 = S64; 312 const char *s65 = S64 "0"; 313 const char *s128 = S128; 314 const char *s129 = S128 "0"; 315 #undef S16 316 #undef S32 317 #undef S64 318 #undef S128 319 320 archive_string_init(&s); 321 assertExactString(0, 0, NULL, s); 322 323 archive_string_sprintf(&s, "%s", ""); 324 assertExactString(0, 2 * EXTENT, "", s); 325 326 archive_string_empty(&s); 327 archive_string_sprintf(&s, "%s", s32); 328 assertExactString(32, 2 * EXTENT, s32, s); 329 330 archive_string_empty(&s); 331 archive_string_sprintf(&s, "%s", s33); 332 assertExactString(33, 2 * EXTENT, s33, s); 333 334 archive_string_empty(&s); 335 archive_string_sprintf(&s, "%s", s64); 336 assertExactString(64, 4 * EXTENT, s64, s); 337 338 archive_string_empty(&s); 339 archive_string_sprintf(&s, "%s", s65); 340 assertExactString(65, 4 * EXTENT, s65, s); 341 342 archive_string_empty(&s); 343 archive_string_sprintf(&s, "%s", s128); 344 assertExactString(128, 8 * EXTENT, s128, s); 345 346 archive_string_empty(&s); 347 archive_string_sprintf(&s, "%s", s129); 348 assertExactString(129, 8 * EXTENT, s129, s); 349 350 archive_string_empty(&s); 351 archive_string_sprintf(&s, "%d", 1234567890); 352 assertExactString(10, 8 * EXTENT, "1234567890", s); 353 354 archive_string_free(&s); 355 } 356 357 DEFINE_TEST(test_archive_string) 358 { 359 test_archive_string_ensure(); 360 test_archive_strcat(); 361 test_archive_strappend_char(); 362 test_archive_strncat(); 363 test_archive_strncpy(); 364 test_archive_strcpy(); 365 test_archive_string_concat(); 366 test_archive_string_copy(); 367 test_archive_string_sprintf(); 368 } 369 370 static const char *strings[] = 371 { 372 "dir/path", 373 "dir/path2", 374 "dir/path3", 375 "dir/path4", 376 "dir/path5", 377 "dir/path6", 378 "dir/path7", 379 "dir/path8", 380 "dir/path9", 381 "dir/subdir/path", 382 "dir/subdir/path2", 383 "dir/subdir/path3", 384 "dir/subdir/path4", 385 "dir/subdir/path5", 386 "dir/subdir/path6", 387 "dir/subdir/path7", 388 "dir/subdir/path8", 389 "dir/subdir/path9", 390 "dir2/path", 391 "dir2/path2", 392 "dir2/path3", 393 "dir2/path4", 394 "dir2/path5", 395 "dir2/path6", 396 "dir2/path7", 397 "dir2/path8", 398 "dir2/path9", 399 NULL 400 }; 401 402 DEFINE_TEST(test_archive_string_sort) 403 { 404 unsigned int i, j, size; 405 char **test_strings, *tmp; 406 407 srand((unsigned int)time(NULL)); 408 size = sizeof(strings) / sizeof(char *); 409 assert((test_strings = (char **)calloc(1, sizeof(strings))) != NULL); 410 for (i = 0; i < (size - 1); i++) 411 assert((test_strings[i] = strdup(strings[i])) != NULL); 412 413 /* Shuffle the test strings */ 414 for (i = 0; i < (size - 1); i++) 415 { 416 j = rand() % ((size - 1) - i); 417 j += i; 418 tmp = test_strings[i]; 419 test_strings[i] = test_strings[j]; 420 test_strings[j] = tmp; 421 } 422 423 /* Sort and test */ 424 assertEqualInt(ARCHIVE_OK, archive_utility_string_sort(test_strings)); 425 for (i = 0; i < (size - 1); i++) 426 assertEqualString(test_strings[i], strings[i]); 427 428 for (i = 0; i < (size - 1); i++) 429 free(test_strings[i]); 430 free(test_strings); 431 } 432