_ZNK4crow7ci_hashclENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
   15|  1.02M|        {
   16|  1.02M|            std::size_t seed = 0;
   17|  1.02M|            std::locale locale;
   18|       |
   19|  1.02M|            for (auto c : key)
  ------------------
  |  Branch (19:25): [True: 10.3M, False: 1.02M]
  ------------------
   20|  10.3M|                hash_combine(seed, std::toupper(c, locale));
   21|       |
   22|  1.02M|            return seed;
   23|  1.02M|        }
_ZN4crow7ci_hash12hash_combineERmc:
   27|  10.3M|        {
   28|  10.3M|            std::hash<char> hasher;
   29|  10.3M|            seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
   30|  10.3M|        }
_ZNK4crow9ci_key_eqclENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_:
   37|  73.5M|        {
   38|  73.5M|            return utility::string_equals(l, r);
   39|  73.5M|        }

_ZN4crow11bad_requestC2EPKc:
   12|  7.30k|            : std::runtime_error(what_arg) {}

_ZN4crow7requestC2Ev:
   67|  5.80k|          method(HTTPMethod::Get)
   68|  5.80k|        {}
_ZN4crow7request10add_headerENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES7_:
   76|  5.80k|        {
   77|  5.80k|            sanitize_header_value(key);
   78|  5.80k|            sanitize_header_value(value);
   79|  5.80k|            headers.emplace(std::move(key), std::move(value));
   80|  5.80k|        }
_ZN4crow21sanitize_header_valueERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   26|  11.6k|    {
   27|  11.6k|        s.erase(std::remove_if(s.begin(), s.end(),
   28|  11.6k|                               [](char c) { return c == '\r' || c == '\n'; }),
   29|  11.6k|                s.end());
   30|  11.6k|    }
_ZZN4crow21sanitize_header_valueERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEENKUlcE_clEc:
   28|   252k|                               [](char c) { return c == '\r' || c == '\n'; }),
  ------------------
  |  Branch (28:52): [True: 0, False: 252k]
  |  Branch (28:65): [True: 0, False: 252k]
  ------------------
_ZN4crow16get_header_valueERKNSt3__118unordered_multimapINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES7_NS_7ci_hashENS_9ci_key_eqENS5_INS0_4pairIKS7_S7_EEEEEERSB_:
   34|  11.3k|    {
   35|  11.3k|        static const std::string EMPTY;
   36|  11.3k|        const auto it = headers.find(key);
   37|  11.3k|        if (it != headers.end()) {
  ------------------
  |  Branch (37:13): [True: 11.3k, False: 0]
  ------------------
   38|  11.3k|            return it->second;
   39|  11.3k|        }
   40|      0|        else {
   41|      0|            return EMPTY;
   42|      0|        }
   43|  11.3k|    }

_ZN4crow9multipart7messageC2ERKNS_7requestE:
  146|  5.70k|              returnable("multipart/form-data; boundary=CROW-BOUNDARY"),
  147|  5.70k|              headers(req.headers),
  148|  5.70k|              boundary(get_boundary(get_header_value("Content-Type")))
  149|  5.70k|            {
  150|  5.70k|                if (!boundary.empty())
  ------------------
  |  Branch (150:21): [True: 5.70k, False: 0]
  ------------------
  151|  5.70k|                {
  152|  5.70k|                    content_type = "multipart/form-data; boundary=" + boundary;
  153|  5.70k|                    parse_body(req.body);
  154|  5.70k|                }
  155|      0|                else
  156|      0|                {
  157|      0|                    throw bad_request("Empty boundary in multipart message");
  158|      0|                }
  159|  5.70k|            }
