electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 36178df875eef5186b9c25622b7b5ae345776ecf
parent 6802bcb960bb4832b6a83b75aa62f46d3a248aee
Author: SomberNight <somber.night@protonmail.com>
Date:   Tue, 25 Aug 2020 18:18:07 +0200

sql: test read-write permissions for given path and raise early

maybe fix #6485

Diffstat:
Melectrum/sql_db.py | 3+++
Melectrum/storage.py | 30++++++------------------------
Melectrum/util.py | 22++++++++++++++++++++++
3 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/electrum/sql_db.py b/electrum/sql_db.py @@ -6,6 +6,7 @@ import asyncio import sqlite3 from .logging import Logger +from .util import test_read_write_permissions def sql(func): @@ -17,12 +18,14 @@ def sql(func): return f return wrapper + class SqlDB(Logger): def __init__(self, asyncio_loop, path, commit_interval=None): Logger.__init__(self) self.asyncio_loop = asyncio_loop self.path = path + test_read_write_permissions(path) self.commit_interval = commit_interval self.db_requests = queue.Queue() self.sql_thread = threading.Thread(target=self.run_sql) diff --git a/electrum/storage.py b/electrum/storage.py @@ -31,7 +31,8 @@ import zlib from enum import IntEnum from . import ecc -from .util import profiler, InvalidPassword, WalletFileException, bfh, standardize_path +from .util import (profiler, InvalidPassword, WalletFileException, bfh, standardize_path, + test_read_write_permissions) from .wallet_db import WalletDB from .logging import Logger @@ -62,7 +63,10 @@ class WalletStorage(Logger): self.logger.info(f"wallet path {self.path}") self.pubkey = None self.decrypted = '' - self._test_read_write_permissions(self.path) + try: + test_read_write_permissions(self.path) + except IOError as e: + raise StorageReadWriteError(e) from e if self.file_exists(): with open(self.path, "r", encoding='utf-8') as f: self.raw = f.read() @@ -74,28 +78,6 @@ class WalletStorage(Logger): def read(self): return self.decrypted if self.is_encrypted() else self.raw - @classmethod - def _test_read_write_permissions(cls, path): - # note: There might already be a file at 'path'. - # Make sure we do NOT overwrite/corrupt that! - temp_path = "%s.tmptest.%s" % (path, os.getpid()) - echo = "fs r/w test" - try: - # test READ permissions for actual path - if os.path.exists(path): - with open(path, "r", encoding='utf-8') as f: - f.read(1) # read 1 byte - # test R/W sanity for "similar" path - with open(temp_path, "w", encoding='utf-8') as f: - f.write(echo) - with open(temp_path, "r", encoding='utf-8') as f: - echo2 = f.read() - os.remove(temp_path) - except Exception as e: - raise StorageReadWriteError(e) from e - if echo != echo2: - raise StorageReadWriteError('echo sanity-check failed') - @profiler def write(self, data): s = self.encrypt_before_writing(data) diff --git a/electrum/util.py b/electrum/util.py @@ -1465,3 +1465,25 @@ def random_shuffled_copy(x: Iterable[T]) -> List[T]: x_copy = list(x) # copy random.shuffle(x_copy) # shuffle in-place return x_copy + + +def test_read_write_permissions(path) -> None: + # note: There might already be a file at 'path'. + # Make sure we do NOT overwrite/corrupt that! + temp_path = "%s.tmptest.%s" % (path, os.getpid()) + echo = "fs r/w test" + try: + # test READ permissions for actual path + if os.path.exists(path): + with open(path, "rb") as f: + f.read(1) # read 1 byte + # test R/W sanity for "similar" path + with open(temp_path, "w", encoding='utf-8') as f: + f.write(echo) + with open(temp_path, "r", encoding='utf-8') as f: + echo2 = f.read() + os.remove(temp_path) + except Exception as e: + raise IOError(e) from e + if echo != echo2: + raise IOError('echo sanity-check failed')