File foo.patch of Package rpmlint

From 4a3718ed0cf3afece27f8d2f0b32ee01937a9b0b Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Mon, 13 Jan 2025 13:17:47 +0100
Subject: [PATCH] foo

---
 rpmlint/checks/BinariesCheck.py | 581 ++++++++++++++++++++------------
 1 file changed, 369 insertions(+), 212 deletions(-)

diff --git a/rpmlint/checks/BinariesCheck.py b/rpmlint/checks/BinariesCheck.py
index 0e147709..3d484ce1 100644
--- a/rpmlint/checks/BinariesCheck.py
+++ b/rpmlint/checks/BinariesCheck.py
@@ -12,85 +12,98 @@ from rpmlint.pkg import FakePkg, InstalledPkg
 from rpmlint.readelfparser import ReadelfParser
 from rpmlint.stringsparser import StringsParser
 
-KERNEL_MODULES_PATHS = ('/lib/modules/', '/usr/lib/modules/')
-GLIBC_EMPTY_ARCHIVES = ('libanl', 'libdl', 'libpthread', 'librt', 'libutil')
+KERNEL_MODULES_PATHS = ("/lib/modules/", "/usr/lib/modules/")
+GLIBC_EMPTY_ARCHIVES = ("libanl", "libdl", "libpthread", "librt", "libutil")
 
 
 class BinariesCheck(AbstractCheck):
     """
     Checks for binary files in the package.
     """
-    validso_regex = re.compile(r'(\.so\.\d+(\.\d+)*|\d\.so)$')
-    soversion_regex = re.compile(r'.*?(-(?P<pkgversion>[0-9][.0-9]*))?\.so(\.(?P<soversion>[0-9][.0-9]*))?')
-    usr_lib_regex = re.compile(r'^/usr/lib(64)?/')
-    ldso_soname_regex = re.compile(r'^ld(-linux(-(ia|x86_)64))?\.so')
-
-    numeric_dir_regex = re.compile(r'/usr(?:/share)/man/man./(.*)\.[0-9](?:\.gz|\.bz2)')
-    versioned_dir_regex = re.compile(r'[^.][0-9]')
-    so_regex = re.compile(r'/lib(64)?/[^/]+\.so(\.[0-9]+)*$')
-    bin_regex = re.compile(r'^(/usr(/X11R6)?)?/s?bin/')
-    la_file_regex = re.compile(r'\.la$')
-    invalid_dir_ref_regex = re.compile(r'/(home|tmp)(\W|$)')
-    usr_arch_share_regex = re.compile(r'/share/.*/(?:x86|i.86|x86_64|ppc|ppc64|s390|s390x|ia64|m68k|arm|aarch64|mips|riscv)')
-    python_module_regex = re.compile(r'.*\.(\w*(python|pypy)\w*(-\w+){4}|abi3)\.so')
+
+    validso_regex = re.compile(r"(\.so\.\d+(\.\d+)*|\d\.so)$")
+    soversion_regex = re.compile(
+        r".*?(-(?P<pkgversion>[0-9][.0-9]*))?\.so(\.(?P<soversion>[0-9][.0-9]*))?"
+    )
+    usr_lib_regex = re.compile(r"^/usr/lib(64)?/")
+    ldso_soname_regex = re.compile(r"^ld(-linux(-(ia|x86_)64))?\.so")
+
+    numeric_dir_regex = re.compile(r"/usr(?:/share)/man/man./(.*)\.[0-9](?:\.gz|\.bz2)")
+    versioned_dir_regex = re.compile(r"[^.][0-9]")
+    so_regex = re.compile(r"/lib(64)?/[^/]+\.so(\.[0-9]+)*$")
+    bin_regex = re.compile(r"^(/usr(/X11R6)?)?/s?bin/")
+    la_file_regex = re.compile(r"\.la$")
+    invalid_dir_ref_regex = re.compile(r"/(home|tmp)(\W|$)")
+    usr_arch_share_regex = re.compile(
+        r"/share/.*/(?:x86|i.86|x86_64|ppc|ppc64|s390|s390x|ia64|m68k|arm|aarch64|mips|riscv)"
+    )
+    python_module_regex = re.compile(r".*\.(\w*(python|pypy)\w*(-\w+){4}|abi3)\.so")
     # Starts with ELF or with a special qualifiers like setuid or setgid
     # https://github.com/rpm-software-management/rpmlint/issues/1088
-    elf_regex = re.compile(r'^(\w+ )?ELF ')
+    elf_regex = re.compile(r"^(\w+ )?ELF ")
 
-    lto_text_like_sections = {'.preinit_array', '.init_array', '.fini_array'}
+    lto_text_like_sections = {".preinit_array", ".init_array", ".fini_array"}
     # The following sections are part of the RX ABI and do correspond to .text, .data and .bss
-    lto_text_like_sections |= {'P', 'D_1', 'B_1'}
+    lto_text_like_sections |= {"P", "D_1", "B_1"}
 
     # The list is taken from glibc: sysdeps/${arch}/stackinfo.h
-    default_executable_stack_archs = re.compile(r'alpha|arm.*|hppa|i.86|m68k|microblaze|mips|ppc|s390|s390x|sh|sparc|x86_64')
+    default_executable_stack_archs = re.compile(
+        r"alpha|arm.*|hppa|i.86|m68k|microblaze|mips|ppc|s390|s390x|sh|sparc|x86_64"
+    )
 
-    rpath_origin = '$ORIGIN'
-    hpc_locations = ('/usr/lib/mpi/', '/usr/lib64/mpi/', '/usr/lib/hpc/')
+    rpath_origin = "$ORIGIN"
+    hpc_locations = ("/usr/lib/mpi/", "/usr/lib64/mpi/", "/usr/lib/hpc/")
 
     def __init__(self, config, output):
         super().__init__(config, output)
         self.checked_files = 0