_ZNK4crow9multipart7message12get_boundaryERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  163|  5.70k|            {
  164|  5.70k|                constexpr char boundary_text[] = "boundary=";
  165|  5.70k|                size_t found = header.find(boundary_text);
  166|  5.70k|                if (found != std::string::npos)
  ------------------
  |  Branch (166:21): [True: 5.70k, False: 0]
  ------------------
  167|  5.70k|                {
  168|  5.70k|                    std::string to_return(header.substr(found + strlen(boundary_text)));
  169|  5.70k|                    if (to_return[0] == '\"')
  ------------------
  |  Branch (169:25): [True: 0, False: 5.70k]
  ------------------
  170|      0|                    {
  171|      0|                        to_return = to_return.substr(1, to_return.length() - 2);
  172|      0|                    }
  173|  5.70k|                    return to_return;
  174|  5.70k|                }
  175|      0|                return std::string();
  176|  5.70k|            }
_ZNK4crow9multipart7message16get_header_valueERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   83|  5.70k|            {
   84|  5.70k|                return crow::get_header_value(headers, key);
   85|  5.70k|            }
_ZN4crow9multipart7message10parse_bodyENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  179|  5.70k|            {
  180|  5.70k|                std::string delimiter = dd + boundary;
  181|       |
  182|       |                // TODO(EDev): Exit on error
  183|  32.3k|                while (body != (crlf))
  ------------------
  |  Branch (183:24): [True: 30.2k, False: 2.03k]
  ------------------
  184|  30.2k|                {
  185|  30.2k|                    size_t found = body.find(delimiter);
  186|  30.2k|                    if (found == std::string::npos)
  ------------------
  |  Branch (186:25): [True: 176, False: 30.1k]
  ------------------
  187|    176|                    {
  188|       |                        // did not find delimiter; probably an ill-formed body; throw to indicate the issue to user
  189|    176|                        throw bad_request("Unable to find delimiter in multipart message. Probably ill-formed body");
  190|    176|                    }
  191|  30.1k|                    std::string section = body.substr(0, found);
  192|       |
  193|       |                    // +2 is the CRLF.
  194|       |                    // We don't check it and delete it so that the same delimiter can be used for The last delimiter (--delimiter--CRLF).
  195|  30.1k|                    body.erase(0, found + delimiter.length() + 2);
  196|  30.1k|                    if (!section.empty()) {
  ------------------
  |  Branch (196:25): [True: 24.6k, False: 5.44k]
  ------------------
  197|  24.6k|                        part parsed_section(parse_section(section));
  198|  24.6k|                        const auto section_params_headers = get_header_object(
  199|  24.6k|                            parsed_section.headers, "Content-Disposition").params;
  200|  24.6k|                        const auto name_header = section_params_headers.find("name");
  201|  24.6k|                        if (name_header == section_params_headers.end()) {
  ------------------
  |  Branch (201:29): [True: 3.49k, False: 21.1k]
  ------------------
  202|  3.49k|                            throw bad_request("Unable to find header 'name' in multipart section. Probably ill-formed body.");
  203|  21.1k|                        } else {
  204|  21.1k|                            part_map.emplace(name_header->second, parsed_section);
  205|  21.1k|                            parts.push_back(std::move(parsed_section));
  206|  21.1k|                        }
  207|  24.6k|                    }
  208|  30.1k|                }
  209|  5.70k|            }
_ZN4crow9multipart7message13parse_sectionERNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  212|  24.6k|            {
  213|  24.6k|                struct part to_return;
  214|       |
  215|  24.6k|                size_t found = section.find(crlfcrlf);
  216|  24.6k|                if (found == std::string::npos)
  ------------------
  |  Branch (216:21): [True: 81, False: 24.5k]
  ------------------
  217|     81|                {
  218|     81|                    throw bad_request("Unable to find section headers in multipart message. Probably ill-formed body.");
  219|     81|                }
  220|  24.5k|                std::string head_line = section.substr(0, found + 2);
  221|  24.5k|                section.erase(0, found + 4);
  222|       |
  223|  24.5k|                parse_section_head(head_line, to_return);
  224|  24.5k|                to_return.body = section.substr(0, section.length() - 2);
  225|  24.5k|                return to_return;
  226|  24.6k|            }
