]>
Commit | Line | Data |
---|---|---|
3fd1520c | 1 | #include "clar_libgit2.h" |
d1a721c5 VM |
2 | |
3 | #include "filebuf.h" | |
22a2d3d5 | 4 | #include "futils.h" |
d1a721c5 VM |
5 | #include "posix.h" |
6 | ||
a1abe66a | 7 | #define TEST_CONFIG "git-test-config" |
8 | ||
9a97f49e CMN |
9 | static git_buf buf = GIT_BUF_INIT; |
10 | ||
d1a721c5 VM |
11 | void test_config_stress__initialize(void) |
12 | { | |
bf038dab | 13 | git_filebuf file = GIT_FILEBUF_INIT; |
d1a721c5 | 14 | |
1d3a8aeb | 15 | cl_git_pass(git_filebuf_open(&file, TEST_CONFIG, 0, 0666)); |
d1a721c5 VM |
16 | |
17 | git_filebuf_printf(&file, "[color]\n\tui = auto\n"); | |
18 | git_filebuf_printf(&file, "[core]\n\teditor = \n"); | |
19 | ||
1d3a8aeb | 20 | cl_git_pass(git_filebuf_commit(&file)); |
d1a721c5 VM |
21 | } |
22 | ||
23 | void test_config_stress__cleanup(void) | |
24 | { | |
ac3d33df | 25 | git_buf_dispose(&buf); |
a1abe66a | 26 | p_unlink(TEST_CONFIG); |
d1a721c5 VM |
27 | } |
28 | ||
29 | void test_config_stress__dont_break_on_invalid_input(void) | |
30 | { | |
d1a721c5 VM |
31 | git_config *config; |
32 | ||
e579e0f7 | 33 | cl_assert(git_fs_path_exists(TEST_CONFIG)); |
a1abe66a | 34 | cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); |
d1a721c5 | 35 | |
9a97f49e CMN |
36 | cl_git_pass(git_config_get_string_buf(&buf, config, "color.ui")); |
37 | cl_git_pass(git_config_get_string_buf(&buf, config, "core.editor")); | |
d1a721c5 VM |
38 | |
39 | git_config_free(config); | |
40 | } | |
2c1075d6 | 41 | |
e579e0f7 | 42 | static void assert_config_value(git_config *config, const char *key, const char *value) |
9a97f49e | 43 | { |
e579e0f7 | 44 | git_buf_dispose(&buf); |
9a97f49e | 45 | cl_git_pass(git_config_get_string_buf(&buf, config, key)); |
e579e0f7 | 46 | cl_assert_equal_s(value, buf.ptr); |
9a97f49e CMN |
47 | } |
48 | ||
2c1075d6 CMN |
49 | void test_config_stress__comments(void) |
50 | { | |
2c1075d6 | 51 | git_config *config; |
2c1075d6 | 52 | |
a1abe66a | 53 | cl_git_pass(git_config_open_ondisk(&config, cl_fixture("config/config12"))); |
2c1075d6 | 54 | |
9a97f49e CMN |
55 | assert_config_value(config, "some.section.test2", "hello"); |
56 | assert_config_value(config, "some.section.test3", "welcome"); | |
57 | assert_config_value(config, "some.section.other", "hello! \" ; ; ; "); | |
58 | assert_config_value(config, "some.section.other2", "cool! \" # # # "); | |
59 | assert_config_value(config, "some.section.multi", "hi, this is a ; multiline comment # with ;\n special chars and other stuff !@#"); | |
60 | assert_config_value(config, "some.section.multi2", "good, this is a ; multiline comment # with ;\n special chars and other stuff !@#"); | |
61 | assert_config_value(config, "some.section.back", "this is \ba phrase"); | |
22a2d3d5 UG |
62 | assert_config_value(config, "some.section.dollar", "some $sign"); |
63 | assert_config_value(config, "some.section.multiquotes", "!ls x ls # comment2 $HOME"); | |
64 | assert_config_value(config, "some.section.multiquotes2", "!ls x ls \"# comment2 $HOME\""); | |
65 | assert_config_value(config, "some.section.multiquotes3", "hi # ho there are # more quotes"); | |
66 | assert_config_value(config, "some.section.quotecomment", "hi # ho there are # more"); | |
2c1075d6 CMN |
67 | |
68 | git_config_free(config); | |
69 | } | |
5d9cfa07 CMN |
70 | |
71 | void test_config_stress__escape_subsection_names(void) | |
72 | { | |
5d9cfa07 | 73 | git_config *config; |
5d9cfa07 | 74 | |
e579e0f7 | 75 | cl_assert(git_fs_path_exists("git-test-config")); |
a1abe66a | 76 | cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); |
5d9cfa07 CMN |
77 | |
78 | cl_git_pass(git_config_set_string(config, "some.sec\\tion.other", "foo")); | |
79 | git_config_free(config); | |
80 | ||
a1abe66a | 81 | cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); |
5d9cfa07 | 82 | |
9a97f49e CMN |
83 | assert_config_value(config, "some.sec\\tion.other", "foo"); |
84 | ||
14e1bc15 | 85 | git_config_free(config); |
5d9cfa07 | 86 | } |
9f35754a CMN |
87 | |
88 | void test_config_stress__trailing_backslash(void) | |
89 | { | |
90 | git_config *config; | |
9f35754a CMN |
91 | const char *path = "C:\\iam\\some\\windows\\path\\"; |
92 | ||
e579e0f7 | 93 | cl_assert(git_fs_path_exists("git-test-config")); |
9f35754a CMN |
94 | cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); |
95 | cl_git_pass(git_config_set_string(config, "windows.path", path)); | |
96 | git_config_free(config); | |
97 | ||
98 | cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); | |
9a97f49e CMN |
99 | assert_config_value(config, "windows.path", path); |
100 | ||
9f35754a CMN |
101 | git_config_free(config); |
102 | } | |
9dac1f95 CMN |
103 | |
104 | void test_config_stress__complex(void) | |
105 | { | |
106 | git_config *config; | |
9dac1f95 CMN |
107 | const char *path = "./config-immediate-multiline"; |
108 | ||
109 | cl_git_mkfile(path, "[imm]\n multi = \"\\\nfoo\""); | |
110 | cl_git_pass(git_config_open_ondisk(&config, path)); | |
9a97f49e CMN |
111 | assert_config_value(config, "imm.multi", "foo"); |
112 | ||
9dac1f95 CMN |
113 | git_config_free(config); |
114 | } | |
a2f96479 CMN |
115 | |
116 | void test_config_stress__quick_write(void) | |
117 | { | |
118 | git_config *config_w, *config_r; | |
119 | const char *path = "./config-quick-write"; | |
120 | const char *key = "quick.write"; | |
121 | int32_t i; | |
122 | ||
123 | /* Create an external writer for one instance with the other one */ | |
124 | cl_git_pass(git_config_open_ondisk(&config_w, path)); | |
125 | cl_git_pass(git_config_open_ondisk(&config_r, path)); | |
126 | ||
127 | /* Write and read in the same second (repeat to increase the chance of it happening) */ | |
128 | for (i = 0; i < 10; i++) { | |
129 | int32_t val; | |
130 | cl_git_pass(git_config_set_int32(config_w, key, i)); | |
22a2d3d5 | 131 | cl_msleep(1); |
a2f96479 CMN |
132 | cl_git_pass(git_config_get_int32(&val, config_r, key)); |
133 | cl_assert_equal_i(i, val); | |
134 | } | |
9031be18 PS |
135 | |
136 | git_config_free(config_r); | |
137 | git_config_free(config_w); | |
a2f96479 | 138 | } |
22a2d3d5 UG |
139 | |
140 | static int foreach_cb(const git_config_entry *entry, void *payload) | |
141 | { | |
142 | if (!strcmp(entry->name, "key.value")) { | |
143 | *(char **)payload = git__strdup(entry->value); | |
144 | return 0; | |
145 | } | |
146 | return -1; | |
147 | } | |
148 | ||
149 | void test_config_stress__foreach_refreshes(void) | |
150 | { | |
151 | git_config *config_w, *config_r; | |
152 | char *value = NULL; | |
153 | ||
154 | cl_git_pass(git_config_open_ondisk(&config_w, "./cfg")); | |
155 | cl_git_pass(git_config_open_ondisk(&config_r, "./cfg")); | |
156 | ||
157 | cl_git_pass(git_config_set_string(config_w, "key.value", "1")); | |
158 | cl_git_pass(git_config_foreach_match(config_r, "key.value", foreach_cb, &value)); | |
159 | ||
160 | cl_assert_equal_s(value, "1"); | |
161 | ||
162 | git_config_free(config_r); | |
163 | git_config_free(config_w); | |
164 | git__free(value); | |
165 | } | |
166 | ||
167 | void test_config_stress__foreach_refreshes_snapshot(void) | |
168 | { | |
169 | git_config *config, *snapshot; | |
170 | char *value = NULL; | |
171 | ||
172 | cl_git_pass(git_config_open_ondisk(&config, "./cfg")); | |
173 | ||
174 | cl_git_pass(git_config_set_string(config, "key.value", "1")); | |
175 | cl_git_pass(git_config_snapshot(&snapshot, config)); | |
176 | cl_git_pass(git_config_foreach_match(snapshot, "key.value", foreach_cb, &value)); | |
177 | ||
178 | cl_assert_equal_s(value, "1"); | |
179 | ||
180 | git_config_free(snapshot); | |
181 | git_config_free(config); | |
182 | git__free(value); | |
183 | } | |
184 | ||
185 | void test_config_stress__huge_section_with_many_values(void) | |
186 | { | |
187 | git_config *config; | |
188 | ||
189 | if (!cl_is_env_set("GITTEST_INVASIVE_SPEED")) | |
190 | cl_skip(); | |
191 | ||
192 | /* | |
193 | * The config file is structured in such a way that is | |
194 | * has a section header that is approximately 500kb of | |
195 | * size followed by 40k entries. While the resulting | |
196 | * configuration file itself is roughly 650kb in size and | |
197 | * thus considered to be rather small, in the past we'd | |
198 | * balloon to more than 20GB of memory (20000x500kb) | |
199 | * while parsing the file. It thus was a trivial way to | |
200 | * cause an out-of-memory situation and thus cause denial | |
201 | * of service, e.g. via gitmodules. | |
202 | */ | |
203 | cl_git_pass(git_config_open_ondisk(&config, cl_fixture("config/config-oom"))); | |
204 | ||
205 | git_config_free(config); | |
206 | } |