debian: apply security fixes from 2.24.1
[git/debian.git] / debian / patches / 0019-tests-add-a-helper-to-stress-test-argument-quoting.diff
blob8ff372c15a81883578daf50a68fba26f42889793
1 From abf2e09ee55a3ac3f227ea343fc9065b5d4e7288 Mon Sep 17 00:00:00 2001
2 From: Garima Singh <garima.singh@microsoft.com>
3 Date: Wed, 18 Sep 2019 16:03:59 -0400
4 Subject: tests: add a helper to stress test argument quoting
6 On Windows, we have to do all the command-line argument quoting
7 ourselves. Worse: we have to have two versions of said quoting, one for
8 MSYS2 programs (which have their own dequoting rules) and the rest.
10 We care mostly about the rest, and to make sure that that works, let's
11 have a stress test that comes up with all kinds of awkward arguments,
12 verifying that a spawned sub-process receives those unharmed.
14 Signed-off-by: Garima Singh <garima.singh@microsoft.com>
15 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
16 (cherry picked from commit ad1559252945179e28fba7d693494051352810c5)
17 Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
18 ---
19 t/helper/test-run-command.c | 118 +++++++++++++++++++++++++++++++++++-
20 1 file changed, 116 insertions(+), 2 deletions(-)
22 diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
23 index ead6dc611a..8aad4fbd42 100644
24 --- a/t/helper/test-run-command.c
25 +++ b/t/helper/test-run-command.c
26 @@ -18,8 +18,8 @@
27 #include "string-list.h"
28 #include "thread-utils.h"
29 #include "wildmatch.h"
30 -#include <string.h>
31 -#include <errno.h>
32 +#include "gettext.h"
33 +#include "parse-options.h"
35 static int number_callbacks;
36 static int parallel_next(struct child_process *cp,
37 @@ -200,6 +200,114 @@ static int testsuite(int argc, const char **argv)
38 return !!ret;
41 +static uint64_t my_random_next = 1234;
43 +static uint64_t my_random(void)
45 + uint64_t res = my_random_next;
46 + my_random_next = my_random_next * 1103515245 + 12345;
47 + return res;
50 +static int quote_stress_test(int argc, const char **argv)
52 + /*
53 + * We are running a quote-stress test.
54 + * spawn a subprocess that runs quote-stress with a
55 + * special option that echoes back the arguments that
56 + * were passed in.
57 + */
58 + char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a";
59 + int i, j, k, trials = 100;
60 + struct strbuf out = STRBUF_INIT;
61 + struct argv_array args = ARGV_ARRAY_INIT;
62 + struct option options[] = {
63 + OPT_INTEGER('n', "trials", &trials, "Number of trials"),
64 + OPT_END()
65 + };
66 + const char * const usage[] = {
67 + "test-tool run-command quote-stress-test <options>",
68 + NULL
69 + };
71 + argc = parse_options(argc, argv, NULL, options, usage, 0);
73 + for (i = 0; i < trials; i++) {
74 + struct child_process cp = CHILD_PROCESS_INIT;
75 + size_t arg_count = 1 + (my_random() % 5), arg_offset;
76 + int ret = 0;
78 + argv_array_clear(&args);
79 + argv_array_pushl(&args, "test-tool", "run-command",
80 + "quote-echo", NULL);
81 + arg_offset = args.argc;
82 + for (j = 0; j < arg_count; j++) {
83 + char buf[20];
84 + size_t min_len = 1;
85 + size_t arg_len = min_len +
86 + (my_random() % (ARRAY_SIZE(buf) - min_len));
88 + for (k = 0; k < arg_len; k++)
89 + buf[k] = special[my_random() %
90 + ARRAY_SIZE(special)];
91 + buf[arg_len] = '\0';
93 + argv_array_push(&args, buf);
94 + }
96 + cp.argv = args.argv;
97 + strbuf_reset(&out);
98 + if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0)
99 + return error("Failed to spawn child process");
101 + for (j = 0, k = 0; j < arg_count; j++) {
102 + const char *arg = args.argv[j + arg_offset];
104 + if (strcmp(arg, out.buf + k))
105 + ret = error("incorrectly quoted arg: '%s', "
106 + "echoed back as '%s'",
107 + arg, out.buf + k);
108 + k += strlen(out.buf + k) + 1;
111 + if (k != out.len)
112 + ret = error("got %d bytes, but consumed only %d",
113 + (int)out.len, (int)k);
115 + if (ret) {
116 + fprintf(stderr, "Trial #%d failed. Arguments:\n", i);
117 + for (j = 0; j < arg_count; j++)
118 + fprintf(stderr, "arg #%d: '%s'\n",
119 + (int)j, args.argv[j + arg_offset]);
121 + strbuf_release(&out);
122 + argv_array_clear(&args);
124 + return ret;
127 + if (i && (i % 100) == 0)
128 + fprintf(stderr, "Trials completed: %d\n", (int)i);
131 + strbuf_release(&out);
132 + argv_array_clear(&args);
134 + return 0;
137 +static int quote_echo(int argc, const char **argv)
139 + while (argc > 1) {
140 + fwrite(argv[1], strlen(argv[1]), 1, stdout);
141 + fputc('\0', stdout);
142 + argv++;
143 + argc--;
146 + return 0;
149 int cmd__run_command(int argc, const char **argv)
151 struct child_process proc = CHILD_PROCESS_INIT;
152 @@ -208,6 +316,12 @@ int cmd__run_command(int argc, const char **argv)
153 if (argc > 1 && !strcmp(argv[1], "testsuite"))
154 exit(testsuite(argc - 1, argv + 1));
156 + if (argc >= 2 && !strcmp(argv[1], "quote-stress-test"))
157 + return !!quote_stress_test(argc - 1, argv + 1);
159 + if (argc >= 2 && !strcmp(argv[1], "quote-echo"))
160 + return !!quote_echo(argc - 1, argv + 1);
162 if (argc < 3)
163 return 1;
164 while (!strcmp(argv[1], "env")) {
166 2.24.0.393.g34dc348eaf