_ZN4crow9multipart7message18parse_section_headERNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERNS0_4partE:
  229|  24.5k|            {
  230|   117k|                while (!lines.empty())
  ------------------
  |  Branch (230:24): [True: 93.0k, False: 24.5k]
  ------------------
  231|  93.0k|                {
  232|  93.0k|                    header to_add;
  233|       |
  234|  93.0k|                    const size_t found_crlf = lines.find(crlf);
  235|  93.0k|                    std::string line = lines.substr(0, found_crlf);
  236|  93.0k|                    std::string key;
  237|  93.0k|                    lines.erase(0, found_crlf + 2);
  238|       |                    // Add the header if available
  239|  93.0k|                    if (!line.empty())
  ------------------
  |  Branch (239:25): [True: 91.1k, False: 1.92k]
  ------------------
  240|  91.1k|                    {
  241|  91.1k|                        const size_t found_semicolon = line.find("; ");
  242|  91.1k|                        std::string header = line.substr(0, found_semicolon);
  243|  91.1k|                        if (found_semicolon != std::string::npos)
  ------------------
  |  Branch (243:29): [True: 29.9k, False: 61.2k]
  ------------------
  244|  29.9k|                            line.erase(0, found_semicolon + 2);
  245|  61.2k|                        else
  246|  61.2k|                            line = std::string();
  247|       |
  248|  91.1k|                        size_t header_split = header.find(": ");
  249|  91.1k|                        key = header.substr(0, header_split);
  250|       |
  251|  91.1k|                        to_add.value = header.substr(header_split + 2);
  252|  91.1k|                    }
  253|       |
  254|       |                    // Add the parameters
  255|   153k|                    while (!line.empty())
  ------------------
  |  Branch (255:28): [True: 60.2k, False: 93.0k]
  ------------------
  256|  60.2k|                    {
  257|  60.2k|                        const size_t found_semicolon = line.find("; ");
  258|  60.2k|                        std::string param = line.substr(0, found_semicolon);
  259|  60.2k|                        if (found_semicolon != std::string::npos)
  ------------------
  |  Branch (259:29): [True: 30.9k, False: 29.3k]
  ------------------
  260|  30.9k|                            line.erase(0, found_semicolon + 2);
  261|  29.3k|                        else
  262|  29.3k|                            line = std::string();
  263|       |
  264|  60.2k|                        size_t param_split = param.find('=');
  265|       |
  266|  60.2k|                        std::string value = param.substr(param_split + 1);
  267|       |
  268|  60.2k|                        to_add.params.emplace(param.substr(0, param_split), trim(value));
  269|  60.2k|                    }
  270|  93.0k|                    part.headers.emplace(key, to_add);
  271|  93.0k|                }
  272|  24.5k|            }
_ZNK4crow9multipart7message4trimERNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKc:
  275|  60.2k|            {
  276|  60.2k|                if (string.length() > 1 && string[0] == excess && string[string.length() - 1] == excess)
  ------------------
  |  Branch (276:21): [True: 39.0k, False: 21.2k]
  |  Branch (276:44): [True: 10.3k, False: 28.7k]
  |  Branch (276:67): [True: 7.48k, False: 2.86k]
  ------------------
  277|  7.48k|                    return string.substr(1, string.length() - 2);
  278|  52.8k|                return string;
  279|  60.2k|            }
_ZN4crow9multipart17get_header_objectINSt3__118unordered_multimapINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_6headerENS_7ci_hashENS_9ci_key_eqENS7_INS2_4pairIKS9_SA_EEEEEEEERKSA_RKT_RSE_:
   49|  24.5k|        {
   50|  24.5k|            return get_header_value_object<header>(headers, key);
   51|  24.5k|        }
