diff --git a/news/fix_noaccess.rst b/news/fix_noaccess.rst new file mode 100644 index 000000000..c6a77ca49 --- /dev/null +++ b/news/fix_noaccess.rst @@ -0,0 +1,24 @@ +**Added:** + +* Added catching an exceptions during load a history backend to avoid shell exiting e.g. on permission error. +* Added catching an exception when cache file is not writable. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/xonsh/codecache.py b/xonsh/codecache.py index 0327a596d..be163eac5 100644 --- a/xonsh/codecache.py +++ b/xonsh/codecache.py @@ -9,6 +9,7 @@ from xonsh import __version__ as XONSH_VERSION from xonsh.built_ins import XSH from xonsh.lazyasd import lazyobject from xonsh.platform import PYTHON_VERSION_INFO_BYTES +from xonsh.tools import is_writable_file, print_warning def _splitpath(path, sofar=()): @@ -94,6 +95,13 @@ def update_cache(ccode, cache_file_name): represented by ``ccode``. """ if cache_file_name is not None: + if not is_writable_file(cache_file_name): + if XSH.env.get("XONSH_DEBUG", "False"): + print_warning( + f"update_cache: Cache file is not writable: {cache_file_name}\n" + f"Set $XONSH_CACHE_SCRIPTS=0, $XONSH_CACHE_EVERYTHING=0 to disable cache." + ) + return os.makedirs(os.path.dirname(cache_file_name), exist_ok=True) with open(cache_file_name, "wb") as cfile: cfile.write(XONSH_VERSION.encode() + b"\n") @@ -166,7 +174,8 @@ def run_script_with_cache(filename, execer, glb=None, loc=None, mode="exec"): with open(filename, encoding="utf-8") as f: code = f.read() ccode = compile_code(filename, code, execer, glb, loc, mode) - update_cache(ccode, cachefname) + if use_cache: + update_cache(ccode, cachefname) return run_compiled_code(ccode, glb, loc, mode) diff --git a/xonsh/history/main.py b/xonsh/history/main.py index b765cb0c4..4c41f0520 100644 --- a/xonsh/history/main.py +++ b/xonsh/history/main.py @@ -36,7 +36,16 @@ def construct_history(backend=None, **kwargs) -> "History": file=sys.stderr, ) kls_history = JsonHistory - return kls_history(**kwargs) + + try: + return kls_history(**kwargs) + except Exception as e: + xt.print_exception( + f"Error during load {kls_history}: {e}\n" + f"Set $XONSH_HISTORY_BACKEND='dummy' to disable history.\n" + f"History disabled." + ) + return DummyHistory() def _xh_session_parser(hist=None, newest_first=False, **kwargs):