diff options
author | Daniel Pinto <danielpinto52@gmail.com> | 2019-09-22 22:30:48 +0100 |
---|---|---|
committer | teor <teor@torproject.org> | 2019-09-23 10:39:08 +1000 |
commit | 15490816da0f8b651d67acef9c7f4e5bf9652ce2 (patch) | |
tree | 7c1b4fa536f5bae13996a9c79abe7622763374d0 /src | |
parent | 02840169d860384257042bdf6d7601c2bf48b47b (diff) | |
download | tor-15490816da0f8b651d67acef9c7f4e5bf9652ce2.tar.gz tor-15490816da0f8b651d67acef9c7f4e5bf9652ce2.zip |
Fix bug when %including folder with comment only files. #31408
When processing a %included folder, a bug caused the pointer to
the last element of the options list to be set to NULL when
processing a file with only comments or whitepace. This could
cause options from other files on the same folder to be
discarded depending on the lines after the affected %include.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/fs/conffile.c | 10 | ||||
-rw-r--r-- | src/test/test_config.c | 68 |
2 files changed, 74 insertions, 4 deletions
diff --git a/src/lib/fs/conffile.c b/src/lib/fs/conffile.c index 7bb2f23931..0d5d56b335 100644 --- a/src/lib/fs/conffile.c +++ b/src/lib/fs/conffile.c @@ -153,16 +153,18 @@ config_process_include(const char *path, int recursion_level, int extended, int rv = -1; SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) { config_line_t *included_config = NULL; + config_line_t *included_config_last = NULL; if (config_get_included_config(config_file, recursion_level, extended, - &included_config, list_last, + &included_config, &included_config_last, opened_lst) < 0) { goto done; } *next = included_config; - if (*list_last) - next = &(*list_last)->next; - + if (included_config_last) { + next = &included_config_last->next; + *list_last = included_config_last; + } } SMARTLIST_FOREACH_END(config_file); *list = ret_list; rv = 0; diff --git a/src/test/test_config.c b/src/test/test_config.c index 0de6b12919..8f011ce1f1 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -5287,6 +5287,73 @@ test_config_include_folder_order(void *data) } static void +test_config_include_blank_file_last(void *data) +{ + (void)data; + + config_line_t *result = NULL; + char *torrcd = NULL; + char *path = NULL; + char *dir = tor_strdup(get_fname("test_include_blank_file_last")); + tt_ptr_op(dir, OP_NE, NULL); + +#ifdef _WIN32 + tt_int_op(mkdir(dir), OP_EQ, 0); +#else + tt_int_op(mkdir(dir, 0700), OP_EQ, 0); +#endif + + tor_asprintf(&torrcd, "%s"PATH_SEPARATOR"%s", dir, "torrc.d"); + +#ifdef _WIN32 + tt_int_op(mkdir(torrcd), OP_EQ, 0); +#else + tt_int_op(mkdir(torrcd, 0700), OP_EQ, 0); +#endif + + tor_asprintf(&path, "%s"PATH_SEPARATOR"%s", torrcd, "aa_1st"); + tt_int_op(write_str_to_file(path, "Test 1\n", 0), OP_EQ, 0); + tor_free(path); + + tor_asprintf(&path, "%s"PATH_SEPARATOR"%s", torrcd, "bb_2nd"); + tt_int_op(write_str_to_file(path, "Test 2\n", 0), OP_EQ, 0); + tor_free(path); + + tor_asprintf(&path, "%s"PATH_SEPARATOR"%s", torrcd, "cc_comment"); + tt_int_op(write_str_to_file(path, "# comment only\n", 0), OP_EQ, 0); + tor_free(path); + + char torrc_contents[1000]; + tor_snprintf(torrc_contents, sizeof(torrc_contents), + "%%include %s\n" + "Test 3\n", + torrcd); + + int include_used; + tt_int_op(config_get_lines_include(torrc_contents, &result, 0, &include_used, + NULL), OP_EQ, 0); + tt_ptr_op(result, OP_NE, NULL); + tt_int_op(include_used, OP_EQ, 1); + + int len = 0; + config_line_t *next; + for (next = result; next != NULL; next = next->next) { + char expected[10]; + tor_snprintf(expected, sizeof(expected), "%d", len + 1); + tt_str_op(next->key, OP_EQ, "Test"); + tt_str_op(next->value, OP_EQ, expected); + len++; + } + tt_int_op(len, OP_EQ, 3); + + done: + config_free_lines(result); + tor_free(torrcd); + tor_free(path); + tor_free(dir); +} + +static void test_config_include_path_syntax(void *data) { (void)data; @@ -5848,6 +5915,7 @@ struct testcase_t config_tests[] = { CONFIG_TEST(include_recursion_before_after, 0), CONFIG_TEST(include_recursion_after_only, 0), CONFIG_TEST(include_folder_order, 0), + CONFIG_TEST(include_blank_file_last, 0), CONFIG_TEST(include_path_syntax, 0), CONFIG_TEST(include_not_processed, 0), CONFIG_TEST(include_has_include, 0), |