diff --git a/dmoj/judgeenv.py b/dmoj/judgeenv.py index 0cbf637f5..fb77bdd24 100644 --- a/dmoj/judgeenv.py +++ b/dmoj/judgeenv.py @@ -31,6 +31,7 @@ 'compiler_output_character_limit': 65536, # Number of characters allowed in compile output 'compiled_binary_cache_dir': None, # Location to store cached binaries, defaults to tempdir 'compiled_binary_cache_size': 100, # Maximum number of executables to cache (LRU order) + 'test_size_limit': 262144, # Maximum allowable test size, 256mb 'runtime': {}, # Map of executor: fs_config, used to configure # the filesystem sandbox on a per-machine basis, without having to hack diff --git a/dmoj/problem.py b/dmoj/problem.py index 3aa4eaf4a..c3aa5d248 100644 --- a/dmoj/problem.py +++ b/dmoj/problem.py @@ -30,6 +30,7 @@ from dmoj import checkers from dmoj.checkers import Checker from dmoj.config import ConfigNode, InvalidInitException +from dmoj.error import InternalError from dmoj.judgeenv import env, get_problem_root from dmoj.utils.helper_files import compile_with_auxiliary_files, parse_helper_file_error from dmoj.utils.module import load_module_from_file @@ -80,6 +81,9 @@ def __init__(self, problem_id: str, time_limit: float, memory_limit: int, meta: self.problem_data.archive = self._resolve_archive_files() + if self.config.test_size_limit: + self.problem_data.test_size_limit = self.config.test_size_limit + if not self._resolve_test_cases(): raise InvalidInitException('No test cases? What am I judging?') @@ -267,6 +271,7 @@ def __init__(self, problem_root_dir: str, **kwargs): super().__init__(**kwargs) self.problem_root_dir = problem_root_dir self.archive = None + self.test_size_limit = env.test_size_limit def __missing__(self, key: str) -> bytes: f: IO[bytes] @@ -276,6 +281,8 @@ def __missing__(self, key: str) -> bytes: except IOError: if self.archive: zipinfo = self.archive.getinfo(key) + if zipinfo.file_size > self.test_size_limit * 1024: + raise InternalError('test file is too large: %s' % key) with self.archive.open(zipinfo) as f: return f.read() raise KeyError('file "%s" could not be found in "%s"' % (key, self.problem_root_dir)) diff --git a/testsuite/test_size_limit/bomb.zip b/testsuite/test_size_limit/bomb.zip new file mode 100644 index 000000000..ef97f226d Binary files /dev/null and b/testsuite/test_size_limit/bomb.zip differ diff --git a/testsuite/test_size_limit/init.yml b/testsuite/test_size_limit/init.yml new file mode 100644 index 000000000..c8bc3e28a --- /dev/null +++ b/testsuite/test_size_limit/init.yml @@ -0,0 +1,4 @@ +archive: bomb.zip +test_size_limit: 65536 +test_cases: +- { in: 01.inp, out: 01.out } diff --git a/testsuite/test_size_limit/tests/py_ie/ie.py b/testsuite/test_size_limit/tests/py_ie/ie.py new file mode 100644 index 000000000..2ae28399f --- /dev/null +++ b/testsuite/test_size_limit/tests/py_ie/ie.py @@ -0,0 +1 @@ +pass diff --git a/testsuite/test_size_limit/tests/py_ie/test.yml b/testsuite/test_size_limit/tests/py_ie/test.yml new file mode 100644 index 000000000..41513b086 --- /dev/null +++ b/testsuite/test_size_limit/tests/py_ie/test.yml @@ -0,0 +1,6 @@ +language: PY3 +time: 1 +memory: 65536 +source: ie.py +expect: IE +feedback: 'test file is too large: 01.inp'