LCOV - code coverage report
Current view: top level - src/ipc - listen.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 100.0 % 32 32
Test Date: 2026-10-11 07:59:32 Functions: 100.0 % 2 2
Branches: 69.6 % 56 39

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2026-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                 :             : #include <interfaces/ipc.h>
       7                 :             : #include <util/strencodings.h>
       8                 :             : #include <util/string.h>
       9                 :             : #include <util/translation.h>
      10                 :             : 
      11                 :             : #include <cstdint>
      12                 :             : #include <string>
      13                 :             : #include <string_view>
      14                 :             : #include <utility>
      15                 :             : 
      16                 :             : namespace {
      17                 :          17 : util::Result<int64_t> ParseIntOption(std::string_view name, std::string_view value, int64_t min_val, int64_t max_val)
      18                 :             : {
      19   [ +  +  +  - ]:          21 :     if (value.empty()) return util::Error{Untranslated(strprintf("Missing value for %s option", name))};
      20                 :          15 :     const auto parsed{ToIntegral<int64_t>(value)};
      21   [ +  +  +  - ]:          17 :     if (!parsed) return util::Error{Untranslated(strprintf("Invalid %s value '%s'", name, value))};
      22   [ +  +  +  - ]:          20 :     if (*parsed < min_val) return util::Error{Untranslated(strprintf("%s must be at least %d", name, min_val))};
      23   [ +  +  +  - ]:          13 :     if (*parsed > max_val) return util::Error{Untranslated(strprintf("%s must be at most %d", name, max_val))};
      24                 :          10 :     return *parsed;
      25                 :             : }
      26                 :             : } // namespace
      27                 :             : 
      28                 :             : namespace interfaces {
      29                 :          21 : util::Result<ipc::ListenAddress> Ipc::parseListenAddress(std::string address)
      30                 :             : {
      31                 :          21 :     constexpr std::string_view UNIX_PREFIX{"unix:"};
      32                 :             : 
      33                 :             :     // Only Unix socket -ipcbind values support inline socket options. Leave
      34                 :             :     // other address families untouched so ipc::Process can report address
      35                 :             :     // scheme errors consistently with -ipcconnect.
      36   [ -  +  +  + ]:          21 :     if (!address.starts_with(UNIX_PREFIX)) {
      37                 :           1 :         return ipc::ListenAddress{.address = std::move(address)};
      38                 :             :     }
      39                 :             : 
      40                 :             :     // Socket options follow the first comma:
      41                 :             :     //   unix:,max-connections=8
      42                 :             :     //   unix:/custom/path,max-connections=8
      43                 :             :     // Commas in socket paths must be URL-encoded as %2C.
      44                 :             :     //
      45                 :             :     // Subsequent commas separate individual options.
      46                 :          20 :     const size_t option_pos{address.find(',')};
      47         [ +  + ]:          20 :     if (option_pos == std::string::npos) {
      48         [ -  + ]:           2 :         return ipc::ListenAddress{.address = UrlDecode(address)};
      49                 :             :     }
      50                 :             : 
      51         [ -  + ]:          18 :     const std::string_view address_view{address};
      52                 :             : 
      53                 :          18 :     ipc::ListenAddress listen_address{
      54                 :             :         .address = UrlDecode(address_view.substr(0, option_pos)),
      55                 :          18 :     };
      56                 :             : 
      57   [ +  -  +  + ]:          46 :     for (const std::string& option_str : util::SplitString(address_view.substr(option_pos + 1), ',')) {
      58         [ +  + ]:          22 :         if (option_str.empty()) {
      59   [ +  -  +  - ]:           9 :             return util::Error{Untranslated("Empty socket option")};
      60                 :             :         }
      61                 :          19 :         const size_t eq{option_str.find('=')};
      62   [ -  +  +  - ]:          19 :         const std::string_view name{std::string_view{option_str}.substr(0, eq)};
      63   [ +  +  +  - ]:          37 :         const std::string_view value{eq == std::string::npos ? std::string_view{} : std::string_view{option_str}.substr(eq + 1)};
      64         [ +  + ]:          19 :         if (name == "max-connections") {
      65         [ +  - ]:          17 :             auto parsed{ParseIntOption(name, value, 1, static_cast<int64_t>(ipc::MAX_CONNECTIONS))};
      66   [ +  +  +  - ]:          31 :             if (!parsed) return util::Error{util::ErrorString(parsed)};
      67                 :          10 :             listen_address.max_connections = static_cast<size_t>(*parsed);
      68                 :          17 :         } else {
      69   [ +  -  +  - ]:           6 :             return util::Error{Untranslated(strprintf("Unknown socket option '%s'", name))};
      70                 :             :         }
      71                 :          18 :     }
      72                 :             : 
      73                 :           6 :     return listen_address;
      74                 :          18 : }
      75                 :             : } // namespace interfaces
        

Generated by: LCOV version 2.0-1