diff options
-rw-r--r-- | src/lib/encoding/kvline.c | 24 | ||||
-rw-r--r-- | src/lib/encoding/kvline.h | 1 | ||||
-rw-r--r-- | src/test/test_config.c | 8 |
3 files changed, 26 insertions, 7 deletions
diff --git a/src/lib/encoding/kvline.c b/src/lib/encoding/kvline.c index e56b57b4cf..f55e3d966f 100644 --- a/src/lib/encoding/kvline.c +++ b/src/lib/encoding/kvline.c @@ -85,8 +85,9 @@ kvline_can_encode_lines(const config_line_t *line, unsigned flags) return false; } - if (needs_escape(line->value, keyless) && ! (flags & KV_QUOTED)) { - /* If KV_QUOTED is false, we can't encode a value that needs quotes. */ + if (needs_escape(line->value, keyless) && ! (flags & (KV_QUOTED|KV_RAW))) { + /* If both KV_QUOTED and KV_RAW are false, we can't encode a + value that needs quotes. */ return false; } if (!keyless && needs_escape(line->key, true)) { @@ -104,7 +105,7 @@ kvline_can_encode_lines(const config_line_t *line, unsigned flags) * * If KV_QUOTED is set in <b>flags</b>, then all values that contain * spaces or unusual characters are escaped and quoted. Otherwise, such - * values are not allowed. + * values are not allowed. Mutually exclusive with KV_RAW. * * If KV_OMIT_KEYS is set in <b>flags</b>, then pairs with empty keys are * allowed, and are encoded as 'Value'. Otherwise, such pairs are not @@ -114,6 +115,11 @@ kvline_can_encode_lines(const config_line_t *line, unsigned flags) * encoded as 'Key', not as 'Key=' or 'Key=""'. Mutually exclusive with * KV_OMIT_KEYS. * + * If KV_RAW is set in <b>flags</b>, then don't apply any quoting to + * the value, and assume that the caller has adequately quoted it. + * (The control protocol has some quirks that make this necessary.) + * Mutually exclusive with KV_QUOTED. + * * KV_QUOTED_QSTRING is not supported. */ char * @@ -122,11 +128,12 @@ kvline_encode(const config_line_t *line, { tor_assert(! (flags & KV_QUOTED_QSTRING)); - if (!kvline_can_encode_lines(line, flags)) - return NULL; - tor_assert((flags & (KV_OMIT_KEYS|KV_OMIT_VALS)) != (KV_OMIT_KEYS|KV_OMIT_VALS)); + tor_assert((flags & (KV_QUOTED|KV_RAW)) != (KV_QUOTED|KV_RAW)); + + if (!kvline_can_encode_lines(line, flags)) + return NULL; smartlist_t *elements = smartlist_new(); @@ -148,7 +155,7 @@ kvline_encode(const config_line_t *line, if ((flags & KV_OMIT_VALS) && line_has_no_val(line)) { eq = ""; v = ""; - } else if (esc) { + } else if (!(flags & KV_RAW) && esc) { tmp = esc_for_log(line->value); v = tmp; } else { @@ -185,12 +192,15 @@ kvline_encode(const config_line_t *line, * If KV_QUOTED_QSTRING is set in <b>flags</b>, then double-quoted values * are allowed and handled as QuotedStrings per qstring.c. Do not add * new users of this flag. + * + * KV_RAW is not supported. */ config_line_t * kvline_parse(const char *line, unsigned flags) { tor_assert((flags & (KV_OMIT_KEYS|KV_OMIT_VALS)) != (KV_OMIT_KEYS|KV_OMIT_VALS)); + tor_assert(!(flags & KV_RAW)); const char *cp = line, *cplast = NULL; const bool omit_keys = (flags & KV_OMIT_KEYS) != 0; diff --git a/src/lib/encoding/kvline.h b/src/lib/encoding/kvline.h index dea2ce1809..9d36902ad1 100644 --- a/src/lib/encoding/kvline.h +++ b/src/lib/encoding/kvline.h @@ -19,6 +19,7 @@ struct config_line_t; #define KV_OMIT_KEYS (1u<<1) #define KV_OMIT_VALS (1u<<2) #define KV_QUOTED_QSTRING (1u<<3) +#define KV_RAW (1u<<4) struct config_line_t *kvline_parse(const char *line, unsigned flags); char *kvline_encode(const struct config_line_t *line, unsigned flags); diff --git a/src/test/test_config.c b/src/test/test_config.c index 6294e21f04..8f705da7e0 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -6072,6 +6072,14 @@ test_config_kvline_parse(void *arg) lines->value = tor_strdup("CD"); enc = kvline_encode(lines, 0); tt_assert(!enc); + config_free_lines(lines); + + config_line_append(&lines, "A", "B C"); + enc = kvline_encode(lines, 0); + tt_assert(!enc); + enc = kvline_encode(lines, KV_RAW); + tt_assert(enc); + tt_str_op(enc, OP_EQ, "A=B C"); done: config_free_lines(lines); |