_ZN4crow9multipart23get_header_value_objectINS0_6headerENSt3__118unordered_multimapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEES2_NS_7ci_hashENS_9ci_key_eqENS8_INS3_4pairIKSA_S2_EEEEEEEERKT_RKT0_RSE_:
   37|  24.5k|        {
   38|  24.5k|            if (headers.count(key))
  ------------------
  |  Branch (38:17): [True: 21.3k, False: 3.16k]
  ------------------
   39|  21.3k|            {
   40|  21.3k|                return headers.find(key)->second;
   41|  21.3k|            }
   42|  3.16k|            static O empty;
   43|  3.16k|            return empty;
   44|  24.5k|        }
_ZNK4crow9multipart7message4dumpEv:
   98|  1.91k|            {
   99|  1.91k|                std::stringstream str;
  100|  1.91k|                const std::string delimiter = dd + boundary;
  101|       |
  102|  12.8k|                for (unsigned i = 0; i < parts.size(); i++)
  ------------------
  |  Branch (102:38): [True: 10.8k, False: 1.91k]
  ------------------
  103|  10.8k|                {
  104|  10.8k|                    str << delimiter << crlf;
  105|  10.8k|                    str << dump(i);
  106|  10.8k|                }
  107|  1.91k|                str << delimiter << dd << crlf;
  108|  1.91k|                return str.str();
  109|  1.91k|            }
_ZNK4crow9multipart7message4dumpEi:
  113|  21.7k|            {
  114|  21.7k|                std::stringstream str;
  115|  21.7k|                part item = parts[part_];
  116|  21.7k|                for (auto& item_h : item.headers)
  ------------------
  |  Branch (116:35): [True: 70.1k, False: 21.7k]
  ------------------
  117|  70.1k|                {
  118|  70.1k|                    str << item_h.first << ": " << item_h.second.value;
  119|  70.1k|                    for (auto& it : item_h.second.params)
  ------------------
  |  Branch (119:35): [True: 42.4k, False: 70.1k]
  ------------------
  120|  42.4k|                    {
  121|  42.4k|                        str << "; " << it.first << '=' << pad(it.second);
  122|  42.4k|                    }
  123|  70.1k|                    str << crlf;
  124|  70.1k|                }
  125|  21.7k|                str << crlf;
  126|  21.7k|                str << item.body << crlf;
  127|  21.7k|                return str.str();
  128|  21.7k|            }
_ZNK4crow9multipart7message3padERNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKc:
  282|  42.4k|            {
  283|  42.4k|                return (padding + string + padding);
  284|  42.4k|            }
_ZN4crow9multipart7message16get_part_by_nameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   88|  10.8k|            {
   89|  10.8k|                mp_map::iterator result = part_map.find(name);
   90|  10.8k|                if (result != part_map.end())
  ------------------
  |  Branch (90:21): [True: 10.8k, False: 0]
  ------------------
   91|  10.8k|                    return result->second;
   92|      0|                else
   93|      0|                    return {};
   94|  10.8k|            }

_ZN4crow9multipart12message_viewC2ERKNS_7requestE:
  174|  5.67k|              headers(req.headers),
  175|  5.67k|              boundary(get_boundary(get_header_value("Content-Type")))
  176|  5.67k|            {
  177|  5.67k|                if (boundary.empty())
  ------------------
  |  Branch (177:21): [True: 0, False: 5.67k]
  ------------------
  178|      0|                    throw bad_request("Empty boundary in multipart message");
  179|  5.67k|                parse_body(req.body);
  180|  5.67k|            }
_ZN4crow9multipart12message_view12get_boundaryENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
  184|  5.67k|            {
  185|  5.67k|                constexpr std::string_view boundary_text = "boundary=";
  186|  5.67k|                const size_t found = header.find(boundary_text);
  187|  5.67k|                if (found == std::string_view::npos)
  ------------------
  |  Branch (187:21): [True: 0, False: 5.67k]
  ------------------
  188|      0|                {
  189|      0|                    return {};
  190|      0|                }
  191|       |
  192|  5.67k|                const std::string_view to_return = header.substr(found + boundary_text.size());
  193|  5.67k|                if (!to_return.empty() && to_return[0] == '\"')
  ------------------
  |  Branch (193:21): [True: 5.67k, False: 0]
  |  Branch (193:43): [True: 0, False: 5.67k]
  ------------------
  194|      0|                {
  195|      0|                    return to_return.substr(1, to_return.length() - 2);
  196|      0|                }
  197|  5.67k|                return to_return;
  198|  5.67k|            }
