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