-        self.system_lib_paths = tuple(config.configuration['SystemLibPaths'])
+        self.system_lib_paths = tuple(config.configuration["SystemLibPaths"])
         self.pie_exec_regex_list = []
-        for regex in config.configuration['PieExecutables']:
+        for regex in config.configuration["PieExecutables"]:
             self.pie_exec_regex_list.append(re.compile(regex))
-        self.usr_lib_exception_regex = re.compile(config.configuration['UsrLibBinaryException'])
-
-        self.setgid_call_regex = self.create_regexp_call(r'set(?:res|e)?gid')
-        self.setuid_call_regex = self.create_regexp_call(r'set(?:res|e)?uid')
-        self.setgroups_call_regex = self.create_regexp_call(r'(?:ini|se)tgroups')
-        self.mktemp_call_regex = self.create_regexp_call('mktemp')
-        self.gethostbyname_call_regex = self.create_regexp_call(r'(gethostbyname|gethostbyname2|gethostbyaddr|gethostbyname_r|gethostbyname2_r|gethostbyaddr_r)')
+        self.usr_lib_exception_regex = re.compile(
+            config.configuration["UsrLibBinaryException"]
+        )
+
+        self.setgid_call_regex = self.create_regexp_call(r"set(?:res|e)?gid")
+        self.setuid_call_regex = self.create_regexp_call(r"set(?:res|e)?uid")
+        self.setgroups_call_regex = self.create_regexp_call(r"(?:ini|se)tgroups")
+        self.mktemp_call_regex = self.create_regexp_call("mktemp")
+        self.gethostbyname_call_regex = self.create_regexp_call(
+            r"(gethostbyname|gethostbyname2|gethostbyaddr|gethostbyname_r|gethostbyname2_r|gethostbyaddr_r)"
+        )
 
         # register all check functions
-        self.check_functions = [self._check_lto_section,
-                                self._check_no_text_in_archive,
-                                self._check_missing_symtab_in_archive,
-                                self._check_missing_debug_info_in_archive,
-                                self._check_executable_stack,
-                                self._check_shared_library,
-                                self._check_dependency,
-                                self._check_library_dependency_location,
-                                self._check_security_functions,
-                                self._check_rpath,
-                                self._check_library_dependency,
-                                self._check_forbidden_functions,
-                                self._check_executable_shlib,
-                                self._check_optflags,
-                                self._check_hash_sections,
-                                self._check_no_patchable_function_entries_in_archive]
+        self.check_functions = [
+            self._check_lto_section,
+            self._check_no_text_in_archive,
+            self._check_missing_symtab_in_archive,
+            self._check_missing_debug_info_in_archive,
+            self._check_executable_stack,
+            self._check_shared_library,
+            self._check_dependency,
+            self._check_library_dependency_location,
+            self._check_security_functions,
+            self._check_rpath,
+            self._check_library_dependency,
+            self._check_forbidden_functions,
+            self._check_executable_shlib,
+            self._check_optflags,
+            self._check_hash_sections,
+            self._check_no_patchable_function_entries_in_archive,
+        ]
 
     def reset(self):
         self.checked_files = 0
 
     @staticmethod
     def create_nonlibc_regexp_call(call):
-        r = r'(%s)\s?.*$' % call
+        r = r"(%s)\s?.*$" % call
         return re.compile(r)
 
     @staticmethod
     def create_regexp_call(call):
-        r = r'(%s(?:@GLIBC\S+)?)(?:\s|$)' % call
+        r = r"(%s(?:@GLIBC\S+)?)(?:\s|$)" % call
         return re.compile(r)
 
     def _check_libtool_wrapper(self, pkg, fname, pkgfile):
@@ -98,15 +111,17 @@ class BinariesCheck(AbstractCheck):
         Print an error if the fname file contains a libtool wrapper shell
         script.
         """
-        if 'shell script' in pkgfile.magic:
+        if "shell script" in pkgfile.magic:
             file_start = None
-            with contextlib.suppress(IOError), open(pkgfile.path, 'rb') as inputf:
+            with contextlib.suppress(IOError), open(pkgfile.path, "rb") as inputf:
                 file_start = inputf.read(2048)
-            if (file_start and b'This wrapper script should never '
-                               b'be moved out of the build directory'
-                    in file_start):
-                self.output.add_info('E', pkg, 'libtool-wrapper-in-package',
-                                     fname)
+            if (
+                file_start
+                and b"This wrapper script should never "
+                b"be moved out of the build directory"
+                in file_start
+            ):
+                self.output.add_info("E", pkg, "libtool-wrapper-in-package", fname)
 
     def _check_invalid_la_file(self, pkg, fname):
         """
@@ -118,17 +133,18 @@ class BinariesCheck(AbstractCheck):
         if self.la_file_regex.search(fname):
             line = pkg.grep(self.invalid_dir_ref_regex, fname)
             if line:
-                self.output.add_info('E', pkg, 'invalid-la-file', fname,
-                                     f'(line {line})')
+                self.output.add_info(
+                    "E", pkg, "invalid-la-file", fname, f"(line {line})"
+                )
 
     def _check_binary_in_noarch(self, pkg, bin_name):
         """
         Print an error if the binary file bin_name is in the noarch package.
         """
-        if pkg.arch == 'noarch':
-            self.output.add_info('E', pkg,
-                                 'arch-independent-package-contains-binary-or-object',
-                                 bin_name)
+        if pkg.arch == "noarch":
+            self.output.add_info(
+                "E", pkg, "arch-independent-package-contains-binary-or-object", bin_name
+            )
 
     def _check_binary_in_usr_share(self, pkg, bin_name):
         """
@@ -136,10 +152,10 @@ class BinariesCheck(AbstractCheck):
 
         We suppose that the package is arch dependent.
         """
