Skip to content

Commit

Permalink
Do not throw on malformed Desktop Entries on Linux.
Browse files Browse the repository at this point in the history
This just skips the malformed entry when it's found.

Fixes #899
  • Loading branch information
almet committed Sep 10, 2024
1 parent df3b265 commit 0c9f426
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 22 deletions.
52 changes: 31 additions & 21 deletions dangerzone/gui/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
24 changes: 23 additions & 1 deletion tests/gui/test_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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()

0 comments on commit 0c9f426

Please sign in to comment.