Commit 334ecba6 authored by Reiner Herrmann's avatar Reiner Herrmann

Make some hardcoded limits configurable.

Closes: #795292
parent 14555977
......@@ -29,6 +29,7 @@ import sys
import traceback
from diffoscope import logger, VERSION, set_locale
import diffoscope.comparators
from diffoscope.config import Config
from diffoscope.presenters.html import output_html
from diffoscope.presenters.text import output_text
......@@ -50,6 +51,10 @@ def create_parser():
parser.add_argument('--max-report-size', metavar='BYTES',
dest='max_report_size', type=int,
help='maximum bytes written in report')
parser.add_argument('--max-diff-block-lines', dest='max_diff_block_lines', type=int,
help='maximum number of lines per diff block')
parser.add_argument('--max-diff-input-lines', dest='max_diff_input_lines', type=int,
help='maximum number of lines fed to diff')
parser.add_argument('--css', metavar='url', dest='css_url',
help='link to an extra CSS for the HTML report')
parser.add_argument('file1', help='first file to compare')
......@@ -87,6 +92,9 @@ class ListToolsAction(argparse.Action):
def main():
parser = create_parser()
parsed_args = parser.parse_args(sys.argv[1:])
Config.setMaxDiffBlockLines(parsed_args.max_diff_block_lines)
Config.setMaxDiffInputLines(parsed_args.max_diff_input_lines)
Config.setMaxReportSize(parsed_args.max_report_size)
if parsed_args.debug:
logger.setLevel(logging.DEBUG)
set_locale()
......@@ -95,8 +103,7 @@ def main():
if difference:
if parsed_args.html_output:
with make_printer(parsed_args.html_output) as print_func:
output_html(difference, css_url=parsed_args.css_url, print_func=print_func,
max_page_size=parsed_args.max_report_size)
output_html(difference, css_url=parsed_args.css_url, print_func=print_func)
if (parsed_args.text_output and parsed_args.text_output != parsed_args.html_output) or not parsed_args.html_output:
with make_printer(parsed_args.text_output or '-') as print_func:
output_text(difference, print_func=print_func)
......
# -*- coding: utf-8 -*-
#
# diffoscope: in-depth comparison of files, archives, and directories
#
# Copyright © 2015 Reiner Herrmann <reiner@reiner-h.de>
#
# diffoscope is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# diffoscope is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with diffoscope. If not, see <http://www.gnu.org/licenses/>.
class Config(object):
MAX_DIFF_BLOCK_LINES = 50
MAX_DIFF_INPUT_LINES = 100000 # GNU diff cannot process arbitrary large files :(
MAX_REPORT_SIZE = 2000 * 2 ** 10 # 2000 kB
@classmethod
def setMaxDiffBlockLines(cls, lines):
if lines:
cls.MAX_DIFF_BLOCK_LINES = lines
@classmethod
def setMaxDiffInputLines(cls, lines):
if lines:
cls.MAX_DIFF_INPUT_LINES = lines
@classmethod
def setMaxReportSize(cls, bytes):
if bytes:
cls.MAX_REPORT_SIZE = bytes
@classmethod
def maxReportSize(cls):
return cls.MAX_REPORT_SIZE
@classmethod
def maxDiffBlockLines(cls):
return cls.MAX_DIFF_BLOCK_LINES
@classmethod
def maxDiffInputLines(cls):
return cls.MAX_DIFF_INPUT_LINES
......@@ -29,13 +29,10 @@ import traceback
from StringIO import StringIO
from threading import Thread
from multiprocessing import Queue
from diffoscope.config import Config
from diffoscope import logger, tool_required, RequiredToolNotFound
MAX_DIFF_BLOCK_LINES = 50
MAX_DIFF_INPUT_LINES = 100000 # GNU diff cannot process arbitrary large files :(
class DiffParser(object):
RANGE_RE = re.compile(r'^@@\s+-(?P<start1>\d+)(,(?P<len1>\d+))?\s+\+(?P<start2>\d+)(,(?P<len2>\d+))?\s+@@$')
......@@ -107,7 +104,8 @@ class DiffParser(object):
self._diff.write(line)
if line[0] in ('-', '+') and line[0] == self._direction:
self._block_len += 1
if self._block_len >= MAX_DIFF_BLOCK_LINES:
max_lines = Config.maxDiffBlockLines()
if max_lines > 0 and self._block_len >= max_lines:
return self.skip_block
else:
self._block_len = 1
......@@ -116,7 +114,7 @@ class DiffParser(object):
def skip_block(self, line):
if self._remaining_hunk_lines == 0 or line[0] != self._direction:
self._diff.write('%s[ %d lines removed ]\n' % (self._direction, self._block_len - MAX_DIFF_BLOCK_LINES))
self._diff.write('%s[ %d lines removed ]\n' % (self._direction, self._block_len - Config.maxDiffBlockLines()))
return self.read_hunk(line)
self._block_len += 1
self._remaining_hunk_lines -= 1
......@@ -231,7 +229,8 @@ def make_feeder_from_file(in_file, filter=lambda buf: buf.encode('utf-8')):
for buf in in_file.readlines():
line_count += 1
out_file.write(filter(buf))
if line_count >= MAX_DIFF_INPUT_LINES:
max_lines = Config.maxDiffInputLines()
if max_lines > 0 and line_count >= max_lines:
out_file.write('[ Too much input for diff ]%s\n' % (' ' * out_file.fileno()))
end_nl = True
break
......
......@@ -40,6 +40,7 @@ import sys
from tempfile import NamedTemporaryFile
from xml.sax.saxutils import escape
from diffoscope import logger, VERSION
from diffoscope.config import Config
from diffoscope.comparators.utils import make_temp_directory
from diffoscope.presenters.icon import FAVICON_BASE64
......@@ -153,8 +154,6 @@ FOOTER = """
</html>
"""
DEFAULT_MAX_PAGE_SIZE = 2000 * 2 ** 10 # 2000 kB
class PrintLimitReached(Exception):
pass
......@@ -513,12 +512,10 @@ def output_header(css_url, print_func):
})
def output_html(difference, css_url=None, print_func=None, max_page_size=None):
def output_html(difference, css_url=None, print_func=None):
if print_func is None:
print_func = print
if max_page_size is None:
max_page_size = DEFAULT_MAX_PAGE_SIZE
print_func = create_limited_print_func(print_func, max_page_size)
print_func = create_limited_print_func(print_func, Config.maxReportSize())
try:
output_header(css_url, print_func)
output_difference(difference, print_func, [])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment