LCOV - code coverage report
Current view: top level - src/common - url.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 93.1 % 29 27
Test Date: 2026-08-07 06:33:33 Functions: 100.0 % 2 2
Branches: 76.2 % 42 32

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2015-present The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #include <common/url.h>
       6                 :             : 
       7                 :             : #include <charconv>
       8                 :             : #include <cstddef>
       9                 :             : #include <string>
      10                 :             : #include <string_view>
      11                 :             : #include <system_error>
      12                 :             : 
      13                 :          66 : std::string UrlDecode(std::string_view url_encoded)
      14                 :             : {
      15         [ +  - ]:          66 :     std::string res;
      16         [ +  - ]:          66 :     res.reserve(url_encoded.size());
      17                 :             : 
      18         [ +  + ]:         633 :     for (size_t i = 0; i < url_encoded.size(); ++i) {
      19         [ +  + ]:         567 :         char c = url_encoded[i];
      20                 :             :         // Special handling for percent which should be followed by two hex digits
      21                 :             :         // representing an octet values, see RFC 3986, Section 2.1 Percent-Encoding
      22   [ +  +  +  + ]:         567 :         if (c == '%' && i + 2 < url_encoded.size()) {
      23                 :         240 :             unsigned int decoded_value{0};
      24                 :         240 :             auto [p, ec] = std::from_chars(url_encoded.data() + i + 1, url_encoded.data() + i + 3, decoded_value, 16);
      25                 :             : 
      26                 :             :             // Only if there is no error and the pointer is set to the end of
      27                 :             :             // the string, we can be sure both characters were valid hex
      28   [ +  +  +  + ]:         240 :             if (ec == std::errc{} && p == url_encoded.data() + i + 3) {
      29         [ +  - ]:         221 :                 res += static_cast<char>(decoded_value);
      30                 :             :                 // Next two characters are part of the percent encoding
      31                 :         221 :                 i += 2;
      32                 :         221 :                 continue;
      33                 :             :             }
      34                 :             :             // In case of invalid percent encoding, add the '%' and continue
      35                 :             :         }
      36         [ +  - ]:         913 :         res += c;
      37                 :             :     }
      38                 :             : 
      39                 :          66 :     return res;
      40                 :           0 : }
      41                 :             : 
      42                 :           1 : std::string UrlEncode(std::string_view str)
      43                 :             : {
      44         [ +  - ]:           1 :     std::string res;
      45         [ +  - ]:           1 :     res.reserve(str.size() * 3); // worst case: every char needs encoding
      46                 :             : 
      47         [ +  + ]:         257 :     for (char ch : str) {
      48                 :         256 :         auto c = static_cast<unsigned char>(ch);
      49                 :             :         // Unreserved characters per RFC 3986, Section 2.3
      50         [ +  + ]:         256 :         if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
      51   [ +  +  +  +  :         204 :             (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~') {
                   +  + ]
      52         [ +  - ]:          66 :             res += ch;
      53                 :             :         } else {
      54                 :             :             // Percent-encode all other characters
      55         [ +  - ]:         190 :             res += '%';
      56                 :         190 :             constexpr char hex_chars[] = "0123456789ABCDEF";
      57         [ +  - ]:         190 :             res += hex_chars[(c >> 4) & 0xF];
      58         [ +  - ]:         446 :             res += hex_chars[c & 0xF];
      59                 :             :         }
      60                 :             :     }
      61                 :           1 :     return res;
      62                 :           0 : }
        

Generated by: LCOV version 2.0-1