def handle_timeout(subscriber, subscription, ack_id, oss_fuzz_dir, message): """Handle a timeout.""" subscriber.acknowledge(subscription=subscription, ack_ids=[ack_id]) bisect_type = message.attributes['type'] source_id = get_source_id(message) logging.error('Task %s timed out (source_id=%s)', bisect_type, source_id) if bisect_type not in ('fixed', 'regressed'): return old_commit = message.attributes['old_commit'] new_commit = message.attributes['new_commit'] if bisect_type == 'fixed': entity = osv.FixResult(id=source_id) else: assert bisect_type == 'regressed' entity = osv.RegressResult(id=source_id) _set_result_attributes(oss_fuzz_dir, message, entity) entity.commit = format_commit_range(old_commit, new_commit) entity.error = 'Timeout' entity.put()
def process_bisect_task(oss_fuzz_dir, bisect_type, source_id, message): """Process a bisect task.""" bisect_type = message.attributes['type'] project_name = message.attributes['project_name'] engine = 'libfuzzer' architecture = message.attributes['architecture'] or 'x86_64' sanitizer = message.attributes['sanitizer'] fuzz_target = message.attributes['fuzz_target'] old_commit = message.attributes['old_commit'] new_commit = message.attributes['new_commit'] testcase = message.data logging.info( 'Performing %s bisect on source_id=%s, project=%s, engine=%s, ' 'architecture=%s, sanitizer=%s, fuzz_target=%s, old_commit=%s, ' 'new_commit=%s', bisect_type, source_id, project_name, engine, architecture, sanitizer, fuzz_target, old_commit, new_commit) result = None if project_name in PROJECT_DENYLIST: logging.info('Skipping bisect for denylisted project %s', project_name) elif not old_commit: logging.info('Skipping bisect since there is no old_commit.') else: result = do_bisect(bisect_type, source_id, project_name, engine, sanitizer, architecture, fuzz_target, old_commit, new_commit, testcase) if result.repo_url in REPO_DENYLIST: logging.info('Skipping because of denylisted repo %s.', result.repo_url) return if bisect_type == 'fixed': entity = osv.FixResult(id=source_id) else: assert bisect_type == 'regressed' entity = osv.RegressResult(id=source_id) _set_result_attributes(oss_fuzz_dir, message, entity) if result and result.commit: logging.info('Bisected to %s', result.commit) entity.commit = result.commit entity.repo_url = result.repo_url else: logging.info( 'Bisect not successfully performed. Setting commit range from request.' ) entity.commit = format_commit_range(old_commit, new_commit) entity.repo_url = result.repo_url if result else None entity.error = 'Bisect error' entity.put()
def test_fixed_range_too_long(self): """Test fixed range that's too long.""" message = mock.Mock() message.attributes = { 'source_id': 'oss-fuzz:123', 'allocated_id': 'OSV-2020-1337', } regress_result = osv.RegressResult( id='oss-fuzz:123', commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', repo_url='https://repo.com/repo', issue_id='9001', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', severity='MEDIUM', reference_urls=['https://url/']) regress_result.put() fix_result = osv.FixResult( id='oss-fuzz:123', commit=('eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:' 'b587c21c36a84e16cfc6b39eb68578d43b5281ad'), repo_url='https://repo.com/repo', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', details='DETAILS', severity='MEDIUM', reference_urls=['https://url/']) fix_result.put() oss_fuzz.process_impact_task('oss-fuzz:123', message) self.expect_dict_equal( 'fixed_range_too_long', ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) affected_commits = list(osv.AffectedCommit.query()) self.assertCountEqual([ 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', 'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', 'febfac1940086bc1f6d3dc33fda0a1d1ba336209', '4c155795426727ea05575bd5904321def23c03f4', 'b1c95a196f22d06fcf80df8c6691cd113d8fefff', 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', '3ea6feea9bb853596c727abab309476cc07d1505', '36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', ], [commit.commit for commit in affected_commits])
def handle_timeout(task_type, source_id, oss_fuzz_dir, message): """Handle a timeout.""" old_commit = message.attributes['old_commit'] new_commit = message.attributes['new_commit'] if task_type == 'fixed': entity = osv.FixResult(id=source_id) else: assert task_type == 'regressed' entity = osv.RegressResult(id=source_id) _set_result_attributes(oss_fuzz_dir, message, entity) entity.commit = format_commit_range(old_commit, new_commit) entity.error = 'Timeout' entity.put()
def test_zero_regression_range(self): """Test regression range with "0:X".""" message = mock.Mock() message.attributes = { 'source_id': 'oss-fuzz:123', 'allocated_id': 'OSV-2020-1337', } regress_result = osv.RegressResult( id='oss-fuzz:123', commit='unknown:eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', repo_url='https://repo.com/repo', issue_id='9001', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', severity='MEDIUM', reference_urls=['https://url/']) regress_result.put() fix_result = osv.FixResult( id='oss-fuzz:123', commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', repo_url='https://repo.com/repo', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', details='DETAILS', severity='MEDIUM', reference_urls=['https://url/']) fix_result.put() oss_fuzz.process_impact_task('oss-fuzz:123', message) self.expect_dict_equal( 'zero_regression_range', ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict()) affected_commits = list(osv.AffectedCommit.query()) self.assertCountEqual([ 'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', 'febfac1940086bc1f6d3dc33fda0a1d1ba336209', '4c155795426727ea05575bd5904321def23c03f4', 'b1c95a196f22d06fcf80df8c6691cd113d8fefff', 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', ], [commit.commit for commit in affected_commits])
def test_update_add_fix(self): """Test basic update adding a fix.""" fix_result = osv.FixResult( id='source:BLAH-124.yaml', commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735') fix_result.put() task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, None) message = mock.Mock() message.attributes = { 'source': 'source', 'path': 'BLAH-124.yaml', 'original_sha256': ('5d6224b81fb100d51bf61c2568b1c75f' '1df355ace1872af1b7eb0b1b5d93f477'), 'deleted': 'false', } task_runner._source_update(message) repo = pygit2.Repository(self.remote_source_repo_path) commit = repo.head.peel() self.assertEqual('*****@*****.**', commit.author.email) self.assertEqual('OSV', commit.author.name) self.assertEqual('Update BLAH-124', commit.message) diff = repo.diff(commit.parents[0], commit) self.expect_equal('diff_update_add_fix', diff.patch) self.expect_dict_equal('update_add_fix', osv.Bug.get_by_id('BLAH-124')._to_dict()) affected_commits = list(osv.AffectedCommit.query()) self.assertCountEqual([ '4c155795426727ea05575bd5904321def23c03f4', 'b1c95a196f22d06fcf80df8c6691cd113d8fefff', 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'febfac1940086bc1f6d3dc33fda0a1d1ba336209', 'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', ], [commit.commit for commit in affected_commits])
def test_simplify_range(self): """Test simplifying commit range.""" message = mock.Mock() message.attributes = { 'source_id': 'oss-fuzz:123', 'allocated_id': 'OSV-2020-1337', } regress_result = osv.RegressResult( id='oss-fuzz:123', commit=('a2ba949290915d445d34d0e8e9de2e7ce38198fc:' 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'), repo_url='https://repo.com/repo', issue_id='9001', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', severity='MEDIUM', reference_urls=['https://url/']) regress_result.put() fix_result = osv.FixResult( id='oss-fuzz:123', commit=('b1c95a196f22d06fcf80df8c6691cd113d8fefff:' '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'), repo_url='https://repo.com/repo', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', details='DETAILS', severity='MEDIUM', reference_urls=['https://url/']) fix_result.put() oss_fuzz.process_impact_task('oss-fuzz:123', message) self.expect_dict_equal( 'simplify_range', ndb.Key(osv.Bug, 'OSV-2020-1337').get()._to_dict())
def process_impact_task(source_id, message): """Process an impact task.""" logging.info('Processing impact task for %s', source_id) regress_result = ndb.Key(osv.RegressResult, source_id).get() if not regress_result: logging.error('Missing RegressResult for %s', source_id) return fix_result = ndb.Key(osv.FixResult, source_id).get() if not fix_result: logging.warning('Missing FixResult for %s', source_id) fix_result = osv.FixResult() # Check if there is an existing Bug for the same source, but with a different # allocated ID. This shouldn't happen. allocated_bug_id = message.attributes['allocated_id'] existing_bug = osv.Bug.query(osv.Bug.source_id == source_id).get() if existing_bug and existing_bug.key.id() != allocated_bug_id: logging.error('Bug entry already exists for %s with a different ID %s', source_id, existing_bug.key.id()) return if existing_bug and existing_bug.status == osv.BugStatus.INVALID: logging.warning('Bug %s already marked as invalid.', existing_bug.key.id()) return if existing_bug: public = existing_bug.public else: raise osv.ImpactError('Task requested without Bug allocated.') # TODO(ochang): Handle changing repo types? e.g. SVN -> Git. repo_url = regress_result.repo_url or fix_result.repo_url if not repo_url: raise osv.ImpactError('No repo_url set') issue_id = fix_result.issue_id or regress_result.issue_id fix_commit = fix_result.commit with tempfile.TemporaryDirectory() as tmp_dir: repo = osv.clone_with_retries(repo_url, tmp_dir) # If not a precise fix commit, try to find the exact one by going through # commit messages (oss-fuzz only). if source_id.startswith(SOURCE_PREFIX) and ':' in fix_commit: start_commit, end_commit = fix_commit.split(':') commit = find_oss_fuzz_fix_via_commit(repo, start_commit, end_commit, source_id, issue_id) if commit: logging.info('Found exact fix commit %s via commit message (oss-fuzz)', commit) fix_commit = commit # Actually compute the affected commits/tags. result = osv.get_affected(repo, regress_result.commit, fix_commit) logging.info('Found affected %s', ', '.join(result.tags)) # If the range resolved to a single commit, simplify it. if len(result.fix_commits) == 1: fix_commit = result.fix_commits[0] elif not result.fix_commits: # Not fixed. fix_commit = '' if len(result.regress_commits) == 1: regress_commit = result.regress_commits[0] else: regress_commit = regress_result.commit project = fix_result.project or regress_result.project ecosystem = fix_result.ecosystem or regress_result.ecosystem summary = fix_result.summary or regress_result.summary details = fix_result.details or regress_result.details severity = fix_result.severity or regress_result.severity reference_urls = fix_result.reference_urls or regress_result.reference_urls update_affected_commits(allocated_bug_id, result, project, ecosystem, public) existing_bug.repo_url = repo_url existing_bug.fixed = fix_commit existing_bug.regressed = regress_commit existing_bug.affected = result.tags existing_bug.affected_fuzzy = osv.normalize_tags(result.tags) existing_bug.confidence = result.confidence existing_bug.issue_id = issue_id existing_bug.project = project existing_bug.ecosystem = ecosystem existing_bug.summary = summary existing_bug.details = details existing_bug.status = osv.BugStatus.PROCESSED existing_bug.severity = severity existing_bug.reference_urls = reference_urls existing_bug.additional_commit_ranges = [] # Don't display additional ranges for imprecise commits, as they can be # confusing. if ':' in existing_bug.fixed or ':' in existing_bug.regressed: existing_bug.put() return def _sort_key(value): # Allow sorting of None values. return (value[0] or '', value[1] or '') for introduced_in, fixed_in in sorted(result.affected_ranges, key=_sort_key): if (introduced_in == existing_bug.regressed and (fixed_in or '') == existing_bug.fixed): # Don't include the main range. continue existing_bug.additional_commit_ranges.append( osv.CommitRange(introduced_in=introduced_in, fixed_in=fixed_in)) existing_bug.put()
def process_impact_task(source_id, message): """Process an impact task.""" logging.info('Processing impact task for %s', source_id) regress_result = ndb.Key(osv.RegressResult, source_id).get() if not regress_result: logging.error('Missing RegressResult for %s', source_id) return fix_result = ndb.Key(osv.FixResult, source_id).get() if not fix_result: logging.warning('Missing FixResult for %s', source_id) fix_result = osv.FixResult() # Check if there is an existing Bug for the same source, but with a different # allocated ID. This shouldn't happen. allocated_bug_id = message.attributes['allocated_id'] existing_bug = osv.Bug.query(osv.Bug.source_id == source_id).get() if existing_bug and existing_bug.key.id() != allocated_bug_id: logging.error('Bug entry already exists for %s with a different ID %s', source_id, existing_bug.key.id()) return if existing_bug and existing_bug.status == osv.BugStatus.INVALID: logging.warning('Bug %s already marked as invalid.', existing_bug.key.id()) return if existing_bug: public = existing_bug.public else: raise osv.ImpactError('Task requested without Bug allocated.') repo_url = regress_result.repo_url or fix_result.repo_url if not repo_url: raise osv.ImpactError('No repo_url set') # Always populate Bug attributes, even if the remainder of the analysis fails. # This does not mark the Bug as being valid. set_bug_attributes(existing_bug, regress_result, fix_result) existing_bug.put() issue_id = fix_result.issue_id or regress_result.issue_id fix_commit = fix_result.commit with tempfile.TemporaryDirectory() as tmp_dir: repo = osv.clone_with_retries(repo_url, tmp_dir) # If not a precise fix commit, try to find the exact one by going through # commit messages (oss-fuzz only). if source_id.startswith(SOURCE_PREFIX) and ':' in fix_commit: start_commit, end_commit = fix_commit.split(':') commit = find_oss_fuzz_fix_via_commit(repo, start_commit, end_commit, source_id, issue_id) if commit: logging.info( 'Found exact fix commit %s via commit message (oss-fuzz)', commit) fix_commit = commit # Actually compute the affected commits/tags. repo_analyzer = osv.RepoAnalyzer() result = repo_analyzer.get_affected(repo, regress_result.commit, fix_commit) affected_tags = sorted(list(result.tags)) logging.info('Found affected %s', ', '.join(affected_tags)) # If the range resolved to a single commit, simplify it. if len(result.fix_commits) == 1: fix_commit = result.fix_commits[0] elif not result.fix_commits: # Not fixed. fix_commit = '' if (len(result.regress_commits) == 1 and osv.UNKNOWN_COMMIT not in regress_result.commit): regress_commit = result.regress_commits[0] else: regress_commit = regress_result.commit project = fix_result.project or regress_result.project ecosystem = fix_result.ecosystem or regress_result.ecosystem osv.update_affected_commits(allocated_bug_id, result.commits, project, ecosystem, public) affected_tags = sorted(list(result.tags)) existing_bug.fixed = fix_commit existing_bug.regressed = regress_commit existing_bug.affected = affected_tags existing_bug.affected_fuzzy = osv.normalize_tags(affected_tags) existing_bug.status = osv.BugStatus.PROCESSED # For the AffectedRange, use the first commit in the regress commit range, and # the last commit in the fix commit range. introduced = result.regress_commits[0] if result.regress_commits else '' fixed = result.fix_commits[-1] if result.fix_commits else '' existing_bug.affected_ranges = [ osv.AffectedRange(type='GIT', repo_url=repo_url, introduced=introduced, fixed=fixed), ] # Expose range data in `database_specific`. database_specific = {} if ':' in existing_bug.regressed: database_specific['introduced_range'] = existing_bug.regressed if ':' in existing_bug.fixed: database_specific['fixed_range'] = existing_bug.fixed if database_specific: existing_bug.database_specific = database_specific # Don't display additional ranges for imprecise commits, as they can be # confusing. if ':' in existing_bug.fixed or ':' in existing_bug.regressed: existing_bug.put() return def _sort_key(value): # Allow sorting of None values. return (value[0] or '', value[1] or '') for introduced_in, fixed_in in sorted(result.affected_ranges, key=_sort_key): if not fixed_in: fixed_in = '' if (introduced_in == existing_bug.regressed and fixed_in == existing_bug.fixed): # Don't repeat the main range. continue existing_bug.affected_ranges.append( osv.AffectedRange(type='GIT', repo_url=repo_url, introduced=introduced_in, fixed=fixed_in)) existing_bug.put()
def test_simplify_range(self): """Test simplifying commit range.""" message = mock.Mock() message.attributes = { 'source_id': 'oss-fuzz:123', 'allocated_id': '2020-1337', } regress_result = osv.RegressResult( id='oss-fuzz:123', commit=('a2ba949290915d445d34d0e8e9de2e7ce38198fc:' 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'), repo_url='https://repo.com/repo', issue_id='9001', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', severity='MEDIUM', reference_urls=['https://url/']) regress_result.put() fix_result = osv.FixResult( id='oss-fuzz:123', commit=('b1c95a196f22d06fcf80df8c6691cd113d8fefff:' '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'), repo_url='https://repo.com/repo', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', details='DETAILS', severity='MEDIUM', reference_urls=['https://url/']) fix_result.put() oss_fuzz.process_impact_task('oss-fuzz:123', message) self.assertDictEqual( { 'affected': ['branch-v0.1.1', 'branch_1_cherrypick_regress', 'v0.1.1'], 'affected_fuzzy': ['0-1-1', '1', '0-1-1'], 'additional_commit_ranges': [{ 'introduced_in': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'fixed_in': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98' }, { 'introduced_in': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209', 'fixed_in': None }], 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'repo_url': 'https://repo.com/repo', 'confidence': 100, 'issue_id': '9001', 'last_modified': datetime.datetime(2021, 1, 1, 0, 0), 'timestamp': datetime.datetime(2020, 1, 1), 'source_id': 'oss-fuzz:123', 'project': 'project', 'ecosystem': 'ecosystem', 'summary': 'Heap-buffer-overflow in Foo', 'details': 'DETAILS', 'severity': 'MEDIUM', 'sort_key': '2020-0001337', 'source_of_truth': osv.SourceOfTruth.INTERNAL, 'reference_urls': ['https://url/'], 'public': False, 'status': osv.BugStatus.PROCESSED.value, 'has_affected': True, 'search_indices': ['project', '2020-1337', '2020', '1337'], }, ndb.Key(osv.Bug, '2020-1337').get()._to_dict())
def test_zero_regression_range(self): """Test regression range with "0:X".""" message = mock.Mock() message.attributes = { 'source_id': 'oss-fuzz:123', 'allocated_id': '2020-1337', } regress_result = osv.RegressResult( id='oss-fuzz:123', commit='unknown:eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', repo_url='https://repo.com/repo', issue_id='9001', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', severity='MEDIUM', reference_urls=['https://url/']) regress_result.put() fix_result = osv.FixResult( id='oss-fuzz:123', commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', repo_url='https://repo.com/repo', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', details='DETAILS', severity='MEDIUM', reference_urls=['https://url/']) fix_result.put() oss_fuzz.process_impact_task('oss-fuzz:123', message) self.assertDictEqual( { 'affected': ['branch-v0.1.1', 'branch_1_cherrypick_regress', 'v0.1.1'], 'affected_fuzzy': ['0-1-1', '1', '0-1-1'], 'additional_commit_ranges': [], 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', 'regressed': 'unknown:eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'repo_url': 'https://repo.com/repo', 'confidence': 80, 'issue_id': '9001', 'last_modified': datetime.datetime(2021, 1, 1, 0, 0), 'timestamp': datetime.datetime(2020, 1, 1), 'source_id': 'oss-fuzz:123', 'project': 'project', 'ecosystem': 'ecosystem', 'summary': 'Heap-buffer-overflow in Foo', 'details': 'DETAILS', 'severity': 'MEDIUM', 'sort_key': '2020-0001337', 'source_of_truth': osv.SourceOfTruth.INTERNAL, 'reference_urls': ['https://url/'], 'public': False, 'status': osv.BugStatus.PROCESSED.value, 'has_affected': True, 'search_indices': ['project', '2020-1337', '2020', '1337'], }, ndb.Key(osv.Bug, '2020-1337').get()._to_dict()) affected_commits = list(osv.AffectedCommit.query()) for commit in affected_commits: self.assertEqual(80, commit.confidence) self.assertEqual('project', commit.project) self.assertCountEqual([ 'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', 'febfac1940086bc1f6d3dc33fda0a1d1ba336209', '4c155795426727ea05575bd5904321def23c03f4', 'b1c95a196f22d06fcf80df8c6691cd113d8fefff', 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', ], [commit.commit for commit in affected_commits])
def test_update_add_fix(self): """Test basic update adding a fix.""" fix_result = osv.FixResult( id='source:BLAH-124.yaml', commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735') fix_result.put() task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, None) message = mock.Mock() message.attributes = { 'source': 'source', 'path': 'BLAH-124.yaml', 'original_sha256': ('80e0cb5e08fb624fc265c91729422cd8' '8d1c0b1696990f9a6defe417101e6d6d'), } task_runner._source_update(message) repo = pygit2.Repository(self.remote_source_repo_path) commit = repo.head.peel() self.assertEqual('*****@*****.**', commit.author.email) self.assertEqual('OSV', commit.author.name) self.assertEqual('Update BLAH-124', commit.message) diff = repo.diff(commit.parents[0], commit) self.assertEqual(self._load_test_data('expected_add_fix.diff'), diff.patch) self.assertDictEqual( { 'additional_commit_ranges': [{ 'fixed_in': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', 'introduced_in': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd' }, { 'fixed_in': '', 'introduced_in': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209' }], 'affected': [], 'affected_fuzzy': [], 'confidence': None, 'details': 'Blah blah blah\nBlah\n', 'ecosystem': 'golang', 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', 'has_affected': False, 'issue_id': None, 'last_modified': datetime.datetime(2021, 1, 1, 0, 0), 'project': 'blah.com/package', 'public': None, 'reference_urls': ['https://ref.com/ref'], 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'repo_url': None, 'search_indices': ['blah.com/package', 'BLAH-124', 'BLAH', '124'], 'severity': 'HIGH', 'sort_key': 'BLAH-0000124', 'source_id': 'source:BLAH-124.yaml', 'source_of_truth': osv.SourceOfTruth.SOURCE_REPO, 'status': None, 'summary': 'A vulnerability', 'timestamp': None }, osv.Bug.get_by_id('BLAH-124')._to_dict())
def test_update_add_fix(self): """Test basic update adding a fix.""" fix_result = osv.FixResult( id='source:BLAH-124.yaml', commit='8d8242f545e9cec3e6d0d2e3f5bde8be1c659735') fix_result.put() task_runner = worker.TaskRunner(ndb_client, None, self.tmp_dir.name, None, None) message = mock.Mock() message.attributes = { 'source': 'source', 'path': 'BLAH-124.yaml', 'original_sha256': ('df9b0207ff2aa433d71869fa206b4884' '071807d5dfddf8626b93da210b6572ef'), } task_runner._source_update(message) repo = pygit2.Repository(self.remote_source_repo_path) commit = repo.head.peel() self.assertEqual('*****@*****.**', commit.author.email) self.assertEqual('OSV', commit.author.name) self.assertEqual('Update BLAH-124', commit.message) diff = repo.diff(commit.parents[0], commit) self.assertEqual(self._load_test_data('expected_add_fix.diff'), diff.patch) self.assertDictEqual( { 'additional_commit_ranges': [{ 'fixed_in': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98', 'introduced_in': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd' }, { 'fixed_in': '', 'introduced_in': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209' }], 'affected': [], 'affected_fuzzy': [], 'confidence': None, 'details': 'Blah blah blah\nBlah\n', 'ecosystem': 'golang', 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', 'has_affected': False, 'issue_id': None, 'last_modified': datetime.datetime(2021, 1, 1, 0, 0), 'project': 'blah.com/package', 'public': None, 'reference_urls': ['https://ref.com/ref'], 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'repo_url': None, 'search_indices': ['blah.com/package', 'BLAH-124', 'BLAH', '124'], 'severity': 'HIGH', 'sort_key': 'BLAH-0000124', 'source_id': 'source:BLAH-124.yaml', 'source_of_truth': osv.SourceOfTruth.SOURCE_REPO, 'status': None, 'summary': 'A vulnerability', 'timestamp': None }, osv.Bug.get_by_id('BLAH-124')._to_dict()) affected_commits = list(osv.AffectedCommit.query()) self.assertCountEqual([ '4c155795426727ea05575bd5904321def23c03f4', 'b1c95a196f22d06fcf80df8c6691cd113d8fefff', 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'febfac1940086bc1f6d3dc33fda0a1d1ba336209', 'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', ], [commit.commit for commit in affected_commits])
def test_fixed_range_too_long(self): """Test fixed range that's too long.""" message = mock.Mock() message.attributes = { 'source_id': 'oss-fuzz:123', 'allocated_id': '2020-1337', } regress_result = osv.RegressResult( id='oss-fuzz:123', commit='eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', repo_url='https://repo.com/repo', issue_id='9001', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', severity='MEDIUM', reference_urls=['https://url/']) regress_result.put() fix_result = osv.FixResult( id='oss-fuzz:123', commit=('eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:' 'b587c21c36a84e16cfc6b39eb68578d43b5281ad'), repo_url='https://repo.com/repo', project='project', ecosystem='ecosystem', summary='Heap-buffer-overflow in Foo', details='DETAILS', severity='MEDIUM', reference_urls=['https://url/']) fix_result.put() oss_fuzz.process_impact_task('oss-fuzz:123', message) self.assertDictEqual( { 'affected': [ 'branch-v0.1.1', 'branch-v0.1.1-with-fix', 'branch_1_cherrypick_regress', 'v0.1.1', 'v0.2' ], 'affected_fuzzy': ['0-1-1', '0-1-1', '1', '0-1-1', '0-2'], 'additional_commit_ranges': [], 'regressed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', 'fixed': ('eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:' 'b587c21c36a84e16cfc6b39eb68578d43b5281ad'), 'repo_url': 'https://repo.com/repo', 'confidence': 30, 'issue_id': '9001', 'last_modified': datetime.datetime(2021, 1, 1, 0, 0), 'timestamp': datetime.datetime(2020, 1, 1), 'source_id': 'oss-fuzz:123', 'project': 'project', 'ecosystem': 'ecosystem', 'summary': 'Heap-buffer-overflow in Foo', 'details': 'DETAILS', 'reference_urls': ['https://url/'], 'severity': 'MEDIUM', 'sort_key': '2020-0001337', 'public': False, 'status': osv.BugStatus.PROCESSED.value, 'has_affected': True, 'search_indices': ['project', '2020-1337', '2020', '1337'], }, ndb.Key(osv.Bug, '2020-1337').get()._to_dict()) affected_commits = list(osv.AffectedCommit.query()) for commit in affected_commits: self.assertEqual(30, commit.confidence) self.assertEqual('project', commit.project) self.assertCountEqual([ 'ff8cc32ba60ad9cbb3b23f0a82aad96ebe9ff76b', 'febfac1940086bc1f6d3dc33fda0a1d1ba336209', '4c155795426727ea05575bd5904321def23c03f4', 'b1c95a196f22d06fcf80df8c6691cd113d8fefff', 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd', '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', '3ea6feea9bb853596c727abab309476cc07d1505', '36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', ], [commit.commit for commit in affected_commits])