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
test_archive_string_ensure(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
test_archive_strcat(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
test_archive_strappend_char(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
test_archive_strncat(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
test_archive_strncpy(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
test_archive_strcpy(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
test_archive_string_concat(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
test_archive_string_copy(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
test_archive_string_sprintf(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
DEFINE_TEST(test_archive_string)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
DEFINE_TEST(test_archive_string_sort)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