Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | |||
29 | #include "gate/uris.h" | ||
30 | #include "gate/results.h" | ||
31 | |||
32 | static gate_string_t const gate_uri_scheme_separator = GATE_STRING_INIT_STATIC(GATE_URI_SCHEME_SEPARATOR); | ||
33 | |||
34 | static gate_string_t const gate_uri_userinfo_separator = GATE_STRING_INIT_STATIC("@"); | ||
35 | static gate_string_t const gate_uri_path_separator = GATE_STRING_INIT_STATIC("/"); | ||
36 | static gate_string_t const gate_uri_query_separator = GATE_STRING_INIT_STATIC("?"); | ||
37 | |||
38 | |||
39 | 12 | gate_result_t gate_uri_init(gate_uri_t* uri) | |
40 | { | ||
41 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | if (uri) |
42 | { | ||
43 | 12 | gate_mem_clear(uri, sizeof(gate_uri_t)); | |
44 | 12 | return GATE_RESULT_OK; | |
45 | } | ||
46 | else | ||
47 | { | ||
48 | ✗ | return GATE_RESULT_NULLPOINTER; | |
49 | } | ||
50 | } | ||
51 | |||
52 | 2 | gate_result_t gate_uri_copy(gate_uri_t* target, gate_uri_t const* src) | |
53 | { | ||
54 | 2 | gate_result_t result = GATE_RESULT_OUTOFMEMORY; | |
55 | |||
56 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!target) |
57 | { | ||
58 | ✗ | return GATE_RESULT_NULLPOINTER; | |
59 | } | ||
60 | |||
61 | do | ||
62 | { | ||
63 | 2 | gate_mem_clear(target, sizeof(gate_uri_t)); | |
64 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (src) |
65 | { | ||
66 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_string_clone(&target->scheme, &src->scheme)) break; |
67 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_string_clone(&target->user_info, &src->user_info)) break; |
68 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_string_clone(&target->host, &src->host)) break; |
69 | 2 | target->port = src->port; | |
70 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_string_clone(&target->absolute_path, &src->absolute_path)) break; |
71 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_string_clone(&target->query, &src->query)) break; |
72 | } | ||
73 | |||
74 | 2 | result = GATE_RESULT_OK; | |
75 | } while (0); | ||
76 | |||
77 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (GATE_FAILED(result)) |
78 | { | ||
79 | ✗ | gate_uri_destroy(target); | |
80 | } | ||
81 | |||
82 | 2 | return result; | |
83 | } | ||
84 | |||
85 | |||
86 | 13 | gate_result_t gate_uri_destroy(gate_uri_t* uri) | |
87 | { | ||
88 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | if (uri) |
89 | { | ||
90 | 13 | gate_string_release(&uri->scheme); | |
91 | 13 | gate_string_release(&uri->user_info); | |
92 | 13 | gate_string_release(&uri->host); | |
93 | 13 | uri->port = 0; | |
94 | 13 | gate_string_release(&uri->absolute_path); | |
95 | 13 | gate_string_release(&uri->query); | |
96 | 13 | gate_mem_clear(uri, sizeof(gate_uri_t)); | |
97 | 13 | return GATE_RESULT_OK; | |
98 | } | ||
99 | else | ||
100 | { | ||
101 | ✗ | return GATE_RESULT_NULLPOINTER; | |
102 | } | ||
103 | } | ||
104 | |||
105 | 6 | gate_result_t gate_uri_parse_path(gate_string_t const* path, gate_string_t* abs_path, gate_string_t* query_part) | |
106 | { | ||
107 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
|
6 | if (gate_string_is_empty(path)) |
108 | { | ||
109 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (abs_path) |
110 | { | ||
111 | 1 | gate_string_create_static_len(abs_path, gate_uri_path_separator.str, gate_uri_path_separator.length); | |
112 | } | ||
113 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (query_part) |
114 | { | ||
115 | 1 | gate_string_create_empty(query_part); | |
116 | } | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
|
5 | if (0 == gate_string_parse(path, &gate_uri_query_separator, 0, abs_path, query_part, true)) |
121 | { | ||
122 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (abs_path) |
123 | { | ||
124 | 3 | gate_string_duplicate(abs_path, path); | |
125 | } | ||
126 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (query_part) |
127 | { | ||
128 | 3 | gate_string_create_empty(query_part); | |
129 | } | ||
130 | } | ||
131 | } | ||
132 | 6 | return GATE_RESULT_OK; | |
133 | } | ||
134 | |||
135 | |||
136 | 4 | gate_result_t gate_uri_parse(gate_uri_t* uri, gate_string_t const* text) | |
137 | { | ||
138 | 4 | gate_result_t ret = GATE_RESULT_FAILED; | |
139 | gate_size_t pos; | ||
140 | 4 | gate_string_t source = GATE_STRING_INIT_EMPTY; | |
141 | 4 | gate_string_t part = GATE_STRING_INIT_EMPTY; | |
142 | 4 | gate_string_t address = GATE_STRING_INIT_EMPTY; | |
143 | 4 | gate_string_t path = GATE_STRING_INIT_EMPTY; | |
144 | 4 | gate_string_t hostport = GATE_STRING_INIT_EMPTY; | |
145 | 4 | gate_int64_t num = 0; | |
146 | |||
147 | do | ||
148 | { | ||
149 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (NULL == gate_string_clone(&source, text)) |
150 | { | ||
151 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
152 | ✗ | break; | |
153 | } | ||
154 | 4 | gate_uri_init(uri); | |
155 | |||
156 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_parse(&source, &gate_uri_scheme_separator, 0, &uri->scheme, &part, false)) |
157 | { | ||
158 | ✗ | break; | |
159 | } | ||
160 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_parse(&part, &gate_uri_path_separator, 0, &address, &path, true)) |
161 | { | ||
162 | ✗ | gate_string_clone(&address, &part); | |
163 | } | ||
164 | |||
165 | 4 | gate_uri_parse_path(&path, &uri->absolute_path, &uri->query); | |
166 | |||
167 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
4 | if (!gate_string_parse(&address, &gate_uri_userinfo_separator, 0, &uri->user_info, &hostport, false)) |
168 | { | ||
169 | 3 | gate_string_clone(&hostport, &address); | |
170 | } | ||
171 | 4 | pos = gate_string_char_pos(&hostport, ':', 0); | |
172 | 4 | uri->port = 0; | |
173 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
|
4 | if (pos == GATE_STR_NPOS) |
174 | { | ||
175 | 3 | gate_string_clone(&uri->host, &hostport); | |
176 | } | ||
177 | else | ||
178 | { | ||
179 | 1 | gate_string_substr(&uri->host, &hostport, 0, pos); | |
180 | 1 | gate_str_parse_int64(gate_string_ptr(&hostport, pos + 1), | |
181 | 1 | gate_string_length(&hostport) - pos - 1, | |
182 | &num); | ||
183 | 1 | uri->port = (gate_int32_t)num; | |
184 | } | ||
185 | 4 | ret = GATE_RESULT_OK; | |
186 | |||
187 | } while (0); | ||
188 | |||
189 | 4 | gate_string_release(&hostport); | |
190 | 4 | gate_string_release(&path); | |
191 | 4 | gate_string_release(&address); | |
192 | 4 | gate_string_release(&part); | |
193 | 4 | gate_string_release(&source); | |
194 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (GATE_FAILED(ret)) |
195 | { | ||
196 | ✗ | gate_uri_destroy(uri); | |
197 | } | ||
198 | 4 | pos = gate_string_pos(text, &gate_uri_scheme_separator, 0); | |
199 | 4 | return ret; | |
200 | } | ||
201 | 9 | gate_result_t gate_uri_to_string(gate_uri_t const* uri, gate_string_t* text, gate_bool_t absolute_path_only) | |
202 | { | ||
203 | 9 | gate_result_t ret = GATE_RESULT_OUTOFMEMORY; | |
204 | gate_strbuilder_t builder; | ||
205 | do | ||
206 | { | ||
207 | 9 | gate_strbuilder_create(&builder, 128); | |
208 | |||
209 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
|
9 | if (!absolute_path_only) |
210 | { | ||
211 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if (0 == gate_strbuilder_append_string(&builder, &uri->scheme)) break; |
212 | |||
213 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if (0 == gate_strbuilder_append_string(&builder, &gate_uri_scheme_separator)) break; |
214 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
|
6 | if (!gate_string_is_empty(&uri->user_info)) |
215 | { | ||
216 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (0 == gate_strbuilder_append_string(&builder, &uri->user_info)) break; |
217 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (0 == gate_strbuilder_append_text(&builder, "@", 1)) break; |
218 | } | ||
219 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if (0 == gate_strbuilder_append_string(&builder, &uri->host)) break; |
220 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (uri->port != 0) |
221 | { | ||
222 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if (0 == gate_strbuilder_append_text(&builder, ":", 1)) break; |
223 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if (0 == gate_strbuilder_append_int32(&builder, uri->port)) break; |
224 | } | ||
225 | } | ||
226 | |||
227 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
|
9 | if (gate_string_is_empty(&uri->absolute_path) || uri->absolute_path.str[0] != '/') |
228 | { | ||
229 | ✗ | if (0 == gate_strbuilder_append_text(&builder, "/", 1)) break; | |
230 | } | ||
231 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | if (!gate_string_is_empty(&uri->absolute_path)) |
232 | { | ||
233 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
9 | if (0 == gate_strbuilder_append_string(&builder, &uri->absolute_path)) break; |
234 | } | ||
235 | |||
236 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 5 times.
|
9 | if (!gate_string_is_empty(&uri->query)) |
237 | { | ||
238 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
4 | if ((uri->query.str[0] != '?') && (uri->query.str[0] != '#')) |
239 | { | ||
240 | ✗ | if (0 == gate_strbuilder_append_text(&builder, "?", 1)) break; | |
241 | } | ||
242 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (0 == gate_strbuilder_append_string(&builder, &uri->query)) break; |
243 | } | ||
244 | |||
245 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | if (gate_strbuilder_to_string(&builder, text)) |
246 | { | ||
247 | 9 | ret = GATE_RESULT_OK; | |
248 | } | ||
249 | } while (0); | ||
250 | |||
251 | 9 | gate_strbuilder_release(&builder); | |
252 | 9 | return ret; | |
253 | } | ||
254 | |||
255 | 54 | static gate_bool_t gate_uri_is_allowed_char(char c) | |
256 | { | ||
257 | return ( | ||
258 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | ((c >= 'A') && (c <= 'Z')) |
259 |
4/4✓ Branch 0 taken 27 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 24 times.
|
54 | || ((c >= 'a') && (c <= 'z')) |
260 |
3/4✓ Branch 0 taken 13 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
30 | || ((c >= '0') && (c <= '9')) |
261 |
2/2✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
|
30 | || (c == '_') |
262 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1 times.
|
29 | || (c == '-') |
263 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
|
28 | || (c == '.') |
264 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
|
27 | || (c == '*') |
265 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
|
26 | || (c == '!') |
266 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | || (c == '~') |
267 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1 times.
|
25 | || (c == '\'') |
268 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1 times.
|
24 | || (c == '(') |
269 |
4/4✓ Branch 0 taken 31 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 22 times.
|
108 | || (c == ')') |
270 | ); | ||
271 | } | ||
272 | |||
273 | 6 | gate_result_t gate_uri_escape(gate_string_t const* src, gate_string_t* dest) | |
274 | { | ||
275 | 6 | gate_result_t ret = GATE_RESULT_OUTOFMEMORY; | |
276 | 6 | gate_strbuilder_t builder = GATE_INIT_EMPTY; | |
277 | gate_size_t len; | ||
278 | char const* ptr; | ||
279 | 6 | char hexbuf[4] = "%__"; | |
280 | do | ||
281 | { | ||
282 | 6 | len = gate_string_length(src); | |
283 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
|
6 | if (len == 0) |
284 | { | ||
285 | 1 | gate_string_create_empty(dest); | |
286 | 1 | ret = GATE_RESULT_OK; | |
287 | 1 | break; | |
288 | } | ||
289 | 5 | gate_strbuilder_create(&builder, len + len / 2 + 2); | |
290 | |||
291 | 5 | ret = GATE_RESULT_OK; | |
292 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 5 times.
|
59 | for (ptr = src->str; len != 0; ++ptr, --len) |
293 | { | ||
294 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 2 taken 22 times.
|
54 | if (gate_uri_is_allowed_char(*ptr)) |
295 | { | ||
296 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
|
32 | if (0 == gate_strbuilder_append_text(&builder, ptr, 1)) |
297 | { | ||
298 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
299 | ✗ | break; | |
300 | } | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | 22 | gate_str_print_hex_byte(&hexbuf[1], 2, (gate_uint8_t)*ptr, true); | |
305 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
|
22 | if (3 != gate_strbuilder_append_text(&builder, hexbuf, 3)) |
306 | { | ||
307 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
308 | ✗ | break; | |
309 | } | ||
310 | } | ||
311 | } | ||
312 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | if (GATE_SUCCEEDED(ret)) |
313 | { | ||
314 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
|
5 | if (!gate_strbuilder_to_string(&builder, dest)) |
315 | { | ||
316 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
317 | } | ||
318 | } | ||
319 | |||
320 | } while (0); | ||
321 | 6 | gate_strbuilder_release(&builder); | |
322 | 6 | return ret; | |
323 | } | ||
324 | 4 | gate_result_t gate_uri_unescape(gate_string_t const* src, gate_string_t* dest) | |
325 | { | ||
326 | 4 | gate_result_t ret = GATE_RESULT_OUTOFMEMORY; | |
327 | 4 | gate_strbuilder_t builder = GATE_INIT_EMPTY; | |
328 | gate_size_t len; | ||
329 | char const* ptr; | ||
330 | gate_uint8_t u8; | ||
331 | do | ||
332 | { | ||
333 | 4 | len = gate_string_length(src); | |
334 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
|
4 | if (len == 0) |
335 | { | ||
336 | 1 | gate_string_create_empty(dest); | |
337 | 1 | ret = GATE_RESULT_OK; | |
338 | 1 | break; | |
339 | } | ||
340 | 3 | gate_strbuilder_create(&builder, len); | |
341 | |||
342 | 3 | ret = GATE_RESULT_OK; | |
343 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 3 times.
|
45 | for (ptr = src->str; len != 0; ++ptr, --len) |
344 | { | ||
345 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 20 times.
|
42 | if (*ptr == '%') |
346 | { | ||
347 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
|
22 | if (len < 3) |
348 | { | ||
349 | ✗ | ret = GATE_RESULT_INVALIDDATA; | |
350 | ✗ | break; | |
351 | } | ||
352 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
|
22 | if (!gate_str_parse_hex_byte(&ptr[1], &u8)) |
353 | { | ||
354 | ✗ | ret = GATE_RESULT_INVALIDDATA; | |
355 | ✗ | break; | |
356 | } | ||
357 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
|
22 | if (0 == gate_strbuilder_append_text(&builder, (char const*)&u8, 1)) |
358 | { | ||
359 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
360 | ✗ | break; | |
361 | } | ||
362 | 22 | ptr += 2; | |
363 | 22 | len -= 2; | |
364 | } | ||
365 | else | ||
366 | { | ||
367 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
|
20 | if (0 == gate_strbuilder_append_text(&builder, ptr, 1)) |
368 | { | ||
369 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
370 | ✗ | break; | |
371 | } | ||
372 | } | ||
373 | } | ||
374 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (GATE_SUCCEEDED(ret)) |
375 | { | ||
376 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
3 | if (!gate_strbuilder_to_string(&builder, dest)) |
377 | { | ||
378 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
379 | } | ||
380 | } | ||
381 | } while (0); | ||
382 | 4 | gate_strbuilder_release(&builder); | |
383 | 4 | return ret; | |
384 | } | ||
385 | |||
386 | 4 | gate_result_t gate_uri_parse_user_info(gate_string_t const* src, gate_string_t* username, gate_string_t* password) | |
387 | { | ||
388 | 4 | gate_result_t ret = GATE_RESULT_OUTOFMEMORY; | |
389 | gate_size_t pos; | ||
390 | gate_string_t str_user, str_pass; | ||
391 | do | ||
392 | { | ||
393 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
4 | if (gate_string_is_empty(src)) |
394 | { | ||
395 | 3 | gate_string_create_empty(username); | |
396 | 3 | gate_string_create_empty(password); | |
397 | 3 | ret = GATE_RESULT_OK; | |
398 | } | ||
399 | else | ||
400 | { | ||
401 | 1 | pos = gate_string_char_pos(src, ':', 0); | |
402 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (pos == GATE_STR_NPOS) |
403 | { | ||
404 | ✗ | if (gate_string_create(username, src->str, src->length)) | |
405 | { | ||
406 | ✗ | ret = GATE_RESULT_OK; | |
407 | } | ||
408 | } | ||
409 | else | ||
410 | { | ||
411 | 1 | gate_string_create_static_len(&str_user, src->str, pos); | |
412 | 1 | gate_string_create_static_len(&str_pass, src->str + pos + 1, src->length - pos - 1); | |
413 | 1 | ret = gate_uri_unescape(&str_user, username); | |
414 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(ret); |
415 | 1 | ret = gate_uri_unescape(&str_pass, password); | |
416 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (GATE_FAILED(ret)) |
417 | { | ||
418 | ✗ | gate_string_release(username); | |
419 | } | ||
420 | } | ||
421 | } | ||
422 | } while (0); | ||
423 | 4 | return ret; | |
424 | } | ||
425 | 1 | gate_result_t gate_uri_build_user_info(gate_string_t const* username, gate_string_t const* password, gate_string_t* user_info) | |
426 | { | ||
427 | 1 | gate_result_t ret = GATE_RESULT_OUTOFMEMORY; | |
428 | gate_strbuilder_t builder; | ||
429 | gate_size_t len; | ||
430 | 1 | gate_string_t str_user = GATE_STRING_INIT_EMPTY; | |
431 | 1 | gate_string_t str_pass = GATE_STRING_INIT_EMPTY; | |
432 | do | ||
433 | { | ||
434 | 1 | gate_strbuilder_create(&builder, gate_string_length(username) + gate_string_length(password) + 3); | |
435 | |||
436 | 1 | len = gate_string_length(username); | |
437 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (len > 0) |
438 | { | ||
439 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(gate_uri_escape(username, &str_user)); |
440 | |||
441 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (0 == gate_strbuilder_append_string(&builder, &str_user)) break; |
442 | } | ||
443 | 1 | len = gate_string_length(password); | |
444 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (len != 0) |
445 | { | ||
446 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (0 == gate_strbuilder_append_text(&builder, ":", 1)) break; |
447 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(gate_uri_escape(password, &str_pass)); |
448 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (0 == gate_strbuilder_append_string(&builder, &str_pass)) break; |
449 | } | ||
450 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if (gate_strbuilder_to_string(&builder, user_info)) |
451 | { | ||
452 | 1 | ret = GATE_RESULT_OK; | |
453 | } | ||
454 | } while (0); | ||
455 | |||
456 | 1 | gate_strbuilder_release(&builder); | |
457 | 1 | gate_string_release(&str_user); | |
458 | 1 | gate_string_release(&str_pass); | |
459 | 1 | return ret; | |
460 | } | ||
461 |