recentchangesdiff: truncate extremely large diffs
authorJoey Hess <joey@kitenet.net>
Mon, 23 Jan 2012 22:36:33 +0000 (18:36 -0400)
committerJoey Hess <joey@kitenet.net>
Mon, 23 Jan 2012 22:39:53 +0000 (18:39 -0400)
A diff was already truncated after 200 lines. But it could still be
arbitrarily enormous, if a spammer or other random noise source likes long
lines. That could use a lot of memory to html encode etc the diff and fill
it into the template. Truncating after 100kb seems sufficient; it allows
for 200 lines of up to 512 characters each.

IkiWiki/Plugin/recentchangesdiff.pm

index 71297572d7b74a5042e18fd93128a4dca773e170..41882279331f8b1a2171bb98197602197ba64190 100644 (file)
@@ -31,13 +31,21 @@ sub pagetemplate (@) {
                my @lines=IkiWiki::rcs_diff($params{rev}, $maxlines+1);
                if (@lines) {
                        my $diff;
+                       my $trunc=0;
                        if (@lines > $maxlines) {
-                               $diff=join("", @lines[0..($maxlines-1)])."\n".
-                                       gettext("(Diff truncated)");
+                               $diff=join("", @lines[0..($maxlines-1)]);
+                               $trunc=1;
                        }
                        else {
                                $diff=join("", @lines);
                        }
+                       if (length $diff > 102400) {
+                               $diff=substr($diff, 0, 10240);
+                               $trunc=1;
+                       }
+                       if ($trunc) {
+                               $diff.="\n".gettext("(Diff truncated)");
+                       }
                        # escape html
                        $diff = encode_entities($diff);
                        # escape links and preprocessor stuff