]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strv.c
tree-wide: make new/new0/malloc_multiply/reallocarray safe for size 0
[thirdparty/systemd.git] / src / basic / strv.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <fnmatch.h>
5 #include <stdarg.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "alloc-util.h"
11 #include "escape.h"
12 #include "extract-word.h"
13 #include "fileio.h"
14 #include "string-util.h"
15 #include "strv.h"
16 #include "util.h"
17
18 char *strv_find(char **l, const char *name) {
19 char **i;
20
21 assert(name);
22
23 STRV_FOREACH(i, l)
24 if (streq(*i, name))
25 return *i;
26
27 return NULL;
28 }
29
30 char *strv_find_prefix(char **l, const char *name) {
31 char **i;
32
33 assert(name);
34
35 STRV_FOREACH(i, l)
36 if (startswith(*i, name))
37 return *i;
38
39 return NULL;
40 }
41
42 char *strv_find_startswith(char **l, const char *name) {
43 char **i, *e;
44
45 assert(name);
46
47 /* Like strv_find_prefix, but actually returns only the
48 * suffix, not the whole item */
49
50 STRV_FOREACH(i, l) {
51 e = startswith(*i, name);
52 if (e)
53 return e;
54 }
55
56 return NULL;
57 }
58
59 void strv_clear(char **l) {
60 char **k;
61
62 if (!l)
63 return;
64
65 for (k = l; *k; k++)
66 free(*k);
67
68 *l = NULL;
69 }
70
71 char **strv_free(char **l) {
72 strv_clear(l);
73 return mfree(l);
74 }
75
76 char **strv_free_erase(char **l) {
77 char **i;
78
79 STRV_FOREACH(i, l)
80 string_erase(*i);
81
82 return strv_free(l);
83 }
84
85 char **strv_copy(char * const *l) {
86 char **r, **k;
87
88 k = r = new(char*, strv_length(l) + 1);
89 if (!r)
90 return NULL;
91
92 if (l)
93 for (; *l; k++, l++) {
94 *k = strdup(*l);
95 if (!*k) {
96 strv_free(r);
97 return NULL;
98 }
99 }
100
101 *k = NULL;
102 return r;
103 }
104
105 size_t strv_length(char * const *l) {
106 size_t n = 0;
107
108 if (!l)
109 return 0;
110
111 for (; *l; l++)
112 n++;
113
114 return n;
115 }
116
117 char **strv_new_ap(const char *x, va_list ap) {
118 const char *s;
119 _cleanup_strv_free_ char **a = NULL;
120 size_t n = 0, i = 0;
121 va_list aq;
122
123 /* As a special trick we ignore all listed strings that equal
124 * STRV_IGNORE. This is supposed to be used with the
125 * STRV_IFNOTNULL() macro to include possibly NULL strings in
126 * the string list. */
127
128 if (x) {
129 n = x == STRV_IGNORE ? 0 : 1;
130
131 va_copy(aq, ap);
132 while ((s = va_arg(aq, const char*))) {
133 if (s == STRV_IGNORE)
134 continue;
135
136 n++;
137 }
138
139 va_end(aq);
140 }
141
142 a = new(char*, n+1);
143 if (!a)
144 return NULL;
145
146 if (x) {
147 if (x != STRV_IGNORE) {
148 a[i] = strdup(x);
149 if (!a[i])
150 return NULL;
151 i++;
152 }
153
154 while ((s = va_arg(ap, const char*))) {
155
156 if (s == STRV_IGNORE)
157 continue;
158
159 a[i] = strdup(s);
160 if (!a[i])
161 return NULL;
162
163 i++;
164 }
165 }
166
167 a[i] = NULL;
168
169 return TAKE_PTR(a);
170 }
171
172 char **strv_new_internal(const char *x, ...) {
173 char **r;
174 va_list ap;
175
176 va_start(ap, x);
177 r = strv_new_ap(x, ap);
178 va_end(ap);
179
180 return r;
181 }
182
183 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
184 char **s, **t;
185 size_t p, q, i = 0, j;
186
187 assert(a);
188
189 if (strv_isempty(b))
190 return 0;
191
192 p = strv_length(*a);
193 q = strv_length(b);
194
195 t = reallocarray(*a, p + q + 1, sizeof(char *));
196 if (!t)
197 return -ENOMEM;
198
199 t[p] = NULL;
200 *a = t;
201
202 STRV_FOREACH(s, b) {
203
204 if (filter_duplicates && strv_contains(t, *s))
205 continue;
206
207 t[p+i] = strdup(*s);
208 if (!t[p+i])
209 goto rollback;
210
211 i++;
212 t[p+i] = NULL;
213 }
214
215 assert(i <= q);
216
217 return (int) i;
218
219 rollback:
220 for (j = 0; j < i; j++)
221 free(t[p + j]);
222
223 t[p] = NULL;
224 return -ENOMEM;
225 }
226
227 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
228 int r;
229 char **s;
230
231 STRV_FOREACH(s, b) {
232 char *v;
233
234 v = strappend(*s, suffix);
235 if (!v)
236 return -ENOMEM;
237
238 r = strv_push(a, v);
239 if (r < 0) {
240 free(v);
241 return r;
242 }
243 }
244
245 return 0;
246 }
247
248 char **strv_split_full(const char *s, const char *separator, SplitFlags flags) {
249 const char *word, *state;
250 size_t l;
251 size_t n, i;
252 char **r;
253
254 assert(s);
255
256 if (!separator)
257 separator = WHITESPACE;
258
259 s += strspn(s, separator);
260 if (isempty(s))
261 return new0(char*, 1);
262
263 n = 0;
264 _FOREACH_WORD(word, l, s, separator, flags, state)
265 n++;
266
267 r = new(char*, n+1);
268 if (!r)
269 return NULL;
270
271 i = 0;
272 _FOREACH_WORD(word, l, s, separator, flags, state) {
273 r[i] = strndup(word, l);
274 if (!r[i]) {
275 strv_free(r);
276 return NULL;
277 }
278
279 i++;
280 }
281
282 r[i] = NULL;
283 return r;
284 }
285
286 char **strv_split_newlines(const char *s) {
287 char **l;
288 size_t n;
289
290 assert(s);
291
292 /* Special version of strv_split() that splits on newlines and
293 * suppresses an empty string at the end */
294
295 l = strv_split(s, NEWLINE);
296 if (!l)
297 return NULL;
298
299 n = strv_length(l);
300 if (n <= 0)
301 return l;
302
303 if (isempty(l[n - 1]))
304 l[n - 1] = mfree(l[n - 1]);
305
306 return l;
307 }
308
309 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
310 _cleanup_strv_free_ char **l = NULL;
311 size_t n = 0, allocated = 0;
312 int r;
313
314 assert(t);
315 assert(s);
316
317 for (;;) {
318 _cleanup_free_ char *word = NULL;
319
320 r = extract_first_word(&s, &word, separators, flags);
321 if (r < 0)
322 return r;
323 if (r == 0)
324 break;
325
326 if (!GREEDY_REALLOC(l, allocated, n + 2))
327 return -ENOMEM;
328
329 l[n++] = TAKE_PTR(word);
330
331 l[n] = NULL;
332 }
333
334 if (!l) {
335 l = new0(char*, 1);
336 if (!l)
337 return -ENOMEM;
338 }
339
340 *t = TAKE_PTR(l);
341
342 return (int) n;
343 }
344
345 char *strv_join_prefix(char **l, const char *separator, const char *prefix) {
346 char *r, *e;
347 char **s;
348 size_t n, k, m;
349
350 if (!separator)
351 separator = " ";
352
353 k = strlen(separator);
354 m = strlen_ptr(prefix);
355
356 n = 0;
357 STRV_FOREACH(s, l) {
358 if (s != l)
359 n += k;
360 n += m + strlen(*s);
361 }
362
363 r = new(char, n+1);
364 if (!r)
365 return NULL;
366
367 e = r;
368 STRV_FOREACH(s, l) {
369 if (s != l)
370 e = stpcpy(e, separator);
371
372 if (prefix)
373 e = stpcpy(e, prefix);
374
375 e = stpcpy(e, *s);
376 }
377
378 *e = 0;
379
380 return r;
381 }
382
383 int strv_push(char ***l, char *value) {
384 char **c;
385 size_t n, m;
386
387 if (!value)
388 return 0;
389
390 n = strv_length(*l);
391
392 /* Increase and check for overflow */
393 m = n + 2;
394 if (m < n)
395 return -ENOMEM;
396
397 c = reallocarray(*l, m, sizeof(char*));
398 if (!c)
399 return -ENOMEM;
400
401 c[n] = value;
402 c[n+1] = NULL;
403
404 *l = c;
405 return 0;
406 }
407
408 int strv_push_pair(char ***l, char *a, char *b) {
409 char **c;
410 size_t n, m;
411
412 if (!a && !b)
413 return 0;
414
415 n = strv_length(*l);
416
417 /* increase and check for overflow */
418 m = n + !!a + !!b + 1;
419 if (m < n)
420 return -ENOMEM;
421
422 c = reallocarray(*l, m, sizeof(char*));
423 if (!c)
424 return -ENOMEM;
425
426 if (a)
427 c[n++] = a;
428 if (b)
429 c[n++] = b;
430 c[n] = NULL;
431
432 *l = c;
433 return 0;
434 }
435
436 int strv_insert(char ***l, size_t position, char *value) {
437 char **c;
438 size_t n, m, i;
439
440 if (!value)
441 return 0;
442
443 n = strv_length(*l);
444 position = MIN(position, n);
445
446 /* increase and check for overflow */
447 m = n + 2;
448 if (m < n)
449 return -ENOMEM;
450
451 c = new(char*, m);
452 if (!c)
453 return -ENOMEM;
454
455 for (i = 0; i < position; i++)
456 c[i] = (*l)[i];
457 c[position] = value;
458 for (i = position; i < n; i++)
459 c[i+1] = (*l)[i];
460
461 c[n+1] = NULL;
462
463 free(*l);
464 *l = c;
465
466 return 0;
467 }
468
469 int strv_consume(char ***l, char *value) {
470 int r;
471
472 r = strv_push(l, value);
473 if (r < 0)
474 free(value);
475
476 return r;
477 }
478
479 int strv_consume_pair(char ***l, char *a, char *b) {
480 int r;
481
482 r = strv_push_pair(l, a, b);
483 if (r < 0) {
484 free(a);
485 free(b);
486 }
487
488 return r;
489 }
490
491 int strv_consume_prepend(char ***l, char *value) {
492 int r;
493
494 r = strv_push_prepend(l, value);
495 if (r < 0)
496 free(value);
497
498 return r;
499 }
500
501 int strv_extend(char ***l, const char *value) {
502 char *v;
503
504 if (!value)
505 return 0;
506
507 v = strdup(value);
508 if (!v)
509 return -ENOMEM;
510
511 return strv_consume(l, v);
512 }
513
514 int strv_extend_front(char ***l, const char *value) {
515 size_t n, m;
516 char *v, **c;
517
518 assert(l);
519
520 /* Like strv_extend(), but prepends rather than appends the new entry */
521
522 if (!value)
523 return 0;
524
525 n = strv_length(*l);
526
527 /* Increase and overflow check. */
528 m = n + 2;
529 if (m < n)
530 return -ENOMEM;
531
532 v = strdup(value);
533 if (!v)
534 return -ENOMEM;
535
536 c = reallocarray(*l, m, sizeof(char*));
537 if (!c) {
538 free(v);
539 return -ENOMEM;
540 }
541
542 memmove(c+1, c, n * sizeof(char*));
543 c[0] = v;
544 c[n+1] = NULL;
545
546 *l = c;
547 return 0;
548 }
549
550 char **strv_uniq(char **l) {
551 char **i;
552
553 /* Drops duplicate entries. The first identical string will be
554 * kept, the others dropped */
555
556 STRV_FOREACH(i, l)
557 strv_remove(i+1, *i);
558
559 return l;
560 }
561
562 bool strv_is_uniq(char **l) {
563 char **i;
564
565 STRV_FOREACH(i, l)
566 if (strv_find(i+1, *i))
567 return false;
568
569 return true;
570 }
571
572 char **strv_remove(char **l, const char *s) {
573 char **f, **t;
574
575 if (!l)
576 return NULL;
577
578 assert(s);
579
580 /* Drops every occurrence of s in the string list, edits
581 * in-place. */
582
583 for (f = t = l; *f; f++)
584 if (streq(*f, s))
585 free(*f);
586 else
587 *(t++) = *f;
588
589 *t = NULL;
590 return l;
591 }
592
593 char **strv_parse_nulstr(const char *s, size_t l) {
594 /* l is the length of the input data, which will be split at NULs into
595 * elements of the resulting strv. Hence, the number of items in the resulting strv
596 * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
597 * unless s[l-1] is NUL, in which case the final empty string is not stored in
598 * the resulting strv, and length is equal to the number of NUL bytes.
599 *
600 * Note that contrary to a normal nulstr which cannot contain empty strings, because
601 * the input data is terminated by any two consequent NUL bytes, this parser accepts
602 * empty strings in s.
603 */
604
605 const char *p;
606 size_t c = 0, i = 0;
607 char **v;
608
609 assert(s || l <= 0);
610
611 if (l <= 0)
612 return new0(char*, 1);
613
614 for (p = s; p < s + l; p++)
615 if (*p == 0)
616 c++;
617
618 if (s[l-1] != 0)
619 c++;
620
621 v = new0(char*, c+1);
622 if (!v)
623 return NULL;
624
625 p = s;
626 while (p < s + l) {
627 const char *e;
628
629 e = memchr(p, 0, s + l - p);
630
631 v[i] = strndup(p, e ? e - p : s + l - p);
632 if (!v[i]) {
633 strv_free(v);
634 return NULL;
635 }
636
637 i++;
638
639 if (!e)
640 break;
641
642 p = e + 1;
643 }
644
645 assert(i == c);
646
647 return v;
648 }
649
650 char **strv_split_nulstr(const char *s) {
651 const char *i;
652 char **r = NULL;
653
654 NULSTR_FOREACH(i, s)
655 if (strv_extend(&r, i) < 0) {
656 strv_free(r);
657 return NULL;
658 }
659
660 if (!r)
661 return strv_new(NULL);
662
663 return r;
664 }
665
666 int strv_make_nulstr(char **l, char **p, size_t *q) {
667 /* A valid nulstr with two NULs at the end will be created, but
668 * q will be the length without the two trailing NULs. Thus the output
669 * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
670 * and can also be parsed by strv_parse_nulstr as long as the length
671 * is provided separately.
672 */
673
674 size_t n_allocated = 0, n = 0;
675 _cleanup_free_ char *m = NULL;
676 char **i;
677
678 assert(p);
679 assert(q);
680
681 STRV_FOREACH(i, l) {
682 size_t z;
683
684 z = strlen(*i);
685
686 if (!GREEDY_REALLOC(m, n_allocated, n + z + 2))
687 return -ENOMEM;
688
689 memcpy(m + n, *i, z + 1);
690 n += z + 1;
691 }
692
693 if (!m) {
694 m = new0(char, 1);
695 if (!m)
696 return -ENOMEM;
697 n = 1;
698 } else
699 /* make sure there is a second extra NUL at the end of resulting nulstr */
700 m[n] = '\0';
701
702 assert(n > 0);
703 *p = m;
704 *q = n - 1;
705
706 m = NULL;
707
708 return 0;
709 }
710
711 bool strv_overlap(char **a, char **b) {
712 char **i;
713
714 STRV_FOREACH(i, a)
715 if (strv_contains(b, *i))
716 return true;
717
718 return false;
719 }
720
721 static int str_compare(char * const *a, char * const *b) {
722 return strcmp(*a, *b);
723 }
724
725 char **strv_sort(char **l) {
726 typesafe_qsort(l, strv_length(l), str_compare);
727 return l;
728 }
729
730 bool strv_equal(char **a, char **b) {
731
732 if (strv_isempty(a))
733 return strv_isempty(b);
734
735 if (strv_isempty(b))
736 return false;
737
738 for ( ; *a || *b; ++a, ++b)
739 if (!streq_ptr(*a, *b))
740 return false;
741
742 return true;
743 }
744
745 void strv_print(char **l) {
746 char **s;
747
748 STRV_FOREACH(s, l)
749 puts(*s);
750 }
751
752 int strv_extendf(char ***l, const char *format, ...) {
753 va_list ap;
754 char *x;
755 int r;
756
757 va_start(ap, format);
758 r = vasprintf(&x, format, ap);
759 va_end(ap);
760
761 if (r < 0)
762 return -ENOMEM;
763
764 return strv_consume(l, x);
765 }
766
767 char **strv_reverse(char **l) {
768 size_t n, i;
769
770 n = strv_length(l);
771 if (n <= 1)
772 return l;
773
774 for (i = 0; i < n / 2; i++)
775 SWAP_TWO(l[i], l[n-1-i]);
776
777 return l;
778 }
779
780 char **strv_shell_escape(char **l, const char *bad) {
781 char **s;
782
783 /* Escapes every character in every string in l that is in bad,
784 * edits in-place, does not roll-back on error. */
785
786 STRV_FOREACH(s, l) {
787 char *v;
788
789 v = shell_escape(*s, bad);
790 if (!v)
791 return NULL;
792
793 free(*s);
794 *s = v;
795 }
796
797 return l;
798 }
799
800 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
801 char* const* p;
802
803 STRV_FOREACH(p, patterns)
804 if (fnmatch(*p, s, flags) == 0)
805 return true;
806
807 return false;
808 }
809
810 char ***strv_free_free(char ***l) {
811 char ***i;
812
813 if (!l)
814 return NULL;
815
816 for (i = l; *i; i++)
817 strv_free(*i);
818
819 return mfree(l);
820 }
821
822 char **strv_skip(char **l, size_t n) {
823
824 while (n > 0) {
825 if (strv_isempty(l))
826 return l;
827
828 l++, n--;
829 }
830
831 return l;
832 }
833
834 int strv_extend_n(char ***l, const char *value, size_t n) {
835 size_t i, j, k;
836 char **nl;
837
838 assert(l);
839
840 if (!value)
841 return 0;
842 if (n == 0)
843 return 0;
844
845 /* Adds the value n times to l */
846
847 k = strv_length(*l);
848
849 nl = reallocarray(*l, k + n + 1, sizeof(char *));
850 if (!nl)
851 return -ENOMEM;
852
853 *l = nl;
854
855 for (i = k; i < k + n; i++) {
856 nl[i] = strdup(value);
857 if (!nl[i])
858 goto rollback;
859 }
860
861 nl[i] = NULL;
862 return 0;
863
864 rollback:
865 for (j = k; j < i; j++)
866 free(nl[j]);
867
868 nl[k] = NULL;
869 return -ENOMEM;
870 }
871
872 int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
873 bool b = false;
874 char **s;
875 int r;
876
877 /* Like fputs(), but for strv, and with a less stupid argument order */
878
879 if (!space)
880 space = &b;
881
882 STRV_FOREACH(s, l) {
883 r = fputs_with_space(f, *s, separator, space);
884 if (r < 0)
885 return r;
886 }
887
888 return 0;
889 }