autograder.util.path

 1import os
 2import typing
 3
 4THIS_DIR: str = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
 5
 6RESERVED_NAMES: typing.FrozenSet[str] = frozenset(
 7    {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} |  # noqa: W504
 8    {f'COM{c}' for c in '123456789\xb9\xb2\xb3'} |  # noqa: W504
 9    {f'LPT{c}' for c in '123456789\xb9\xb2\xb3'}
10)
11"""
12Reserved filenames (mainly on Windows).
13See: https://github.com/python/cpython/blob/3.13/Lib/ntpath.py
14"""
15
16def is_local(path: str) -> bool:
17    """
18    Try to see of a file is "local" using only lexical analysis.
19    See: https://pkg.go.dev/path/filepath#IsLocal
20    This is not robust and should not be used for any systems where security can be an issue.
21    """
22
23    path = os.path.normpath(path.strip())
24
25    if (path == ''):
26        return False
27
28    if (os.path.isabs(path)):
29        return False
30
31    if (_is_reserved(path)):
32        return False
33
34    # To see if the path does not break out of the current directory,
35    # join it to the current directory and see if the current
36    # directory is still a base path.
37
38    current_path = THIS_DIR
39
40    # Note that the normalization should remove any (or several)
41    # parent references ('..') at this point.
42    test_path = os.path.normpath(os.path.join(THIS_DIR, path))
43
44    common_prefix = os.path.commonprefix([current_path, test_path])
45    if (common_prefix != current_path):
46        return False
47
48    return True
49
50def _is_reserved(path: str) -> bool:
51    """
52    A very weak version of ntpath.isreserved(path) (which was added in version 3.13).
53    https://docs.python.org/3/library/os.path.html#os.path.isreserved
54    """
55
56    return os.path.basename(path).upper() in RESERVED_NAMES
THIS_DIR: str = '/home/runner/work/autograder-py/autograder-py/autograder/util'
RESERVED_NAMES: FrozenSet[str] = frozenset({'COM5', 'COM7', 'COM²', 'LPT¹', 'LPT3', 'LPT5', 'COM4', 'LPT4', 'NUL', 'COM3', 'COM1', 'LPT³', 'CON', 'COM2', 'LPT7', 'CONOUT$', 'LPT²', 'COM8', 'LPT1', 'LPT2', 'PRN', 'COM9', 'COM³', 'LPT6', 'COM6', 'AUX', 'LPT8', 'COM¹', 'CONIN$', 'LPT9'})

Reserved filenames (mainly on Windows). See: https://github.com/python/cpython/blob/3.13/Lib/ntpath.py

def is_local(path: str) -> bool:
17def is_local(path: str) -> bool:
18    """
19    Try to see of a file is "local" using only lexical analysis.
20    See: https://pkg.go.dev/path/filepath#IsLocal
21    This is not robust and should not be used for any systems where security can be an issue.
22    """
23
24    path = os.path.normpath(path.strip())
25
26    if (path == ''):
27        return False
28
29    if (os.path.isabs(path)):
30        return False
31
32    if (_is_reserved(path)):
33        return False
34
35    # To see if the path does not break out of the current directory,
36    # join it to the current directory and see if the current
37    # directory is still a base path.
38
39    current_path = THIS_DIR
40
41    # Note that the normalization should remove any (or several)
42    # parent references ('..') at this point.
43    test_path = os.path.normpath(os.path.join(THIS_DIR, path))
44
45    common_prefix = os.path.commonprefix([current_path, test_path])
46    if (common_prefix != current_path):
47        return False
48
49    return True

Try to see of a file is "local" using only lexical analysis. See: https://pkg.go.dev/path/filepath#IsLocal This is not robust and should not be used for any systems where security can be an issue.