コード例 #1
0
def load_debian_issue(f):
    deb_issue = deb822.Deb822(f)
    issue = {}

    issue['description'] = deb_issue['Description']

    references = [
        ref for ref in (LINE_BREAK_RE.split(deb_issue['References'].strip()) +
                        LINE_BREAK_RE.split(deb_issue['Bugs'].strip())) if ref
    ]
    if references:
        issue['references'] = references

    # Group and join comment lines by name
    comments = {}
    for line in LINE_BREAK_RE.split(deb_issue['Notes'].strip()):
        if not line:
            continue
        match = COMMENT_RE.match(line)
        if match:
            name = 'Debian-' + match.group(1)
            rest = match.group(2)
        else:
            name = 'Debian'
            rest = line
        comments.setdefault(name, []).append(rest)
    if comments:
        issue['comments'] = dict(
            (name, '\n'.join(lines)) for (name, lines) in comments.items())

    # Branch status
    for key in deb_issue:
        if key == 'upstream':
            branch = 'mainline'
        elif key.endswith('-upstream-stable'):
            branch = 'linux-%s.y' % key.replace('-upstream-stable', '')
        else:
            continue
        match = STATUS_RE.match(deb_issue[key])
        if match and \
           match.group('state') in ['pending', 'released'] and \
           match.group('changerefs'):
            # These are *usually* git commit hashes but could be patch names
            hashes = [
                ref for ref in COMMA_SEP_RE.split(match.group('changerefs'))
                if kernel_sec.issue.is_git_hash(ref)
            ]
            if hashes:
                issue.setdefault('fixed-by', {})[branch] = hashes
        if match and \
           match.group('state') == 'ignored' and \
           match.group('reason'):
            issue.setdefault('ignore', {})[branch] = match.group('reason')

    return issue
コード例 #2
0
def load_ubuntu_issue(f):
    ubu_issue = load_cve(f)
    issue = {}

    assert ubu_issue['Candidate'] == os.path.basename(f.name)

    if 'linux' not in ubu_issue['pkgs']:
        raise NonKernelIssue()

    # Issues with Android in the description almost always refer to things
    # not in mainline, that we should not track
    if DESCRIPTION_ANDROID_RE.search(ubu_issue['Description']):
        raise NonKernelIssue()

    issue['description'] = ubu_issue['Description'].strip()

    refs = [
        ref for ref in (ubu_issue.get('References', '').strip().split() +
                        ubu_issue.get('Bugs', '').strip().split())
        if ':' in ref
    ]
    if refs:
        issue['references'] = refs

    comments = {}
    name = 'Ubuntu'
    for line in ubu_issue['Notes'].split('\n'):
        if not line:
            continue
        match = COMMENT_RE.match(line)
        if match:
            name = 'Ubuntu-' + match.group(1)
            rest = match.group(2)
        else:
            rest = line
        comments.setdefault(name, []).append(rest)
    if comments:
        issue['comments'] = dict(
            (name, '\n'.join(lines)) for (name, lines) in comments.items())

    disc = ubu_issue.get('Discovered-by', '').strip()
    if disc:
        issue['reporters'] = DISCOVERED_BY_SEP_RE.split(disc)

    patches = ubu_issue.get('Patches_linux', '').strip()
    match = BREAK_FIX_RE.match(patches)
    if match and match.group(1):
        issue.setdefault('introduced-by', {})['mainline'] = [match.group(1)]
    if match and match.group(2):
        issue.setdefault('fixed-by', {})['mainline'] = [match.group(2)]

    return issue
コード例 #3
0
def load_ubuntu_issue(f, branches):
    ubu_issue = load_cve(f)
    issue = {}

    assert ubu_issue['Candidate'] == os.path.basename(f.name)

    if 'linux' not in ubu_issue['pkgs']:
        raise NonKernelIssue()

    issue['description'] = ubu_issue['Description'].strip()

    refs = [
        ref for ref in (ubu_issue.get('References', '').strip().split() +
                        ubu_issue.get('Bugs', '').strip().split())
        if ':' in ref
    ]
    if refs:
        issue['references'] = refs

    comments = {}
    name = 'ubuntu'
    for line in ubu_issue['Notes'].split('\n'):
        if not line:
            continue
        match = COMMENT_RE.match(line)
        if match:
            name = 'ubuntu/' + match.group(1)
            rest = match.group(2)
        else:
            rest = line
        comments.setdefault(name, []).append(rest)
    if comments:
        issue['comments'] = dict(
            (name, '\n'.join(lines)) for (name, lines) in comments.items())

    disc = ubu_issue.get('Discovered-by', '').strip()
    if disc:
        issue['reporters'] = DISCOVERED_BY_SEP_RE.split(disc)

    patches = ubu_issue.get('Patches_linux', '').strip()
    match = BREAK_FIX_RE.match(patches)
    if match and match.group(1):
        issue.setdefault('introduced-by', {})['mainline'] = [match.group(1)]
    if match and match.group(2):
        issue.setdefault('fixed-by', {})['mainline'] = [match.group(2)]

    for branch in branches:
        branch_name = branch['short_name']
        assert branch_name.startswith('ubuntu/')
        branch_state, branch_notes = \
            ubu_issue['pkgs']['linux'].get(branch_name[7:], (None, None))
        if branch_state in ['released', 'not-affected'] \
           and VERSION_RE.match(branch_notes):
            # Just record the version for now.  This can hopefully be
            # converted into a list of commits by the find_commits()
            # function.  Note that this is usually the first version
            # that is fixed *and* was released to users.
            issue.setdefault('fixed-by', {})[branch_name] = \
                ['version:' + branch_notes]

    return issue
