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