/src/systemd/src/libsystemd/sd-bus/bus-signature.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #include "sd-bus-protocol.h" |
4 | | |
5 | | #include "bus-signature.h" |
6 | | #include "bus-type.h" |
7 | | |
8 | | static int signature_element_length_internal( |
9 | | const char *s, |
10 | | bool allow_dict_entry, |
11 | | unsigned array_depth, |
12 | | unsigned struct_depth, |
13 | 489k | size_t *l) { |
14 | | |
15 | 489k | int r; |
16 | | |
17 | 489k | if (!s) |
18 | 0 | return -EINVAL; |
19 | | |
20 | 489k | assert(l); |
21 | | |
22 | 489k | if (bus_type_is_basic(*s) || *s == SD_BUS_TYPE_VARIANT) { |
23 | 231k | *l = 1; |
24 | 231k | return 0; |
25 | 231k | } |
26 | | |
27 | 258k | if (*s == SD_BUS_TYPE_ARRAY) { |
28 | 83.2k | size_t t; |
29 | | |
30 | 83.2k | if (array_depth >= 32) |
31 | 4 | return -EINVAL; |
32 | | |
33 | 83.2k | r = signature_element_length_internal(s + 1, true, array_depth+1, struct_depth, &t); |
34 | 83.2k | if (r < 0) |
35 | 227 | return r; |
36 | | |
37 | 82.9k | *l = t + 1; |
38 | 82.9k | return 0; |
39 | 83.2k | } |
40 | | |
41 | 175k | if (*s == SD_BUS_TYPE_STRUCT_BEGIN) { |
42 | 162k | const char *p = s + 1; |
43 | | |
44 | 162k | if (struct_depth >= 32) |
45 | 3 | return -EINVAL; |
46 | | |
47 | 356k | while (*p != SD_BUS_TYPE_STRUCT_END) { |
48 | 194k | size_t t; |
49 | | |
50 | 194k | r = signature_element_length_internal(p, false, array_depth, struct_depth+1, &t); |
51 | 194k | if (r < 0) |
52 | 283 | return r; |
53 | | |
54 | 193k | p += t; |
55 | 193k | } |
56 | | |
57 | 162k | if (p - s < 2) |
58 | | /* D-Bus spec: Empty structures are not allowed; there |
59 | | * must be at least one type code between the parentheses. |
60 | | */ |
61 | 3 | return -EINVAL; |
62 | | |
63 | 162k | *l = p - s + 1; |
64 | 162k | return 0; |
65 | 162k | } |
66 | | |
67 | 12.3k | if (*s == SD_BUS_TYPE_DICT_ENTRY_BEGIN && allow_dict_entry) { |
68 | 12.1k | const char *p = s + 1; |
69 | 12.1k | unsigned n = 0; |
70 | | |
71 | 12.1k | if (struct_depth >= 32) |
72 | 3 | return -EINVAL; |
73 | | |
74 | 36.7k | while (*p != SD_BUS_TYPE_DICT_ENTRY_END) { |
75 | 24.6k | size_t t; |
76 | | |
77 | 24.6k | if (n == 0 && !bus_type_is_basic(*p)) |
78 | 9 | return -EINVAL; |
79 | | |
80 | 24.6k | r = signature_element_length_internal(p, false, array_depth, struct_depth+1, &t); |
81 | 24.6k | if (r < 0) |
82 | 85 | return r; |
83 | | |
84 | 24.5k | p += t; |
85 | 24.5k | n++; |
86 | 24.5k | } |
87 | | |
88 | 12.1k | if (n != 2) |
89 | 5 | return -EINVAL; |
90 | | |
91 | 12.0k | *l = p - s + 1; |
92 | 12.0k | return 0; |
93 | 12.1k | } |
94 | | |
95 | 167 | return -EINVAL; |
96 | 12.3k | } |
97 | | |
98 | 47.0k | int signature_element_length(const char *s, size_t *l) { |
99 | 47.0k | return signature_element_length_internal(s, true, 0, 0, l); |
100 | 47.0k | } |
101 | | |
102 | 26.7k | bool signature_is_single(const char *s, bool allow_dict_entry) { |
103 | 26.7k | int r; |
104 | 26.7k | size_t t; |
105 | | |
106 | 26.7k | if (!s) |
107 | 0 | return false; |
108 | | |
109 | 26.7k | r = signature_element_length_internal(s, allow_dict_entry, 0, 0, &t); |
110 | 26.7k | if (r < 0) |
111 | 106 | return false; |
112 | | |
113 | 26.6k | return s[t] == 0; |
114 | 26.7k | } |
115 | | |
116 | 5.59k | bool signature_is_pair(const char *s) { |
117 | | |
118 | 5.59k | if (!s) |
119 | 0 | return false; |
120 | | |
121 | 5.59k | if (!bus_type_is_basic(*s)) |
122 | 0 | return false; |
123 | | |
124 | 5.59k | return signature_is_single(s + 1, false); |
125 | 5.59k | } |
126 | | |
127 | 98.6k | bool signature_is_valid(const char *s, bool allow_dict_entry) { |
128 | 98.6k | const char *p; |
129 | 98.6k | int r; |
130 | | |
131 | 98.6k | if (!s) |
132 | 0 | return false; |
133 | | |
134 | 98.6k | p = s; |
135 | 212k | while (*p) { |
136 | 113k | size_t t; |
137 | | |
138 | 113k | r = signature_element_length_internal(p, allow_dict_entry, 0, 0, &t); |
139 | 113k | if (r < 0) |
140 | 88 | return false; |
141 | | |
142 | 113k | p += t; |
143 | 113k | } |
144 | | |
145 | 98.5k | return p - s <= SD_BUS_MAXIMUM_SIGNATURE_LENGTH; |
146 | 98.6k | } |