1 /*
2 * ProFTPD - FTP server testsuite
3 * Copyright (c) 2008-2017 The ProFTPD Project team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, The ProFTPD Project team and other respective
20 * copyright holders give permission to link this program with OpenSSL, and
21 * distribute the resulting executable, without including the source code for
22 * OpenSSL in the source distribution.
23 */
24
25 /* String API tests. */
26
27 #include "tests.h"
28
29 static pool *p = NULL;
30
set_up(void)31 static void set_up(void) {
32 if (p == NULL) {
33 p = make_sub_pool(NULL);
34 }
35 }
36
tear_down(void)37 static void tear_down(void) {
38 if (p) {
39 destroy_pool(p);
40 p = NULL;
41 }
42 }
43
START_TEST(sstrncpy_test)44 START_TEST (sstrncpy_test) {
45 char *ok, *dst;
46 size_t len, sz = 32;
47 int res;
48
49 len = 0;
50 res = sstrncpy(NULL, NULL, len);
51 fail_unless(res == -1, "Failed to handle null arguments");
52
53 dst = "";
54 res = sstrncpy(dst, "foo", 0);
55 fail_unless(res == 0, "Failed to handle zero length");
56
57 dst = pcalloc(p, sz);
58 memset(dst, 'A', sz);
59
60 len = 1;
61 res = sstrncpy(dst, NULL, len);
62 fail_unless(res == -1, "Failed to handle null arguments");
63
64 ok = "Therefore, all progress depends on the unreasonable man";
65
66 mark_point();
67 res = sstrncpy(ok, ok, 1);
68 fail_unless(res == 1, "Expected result 1, got %d", len, res);
69
70 mark_point();
71 memset(dst, 'A', sz);
72 len = 1;
73
74 res = sstrncpy(dst, ok, len);
75 fail_unless((size_t) res <= len, "Expected result %d, got %d", len, res);
76 fail_unless(strlen(dst) == (len - 1), "Expected len %u, got len %u", len - 1,
77 strlen(dst));
78 fail_unless(dst[len-1] == '\0', "Expected NUL, got '%c'", dst[len-1]);
79
80 memset(dst, 'A', sz);
81 len = 7;
82
83 res = sstrncpy(dst, ok, len);
84 fail_unless((size_t) res <= len, "Expected result %d, got %d", len, res);
85 fail_unless(strlen(dst) == (len - 1), "Expected len %u, got len %u", len - 1,
86 strlen(dst));
87 fail_unless(dst[len-1] == '\0', "Expected NUL, got '%c'", dst[len-1]);
88
89 memset(dst, 'A', sz);
90 len = sz;
91
92 res = sstrncpy(dst, ok, len);
93 fail_unless((size_t) res <= len, "Expected result %d, got %d", len, res);
94 fail_unless(strlen(dst) == (len - 1), "Expected len %u, got len %u", len - 1,
95 strlen(dst));
96 fail_unless(dst[len-1] == '\0', "Expected NUL, got '%c'", dst[len-1]);
97
98 memset(dst, 'A', sz);
99 len = sz;
100
101 res = sstrncpy(dst, "", len);
102 fail_unless((size_t) res <= len, "Expected result %d, got %d", len, res);
103 fail_unless(strlen(dst) == 0, "Expected len %u, got len %u", 0, strlen(dst));
104 fail_unless(*dst == '\0', "Expected NUL, got '%c'", *dst);
105 }
106 END_TEST
107
START_TEST(sstrcat_test)108 START_TEST (sstrcat_test) {
109 register unsigned int i;
110 char c = 'A', src[1024], dst[1024], *res;
111
112 res = sstrcat(dst, src, 0);
113 fail_unless(res == NULL, "Non-null result for zero-length strcat");
114
115 src[0] = 'f';
116 src[1] = '\0';
117 dst[0] = 'e';
118 dst[1] = '\0';
119 res = sstrcat(dst, src, 1);
120 fail_unless(res == dst, "Returned wrong destination buffer");
121
122 /* In this case, we told sstrcat() that dst is len 1, which means that
123 * sstrcat() should set dst[0] to NUL.
124 */
125 fail_unless(dst[0] == 0, "Failed to terminate destination buffer");
126
127 src[0] = 'f';
128 src[1] = '\0';
129 dst[0] = 'e';
130 dst[1] = '\0';
131 res = sstrcat(dst, src, 2);
132 fail_unless(res == dst, "Returned wrong destination buffer");
133
134 /* In this case, we told sstrcat() that dst is len 2, which means that
135 * sstrcat() should preserve the value at 0, and set dst[1] to NUL.
136 */
137 fail_unless(dst[0] == 'e',
138 "Failed to preserve destination buffer (expected '%c' at index 0, "
139 "got '%c')", 'e', dst[0]);
140
141 fail_unless(dst[1] == 0, "Failed to terminate destination buffer");
142
143 mark_point();
144 src[0] = 'f';
145 src[1] = '\0';
146 dst[0] = 'e';
147 dst[1] = '\0';
148 res = sstrcat(dst, src, 3);
149 fail_unless(res == dst, "Returned wrong destination buffer");
150
151 mark_point();
152 fail_unless(dst[0] == 'e',
153 "Failed to preserve destination buffer (expected '%c' at index 0, "
154 "got '%c')", 'e', dst[0]);
155
156 mark_point();
157 fail_unless(dst[1] == 'f',
158 "Failed to copy source buffer (expected '%c' at index 1, got '%c')",
159 'f', dst[1]);
160
161 mark_point();
162 fail_unless(dst[2] == 0, "Failed to terminate destination buffer");
163
164 mark_point();
165 memset(src, c, sizeof(src)-1);
166
167 /* Note: we need to NUL-terminate the source buffer, for e.g. strlcat(3)
168 * implementations. Failure to do so can yield SIGABRT/SIGSEGV problems
169 * during e.g. unit tests.
170 */
171 src[sizeof(src)-1] = '\0';
172 dst[0] = '\0';
173
174 mark_point();
175 res = sstrcat(dst, src, sizeof(dst));
176
177 mark_point();
178 fail_unless(res == dst, "Returned wrong destination buffer");
179
180 mark_point();
181 fail_unless(dst[sizeof(dst)-1] == 0,
182 "Failed to terminate destination buffer");
183
184 mark_point();
185 fail_unless(strlen(dst) == (sizeof(dst)-1),
186 "Failed to copy all the data (expected len %u, got len %u)",
187 sizeof(dst)-1, strlen(dst));
188
189 mark_point();
190 for (i = 0; i < sizeof(dst)-1; i++) {
191 fail_unless(dst[i] == c, "Copied wrong value (expected '%c', got '%c')",
192 c, dst[i]);
193 }
194 }
195 END_TEST
196
START_TEST(sreplace_test)197 START_TEST (sreplace_test) {
198 const char *res;
199 char *fmt = NULL, *ok;
200
201 res = sreplace(NULL, NULL, 0);
202 fail_unless(res == NULL, "Failed to handle invalid arguments");
203 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
204
205 res = sreplace(NULL, "", 0);
206 fail_unless(res == NULL, "Failed to handle invalid arguments");
207 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
208
209 res = sreplace(p, NULL, 0);
210 fail_unless(res == NULL, "Failed to handle invalid arguments");
211 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
212
213 fmt = "%a";
214 res = sreplace(p, fmt, "foo", NULL);
215 fail_unless(strcmp(res, fmt) == 0, "Expected '%s', got '%s'", fmt, res);
216
217 fmt = "foo %a";
218 res = sreplace(p, fmt, "%b", NULL);
219 fail_unless(strcmp(res, fmt) == 0, "Expected '%s', got '%s'", fmt, res);
220
221 fmt = "foo %a";
222 ok = "foo bar";
223 res = sreplace(p, fmt, "%a", "bar", NULL);
224 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
225
226 fmt = "foo %a %a";
227 ok = "foo bar bar";
228 res = sreplace(p, fmt, "%a", "bar", NULL);
229 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
230
231 fmt = "foo %a %a %a %a %a %a %a %a";
232 ok = "foo bar bar bar bar bar bar bar bar";
233 res = sreplace(p, fmt, "%a", "bar", NULL);
234 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
235
236 /* sreplace() will not handle more than 8 occurrences of the same escape
237 * sequence in the same line. Make sure this happens.
238 */
239 fmt = "foo %a %a %a %a %a %a %a %a %a";
240 ok = "foo bar bar bar bar bar bar bar bar bar";
241 res = sreplace(p, fmt, "%a", "bar", NULL);
242 fail_unless(strcmp(res, fmt) == 0, "Expected '%s', got '%s'", fmt, res);
243 }
244 END_TEST
245
START_TEST(sreplace_enospc_test)246 START_TEST (sreplace_enospc_test) {
247 const char *res;
248 char *fmt = NULL;
249 size_t bufsz = 8192;
250
251 fmt = palloc(p, bufsz + 1);
252 memset(fmt, ' ', bufsz);
253 fmt[bufsz-2] = '%';
254 fmt[bufsz-1] = 'a';
255 fmt[bufsz] = '\0';
256
257 res = sreplace(p, fmt, "%a", "foo", NULL);
258 fail_unless(res == NULL, "Failed to reject too-long buffer");
259 fail_unless(errno == ENOSPC, "Failed to set errno to ENOSPC");
260 }
261 END_TEST
262
START_TEST(sreplace_bug3614_test)263 START_TEST (sreplace_bug3614_test) {
264 const char *res;
265 char *fmt = NULL, *ok;
266
267 fmt = "%a %b %c %d %e %f %g %h %i %j %k %l %m "
268 "%n %o %p %q %r %s %t %u %v %w %x %y %z "
269 "%A %B %C %D %E %F %G %H %I %J %K %L %M "
270 "%N %O %P %Q %R %S %T %U %V %W %X %Y %Z "
271 "%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 "
272 "%{a} %{b} %{c} %{d} %{e} %{f} %{g} %{h} %{i} %{j} %{k} %{l} %{m} "
273 "%{n} %{o} %{p} %{q} %{r} %{s} %{t} %{u} %{v} %{w} %{x} %{y} %{z} "
274 "%{A} %{B} %{C} %{D} %{E} %{F} %{G} %{H} %{I} %{J} %{K} %{L} %{M} "
275 "%{N} %{O} %{P} %{Q} %{R} %{S} %{T} %{U} %{V} %{W} %{X} %{Y} %{Z} "
276 "%{aa} %{bb} %{cc} %{dd} %{ee} %{ff} %{gg} %{hh} %{ii} %{jj} "
277 "%{kk} %{ll} %{mm} %{nn} %{oo} %{pp} %{qq} %{rr} %{ss} %{tt} "
278 "%{uu} %{vv} %{ww} %{xx} %{yy} %{zz}";
279
280 /* We put a limit on the maximum number of replacements that sreplace()
281 * will perform on a given string, per Bug#3614.
282 */
283 ok = "bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar %{oo} %{pp} %{qq} %{rr} %{ss} %{tt} %{uu} %{vv} %{ww} %{xx} %{yy} %{zz}";
284
285 res = sreplace(p, fmt,
286 "%a", "bar", "%b", "bar", "%c", "bar", "%d", "bar", "%e", "bar",
287 "%f", "bar", "%g", "bar", "%h", "bar", "%i", "bar", "%j", "bar",
288 "%k", "bar", "%l", "bar", "%m", "bar", "%n", "bar", "%o", "bar",
289 "%p", "bar", "%q", "bar", "%r", "bar", "%s", "bar", "%t", "bar",
290 "%u", "bar", "%v", "bar", "%w", "bar", "%x", "bar", "%y", "bar",
291 "%z", "bar",
292 "%A", "bar", "%B", "bar", "%C", "bar", "%D", "bar", "%E", "bar",
293 "%F", "bar", "%G", "bar", "%H", "bar", "%I", "bar", "%J", "bar",
294 "%K", "bar", "%L", "bar", "%M", "bar", "%N", "bar", "%O", "bar",
295 "%P", "bar", "%Q", "bar", "%R", "bar", "%S", "bar", "%T", "bar",
296 "%U", "bar", "%V", "bar", "%W", "bar", "%X", "bar", "%Y", "bar",
297 "%Z", "bar",
298 "%0", "bar", "%1", "bar", "%2", "bar", "%3", "bar", "%4", "bar",
299 "%5", "bar", "%6", "bar", "%7", "bar", "%8", "bar", "%9", "bar",
300 "%{a}", "bar", "%{b}", "bar", "%{c}", "bar", "%{d}", "bar", "%{e}", "bar",
301 "%{f}", "bar", "%{g}", "bar", "%{h}", "bar", "%{i}", "bar", "%{j}", "bar",
302 "%{k}", "bar", "%{l}", "bar", "%{m}", "bar", "%{n}", "bar", "%{o}", "bar",
303 "%{p}", "bar", "%{q}", "bar", "%{r}", "bar", "%{s}", "bar", "%{t}", "bar",
304 "%{u}", "bar", "%{v}", "bar", "%{w}", "bar", "%{x}", "bar", "%{y}", "bar",
305 "%{z}", "bar",
306 "%{A}", "bar", "%{B}", "bar", "%{C}", "bar", "%{D}", "bar", "%{E}", "bar",
307 "%{F}", "bar", "%{G}", "bar", "%{H}", "bar", "%{I}", "bar", "%{J}", "bar",
308 "%{K}", "bar", "%{L}", "bar", "%{M}", "bar", "%{N}", "bar", "%{O}", "bar",
309 "%{P}", "bar", "%{Q}", "bar", "%{R}", "bar", "%{S}", "bar", "%{T}", "bar",
310 "%{U}", "bar", "%{V}", "bar", "%{W}", "bar", "%{X}", "bar", "%{Y}", "bar",
311 "%{Z}", "bar",
312 "%{aa}", "bar", "%{bb}", "bar", "%{cc}", "bar", "%{dd}", "bar",
313 "%{ee}", "bar", "%{ff}", "bar", "%{gg}", "bar", "%{hh}", "bar",
314 "%{ii}", "bar", "%{jj}", "bar", "%{kk}", "bar", "%{ll}", "bar",
315 "%{mm}", "bar", "%{nn}", "bar", "%{oo}", "bar", "%{pp}", "bar",
316 "%{qq}", "bar", "%{rr}", "bar", "%{ss}", "bar", "%{tt}", "bar",
317 "%{uu}", "bar", "%{vv}", "bar", "%{ww}", "bar", "%{xx}", "bar",
318 "%{yy}", "bar", "%{zz}", "bar",
319 NULL);
320 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
321 }
322 END_TEST
323
START_TEST(str_replace_test)324 START_TEST (str_replace_test) {
325 const char *res;
326 char *fmt = NULL, *ok;
327 int max_replace = PR_STR_MAX_REPLACEMENTS;
328
329 res = pr_str_replace(NULL, max_replace, NULL, 0);
330 fail_unless(res == NULL, "Failed to handle invalid arguments");
331 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
332
333 res = pr_str_replace(NULL, max_replace, "", 0);
334 fail_unless(res == NULL, "Failed to handle invalid arguments");
335 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
336
337 res = pr_str_replace(p, max_replace, NULL, 0);
338 fail_unless(res == NULL, "Failed to handle invalid arguments");
339 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
340
341 fmt = "%a";
342 res = pr_str_replace(p, max_replace, fmt, "foo", NULL);
343 fail_unless(strcmp(res, fmt) == 0, "Expected '%s', got '%s'", fmt, res);
344
345 fmt = "foo %a";
346 res = pr_str_replace(p, max_replace, fmt, "%b", NULL);
347 fail_unless(strcmp(res, fmt) == 0, "Expected '%s', got '%s'", fmt, res);
348
349 fmt = "foo %a";
350 ok = "foo bar";
351 res = pr_str_replace(p, max_replace, fmt, "%a", "bar", NULL);
352 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
353
354 fmt = "foo %a %a";
355 ok = "foo bar bar";
356 res = pr_str_replace(p, max_replace, fmt, "%a", "bar", NULL);
357 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
358
359 fmt = "foo %a %a %a %a %a %a %a %a";
360 ok = "foo bar bar bar bar bar bar bar bar";
361 res = pr_str_replace(p, max_replace, fmt, "%a", "bar", NULL);
362 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
363
364 fmt = "foo %a %a %a %a %a %a %a %a %a";
365 ok = "foo bar bar bar bar bar bar bar bar bar";
366 res = pr_str_replace(p, max_replace, fmt, "%a", "bar", NULL);
367 fail_unless(res == NULL, "Failed to handle too many replacements");
368 fail_unless(errno == E2BIG, "Failed to set errno to E2BIG");
369 }
370 END_TEST
371
START_TEST(pdircat_test)372 START_TEST (pdircat_test) {
373 char *res, *ok;
374
375 res = pdircat(NULL, 0);
376 fail_unless(res == NULL, "Failed to handle null arguments");
377 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
378
379 res = pdircat(p, 0);
380 fail_unless(res != NULL,
381 "Failed to handle empty arguments (expected '', got '%s')", res);
382 fail_unless(strcmp(res, "") == 0, "Expected '%s', got '%s'", "", res);
383
384 /* Comments in the pdircat() function suggest that an empty string
385 * should be treated as a leading slash. However, that never got
386 * implemented. Is this a bug, or just an artifact? I doubt that it
387 * is causing problems at present.
388 */
389 res = pdircat(p, "", NULL);
390 ok = "";
391 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
392
393 res = pdircat(p, "foo", "bar", NULL);
394 ok = "foo/bar";
395 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
396
397 res = pdircat(p, "", "foo", "bar", NULL);
398 ok = "foo/bar";
399 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
400
401 res = pdircat(p, "/", "/foo/", "/bar/", NULL);
402 ok = "/foo/bar/";
403 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
404
405 /* Sadly, pdircat() only handles single leading/trailing slashes, not
406 * an arbitrary number of leading/trailing slashes.
407 */
408 res = pdircat(p, "//", "//foo//", "//bar//", NULL);
409 ok = "///foo///bar//";
410 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
411 }
412 END_TEST
413
START_TEST(pstrcat_test)414 START_TEST (pstrcat_test) {
415 char *res, *ok;
416
417 res = pstrcat(NULL, 0);
418 fail_unless(res == NULL, "Failed to handle null arguments");
419 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
420
421 res = pstrcat(p, 0);
422 fail_unless(res != NULL,
423 "Failed to handle empty arguments (expected '', got '%s')", res);
424 fail_unless(strcmp(res, "") == 0, "Expected '%s', got '%s'", "", res);
425
426 res = pstrcat(p, "", NULL);
427 ok = "";
428 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
429
430 res = pstrcat(p, "foo", "bar", NULL);
431 ok = "foobar";
432 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
433
434 res = pstrcat(p, "", "foo", "bar", NULL);
435 ok = "foobar";
436 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
437
438 res = pstrcat(p, "/", "/foo/", "/bar/", NULL);
439 ok = "//foo//bar/";
440 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
441
442 res = pdircat(p, "//", "//foo//", NULL, "//bar//", NULL);
443 ok = "///foo//";
444 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
445 }
446 END_TEST
447
START_TEST(pstrdup_test)448 START_TEST (pstrdup_test) {
449 char *res, *ok;
450
451 res = pstrdup(NULL, NULL);
452 fail_unless(res == NULL, "Failed to handle null arguments");
453 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
454
455 res = pstrdup(p, NULL);
456 fail_unless(res == NULL, "Failed to handle null arguments");
457 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
458
459 res = pstrdup(NULL, "");
460 fail_unless(res == NULL, "Failed to handle null arguments");
461 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
462
463 res = pstrdup(p, "foo");
464 ok = "foo";
465 fail_unless(strlen(res) == strlen(ok), "Expected len %u, got len %u",
466 strlen(ok), strlen(res));
467 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
468 }
469 END_TEST
470
START_TEST(pstrndup_test)471 START_TEST (pstrndup_test) {
472 char *res, *ok;
473
474 res = pstrndup(NULL, NULL, 0);
475 fail_unless(res == NULL, "Failed to handle null arguments");
476 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
477
478 res = pstrndup(p, NULL, 0);
479 fail_unless(res == NULL, "Failed to handle null arguments");
480 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
481
482 res = pstrndup(NULL, "", 0);
483 fail_unless(res == NULL, "Failed to handle null arguments");
484 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
485
486 res = pstrndup(p, "foo", 0);
487 ok = "";
488 fail_unless(strlen(res) == strlen(ok), "Expected len %u, got len %u",
489 strlen(ok), strlen(res));
490 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
491
492 res = pstrndup(p, "foo", 1);
493 ok = "f";
494 fail_unless(strlen(res) == strlen(ok), "Expected len %u, got len %u",
495 strlen(ok), strlen(res));
496 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
497
498 res = pstrndup(p, "foo", 10);
499 ok = "foo";
500 fail_unless(strlen(res) == strlen(ok), "Expected len %u, got len %u",
501 strlen(ok), strlen(res));
502 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
503 }
504 END_TEST
505
START_TEST(strip_test)506 START_TEST (strip_test) {
507 const char *ok, *res, *str;
508
509 res = pr_str_strip(NULL, NULL);
510 fail_unless(res == NULL, "Failed to handle null arguments");
511 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
512
513 res = pr_str_strip(p, NULL);
514 fail_unless(res == NULL, "Failed to handle null str argument");
515 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
516
517 res = pr_str_strip(NULL, "foo");
518 fail_unless(res == NULL, "Failed to handle null pool argument");
519 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
520
521 str = pstrdup(p, "foo");
522 res = pr_str_strip(p, str);
523 fail_unless(res != NULL, "Failed to strip '%s': %s", str, strerror(errno));
524
525 ok = "foo";
526 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
527
528 str = pstrdup(p, " \n \t foo");
529 res = pr_str_strip(p, str);
530 fail_unless(res != NULL, "Failed to strip '%s': %s", str, strerror(errno));
531
532 ok = "foo";
533 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
534
535 str = pstrdup(p, "foo \n \t \r");
536 res = pr_str_strip(p, str);
537 fail_unless(res != NULL, "Failed to strip '%s': %s", str, strerror(errno));
538
539 ok = "foo";
540 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
541
542 str = pstrdup(p, "\r \n\n\t foo \n \t \r");
543 res = pr_str_strip(p, str);
544 fail_unless(res != NULL, "Failed to strip '%s': %s", str, strerror(errno));
545
546 ok = "foo";
547 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
548 }
549 END_TEST
550
START_TEST(strip_end_test)551 START_TEST (strip_end_test) {
552 char *ch, *ok, *res, *str;
553
554 res = pr_str_strip_end(NULL, NULL);
555 fail_unless(res == NULL, "Failed to handle null arguments");
556 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
557
558 str = pstrdup(p, "foo");
559
560 res = pr_str_strip_end(str, NULL);
561 fail_unless(res == NULL, "Failed to handle null char argument");
562 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
563
564 ch = "\r\n";
565
566 res = pr_str_strip_end(NULL, ch);
567 fail_unless(res == NULL, "Failed to handle null str argument");
568 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
569
570 res = pr_str_strip_end(str, ch);
571 fail_unless(res != NULL, "Failed to strip '%s' from end of '%s': %s",
572 ch, str, strerror(errno));
573
574 ok = "foo";
575 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
576
577 str = pstrdup(p, "foo\r\n");
578 res = pr_str_strip_end(str, ch);
579 fail_unless(res != NULL, "Failed to strip '%s' from end of '%s': %s",
580 ch, str, strerror(errno));
581
582 ok = "foo";
583 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
584
585 str = pstrdup(p, "foo\r\n\r\n\r\n");
586 res = pr_str_strip_end(str, ch);
587 fail_unless(res != NULL, "Failed to strip '%s' from end of '%s': %s",
588 ch, str, strerror(errno));
589
590 ok = "foo";
591 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
592 }
593 END_TEST
594
START_TEST(get_token_test)595 START_TEST (get_token_test) {
596 char *ok, *res, *str;
597
598 res = pr_str_get_token(NULL, NULL);
599 fail_unless(res == NULL, "Failed to handle null arguments");
600 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
601
602 str = NULL;
603 res = pr_str_get_token(&str, NULL);
604 fail_unless(res == NULL, "Failed to handle null str argument");
605 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
606
607 str = pstrdup(p, "foo,bar,baz");
608 res = pr_str_get_token(&str, NULL);
609 fail_unless(res == NULL, "Failed to handle null sep argument");
610 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
611
612 res = pr_str_get_token(&str, ",");
613 fail_unless(res != NULL, "Failed to get token from '%s': %s", str,
614 strerror(errno));
615
616 ok = "foo";
617 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
618
619 res = pr_str_get_token(&str, ",");
620 fail_unless(res != NULL, "Failed to get token from '%s': %s", str,
621 strerror(errno));
622
623 ok = "bar";
624 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
625
626 res = pr_str_get_token(&str, ",");
627 fail_unless(res != NULL, "Failed to get token from '%s': %s", str,
628 strerror(errno));
629
630 ok = "baz";
631 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
632
633 res = pr_str_get_token(&str, ",");
634 fail_unless(res == NULL, "Unexpectedly got token '%s'", res);
635 }
636 END_TEST
637
START_TEST(get_token2_test)638 START_TEST (get_token2_test) {
639 char *ok, *res, *str;
640 size_t len = 0, ok_len;
641
642 res = pr_str_get_token2(NULL, NULL, NULL);
643 fail_unless(res == NULL, "Failed to handle null arguments");
644 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
645
646 str = NULL;
647 res = pr_str_get_token2(&str, NULL, NULL);
648 fail_unless(res == NULL, "Failed to handle null str argument");
649 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
650
651 str = pstrdup(p, "foo,bar,bazz");
652 res = pr_str_get_token2(&str, NULL, NULL);
653 fail_unless(res == NULL, "Failed to handle null sep argument");
654 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
655
656 res = pr_str_get_token2(&str, ",", &len);
657 fail_unless(res != NULL, "Failed to get token from '%s': %s", str,
658 strerror(errno));
659
660 ok = "foo";
661 ok_len = 3;
662 fail_unless(len == ok_len, "Expected len %lu, got %lu",
663 (unsigned long) ok_len, (unsigned long) len);
664 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
665
666 res = pr_str_get_token2(&str, ",", &len);
667 fail_unless(res != NULL, "Failed to get token from '%s': %s", str,
668 strerror(errno));
669
670 ok = "bar";
671 ok_len = 3;
672 fail_unless(len == ok_len, "Expected len %lu, got %lu",
673 (unsigned long) ok_len, (unsigned long) len);
674 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
675
676 res = pr_str_get_token2(&str, ",", &len);
677 fail_unless(res != NULL, "Failed to get token from '%s': %s", str,
678 strerror(errno));
679
680 ok = "bazz";
681 ok_len = 4;
682 fail_unless(len == ok_len, "Expected len %lu, got %lu",
683 (unsigned long) ok_len, (unsigned long) len);
684 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
685
686 res = pr_str_get_token2(&str, ",", &len);
687
688 ok_len = 0;
689 fail_unless(len == ok_len, "Expected len %lu, got %lu",
690 (unsigned long) ok_len, (unsigned long) len);
691 fail_unless(res == NULL, "Unexpectedly got token '%s'", res);
692 }
693 END_TEST
694
START_TEST(get_word_test)695 START_TEST (get_word_test) {
696 char *ok, *res, *str;
697
698 res = pr_str_get_word(NULL, 0);
699 fail_unless(res == NULL, "Failed to handle null arguments");
700 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
701
702 str = NULL;
703 res = pr_str_get_word(&str, 0);
704 fail_unless(res == NULL, "Failed to handle null str argument");
705 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
706
707 str = pstrdup(p, " ");
708 res = pr_str_get_word(&str, 0);
709 fail_unless(res == NULL, "Failed to handle whitespace argument");
710
711 str = pstrdup(p, " foo");
712 res = pr_str_get_word(&str, PR_STR_FL_PRESERVE_WHITESPACE);
713 fail_unless(res != NULL, "Failed to handle whitespace argument: %s",
714 strerror(errno));
715
716 ok = "";
717 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
718
719 res = pr_str_get_word(&str, PR_STR_FL_PRESERVE_WHITESPACE);
720 fail_unless(res != NULL, "Failed to handle whitespace argument: %s",
721 strerror(errno));
722
723 ok = "foo";
724 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
725
726 str = pstrdup(p, " # foo");
727 res = pr_str_get_word(&str, 0);
728 fail_unless(res == NULL, "Failed to handle commented argument");
729
730 res = pr_str_get_word(&str, PR_STR_FL_PRESERVE_COMMENTS);
731 fail_unless(res != NULL, "Failed to handle commented argument: %s",
732 strerror(errno));
733
734 ok = "#";
735 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
736
737 res = pr_str_get_word(&str, PR_STR_FL_PRESERVE_COMMENTS);
738 fail_unless(res != NULL, "Failed to handle commented argument: %s",
739 strerror(errno));
740
741 ok = "foo";
742 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
743
744 /* Test multiple embedded quotes. */
745 str = pstrdup(p, "foo \"bar baz\" qux \"quz norf\"");
746 res = pr_str_get_word(&str, 0);
747 fail_unless(res != NULL, "Failed to handle quoted argument: %s",
748 strerror(errno));
749
750 ok = "foo";
751 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
752
753 res = pr_str_get_word(&str, 0);
754 fail_unless(res != NULL, "Failed to handle quoted argument: %s",
755 strerror(errno));
756
757 ok = "bar baz";
758 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
759
760 res = pr_str_get_word(&str, 0);
761 fail_unless(res != NULL, "Failed to handle quoted argument: %s",
762 strerror(errno));
763
764 ok = "qux";
765 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
766
767 res = pr_str_get_word(&str, 0);
768 fail_unless(res != NULL, "Failed to handle quoted argument: %s",
769 strerror(errno));
770
771 ok = "quz norf";
772 fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
773 }
774 END_TEST
775
START_TEST(get_word_utf8_test)776 START_TEST (get_word_utf8_test) {
777 const char *path;
778 FILE *fh;
779
780 /* Test UT8 spaces. Note that in order to do this, I had to use
781 * some other tool (Perl) to emit the desired UTF8 characters to
782 * a file; we then read in the bytes to parse from that file. Some
783 * compilers (e.g. gcc), in conjunction with the terminal/editor I'm
784 * using, don't like using the '\uNNNN' syntax for encoding UTF8 in C
785 * source code.
786 */
787
788 path = "api/etc/str/utf8-space.txt";
789 fh = fopen(path, "r");
790 if (fh != NULL) {
791 char *ok, *res, *str;
792 size_t nread = 0, sz;
793
794 sz = 256;
795 str = pcalloc(p, sz);
796
797 nread = fread(str, sizeof(char), sz-1, fh);
798 fail_if(ferror(fh), "Error reading '%s': %s", path, strerror(errno));
799 fail_unless(nread > 0, "Expected >0 bytes read, got 0");
800
801 res = pr_str_get_word(&str, 0);
802 fail_unless(res != NULL, "Failed to handle UTF8 argument: %s",
803 strerror(errno));
804
805 ok = "foo";
806 fail_if(strcmp(res, ok) == 0, "Did NOT expect '%s'", ok);
807
808 fclose(fh);
809 }
810 }
811 END_TEST
812
START_TEST(is_boolean_test)813 START_TEST (is_boolean_test) {
814 int res;
815
816 res = pr_str_is_boolean(NULL);
817 fail_unless(res == -1, "Failed to handle null argument");
818 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL (got %d)",
819 errno);
820
821 res = pr_str_is_boolean("on");
822 fail_unless(res == TRUE, "Expected TRUE, got FALSE");
823
824 res = pr_str_is_boolean("Yes");
825 fail_unless(res == TRUE, "Expected TRUE, got FALSE");
826
827 res = pr_str_is_boolean("TrUe");
828 fail_unless(res == TRUE, "Expected TRUE, got FALSE");
829
830 res = pr_str_is_boolean("1");
831 fail_unless(res == TRUE, "Expected TRUE, got FALSE");
832
833 res = pr_str_is_boolean("oFF");
834 fail_unless(res == FALSE, "Expected FALSE, got TRUE");
835
836 res = pr_str_is_boolean("no");
837 fail_unless(res == FALSE, "Expected FALSE, got TRUE");
838
839 res = pr_str_is_boolean("false");
840 fail_unless(res == FALSE, "Expected FALSE, got TRUE");
841
842 res = pr_str_is_boolean("0");
843 fail_unless(res == FALSE, "Expected FALSE, got TRUE");
844
845 res = pr_str_is_boolean("foo");
846 fail_unless(res == -1, "Failed to handle null argument");
847 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL (got %d)",
848 errno);
849 }
850 END_TEST
851
START_TEST(is_fnmatch_test)852 START_TEST (is_fnmatch_test) {
853 int res;
854 char *str;
855
856 res = pr_str_is_fnmatch(NULL);
857 fail_unless(res == FALSE, "Expected false for NULL");
858
859 str = "foo";
860 res = pr_str_is_fnmatch(str);
861 fail_if(res != FALSE, "Expected false for string '%s'", str);
862
863 str = "foo?";
864 res = pr_str_is_fnmatch(str);
865 fail_if(res != TRUE, "Expected true for string '%s'", str);
866
867 str = "foo*";
868 res = pr_str_is_fnmatch(str);
869 fail_if(res != TRUE, "Expected true for string '%s'", str);
870
871 str = "foo[";
872 res = pr_str_is_fnmatch(str);
873 fail_if(res != FALSE, "Expected false for string '%s'", str);
874
875 str = "foo]";
876 res = pr_str_is_fnmatch(str);
877 fail_if(res != FALSE, "Expected false for string '%s'", str);
878
879 str = "foo[]";
880 res = pr_str_is_fnmatch(str);
881 fail_if(res != TRUE, "Expected true for string '%s'", str);
882
883 /* Now the fun cases using the escape character. */
884
885 str = "f\\oo";
886 res = pr_str_is_fnmatch(str);
887 fail_if(res != FALSE, "Expected false for string '%s'", str);
888
889 str = "foo\\";
890 res = pr_str_is_fnmatch(str);
891 fail_if(res != FALSE, "Expected false for string '%s'", str);
892
893 str = "foo\\?";
894 res = pr_str_is_fnmatch(str);
895 fail_if(res != FALSE, "Expected false for string '%s'", str);
896
897 str = "foo\\??";
898 res = pr_str_is_fnmatch(str);
899 fail_if(res != TRUE, "Expected true for string '%s'", str);
900 }
901 END_TEST
902
START_TEST(get_nbytes_test)903 START_TEST (get_nbytes_test) {
904 char *str, *units;
905 off_t nbytes;
906 int res;
907
908 res = pr_str_get_nbytes(NULL, NULL, NULL);
909 fail_unless(res == -1, "Failed to handle null arguments");
910 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
911
912 str = NULL;
913 res = pr_str_get_nbytes(str, NULL, NULL);
914 fail_unless(res == -1, "Failed to handle null str argument");
915 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
916
917 str = "1";
918 units = "f";
919 res = pr_str_get_nbytes(str, units, NULL);
920 fail_unless(res == -1, "Failed to handle bad suffix argument");
921 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
922
923 str = "a";
924 units = "";
925 res = pr_str_get_nbytes(str, units, NULL);
926 fail_unless(res == -1, "Failed to handle invalid str argument");
927 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
928
929 str = "1 1";
930 units = "";
931 res = pr_str_get_nbytes(str, units, NULL);
932 fail_unless(res == -1, "Failed to handle invalid str argument");
933 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
934
935 str = "1.1";
936 units = "";
937 res = pr_str_get_nbytes(str, units, NULL);
938 fail_unless(res == -1, "Failed to handle invalid str argument");
939 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
940
941 str = "-1";
942 units = "";
943 res = pr_str_get_nbytes(str, units, NULL);
944 fail_unless(res == -1, "Failed to handle invalid str argument");
945 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
946
947 /* XXX Test good suffix: B, KB, MB, GB, TB */
948
949 str = "1";
950 units = "";
951 res = pr_str_get_nbytes(str, units, &nbytes);
952 fail_unless(res == 0, "Expected result 0, got %d: %s", res, strerror(errno));
953 fail_unless(nbytes == 1, "Expected nbytes = 1, got %" PR_LU,
954 (pr_off_t) nbytes);
955
956 str = "1";
957 units = "B";
958 res = pr_str_get_nbytes(str, units, &nbytes);
959 fail_unless(res == 0, "Expected result 0, got %d: %s", res, strerror(errno));
960 fail_unless(nbytes == 1,
961 "Expected nbytes = 1, got %" PR_LU, (pr_off_t) nbytes);
962
963 str = "1";
964 units = "KB";
965 res = pr_str_get_nbytes(str, units, &nbytes);
966 fail_unless(res == 0, "Expected result 0, got %d: %s", res, strerror(errno));
967 fail_unless(nbytes == 1024UL,
968 "Expected nbytes = 1024, got %" PR_LU, (pr_off_t) nbytes);
969
970 str = "1";
971 units = "MB";
972 res = pr_str_get_nbytes(str, units, &nbytes);
973 fail_unless(res == 0, "Expected result 0, got %d: %s", res, strerror(errno));
974 fail_unless(nbytes == 1048576UL,
975 "Expected nbytes = 1048576, got %" PR_LU, (pr_off_t) nbytes);
976
977 str = "1";
978 units = "GB";
979 res = pr_str_get_nbytes(str, units, &nbytes);
980 fail_unless(res == 0, "Expected result 0, got %d: %s", res, strerror(errno));
981 fail_unless(nbytes == 1073741824UL,
982 "Expected nbytes = 1073741824, got %" PR_LU, (pr_off_t) nbytes);
983
984 str = "1";
985 units = "TB";
986 res = pr_str_get_nbytes(str, units, &nbytes);
987 fail_unless(res == 0, "Expected result 0, got %d: %s", res, strerror(errno));
988 fail_unless(nbytes == 1099511627776UL,
989 "Expected nbytes = 1099511627776, got %" PR_LU, (pr_off_t) nbytes);
990
991 /* This should definitely trigger the ERANGE error. */
992 str = "1099511627776";
993 units = "TB";
994 res = pr_str_get_nbytes(str, units, &nbytes);
995 fail_unless(res == -1, "Expected ERANGE failure, succeeded unexpectedly");
996 fail_unless(errno == ERANGE, "Expected %s [%d], got %s [%d]",
997 strerror(ERANGE), ERANGE, strerror(errno), errno);
998 }
999 END_TEST
1000
START_TEST(get_duration_test)1001 START_TEST (get_duration_test) {
1002 char *str;
1003 int duration, expected;
1004 int res;
1005
1006 res = pr_str_get_duration(NULL, NULL);
1007 fail_unless(res == -1, "Failed to handle null arguments");
1008 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1009
1010 str = "";
1011 res = pr_str_get_duration(str, NULL);
1012 fail_unless(res == -1,
1013 "Failed to handle badly formatted string '%s'", str);
1014 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1015
1016 str = "-1:-1:-1";
1017 res = pr_str_get_duration(str, NULL);
1018 fail_unless(res == -1,
1019 "Failed to handle badly formatted string '%s'", str);
1020 fail_unless(errno == ERANGE, "Failed to set errno to ERANGE");
1021
1022 str = "a:b:c";
1023 res = pr_str_get_duration(str, NULL);
1024 fail_unless(res == -1,
1025 "Failed to handle badly formatted string '%s'", str);
1026 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1027
1028 str = "111:222:333";
1029 res = pr_str_get_duration(str, NULL);
1030 fail_unless(res == -1,
1031 "Failed to handle badly formatted string '%s'", str);
1032 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1033
1034 /* Test well-formatted hh::mm::ss strings. */
1035
1036 str = "00:00:00";
1037 expected = 0;
1038 res = pr_str_get_duration(str, &duration);
1039 fail_unless(res == 0,
1040 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1041 fail_unless(duration == expected,
1042 "Expected duration %d secs, got %d", expected, duration);
1043
1044 str = "01:02:03";
1045 expected = 3723;
1046 res = pr_str_get_duration(str, &duration);
1047 fail_unless(res == 0,
1048 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1049 fail_unless(duration == expected,
1050 "Expected duration %d secs, got %d", expected, duration);
1051
1052 str = "99:99:99";
1053 expected = 362439;
1054 res = pr_str_get_duration(str, &duration);
1055 fail_unless(res == 0,
1056 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1057 fail_unless(duration == expected,
1058 "Expected duration %d secs, got %d", expected, duration);
1059
1060 /* Test bad suffixes: -1h, -1hr, 9999foo, etc */
1061
1062 str = "-1h";
1063 res = pr_str_get_duration(str, NULL);
1064 fail_unless(res == -1,
1065 "Failed to handle badly formatted suffix string '%s'", str);
1066 fail_unless(errno == ERANGE, "Failed to set errno to ERANGE");
1067
1068 str = "-1hr";
1069 res = pr_str_get_duration(str, NULL);
1070 fail_unless(res == -1,
1071 "Failed to handle badly formatted suffix string '%s'", str);
1072 fail_unless(errno == ERANGE, "Failed to set errno to ERANGE");
1073
1074 str = "99foo";
1075 res = pr_str_get_duration(str, NULL);
1076 fail_unless(res == -1,
1077 "Failed to handle badly formatted suffix string '%s'", str);
1078 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1079
1080 str = "foo";
1081 res = pr_str_get_duration(str, NULL);
1082 fail_unless(res == -1,
1083 "Failed to handle badly formatted suffix string '%s'", str);
1084 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1085
1086 /* Test good suffices: "H"/"h"/"hr", "M"/"m"/"min", "S"/"s"/"sec" */
1087
1088 str = "76H";
1089 expected = 273600;
1090 res = pr_str_get_duration(str, &duration);
1091 fail_unless(res == 0,
1092 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1093 fail_unless(duration == expected,
1094 "Expected duration %d secs, got %d", expected, duration);
1095
1096 str = "76h";
1097 expected = 273600;
1098 res = pr_str_get_duration(str, &duration);
1099 fail_unless(res == 0,
1100 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1101 fail_unless(duration == expected,
1102 "Expected duration %d secs, got %d", expected, duration);
1103
1104 str = "76Hr";
1105 expected = 273600;
1106 res = pr_str_get_duration(str, &duration);
1107 fail_unless(res == 0,
1108 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1109 fail_unless(duration == expected,
1110 "Expected duration %d secs, got %d", expected, duration);
1111
1112 str = "888M";
1113 expected = 53280;
1114 res = pr_str_get_duration(str, &duration);
1115 fail_unless(res == 0,
1116 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1117 fail_unless(duration == expected,
1118 "Expected duration %d secs, got %d", expected, duration);
1119
1120 str = "888m";
1121 expected = 53280;
1122 res = pr_str_get_duration(str, &duration);
1123 fail_unless(res == 0,
1124 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1125 fail_unless(duration == expected,
1126 "Expected duration %d secs, got %d", expected, duration);
1127
1128 str = "888MiN";
1129 expected = 53280;
1130 res = pr_str_get_duration(str, &duration);
1131 fail_unless(res == 0,
1132 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1133 fail_unless(duration == expected,
1134 "Expected duration %d secs, got %d", expected, duration);
1135
1136 str = "999S";
1137 expected = 999;
1138 res = pr_str_get_duration(str, &duration);
1139 fail_unless(res == 0,
1140 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1141 fail_unless(duration == expected,
1142 "Expected duration %d secs, got %d", expected, duration);
1143
1144 str = "999s";
1145 expected = 999;
1146 res = pr_str_get_duration(str, &duration);
1147 fail_unless(res == 0,
1148 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1149 fail_unless(duration == expected,
1150 "Expected duration %d secs, got %d", expected, duration);
1151
1152 str = "999sEc";
1153 expected = 999;
1154 res = pr_str_get_duration(str, &duration);
1155 fail_unless(res == 0,
1156 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1157 fail_unless(duration == expected,
1158 "Expected duration %d secs, got %d", expected, duration);
1159
1160 str = "0h";
1161 expected = 0;
1162 res = pr_str_get_duration(str, &duration);
1163 fail_unless(res == 0,
1164 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1165 fail_unless(duration == expected,
1166 "Expected duration %d secs, got %d", expected, duration);
1167
1168 str = "0M";
1169 expected = 0;
1170 res = pr_str_get_duration(str, &duration);
1171 fail_unless(res == 0,
1172 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1173 fail_unless(duration == expected,
1174 "Expected duration %d secs, got %d", expected, duration);
1175
1176 str = "0sec";
1177 expected = 0;
1178 res = pr_str_get_duration(str, &duration);
1179 fail_unless(res == 0,
1180 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1181 fail_unless(duration == expected,
1182 "Expected duration %d secs, got %d", expected, duration);
1183
1184 str = "17";
1185 expected = 17;
1186 res = pr_str_get_duration(str, &duration);
1187 fail_unless(res == 0,
1188 "Failed to parse well-formed time string '%s': %s", str, strerror(errno));
1189 fail_unless(duration == expected,
1190 "Expected duration %d secs, got %d", expected, duration);
1191
1192 str = "-1";
1193 res = pr_str_get_duration(str, NULL);
1194 fail_unless(res == -1,
1195 "Failed to handle badly formatted suffix string '%s'", str);
1196 fail_unless(errno == ERANGE, "Failed to set errno to ERANGE");
1197 }
1198 END_TEST
1199
START_TEST(strnrstr_test)1200 START_TEST (strnrstr_test) {
1201 int res, flags = 0;
1202 const char *s = NULL, *suffix = NULL;
1203
1204 res = pr_strnrstr(NULL, 0, NULL, 0, flags);
1205 fail_unless(res == -1, "Failed to handle null arguments");
1206 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1207
1208 res = pr_strnrstr(NULL, 0, "", 0, flags);
1209 fail_unless(res == -1, "Failed to handle null s");
1210 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1211
1212 res = pr_strnrstr("", 0, NULL, 0, flags);
1213 fail_unless(res == -1, "Failed to handle null suffix");
1214 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
1215
1216 s = suffix = "";
1217 res = pr_strnrstr(s, 0, suffix, 0, flags);
1218 fail_unless(res == TRUE, "Expected true, got false");
1219
1220 s = "";
1221 suffix = "s";
1222 res = pr_strnrstr(s, 0, suffix, 0, flags);
1223 fail_unless(res == FALSE, "Expected false, got true");
1224
1225 s = "food";
1226 suffix = "ood";
1227 res = pr_strnrstr(s, 0, suffix, 0, flags);
1228 fail_unless(res == TRUE, "Expected true, got false");
1229
1230 s = "food";
1231 suffix = "ood";
1232 res = pr_strnrstr(s, 4, suffix, 3, flags);
1233 fail_unless(res == TRUE, "Expected true, got false");
1234
1235 s = "FOOD";
1236 suffix = "ood";
1237 res = pr_strnrstr(s, 4, suffix, 3, flags);
1238 fail_unless(res == FALSE, "Expected false, got true");
1239
1240 flags = PR_STR_FL_IGNORE_CASE;
1241 s = "FOOD";
1242 suffix = "ood";
1243 res = pr_strnrstr(s, 4, suffix, 3, flags);
1244 fail_unless(res == TRUE, "Expected true, got false");
1245 }
1246 END_TEST
1247
START_TEST(bin2hex_test)1248 START_TEST (bin2hex_test) {
1249 char *expected, *res;
1250 const unsigned char *str;
1251
1252 res = pr_str_bin2hex(NULL, NULL, 0, 0);
1253 fail_unless(res == NULL, "Failed to handle null arguments");
1254 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1255 strerror(errno), errno);
1256
1257 res = pr_str_bin2hex(p, NULL, 0, 0);
1258 fail_unless(res == NULL, "Failed to handle null data argument");
1259 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1260 strerror(errno), errno);
1261
1262 /* Empty string. */
1263 str = (const unsigned char *) "foobar";
1264 expected = "";
1265 res = pr_str_bin2hex(p, (const unsigned char *) str, 0, 0);
1266 fail_unless(res != NULL, "Failed to hexify '%s': %s", str, strerror(errno));
1267 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'",
1268 expected, res);
1269
1270 /* default (lowercase) */
1271 expected = "666f6f626172";
1272 res = pr_str_bin2hex(p, str, strlen((char *) str), 0);
1273 fail_unless(res != NULL, "Failed to hexify '%s': %s", str, strerror(errno));
1274 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'",
1275 expected, res);
1276
1277 /* lowercase */
1278 expected = "666f6f626172";
1279 res = pr_str_bin2hex(p, str, strlen((char *) str), 0);
1280 fail_unless(res != NULL, "Failed to hexify '%s': %s", str, strerror(errno));
1281 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'",
1282 expected, res);
1283
1284 /* uppercase */
1285 expected = "666F6F626172";
1286 res = pr_str_bin2hex(p, str, strlen((char *) str), PR_STR_FL_HEX_USE_UC);
1287 fail_unless(res != NULL, "Failed to hexify '%s': %s", str, strerror(errno));
1288 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'",
1289 expected, res);
1290 }
1291 END_TEST
1292
START_TEST(hex2bin_test)1293 START_TEST (hex2bin_test) {
1294 unsigned char *expected, *res;
1295 const unsigned char *hex;
1296 size_t expected_len, hex_len, len;
1297
1298 res = pr_str_hex2bin(NULL, NULL, 0, NULL);
1299 fail_unless(res == NULL, "Failed to handle null arguments");
1300 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1301 strerror(errno), errno);
1302
1303 res = pr_str_hex2bin(p, NULL, 0, 0);
1304 fail_unless(res == NULL, "Failed to handle null data argument");
1305 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1306 strerror(errno), errno);
1307
1308 /* Empty string. */
1309 hex = (const unsigned char *) "";
1310 hex_len = strlen((char *) hex);
1311 expected = (unsigned char *) "";
1312 res = pr_str_hex2bin(p, hex, hex_len, &len);
1313 fail_unless(res != NULL, "Failed to unhexify '%s': %s", hex, strerror(errno));
1314 fail_unless(strcmp((const char *) res, (const char *) expected) == 0,
1315 "Expected '%s', got '%s'", expected, res);
1316
1317 hex = (const unsigned char *) "112233";
1318 hex_len = strlen((char *) hex);
1319 expected_len = 3;
1320 expected = palloc(p, expected_len);
1321 expected[0] = 17;
1322 expected[1] = 34;
1323 expected[2] = 51;
1324
1325 res = pr_str_hex2bin(p, (const unsigned char *) hex, hex_len, &len);
1326 fail_unless(res != NULL, "Failed to unhexify '%s': %s", hex, strerror(errno));
1327 fail_unless(len == expected_len, "Expected len %lu, got %lu",
1328 (unsigned long) expected_len, len);
1329 fail_unless(memcmp(res, expected, len) == 0,
1330 "Did not receive expected unhexified data");
1331
1332 /* lowercase */
1333 hex = (const unsigned char *) "666f6f626172";
1334 hex_len = strlen((char *) hex);
1335 expected_len = 6;
1336 expected = palloc(p, expected_len);
1337 expected[0] = 'f';
1338 expected[1] = 'o';
1339 expected[2] = 'o';
1340 expected[3] = 'b';
1341 expected[4] = 'a';
1342 expected[5] = 'r';
1343
1344 res = pr_str_hex2bin(p, (const unsigned char *) hex, hex_len, &len);
1345 fail_unless(res != NULL, "Failed to unhexify '%s': %s", hex, strerror(errno));
1346 fail_unless(len == expected_len, "Expected len %lu, got %lu",
1347 (unsigned long) expected_len, len);
1348 fail_unless(memcmp(res, expected, len) == 0,
1349 "Did not receive expected unhexified data");
1350
1351 /* uppercase */
1352 hex = (const unsigned char *) "666F6F626172";
1353 hex_len = strlen((char *) hex);
1354
1355 res = pr_str_hex2bin(p, (const unsigned char *) hex, hex_len, &len);
1356 fail_unless(res != NULL, "Failed to unhexify '%s': %s", hex, strerror(errno));
1357 fail_unless(len == expected_len, "Expected len %lu, got %lu",
1358 (unsigned long) expected_len, len);
1359 fail_unless(memcmp(res, expected, len) == 0,
1360 "Did not receive expected unhexified data");
1361
1362 /* Handle known not-hex data properly. */
1363 hex = (const unsigned char *) "Hello, World!\n";
1364 hex_len = strlen((char *) hex);
1365 res = pr_str_hex2bin(p, hex, hex_len, &len);
1366 fail_unless(res == NULL, "Successfully unhexified '%s' unexpectedly", hex);
1367 fail_unless(errno == ERANGE, "Expected ERANGE (%d), got %s (%d)", ERANGE,
1368 strerror(errno), errno);
1369 }
1370 END_TEST
1371
START_TEST(levenshtein_test)1372 START_TEST (levenshtein_test) {
1373 int res, expected, flags = 0;
1374 const char *a, *b;
1375
1376 mark_point();
1377 res = pr_str_levenshtein(NULL, NULL, NULL, 0, 0, 0, 0, flags);
1378 fail_unless(res < 0, "Failed to handle null pool");
1379 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1380 strerror(errno), errno);
1381
1382 mark_point();
1383 res = pr_str_levenshtein(p, NULL, NULL, 0, 0, 0, 0, flags);
1384 fail_unless(res < 0, "Failed to handle null a string");
1385 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1386 strerror(errno), errno);
1387
1388 a = "foo";
1389
1390 mark_point();
1391 res = pr_str_levenshtein(p, a, NULL, 0, 0, 0, 0, flags);
1392 fail_unless(res < 0, "Failed to handle null b string");
1393 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1394 strerror(errno), errno);
1395
1396 expected = 0;
1397 b = "Foo";
1398
1399 mark_point();
1400 res = pr_str_levenshtein(p, a, b, 0, 0, 0, 0, flags);
1401 fail_if(res < 0,
1402 "Failed to compute Levenshtein distance from '%s' to '%s': %s", a, b,
1403 strerror(errno));
1404 fail_unless(expected == res, "Expected distance %d, got %d", expected, res);
1405
1406 expected = 3;
1407 b = "Foo";
1408 res = pr_str_levenshtein(p, a, b, 0, 1, 1, 1, flags);
1409 fail_if(res < 0,
1410 "Failed to compute Levenshtein distance from '%s' to '%s': %s", a, b,
1411 strerror(errno));
1412 fail_unless(expected == res, "Expected distance %d, got %d", expected, res);
1413
1414 flags = PR_STR_FL_IGNORE_CASE;
1415 expected = 2;
1416 b = "Foo";
1417 res = pr_str_levenshtein(p, a, b, 0, 1, 1, 1, flags);
1418 fail_if(res < 0,
1419 "Failed to compute Levenshtein distance from '%s' to '%s': %s", a, b,
1420 strerror(errno));
1421 fail_unless(expected == res, "Expected distance %d, got %d", expected, res);
1422 }
1423 END_TEST
1424
START_TEST(similars_test)1425 START_TEST (similars_test) {
1426 array_header *res, *candidates;
1427 const char *s, **similars, *expected;
1428
1429 mark_point();
1430 res = pr_str_get_similars(NULL, NULL, NULL, 0, 0);
1431 fail_unless(res == NULL, "Failed to handle null pool");
1432 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1433 strerror(errno), errno);
1434
1435 mark_point();
1436 res = pr_str_get_similars(p, NULL, NULL, 0, 0);
1437 fail_unless(res == NULL, "Failed to handle null string");
1438 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1439 strerror(errno), errno);
1440
1441 s = "foo";
1442
1443 mark_point();
1444 res = pr_str_get_similars(p, s, NULL, 0, 0);
1445 fail_unless(res == NULL, "Failed to handle null candidates");
1446 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1447 strerror(errno), errno);
1448
1449 candidates = make_array(p, 5, sizeof(const char *));
1450
1451 mark_point();
1452 res = pr_str_get_similars(p, s, candidates, 0, 0);
1453 fail_unless(res == NULL, "Failed to handle empty candidates");
1454 fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1455 strerror(errno), errno);
1456
1457 *((const char **) push_array(candidates)) = pstrdup(p, "fools");
1458 *((const char **) push_array(candidates)) = pstrdup(p, "odd");
1459 *((const char **) push_array(candidates)) = pstrdup(p, "bar");
1460 *((const char **) push_array(candidates)) = pstrdup(p, "FOO");
1461
1462 mark_point();
1463 res = pr_str_get_similars(p, s, candidates, 0, 0);
1464 fail_unless(res != NULL, "Failed to find similar strings to '%s': %s", s,
1465 strerror(errno));
1466 fail_unless(res->nelts > 0, "Expected >0 similar strings, got %u",
1467 res->nelts);
1468
1469 mark_point();
1470 similars = (const char **) res->elts;
1471
1472 /*
1473 * Note: expected distances are as follows:
1474 *
1475 * Candidate Case-Sensitive Case-Insensitive
1476 * fools 0 0
1477 * odd 5 5
1478 * bar 5 5
1479 * FOO 5 0
1480 */
1481
1482 expected = "fools";
1483
1484 fail_unless(strcmp(similars[0], expected) == 0,
1485 "Expected similar '%s', got '%s'", expected, similars[0]);
1486
1487 fail_unless(strcmp(similars[1], expected) != 0,
1488 "Unexpectedly got similar '%s'", similars[1]);
1489
1490 mark_point();
1491 res = pr_str_get_similars(p, s, candidates, 0, PR_STR_FL_IGNORE_CASE);
1492 fail_unless(res != NULL, "Failed to find similar strings to '%s': %s", s,
1493 strerror(errno));
1494 fail_unless(res->nelts > 0, "Expected >0 similar strings, got %u",
1495 res->nelts);
1496
1497 mark_point();
1498 similars = (const char **) res->elts;
1499
1500 /*
1501 * similars[0] and similars[1] should be "FOO" and "fools", but
1502 * not necessarily in that order
1503 */
1504 expected = "FOO";
1505 if (strcmp(similars[0], expected) != 0) {
1506 expected = similars[0];
1507 similars[0] = similars[1];
1508 similars[1] = expected;
1509 expected = "FOO";
1510 }
1511
1512 fail_unless(strcmp(similars[0], expected) == 0,
1513 "Expected similar '%s', got '%s'", expected, similars[0]);
1514
1515 expected = "fools";
1516
1517 fail_unless(strcmp(similars[1], expected) == 0,
1518 "Expected similar '%s', got '%s'", expected, similars[1]);
1519 }
1520 END_TEST
1521
START_TEST(str2uid_test)1522 START_TEST (str2uid_test) {
1523 int res;
1524
1525 res = pr_str2uid(NULL, NULL);
1526 fail_unless(res == -1, "Failed to handle null arguments");
1527 }
1528 END_TEST
1529
START_TEST(str2gid_test)1530 START_TEST (str2gid_test) {
1531 int res;
1532
1533 res = pr_str2gid(NULL, NULL);
1534 fail_unless(res == -1, "Failed to handle null arguments");
1535 }
1536 END_TEST
1537
START_TEST(uid2str_test)1538 START_TEST (uid2str_test) {
1539 const char *res;
1540
1541 res = pr_uid2str(NULL, (uid_t) 1);
1542 fail_unless(strcmp(res, "1") == 0, "Expected '1', got '%s'", res);
1543
1544 res = pr_uid2str(NULL, (uid_t) -1);
1545 fail_unless(strcmp(res, "-1") == 0, "Expected '-1', got '%s'", res);
1546 }
1547 END_TEST
1548
START_TEST(gid2str_test)1549 START_TEST (gid2str_test) {
1550 const char *res;
1551
1552 res = pr_gid2str(NULL, (gid_t) 1);
1553 fail_unless(strcmp(res, "1") == 0, "Expected '1', got '%s'", res);
1554
1555 res = pr_gid2str(NULL, (gid_t) -1);
1556 fail_unless(strcmp(res, "-1") == 0, "Expected '-1', got '%s'", res);
1557 }
1558 END_TEST
1559
START_TEST(str_quote_test)1560 START_TEST (str_quote_test) {
1561 const char *res;
1562 char *expected, *path;
1563
1564 res = pr_str_quote(NULL, NULL);
1565 fail_unless(res == NULL, "Failed to handle null arguments");
1566 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1567 strerror(errno), errno);
1568
1569 res = pr_str_quote(p, NULL);
1570 fail_unless(res == NULL, "Failed to handle null path argument");
1571 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1572 strerror(errno), errno);
1573
1574 path = "/tmp/";
1575 expected = path;
1576 res = pr_str_quote(p, path);
1577 fail_unless(res != NULL, "Failed to quote '%s': %s", path, strerror(errno));
1578 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1579 res);
1580
1581 path = "/\"tmp\"/";
1582 expected = "/\"\"tmp\"\"/";
1583 res = pr_str_quote(p, path);
1584 fail_unless(res != NULL, "Failed to quote '%s': %s", path, strerror(errno));
1585 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1586 res);
1587 }
1588 END_TEST
1589
START_TEST(quote_dir_test)1590 START_TEST (quote_dir_test) {
1591 const char *res;
1592 char *expected, *path;
1593
1594 res = quote_dir(NULL, NULL);
1595 fail_unless(res == NULL, "Failed to handle null arguments");
1596 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1597 strerror(errno), errno);
1598
1599 res = quote_dir(p, NULL);
1600 fail_unless(res == NULL, "Failed to handle null path argument");
1601 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1602 strerror(errno), errno);
1603
1604 path = "/tmp/";
1605 expected = path;
1606 res = quote_dir(p, path);
1607 fail_unless(res != NULL, "Failed to quote '%s': %s", path, strerror(errno));
1608 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1609 res);
1610
1611 path = "/\"tmp\"/";
1612 expected = "/\"\"tmp\"\"/";
1613 res = quote_dir(p, path);
1614 fail_unless(res != NULL, "Failed to quote '%s': %s", path, strerror(errno));
1615 fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1616 res);
1617 }
1618 END_TEST
1619
START_TEST(text_to_array_test)1620 START_TEST (text_to_array_test) {
1621 register unsigned int i;
1622 array_header *res;
1623 const char *text;
1624
1625 mark_point();
1626 res = pr_str_text_to_array(NULL, NULL, ',');
1627 fail_unless(res == NULL, "Failed to handle null pool");
1628 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1629 strerror(errno), errno);
1630
1631 mark_point();
1632 res = pr_str_text_to_array(p, NULL, ',');
1633 fail_unless(res == NULL, "Failed to handle null text");
1634 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1635 strerror(errno), errno);
1636
1637 text = "";
1638
1639 mark_point();
1640 res = pr_str_text_to_array(p, text, ',');
1641 fail_unless(res != NULL, "Failed to handle text '%s': %s", text,
1642 strerror(errno));
1643 fail_unless(res->nelts == 0, "Expected 0 items, got %u", res->nelts);
1644
1645 text = ",";
1646
1647 mark_point();
1648 res = pr_str_text_to_array(p, text, ',');
1649 fail_unless(res != NULL, "Failed to handle text '%s': %s", text,
1650 strerror(errno));
1651 fail_unless(res->nelts == 0, "Expected 0 items, got %u", res->nelts);
1652
1653 text = ",,,";
1654
1655 mark_point();
1656 res = pr_str_text_to_array(p, text, ',');
1657 fail_unless(res != NULL, "Failed to handle text '%s': %s", text,
1658 strerror(errno));
1659 fail_unless(res->nelts == 0, "Expected 0 items, got %u", res->nelts);
1660
1661 text = "foo";
1662
1663 mark_point();
1664 res = pr_str_text_to_array(p, text, ',');
1665 fail_unless(res != NULL, "Failed to handle text '%s': %s", text,
1666 strerror(errno));
1667 fail_unless(res->nelts == 1, "Expected 1 item, got %u", res->nelts);
1668
1669 text = "foo,foo,foo";
1670
1671 mark_point();
1672 res = pr_str_text_to_array(p, text, ',');
1673 fail_unless(res != NULL, "Failed to handle text '%s': %s", text,
1674 strerror(errno));
1675 fail_unless(res->nelts == 3, "Expected 3 items, got %u", res->nelts);
1676 for (i = 0; i < res->nelts; i++) {
1677 char *item, *expected;
1678
1679 item = ((char **) res->elts)[i];
1680 fail_unless(item != NULL, "Expected item at index %u, got null", i);
1681
1682 expected = "foo";
1683 fail_unless(strcmp(item, expected) == 0,
1684 "Expected '%s' at index %u, got '%s'", expected, i, item);
1685 }
1686
1687 text = "foo,foo,foo,";
1688
1689 mark_point();
1690 res = pr_str_text_to_array(p, text, ',');
1691 fail_unless(res != NULL, "Failed to handle text '%s': %s", text,
1692 strerror(errno));
1693 fail_unless(res->nelts == 3, "Expected 3 items, got %u", res->nelts);
1694 for (i = 0; i < res->nelts; i++) {
1695 char *item, *expected;
1696
1697 item = ((char **) res->elts)[i];
1698 fail_unless(item != NULL, "Expected item at index %u, got null", i);
1699
1700 if (i == 3) {
1701 expected = "";
1702
1703 } else {
1704 expected = "foo";
1705 }
1706
1707 fail_unless(strcmp(item, expected) == 0,
1708 "Expected '%s' at index %u, got '%s'", expected, i, item);
1709 }
1710
1711 text = "foo|foo|foo";
1712
1713 mark_point();
1714 res = pr_str_text_to_array(p, text, '|');
1715 fail_unless(res != NULL, "Failed to handle text '%s': %s", text,
1716 strerror(errno));
1717 fail_unless(res->nelts == 3, "Expected 3 items, got %u", res->nelts);
1718 for (i = 0; i < res->nelts; i++) {
1719 char *item, *expected;
1720
1721 item = ((char **) res->elts)[i];
1722 fail_unless(item != NULL, "Expected item at index %u, got null", i);
1723
1724 expected = "foo";
1725 fail_unless(strcmp(item, expected) == 0,
1726 "Expected '%s' at index %u, got '%s'", expected, i, item);
1727 }
1728 }
1729 END_TEST
1730
tests_get_str_suite(void)1731 Suite *tests_get_str_suite(void) {
1732 Suite *suite;
1733 TCase *testcase;
1734
1735 suite = suite_create("str");
1736
1737 testcase = tcase_create("base");
1738 tcase_add_checked_fixture(testcase, set_up, tear_down);
1739
1740 tcase_add_test(testcase, sstrncpy_test);
1741 tcase_add_test(testcase, sstrcat_test);
1742 tcase_add_test(testcase, sreplace_test);
1743 tcase_add_test(testcase, sreplace_enospc_test);
1744 tcase_add_test(testcase, sreplace_bug3614_test);
1745 tcase_add_test(testcase, str_replace_test);
1746 tcase_add_test(testcase, pdircat_test);
1747 tcase_add_test(testcase, pstrcat_test);
1748 tcase_add_test(testcase, pstrdup_test);
1749 tcase_add_test(testcase, pstrndup_test);
1750 tcase_add_test(testcase, strip_test);
1751 tcase_add_test(testcase, strip_end_test);
1752 tcase_add_test(testcase, get_token_test);
1753 tcase_add_test(testcase, get_token2_test);
1754 tcase_add_test(testcase, get_word_test);
1755 tcase_add_test(testcase, get_word_utf8_test);
1756 tcase_add_test(testcase, is_boolean_test);
1757 tcase_add_test(testcase, is_fnmatch_test);
1758 tcase_add_test(testcase, get_nbytes_test);
1759 tcase_add_test(testcase, get_duration_test);
1760 tcase_add_test(testcase, bin2hex_test);
1761 tcase_add_test(testcase, hex2bin_test);
1762 tcase_add_test(testcase, levenshtein_test);
1763 tcase_add_test(testcase, similars_test);
1764 tcase_add_test(testcase, strnrstr_test);
1765 tcase_add_test(testcase, str2uid_test);
1766 tcase_add_test(testcase, str2gid_test);
1767 tcase_add_test(testcase, uid2str_test);
1768 tcase_add_test(testcase, gid2str_test);
1769 tcase_add_test(testcase, str_quote_test);
1770 tcase_add_test(testcase, quote_dir_test);
1771 tcase_add_test(testcase, text_to_array_test);
1772
1773 suite_add_tcase(suite, testcase);
1774 return suite;
1775 }
1776