Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _parse_hunk(diff, source_start, source_len, target_start, target_len,
section_header):
"""Parse a diff hunk details."""
hunk = Hunk(source_start, source_len, target_start, target_len,
section_header)
source_line_no = hunk.source_start
target_line_no = hunk.target_start
for line in diff:
valid_line = RE_HUNK_BODY_LINE.match(line)
if not valid_line:
raise UnidiffParseError('Hunk diff line expected: %s' % line)
line_type = valid_line.group('line_type')
value = valid_line.group('value')
original_line = Line(value, line_type=line_type)
if line_type == LINE_TYPE_ADDED:
original_line.target_line_no = target_line_no
target_line_no += 1
elif line_type == LINE_TYPE_REMOVED:
original_line.source_line_no = source_line_no
source_line_no += 1
elif line_type == LINE_TYPE_CONTEXT:
original_line.target_line_no = target_line_no
target_line_no += 1
original_line.source_line_no = source_line_no
source_line_no += 1
else:
def _add_no_newline_marker_to_last_hunk(self):
if not self:
raise UnidiffParseError(
'Unexpected marker:' + LINE_VALUE_NO_NEWLINE)
last_hunk = self[-1]
last_hunk.append(
Line(LINE_VALUE_NO_NEWLINE + '\n', line_type=LINE_TYPE_NO_NEWLINE))
target_file = is_target_filename.group('filename')
target_timestamp = is_target_filename.group('timestamp')
if current_file is None:
# add current file to PatchSet
current_file = PatchedFile(
patch_info, source_file, target_file,
source_timestamp, target_timestamp)
self.append(current_file)
patch_info = None
continue
# check for hunk header
is_hunk_header = RE_HUNK_HEADER.match(line)
if is_hunk_header:
if current_file is None:
raise UnidiffParseError('Unexpected hunk found: %s' % line)
current_file._parse_hunk(line, diff, encoding)
continue
# check for no newline marker
is_no_newline = RE_NO_NEWLINE_MARKER.match(line)
if is_no_newline:
if current_file is None:
raise UnidiffParseError('Unexpected marker: %s' % line)
current_file._add_no_newline_marker_to_last_hunk()
continue
# sometimes hunks can be followed by empty lines
if line == '\n' and current_file is not None:
current_file._append_trailing_empty_line()
continue
target_line_no > expected_target_end):
raise UnidiffParseError('Hunk is longer than expected')
if original_line:
original_line.diff_line_no = diff_line_no
hunk.append(original_line)
# if hunk source/target lengths are ok, hunk is complete
if (source_line_no == expected_source_end and
target_line_no == expected_target_end):
break
# report an error if we haven't got expected number of lines
if (source_line_no < expected_source_end or
target_line_no < expected_target_end):
raise UnidiffParseError('Hunk is shorter than expected')
self.append(hunk)
original_line.source_line_no = source_line_no
source_line_no += 1
elif line_type == LINE_TYPE_CONTEXT:
original_line.target_line_no = target_line_no
target_line_no += 1
original_line.source_line_no = source_line_no
source_line_no += 1
elif line_type == LINE_TYPE_NO_NEWLINE:
pass
else:
original_line = None
# stop parsing if we got past expected number of lines
if (source_line_no > expected_source_end or
target_line_no > expected_target_end):
raise UnidiffParseError('Hunk is longer than expected')
if original_line:
original_line.diff_line_no = diff_line_no
hunk.append(original_line)
# if hunk source/target lengths are ok, hunk is complete
if (source_line_no == expected_source_end and
target_line_no == expected_target_end):
break
# report an error if we haven't got expected number of lines
if (source_line_no < expected_source_end or
target_line_no < expected_target_end):
raise UnidiffParseError('Hunk is shorter than expected')
self.append(hunk)
source_line_no = hunk.source_start
target_line_no = hunk.target_start
expected_source_end = source_line_no + hunk.source_length
expected_target_end = target_line_no + hunk.target_length
for diff_line_no, line in diff:
if encoding is not None:
line = line.decode(encoding)
valid_line = RE_HUNK_BODY_LINE.match(line)
if not valid_line:
valid_line = RE_HUNK_EMPTY_BODY_LINE.match(line)
if not valid_line:
raise UnidiffParseError('Hunk diff line expected: %s' % line)
line_type = valid_line.group('line_type')
if line_type == LINE_TYPE_EMPTY:
line_type = LINE_TYPE_CONTEXT
value = valid_line.group('value')
original_line = Line(value, line_type=line_type)
if line_type == LINE_TYPE_ADDED:
original_line.target_line_no = target_line_no
target_line_no += 1
elif line_type == LINE_TYPE_REMOVED:
original_line.source_line_no = source_line_no
source_line_no += 1
elif line_type == LINE_TYPE_CONTEXT:
original_line.target_line_no = target_line_no
target_line_no += 1
original_line.source_line_no = source_line_no
def _append_trailing_empty_line(self):
if not self:
raise UnidiffParseError('Unexpected trailing newline character')
last_hunk = self[-1]
last_hunk.append(Line('\n', line_type=LINE_TYPE_EMPTY))
def load_from_diff(self, diff, exclude_regex='', baseline_file='', last_commit_hash='', repo_name=''):
"""Initializes a SecretsCollection object from diff.
Not a classmethod, since it needs the list of self.plugins for secret scanning.
:param diff: string; diff string
:param exclude_regex: string; a regular expression of what files to skip over
:param baseline_file: string or None; the baseline_file of the repo, to skip over since it contains hashes
:param last_commit_hash: string; used for logging only -- the last hash we saved
:param repo_name: string; used for logging only -- the name of the repo
"""
try:
patch_set = PatchSet.from_string(diff)
except UnidiffParseError: # pragma: no cover
alert = {
'alert': 'UnidiffParseError',
'hash': last_commit_hash,
'repo_name': repo_name,
}
CustomLogObj.getLogger().error(alert)
raise
if exclude_regex:
regex = re.compile(exclude_regex, re.IGNORECASE)
for patch_file in patch_set:
filename = patch_file.path
# If the file matches the exclude_regex, we skip it
if exclude_regex and regex.search(filename):
continue