MCPcopy Create free account
hub / github.com/ada-url/ada / parse_url_impl

Function parse_url_impl

src/parser.cpp:14–927  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

12
13template <class result_type, bool store_values>
14result_type parse_url_impl(std::string_view user_input,
15 const result_type* base_url) {
16 // We can specialize the implementation per type.
17 // Important: result_type_is_ada_url is evaluated at *compile time*. This
18 // means that doing if constexpr(result_type_is_ada_url) { something } else {
19 // something else } is free (at runtime). This means that ada::url_aggregator
20 // and ada::url **do not have to support the exact same API**.
21 constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>;
22 constexpr bool result_type_is_ada_url_aggregator =
23 std::is_same_v<url_aggregator, result_type>;
24 static_assert(result_type_is_ada_url ||
25 result_type_is_ada_url_aggregator); // We don't support
26 // anything else for now.
27
28 ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
29 " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
30 ")");
31
32 state state = state::SCHEME_START;
33 result_type url{};
34
35 // We refuse to parse URL strings that exceed 4GB. Such strings are almost
36 // surely the result of a bug or are otherwise a security concern.
37 if (user_input.size() > std::numeric_limits<uint32_t>::max()) [[unlikely]] {
38 url.is_valid = false;
39 }
40 // Going forward, user_input.size() is in [0,
41 // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
42 // base, or the optional_url was invalid, we must return.
43 if (base_url != nullptr) {
44 url.is_valid &= base_url->is_valid;
45 }
46 if (!url.is_valid) {
47 return url;
48 }
49 if constexpr (result_type_is_ada_url_aggregator && store_values) {
50 // Most of the time, we just need user_input.size().
51 // In some instances, we may need a bit more.
52 ///////////////////////////
53 // This is *very* important. This line should *not* be removed
54 // hastily. There are principled reasons why reserve is important
55 // for performance. If you have a benchmark with small inputs,
56 // it may not matter, but in other instances, it could.
57 ////
58 // This rounds up to the next power of two.
59 // We know that user_input.size() is in [0,
60 // std::numeric_limits<uint32_t>::max).
61 uint32_t reserve_capacity =
62 (0xFFFFFFFF >>
63 helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
64 1;
65 url.reserve(reserve_capacity);
66 }
67 std::string tmp_buffer;
68 std::string_view url_data;
69 if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] {
70 tmp_buffer = user_input;
71 // Optimization opportunity: Instead of copying and then pruning, we could

Callers

nothing calls this directly

Calls 15

leading_zeroesFunction · 0.85
has_tabs_or_newlineFunction · 0.85
trim_c0_whitespaceFunction · 0.85
to_stringFunction · 0.85
is_alphaFunction · 0.85
is_alnum_plusFunction · 0.85
find_authority_delimiterFunction · 0.85
percent_encodeFunction · 0.85
shorten_pathFunction · 0.85
parse_prepared_pathFunction · 0.85

Tested by

no test coverage detected