-        if bin_name.startswith('/usr/share/') and \
-                not self.usr_arch_share_regex.search(bin_name):
-            self.output.add_info('E', pkg, 'arch-dependent-file-in-usr-share',
-                                 bin_name)
+        if bin_name.startswith("/usr/share/") and not self.usr_arch_share_regex.search(
+            bin_name
+        ):
+            self.output.add_info("E", pkg, "arch-dependent-file-in-usr-share", bin_name)
 
     def _check_binary_in_etc(self, pkg, bin_name):
         """
@@ -147,8 +163,8 @@ class BinariesCheck(AbstractCheck):
 
         We suppose that the package is arch dependent.
         """
-        if bin_name.startswith('/etc/'):
-            self.output.add_info('E', pkg, 'binary-in-etc', bin_name)
+        if bin_name.startswith("/etc/"):
+            self.output.add_info("E", pkg, "binary-in-etc", bin_name)
 
     def _check_unstripped_binary(self, bin_name, pkg, pkgfile):
         """
@@ -157,9 +173,8 @@ class BinariesCheck(AbstractCheck):
         We suppose that the package is arch dependent and bin_name is not
         ocaml native, lua bytecode, .o or .static.
         """
-        if 'not stripped' in pkgfile.magic:
-            self.output.add_info('W', pkg, 'unstripped-binary-or-object',
-                                 bin_name)
+        if "not stripped" in pkgfile.magic:
+            self.output.add_info("W", pkg, "unstripped-binary-or-object", bin_name)
 
     def _check_non_pie(self, pkg, bin_name):
         """
@@ -172,13 +187,13 @@ class BinariesCheck(AbstractCheck):
         """
         if not self.is_shobj and not self.is_pie_exec:
             if any(regex.fullmatch(bin_name) for regex in self.pie_exec_regex_list):
-                self.output.add_info('E', pkg,
-                                     'non-position-independent-executable',
-                                     bin_name)
+                self.output.add_info(
+                    "E", pkg, "non-position-independent-executable", bin_name
+                )
             else:
-                self.output.add_info('W', pkg,
-                                     'position-independent-executable-suggested',
-                                     bin_name)
+                self.output.add_info(
+                    "W", pkg, "position-independent-executable-suggested", bin_name
+                )
 
     def _check_exec_in_library(self, pkg, has_lib, exec_files):
         """
@@ -188,7 +203,7 @@ class BinariesCheck(AbstractCheck):
         """
         if has_lib:
             for f in exec_files:
-                self.output.add_info('E', pkg, 'executable-in-library-package', f)
+                self.output.add_info("E", pkg, "executable-in-library-package", f)
 
     def _check_non_versioned(self, pkg, has_lib, exec_files):
         """
@@ -201,9 +216,14 @@ class BinariesCheck(AbstractCheck):
             for f in pkg.files:
                 res = self.numeric_dir_regex.search(f)
                 fn = res and res.group(1) or f
-                if f not in exec_files and not self.so_regex.search(f) and \
-                        not self.versioned_dir_regex.search(fn):
-                    self.output.add_info('E', pkg, 'non-versioned-file-in-library-package', f)
+                if (
+                    f not in exec_files
+                    and not self.so_regex.search(f)
+                    and not self.versioned_dir_regex.search(fn)
+                ):
+                    self.output.add_info(
+                        "E", pkg, "non-versioned-file-in-library-package", f
+                    )
 
     def _check_no_binary(self, pkg, has_binary, has_file_in_lib64):
         """
@@ -211,19 +231,20 @@ class BinariesCheck(AbstractCheck):
 
         Print an error if there is no binary and it's not noarch.
         """
-        if not has_binary and not has_file_in_lib64 and \
-                pkg.arch != 'noarch':
-            self.output.add_info('E', pkg, 'no-binary')
+        if not has_binary and not has_file_in_lib64 and pkg.arch != "noarch":
+            self.output.add_info("E", pkg, "no-binary")
 
     def _check_noarch_with_lib64(self, pkg, has_file_in_lib64):
         """
         Print an error if we have a noarch package that contains a file
         in /usr/lib64.
         """
-        if pkg.arch == 'noarch' and has_file_in_lib64:
-            self.output.add_info('E', pkg, 'noarch-with-lib64')
+        if pkg.arch == "noarch" and has_file_in_lib64:
+            self.output.add_info("E", pkg, "noarch-with-lib64")
 
-    def _check_only_non_binary_in_usrlib(self, pkg, has_usr_lib_file, has_binary_in_usr_lib):
+    def _check_only_non_binary_in_usrlib(
+        self, pkg, has_usr_lib_file, has_binary_in_usr_lib
+    ):
         """
         Check and print a warning if we have _only_ non-binary files in the
         '/usr/lib'.
@@ -232,7 +253,7 @@ class BinariesCheck(AbstractCheck):
         are considered binaries.
         """
         if has_usr_lib_file and not has_binary_in_usr_lib:
-            self.output.add_info('W', pkg, 'only-non-binary-in-usr-lib')
+            self.output.add_info("W", pkg, "only-non-binary-in-usr-lib")
 
     def _check_no_text_in_archive(self, pkg, pkgfile):
         """
