Skip to content

Commit 1fdea4c

Browse files
Guard better agains non-unicode feedback
1 parent b850e32 commit 1fdea4c

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

problemtools/tests/test_unicode.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import random
2+
import pathlib
3+
import tempfile
4+
5+
from problemtools.verifyproblem import OutputValidators
6+
7+
8+
def test_output_validator_unicode():
9+
r = random.Random(0)
10+
with tempfile.TemporaryDirectory() as directory:
11+
feedback = pathlib.Path(directory) / "feedback.txt"
12+
feedback.write_bytes(r.randbytes(1024))
13+
# This should just not throw an error
14+
OutputValidators._get_feedback(directory)

problemtools/verifyproblem.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,7 @@ def __str__(self) -> str:
11861186

11871187
_JUNK_CASES = [
11881188
('an empty file', b''),
1189-
('a binary file with byte values 0 up to 127', bytearray(x for x in range(127))),
1189+
('a binary file with random bytes', bytearray(random.Random(0).randbytes(1024))),
11901190
('a text file with the ASCII characters 32 up to 127', bytearray(x for x in range(32, 127))),
11911191
('a random text file with printable ASCII characters', bytearray(random.choice(string.printable.encode('utf8')) for _ in range(200))),
11921192
]
@@ -1479,15 +1479,15 @@ def check(self, args: argparse.Namespace) -> bool:
14791479
return self._check_res
14801480

14811481
@staticmethod
1482-
def __get_feedback(feedback_dir: str) -> str|None:
1482+
def _get_feedback(feedback_dir: str) -> str|None:
14831483
all_feedback = []
14841484
for feedback_file in os.listdir(feedback_dir):
14851485
feedback_path = os.path.join(feedback_dir, feedback_file)
14861486
if os.path.getsize(feedback_path) == 0:
14871487
continue
14881488
all_feedback.append(f'=== {feedback_file}: ===')
1489-
# FIXME handle feedback files containing non-text
1490-
with open(feedback_path, 'r') as feedback:
1489+
# Note: The file could contain non-unicode characters, "replace" to be on the safe side
1490+
with open(feedback_path, 'r', errors="replace") as feedback:
14911491
# Cap amount of feedback per file at some high-ish
14921492
# size, so that a buggy validator spewing out lots of
14931493
# data doesn't kill us.
@@ -1508,15 +1508,15 @@ def _parse_validator_results(self, val, status: int, feedbackdir, testcase: Test
15081508
if not os.WIFEXITED(status):
15091509
return SubmissionResult('JE',
15101510
reason=f'output validator {val} crashed, status {status}',
1511-
additional_info=OutputValidators.__get_feedback(feedbackdir))
1511+
additional_info=OutputValidators._get_feedback(feedbackdir))
15121512
ret = os.WEXITSTATUS(status)
15131513
if ret not in [42, 43]:
15141514
return SubmissionResult('JE',
15151515
reason=f'output validator {val} exited with status {ret}',
1516-
additional_info=OutputValidators.__get_feedback(feedbackdir))
1516+
additional_info=OutputValidators._get_feedback(feedbackdir))
15171517

15181518
if ret == 43:
1519-
return SubmissionResult('WA', additional_info=OutputValidators.__get_feedback(feedbackdir))
1519+
return SubmissionResult('WA', additional_info=OutputValidators._get_feedback(feedbackdir))
15201520

15211521
if custom_score:
15221522
if os.path.isfile(score_file):

0 commit comments

Comments
 (0)