Repository: bitcoin/bitcoin
File: src/rpc/request.cpp (C++)

Code before:
        }
    }

    g_generated_cookie = true;
    LogInfo("Generated RPC authentication cookie %s\n", fs::PathToString(filepath));
    LogInfo("Permissions used for cookie: %s\n", PermsToSymbolicString(fs::status(filepath).permissions()));

    if (cookie_out)
        *cookie_out = cookie;
    return true;
}

bool GetAuthCookie(std::string *cookie_out)
{
    std::ifstream file;
    std::string cookie;
    fs::path filepath = GetAuthCookieFile();
    file.open(filepath);
    if (!file.is_open())
        return false;
    std::getline(file, cookie);
    file.close();

    if (cookie_out)
        *cookie_out = cookie;
    return true;
}

void DeleteAuthCookie()
{
    try {
        if (g_generated_cookie) {
            // Delete the cookie file if it was generated by this process
            fs::remove(GetAuthCookieFile());
        }
    } catch (const fs::filesystem_error& e) {
        LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
    }
}

std::vector<UniValue> JSONRPCProcessBatchReply(const UniValue& in)
{
    if (!in.isArray()) {
        throw std::runtime_error("Batch must be an array");
    }
    const size_t num {in.size()};
    std::vector<UniValue> batch(num);
    for (const UniValue& rec : in.getValues()) {
        if (!rec.isObject()) {
            throw std::runtime_error("Batch member must be an object");
        }

Review comment (suggestion):
Do I understand correctly that we're basically treating an empty path as an `std::nullopt` here (and commenting it everywhere since we admit it's hard to understand)?
I understand that we can't fix everything in the same PR, but would like us to consider if it still makes sense to build on previous hacks.

Code after:
    if (cookie_perms) {
        std::error_code code;
        fs::permissions(filepath, cookie_perms.value(), fs::perm_options::replace, code);
        if (code) {
            LogWarning("Unable to set permissions on cookie authentication file %s", fs::PathToString(filepath));
            return false;
        }
    }

    g_generated_cookie = true;
    LogInfo("Generated RPC authentication cookie %s\n", fs::PathToString(filepath));
    LogInfo("Permissions used for cookie: %s\n", PermsToSymbolicString(fs::status(filepath).permissions()));

    if (cookie_out)
        *cookie_out = cookie;
    return true;
}

bool GetAuthCookie(std::string *cookie_out)
{
    std::ifstream file;
    std::string cookie;
    fs::path filepath = GetAuthCookieFile();
    if (filepath.empty()) {
        return true; // -norpccookiefile
    }
    file.open(filepath);
    if (!file.is_open())
        return false;
    std::getline(file, cookie);
    file.close();

    if (cookie_out)
        *cookie_out = cookie;
    return true;
}

void DeleteAuthCookie()
{
    try {
        if (g_generated_cookie) {
            // Delete the cookie file if it was generated by this process
            fs::remove(GetAuthCookieFile());
        }
    } catch (const fs::filesystem_error& e) {
        LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
    }
}

std::vector<UniValue> JSONRPCProcessBatchReply(const UniValue& in)
{