Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) | ||
3 | // | ||
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
6 | // | ||
7 | // Official repository: https://github.com/boostorg/url | ||
8 | // | ||
9 | |||
10 | |||
11 | #include <boost/url/detail/config.hpp> | ||
12 | #include "path.hpp" | ||
13 | #include <boost/url/detail/url_impl.hpp> | ||
14 | #include <boost/url/authority_view.hpp> | ||
15 | #include <boost/assert.hpp> | ||
16 | #include <cstring> | ||
17 | |||
18 | namespace boost { | ||
19 | namespace urls { | ||
20 | namespace detail { | ||
21 | |||
22 | #if defined(__GNUC__) && ! defined(__clang__) && defined(__MINGW32__) | ||
23 | #pragma GCC diagnostic push | ||
24 | #pragma GCC diagnostic ignored "-Warray-bounds" | ||
25 | #endif | ||
26 | |||
27 | //------------------------------------------------ | ||
28 | // | ||
29 | // url_impl | ||
30 | // | ||
31 | //------------------------------------------------ | ||
32 | |||
33 | void | ||
34 | 2269 | url_impl:: | |
35 | apply_scheme( | ||
36 | core::string_view s) noexcept | ||
37 | { | ||
38 | 2269 | scheme_ = string_to_scheme(s); | |
39 | 2269 | set_size(id_scheme, s.size() + 1); | |
40 | 2269 | } | |
41 | |||
42 | void | ||
43 | 381 | url_impl:: | |
44 | apply_userinfo( | ||
45 | pct_string_view const& user, | ||
46 | pct_string_view const* pass) noexcept | ||
47 | { | ||
48 | // this function is for | ||
49 | // authority_view_rule only | ||
50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 381 times.
|
381 | BOOST_ASSERT(from_ == from::authority); |
51 | |||
52 | // userinfo | ||
53 | 381 | set_size(id_user, user.size()); | |
54 | 381 | decoded_[id_user] = | |
55 | 381 | user.decoded_size(); | |
56 |
2/2✓ Branch 0 taken 252 times.
✓ Branch 1 taken 129 times.
|
381 | if(pass) |
57 | { | ||
58 | 252 | set_size(id_pass, | |
59 | 252 | pass->size() + 2); | |
60 | 252 | decoded_[id_pass] = | |
61 | 252 | pass->decoded_size(); | |
62 | } | ||
63 | else | ||
64 | { | ||
65 | // trailing '@' | ||
66 | 129 | set_size(id_pass, 1 ); | |
67 | } | ||
68 | 381 | } | |
69 | |||
70 | void | ||
71 | 1870 | url_impl:: | |
72 | apply_host( | ||
73 | host_type ht, | ||
74 | pct_string_view s, | ||
75 | unsigned char const* addr) noexcept | ||
76 | { | ||
77 | // this function is for | ||
78 | // authority_view_rule only | ||
79 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1870 times.
|
1870 | BOOST_ASSERT(from_ == from::authority); |
80 | |||
81 | // host, port | ||
82 | 1870 | host_type_ = ht; | |
83 | 1870 | set_size(id_host, s.size()); | |
84 | 1870 | decoded_[id_host] = | |
85 | 1870 | s.decoded_size(); | |
86 | 1870 | std::memcpy( | |
87 | 1870 | ip_addr_, | |
88 | addr, | ||
89 | sizeof(ip_addr_)); | ||
90 | 1870 | } | |
91 | |||
92 | void | ||
93 | 260 | url_impl:: | |
94 | apply_port( | ||
95 | core::string_view s, | ||
96 | unsigned short pn) noexcept | ||
97 | { | ||
98 | // this function is for | ||
99 | // authority_view_rule only | ||
100 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 260 times.
|
260 | BOOST_ASSERT(from_ == from::authority); |
101 | |||
102 | 260 | port_number_ = pn; | |
103 | 260 | set_size(id_port, 1 + s.size()); | |
104 | 260 | } | |
105 | |||
106 | void | ||
107 | 1812 | url_impl:: | |
108 | apply_authority( | ||
109 | authority_view const& a) noexcept | ||
110 | { | ||
111 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1812 times.
|
1812 | BOOST_ASSERT(from_ != from::authority); |
112 | |||
113 | // userinfo | ||
114 | 1812 | set_size(id_user, | |
115 | 1812 | a.u_.len(id_user) + | |
116 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1812 times.
|
1812 | (from_ == from::authority ? 0 : 2)); |
117 | 1812 | set_size(id_pass, a.u_.len(id_pass)); | |
118 | 1812 | decoded_[id_user] = a.u_.decoded_[id_user]; | |
119 | 1812 | decoded_[id_pass] = a.u_.decoded_[id_pass]; | |
120 | |||
121 | // host, port | ||
122 | 1812 | host_type_ = a.u_.host_type_; | |
123 | 1812 | port_number_ = a.u_.port_number_; | |
124 | 1812 | set_size(id_host, a.u_.len(id_host)); | |
125 | 1812 | set_size(id_port, a.u_.len(id_port)); | |
126 | 1812 | std::memcpy( | |
127 | 1812 | ip_addr_, | |
128 | 1812 | a.u_.ip_addr_, | |
129 | sizeof(ip_addr_)); | ||
130 | 1812 | decoded_[id_host] = a.u_.decoded_[id_host]; | |
131 | 1812 | } | |
132 | |||
133 | void | ||
134 | 3544 | url_impl:: | |
135 | apply_path( | ||
136 | pct_string_view s, | ||
137 | std::size_t nseg) noexcept | ||
138 | { | ||
139 | 3544 | set_size(id_path, s.size()); | |
140 | 3544 | decoded_[id_path] = s.decoded_size(); | |
141 | 3544 | nseg_ = detail::path_segments(s, nseg); | |
142 | 3544 | } | |
143 | |||
144 | void | ||
145 | 430 | url_impl:: | |
146 | apply_query( | ||
147 | pct_string_view s, | ||
148 | std::size_t n) noexcept | ||
149 | { | ||
150 | 430 | nparam_ = n; | |
151 | 430 | set_size(id_query, 1 + s.size()); | |
152 | 430 | decoded_[id_query] = s.decoded_size(); | |
153 | 430 | } | |
154 | |||
155 | void | ||
156 | 210 | url_impl:: | |
157 | apply_frag( | ||
158 | pct_string_view s) noexcept | ||
159 | { | ||
160 | 210 | set_size(id_frag, s.size() + 1); | |
161 | 210 | decoded_[id_frag] = s.decoded_size(); | |
162 | 210 | } | |
163 | |||
164 | // return length of [first, last) | ||
165 | auto | ||
166 | 20207 | url_impl:: | |
167 | len( | ||
168 | int first, | ||
169 | int last) const noexcept -> | ||
170 | std::size_t | ||
171 | { | ||
172 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20207 times.
|
20207 | BOOST_ASSERT(first <= last); |
173 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20207 times.
|
20207 | BOOST_ASSERT(last <= id_end); |
174 | 20207 | return offset(last) - offset(first); | |
175 | } | ||
176 | |||
177 | // return length of part | ||
178 | auto | ||
179 | 265516 | url_impl:: | |
180 | len(int id) const noexcept -> | ||
181 | std::size_t | ||
182 | { | ||
183 | return id == id_end | ||
184 |
1/2✓ Branch 0 taken 265516 times.
✗ Branch 1 not taken.
|
531032 | ? zero_ |
185 | 265516 | : ( offset(id + 1) - | |
186 | 531032 | offset(id) ); | |
187 | } | ||
188 | |||
189 | // return offset of id | ||
190 | auto | ||
191 | 695451 | url_impl:: | |
192 | offset(int id) const noexcept -> | ||
193 | std::size_t | ||
194 | { | ||
195 | return | ||
196 | id == id_scheme | ||
197 |
2/2✓ Branch 0 taken 643123 times.
✓ Branch 1 taken 52328 times.
|
695451 | ? zero_ |
198 | 695451 | : offset_[id]; | |
199 | } | ||
200 | |||
201 | // return id as string | ||
202 | core::string_view | ||
203 | 47265 | url_impl:: | |
204 | get(int id) const noexcept | ||
205 | { | ||
206 | return { | ||
207 | 47265 | cs_ + offset(id), len(id) }; | |
208 | } | ||
209 | |||
210 | // return [first, last) as string | ||
211 | core::string_view | ||
212 | 873 | url_impl:: | |
213 | get(int first, | ||
214 | int last) const noexcept | ||
215 | { | ||
216 | 873 | return { cs_ + offset(first), | |
217 | 873 | offset(last) - offset(first) }; | |
218 | } | ||
219 | |||
220 | // return id as pct-string | ||
221 | pct_string_view | ||
222 | 2172 | url_impl:: | |
223 | pct_get( | ||
224 | int id) const noexcept | ||
225 | { | ||
226 | 2172 | return make_pct_string_view_unsafe( | |
227 | 2172 | cs_ + offset(id), | |
228 | len(id), | ||
229 | 4344 | decoded_[id]); | |
230 | } | ||
231 | |||
232 | // return [first, last) as pct-string | ||
233 | pct_string_view | ||
234 | 120 | url_impl:: | |
235 | pct_get( | ||
236 | int first, | ||
237 | int last) const noexcept | ||
238 | { | ||
239 | 120 | auto const pos = offset(first); | |
240 | 120 | std::size_t n = 0; | |
241 |
2/2✓ Branch 0 taken 240 times.
✓ Branch 1 taken 120 times.
|
360 | for(auto i = first; i < last;) |
242 | 240 | n += decoded_[i++]; | |
243 | 120 | return make_pct_string_view_unsafe( | |
244 | 120 | cs_ + pos, | |
245 | 120 | offset(last) - pos, | |
246 | 120 | n); | |
247 | } | ||
248 | |||
249 | //------------------------------------------------ | ||
250 | |||
251 | // change id to size n | ||
252 | void | ||
253 | 19240 | url_impl:: | |
254 | set_size( | ||
255 | int id, | ||
256 | std::size_t n) noexcept | ||
257 | { | ||
258 | 19240 | auto d = n - len(id); | |
259 | 19240 | for(auto i = id + 1; | |
260 |
2/2✓ Branch 0 taken 97659 times.
✓ Branch 1 taken 19240 times.
|
116899 | i <= id_end; ++i) |
261 | 97659 | offset_[i] += d; | |
262 | 19240 | } | |
263 | |||
264 | // trim id to size n, | ||
265 | // moving excess into id+1 | ||
266 | void | ||
267 | 811 | url_impl:: | |
268 | split( | ||
269 | int id, | ||
270 | std::size_t n) noexcept | ||
271 | { | ||
272 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 811 times.
|
811 | BOOST_ASSERT(id < id_end - 1); |
273 | //BOOST_ASSERT(n <= len(id)); | ||
274 | 811 | offset_[id + 1] = offset(id) + n; | |
275 | 811 | } | |
276 | |||
277 | // add n to [first, last] | ||
278 | void | ||
279 | 911 | url_impl:: | |
280 | adjust_right( | ||
281 | int first, | ||
282 | int last, | ||
283 | std::size_t n) noexcept | ||
284 | { | ||
285 | 911 | for(int i = first; | |
286 |
2/2✓ Branch 0 taken 4394 times.
✓ Branch 1 taken 911 times.
|
5305 | i <= last; ++i) |
287 | 4394 | offset_[i] += n; | |
288 | 911 | } | |
289 | |||
290 | // remove n from [first, last] | ||
291 | void | ||
292 | 676 | url_impl:: | |
293 | adjust_left( | ||
294 | int first, | ||
295 | int last, | ||
296 | std::size_t n) noexcept | ||
297 | { | ||
298 | 676 | for(int i = first; | |
299 |
2/2✓ Branch 0 taken 2657 times.
✓ Branch 1 taken 676 times.
|
3333 | i <= last; ++i) |
300 | 2657 | offset_[i] -= n; | |
301 | 676 | } | |
302 | |||
303 | // set [first, last) offset | ||
304 | void | ||
305 | 1568 | url_impl:: | |
306 | collapse( | ||
307 | int first, | ||
308 | int last, | ||
309 | std::size_t n) noexcept | ||
310 | { | ||
311 | 1568 | for(int i = first + 1; | |
312 |
2/2✓ Branch 0 taken 545 times.
✓ Branch 1 taken 1568 times.
|
2113 | i < last; ++i) |
313 | 545 | offset_[i] = n; | |
314 | 1568 | } | |
315 | |||
316 | |||
317 | //------------------------------------------------ | ||
318 | // | ||
319 | // path_ref | ||
320 | // | ||
321 | //------------------------------------------------ | ||
322 | |||
323 | 2027 | path_ref:: | |
324 | path_ref( | ||
325 | 2027 | url_impl const& impl) noexcept | |
326 | { | ||
327 |
2/2✓ Branch 0 taken 1571 times.
✓ Branch 1 taken 456 times.
|
2027 | if(impl.from_ == url_impl::from::url) |
328 | { | ||
329 | 1571 | impl_ = &impl; | |
330 | } | ||
331 | else | ||
332 | { | ||
333 | 456 | core::string_view s = impl.get(id_path); | |
334 | 456 | data_ = s.data(); | |
335 | 456 | size_ = s.size(); | |
336 | 456 | nseg_ = impl.nseg_; | |
337 | 456 | dn_ = impl.decoded_[id_path]; | |
338 | } | ||
339 | 2027 | } | |
340 | |||
341 | 141 | path_ref:: | |
342 | path_ref( | ||
343 | core::string_view s, | ||
344 | std::size_t dn, | ||
345 | 141 | std::size_t nseg) noexcept | |
346 | 282 | : data_(s.data()) | |
347 | 141 | , size_(s.size()) | |
348 | 141 | , nseg_(nseg) | |
349 | 141 | , dn_(dn) | |
350 | { | ||
351 | 141 | } | |
352 | |||
353 | pct_string_view | ||
354 | 4517 | path_ref:: | |
355 | buffer() const noexcept | ||
356 | { | ||
357 |
2/2✓ Branch 0 taken 2333 times.
✓ Branch 1 taken 2184 times.
|
4517 | if(impl_) |
358 | 2333 | return make_pct_string_view_unsafe( | |
359 | 2333 | impl_->cs_ + | |
360 | 2333 | impl_->offset(id_path), | |
361 | 2333 | impl_->len(id_path), | |
362 | 4666 | impl_->decoded_[id_path]); | |
363 | 2184 | return make_pct_string_view_unsafe( | |
364 | 2184 | data_, size_, dn_); | |
365 | } | ||
366 | |||
367 | std::size_t | ||
368 | 3927 | path_ref:: | |
369 | size() const noexcept | ||
370 | { | ||
371 |
2/2✓ Branch 0 taken 2665 times.
✓ Branch 1 taken 1262 times.
|
3927 | if(impl_) |
372 | 2665 | return impl_->len(id_path); | |
373 | 1262 | return size_; | |
374 | } | ||
375 | |||
376 | char const* | ||
377 | 12658 | path_ref:: | |
378 | data() const noexcept | ||
379 | { | ||
380 |
2/2✓ Branch 0 taken 7463 times.
✓ Branch 1 taken 5195 times.
|
12658 | if(impl_) |
381 | 7463 | return impl_->cs_ + | |
382 | 7463 | impl_->offset(id_path); | |
383 | 5195 | return data_; | |
384 | } | ||
385 | |||
386 | char const* | ||
387 | 4421 | path_ref:: | |
388 | end() const noexcept | ||
389 | { | ||
390 |
2/2✓ Branch 0 taken 2951 times.
✓ Branch 1 taken 1470 times.
|
4421 | if(impl_) |
391 | 2951 | return impl_->cs_ + | |
392 | 2951 | impl_->offset(id_query); | |
393 | 1470 | return data_ + size_; | |
394 | } | ||
395 | |||
396 | std::size_t | ||
397 | 8654 | path_ref:: | |
398 | nseg() const noexcept | ||
399 | { | ||
400 |
2/2✓ Branch 0 taken 5514 times.
✓ Branch 1 taken 3140 times.
|
8654 | if(impl_) |
401 | 5514 | return impl_->nseg_; | |
402 | 3140 | return nseg_; | |
403 | } | ||
404 | |||
405 | //------------------------------------------------ | ||
406 | // | ||
407 | // query_ref | ||
408 | // | ||
409 | //------------------------------------------------ | ||
410 | |||
411 | 674 | query_ref:: | |
412 | query_ref( | ||
413 | core::string_view s, | ||
414 | std::size_t dn, | ||
415 | 674 | std::size_t nparam) noexcept | |
416 | 1348 | : data_(s.data()) | |
417 | 674 | , size_(s.size()) | |
418 | 674 | , nparam_(nparam) | |
419 | 674 | , dn_(dn) | |
420 | { | ||
421 | 674 | } | |
422 | |||
423 | 425 | query_ref:: | |
424 | query_ref( | ||
425 | 425 | url_impl const& impl) noexcept | |
426 | { | ||
427 |
2/2✓ Branch 0 taken 344 times.
✓ Branch 1 taken 81 times.
|
425 | if(impl.from_ == url_impl::from::url) |
428 | { | ||
429 | 344 | impl_ = &impl; | |
430 | } | ||
431 | else | ||
432 | { | ||
433 | 81 | core::string_view s = impl.get(id_query); | |
434 |
2/2✓ Branch 1 taken 79 times.
✓ Branch 2 taken 2 times.
|
81 | if (!s.empty()) |
435 | { | ||
436 | 79 | s.remove_prefix(1); | |
437 | 79 | question_mark_ = true; | |
438 | } | ||
439 | 81 | data_ = s.data(); | |
440 | 81 | size_ = s.size(); | |
441 | 81 | nparam_ = impl.nparam_; | |
442 | 81 | dn_ = impl.decoded_[id_query]; | |
443 | } | ||
444 | 425 | } | |
445 | |||
446 | pct_string_view | ||
447 | 454 | query_ref:: | |
448 | buffer() const noexcept | ||
449 | { | ||
450 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 452 times.
|
454 | if(impl_) |
451 | { | ||
452 | 2 | auto pos = impl_->offset_[id_query]; | |
453 | 2 | auto pos1 = impl_->offset_[id_frag]; | |
454 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if(pos < pos1) |
455 | { | ||
456 | ✗ | ++pos; // no '?' | |
457 | ✗ | return make_pct_string_view_unsafe( | |
458 | ✗ | impl_->cs_ + pos, | |
459 | pos1 - pos, | ||
460 | ✗ | impl_->decoded_[id_query]); | |
461 | } | ||
462 | // empty | ||
463 | 2 | return make_pct_string_view_unsafe( | |
464 | 2 | impl_->cs_ + pos, | |
465 | 0, | ||
466 | 2 | 0); | |
467 | } | ||
468 | // no '?' | ||
469 | 452 | return make_pct_string_view_unsafe( | |
470 | 452 | data_, size_, dn_); | |
471 | } | ||
472 | |||
473 | // with '?' | ||
474 | std::size_t | ||
475 | 5282 | query_ref:: | |
476 | size() const noexcept | ||
477 | { | ||
478 |
2/2✓ Branch 0 taken 1990 times.
✓ Branch 1 taken 3292 times.
|
5282 | if(impl_) |
479 | 1990 | return impl_->len(id_query); | |
480 |
2/2✓ Branch 0 taken 3264 times.
✓ Branch 1 taken 28 times.
|
3292 | if(size_ > 0) |
481 | 3264 | return size_ + 1; | |
482 | 28 | return question_mark_; | |
483 | } | ||
484 | |||
485 | // no '?' | ||
486 | char const* | ||
487 | 5807 | query_ref:: | |
488 | begin() const noexcept | ||
489 | { | ||
490 |
2/2✓ Branch 0 taken 2267 times.
✓ Branch 1 taken 3540 times.
|
5807 | if(impl_) |
491 | { | ||
492 | // using the offset array here | ||
493 | 2267 | auto pos = impl_->offset_[id_query]; | |
494 | 2267 | auto pos1 = impl_->offset_[id_frag]; | |
495 |
1/2✓ Branch 0 taken 2267 times.
✗ Branch 1 not taken.
|
2267 | if(pos < pos1) |
496 | 2267 | return impl_->cs_ + pos + 1; // no '?' | |
497 | // empty | ||
498 | ✗ | return impl_->cs_ + pos; | |
499 | } | ||
500 | 3540 | return data_; | |
501 | |||
502 | } | ||
503 | |||
504 | char const* | ||
505 | 2282 | query_ref:: | |
506 | end() const noexcept | ||
507 | { | ||
508 |
2/2✓ Branch 0 taken 902 times.
✓ Branch 1 taken 1380 times.
|
2282 | if(impl_) |
509 | 902 | return impl_->cs_ + | |
510 | 902 | impl_->offset(id_frag); | |
511 | 1380 | return data_ + size_; | |
512 | } | ||
513 | |||
514 | std::size_t | ||
515 | 8886 | query_ref:: | |
516 | nparam() const noexcept | ||
517 | { | ||
518 |
2/2✓ Branch 0 taken 3134 times.
✓ Branch 1 taken 5752 times.
|
8886 | if(impl_) |
519 | 3134 | return impl_->nparam_; | |
520 | 5752 | return nparam_; | |
521 | } | ||
522 | |||
523 | #if defined(__GNUC__) && ! defined(__clang__) && defined(__MINGW32__) | ||
524 | #pragma GCC diagnostic pop | ||
525 | #endif | ||
526 | |||
527 | } // detail | ||
528 | } // urls | ||
529 | } // boost | ||
530 | |||
531 |