add KV_RAW to kvline.c

Add the KV_RAW flag to kvline_encode().  This allows generation of
output that is compatible with some quirks of the control protocol.

Part of #30984.
This commit is contained in:
Taylor Yu
2019-07-03 16:35:35 -05:00
parent 4b22c739fe
commit 1e8bb79bbe
3 changed files with 26 additions and 7 deletions
+17 -7
View File
@@ -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;
+1
View File
@@ -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);
+8
View File
@@ -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);