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

Code before:
    auto wallet_file = wallet_path / "wallet.dat";
    std::shared_ptr<CWallet> wallet;

    try {
        if (!fs::exists(backup_file)) {
            error = Untranslated("Backup file does not exist");
            status = DatabaseStatus::FAILED_INVALID_BACKUP_FILE;
            return nullptr;
        }

        // Wallet directories are allowed to exist, but must not contain a .dat file.
        // Any existing wallet database is treated as a hard failure to prevent overwriting.
        if (fs::exists(wallet_path)) {
            // If this is a file, it is the db and we don't want to overwrite it.
            if (!fs::is_directory(wallet_path)) {
                error = Untranslated(strprintf("Failed to restore wallet. Database file exists '%s'.", fs::PathToString(wallet_path)));
                status = DatabaseStatus::FAILED_ALREADY_EXISTS;
                return nullptr;
            }

            // Safety extra check:
            // The directory must not contain a database file.
            // Any .dat file indicates an existing wallet, and restoring into this
            // directory would overwrite it.
            for (const auto& entry : fs::directory_iterator(wallet_path)) {
                if (entry.path().extension() == ".dat") {
                    error = Untranslated(strprintf("Failed to restore wallet. Database file exists in '%s'.", fs::PathToString(wallet_path)));
                    status = DatabaseStatus::FAILED_ALREADY_EXISTS;
                    return nullptr;
                }
            }
        } else {
            // The directory doesn't exist, create it
            if (!TryCreateDirectories(wallet_path)) {
                error = Untranslated(strprintf("Failed to restore database path '%s'.", fs::PathToString(wallet_path)));
                status = DatabaseStatus::FAILED_ALREADY_EXISTS;
                return nullptr;
            }
        }

        fs::copy_file(backup_file, wallet_file, fs::copy_options::none);

        if (load_after_restore) {
            wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings);
        }
    } catch (const std::exception& e) {
        assert(!wallet);
        if (!error.empty()) error += Untranslated("\n");
        error += Untranslated(strprintf("Unexpected exception: %s", e.what()));
    }


Review comment (bug):
In d9e4593afb386268fbdd5f7fc1f409ea2253a244 "wallet: fix unnamed legacy wallet migration failure"

I think it would be better to check the filenames specifically:

```suggestion
                if (entry.path().filename() == wallet_file.filename()) {
```

This also enables this commit to restore a default wallet if the wallets directory already contains other files with the `.dat` extension.

Code after:
    auto wallet_file = wallet_path / "wallet.dat";
    std::shared_ptr<CWallet> wallet;
    bool wallet_file_copied = false;
    bool created_parent_dir = false;

    try {
        if (!fs::exists(backup_file)) {
            error = Untranslated("Backup file does not exist");
            status = DatabaseStatus::FAILED_INVALID_BACKUP_FILE;
            return nullptr;
        }

        // Wallet directories are allowed to exist, but must not contain a .dat file.
        // Any existing wallet database is treated as a hard failure to prevent overwriting.
        if (fs::exists(wallet_path)) {
            // If this is a file, it is the db and we don't want to overwrite it.
            if (!fs::is_directory(wallet_path)) {
                error = Untranslated(strprintf("Failed to restore wallet. Database file exists '%s'.", fs::PathToString(wallet_path)));
                status = DatabaseStatus::FAILED_ALREADY_EXISTS;
                return nullptr;
            }

            // Check we are not going to overwrite an existing db file
            if (fs::exists(wallet_file)) {
                error = Untranslated(strprintf("Failed to restore wallet. Database file exists in '%s'.", fs::PathToString(wallet_file)));
                status = DatabaseStatus::FAILED_ALREADY_EXISTS;
                return nullptr;
            }
        } else {
            // The directory doesn't exist, create it
            if (!TryCreateDirectories(wallet_path)) {
                error = Untranslated(strprintf("Failed to restore database path '%s'.", fs::PathToString(wallet_path)));
                status = DatabaseStatus::FAILED_ALREADY_EXISTS;
                return nullptr;
            }
            created_parent_dir = true;
        }

        fs::copy_file(backup_file, wallet_file, fs::copy_options::none);
        wallet_file_copied = true;

        if (load_after_restore) {
            wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings);
        }
    } catch (const std::exception& e) {
        assert(!wallet);
        if (!error.empty()) error += Untranslated("\n");
        error += Untranslated(strprintf("Unexpected exception: %s", e.what()));
    }

    // Remove created wallet path only when loading fails