_ZNK4crow9multipart12message_view16get_header_valueERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  129|  5.67k|            {
  130|  5.67k|                return crow::get_header_value(headers.get(), key);
  131|  5.67k|            }
_ZN4crow9multipart12message_view10parse_bodyENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
  201|  5.67k|            {
  202|  5.67k|                const std::string delimiter = dd + boundary;
  203|       |
  204|       |                // TODO(EDev): Exit on error
  205|  32.4k|                while (body != (crlf))
  ------------------
  |  Branch (205:24): [True: 30.2k, False: 2.19k]
  ------------------
  206|  30.2k|                {
  207|  30.2k|                    const size_t found = body.find(delimiter);
  208|  30.2k|                    if (found == std::string_view::npos)
  ------------------
  |  Branch (208:25): [True: 154, False: 30.1k]
  ------------------
  209|    154|                    {
  210|       |                        // did not find delimiter; probably an ill-formed body; ignore the rest
  211|    154|                        throw bad_request("Unable to find multipart delimiter. Probably ill-formed body.");
  212|    154|                    }
  213|       |
  214|  30.1k|                    const std::string_view section = body.substr(0, found);
  215|       |
  216|       |                    // +2 is the CRLF.
  217|       |                    // We don't check it and delete it so that the same delimiter can be used for The last delimiter (--delimiter--CRLF).
  218|  30.1k|                    body = body.substr(found + delimiter.length() + 2);
  219|  30.1k|                    if (!section.empty())
  ------------------
  |  Branch (219:25): [True: 24.5k, False: 5.58k]
  ------------------
  220|  24.5k|                    {
  221|  24.5k|                        part_view parsed_section = parse_section(section);
  222|  24.5k|                        const auto& section_params = get_header_object(parsed_section.headers, "Content-Disposition").params;
  223|  24.5k|                        const auto name_header = section_params.find("name");
  224|  24.5k|                        if (name_header == section_params.end())
  ------------------
  |  Branch (224:29): [True: 3.32k, False: 21.2k]
  ------------------
  225|  3.32k|                        {
  226|  3.32k|                            throw bad_request("Unable to find header 'name' in multipart section. Probably ill-formed body.");
  227|  3.32k|                        }
  228|  21.2k|                        part_map.emplace(name_header->second, parsed_section);
  229|  21.2k|                        parts.push_back(std::move(parsed_section));
  230|  21.2k|                    }
  231|  30.1k|                }
  232|  5.67k|            }
_ZN4crow9multipart12message_view13parse_sectionENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
  235|  24.5k|            {
  236|  24.5k|                const size_t found = section.find(crlfcrlf);
  237|  24.5k|                if (found==std::string_view::npos)
  ------------------
  |  Branch (237:21): [True: 77, False: 24.4k]
  ------------------
  238|     77|                {
  239|     77|                    throw bad_request("Section Header end missing in multipart message");
  240|     77|                }
  241|  24.4k|                const std::string_view head_line = section.substr(0, found + 2);
  242|  24.4k|                section = section.substr(found + 4);
  243|       |
  244|  24.4k|                return part_view{
  245|  24.4k|                  parse_section_head(head_line),
  246|  24.4k|                  section.substr(0, section.length() - 2),
  247|  24.4k|                };
  248|  24.5k|            }
