forked from pool/rpmlint
Dirk Mueller
fc588f707f
OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory:rpmlint/rpmlint?expand=0&rev=567
131 lines
5.2 KiB
Diff
131 lines
5.2 KiB
Diff
From 8de78fa8b0cd9a2fe4156b841429ac8d55b39909 Mon Sep 17 00:00:00 2001
|
|
From: Dirk Mueller <dirk@dmllr.de>
|
|
Date: Fri, 29 Sep 2017 09:12:33 +0200
|
|
Subject: [PATCH] Improve XDG Menu checks stability
|
|
|
|
Running RawConfigParser on untrusted input can cause a lot
|
|
of exceptions. Handle them gracefully and raise appropriate
|
|
rpmlint errors. Also separate the code a little and cleaning it up.
|
|
---
|
|
MenuXDGCheck.py | 84 ++++++++++++++++++++++++++----------
|
|
test/binary/menuxdg1-0-0.noarch.rpm | Bin 0 -> 6555 bytes
|
|
test/test_menuxdg.py | 17 ++++++++
|
|
3 files changed, 78 insertions(+), 23 deletions(-)
|
|
create mode 100644 test/binary/menuxdg1-0-0.noarch.rpm
|
|
create mode 100644 test/test_menuxdg.py
|
|
|
|
Index: rpmlint-rpmlint-1.10/MenuXDGCheck.py
|
|
===================================================================
|
|
--- rpmlint-rpmlint-1.10.orig/MenuXDGCheck.py
|
|
+++ rpmlint-rpmlint-1.10/MenuXDGCheck.py
|
|
@@ -8,9 +8,9 @@
|
|
|
|
import os
|
|
try:
|
|
- from ConfigParser import RawConfigParser
|
|
-except:
|
|
- from configparser import RawConfigParser
|
|
+ import ConfigParser as cfgparser
|
|
+except ImportError:
|
|
+ import configparser as cfgparser
|
|
|
|
import AbstractCheck
|
|
from Filter import addDetails, printError, printWarning
|
|
@@ -25,7 +25,52 @@ class MenuXDGCheck(AbstractCheck.Abstrac
|
|
# $ echo $XDG_DATA_DIRS/applications
|
|
# /var/lib/menu-xdg:/usr/share
|
|
AbstractCheck.AbstractFilesCheck.__init__(
|
|
- self, "MenuXDGCheck", r"/usr/share/applications/.*\.desktop$")
|
|
+ self, "MenuXDGCheck", r'(?:/usr|/etc/opt|/opt/.*)/share/applications/.*\.desktop$')
|
|
+
|
|
+ def parse_desktop_file(self, pkg, root, f, filename):
|
|
+ cfp = cfgparser.RawConfigParser()
|
|
+ try:
|
|
+ with open(f, 'rb') as inputf:
|
|
+ cfp.readfp(inputf, filename)
|
|
+ except cfgparser.DuplicateSectionError as e:
|
|
+ printError(
|
|
+ pkg, 'desktopfile-duplicate-section', filename,
|
|
+ '[%s]' % e.section)
|
|
+ except cfgparser.MissingSectionHeaderError:
|
|
+ printError(
|
|
+ pkg, 'desktopfile-missing-header', filename)
|
|
+ except cfgparser.Error as e:
|
|
+ # Only in Python >= 3.2
|
|
+ if (hasattr(cfgparser, 'DuplicateOptionError') and
|
|
+ isinstance(e, cfgparser.DuplicateOptionError)):
|
|
+ printError(
|
|
+ pkg, 'desktopfile-duplicate-option', filename,
|
|
+ '[%s]/%s' % (e.section, e.option))
|
|
+ else:
|
|
+ printWarning(
|
|
+ pkg, 'invalid-desktopfile', filename,
|
|
+ e.message.partition(':')[0])
|
|
+ except UnicodeDecodeError as e:
|
|
+ printWarning(
|
|
+ pkg, 'invalid-desktopfile', filename, 'No valid Unicode')
|
|
+ else:
|
|
+ binary = None
|
|
+ if cfp.has_option('Desktop Entry', 'Exec'):
|
|
+ binary = cfp.get('Desktop Entry', 'Exec').partition(' ')[0]
|
|
+ if binary:
|
|
+ found = False
|
|
+ if binary.startswith('/'):
|
|
+ found = os.path.exists(root + binary)
|
|
+ else:
|
|
+ for i in STANDARD_BIN_DIRS:
|
|
+ if os.path.exists(root + i + '/' + binary):
|
|
+ # no need to check if the binary is +x, rpmlint does it
|
|
+ # in another place
|
|
+ found = True
|
|
+ break
|
|
+ if not found:
|
|
+ printWarning(
|
|
+ pkg, 'desktopfile-without-binary', filename, binary)
|
|
|
|
def check_file(self, pkg, filename):
|
|
root = pkg.dirName()
|
|
@@ -43,25 +88,7 @@ class MenuXDGCheck(AbstractCheck.Abstrac
|
|
if not is_utf8(f):
|
|
printError(pkg, 'non-utf8-desktopfile', filename)
|
|
|
|
- cfp = RawConfigParser()
|
|
- cfp.read(f)
|
|
- binary = None
|
|
- if cfp.has_option('Desktop Entry', 'Exec'):
|
|
- binary = cfp.get('Desktop Entry', 'Exec').split(' ', 1)[0]
|
|
- if binary:
|
|
- found = False
|
|
- if binary.startswith('/'):
|
|
- found = os.path.exists(root + binary)
|
|
- else:
|
|
- for i in STANDARD_BIN_DIRS:
|
|
- if os.path.exists(root + i + binary):
|
|
- # no need to check if the binary is +x, rpmlint does it
|
|
- # in another place
|
|
- found = True
|
|
- break
|
|
- if not found:
|
|
- printWarning(pkg, 'desktopfile-without-binary', filename,
|
|
- binary)
|
|
+ self.parse_desktop_file(pkg, root, f, filename)
|
|
|
|
|
|
check = MenuXDGCheck()
|
|
@@ -76,4 +103,15 @@ addDetails(
|
|
'desktopfile-without-binary',
|
|
'''the .desktop file is for a file not present in the package. You
|
|
should check the requires or see if this is not a error''',
|
|
+
|
|
+'desktopfile-duplicate-section',
|
|
+'''The .desktop file contains the mentioned section name twice, which
|
|
+can trigger parsing ambiguities. Remove the duplicate.''',
|
|
+
|
|
+'desktopfile-duplicate-option',
|
|
+'''The .desktop file contains the mentioned option key twice,
|
|
+which can trigger parsing ambiguities. Remove the duplicate.''',
|
|
+
|
|
+'desktopfile-missing-header',
|
|
+'''The .desktop file should start with a section header.''',
|
|
)
|