コード例 #4
0
def load_debian_issue(f, branches):
    deb_issue = deb822.Deb822(f)
    issue = {}

    issue['description'] = deb_issue['Description']

    references = \
        [ref
         for ref in LINE_BREAK_RE.split(deb_issue['References'].strip())
         if ref] + \
        [bug_url(ref)
         for ref in LINE_BREAK_RE.split(deb_issue['Bugs'].strip())
         if ref]
    if references:
        issue['references'] = references

    # Group and join comment lines by name
    comments = {}
    for line in LINE_BREAK_RE.split(deb_issue['Notes'].strip()):
        if not line:
            continue
        match = COMMENT_RE.match(line)
        if match:
            name = 'debian/' + match.group(1)
            rest = match.group(2)
        else:
            name = 'debian'
            rest = line
        comments.setdefault(name, []).append(rest)
    if comments:
        issue['comments'] = dict(
            (name, '\n'.join(lines)) for (name, lines) in comments.items())

    def get_fixes(branch_name, branch_format, match):
        if branch_format == BranchFormat.STANDARD:
            if match.group('changerefs'):
                hashes = [
                    ref_name for ref_name in COMMA_SEP_RE.split(
                        match.group('changerefs'))
                    if kernel_sec.issue.change_is_git_hash(ref_name)
                ]
                if hashes:
                    return hashes
        else:
            assert branch_format == BranchFormat.PATCH_QUEUE
            is_debian = branch_name.startswith('debian/')
            state = match.group('state')

            if is_debian:
                if state == 'released':
                    version = match.group('version')
                    if version is None or ',' in version or '-' not in version:
                        return None
                    ref_name = 'debian/' + version.replace('~', '_')
                else:
                    assert state == 'pending'
                    ref_name = branch_name[7:]
            else:
                ref_name = 'master'

            if match.group('changerefs'):
                assert branch_format == BranchFormat.PATCH_QUEUE
                patches = COMMA_SEP_RE.split(match.group('changerefs'))
                if patches:
                    return [
                        'patch:%s:%s' % (ref_name, file_name)
                        for file_name in patches
                    ]
            elif is_debian and state == 'released':
                # Fixed in this version but without any changes listed.
                # Probably fixed by importing a newer upstream.
                return ['version:' + ref_name]

        return None

    # Branch status
    for key in deb_issue:
        # Parse the branch name and determine format of the branch
        # dependent on state
        match = BRANCH_RE.match(key)
        if not match:
            continue
        base_ver = match.group('base_ver')
        if match.group('mainline'):
            branch_format = {
                'pending': BranchFormat.STANDARD,
                'released': BranchFormat.STANDARD,
            }
            branch_name = 'mainline'
        elif not match.group('debian'):
            branch_format = {
                'pending': BranchFormat.PATCH_QUEUE,
                'released': BranchFormat.STANDARD,
            }
            branch_name = 'stable/' + base_ver
        else:
            branch_format = {
                'pending': BranchFormat.PATCH_QUEUE,
                'released': BranchFormat.PATCH_QUEUE,
            }
            branch_name = 'debian/' + match.group('debian')
        if branch_name not in branches:
            continue

        # For mainline, fixes may span multiple releases
        for match in STATUS_RE.finditer(deb_issue[key]):
            state = match.group('state')
            if state in ['pending', 'released']:
                fixes = get_fixes(branch_name, branch_format[state], match)
                if fixes:
                    issue.setdefault('fixed-by',
                                     {}).setdefault(branch_name,
                                                    []).extend(fixes)
            # However, there will be only one "ignored" entry
            if state == 'ignored' and match.group('reason'):
                issue.setdefault('ignore',
                                 {})[branch_name] = match.group('reason')

    # Fill in status for Debian stable branches fixed before the
    # Debian branch point.  These will only be explicitly marked as
    # fixed in sid, though they may have a free-form comment
    # explaining why the stable branch wasn't affected.
    if 'sid' in deb_issue:
        match = STATUS_RE.match(deb_issue['sid'])
        version = match and match.group('version')
        if match \
           and match.group('state') == 'released' \
           and version and ',' not in version:
            fixes = get_fixes('debian/sid', BranchFormat.PATCH_QUEUE, match)
            if fixes:
                for branch_name, branch in branches.items():
                    if branch_name.startswith('debian/') \
                       and branch_name not in issue.get('fixed-by', {}) \
                       and dpkg_version_cmp(
                           version, branch['debian_branch_point']) <= 0:
                        issue.setdefault('fixed-by', {})[branch_name] = fixes

    return issue