kvline.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file kvline.c
  8. *
  9. * \brief Manipulating lines of key-value pairs.
  10. **/
  11. #include "orconfig.h"
  12. #include "lib/container/smartlist.h"
  13. #include "lib/encoding/confline.h"
  14. #include "lib/encoding/cstring.h"
  15. #include "lib/encoding/kvline.h"
  16. #include "lib/encoding/qstring.h"
  17. #include "lib/malloc/malloc.h"
  18. #include "lib/string/compat_ctype.h"
  19. #include "lib/string/printf.h"
  20. #include "lib/string/util_string.h"
  21. #include "lib/log/escape.h"
  22. #include "lib/log/util_bug.h"
  23. #include <stdbool.h>
  24. #include <stddef.h>
  25. #include <string.h>
  26. /** Return true iff we need to quote and escape the string <b>s</b> to encode
  27. * it. */
  28. static bool
  29. needs_escape(const char *s, bool as_keyless_val)
  30. {
  31. if (as_keyless_val && *s == 0)
  32. return true;
  33. for (; *s; ++s) {
  34. if (*s >= 127 || TOR_ISSPACE(*s) || ! TOR_ISPRINT(*s) ||
  35. *s == '\'' || *s == '\"') {
  36. return true;
  37. }
  38. }
  39. return false;
  40. }
  41. /**
  42. * Return true iff the key in <b>line</b> is not set.
  43. **/
  44. static bool
  45. line_has_no_key(const config_line_t *line)
  46. {
  47. return line->key == NULL || strlen(line->key) == 0;
  48. }
  49. /**
  50. * Return true iff the value in <b>line</b> is not set.
  51. **/
  52. static bool
  53. line_has_no_val(const config_line_t *line)
  54. {
  55. return line->value == NULL || strlen(line->value) == 0;
  56. }
  57. /**
  58. * Return true iff the all the lines in <b>line</b> can be encoded
  59. * using <b>flags</b>.
  60. **/
  61. static bool
  62. kvline_can_encode_lines(const config_line_t *line, unsigned flags)
  63. {
  64. for ( ; line; line = line->next) {
  65. const bool keyless = line_has_no_key(line);
  66. if (keyless) {
  67. if (! (flags & KV_OMIT_KEYS)) {
  68. /* If KV_OMIT_KEYS is not set, we can't encode a line with no key. */
  69. return false;
  70. }
  71. if (strchr(line->value, '=') && !( flags & KV_QUOTED)) {
  72. /* We can't have a keyless value with = without quoting it. */
  73. return false;
  74. }
  75. }
  76. if (needs_escape(line->value, keyless) && ! (flags & KV_QUOTED)) {
  77. /* If KV_QUOTED is false, we can't encode a value that needs quotes. */
  78. return false;
  79. }
  80. if (line->key && strlen(line->key) &&
  81. (needs_escape(line->key, false) || strchr(line->key, '='))) {
  82. /* We can't handle keys that need quoting. */
  83. return false;
  84. }
  85. }
  86. return true;
  87. }
  88. /**
  89. * Encode a linked list of lines in <b>line</b> as a series of 'Key=Value'
  90. * pairs, using the provided <b>flags</b> to encode it. Return a newly
  91. * allocated string on success, or NULL on failure.
  92. *
  93. * If KV_QUOTED is set in <b>flags</b>, then all values that contain
  94. * spaces or unusual characters are escaped and quoted. Otherwise, such
  95. * values are not allowed.
  96. *
  97. * If KV_OMIT_KEYS is set in <b>flags</b>, then pairs with empty keys are
  98. * allowed, and are encoded as 'Value'. Otherwise, such pairs are not
  99. * allowed.
  100. *
  101. * If KV_OMIT_VALS is set in <b>flags</b>, then an empty value is
  102. * encoded as 'Key', not as 'Key=' or 'Key=""'. Mutually exclusive with
  103. * KV_OMIT_KEYS.
  104. *
  105. * KV_QUOTED_QSTRING is not supported.
  106. */
  107. char *
  108. kvline_encode(const config_line_t *line,
  109. unsigned flags)
  110. {
  111. tor_assert(! (flags & KV_QUOTED_QSTRING));
  112. if (!kvline_can_encode_lines(line, flags))
  113. return NULL;
  114. tor_assert((flags & (KV_OMIT_KEYS|KV_OMIT_VALS)) !=
  115. (KV_OMIT_KEYS|KV_OMIT_VALS));
  116. smartlist_t *elements = smartlist_new();
  117. for (; line; line = line->next) {
  118. const char *k = "";
  119. const char *eq = "=";
  120. const char *v = "";
  121. const bool keyless = line_has_no_key(line);
  122. bool esc = needs_escape(line->value, keyless);
  123. char *tmp = NULL;
  124. if (! keyless) {
  125. k = line->key;
  126. } else {
  127. eq = "";
  128. if (strchr(line->value, '=')) {
  129. esc = true;
  130. }
  131. }
  132. if ((flags & KV_OMIT_VALS) && line_has_no_val(line)) {
  133. eq = "";
  134. v = "";
  135. } else if (esc) {
  136. tmp = esc_for_log(line->value);
  137. v = tmp;
  138. } else {
  139. v = line->value;
  140. }
  141. smartlist_add_asprintf(elements, "%s%s%s", k, eq, v);
  142. tor_free(tmp);
  143. }
  144. char *result = smartlist_join_strings(elements, " ", 0, NULL);
  145. SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
  146. smartlist_free(elements);
  147. return result;
  148. }
  149. /**
  150. * Decode a <b>line</b> containing a series of space-separated 'Key=Value'
  151. * pairs, using the provided <b>flags</b> to decode it. Return a newly
  152. * allocated list of pairs on success, or NULL on failure.
  153. *
  154. * If KV_QUOTED is set in <b>flags</b>, then (double-)quoted values are
  155. * allowed and handled as C strings. Otherwise, such values are not allowed.
  156. *
  157. * If KV_OMIT_KEYS is set in <b>flags</b>, then values without keys are
  158. * allowed. Otherwise, such values are not allowed.
  159. *
  160. * If KV_OMIT_VALS is set in <b>flags</b>, then keys without values are
  161. * allowed. Otherwise, such keys are not allowed. Mutually exclusive with
  162. * KV_OMIT_KEYS.
  163. *
  164. * If KV_QUOTED_QSTRING is set in <b>flags</b>, then double-quoted values
  165. * are allowed and handled as QuotedStrings per qstring.c. Do not add
  166. * new users of this flag.
  167. */
  168. config_line_t *
  169. kvline_parse(const char *line, unsigned flags)
  170. {
  171. tor_assert((flags & (KV_OMIT_KEYS|KV_OMIT_VALS)) !=
  172. (KV_OMIT_KEYS|KV_OMIT_VALS));
  173. const char *cp = line, *cplast = NULL;
  174. const bool omit_keys = (flags & KV_OMIT_KEYS) != 0;
  175. const bool omit_vals = (flags & KV_OMIT_VALS) != 0;
  176. const bool quoted = (flags & (KV_QUOTED|KV_QUOTED_QSTRING)) != 0;
  177. const bool c_quoted = (flags & (KV_QUOTED)) != 0;
  178. config_line_t *result = NULL;
  179. config_line_t **next_line = &result;
  180. char *key = NULL;
  181. char *val = NULL;
  182. while (*cp) {
  183. key = val = NULL;
  184. /* skip all spaces */
  185. {
  186. size_t idx = strspn(cp, " \t\r\v\n");
  187. cp += idx;
  188. }
  189. if (BUG(cp == cplast)) {
  190. /* If we didn't parse anything since the last loop, this code is
  191. * broken. */
  192. goto err; // LCOV_EXCL_LINE
  193. }
  194. cplast = cp;
  195. if (! *cp)
  196. break; /* End of string; we're done. */
  197. /* Possible formats are K=V, K="V", K, V, and "V", depending on flags. */
  198. /* Find where the key ends */
  199. if (*cp != '\"') {
  200. size_t idx = strcspn(cp, " \t\r\v\n=");
  201. if (cp[idx] == '=') {
  202. key = tor_memdup_nulterm(cp, idx);
  203. cp += idx + 1;
  204. } else if (omit_vals) {
  205. key = tor_memdup_nulterm(cp, idx);
  206. cp += idx;
  207. goto commit;
  208. } else {
  209. if (!omit_keys)
  210. goto err;
  211. }
  212. }
  213. if (*cp == '\"') {
  214. /* The type is "V". */
  215. if (!quoted)
  216. goto err;
  217. size_t len=0;
  218. if (c_quoted) {
  219. cp = unescape_string(cp, &val, &len);
  220. } else {
  221. cp = decode_qstring(cp, strlen(cp), &val, &len);
  222. }
  223. if (cp == NULL || len != strlen(val)) {
  224. // The string contains a NUL or is badly coded.
  225. goto err;
  226. }
  227. } else {
  228. size_t idx = strcspn(cp, " \t\r\v\n");
  229. val = tor_memdup_nulterm(cp, idx);
  230. cp += idx;
  231. }
  232. commit:
  233. if (key && strlen(key) == 0) {
  234. /* We don't allow empty keys. */
  235. goto err;
  236. }
  237. *next_line = tor_malloc_zero(sizeof(config_line_t));
  238. (*next_line)->key = key ? key : tor_strdup("");
  239. (*next_line)->value = val ? val : tor_strdup("");
  240. next_line = &(*next_line)->next;
  241. key = val = NULL;
  242. }
  243. if (! (flags & KV_QUOTED_QSTRING)) {
  244. if (!kvline_can_encode_lines(result, flags)) {
  245. goto err;
  246. }
  247. }
  248. return result;
  249. err:
  250. tor_free(key);
  251. tor_free(val);
  252. config_free_lines(result);
  253. return NULL;
  254. }