changeset 1274:7a0004efde12 beta

Added extra check for very large diffs in changesets, sometimes for very large diffs the diff parser could kill CPU.
author Marcin Kuzminski <marcin@python-works.com>
date Sat, 23 Apr 2011 14:52:44 +0200
parents 64cb9612f9aa
children 2723276285ae
files rhodecode/controllers/changeset.py
diffstat 1 files changed, 18 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/changeset.py	Sat Apr 23 14:23:13 2011 +0200
+++ b/rhodecode/controllers/changeset.py	Sat Apr 23 14:52:44 2011 +0200
@@ -88,8 +88,9 @@
         c.sum_removed = 0
         c.lines_added = 0
         c.lines_deleted = 0
-        c.cut_off = False
+        c.cut_off = False # defines if cut off limit is reached
 
+        # Iterate over ranges (default changeset view is always one changeset)
         for changeset in c.cs_ranges:
             c.changes[changeset.raw_id] = []
             try:
@@ -101,17 +102,23 @@
             # ADDED FILES
             #==================================================================
             for node in changeset.added:
+
                 filenode_old = FileNode(node.path, '', EmptyChangeset())
                 if filenode_old.is_binary or node.is_binary:
                     diff = wrap_to_table(_('binary file'))
                     st = (0, 0)
                 else:
+                    # in this case node.size is good parameter since those are
+                    # added nodes and their size defines how many changes were
+                    # made
                     c.sum_added += node.size
                     if c.sum_added < self.cut_off_limit:
                         f_gitdiff = differ.get_gitdiff(filenode_old, node)
                         d = differ.DiffProcessor(f_gitdiff, format='gitdiff')
+
+                        st = d.stat()
                         diff = d.as_html()
-                        st = d.stat()
+
                     else:
                         diff = wrap_to_table(_('Changeset is to big and '
                                                'was cut off, see raw '
@@ -134,6 +141,7 @@
                     try:
                         filenode_old = changeset_parent.get_node(node.path)
                     except ChangesetError:
+                        log.warning('Unable to fetch parent node for diff')
                         filenode_old = FileNode(node.path, '',
                                                 EmptyChangeset())
 
@@ -146,8 +154,15 @@
                             f_gitdiff = differ.get_gitdiff(filenode_old, node)
                             d = differ.DiffProcessor(f_gitdiff,
                                                      format='gitdiff')
-                            diff = d.as_html()
                             st = d.stat()
+                            if (st[0] + st[1]) * 256 > self.cut_off_limit:
+                                diff = wrap_to_table(_('Diff is to big '
+                                                       'and was cut off, see '
+                                                       'raw diff instead'))
+                            else:
+                                diff = d.as_html()
+
+
                             if diff:
                                 c.sum_removed += len(diff)
                         else: