Repository: bitcoin/bitcoin
File: src/wallet/bdb.cpp (C++)

Code before:
        assert(m_refcount == 0);

        Db db(env->dbenv.get(), 0);
        const std::string strFile = fs::PathToString(m_filename);
        int result = db.verify(strFile.c_str(), nullptr, nullptr, 0);
        if (result != 0) {
            errorStr = strprintf(_("%s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup."), fs::quoted(fs::PathToString(file_path)));
            return false;
        }
    }
    // also return true if files does not exists
    return true;
}

std::vector<fs::path> BerkeleyDatabase::Files()
{
    std::vector<fs::path> files;
    // If the wallet is the *only* file, clean up the entire BDB environment
    constexpr auto build_files_list = [](std::vector<fs::path>& files, const std::shared_ptr<BerkeleyEnvironment>& env, const fs::path& filename) {
        if (env->m_databases.size() != 1) return false;

        const auto env_dir = env->Directory();
        const auto db_subdir = env_dir / "database";
        if (fs::exists(db_subdir)) {
            if (!fs::is_directory(db_subdir)) return false;
            for (const auto& entry : fs::directory_iterator(env_dir / "database")) {
                const auto& path = entry.path().lexically_proximate(db_subdir);
                if (!fs::PathToString(path).starts_with("log.")) {
                    return false;
                }
                files.emplace_back(entry.path());
            }
        }
        const std::set<fs::path> allowed_paths = {
            filename,
            "db.log",
            ".walletlock",
            "database"
        };
        for (const auto& entry : fs::directory_iterator(env_dir)) {
            const auto& path = entry.path().lexically_proximate(env_dir);
            if (allowed_paths.contains(path)) {
                files.emplace_back(entry.path());
            } else if (fs::is_directory(entry.path())) {
                // Subdirectories can't possibly be using this db env, and is expected if this is a non-directory wallet
                // Do not include them in Files, but still allow the env cleanup
            } else {
                return false;
            }
        }
        return true;

Review comment (suggestion):
In 6a3926aea371bf9217031ccbf79032ccba7f3cf8 "Wallet/bdb: Safely and correctly list files only used by the single wallet"

```suggestion
            for (const auto& entry : fs::directory_iterator(db_subdir)) {
```

Code after:
        assert(m_refcount == 0);

        Db db(env->dbenv.get(), 0);
        const std::string strFile = fs::PathToString(m_filename);
        int result = db.verify(strFile.c_str(), nullptr, nullptr, 0);
        if (result != 0) {
            errorStr = strprintf(_("%s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup."), fs::quoted(fs::PathToString(file_path)));
            return false;
        }
    }
    // also return true if files does not exists
    return true;
}

std::vector<fs::path> BerkeleyDatabase::Files()
{
    std::vector<fs::path> files;
    // If the wallet is the *only* file, clean up the entire BDB environment
    constexpr auto build_files_list = [](std::vector<fs::path>& files, const std::shared_ptr<BerkeleyEnvironment>& env, const fs::path& filename) {
        if (env->m_databases.size() != 1) return false;

        const auto env_dir = env->Directory();
        const auto db_subdir = env_dir / "database";
        if (fs::exists(db_subdir)) {
            if (!fs::is_directory(db_subdir)) return false;
            for (const auto& entry : fs::directory_iterator(db_subdir)) {
                const auto& path = entry.path().filename();
                if (!fs::PathToString(path).starts_with("log.")) {
                    return false;
                }
                files.emplace_back(entry.path());
            }
        }
        const std::set<fs::path> allowed_paths = {
            filename,
            "db.log",
            ".walletlock",
            "database"
        };
        for (const auto& entry : fs::directory_iterator(env_dir)) {
            const auto& path = entry.path().filename();
            if (allowed_paths.contains(path)) {
                files.emplace_back(entry.path());
            } else if (fs::is_directory(entry.path())) {
                // Subdirectories can't possibly be using this db env, and is expected if this is a non-directory wallet
                // Do not include them in Files, but still allow the env cleanup
            } else {
                return false;
            }
        }
        return true;