Exemplo n.º 1
0
    def check_url(self, pkg, tag, url):
        """
        Check that URL points to something that seems to exist.
        Return info() of the response if available.
        """
        if not self.network_enabled:
            if self.verbose:
                printInfo(pkg, 'network-checks-disabled', url)
            return

        if self.verbose:
            printInfo(pkg, 'checking-url', url,
                      '(timeout %s seconds)' % self.network_timeout)

        res = None
        try:
            opener = urllib.request.build_opener(_HeadRedirectHandler())
            opener.addheaders = [('User-Agent', 'rpmlint/%s' % __version__)]
            res = opener.open(_HeadRequest(url), timeout=self.network_timeout)
        except Exception as e:
            errstr = str(e) or repr(e) or type(e)
            printWarning(pkg, 'invalid-url', '%s:' % tag, url, errstr)
        info = None
        if res:
            with contextlib.closing(res):
                info = res.info()
        return info
Exemplo n.º 2
0
def runSpecChecks(pkg, fname, spec_lines=None):

    if verbose:
        printInfo(pkg, 'checking')

    for name in Config.allChecks():
        check = AbstractCheck.known_checks.get(name)
        if check:
            check.verbose = verbose
            check.check_spec(pkg, fname, spec_lines)
        else:
            Pkg.warn('(none): W: unknown check %s, skipping' % name)
Exemplo n.º 3
0
def spell_check(pkg, str, fmt, lang, ignored):

    dict_found = True
    warned = set()
    if enchant:
        if lang == 'C':
            lang = 'en_US'

        checker = _enchant_checkers.get(lang)
        if not checker and lang not in _enchant_checkers:
            try:
                checker = enchant.checker.SpellChecker(
                    lang,
                    filters=[
                        enchant.tokenize.EmailFilter,
                        enchant.tokenize.URLFilter,
                        enchant.tokenize.WikiWordFilter
                    ])
            except enchant.DictNotFoundError:
                printInfo(pkg, 'enchant-dictionary-not-found', lang)
                pass
            _enchant_checkers[lang] = checker

        if checker:
            # squeeze whitespace to ease leading context check
            checker.set_text(re.sub(r'\s+', ' ', str))
            if use_utf8:
                uppername = Pkg.to_unicode(pkg.header[rpm.RPMTAG_NAME]).upper()
            else:
                uppername = pkg.name.upper()
            upperparts = uppername.split('-')
            if lang.startswith('en'):
                ups = [x + "'S" for x in upperparts]
                upperparts.extend(ups)
            for err in checker:

                # Skip already warned and ignored words
                if err.word in warned or err.word in ignored:
                    continue

                # Skip all capitalized words that do not start a sentence
                if err.word[0].isupper() and not \
                        sentence_break_regex.search(checker.leading_context(3)):
                    continue

                upperword = err.word.upper()

                # Skip all uppercase words
                if err.word == upperword:
                    continue

                # Skip errors containing package name or equal to a
                # "component" of it, case insensitively
                if uppername in upperword or upperword in upperparts:
                    continue

                # Work around enchant's digit tokenizing behavior:
                # http://github.com/rfk/pyenchant/issues/issue/3
                if checker.leading_context(1).isdigit() or \
                        checker.trailing_context(1).isdigit():
                    continue

                # Warn and suggest
                sug = ', '.join(checker.suggest()[:3])
                if sug:
                    sug = '-> %s' % sug
                printWarning(pkg, 'spelling-error', fmt % lang, err.word, sug)
                warned.add(err.word)

        else:
            dict_found = False

    if not enchant or not dict_found:
        for seq in str.split():
            for word in re.split(r'[^a-z]+', seq.lower()):
                if len(word) == 0:
                    continue
                correct = BAD_WORDS.get(word)
                if not correct:
                    continue
                if word[0] == '\'':
                    word = word[1:]
                if word[-1] == '\'':
                    word = word[:-1]
                if word in warned or word in ignored:
                    continue
                printWarning(pkg, 'spelling-error', fmt % lang, word, '->',
                             correct)
                warned.add(word)
