Do not throw on malformed Desktop Entries on Linux.

This just skips the malformed entry when it's found.

Fixes #899
This commit is contained in:
Alexis Métaireau 2024-08-29 18:18:15 +02:00
parent df3b26583e
commit 0c9f426b68
No known key found for this signature in database
GPG key ID: C65C7A89A8FFC56E
2 changed files with 53 additions and 21 deletions

View file

@ -24,7 +24,7 @@ else:
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 @@ class DangerzoneGui(DangerzoneCore):
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,
)
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}"
)
# 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

View file

@ -7,7 +7,7 @@ import pytest
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()