This source file includes following definitions.
- check_one
- check_all
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21
22 #include "system-quote.h"
23
24 #if defined _WIN32 && !defined __CYGWIN__
25 # define WINDOWS_NATIVE
26 #endif
27
28 #include <limits.h>
29 #include <stdbool.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #ifdef WINDOWS_NATIVE
35 # define WIN32_LEAN_AND_MEAN
36 # include <windows.h>
37 #endif
38
39 #include "macros.h"
40
41 #define EXPECTED_DATA_FILE "t-sq-data.tmp"
42
43 static int failed;
44
45 static void
46 check_one (enum system_command_interpreter interpreter, const char *prog,
47 const char *input)
48 {
49 char buf[1000];
50 size_t output_len;
51 char *output;
52 char *bufend;
53
54 output_len = system_quote_length (interpreter, input);
55
56 output = system_quote (interpreter, input);
57 ASSERT (strlen (output) == output_len);
58
59 ASSERT (output_len <= sizeof (buf) - 2);
60 memset (buf, '\0', output_len + 1);
61 buf[output_len + 1] = '%';
62 bufend = system_quote_copy (buf, interpreter, input);
63 ASSERT (bufend == buf + output_len);
64 ASSERT (memcmp (buf, output, output_len + 1) == 0);
65 ASSERT (buf[output_len + 1] == '%');
66
67
68
69 {
70 FILE *fp = fopen (EXPECTED_DATA_FILE, "wb");
71 if (fp == NULL)
72 exit (3);
73 if (fwrite (input, 1, strlen (input), fp) != strlen (input))
74 exit (4);
75 if (fclose (fp))
76 exit (5);
77 }
78
79
80 {
81 char command[1000];
82
83 sprintf (command, "%s %s", prog, output);
84
85 switch (interpreter)
86 {
87 case SCI_SYSTEM:
88 #ifdef WINDOWS_NATIVE
89 case SCI_WINDOWS_CMD:
90 #endif
91 {
92 int exitcode = system (command);
93 if (exitcode != 0)
94 {
95 fprintf (stderr, "for input = |%s|: system() command failed with status %d: %s\n",
96 input, exitcode, command);
97 failed = 1;
98 }
99 }
100 {
101 FILE *fp = popen (command, "r");
102 int exitcode = pclose (fp);
103 if (exitcode != 0)
104 {
105 fprintf (stderr, "for input = |%s|: popen() command failed with status %d: %s\n",
106 input, exitcode, command);
107 failed = 1;
108 }
109 }
110 break;
111 #ifdef WINDOWS_NATIVE
112 case SCI_WINDOWS_CREATEPROCESS:
113 {
114 PROCESS_INFORMATION pinfo;
115 STARTUPINFO sinfo;
116 sinfo.cb = sizeof (STARTUPINFO);
117 sinfo.lpReserved = NULL;
118 sinfo.lpDesktop = NULL;
119 sinfo.lpTitle = NULL;
120 sinfo.cbReserved2 = 0;
121 sinfo.lpReserved2 = NULL;
122 sinfo.dwFlags = STARTF_USESTDHANDLES;
123 sinfo.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
124 sinfo.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
125 sinfo.hStdError = GetStdHandle (STD_ERROR_HANDLE);
126
127 if (CreateProcess (NULL, command, NULL, NULL, TRUE, 0, NULL, NULL,
128 &sinfo, &pinfo))
129 {
130 DWORD exitcode;
131 CloseHandle (pinfo.hThread);
132 if (WaitForSingleObject (pinfo.hProcess, INFINITE) == WAIT_OBJECT_0)
133 {
134 if (GetExitCodeProcess (pinfo.hProcess, &exitcode))
135 {
136 if (exitcode != 0)
137 {
138 fprintf (stderr, "for input = |%s|: CreateProcess() command failed with status %d: %s\n",
139 input, exitcode, command);
140 failed = 1;
141 }
142 }
143 else
144 {
145 fprintf (stderr, "for input = |%s|: GetExitCodeProcess failed, GetLastError() = %u\n",
146 input, GetLastError ());
147 failed = 1;
148 }
149 }
150 else
151 {
152 fprintf (stderr, "for input = |%s|: WaitForSingleObject failed\n",
153 input);
154 failed = 1;
155 }
156 CloseHandle (pinfo.hProcess);
157 }
158 else
159 {
160 fprintf (stderr, "for input = |%s|: CreateProcess failed, GetLastError() = %u\n",
161 input, GetLastError ());
162 failed = 1;
163 }
164 }
165 break;
166 #endif
167 default:
168 break;
169 }
170 }
171
172 free (output);
173 }
174
175 static void
176 check_all (enum system_command_interpreter interpreter,
177 bool windows_cmd_limitations,
178 const char *prog)
179 {
180
181
182 {
183 int c;
184
185
186 check_one (interpreter, prog, "");
187
188
189 check_one (interpreter, prog, "foo");
190 check_one (interpreter, prog, "phr0ck");
191
192
193 check_one (interpreter, prog, "foo\tbar");
194 if (!windows_cmd_limitations)
195 {
196 check_one (interpreter, prog, "foo\nbar");
197 check_one (interpreter, prog, "foo\rbar");
198 }
199 check_one (interpreter, prog, "foo bar");
200
201
202 check_one (interpreter, prog, "!foo");
203
204
205 check_one (interpreter, prog, "\"foo\"bar");
206
207
208
209 check_one (interpreter, prog, "#foo");
210
211
212
213 check_one (interpreter, prog, "$foo");
214
215
216
217 check_one (interpreter, prog, "&");
218
219
220 check_one (interpreter, prog, "'foo'bar");
221
222
223 check_one (interpreter, prog, "(");
224
225
226
227 check_one (interpreter, prog, ")");
228
229
230 check_one (interpreter, prog, "*");
231 check_one (interpreter, prog, "*foo");
232
233
234
235 check_one (interpreter, prog, ";");
236 check_one (interpreter, prog, "foo;");
237
238
239 check_one (interpreter, prog, "<");
240
241
242
243 check_one (interpreter, prog, "foo=bar");
244
245
246 check_one (interpreter, prog, ">");
247
248
249 check_one (interpreter, prog, "?");
250 check_one (interpreter, prog, "??");
251 check_one (interpreter, prog, "???");
252 check_one (interpreter, prog, "????");
253 check_one (interpreter, prog, "?????");
254 check_one (interpreter, prog, "??????");
255 check_one (interpreter, prog, "???????");
256 check_one (interpreter, prog, "????????");
257 check_one (interpreter, prog, "?????????");
258 check_one (interpreter, prog, "??????????");
259 check_one (interpreter, prog, "foo?bar");
260
261
262 check_one (interpreter, prog, "^");
263
264
265 check_one (interpreter, prog, "[");
266 check_one (interpreter, prog, "]");
267
268
269 check_one (interpreter, prog, "\\foo");
270
271
272 check_one (interpreter, prog, "`foo");
273
274
275 check_one (interpreter, prog, "{");
276
277
278
279 check_one (interpreter, prog, "|");
280
281
282
283 check_one (interpreter, prog, "}");
284
285
286
287 check_one (interpreter, prog, "~");
288 check_one (interpreter, prog, "~foo");
289
290
291 check_one (interpreter, prog, "foo'bar\"baz");
292
293
294 check_one (interpreter, prog, "%");
295 check_one (interpreter, prog, "%%");
296 check_one (interpreter, prog, "%foo%");
297 check_one (interpreter, prog, "%PATH%");
298
299
300 for (c = 1; c <= UCHAR_MAX; c++)
301 if (strchr ("\t\n\r !\"#$&'()*;<=>?^[\\]`{|}~", c) == NULL)
302 {
303 char s[5];
304 s[0] = 'a';
305 s[1] = (char) c;
306 s[2] = 'z';
307 s[3] = (char) c;
308 s[4] = '\0';
309
310 check_one (interpreter, prog, s);
311 }
312 }
313 }
314
315 int
316 main (int argc, char *argv[])
317 {
318 char *prog;
319
320 if (argc != 2)
321 {
322 fprintf (stderr, "%s: need 1 argument\n", argv[0]);
323 return 2;
324 }
325 prog = argv[1];
326
327 #ifdef WINDOWS_NATIVE
328
329
330 {
331 char *p;
332 for (p = prog; *p != '\0'; p++)
333 if (*p == '/')
334 *p = '\\';
335 }
336 #endif
337
338 #ifdef WINDOWS_NATIVE
339 check_all (SCI_SYSTEM, true, prog);
340 check_all (SCI_WINDOWS_CREATEPROCESS, false, prog);
341 check_all (SCI_WINDOWS_CMD, true, prog);
342 #else
343 check_all (SCI_SYSTEM, false, prog);
344 #endif
345
346
347 unlink (EXPECTED_DATA_FILE);
348
349 return failed;
350 }