mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-25 15:10:48 +01:00
Add a config_lines_partition() function to help with LINELIST_V.
This function works a little bit like strsep(), to get a chunk of configuration lines with a given header. We can use this to make hidden service config easier to parse.
This commit is contained in:
parent
ba8d71d9c3
commit
9dc946ba67
3 changed files with 81 additions and 0 deletions
|
@ -253,6 +253,35 @@ config_lines_dup_and_filter(const config_line_t *inp,
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a linelist <b>inp</b> beginning with the key <b>header</b>, find the
|
||||
* next line with that key, and remove that instance and all following lines
|
||||
* from the list. Return the lines that were removed. Operate
|
||||
* case-insensitively.
|
||||
*
|
||||
* For example, if the header is "H", and <b>inp</b> contains "H, A, B, H, C,
|
||||
* H, D", this function will alter <b>inp</b> to contain only "H, A, B", and
|
||||
* return the elements "H, C, H, D" as a separate list.
|
||||
**/
|
||||
config_line_t *
|
||||
config_lines_partition(config_line_t *inp, const char *header)
|
||||
{
|
||||
if (BUG(inp == NULL))
|
||||
return NULL;
|
||||
if (BUG(strcasecmp(inp->key, header)))
|
||||
return NULL;
|
||||
|
||||
/* Advance ptr until it points to the link to the next segment of this
|
||||
list. */
|
||||
config_line_t **ptr = &inp->next;
|
||||
while (*ptr && strcasecmp((*ptr)->key, header)) {
|
||||
ptr = &(*ptr)->next;
|
||||
}
|
||||
config_line_t *remainder = *ptr;
|
||||
*ptr = NULL;
|
||||
return remainder;
|
||||
}
|
||||
|
||||
/** Return true iff a and b contain identical keys and values in identical
|
||||
* order. */
|
||||
int
|
||||
|
|
|
@ -50,6 +50,7 @@ const config_line_t *config_line_find(const config_line_t *lines,
|
|||
const char *key);
|
||||
const config_line_t *config_line_find_case(const config_line_t *lines,
|
||||
const char *key);
|
||||
config_line_t *config_lines_partition(config_line_t *inp, const char *header);
|
||||
int config_lines_eq(const config_line_t *a, const config_line_t *b);
|
||||
int config_count_key(const config_line_t *a, const char *key);
|
||||
void config_free_lines_(config_line_t *front);
|
||||
|
|
|
@ -1850,6 +1850,56 @@ test_util_config_line_crlf(void *arg)
|
|||
tor_free(k); tor_free(v);
|
||||
}
|
||||
|
||||
static void
|
||||
test_util_config_line_partition(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
config_line_t *lines = NULL, *orig, *rest = NULL;
|
||||
|
||||
config_line_append(&lines, "Header", "X");
|
||||
config_line_append(&lines, "Item", "Y");
|
||||
config_line_append(&lines, "Thing", "Z");
|
||||
|
||||
config_line_append(&lines, "HEADER", "X2");
|
||||
|
||||
config_line_append(&lines, "header", "X3");
|
||||
config_line_append(&lines, "Item3", "Foob");
|
||||
|
||||
/* set up h2 and h3 to point to the places where we hope the headers will
|
||||
be. */
|
||||
config_line_t *h2 = lines->next->next->next;
|
||||
config_line_t *h3 = h2->next;
|
||||
tt_str_op(h2->key, OP_EQ, "HEADER");
|
||||
tt_str_op(h3->key, OP_EQ, "header");
|
||||
|
||||
orig = lines;
|
||||
rest = config_lines_partition(lines, "Header");
|
||||
tt_ptr_op(lines, OP_EQ, orig);
|
||||
tt_ptr_op(rest, OP_EQ, h2);
|
||||
tt_str_op(lines->next->key, OP_EQ, "Item");
|
||||
tt_str_op(lines->next->next->key, OP_EQ, "Thing");
|
||||
tt_ptr_op(lines->next->next->next, OP_EQ, NULL);
|
||||
config_free_lines(lines);
|
||||
|
||||
orig = lines = rest;
|
||||
rest = config_lines_partition(lines, "Header");
|
||||
tt_ptr_op(lines, OP_EQ, orig);
|
||||
tt_ptr_op(rest, OP_EQ, h3);
|
||||
tt_ptr_op(lines->next, OP_EQ, NULL);
|
||||
config_free_lines(lines);
|
||||
|
||||
orig = lines = rest;
|
||||
rest = config_lines_partition(lines, "Header");
|
||||
tt_ptr_op(lines, OP_EQ, orig);
|
||||
tt_ptr_op(rest, OP_EQ, NULL);
|
||||
tt_str_op(lines->next->key, OP_EQ, "Item3");
|
||||
tt_ptr_op(lines->next->next, OP_EQ, NULL);
|
||||
|
||||
done:
|
||||
config_free_lines(lines);
|
||||
config_free_lines(rest);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PWDB_TESTS
|
||||
static void
|
||||
test_util_expand_filename(void *arg)
|
||||
|
@ -6379,6 +6429,7 @@ struct testcase_t util_tests[] = {
|
|||
UTIL_LEGACY(config_line_comment_character),
|
||||
UTIL_LEGACY(config_line_escaped_content),
|
||||
UTIL_LEGACY(config_line_crlf),
|
||||
UTIL_TEST(config_line_partition, 0),
|
||||
UTIL_TEST_PWDB(expand_filename, 0),
|
||||
UTIL_LEGACY(escape_string_socks),
|
||||
UTIL_LEGACY(string_is_key_value),
|
||||
|
|
Loading…
Add table
Reference in a new issue