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-05-23 06:52:35 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 <string>
       9                 :             : #include <string_view>
      10                 :             : #include <system_error>
      11                 :             : 
      12                 :          41 : std::string UrlDecode(std::string_view url_encoded)
      13                 :             : {
      14         [ +  - ]:          41 :     std::string res;
      15         [ +  - ]:          41 :     res.reserve(url_encoded.size());
      16                 :             : 
      17         [ +  + ]:         546 :     for (size_t i = 0; i < url_encoded.size(); ++i) {
      18         [ +  + ]:         505 :         char c = url_encoded[i];
      19                 :             :         // Special handling for percent which should be followed by two hex digits
      20                 :             :         // representing an octet values, see RFC 3986, Section 2.1 Percent-Encoding
      21   [ +  +  +  + ]:         505 :         if (c == '%' && i + 2 < url_encoded.size()) {
      22                 :         235 :             unsigned int decoded_value{0};
      23                 :         235 :             auto [p, ec] = std::from_chars(url_encoded.data() + i + 1, url_encoded.data() + i + 3, decoded_value, 16);
      24                 :             : 
      25                 :             :             // Only if there is no error and the pointer is set to the end of
      26                 :             :             // the string, we can be sure both characters were valid hex
      27   [ +  +  +  + ]:         235 :             if (ec == std::errc{} && p == url_encoded.data() + i + 3) {
      28         [ +  - ]:         216 :                 res += static_cast<char>(decoded_value);
      29                 :             :                 // Next two characters are part of the percent encoding
      30                 :         216 :                 i += 2;
      31                 :         216 :                 continue;
      32                 :             :             }
      33                 :             :             // In case of invalid percent encoding, add the '%' and continue
      34                 :             :         }
      35         [ +  - ]:         794 :         res += c;
      36                 :             :     }
      37                 :             : 
      38                 :          41 :     return res;
      39                 :           0 : }
      40                 :             : 
      41                 :           1 : std::string UrlEncode(std::string_view str)
      42                 :             : {
      43         [ +  - ]:           1 :     std::string res;
      44         [ +  - ]:           1 :     res.reserve(str.size() * 3); // worst case: every char needs encoding
      45                 :             : 
      46         [ +  + ]:         257 :     for (char ch : str) {
      47                 :         256 :         auto c = static_cast<unsigned char>(ch);
      48                 :             :         // Unreserved characters per RFC 3986, Section 2.3
      49         [ +  + ]:         256 :         if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
      50   [ +  +  +  +  :         204 :             (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~') {
                   +  + ]
      51         [ +  - ]:          66 :             res += ch;
      52                 :             :         } else {
      53                 :             :             // Percent-encode all other characters
      54         [ +  - ]:         190 :             res += '%';
      55                 :         190 :             constexpr char hex_chars[] = "0123456789ABCDEF";
      56         [ +  - ]:         190 :             res += hex_chars[(c >> 4) & 0xF];
      57         [ +  - ]:         446 :             res += hex_chars[c & 0xF];
      58                 :             :         }
      59                 :             :     }
      60                 :           1 :     return res;
      61                 :           0 : }
        

Generated by: LCOV version 2.0-1