static void test_split_pair(void) { _cleanup_free_ char *a = NULL, *b = NULL; assert_se(split_pair("", "", &a, &b) == -EINVAL); assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL); assert_se(split_pair("", "=", &a, &b) == -EINVAL); assert_se(split_pair("foo=bar", "=", &a, &b) >= 0); assert_se(streq(a, "foo")); assert_se(streq(b, "bar")); free(a); free(b); assert_se(split_pair("==", "==", &a, &b) >= 0); assert_se(streq(a, "")); assert_se(streq(b, "")); free(a); free(b); assert_se(split_pair("===", "==", &a, &b) >= 0); assert_se(streq(a, "")); assert_se(streq(b, "=")); }
int config_parse_dnssd_txt(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL; DnssdService *s = userdata; DnsTxtItem *last = NULL; assert(filename); assert(lvalue); assert(rvalue); assert(s); if (isempty(rvalue)) { /* Flush out collected items */ s->txt_data_items = dnssd_txtdata_free_all(s->txt_data_items); return 0; } txt_data = new0(DnssdTxtData, 1); if (!txt_data) return log_oom(); for (;;) { _cleanup_free_ char *word = NULL; _cleanup_free_ char *key = NULL; _cleanup_free_ char *value = NULL; _cleanup_free_ void *decoded = NULL; size_t length = 0; DnsTxtItem *i; int r; r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX); if (r == 0) break; if (r == -ENOMEM) return log_oom(); if (r < 0) return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); r = split_pair(word, "=", &key, &value); if (r == -ENOMEM) return log_oom(); if (r == -EINVAL) key = TAKE_PTR(word); if (!ascii_is_valid(key)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring: %s", key); return -EINVAL; } switch (ltype) { case DNS_TXT_ITEM_DATA: if (value) { r = unbase64mem(value, strlen(value), &decoded, &length); if (r == -ENOMEM) return log_oom(); if (r < 0) return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid base64 encoding, ignoring: %s", value); } r = dnssd_txt_item_new_from_data(key, decoded, length, &i); if (r < 0) return log_oom(); break; case DNS_TXT_ITEM_TEXT: r = dnssd_txt_item_new_from_string(key, value, &i); if (r < 0) return log_oom(); break; default: assert_not_reached("Unknown type of Txt config"); } LIST_INSERT_AFTER(items, txt_data->txt, last, i); last = i; } if (!LIST_IS_EMPTY(txt_data->txt)) { LIST_PREPEND(items, s->txt_data_items, txt_data); txt_data = NULL; } return 0; }