Unverified Commit 15490816 authored by Jigsaw52's avatar Jigsaw52 Committed by teor
Browse files

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.
parent 02840169
Loading
Loading
Loading
Loading

changes/bug31408

0 → 100644
+4 −0
Original line number Diff line number Diff line
  o Major bugfixes (torrc):
    - Fix configuration files in a %included folder containing a 
      configuration file with only comments or whitespace being
      ignored. Fixes bug 31408; bugfix on 0.4.0.5.
+6 −4
Original line number Diff line number Diff line
@@ -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;
+68 −0
Original line number Diff line number Diff line
@@ -5286,6 +5286,73 @@ test_config_include_folder_order(void *data)
  tor_free(dir);
}

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)
{
@@ -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),