From c575435782bc345d7f374c81090fe01e93badfb5 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 1 Oct 2015 13:15:50 +0100 Subject: [PATCH] misc/editor: Fix tempfile deleted on error / editor crash This patch attempts to fix an issue where an error occuring in misc/guiprocess or the editor process crashing would delete the temporary file thus making it impossible to recover changes not commited to the form field from the editor. --- qutebrowser/misc/editor.py | 3 ++- qutebrowser/misc/guiprocess.py | 3 +++ tests/unit/misc/test_editor.py | 13 +++++++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/qutebrowser/misc/editor.py b/qutebrowser/misc/editor.py index 4211fe184..4bb83574e 100644 --- a/qutebrowser/misc/editor.py +++ b/qutebrowser/misc/editor.py @@ -58,7 +58,8 @@ class ExternalEditor(QObject): return try: os.close(self._oshandle) - os.remove(self._filename) + if self._proc.exit_status() != QProcess.CrashExit: + os.remove(self._filename) except OSError as e: # NOTE: Do not replace this with "raise CommandError" as it's # executed async. diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py index 2c4c4f0a2..0df4d446f 100644 --- a/qutebrowser/misc/guiprocess.py +++ b/qutebrowser/misc/guiprocess.py @@ -151,3 +151,6 @@ class GUIProcess(QObject): else: message.error(self._win_id, "Error while spawning {}: {}.".format( self._what, self._proc.error()), immediately=True) + + def exit_status(self): + return self._proc.exitStatus() diff --git a/tests/unit/misc/test_editor.py b/tests/unit/misc/test_editor.py index ae1db876c..edeeb8922 100644 --- a/tests/unit/misc/test_editor.py +++ b/tests/unit/misc/test_editor.py @@ -91,19 +91,28 @@ class TestFileHandling: filename = editor._filename assert os.path.exists(filename) + editor._proc._proc.exitStatus = mock.Mock( + return_value=QProcess.CrashExit) editor._proc.finished.emit(1, QProcess.NormalExit) - assert not os.path.exists(filename) + assert os.path.exists(filename) + + os.remove(filename) def test_crash(self, editor): """Test file handling when closing with a crash.""" editor.edit("") filename = editor._filename assert os.path.exists(filename) + + editor._proc._proc.exitStatus = mock.Mock( + return_value=QProcess.CrashExit) editor._proc.error.emit(QProcess.Crashed) editor._proc.finished.emit(0, QProcess.CrashExit) - assert not os.path.exists(filename) + assert os.path.exists(filename) + + os.remove(filename) @pytest.mark.posix def test_unreadable(self, message_mock, editor):