Exemplo n.º 4
0
    def check_binary(self, pkg):
        files = pkg.files()
        menus = []

        for fname, pkgfile in files.items():
            # Check menu files
            res = menu_file_regex.search(fname)
            mode = pkgfile.mode
            if res:
                basename = res.group(1)
                if not stat.S_ISREG(mode):
                    printError(pkg, 'non-file-in-menu-dir', fname)
                else:
                    if basename != pkg.name:
                        printWarning(pkg, 'non-coherent-menu-filename', fname)
                    if mode & 0o444 != 0o444:
                        printError(pkg, 'non-readable-menu-file', fname)
                    if mode & 0o111:
                        printError(pkg, 'executable-menu-file', fname)
                    menus.append(fname)
            else:
                # Check old menus from KDE and GNOME
                res = old_menu_file_regex.search(fname)
                if res:
                    if stat.S_ISREG(mode):
                        printError(pkg, 'old-menu-entry', fname)
                else:
                    # Check non transparent xpm files
                    res = xpm_ext_regex.search(fname)
                    if res:
                        if stat.S_ISREG(mode) and not pkg.grep(
                                'None",', fname):
                            printWarning(pkg, 'non-transparent-xpm', fname)
                if fname.startswith('/usr/lib64/menu'):
                    printError(pkg, 'menu-in-wrong-dir', fname)

        if menus:
            postin = pkg[rpm.RPMTAG_POSTIN] or \
                pkg.scriptprog(rpm.RPMTAG_POSTINPROG)
            if not postin:
                printError(pkg, 'menu-without-postin')
            elif not update_menus_regex.search(postin):
                printError(pkg, 'postin-without-update-menus')

            postun = pkg[rpm.RPMTAG_POSTUN] or \
                pkg.scriptprog(rpm.RPMTAG_POSTUNPROG)
            if not postun:
                printError(pkg, 'menu-without-postun')
            elif not update_menus_regex.search(postun):
                printError(pkg, 'postun-without-update-menus')

            directory = pkg.dirName()
            for f in menus:
                # remove comments and handle cpp continuation lines
                cmd = Pkg.getstatusoutput(('/lib/cpp', directory + f), True)[1]

                for line in cmd.splitlines():
                    if not line.startswith('?'):
                        continue
                    res = package_regex.search(line)
                    if res:
                        package = res.group(1)
                        if package != pkg.name:
                            printWarning(pkg,
                                         'incoherent-package-value-in-menu',
                                         package, f)
                    else:
                        printInfo(pkg, 'unable-to-parse-menu-entry', line)

                    command = True
                    res = command_regex.search(line)
                    if res:
                        command_line = (res.group(1) or res.group(2)).split()
                        command = command_line[0]
                        for launcher in launchers:
                            if not launcher[0].search(command):
                                continue
                            found = False
                            if launcher[1]:
                                found = '/bin/' + command_line[0] in files or \
                                    '/usr/bin/' + command_line[0] in files or \
                                    '/usr/X11R6/bin/' + command_line[0] \
                                    in files
                                if not found:
                                    for l in launcher[1]:
                                        if l in pkg.req_names():
                                            found = True
                                            break
                                if not found:
                                    printError(
                                        pkg,
                                        'use-of-launcher-in-menu-but-no-requires-on',
                                        launcher[1][0])
                            command = command_line[1]
                            break

                        if command[0] == '/':
                            if command not in files:
                                printWarning(pkg,
                                             'menu-command-not-in-package',
                                             command)
                        elif not ('/bin/' + command in files
                                  or '/usr/bin/' + command in files
                                  or '/usr/X11R6/bin/' + command in files):
                            printWarning(pkg, 'menu-command-not-in-package',
                                         command)
                    else:
                        printWarning(pkg, 'missing-menu-command')
                        command = False

                    res = longtitle_regex.search(line)
                    if res:
                        grp = res.groups()
                        title = grp[1] or grp[2]
                        if title[0] != title[0].upper():
                            printWarning(pkg, 'menu-longtitle-not-capitalized',
                                         title)
                        res = version_regex.search(title)
                        if res:
                            printWarning(pkg, 'version-in-menu-longtitle',
                                         title)
                    else:
                        printError(pkg, 'no-longtitle-in-menu', f)
                        title = None

                    res = title_regex.search(line)
                    if res:
                        grp = res.groups()
                        title = grp[1] or grp[2]
                        if title[0] != title[0].upper():
                            printWarning(pkg, 'menu-title-not-capitalized',
                                         title)
                        res = version_regex.search(title)
                        if res:
                            printWarning(pkg, 'version-in-menu-title', title)
                        if '/' in title:
                            printError(pkg, 'invalid-title', title)
                    else:
                        printError(pkg, 'no-title-in-menu', f)
                        title = None

                    res = needs_regex.search(line)
                    if res:
                        grp = res.groups()
                        needs = (grp[1] or grp[2]).lower()
                        if needs in ('x11', 'text', 'wm'):
                            res = section_regex.search(line)
                            if res:
                                grp = res.groups()
                                section = grp[1] or grp[2]
                                # don't warn entries for sections
                                if command and section not in valid_sections:
                                    printError(pkg, 'invalid-menu-section',
                                               section, f)
                            else:
                                printInfo(pkg, 'unable-to-parse-menu-section',
                                          line)
                        elif needs not in standard_needs:
                            printInfo(pkg, 'strange-needs', needs, f)
                    else:
                        printInfo(pkg, 'unable-to-parse-menu-needs', line)

                    res = icon_regex.search(line)
                    if res:
                        icon = res.group(1)
                        if not icon_ext_regex.search(icon):
                            printWarning(pkg, 'invalid-menu-icon-type', icon)
                        if icon[0] == '/' and needs == 'x11':
                            printWarning(pkg, 'hardcoded-path-in-menu-icon',
                                         icon)
                        else:
                            for path in icon_paths:
                                if (path[0] + icon) not in files:
                                    printError(
                                        pkg, path[1] + '-icon-not-in-package',
                                        icon, f)
                    else:
                        printWarning(pkg, 'no-icon-in-menu', title)

                    res = xdg_migrated_regex.search(line)
                    if res:
                        if not res.group(1).lower() == "true":
                            printError(pkg, 'non-xdg-migrated-menu')
                    else:
                        printError(pkg, 'non-xdg-migrated-menu')