Skip to content

Commit

Permalink
Raise error if attachment pathname contains invalid bytes (#209)
Browse files Browse the repository at this point in the history
  • Loading branch information
Esther-Goldberg authored Apr 9, 2024
1 parent f45ae67 commit 5b606b1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
6 changes: 6 additions & 0 deletions snekbox/nsjail.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from snekbox.limits.timed import time_limit
from snekbox.result import EvalError, EvalResult
from snekbox.snekio import FileAttachment, MemFS
from snekbox.snekio.errors import IllegalPathError
from snekbox.snekio.filesystem import Size
from snekbox.utils.iter import iter_lstrip

Expand Down Expand Up @@ -244,6 +245,11 @@ def _parse_attachments(
except TimeoutError as e:
log.info(f"Exceeded time limit while parsing attachments: {e}")
raise EvalError("TimeoutError: Exceeded time limit while parsing attachments") from e
except IllegalPathError as e:
log.info(f"Invalid bytes in filename while parsing attachments: {e}")
raise EvalError(
"FileParsingError: invalid bytes in filename while parsing attachments"
) from e
except Exception as e:
log.exception(f"Unexpected {type(e).__name__} while parse attachments", exc_info=e)
raise EvalError("FileParsingError: Unknown error while parsing attachments") from e
Expand Down
9 changes: 9 additions & 0 deletions snekbox/snekio/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,17 @@ def from_path(cls, file: Path, relative_to: Path | None = None) -> FileAttachmen
Args:
file: The file to attach.
relative_to: The root for the path name.
Raises:
IllegalPathError: If path name contains characters that can't be encoded in UTF-8
"""
path = file.relative_to(relative_to) if relative_to else file

# Disallow filenames with chars that can't be encoded in UTF-8
try:
str(path).encode("utf-8")
except UnicodeEncodeError as e:
raise IllegalPathError("File paths may not contain invalid byte sequences") from e

return cls(str(path), file.read_bytes())

@property
Expand Down
14 changes: 14 additions & 0 deletions tests/test_nsjail.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,20 @@ def test_file_parsing_timeout(self):
)
self.assertEqual(result.stderr, None)

def test_filename_encoding_illegal_chars(self):
code = dedent(
r"""
with open(b"\xC3.txt", "w") as f:
f.write("test")
"""
).strip()
result = self.eval_file(code)
self.assertEqual(result.returncode, None)
self.assertEqual(
result.stdout, "FileParsingError: invalid bytes in filename while parsing attachments"
)
self.assertEqual(result.stderr, None)

def test_file_parsing_depth_limit(self):
code = dedent(
"""
Expand Down

0 comments on commit 5b606b1

Please sign in to comment.