_ZN4crow9multipart12message_view18parse_section_headENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
  251|  24.4k|            {
  252|  24.4k|                mph_view_map result;
  253|       |
  254|   116k|                while (!lines.empty())
  ------------------
  |  Branch (254:24): [True: 92.0k, False: 24.4k]
  ------------------
  255|  92.0k|                {
  256|  92.0k|                    header_view to_add;
  257|       |
  258|  92.0k|                    const size_t found_crlf = lines.find(crlf);
  259|  92.0k|                    std::string_view line = lines.substr(0, found_crlf);
  260|  92.0k|                    std::string_view key;
  261|  92.0k|                    lines = lines.substr(found_crlf + 2);
  262|       |                    // Add the header if available
  263|  92.0k|                    if (!line.empty())
  ------------------
  |  Branch (263:25): [True: 90.1k, False: 1.89k]
  ------------------
  264|  90.1k|                    {
  265|  90.1k|                        const size_t found_semicolon = line.find("; ");
  266|  90.1k|                        std::string_view header = line.substr(0, found_semicolon);
  267|  90.1k|                        if (found_semicolon != std::string_view::npos)
  ------------------
  |  Branch (267:29): [True: 29.8k, False: 60.3k]
  ------------------
  268|  29.8k|                            line = line.substr(found_semicolon + 2);
  269|  60.3k|                        else
  270|  60.3k|                            line = std::string_view();
  271|       |
  272|  90.1k|                        const size_t header_split = header.find(": ");
  273|  90.1k|                        key = header.substr(0, header_split);
  274|       |
  275|  90.1k|                        to_add.value = header.substr(header_split + 2);
  276|  90.1k|                    }
  277|       |
  278|       |                    // Add the parameters
  279|   151k|                    while (!line.empty())
  ------------------
  |  Branch (279:28): [True: 59.0k, False: 92.0k]
  ------------------
  280|  59.0k|                    {
  281|  59.0k|                        const size_t found_semicolon = line.find("; ");
  282|  59.0k|                        std::string_view param = line.substr(0, found_semicolon);
  283|  59.0k|                        if (found_semicolon != std::string_view::npos)
  ------------------
  |  Branch (283:29): [True: 29.7k, False: 29.2k]
  ------------------
  284|  29.7k|                            line = line.substr(found_semicolon + 2);
  285|  29.2k|                        else
  286|  29.2k|                            line = std::string_view();
  287|       |
  288|  59.0k|                        const size_t param_split = param.find('=');
  289|       |
  290|  59.0k|                        const std::string_view value = param.substr(param_split + 1);
  291|       |
  292|  59.0k|                        to_add.params.emplace(param.substr(0, param_split), trim(value));
  293|  59.0k|                    }
  294|  92.0k|                    result.emplace(key, to_add);
  295|  92.0k|                }
  296|       |
  297|  24.4k|                return result;
  298|  24.4k|            }
_ZN4crow9multipart12message_view4trimENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEc:
  301|  59.0k|            {
  302|  59.0k|                if (string.length() > 1 && string[0] == excess && string[string.length() - 1] == excess)
  ------------------
  |  Branch (302:21): [True: 38.0k, False: 20.9k]
  |  Branch (302:44): [True: 9.96k, False: 28.1k]
  |  Branch (302:67): [True: 7.25k, False: 2.70k]
  ------------------
  303|  7.25k|                    return string.substr(1, string.length() - 2);
  304|  51.7k|                return string;
  305|  59.0k|            }
_ZN4crow9multipart17get_header_objectERKNSt3__118unordered_multimapINS1_17basic_string_viewIcNS1_11char_traitsIcEEEENS0_11header_viewENS_7ci_hashENS_9ci_key_eqENS1_9allocatorINS1_4pairIKS6_S7_EEEEEES6_:
   47|  24.4k|        {
   48|  24.4k|            const auto header = headers.find(key);
   49|  24.4k|            if (header != headers.cend())
  ------------------
  |  Branch (49:17): [True: 21.3k, False: 3.02k]
  ------------------
   50|  21.3k|            {
   51|  21.3k|                return header->second;
   52|  21.3k|            }
   53|       |
   54|  3.02k|            static header_view empty;
   55|  3.02k|            return empty;
   56|  24.4k|        }
