LCOV - code coverage report
Current view: top level - /jenkins/workspace/boost-root/libs/url/src/detail - decode.cpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 46 46
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 7 7

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2019 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 <boost/url/detail/decode.hpp>
      13                 : #include <boost/url/grammar/charset.hpp>
      14                 : #include <boost/url/grammar/hexdig_chars.hpp>
      15                 : #include <memory>
      16                 : 
      17                 : namespace boost {
      18                 : namespace urls {
      19                 : namespace detail {
      20                 : 
      21                 : char
      22 HIT         908 : decode_one(
      23                 :     char const* const it) noexcept
      24                 : {
      25             908 :     auto d0 = grammar::hexdig_value(it[0]);
      26             908 :     auto d1 = grammar::hexdig_value(it[1]);
      27                 :     return static_cast<char>(
      28             908 :         ((static_cast<
      29             908 :             unsigned char>(d0) << 4) +
      30             908 :         (static_cast<
      31             908 :             unsigned char>(d1))));
      32                 : }
      33                 : 
      34                 : std::size_t
      35            2227 : decode_bytes_unsafe(
      36                 :     core::string_view s) noexcept
      37                 : {
      38            2227 :     auto p = s.begin();
      39            2227 :     auto const end = s.end();
      40            2227 :     std::size_t dn = 0;
      41            2227 :     if(s.size() >= 3)
      42                 :     {
      43            1034 :         auto const safe_end = end - 2;
      44            8428 :         while(p < safe_end)
      45                 :         {
      46            7394 :             if(*p != '%')
      47            7126 :                 p += 1;
      48                 :             else
      49             268 :                 p += 3;
      50            7394 :             ++dn;
      51                 :         }
      52                 :     }
      53            2227 :     dn += end - p;
      54            2227 :     return dn;
      55                 : }
      56                 : 
      57                 : template <bool SpaceAsPlus>
      58                 : std::size_t
      59                 : decode_unsafe_is_plus_impl(char c);
      60                 : 
      61                 : template <>
      62                 : std::size_t
      63            7990 : decode_unsafe_is_plus_impl<true>(char c)
      64                 : {
      65            7990 :     return c == '+';
      66                 : }
      67                 : 
      68                 : template <>
      69                 : std::size_t
      70            9042 : decode_unsafe_is_plus_impl<false>(char)
      71                 : {
      72            9042 :     return false;
      73                 : }
      74                 : 
      75                 : 
      76                 : template <bool SpaceAsPlus>
      77                 : std::size_t
      78            3035 : decode_unsafe_impl(
      79                 :     char* const dest0,
      80                 :     char const* end,
      81                 :     core::string_view s) noexcept
      82                 : {
      83            3035 :     auto it = s.data();
      84            3035 :     auto const last = it + s.size();
      85            3035 :     auto dest = dest0;
      86                 : 
      87           20067 :     while(it != last)
      88                 :     {
      89                 :         // LCOV_EXCL_START
      90                 :         if(dest == end)
      91                 :         {
      92                 :             /*
      93                 :              * dest too small: unreachable
      94                 :              * public functions always pass
      95                 :              * a buffer of sufficient size
      96                 :              */
      97                 :             return dest - dest0;
      98                 :         }
      99                 :         // LCOV_EXCL_STOP
     100           17032 :         if(decode_unsafe_is_plus_impl<SpaceAsPlus>(*it))
     101                 :         {
     102                 :             // plus to space
     103              46 :             *dest++ = ' ';
     104              46 :             ++it;
     105              46 :             continue;
     106                 :         }
     107           16986 :         if(*it == '%')
     108                 :         {
     109                 :             // escaped
     110             779 :             ++it;
     111                 :             // LCOV_EXCL_START
     112                 :             if(last - it < 2)
     113                 :             {
     114                 :                 // `%` not followed by two hex digits
     115                 :                 // invalid input: unreachable
     116                 :                 // public functions always pass
     117                 :                 // a valid string_view.
     118                 :                 // initialize output
     119                 :                 std::memset(dest,
     120                 :                     0, end - dest);
     121                 :                 return dest - dest0;
     122                 :             }
     123                 :             // LCOV_EXCL_STOP
     124             779 :             *dest++ = decode_one(it);
     125             779 :             it += 2;
     126             779 :             continue;
     127                 :         }
     128                 :         // unescaped
     129           16207 :         *dest++ = *it++;
     130                 :     }
     131            3034 :     return dest - dest0;
     132                 : }
     133                 : 
     134                 : std::size_t
     135            3035 : decode_unsafe(
     136                 :     char* const dest0,
     137                 :     char const* end,
     138                 :     core::string_view s,
     139                 :     encoding_opts opt) noexcept
     140                 : {
     141            3035 :     if(opt.space_as_plus)
     142                 :     {
     143            1340 :         return decode_unsafe_impl<true>(
     144            1340 :             dest0, end, s);
     145                 :     }
     146            1695 :     return decode_unsafe_impl<false>(
     147            1695 :         dest0, end, s);
     148                 : }
     149                 : 
     150                 : } // detail
     151                 : } // urls
     152                 : } // boost
        

Generated by: LCOV version 2.3