@@ -240,25 +261,29 @@ class BinariesCheck(AbstractCheck):
         """
         if self.is_archive:
             for comment in self.readelf_parser.comment_section_info.comments:
-                if comment.startswith('GHC '):
+                if comment.startswith("GHC "):
                     return
 
             # Starting with glibc 2.34, some static libraries were moved to libc
             # and there are empty archives for backward compatibility. Skip these
             # libraries.
             stem = Path(pkgfile.name).stem
-            if stem in GLIBC_EMPTY_ARCHIVES or (stem.endswith('_p') and stem[:-2] in GLIBC_EMPTY_ARCHIVES):
+            if stem in GLIBC_EMPTY_ARCHIVES or (
+                stem.endswith("_p") and stem[:-2] in GLIBC_EMPTY_ARCHIVES
+            ):
                 return
 
             for elf_file in self.readelf_parser.section_info.elf_files:
                 for section in elf_file:
                     sn = section.name
-                    if ((sn in self.lto_text_like_sections or
-                         sn == '.fini_array' or sn.startswith('.text') or
-                         sn.startswith('.data')) and
-                            section.size > 0):
+                    if (
+                        sn in self.lto_text_like_sections
+                        or sn == ".fini_array"
+                        or sn.startswith(".text")
+                        or sn.startswith(".data")
+                    ) and section.size > 0:
                         return
-            self.output.add_info('E', pkg, 'lto-no-text-in-archive', pkgfile.name)
+            self.output.add_info("E", pkg, "lto-no-text-in-archive", pkgfile.name)
             return
 
     def _check_no_patchable_function_entries_in_archive(self, pkg, pkgfile):
@@ -269,8 +294,13 @@ class BinariesCheck(AbstractCheck):
         if self.is_archive:
             for elf_file in self.readelf_parser.section_info.elf_files:
                 for section in elf_file:
-                    if section.name == '__patchable_function_entries':
-                        self.output.add_info('E', pkg, 'patchable-function-entry-in-archive', pkgfile.name)
+                    if section.name == "__patchable_function_entries":
+                        self.output.add_info(
+                            "E",
+                            pkg,
+                            "patchable-function-entry-in-archive",
+                            pkgfile.name,
+                        )
                         return
 
     def _check_missing_symtab_in_archive(self, pkg, pkgfile):
@@ -280,25 +310,29 @@ class BinariesCheck(AbstractCheck):
         if self.is_archive:
             for elf_file in self.readelf_parser.section_info.elf_files:
                 for section in elf_file:
-                    if section.name == '.symtab':
+                    if section.name == ".symtab":
                         return
 
-            self.output.add_info('E', pkg, 'static-library-without-symtab', pkgfile.name)
+            self.output.add_info(
+                "E", pkg, "static-library-without-symtab", pkgfile.name
+            )
 
     def _check_missing_debug_info_in_archive(self, pkg, pkgfile):
         if self.is_archive:
             for elf_file in self.readelf_parser.section_info.elf_files:
                 for section in elf_file:
-                    if section.name.startswith('.debug_'):
+                    if section.name.startswith(".debug_"):
                         return
-            self.output.add_info('E', pkg, 'static-library-without-debuginfo', pkgfile.name)
+            self.output.add_info(
+                "E", pkg, "static-library-without-debuginfo", pkgfile.name
+            )
 
     # Check for LTO sections
     def _check_lto_section(self, pkg, pkgfile):
         for elf_file in self.readelf_parser.section_info.elf_files:
             for section in elf_file:
-                if '.gnu.lto_.' in section.name:
-                    self.output.add_info('E', pkg, 'lto-bytecode', pkgfile.name)
+                if ".gnu.lto_." in section.name:
+                    self.output.add_info("E", pkg, "lto-bytecode", pkgfile.name)
                     return
 
     def _check_executable_stack(self, pkg, pkgfile):
@@ -311,12 +345,20 @@ class BinariesCheck(AbstractCheck):
             return
 
         # Do not check kernel modules and archives
-        if not self.is_archive and not any(pkgfile.name.startswith(p) for p in KERNEL_MODULES_PATHS):
-            stack_headers = [h for h in self.readelf_parser.program_header_info.headers if h.name == 'GNU_STACK']
+        if not self.is_archive and not any(
+            pkgfile.name.startswith(p) for p in KERNEL_MODULES_PATHS
+        ):
+            stack_headers = [
+                h
+                for h in self.readelf_parser.program_header_info.headers
+                if h.name == "GNU_STACK"
+            ]
             if not stack_headers:
-                self.output.add_info('E', pkg, 'missing-PT_GNU_STACK-section', pkgfile.name)
-            elif 'E' in stack_headers[0].flags:
-                self.output.add_info('E', pkg, 'executable-stack', pkgfile.name)
+                self.output.add_info(
+                    "E", pkg, "missing-PT_GNU_STACK-section", pkgfile.name
+                )
+            elif "E" in stack_headers[0].flags:
+                self.output.add_info("E", pkg, "executable-stack", pkgfile.name)
 
     def _check_soname_symlink(self, pkg, shlib, soname):
         """
@@ -328,14 +370,13 @@ class BinariesCheck(AbstractCheck):
         path = Path(shlib)
         symlink = path.parent / soname
         try:
-
             link = pkg.files[str(symlink)].linkto
-            if link not in (shlib, path.name, ''):
-                self.output.add_info('E', pkg, 'invalid-ldconfig-symlink', shlib, link)
+            if link not in (shlib, path.name, ""):
+                self.output.add_info("E", pkg, "invalid-ldconfig-symlink", shlib, link)
         except KeyError:
             # if we do not have a symlink, report an issue