_ZNK4crow9multipart12message_view4dumpEv:
  158|  1.91k|            {
  159|  1.91k|                std::ostringstream str;
  160|  1.91k|                str << *this;
  161|  1.91k|                return std::move(str).str();
  162|  1.91k|            }
_ZN4crow9multipartlsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_12message_viewE:
  143|  1.91k|            {
  144|  1.91k|                std::string delimiter = dd + message.boundary;
  145|       |
  146|  1.91k|                for (const part_view& part : message.parts)
  ------------------
  |  Branch (146:44): [True: 10.8k, False: 1.91k]
  ------------------
  147|  10.8k|                {
  148|  10.8k|                    stream << delimiter << crlf;
  149|  10.8k|                    stream << part;
  150|  10.8k|                }
  151|  1.91k|                stream << delimiter << dd << crlf;
  152|       |
  153|  1.91k|                return stream;
  154|  1.91k|            }
_ZN4crow9multipartlsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_9part_viewE:
  101|  21.7k|            {
  102|  21.7k|                for (const auto& [header_key, header_value] : part.headers)
  ------------------
  |  Branch (102:61): [True: 70.0k, False: 21.7k]
  ------------------
  103|  70.0k|                {
  104|  70.0k|                    stream << header_key << ": " << header_value.value;
  105|  70.0k|                    for (const auto& [param_key, param_value] : header_value.params)
  ------------------
  |  Branch (105:63): [True: 42.0k, False: 70.0k]
  ------------------
  106|  42.0k|                    {
  107|  42.0k|                        stream << "; " << param_key << '=' << padded{param_value};
  108|  42.0k|                    }
  109|  70.0k|                    stream << crlf;
  110|  70.0k|                }
  111|  21.7k|                stream << crlf;
  112|  21.7k|                stream << part.body << crlf;
  113|  21.7k|                return stream;
  114|  21.7k|            }
_ZN4crow9multipartlsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEENS0_6paddedE:
   66|  42.0k|            {
   67|  42.0k|                return stream << padding << value_.value << padding;
   68|  42.0k|            }
_ZNK4crow9multipart12message_view4dumpEi:
  166|  10.8k|            {
  167|  10.8k|                std::ostringstream str;
  168|  10.8k|                str << parts.at(part_);
  169|  10.8k|                return std::move(str).str();
  170|  10.8k|            }

_ZN4crow12query_stringC2Ev:
  339|  5.80k|        query_string() = default;

_ZN4crow10returnableC2ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   14|  5.70k|          content_type{ctype}
   15|  5.70k|        {}
_ZN4crow10returnableD2Ev:
   17|  5.70k|        virtual ~returnable(){}

multipart_fuzzer.cpp:_ZN4crow7utilityL13string_equalsENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_b:
  812|  73.5M|        {
  813|  73.5M|            if (l.length() != r.length())
  ------------------
  |  Branch (813:17): [True: 13.5k, False: 73.5M]
  ------------------
  814|  13.5k|                return false;
  815|       |
  816|   158M|            for (size_t i = 0; i < l.length(); i++)
  ------------------
  |  Branch (816:32): [True: 84.9M, False: 73.5M]
  ------------------
  817|  84.9M|            {
  818|  84.9M|                if (case_sensitive)
  ------------------
  |  Branch (818:21): [True: 0, False: 84.9M]
  ------------------
  819|      0|                {
  820|      0|                    if (l[i] != r[i])
  ------------------
  |  Branch (820:25): [True: 0, False: 0]
  ------------------
  821|      0|                        return false;
  822|      0|                }
  823|  84.9M|                else
  824|  84.9M|                {
  825|  84.9M|                    if (std::toupper(static_cast<unsigned char>(l[i])) != std::toupper(static_cast<unsigned char>(r[i])))
  ------------------
  |  Branch (825:25): [True: 10.8k, False: 84.8M]
  ------------------
  826|  10.8k|                        return false;
  827|  84.9M|                }
  828|  84.9M|            }
  829|       |
  830|  73.5M|            return true;
  831|  73.5M|        }

