diff --git a/dangerzone/gui/logic.py b/dangerzone/gui/logic.py index 163500058..972104380 100644 --- a/dangerzone/gui/logic.py +++ b/dangerzone/gui/logic.py @@ -24,7 +24,7 @@ from PySide2 import QtCore, QtGui, QtWidgets if platform.system() == "Linux": - from xdg.DesktopEntry import DesktopEntry + from xdg.DesktopEntry import DesktopEntry, ParsingError from ..isolation_provider.base import IsolationProvider from ..logic import DangerzoneCore @@ -123,27 +123,37 @@ def _find_pdf_viewers(self) -> OrderedDict[str, str]: full_filename = os.path.join(search_path, filename) if os.path.splitext(filename)[1] == ".desktop": # See which ones can open PDFs - desktop_entry = DesktopEntry(full_filename) - desktop_entry_name = desktop_entry.getName() - if ( - "application/pdf" in desktop_entry.getMimeTypes() - and "dangerzone" not in desktop_entry_name.lower() - ): - pdf_viewers[desktop_entry_name] = ( - desktop_entry.getExec() + try: + desktop_entry = DesktopEntry(full_filename) + except ParsingError: + # Do not stop when encountering malformed desktop entries + continue + except Exception: + log.exception( + "Encountered the following exception while processing desktop entry %s", + full_filename, ) - - # Put the default entry first - if filename == default_pdf_viewer: - try: - pdf_viewers.move_to_end( - desktop_entry_name, last=False - ) - except KeyError as e: - # Should be unreachable - log.error( - f"Problem reordering applications: {e}" - ) + else: + desktop_entry_name = desktop_entry.getName() + if ( + "application/pdf" in desktop_entry.getMimeTypes() + and "dangerzone" not in desktop_entry_name.lower() + ): + pdf_viewers[desktop_entry_name] = ( + desktop_entry.getExec() + ) + + # Put the default entry first + if filename == default_pdf_viewer: + try: + pdf_viewers.move_to_end( + desktop_entry_name, last=False + ) + except KeyError as e: + # Should be unreachable + log.error( + f"Problem reordering applications: {e}" + ) except FileNotFoundError: pass diff --git a/tests/gui/test_logic.py b/tests/gui/test_logic.py index a2bf6e53d..ee75355d9 100644 --- a/tests/gui/test_logic.py +++ b/tests/gui/test_logic.py @@ -7,7 +7,7 @@ from dangerzone.gui.logic import DangerzoneGui if platform.system() == "Linux": - from xdg.DesktopEntry import DesktopEntry + from xdg.DesktopEntry import DesktopEntry, ParsingError @pytest.mark.skipif(platform.system() != "Linux", reason="Linux-only test") @@ -98,3 +98,25 @@ def test_mime_handers_succeeds_no_default_found() -> None: mock_list.assert_called() assert len(dz.pdf_viewers) == 3 assert dz.pdf_viewers.popitem(last=False)[0] == "Evince" + + +@pytest.mark.skipif(platform.system() != "Linux", reason="Linux-only test") +def test_malformed_desktop_entry_is_catched() -> None: + """ + Given a failure to read a desktop entry, + ensure that the exception is not thrown to the end-user. + """ + mock_app = mock.MagicMock() + dummy = mock.MagicMock() + + with mock.patch("dangerzone.gui.logic.DesktopEntry") as mock_desktop, mock.patch( + "os.listdir", + side_effect=[ + ["malformed.desktop", "another.desktop"], + [], + [], + ], + ): + mock_desktop.side_effect = ParsingError("Oh noes!", "malformed.desktop") + DangerzoneGui(mock_app, dummy) + mock_desktop.assert_called()