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