-            if path.name.startswith('lib') or path.name.startswith('ld-'):
-                self.output.add_info('E', pkg, 'no-ldconfig-symlink', shlib)
+            if path.name.startswith("lib") or path.name.startswith("ld-"):
+                self.output.add_info("E", pkg, "no-ldconfig-symlink", shlib)
 
     def _check_shared_library(self, pkg, pkgfile):
         """
@@ -353,35 +394,45 @@ class BinariesCheck(AbstractCheck):
 
         soname = self.readelf_parser.dynamic_section_info.soname
         if not soname:
-            self.output.add_info('W', pkg, 'no-soname', pkgfile.name)
+            self.output.add_info("W", pkg, "no-soname", pkgfile.name)
         else:
             if not self.validso_regex.search(soname):
-                self.output.add_info('E', pkg, 'invalid-soname', pkgfile.name, soname)
+                self.output.add_info("E", pkg, "invalid-soname", pkgfile.name, soname)
             else:
                 self._check_soname_symlink(pkg, pkgfile.name, soname)
 
                 # check if the major version of the library is in the package
                 # name (check only for lib* packages)
                 # for now skip all HPC libraries (#901)
-                if pkg.name.startswith('lib') and not pkgfile.name.startswith(self.hpc_locations):
+                if pkg.name.startswith("lib") and not pkgfile.name.startswith(
+                    self.hpc_locations
+                ):
                     # SLPP is defined here: https://en.opensuse.org/openSUSE:Shared_library_packaging_policy#Package_naming
                     # Example:
                     # SONAME = libgame2-1.9.so.10.0.0
                     # expected package name: libgame2-1_9-10_0_0
                     res = self.soversion_regex.search(soname)
                     if res:
-                        parts = [x.replace('.', '_') for x in (res.group('pkgversion'), res.group('soversion')) if x]
-                        soversion = '-'.join(parts)
+                        parts = [
+                            x.replace(".", "_")
+                            for x in (res.group("pkgversion"), res.group("soversion"))
+                            if x
+                        ]
+                        soversion = "-".join(parts)
                         pkgname = pkg.name
-                        if '.' in pkgname:
-                            pkgname = pkgname[:pkgname.rindex('.')]
+                        if "." in pkgname:
+                            pkgname = pkgname[: pkgname.rindex(".")]
                         if soversion and not pkgname.endswith(soversion):
-                            self.output.add_info('E', pkg, 'shlib-policy-name-error',
-                                                 f'SONAME: {soname} ({pkgfile.name}), expected package suffix: {soversion}')
+                            self.output.add_info(
+                                "E",
+                                pkg,
+                                "shlib-policy-name-error",
+                                f"SONAME: {soname} ({pkgfile.name}), expected package suffix: {soversion}",
+                            )
 
         # check if the object code in the library is compiled with PIC
-        if self.readelf_parser.dynamic_section_info['TEXTREL']:
-            self.output.add_info('E', pkg, 'shlib-with-non-pic-code', pkgfile.name)
+        if self.readelf_parser.dynamic_section_info["TEXTREL"]:
+            self.output.add_info("E", pkg, "shlib-with-non-pic-code", pkgfile.name)
 
     def _check_dependency(self, pkg, pkgfile):
         """
@@ -400,12 +451,19 @@ class BinariesCheck(AbstractCheck):
             return
 
         if not self.is_archive and not self.readelf_parser.is_debug:
-            info_type = 'E' if self.readelf_parser.is_shlib else 'W'
+            info_type = "E" if self.readelf_parser.is_shlib else "W"
             for symbol in self.ldd_parser.undefined_symbols:
-                self.output.add_info(info_type, pkg, 'undefined-non-weak-symbol', pkgfile.name, symbol)
+                self.output.add_info(
+                    info_type, pkg, "undefined-non-weak-symbol", pkgfile.name, symbol
+                )
             for dependency in self.ldd_parser.unused_dependencies:
