1 /* 	$OpenBSD: test_argv.c,v 1.4 2021/12/14 21:25:27 deraadt Exp $ */
2 /*
3  * Regress test for misc argv handling functions.
4  *
5  * Placed in the public domain.
6  */
7 
8 #include "includes.h"
9 
10 #include <sys/types.h>
11 #include <stdio.h>
12 #ifdef HAVE_STDINT_H
13 #include <stdint.h>
14 #endif
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include "../test_helper/test_helper.h"
19 
20 #include "log.h"
21 #include "misc.h"
22 
23 void test_argv(void);
24 
25 void
26 test_argv(void)
27 {
28 	char **av = NULL;
29 	int ac = 0;
30 
31 #define RESET_ARGV() \
32 	do { \
33 		argv_free(av, ac); \
34 		av = NULL; \
35 		ac = -1; \
36 	} while (0)
37 
38 	TEST_START("empty args");
39 	ASSERT_INT_EQ(argv_split("", &ac, &av, 0), 0);
40 	ASSERT_INT_EQ(ac, 0);
41 	ASSERT_PTR_NE(av, NULL);
42 	ASSERT_PTR_EQ(av[0], NULL);
43 	RESET_ARGV();
44 	ASSERT_INT_EQ(argv_split("    ", &ac, &av, 0), 0);
45 	ASSERT_INT_EQ(ac, 0);
46 	ASSERT_PTR_NE(av, NULL);
47 	ASSERT_PTR_EQ(av[0], NULL);
48 	RESET_ARGV();
49 	TEST_DONE();
50 
51 	TEST_START("trivial args");
52 	ASSERT_INT_EQ(argv_split("leamas", &ac, &av, 0), 0);
53 	ASSERT_INT_EQ(ac, 1);
54 	ASSERT_PTR_NE(av, NULL);
55 	ASSERT_STRING_EQ(av[0], "leamas");
56 	ASSERT_PTR_EQ(av[1], NULL);
57 	RESET_ARGV();
58 	ASSERT_INT_EQ(argv_split("smiley leamas", &ac, &av, 0), 0);
59 	ASSERT_INT_EQ(ac, 2);
60 	ASSERT_PTR_NE(av, NULL);
61 	ASSERT_STRING_EQ(av[0], "smiley");
62 	ASSERT_STRING_EQ(av[1], "leamas");
63 	ASSERT_PTR_EQ(av[2], NULL);
64 	RESET_ARGV();
65 	TEST_DONE();
66 
67 	TEST_START("quoted");
68 	ASSERT_INT_EQ(argv_split("\"smiley\"", &ac, &av, 0), 0);
69 	ASSERT_INT_EQ(ac, 1);
70 	ASSERT_PTR_NE(av, NULL);
71 	ASSERT_STRING_EQ(av[0], "smiley");
72 	ASSERT_PTR_EQ(av[1], NULL);
73 	RESET_ARGV();
74 	ASSERT_INT_EQ(argv_split("leamas \" smiley \"", &ac, &av, 0), 0);
75 	ASSERT_INT_EQ(ac, 2);
76 	ASSERT_PTR_NE(av, NULL);
77 	ASSERT_STRING_EQ(av[0], "leamas");
78 	ASSERT_STRING_EQ(av[1], " smiley ");
79 	ASSERT_PTR_EQ(av[2], NULL);
80 	RESET_ARGV();
81 	ASSERT_INT_EQ(argv_split("\"smiley leamas\"", &ac, &av, 0), 0);
82 	ASSERT_INT_EQ(ac, 1);
83 	ASSERT_PTR_NE(av, NULL);
84 	ASSERT_STRING_EQ(av[0], "smiley leamas");
85 	ASSERT_PTR_EQ(av[1], NULL);
86 	RESET_ARGV();
87 	ASSERT_INT_EQ(argv_split("smiley\" leamas\" liz", &ac, &av, 0), 0);
88 	ASSERT_INT_EQ(ac, 2);
89 	ASSERT_PTR_NE(av, NULL);
90 	ASSERT_STRING_EQ(av[0], "smiley leamas");
91 	ASSERT_STRING_EQ(av[1], "liz");
92 	ASSERT_PTR_EQ(av[2], NULL);
93 	RESET_ARGV();
94 	TEST_DONE();
95 
96 	TEST_START("escaped");
97 	ASSERT_INT_EQ(argv_split("\\\"smiley\\'", &ac, &av, 0), 0);
98 	ASSERT_INT_EQ(ac, 1);
99 	ASSERT_PTR_NE(av, NULL);
100 	ASSERT_STRING_EQ(av[0], "\"smiley'");
101 	ASSERT_PTR_EQ(av[1], NULL);
102 	RESET_ARGV();
103 	ASSERT_INT_EQ(argv_split("'\\'smiley\\\"'", &ac, &av, 0), 0);
104 	ASSERT_INT_EQ(ac, 1);
105 	ASSERT_PTR_NE(av, NULL);
106 	ASSERT_STRING_EQ(av[0], "'smiley\"");
107 	ASSERT_PTR_EQ(av[1], NULL);
108 	RESET_ARGV();
109 	ASSERT_INT_EQ(argv_split("smiley\\'s leamas\\'", &ac, &av, 0), 0);
110 	ASSERT_INT_EQ(ac, 2);
111 	ASSERT_PTR_NE(av, NULL);
112 	ASSERT_STRING_EQ(av[0], "smiley's");
113 	ASSERT_STRING_EQ(av[1], "leamas'");
114 	ASSERT_PTR_EQ(av[2], NULL);
115 	RESET_ARGV();
116 	ASSERT_INT_EQ(argv_split("leamas\\\\smiley", &ac, &av, 0), 0);
117 	ASSERT_INT_EQ(ac, 1);
118 	ASSERT_PTR_NE(av, NULL);
119 	ASSERT_STRING_EQ(av[0], "leamas\\smiley");
120 	ASSERT_PTR_EQ(av[1], NULL);
121 	RESET_ARGV();
122 	ASSERT_INT_EQ(argv_split("leamas\\\\ \\\\smiley", &ac, &av, 0), 0);
123 	ASSERT_INT_EQ(ac, 2);
124 	ASSERT_PTR_NE(av, NULL);
125 	ASSERT_STRING_EQ(av[0], "leamas\\");
126 	ASSERT_STRING_EQ(av[1], "\\smiley");
127 	ASSERT_PTR_EQ(av[2], NULL);
128 	RESET_ARGV();
129 	ASSERT_INT_EQ(argv_split("smiley\\ leamas", &ac, &av, 0), 0);
130 	ASSERT_INT_EQ(ac, 1);
131 	ASSERT_PTR_NE(av, NULL);
132 	ASSERT_STRING_EQ(av[0], "smiley leamas");
133 	ASSERT_PTR_EQ(av[1], NULL);
134 	RESET_ARGV();
135 	TEST_DONE();
136 
137 	TEST_START("quoted escaped");
138 	ASSERT_INT_EQ(argv_split("'smiley\\ leamas'", &ac, &av, 0), 0);
139 	ASSERT_INT_EQ(ac, 1);
140 	ASSERT_PTR_NE(av, NULL);
141 	ASSERT_STRING_EQ(av[0], "smiley\\ leamas");
142 	ASSERT_PTR_EQ(av[1], NULL);
143 	RESET_ARGV();
144 	ASSERT_INT_EQ(argv_split("\"smiley\\ leamas\"", &ac, &av, 0), 0);
145 	ASSERT_INT_EQ(ac, 1);
146 	ASSERT_PTR_NE(av, NULL);
147 	ASSERT_STRING_EQ(av[0], "smiley\\ leamas");
148 	ASSERT_PTR_EQ(av[1], NULL);
149 	RESET_ARGV();
150 	TEST_DONE();
151 
152 	TEST_START("comments");
153 	ASSERT_INT_EQ(argv_split("# gold", &ac, &av, 0), 0);
154 	ASSERT_INT_EQ(ac, 2);
155 	ASSERT_PTR_NE(av, NULL);
156 	ASSERT_STRING_EQ(av[0], "#");
157 	ASSERT_STRING_EQ(av[1], "gold");
158 	ASSERT_PTR_EQ(av[2], NULL);
159 	RESET_ARGV();
160 	ASSERT_INT_EQ(argv_split("# gold", &ac, &av, 1), 0);
161 	ASSERT_INT_EQ(ac, 0);
162 	ASSERT_PTR_NE(av, NULL);
163 	ASSERT_PTR_EQ(av[0], NULL);
164 	RESET_ARGV();
165 	ASSERT_INT_EQ(argv_split("leamas#gold", &ac, &av, 1), 0);
166 	ASSERT_INT_EQ(ac, 1);
167 	ASSERT_PTR_NE(av, NULL);
168 	ASSERT_STRING_EQ(av[0], "leamas#gold");
169 	ASSERT_PTR_EQ(av[1], NULL);
170 	RESET_ARGV();
171 	ASSERT_INT_EQ(argv_split("\"leamas # gold\"", &ac, &av, 1), 0);
172 	ASSERT_INT_EQ(ac, 1);
173 	ASSERT_PTR_NE(av, NULL);
174 	ASSERT_STRING_EQ(av[0], "leamas # gold");
175 	ASSERT_PTR_EQ(av[1], NULL);
176 	RESET_ARGV();
177 	ASSERT_INT_EQ(argv_split("\"leamas\"#gold", &ac, &av, 1), 0);
178 	ASSERT_INT_EQ(ac, 1);
179 	ASSERT_PTR_NE(av, NULL);
180 	ASSERT_STRING_EQ(av[0], "leamas#gold");
181 	ASSERT_PTR_EQ(av[1], NULL);
182 	RESET_ARGV();
183 	TEST_DONE();
184 
185 	/* XXX test char *argv_assemble(int argc, char **argv) */
186 }
187