LLVMFuzzerTestOneInput:
   38|  5.80k|{
   39|  5.80k|    FuzzedDataProvider fdp{data, size};
   40|       |
   41|  5.80k|    const std::uint8_t mode = fdp.ConsumeIntegral<std::uint8_t>();
   42|  5.80k|    const std::string boundary = (mode & 1) ? "X" : "CROW-BOUNDARY";
  ------------------
  |  Branch (42:34): [True: 5.51k, False: 283]
  ------------------
   43|  5.80k|    std::string body = bounded(fdp.ConsumeRemainingBytesAsString());
   44|       |
   45|  5.80k|    if (mode & 2)
  ------------------
  |  Branch (45:9): [True: 5.21k, False: 587]
  ------------------
   46|  5.21k|    {
   47|       |        // Structurally valid multipart framing around the fuzzed payload.
   48|  5.21k|        body = "--" + boundary + "\r\n"
   49|  5.21k|               "Content-Disposition: form-data; name=\"field\"\r\n"
   50|  5.21k|               "\r\n" + body + "\r\n"
   51|  5.21k|               "--" + boundary + "--\r\n";
   52|  5.21k|    }
   53|       |
   54|  5.80k|    crow::request req;
   55|  5.80k|    req.body = body;
   56|  5.80k|    req.add_header("Content-Type", "multipart/form-data; boundary=" + boundary);
   57|       |
   58|  5.80k|    if (mode & 4)
  ------------------
  |  Branch (58:9): [True: 5.70k, False: 96]
  ------------------
   59|  5.70k|    {
   60|  5.70k|        try
   61|  5.70k|        {
   62|  5.70k|            crow::multipart::message msg(req);
   63|  5.70k|            (void)msg.dump();
   64|  16.5k|            for (std::size_t i = 0; i < msg.parts.size(); ++i)
  ------------------
  |  Branch (64:37): [True: 10.8k, False: 5.70k]
  ------------------
   65|  10.8k|            {
   66|  10.8k|                (void)msg.dump(static_cast<int>(i));
   67|  10.8k|                (void)msg.parts[i].body.size();
   68|  10.8k|            }
   69|  5.70k|            for (const auto& entry : msg.part_map)
  ------------------
  |  Branch (69:36): [True: 10.8k, False: 5.70k]
  ------------------
   70|  10.8k|                (void)msg.get_part_by_name(entry.first).body.size();
   71|  5.70k|        }
   72|  5.70k|        catch (const std::exception&)
   73|  5.70k|        {
   74|       |            // Ill-formed multipart body: documented parser error channel.
   75|  3.79k|        }
   76|  5.70k|    }
   77|       |
   78|  5.80k|    if (mode & 8)
  ------------------
  |  Branch (78:9): [True: 5.67k, False: 129]
  ------------------
   79|  5.67k|    {
   80|  5.67k|        try
   81|  5.67k|        {
   82|  5.67k|            crow::multipart::message_view view(req);
   83|  5.67k|            (void)view.dump();
   84|  16.5k|            for (std::size_t i = 0; i < view.parts.size(); ++i)
  ------------------
  |  Branch (84:37): [True: 10.8k, False: 5.67k]
  ------------------
   85|  10.8k|                (void)view.dump(static_cast<int>(i));
   86|  5.67k|        }
   87|  5.67k|        catch (const std::exception&)
   88|  5.67k|        {
   89|       |            // Ill-formed multipart body: documented parser error channel.
   90|  3.76k|        }
   91|  5.67k|    }
   92|       |
   93|  5.80k|    return 0;
   94|  5.80k|}
multipart_fuzzer.cpp:_ZN12_GLOBAL__N_17boundedENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   29|  5.80k|    {
   30|  5.80k|        constexpr std::size_t max_body = 8192;
   31|  5.80k|        if (s.size() > max_body)
  ------------------
  |  Branch (31:13): [True: 27, False: 5.77k]
  ------------------
   32|     27|            s.resize(max_body);
   33|  5.80k|        return s;
   34|  5.80k|    }

