From f87f4c7d918247a769800fcb37b16257d93c0faf Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Sat, 9 Nov 2019 04:39:53 +0100 Subject: [PATCH] repoman: Fix unsafe string interpolation. "on line: %d" etc. is no longer included in messages returned from individual checks. "line %d: " is now consistently added by controller directly after ebuild path and precedes specific message. Example: app-misc/test/test-0.ebuild: line 5: please migrate from 'games' (no replacement) app-misc/test/test-0.ebuild: line 5: please migrate from 'versionator' to 'eapi7-ver (built-in since EAPI 7)' app-misc/test/test-0.ebuild: line 10: Useless blank line app-misc/test/test-0.ebuild: line 20: 'econf' call should be moved to src_configure Bug: https://bugs.gentoo.org/699508 Signed-off-by: Arfrever Frehtes Taifersar Arahesis --- repoman/cnf/linechecks/linechecks.yaml | 46 +++++++++---------- .../lib/repoman/modules/linechecks/base.py | 5 +- .../repoman/modules/linechecks/controller.py | 12 +++-- .../modules/linechecks/deprecated/inherit.py | 18 +++----- .../repoman/modules/linechecks/do/dosym.py | 2 +- .../repoman/modules/linechecks/eapi/checks.py | 10 ++-- .../repoman/modules/linechecks/emake/emake.py | 2 +- .../modules/linechecks/phases/phase.py | 4 +- .../modules/linechecks/portage/internal.py | 7 +-- .../modules/linechecks/quotes/quoteda.py | 2 +- .../modules/linechecks/useless/dodoc.py | 2 +- .../modules/linechecks/whitespace/blank.py | 2 +- 12 files changed, 53 insertions(+), 59 deletions(-) diff --git a/repoman/cnf/linechecks/linechecks.yaml b/repoman/cnf/linechecks/linechecks.yaml index c452af07d..410bcd9c5 100644 --- a/repoman/cnf/linechecks/linechecks.yaml +++ b/repoman/cnf/linechecks/linechecks.yaml @@ -9,27 +9,27 @@ repoman_version: 2.3.3 # configuration file for the LineCheck plugins run via the multicheck # scan module errors: - COPYRIGHT_ERROR: 'Invalid Copyright on line: %d' - LICENSE_ERROR: 'Invalid Gentoo/GPL License on line: %d' - ID_HEADER_ERROR: 'Stale CVS header on line: %d' - NO_BLANK_LINE_ERROR: 'Non-blank line after header on line: %d' - LEADING_SPACES_ERROR: 'Ebuild contains leading spaces on line: %d' - TRAILING_WHITESPACE_ERROR: 'Trailing whitespace error on line: %d' - READONLY_ASSIGNMENT_ERROR: 'Ebuild contains assignment to read-only variable on line: %d' - MISSING_QUOTES_ERROR: 'Unquoted Variable on line: %d' - NESTED_DIE_ERROR: 'Ebuild calls die in a subshell on line: %d' - PATCHES_ERROR: 'PATCHES is not a bash array on line: %d' - REDUNDANT_CD_S_ERROR: 'Ebuild has redundant cd ${S} statement on line: %d' - EMAKE_PARALLEL_DISABLED: 'Upstream parallel compilation bug (ebuild calls emake -j1 on line: %d)' - EMAKE_PARALLEL_DISABLED_VIA_MAKEOPTS: 'Upstream parallel compilation bug (MAKEOPTS=-j1 on line: %d)' - DEPRECATED_BINDNOW_FLAGS: 'Deprecated bindnow-flags call on line: %d' - EAPI_DEFINED_AFTER_INHERIT: 'EAPI defined after inherit on line: %d' - NO_AS_NEEDED: 'Upstream asneeded linking bug (no-as-needed on line: %d)' - PRESERVE_OLD_LIB: 'Ebuild calls deprecated preserve_old_lib on line: %d' - BUILT_WITH_USE: 'built_with_use on line: %d' - NO_OFFSET_WITH_HELPERS: 'Helper function is used with D, ROOT, ED, EROOT or EPREFIX on line: %d' - SANDBOX_ADDPREDICT: 'Ebuild calls addpredict on line: %d' - USEQ_ERROR: 'Ebuild calls deprecated useq function on line: %d' - HASQ_ERROR: 'Ebuild calls deprecated hasq function on line: %d' - URI_HTTPS: 'Ebuild uses http:// but should use https:// on line: %d' + COPYRIGHT_ERROR: 'Invalid Copyright' + LICENSE_ERROR: 'Invalid Gentoo/GPL License' + ID_HEADER_ERROR: 'Stale CVS header' + NO_BLANK_LINE_ERROR: 'Non-blank line after header' + LEADING_SPACES_ERROR: 'Ebuild contains leading spaces' + TRAILING_WHITESPACE_ERROR: 'Trailing whitespace error' + READONLY_ASSIGNMENT_ERROR: 'Ebuild contains assignment to read-only variable' + MISSING_QUOTES_ERROR: 'Unquoted Variable' + NESTED_DIE_ERROR: 'Ebuild calls die in a subshell' + PATCHES_ERROR: 'PATCHES is not a bash array' + REDUNDANT_CD_S_ERROR: 'Ebuild has redundant cd ${S} statement' + EMAKE_PARALLEL_DISABLED: 'Upstream parallel compilation bug (ebuild calls emake -j1)' + EMAKE_PARALLEL_DISABLED_VIA_MAKEOPTS: 'Upstream parallel compilation bug (MAKEOPTS=-j1)' + DEPRECATED_BINDNOW_FLAGS: 'Deprecated bindnow-flags call' + EAPI_DEFINED_AFTER_INHERIT: 'EAPI defined after inherit' + NO_AS_NEEDED: 'Upstream asneeded linking bug (no-as-needed)' + PRESERVE_OLD_LIB: 'Ebuild calls deprecated preserve_old_lib' + BUILT_WITH_USE: 'built_with_use' + NO_OFFSET_WITH_HELPERS: 'Helper function is used with D, ROOT, ED, EROOT or EPREFIX' + SANDBOX_ADDPREDICT: 'Ebuild calls addpredict' + USEQ_ERROR: 'Ebuild calls deprecated useq function' + HASQ_ERROR: 'Ebuild calls deprecated hasq function' + URI_HTTPS: 'Ebuild uses http:// but should use https://' diff --git a/repoman/lib/repoman/modules/linechecks/base.py b/repoman/lib/repoman/modules/linechecks/base.py index 4e3d6f0b4..39d7ebd78 100644 --- a/repoman/lib/repoman/modules/linechecks/base.py +++ b/repoman/lib/repoman/modules/linechecks/base.py @@ -88,9 +88,8 @@ class InheritEclass(LineCheck): if eapi_func is None or not eapi_func(self._eapi): self._func_call = True return ( - '%s.eclass is not inherited, ' - 'but "%s" found at line: %s' % - (self._eclass, func_name, '%d')) + '%s.eclass not inherited, but "%s" called' % + (self._eclass, func_name)) elif not self._func_call: self._func_call = self._func_re.search(line) diff --git a/repoman/lib/repoman/modules/linechecks/controller.py b/repoman/lib/repoman/modules/linechecks/controller.py index 7082a5d02..a3dfd9bd1 100644 --- a/repoman/lib/repoman/modules/linechecks/controller.py +++ b/repoman/lib/repoman/modules/linechecks/controller.py @@ -74,7 +74,7 @@ class LineCheckController(object): def run_checks(self, contents, pkg): '''Run the configured linechecks - @param contents: the ebjuild contents to check + @param contents: the ebuild contents to check @param pkg: the package being checked ''' if self._constant_checks is None: @@ -134,9 +134,13 @@ class LineCheckController(object): if lc.check_eapi(pkg.eapi): ignore = lc.ignore_line if not ignore or not ignore.match(line): - e = lc.check(num, line) - if e: - yield lc.repoman_check_name, e % (num + 1) + errors = lc.check(num, line) + if errors: + if isinstance(errors, (tuple, list)): + for error in errors: + yield lc.repoman_check_name, "line %d: %s" % (num + 1, error) + else: + yield lc.repoman_check_name, "line %d: %s" % (num + 1, errors) for lc in checks: i = lc.end() diff --git a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py b/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py index 361da09b9..9cef086da 100644 --- a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py +++ b/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py @@ -37,9 +37,6 @@ class InheritDeprecated(LineCheck): _inherit_re = re.compile(r'^\s*inherit\s(.*)$') - def new(self, pkg): - self._errors = [] - def check(self, num, line): direct_inherits = None m = self._inherit_re.match(line) @@ -51,20 +48,17 @@ class InheritDeprecated(LineCheck): if not direct_inherits: return + errors = [] for eclass in direct_inherits: replacement = self.deprecated_eclasses.get(eclass) if replacement is None: pass elif replacement is False: - self._errors.append( + errors.append( "please migrate from " - "'%s' (no replacement) on line: %d" % (eclass, num + 1)) + "'%s' (no replacement)" % eclass) else: - self._errors.append( + errors.append( "please migrate from " - "'%s' to '%s' on line: %d" % (eclass, replacement, num + 1)) - - def end(self): - for error in self._errors: - yield error - del self._errors + "'%s' to '%s'" % (eclass, replacement)) + return errors diff --git a/repoman/lib/repoman/modules/linechecks/do/dosym.py b/repoman/lib/repoman/modules/linechecks/do/dosym.py index c342d3595..d1aed74d7 100644 --- a/repoman/lib/repoman/modules/linechecks/do/dosym.py +++ b/repoman/lib/repoman/modules/linechecks/do/dosym.py @@ -15,4 +15,4 @@ class EbuildNonRelativeDosym(LineCheck): def check(self, num, line): match = self.regex.match(line) if match: - return "dosym '%s'... could use relative path" % (match.group(1), ) + " on line: %d" + return "dosym '%s'... could use relative path" % match.group(1) diff --git a/repoman/lib/repoman/modules/linechecks/eapi/checks.py b/repoman/lib/repoman/modules/linechecks/eapi/checks.py index de899c061..c53ca3832 100644 --- a/repoman/lib/repoman/modules/linechecks/eapi/checks.py +++ b/repoman/lib/repoman/modules/linechecks/eapi/checks.py @@ -19,7 +19,7 @@ class UndefinedSrcPrepareSrcConfigurePhases(LineCheck): m = self.src_configprepare_re.match(line) if m is not None: return ("'%s'" % m.group(1)) + \ - " phase is not defined in EAPI < 2 on line: %d" + " phase is not defined in EAPI < 2" # EAPI-3 checks @@ -34,7 +34,7 @@ class Eapi3DeprecatedFuncs(LineCheck): m = self.deprecated_commands_re.match(line) if m is not None: return ("'%s'" % m.group(1)) + \ - " has been deprecated in EAPI=3 on line: %d" + " has been deprecated in EAPI=3" # EAPI <4 checks @@ -49,7 +49,7 @@ class UndefinedPkgPretendPhase(LineCheck): m = self.pkg_pretend_re.match(line) if m is not None: return ("'%s'" % m.group(1)) + \ - " phase is not defined in EAPI < 4 on line: %d" + " phase is not defined in EAPI < 4" # EAPI-4 checks @@ -64,7 +64,7 @@ class Eapi4IncompatibleFuncs(LineCheck): m = self.banned_commands_re.match(line) if m is not None: return ("'%s'" % m.group(1)) + \ - " has been banned in EAPI=4 on line: %d" + " has been banned in EAPI=4" class Eapi4GoneVars(LineCheck): @@ -80,4 +80,4 @@ class Eapi4GoneVars(LineCheck): m = self.undefined_vars_re.match(line) if m is not None: return ("variable '$%s'" % m.group(1)) + \ - " is gone in EAPI=4 on line: %d" + " is gone in EAPI=4" diff --git a/repoman/lib/repoman/modules/linechecks/emake/emake.py b/repoman/lib/repoman/modules/linechecks/emake/emake.py index e1e3e638e..e618872e0 100644 --- a/repoman/lib/repoman/modules/linechecks/emake/emake.py +++ b/repoman/lib/repoman/modules/linechecks/emake/emake.py @@ -20,4 +20,4 @@ class WantAutoDefaultValue(LineCheck): m = self._re.match(line) if m is not None: return 'WANT_AUTO' + m.group(1) + \ - ' redundantly set to default value "latest" on line: %d' + ' redundantly set to default value "latest"' diff --git a/repoman/lib/repoman/modules/linechecks/phases/phase.py b/repoman/lib/repoman/modules/linechecks/phases/phase.py index acc3a1e1d..74cf4608f 100644 --- a/repoman/lib/repoman/modules/linechecks/phases/phase.py +++ b/repoman/lib/repoman/modules/linechecks/phases/phase.py @@ -53,7 +53,7 @@ class SrcCompileEconf(PhaseCheck): m = self.configure_re.match(line) if m is not None: return ("'%s'" % m.group(1)) + \ - " call should be moved to src_configure from line: %d" + " call should be moved to src_configure" class SrcUnpackPatches(PhaseCheck): @@ -68,4 +68,4 @@ class SrcUnpackPatches(PhaseCheck): m = self.src_prepare_tools_re.search(line) if m is not None: return ("'%s'" % m.group(1)) + \ - " call should be moved to src_prepare from line: %d" + " call should be moved to src_prepare" diff --git a/repoman/lib/repoman/modules/linechecks/portage/internal.py b/repoman/lib/repoman/modules/linechecks/portage/internal.py index 869337221..bc0564600 100644 --- a/repoman/lib/repoman/modules/linechecks/portage/internal.py +++ b/repoman/lib/repoman/modules/linechecks/portage/internal.py @@ -20,7 +20,7 @@ class PortageInternal(LineCheck): """Run the check on line and return error if there is one""" m = self.re.match(line) if m is not None: - return ("'%s'" % m.group(2)) + " called on line: %d" + return "'%s' called" % m.group(2) class PortageInternalVariableAssignment(LineCheck): @@ -30,8 +30,5 @@ class PortageInternalVariableAssignment(LineCheck): def check(self, num, line): match = self.internal_assignment.match(line) - e = None if match is not None: - e = 'Assignment to variable %s' % match.group(2) - e += ' on line: %d' - return e + return 'Assignment to variable %s' % match.group(2) diff --git a/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py b/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py index 7fd9ba797..5b68f301c 100644 --- a/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py +++ b/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py @@ -13,4 +13,4 @@ class EbuildQuotedA(LineCheck): def check(self, num, line): match = self.a_quoted.match(line) if match: - return "Quoted \"${A}\" on line: %d" + return "Quoted \"${A}\"" diff --git a/repoman/lib/repoman/modules/linechecks/useless/dodoc.py b/repoman/lib/repoman/modules/linechecks/useless/dodoc.py index 502bfbea8..3270af1a9 100644 --- a/repoman/lib/repoman/modules/linechecks/useless/dodoc.py +++ b/repoman/lib/repoman/modules/linechecks/useless/dodoc.py @@ -13,4 +13,4 @@ class EbuildUselessDodoc(LineCheck): def check(self, num, line): match = self.uselessdodoc_re.match(line) if match: - return "Useless dodoc '%s'" % (match.group(2), ) + " on line: %d" + return "Useless dodoc '%s'" % match.group(2) diff --git a/repoman/lib/repoman/modules/linechecks/whitespace/blank.py b/repoman/lib/repoman/modules/linechecks/whitespace/blank.py index 2ab4097a3..1fa3eb2b9 100644 --- a/repoman/lib/repoman/modules/linechecks/whitespace/blank.py +++ b/repoman/lib/repoman/modules/linechecks/whitespace/blank.py @@ -14,7 +14,7 @@ class EbuildBlankLine(LineCheck): def check(self, num, line): if self.line_is_blank and self.blank_line.match(line): - return 'Useless blank line on line: %d' + return 'Useless blank line' if self.blank_line.match(line): self.line_is_blank = True else: -- 2.24.0