1 /*
2 * SPDX-License-Identifier: ISC
3 *
4 * Copyright (c) 2015 Todd C. Miller <Todd.Miller@sudo.ws>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /*
20 * This is an open source non-commercial project. Dear PVS-Studio, please check it.
21 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
22 */
23
24 #include <config.h>
25
26 #include "sudo_compat.h"
27 #include "sudo_debug.h"
28 #include "sudo_util.h"
29
30 /*
31 * Like strtok_r but non-destructive and works w/o a NUL terminator.
32 * TODO: Optimize by storing current char in a variable ch
33 */
34 const char *
sudo_strsplit_v1(const char * str,const char * endstr,const char * sep,const char ** last)35 sudo_strsplit_v1(const char *str, const char *endstr, const char *sep, const char **last)
36 {
37 const char *cp, *s;
38 debug_decl(sudo_strsplit, SUDO_DEBUG_UTIL);
39
40 /* If no str specified, use last ptr (if any). */
41 if (str == NULL)
42 str = *last;
43
44 /* Skip leading separator characters. */
45 while (str < endstr) {
46 for (s = sep; *s != '\0'; s++) {
47 if (*str == *s) {
48 str++;
49 break;
50 }
51 }
52 if (*s == '\0')
53 break;
54 }
55
56 /* Empty string? */
57 if (str >= endstr) {
58 *last = endstr;
59 debug_return_ptr(NULL);
60 }
61
62 /* Scan str until we hit a char from sep. */
63 for (cp = str; cp < endstr; cp++) {
64 for (s = sep; *s != '\0'; s++) {
65 if (*cp == *s)
66 break;
67 }
68 if (*s != '\0')
69 break;
70 }
71 *last = cp;
72 debug_return_const_ptr(str);
73 }
74