LCOV - code coverage report
Current view: top level - common - monero_c_common.cpp (source / functions) Hit Total Coverage
Test: monero-c coverage @ 3fdc3a1 Lines: 47 47 100.0 %
Date: 2026-10-18 16:42:22 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /**
       2             :  * Copyright (c) Libmonero
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  * of this software and associated documentation files (the "Software"), to deal
       6             :  * in the Software without restriction, including without limitation the rights
       7             :  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  * copies of the Software, and to permit persons to whom the Software is
       9             :  * furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in all
      12             :  * copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      20             :  * SOFTWARE.
      21             :  */
      22             : 
      23             : #include "monero_c_common.h"
      24             : #include "monero_c_tls.h"
      25             : 
      26             : #if !defined(_WIN32)
      27             : #include <dirent.h>
      28             : #include <openssl/x509.h>
      29             : #include <sys/stat.h>
      30             : #endif
      31             : 
      32             : // monero-project's own, from crypto/slow-hash.c: it frees the scratchpad of the calling thread
      33             : extern "C" void slow_hash_free_state(void);
      34             : 
      35             : namespace monero_c {
      36             : 
      37             : namespace {
      38             : 
      39             : thread_local std::string g_last_error;
      40             : 
      41             : struct slow_hash_state_owner {
      42          90 :   ~slow_hash_state_owner() { slow_hash_free_state(); }
      43             : };
      44             : 
      45             : } // namespace
      46             : 
      47       27596 : void free_slow_hash_state_at_thread_exit() noexcept {
      48       27596 :   thread_local slow_hash_state_owner owner;
      49             :   (void) owner;
      50       27596 : }
      51             : 
      52       17616 : void set_last_error(const char* msg) noexcept {
      53       17616 :   try { g_last_error = msg; } catch (...) { g_last_error.clear(); }
      54       17616 : }
      55             : 
      56        2806 : void set_null_error(const char* name) noexcept {
      57        2806 :   try { g_last_error = std::string(name) + " must not be null"; } catch (...) { g_last_error.clear(); }
      58        2806 : }
      59             : 
      60       38319 : const std::string& last_error() {
      61       38319 :   return g_last_error;
      62             : }
      63             : 
      64        6356 : void check_json_depth(const std::string& json) {
      65        6356 :   size_t depth = 0;
      66        6356 :   bool in_string = false;
      67    12553517 :   for (size_t i = 0; i < json.size(); i++) {
      68    12547244 :     char c = json[i];
      69    12547244 :     if (in_string) {
      70     7293122 :       if (c == '\\') i++;
      71     7292909 :       else if (c == '"') in_string = false;
      72     5254122 :     } else if (c == '"') {
      73      452313 :       in_string = true;
      74     4801809 :     } else if (c == '[' || c == '{') {
      75       29377 :       if (++depth > MAX_JSON_DEPTH) throw std::invalid_argument("JSON is nested deeper than " + std::to_string(MAX_JSON_DEPTH) + " levels");
      76     4772432 :     } else if ((c == ']' || c == '}') && depth > 0) {
      77       21117 :       depth--;
      78             :     }
      79             :   }
      80        6273 : }
      81             : 
      82             : } // namespace monero_c
      83             : 
      84             : #if !defined(_WIN32)
      85             : 
      86             : namespace {
      87             : 
      88          13 : bool is_file_with_content(const std::string& path) {
      89             :   struct stat info;
      90          13 :   return stat(path.c_str(), &info) == 0 && S_ISREG(info.st_mode) && info.st_size > 0;
      91             : }
      92             : 
      93             : // true if the directory has a certificate by its hashed name, such as 5ad8a5d6.0
      94          13 : bool has_hashed_certificates(const std::string& path) {
      95          13 :   DIR* dir = opendir(path.c_str());
      96          13 :   if (dir == nullptr) return false;
      97          13 :   bool found = false;
      98          39 :   while (struct dirent* entry = readdir(dir)) {
      99          39 :     if (monero_c::is_hashed_certificate_name(entry->d_name)) {
     100          13 :       found = true;
     101          13 :       break;
     102             :     }
     103          26 :   }
     104          13 :   closedir(dir);
     105          13 :   return found;
     106             : }
     107             : 
     108             : // runs when the library is loaded, before a connection makes a TLS context. See find_ca_paths() for why. Windows needs none, since
     109             : // epee reads the root store of the system there
     110          13 : __attribute__((unused)) const bool g_ca_paths_set = [] {
     111          13 :   monero_c::ca_paths paths = monero_c::find_ca_paths(getenv("SSL_CERT_FILE"), getenv("SSL_CERT_DIR"), X509_get_default_cert_file(), X509_get_default_cert_dir(),
     112          26 :                                                      is_file_with_content, has_hashed_certificates);
     113          13 :   if (!paths.file.empty()) setenv("SSL_CERT_FILE", paths.file.c_str(), 1);
     114          13 :   if (!paths.dir.empty()) setenv("SSL_CERT_DIR", paths.dir.c_str(), 1);
     115          13 :   return true;
     116          13 : }();
     117             : 
     118             : } // namespace
     119             : 
     120             : #endif

Generated by: LCOV version 1.16