-                self.output.add_info(info_type, pkg, 'unused-direct-shlib-dependency',
-                                     pkgfile.name, dependency)
+                self.output.add_info(
+                    info_type,
+                    pkg,
+                    "unused-direct-shlib-dependency",
+                    pkgfile.name,
+                    dependency,
+                )
 
     def _check_library_dependency_location(self, pkg, pkgfile):
         """
@@ -416,82 +474,138 @@ class BinariesCheck(AbstractCheck):
 
         if not self.is_archive:
             for dependency in self.ldd_parser.dependencies:
-                if dependency.startswith('/opt/'):
-                    self.output.add_info('E', pkg, 'linked-against-opt-library', pkgfile.name, dependency)
+                if dependency.startswith("/opt/"):
+                    self.output.add_info(
+                        "E", pkg, "linked-against-opt-library", pkgfile.name, dependency
+                    )
                     break
 
-        nonusr = ('/bin', '/lib', '/sbin')
+        nonusr = ("/bin", "/lib", "/sbin")
         if pkgfile.name.startswith(nonusr):
             for dependency in self.ldd_parser.dependencies:
-                if dependency.startswith('/usr/'):
-                    self.output.add_info('W', pkg, 'linked-against-usr-library', pkgfile.name, dependency)
+                if dependency.startswith("/usr/"):
+                    self.output.add_info(
+                        "W", pkg, "linked-against-usr-library", pkgfile.name, dependency
+                    )
                     break
 
     def _check_security_functions(self, pkg, pkgfile):
-        setgid = any(self.readelf_parser.symbol_table_info.get_functions_for_regex(self.setgid_call_regex))
-        setuid = any(self.readelf_parser.symbol_table_info.get_functions_for_regex(self.setuid_call_regex))
-        setgroups = any(self.readelf_parser.symbol_table_info.get_functions_for_regex(self.setgroups_call_regex))
-        mktemp = any(self.readelf_parser.symbol_table_info.get_functions_for_regex(self.mktemp_call_regex))
-        gethostbyname = any(self.readelf_parser.symbol_table_info.get_functions_for_regex(self.gethostbyname_call_regex))
-
+        setgid = any(
+            self.readelf_parser.symbol_table_info.get_functions_for_regex(
+                self.setgid_call_regex
+            )
+        )
+        setuid = any(
+            self.readelf_parser.symbol_table_info.get_functions_for_regex(
+                self.setuid_call_regex
+            )
+        )
+        setgroups = any(
+            self.readelf_parser.symbol_table_info.get_functions_for_regex(
+                self.setgroups_call_regex
+            )
+        )
+        mktemp = any(
+            self.readelf_parser.symbol_table_info.get_functions_for_regex(
+                self.mktemp_call_regex
+            )
+        )
+        gethostbyname = any(
+            self.readelf_parser.symbol_table_info.get_functions_for_regex(
+                self.gethostbyname_call_regex
+            )
+        )
+
+        self.output.add_info("I", pkg, f"setgid {setgid}", pkgfile.name)
+        self.output.add_info("I", pkg, f"setuid {setuid}", pkgfile.name)
+        self.output.add_info("I", pkg, f"setgroups {setgroups}", pkgfile.name)
         if setgid and setuid and not setgroups:
             is_uid = stat.S_ISUID & pkgfile.mode
-            self.output.add_info('W' if is_uid else 'E', pkg, 'missing-call-to-setgroups-before-setuid', pkgfile.name)
+            self.output.add_info(
+                "W" if is_uid else "E",
+                pkg,
+                "missing-call-to-setgroups-before-setuid",
+                pkgfile.name,
+            )
 
         if mktemp:
-            self.output.add_info('E', pkg, 'call-to-mktemp', pkgfile.name)
+            self.output.add_info("E", pkg, "call-to-mktemp", pkgfile.name)
 
         if gethostbyname:
-            self.output.add_info('W', pkg, 'binary-or-shlib-calls-gethostbyname', pkgfile.name)
+            self.output.add_info(
+                "W", pkg, "binary-or-shlib-calls-gethostbyname", pkgfile.name
+            )
 
     def _check_rpath(self, pkg, pkgfile):
         for runpaths in self.readelf_parser.dynamic_section_info.runpaths:
-            for runpath in runpaths.split(':'):
+            for runpath in runpaths.split(":"):
                 if self.rpath_origin in runpath:
-                    runpath = runpath.replace(self.rpath_origin, str(Path(pkgfile.name).parent))
+                    runpath = runpath.replace(
+                        self.rpath_origin, str(Path(pkgfile.name).parent)
+                    )
                     runpath = str(Path(runpath).resolve())
-                if not runpath.startswith(self.system_lib_paths) and not self.usr_lib_regex.search(runpath):
-                    self.output.add_info('E', pkg, 'binary-or-shlib-defines-rpath', pkgfile.name, f'(RUNPATH: {runpaths})')
+                if not runpath.startswith(
+                    self.system_lib_paths
+                ) and not self.usr_lib_regex.search(runpath):
+                    self.output.add_info(
+                        "E",
+                        pkg,
+                        "binary-or-shlib-defines-rpath",
+                        pkgfile.name,
+                        f"(RUNPATH: {runpaths})",
+                    )
                     return
 
     def _check_library_dependency(self, pkg, pkgfile):
-        if (self.is_archive or
-                any(pkgfile.name.startswith(p) for p in KERNEL_MODULES_PATHS) or
-                self.python_module_regex.fullmatch(pkgfile.name)):
+        if (
+            self.is_archive
+            or any(pkgfile.name.startswith(p) for p in KERNEL_MODULES_PATHS)
+            or self.python_module_regex.fullmatch(pkgfile.name)
+        ):
             return
 
         dyn_section = self.readelf_parser.dynamic_section_info
-        if not len(dyn_section.needed) and not (dyn_section.soname and
-                                                self.ldso_soname_regex.search(dyn_section.soname)):
+        if not len(dyn_section.needed) and not (
+            dyn_section.soname and self.ldso_soname_regex.search(dyn_section.soname)
+        ):
             if not self.is_shobj:
-                self.output.add_info('E', pkg, 'statically-linked-binary', pkgfile.name)
+                self.output.add_info("E", pkg, "statically-linked-binary", pkgfile.name)
         else:
             # linked against libc ?
-            if 'libc.' not in dyn_section.runpaths and \
-               (not dyn_section.soname or
-                ('libc.' not in dyn_section.soname and
-                 not self.ldso_soname_regex.search(dyn_section.soname))):
+            if "libc." not in dyn_section.runpaths and (
+                not dyn_section.soname
+                or (
+                    "libc." not in dyn_section.soname
+                    and not self.ldso_soname_regex.search(dyn_section.soname)
+                )
+            ):
                 for lib in dyn_section.needed:
-                    if 'libc.' in lib:
+                    if "libc." in lib:
                         return
                 if not self.is_shobj:
-                    self.output.add_info('W', pkg, 'program-not-linked-against-libc', pkgfile.name)
+                    self.output.add_info(
+                        "W", pkg, "program-not-linked-against-libc", pkgfile.name
+                    )
 
     def _check_forbidden_functions(self, pkg, pkgfile):
-        forbidden_functions = self.config.configuration['WarnOnFunction']
+        forbidden_functions = self.config.configuration["WarnOnFunction"]
         if forbidden_functions:
             for name, func in forbidden_functions.items():
                 # precompile regexps
-                f_name = func['f_name']
-                func['f_regex'] = self.create_nonlibc_regexp_call(f_name)
-                if 'good_param' in func and func['good_param']:
-                    func['waiver_regex'] = re.compile(func['good_param'])
+                f_name = func["f_name"]
+                func["f_regex"] = self.create_nonlibc_regexp_call(f_name)
+                if "good_param" in func and func["good_param"]:
+                    func["waiver_regex"] = re.compile(func["good_param"])
                 # register descriptions
-                self.output.error_details.update({name: func['description']})
+                self.output.error_details.update({name: func["description"]})
 
         forbidden_calls = []
         for r_name, func in forbidden_functions.items():
-            if any(self.readelf_parser.symbol_table_info.get_functions_for_regex(func['f_regex'])):
+            if any(
+                self.readelf_parser.symbol_table_info.get_functions_for_regex(
+                    func["f_regex"]
+                )
+            ):
                 forbidden_calls.append(r_name)
 
         if not forbidden_calls:
@@ -500,67 +614,83 @@ class BinariesCheck(AbstractCheck):
         strings_parser = StringsParser(pkgfile.path)
         failed_reason = strings_parser.parsing_failed_reason
         if failed_reason:
-            self.output.add_info('E', pkg, 'strings-failed', pkgfile.name, failed_reason)
+            self.output.add_info(
+                "E", pkg, "strings-failed", pkgfile.name, failed_reason
+            )
             return
 
         forbidden_functions_filtered = []
 
         for fn in forbidden_calls:
             f = forbidden_functions[fn]
-            if 'waiver_regex' not in f:
+            if "waiver_regex" not in f:
                 forbidden_functions_filtered.append(fn)
                 continue
 
             # See: https://github.com/PyCQA/flake8-bugbear/issues/269
-            waiver = any(f['waiver_regex'].search(string) for string in strings_parser.strings)
+            waiver = any(
+                f["waiver_regex"].search(string) for string in strings_parser.strings
+            )
             if not waiver:
                 forbidden_functions_filtered.append(fn)
 
         for fn in forbidden_functions_filtered:
-            self.output.add_info('W', pkg, fn, pkgfile.name, forbidden_functions[fn]['f_name'])
+            self.output.add_info(
+                "W", pkg, fn, pkgfile.name, forbidden_functions[fn]["f_name"]
+            )
 
     def _check_executable_shlib(self, pkg, pkgfile):
         if not (pkgfile.mode & stat.S_IEXEC) and self.readelf_parser.is_shlib:
-            self.output.add_info('E', pkg, 'shared-library-not-executable', pkgfile.name)
+            self.output.add_info(
+                "E", pkg, "shared-library-not-executable", pkgfile.name
+            )
 
     def _check_optflags(self, pkg, pkgfile):
         if self.is_archive:
             return
 
-        mandatory_optflags = self.config.configuration['MandatoryOptflags']
-        forbidden_optflags = self.config.configuration['ForbiddenOptflags']
+        mandatory_optflags = self.config.configuration["MandatoryOptflags"]
+        forbidden_optflags = self.config.configuration["ForbiddenOptflags"]
         if not mandatory_optflags and not forbidden_optflags:
             return
 
         for dwarf_unit in self.objdump_parser.compile_units:
-            tokens = dwarf_unit['producer'].split(' ')
+            tokens = dwarf_unit["producer"].split(" ")
             missing = [mo for mo in mandatory_optflags if mo not in tokens]
             forbidden = [f for f in forbidden_optflags if f in tokens]
             if missing:
-                self.output.add_info('W', pkg, 'missing-mandatory-optflags', pkgfile.name, ' '.join(missing))
+                self.output.add_info(
+                    "W",
+                    pkg,
+                    "missing-mandatory-optflags",
+                    pkgfile.name,
+                    " ".join(missing),
+                )
             if forbidden:
-                self.output.add_info('E', pkg, 'forbidden-optflags', pkgfile.name, ' '.join(forbidden))
+                self.output.add_info(
+                    "E", pkg, "forbidden-optflags", pkgfile.name, " ".join(forbidden)
+                )
 
     def _check_hash_sections(self, pkg, pkgfile):
         if not self.readelf_parser.is_shlib:
             return
 
         for elf_file in self.readelf_parser.section_info.elf_files:
-            needle = {'.hash', '.gnu.hash'}
+            needle = {".hash", ".gnu.hash"}
             for section in elf_file:
                 if not needle:
                     break
                 if section.name in needle:
                     needle.remove(section.name)
 
-            if '.hash' in needle:
-                self.output.add_info('E', pkg, 'missing-hash-section', pkgfile.name)
-            if '.gnu.hash' in needle:
-                self.output.add_info('W', pkg, 'missing-gnu-hash-section', pkgfile.name)
+            if ".hash" in needle:
+                self.output.add_info("E", pkg, "missing-hash-section", pkgfile.name)
+            if ".gnu.hash" in needle:
+                self.output.add_info("W", pkg, "missing-gnu-hash-section", pkgfile.name)
 
     def _is_standard_archive(self, pkg, pkgfile):
         # skip Klee bytecode archives
-        if pkgfile.path.endswith('.bca'):
+        if pkgfile.path.endswith(".bca"):
             return False
 
         # return false for e.g. Rust or Go packages that are archives
@@ -568,18 +698,18 @@ class BinariesCheck(AbstractCheck):
         ar_parser = ArParser(pkgfile.path)
         failed_reason = ar_parser.parsing_failed_reason
         if failed_reason:
-            self.output.add_info('E', pkg, 'ar-failed', pkgfile.name, failed_reason)
+            self.output.add_info("E", pkg, "ar-failed", pkgfile.name, failed_reason)
             return False
 
-        needles = ('__.PKGDEF', '_go_.o', 'lib.rmeta')
+        needles = ("__.PKGDEF", "_go_.o", "lib.rmeta")
         return not any(needle for needle in needles if needle in ar_parser.objects)
 
     def _detect_attributes(self, magic):
-        self.is_exec = 'executable' in magic
-        self.is_shobj = 'shared object' in magic
-        self.is_archive = 'current ar archive' in magic
-        self.is_dynamically_linked = 'dynamically linked' in magic
-        self.is_pie_exec = 'pie executable' in magic
+        self.is_exec = "executable" in magic
+        self.is_shobj = "shared object" in magic
+        self.is_archive = "current ar archive" in magic
+        self.is_dynamically_linked = "dynamically linked" in magic
+        self.is_pie_exec = "pie executable" in magic
         self.is_nonstandard_archive = False
 
     def run_elf_checks(self, pkg, pkgfile):
@@ -590,24 +720,34 @@ class BinariesCheck(AbstractCheck):
         self.readelf_parser = ReadelfParser(pkgfile.path, pkgfile.name)
         failed_reason = self.readelf_parser.parsing_failed_reason()
         if failed_reason:
-            self.output.add_info('E', pkg, 'readelf-failed', pkgfile.name, failed_reason)
+            self.output.add_info(
+                "E", pkg, "readelf-failed", pkgfile.name, failed_reason
+            )
             return
 
         if not self.is_archive:
             if self.is_dynamically_linked:
                 is_installed_pkg = isinstance(pkg, (InstalledPkg, FakePkg))
-                self.ldd_parser = LddParser(pkgfile.path, pkgfile.name, is_installed_pkg)
+                self.ldd_parser = LddParser(
+                    pkgfile.path, pkgfile.name, is_installed_pkg
+                )
                 failed_reason = self.ldd_parser.parsing_failed_reason
                 if failed_reason:
-                    self.output.add_info('E', pkg, 'ldd-failed', pkgfile.name, failed_reason)
+                    self.output.add_info(
+                        "E", pkg, "ldd-failed", pkgfile.name, failed_reason
+                    )
                     return
 
-            if (self.config.configuration['MandatoryOptflags'] or
-                    self.config.configuration['ForbiddenOptflags']):
+            if (
+                self.config.configuration["MandatoryOptflags"]
+                or self.config.configuration["ForbiddenOptflags"]
+            ):
                 self.objdump_parser = ObjdumpParser(pkgfile.path, pkgfile.name)
                 failed_reason = self.objdump_parser.parsing_failed_reason
                 if failed_reason:
-                    self.output.add_info('E', pkg, 'objdump-failed', pkgfile.name, failed_reason)
+                    self.output.add_info(
+                        "E", pkg, "objdump-failed", pkgfile.name, failed_reason
+                    )
                     return
 
         # NOTE: the speed benefit of the ThreadPoolExecutor is limited due to
@@ -642,31 +782,35 @@ class BinariesCheck(AbstractCheck):
             # do not throw 'only-non-binary-in-usr-lib' warning then
             if not stat.S_ISDIR(pkgfile.mode) and self.usr_lib_regex.search(fname):
                 pkg_has_usrlib_file = True
-                if not pkg_has_binary_in_usrlib and \
-                        self.usr_lib_exception_regex.search(fname):
+                if not pkg_has_binary_in_usrlib and self.usr_lib_exception_regex.search(
+                    fname
+                ):
                     # Fake that we have binaries there to avoid
                     # only-non-binary-in-usr-lib false positives
                     pkg_has_binary_in_usrlib = True
 
             # find out if we have a file in /usr/lib64/ directory (needed later
             # for the package checks)
-            if fname.startswith(('/usr/lib64', '/lib64')):
+            if fname.startswith(("/usr/lib64", "/lib64")):
                 pkg_has_file_in_lib64 = True
 
             # skip the rest of the tests for non-binaries
             # binary files only from here on
-            is_ocaml_native = 'Objective caml native' in pkgfile.magic
-            is_lua_bytecode = 'Lua bytecode' in pkgfile.magic
+            is_ocaml_native = "Objective caml native" in pkgfile.magic
+            is_lua_bytecode = "Lua bytecode" in pkgfile.magic
             #  eBPF binaries are arch independent
             # https://github.com/rpm-software-management/rpmlint/issues/1193
-            is_ebpf = 'eBPF' in pkgfile.magic
+            is_ebpf = "eBPF" in pkgfile.magic
             # Look for ELF in the file magic to check if it's really a binary
             # file
             is_elf = self.elf_regex.match(pkgfile.magic) and not is_ebpf
 
-            if not (is_elf or
-                    'current ar archive' in pkgfile.magic or
-                    is_ocaml_native or is_lua_bytecode):
+            if not (
+                is_elf
+                or "current ar archive" in pkgfile.magic
+                or is_ocaml_native
+                or is_lua_bytecode
+            ):
                 continue
 
             self.checked_files += 1
@@ -676,15 +820,18 @@ class BinariesCheck(AbstractCheck):
 
             # if there is a binary in /usr/lib then mark this package
             # accordingly
-            if pkg_has_usrlib_file and not pkg_has_binary_in_usrlib and \
-                    self.usr_lib_regex.search(fname):
+            if (
+                pkg_has_usrlib_file
+                and not pkg_has_binary_in_usrlib
+                and self.usr_lib_regex.search(fname)
+            ):
                 pkg_has_binary_in_usrlib = True
 
             self._check_binary_in_noarch(pkg, fname)
 
             # skip the rest of the tests for noarch packages
             # arch dependent packages only from here on
-            if pkg.arch == 'noarch':
+            if pkg.arch == "noarch":
                 continue
 
             self._check_binary_in_usr_share(pkg, fname)
@@ -692,9 +839,14 @@ class BinariesCheck(AbstractCheck):
 
             # skip the rest of the tests for ocaml native, Lua bytecode,
             # Go .go and .gox, .o and .static
-            if is_ocaml_native or is_lua_bytecode or fname.endswith('.o') or \
-                    fname.endswith('.static') or fname.endswith('.gox') or \
-                    fname.endswith('.go'):
+            if (
+                is_ocaml_native
+                or is_lua_bytecode
+                or fname.endswith(".o")
+                or fname.endswith(".static")
+                or fname.endswith(".gox")
+                or fname.endswith(".go")
+            ):
                 continue
 
             self._check_unstripped_binary(fname, pkg, pkgfile)
@@ -719,8 +871,12 @@ class BinariesCheck(AbstractCheck):
             if not self.is_exec and not self.is_shobj:
                 continue
 
-            if self.is_shobj and not self.is_exec and '.so' not in fname and \
-                    self.bin_regex.search(fname):
+            if (
+                self.is_shobj
+                and not self.is_exec
+                and ".so" not in fname
+                and self.bin_regex.search(fname)
+            ):
                 # pkgfile.magic does not contain 'executable' for PIEs
                 self.is_exec = True
 
@@ -737,5 +893,6 @@ class BinariesCheck(AbstractCheck):
         self._check_non_versioned(pkg, pkg_has_lib, exec_files)
         self._check_no_binary(pkg, pkg_has_binary, pkg_has_file_in_lib64)
         self._check_noarch_with_lib64(pkg, pkg_has_file_in_lib64)
-        self._check_only_non_binary_in_usrlib(pkg, pkg_has_usrlib_file,
-                                              pkg_has_binary_in_usrlib)
+        self._check_only_non_binary_in_usrlib(
+            pkg, pkg_has_usrlib_file, pkg_has_binary_in_usrlib
+        )
-- 
2.47.1

openSUSE Build Service is sponsored by