]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-signature.c
tree-wide: remove Lennart's copyright lines
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-signature.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
de1c301e 2/***
de1c301e
LP
3***/
4
5#include <util.h>
6
dccca82b
LP
7#include "sd-bus.h"
8
de1c301e
LP
9#include "bus-signature.h"
10#include "bus-type.h"
11
12static int signature_element_length_internal(
13 const char *s,
14 bool allow_dict_entry,
813a4f93
LP
15 unsigned array_depth,
16 unsigned struct_depth,
de1c301e
LP
17 size_t *l) {
18
19 int r;
20
35460afc
LP
21 if (!s)
22 return -EINVAL;
23
718db961 24 assert(l);
de1c301e
LP
25
26 if (bus_type_is_basic(*s) || *s == SD_BUS_TYPE_VARIANT) {
27 *l = 1;
28 return 0;
29 }
30
31 if (*s == SD_BUS_TYPE_ARRAY) {
32 size_t t;
33
813a4f93
LP
34 if (array_depth >= 32)
35 return -EINVAL;
36
37 r = signature_element_length_internal(s + 1, true, array_depth+1, struct_depth, &t);
de1c301e
LP
38 if (r < 0)
39 return r;
40
41 *l = t + 1;
42 return 0;
43 }
44
45 if (*s == SD_BUS_TYPE_STRUCT_BEGIN) {
46 const char *p = s + 1;
47
813a4f93
LP
48 if (struct_depth >= 32)
49 return -EINVAL;
50
de1c301e
LP
51 while (*p != SD_BUS_TYPE_STRUCT_END) {
52 size_t t;
53
813a4f93 54 r = signature_element_length_internal(p, false, array_depth, struct_depth+1, &t);
de1c301e
LP
55 if (r < 0)
56 return r;
57
58 p += t;
59 }
60
61 *l = p - s + 1;
62 return 0;
63 }
64
65 if (*s == SD_BUS_TYPE_DICT_ENTRY_BEGIN && allow_dict_entry) {
66 const char *p = s + 1;
67 unsigned n = 0;
68
813a4f93
LP
69 if (struct_depth >= 32)
70 return -EINVAL;
71
de1c301e
LP
72 while (*p != SD_BUS_TYPE_DICT_ENTRY_END) {
73 size_t t;
74
75 if (n == 0 && !bus_type_is_basic(*p))
76 return -EINVAL;
77
813a4f93 78 r = signature_element_length_internal(p, false, array_depth, struct_depth+1, &t);
de1c301e
LP
79 if (r < 0)
80 return r;
81
82 p += t;
83 n++;
84 }
85
86 if (n != 2)
87 return -EINVAL;
88
89 *l = p - s + 1;
90 return 0;
91 }
92
93 return -EINVAL;
94}
95
813a4f93
LP
96int signature_element_length(const char *s, size_t *l) {
97 return signature_element_length_internal(s, true, 0, 0, l);
98}
99
29ddb38f 100bool signature_is_single(const char *s, bool allow_dict_entry) {
de1c301e
LP
101 int r;
102 size_t t;
103
35460afc
LP
104 if (!s)
105 return false;
de1c301e 106
29ddb38f 107 r = signature_element_length_internal(s, allow_dict_entry, 0, 0, &t);
de1c301e
LP
108 if (r < 0)
109 return false;
110
111 return s[t] == 0;
112}
113
114bool signature_is_pair(const char *s) {
718db961 115
35460afc
LP
116 if (!s)
117 return false;
de1c301e
LP
118
119 if (!bus_type_is_basic(*s))
120 return false;
121
29ddb38f 122 return signature_is_single(s + 1, false);
de1c301e
LP
123}
124
125bool signature_is_valid(const char *s, bool allow_dict_entry) {
126 const char *p;
127 int r;
128
35460afc
LP
129 if (!s)
130 return false;
de1c301e
LP
131
132 p = s;
133 while (*p) {
134 size_t t;
135
813a4f93 136 r = signature_element_length_internal(p, allow_dict_entry, 0, 0, &t);
de1c301e
LP
137 if (r < 0)
138 return false;
139
140 p += t;
141 }
142
143 return p - s <= 255;
144}