Coverage Report

Created: 2026-07-16 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/open62541_15/src_generated/mdnsd/sdtxt.c
Line
Count
Source
1
#include "open62541/config.h"
2
/* Service discovery TXT record parsing/generation
3
 *
4
 * Copyright (c) 2003  Jeremie Miller <jer@jabber.org>
5
 * Copyright (c) 2016-2026  Joachim Wiberg <troglobit@gmail.com>
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are met:
10
 *     * Redistributions of source code must retain the above copyright
11
 *       notice, this list of conditions and the following disclaimer.
12
 *     * Redistributions in binary form must reproduce the above copyright
13
 *       notice, this list of conditions and the following disclaimer in the
14
 *       documentation and/or other materials provided with the distribution.
15
 *     * Neither the name of the copyright holders nor the names of its
16
 *       contributors may be used to endorse or promote products derived from
17
 *       this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
23
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
 * POSSIBILITY OF SUCH DAMAGE.
30
 */
31
32
#include "sdtxt.h"
33
#include <stdlib.h>
34
#include <string.h>
35
36
static size_t _sd2txt_len(const char *key, char *val)
37
29.2k
{
38
29.2k
  size_t ret = strlen(key);
39
40
29.2k
  if (!*val)
41
13.4k
    return ret;
42
43
15.7k
  ret += strlen(val);
44
15.7k
  ret++;
45
46
15.7k
  return ret;
47
29.2k
}
48
49
static void _sd2txt_count(xht_t *h __attribute__((unused)), const char *key, void *val, void *arg)
50
14.6k
{
51
14.6k
  int *const count = arg;
52
53
14.6k
  *count += (int)_sd2txt_len(key, val) + 1;
54
14.6k
}
55
56
static void _sd2txt_write(xht_t *h __attribute__((unused)), const char *key, void *val, void *arg)
57
14.6k
{
58
14.6k
  unsigned char **txtp = arg;
59
14.6k
  char *const cval = val;
60
61
  /* Copy in lengths, then strings */
62
14.6k
  **txtp = _sd2txt_len(key, val);
63
14.6k
  (*txtp)++;
64
14.6k
  memcpy(*txtp, key, strlen(key));
65
14.6k
  *txtp += strlen(key);
66
14.6k
  if (!*cval)
67
6.74k
    return;
68
69
7.89k
  **txtp = '=';
70
7.89k
  (*txtp)++;
71
7.89k
  memcpy(*txtp, cval, strlen(cval));
72
7.89k
  *txtp += strlen(cval);
73
7.89k
}
74
75
unsigned char *sd2txt(xht_t *h, int *len)
76
945
{
77
945
  unsigned char *buf, *raw;
78
79
945
  *len = 0;
80
81
945
  xht_walk(h, _sd2txt_count, len);
82
945
  if (!*len) {
83
40
    *len = 1;
84
40
    return (unsigned char *)strdup("");
85
40
  }
86
87
905
  raw = buf = malloc(*len);
88
905
  if (!buf)
89
0
    return NULL;
90
91
905
  xht_walk(h, _sd2txt_write, &buf);
92
93
905
  return raw;
94
905
}
95
96
xht_t *txt2sd(unsigned char *txt, int len)
97
668
{
98
668
  xht_t *h = 0;
99
100
668
  if (txt == 0 || len == 0 || *txt == 0)
101
2
    return 0;
102
103
666
  h = xht_new(23);
104
105
  /* Loop through data breaking out each block, storing into hashtable */
106
23.5k
  for (; len > 0 && *txt < len; len -= *txt + 1, txt += *txt + 1) {
107
22.9k
    char key[256], *val;
108
109
22.9k
    if (*txt == 0)
110
37
      break;
111
112
22.8k
    memcpy(key, txt + 1, *txt);
113
22.8k
    key[*txt] = 0;
114
115
    /* RFC 6763 ยง6.4: keep a bare key (no '=') as a boolean
116
     * attribute with an empty value rather than drop it (#58) */
117
22.8k
    val = strchr(key, '=');
118
22.8k
    if (val)
119
14.9k
      *val++ = 0;
120
7.90k
    else
121
7.90k
      val = "";
122
22.8k
    xht_store(h, key, (int)strlen(key), val, (int)strlen(val));
123
22.8k
  }
124
125
666
  return h;
126
668
}