[tor-commits] [tor/master] clean up kvline_can_encode_lines()

teor at torproject.org teor at torproject.org
Sun Dec 15 22:17:36 UTC 2019


commit 4b22c739fe8b04b05e7bdfdf18ec42ec4bf1c436
Author: Taylor Yu <catalyst at torproject.org>
Date:   Wed Jul 3 15:13:51 2019 -0500

    clean up kvline_can_encode_lines()
    
    Add a check for '=' characters in needs_escape().  This simplifies the
    logic in kvline_can_encode_lines().
    
    Part of #30984.
---
 src/lib/encoding/kvline.c | 28 +++++++++++++---------------
 src/test/test_config.c    | 22 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/src/lib/encoding/kvline.c b/src/lib/encoding/kvline.c
index d4a8f510b..e56b57b4c 100644
--- a/src/lib/encoding/kvline.c
+++ b/src/lib/encoding/kvline.c
@@ -29,12 +29,20 @@
 #include <string.h>
 
 /** Return true iff we need to quote and escape the string <b>s</b> to encode
- * it. */
+ * it.
+ *
+ * kvline_can_encode_lines() also uses this (with
+ * <b>as_keyless_val</b> true) to check whether a key would require
+ * quoting.
+ */
 static bool
 needs_escape(const char *s, bool as_keyless_val)
 {
   if (as_keyless_val && *s == 0)
     return true;
+  /* Keyless values containing '=' need to be escaped. */
+  if (as_keyless_val && strchr(s, '='))
+    return true;
 
   for (; *s; ++s) {
     if (*s >= 127 || TOR_ISSPACE(*s) || ! TOR_ISPRINT(*s) ||
@@ -72,23 +80,16 @@ kvline_can_encode_lines(const config_line_t *line, unsigned flags)
 {
   for ( ; line; line = line->next) {
     const bool keyless = line_has_no_key(line);
-    if (keyless) {
-      if (! (flags & KV_OMIT_KEYS)) {
-        /* If KV_OMIT_KEYS is not set, we can't encode a line with no key. */
-        return false;
-      }
-      if (strchr(line->value, '=') && !( flags & KV_QUOTED)) {
-        /* We can't have a keyless value with = without quoting it. */
-        return false;
-      }
+    if (keyless && ! (flags & KV_OMIT_KEYS)) {
+      /* If KV_OMIT_KEYS is not set, we can't encode a line with no key. */
+      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. */
       return false;
     }
-    if (line->key && strlen(line->key) &&
-        (needs_escape(line->key, false) || strchr(line->key, '='))) {
+    if (!keyless && needs_escape(line->key, true)) {
       /* We can't handle keys that need quoting. */
       return false;
     }
@@ -142,9 +143,6 @@ kvline_encode(const config_line_t *line,
       k = line->key;
     } else {
       eq = "";
-      if (strchr(line->value, '=')) {
-        esc = true;
-      }
     }
 
     if ((flags & KV_OMIT_VALS) && line_has_no_val(line)) {
diff --git a/src/test/test_config.c b/src/test/test_config.c
index a75a86273..6294e21f0 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -6050,6 +6050,28 @@ test_config_kvline_parse(void *arg)
   tt_str_op(lines->next->next->value, OP_EQ, "I");
   enc = kvline_encode(lines, KV_OMIT_VALS|KV_QUOTED);
   tt_str_op(enc, OP_EQ, "AB=\"CD E\" DE FGH=I");
+  tor_free(enc);
+  config_free_lines(lines);
+
+  lines = kvline_parse("AB=CD \"EF=GH\"", KV_OMIT_KEYS|KV_QUOTED);
+  tt_assert(lines);
+  tt_str_op(lines->key, OP_EQ, "AB");
+  tt_str_op(lines->value, OP_EQ, "CD");
+  tt_str_op(lines->next->key, OP_EQ, "");
+  tt_str_op(lines->next->value, OP_EQ, "EF=GH");
+  enc = kvline_encode(lines, KV_OMIT_KEYS);
+  tt_assert(!enc);
+  enc = kvline_encode(lines, KV_OMIT_KEYS|KV_QUOTED);
+  tt_assert(enc);
+  tt_str_op(enc, OP_EQ, "AB=CD \"EF=GH\"");
+  tor_free(enc);
+  config_free_lines(lines);
+
+  lines = tor_malloc_zero(sizeof(*lines));
+  lines->key = tor_strdup("A=B");
+  lines->value = tor_strdup("CD");
+  enc = kvline_encode(lines, 0);
+  tt_assert(!enc);
 
  done:
   config_free_lines(lines);





More information about the tor-commits mailing list