Mercurial > kallithea
changeset 6915:52e756b40a2b
diffs: do check of cut_off_limit on the raw diff before any parsing and allocation
This redefines the exact meaning of cut_off_limit but it will still be
approximately the same thing. It makes it more a limitation of what amount of
work should be done, more than how much html should be outputted.
It could make sense to push the limit further back to vcs to also prevent
computing or allocating memory for huge diffs.
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Tue, 03 Oct 2017 00:14:40 +0200 |
parents | e85f08375dc6 |
children | 182570502b6a |
files | kallithea/lib/diffs.py |
diffstat | 1 files changed, 12 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/lib/diffs.py Tue Oct 03 00:14:40 2017 +0200 +++ b/kallithea/lib/diffs.py Tue Oct 03 00:14:40 2017 +0200 @@ -137,10 +137,6 @@ BIN_FILENODE = 7 -class DiffLimitExceeded(Exception): - pass - - class DiffProcessor(object): """ Give it a unified or git diff and it returns a list of the files that were @@ -204,24 +200,15 @@ self._diff = diff self.adds = 0 self.removes = 0 - # calculate diff size self.diff_limit = diff_limit - self.cur_diff_size = 0 self.limited_diff = False self.vcs = vcs self.parsed = self._parse_gitdiff(inline_diff=inline_diff) def _escaper(self, string): """ - Do HTML escaping/markup and check the diff limit + Do HTML escaping/markup """ - self.cur_diff_size += len(string) - - # escaper gets iterated on each .next() call and it checks if each - # parsed line doesn't exceed the diff limit - if self.diff_limit is not None and self.cur_diff_size > self.diff_limit: - raise DiffLimitExceeded('Diff Limit Exceeded') - def substitute(m): groups = m.groups() if groups[0]: @@ -304,6 +291,10 @@ starts.append(len(self._diff)) for start, end in zip(starts, starts[1:]): + if self.diff_limit and end > self.diff_limit: + self.limited_diff = True + continue + head, diff_lines = self._get_header(buffer(self._diff, start, end - start)) op = None @@ -363,18 +354,13 @@ # a real non-binary diff if head['a_file'] or head['b_file']: - try: - chunks, added, deleted = self._parse_lines(diff_lines) - stats['binary'] = False - stats['added'] = added - stats['deleted'] = deleted - # explicit mark that it's a modified file - if op == 'M': - stats['ops'][MOD_FILENODE] = 'modified file' - - except DiffLimitExceeded: - self.limited_diff = True - break + chunks, added, deleted = self._parse_lines(diff_lines) + stats['binary'] = False + stats['added'] = added + stats['deleted'] = deleted + # explicit mark that it's a modified file + if op == 'M': + stats['ops'][MOD_FILENODE] = 'modified file' else: # Git binary patch (or empty diff) # Git binary patch if head['bin_patch']: