summaryrefslogtreecommitdiffstats
path: root/test/lib/ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py
blob: 10bf4aaa15b6c95705b68bd3168aba8951995ef0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"""
Check for illegal filenames on various operating systems.
The main rules are derived from restrictions on Windows:
https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
"""
from __future__ import annotations

import os
import struct
import sys

from ansible.module_utils.basic import to_bytes

ILLEGAL_CHARS = [
    b'<',
    b'>',
    b':',
    b'"',
    b'/',
    b'\\',
    b'|',
    b'?',
    b'*'
] + [struct.pack("b", i) for i in range(32)]

ILLEGAL_NAMES = [
    "CON",
    "PRN",
    "AUX",
    "NUL",
    "COM1",
    "COM2",
    "COM3",
    "COM4",
    "COM5",
    "COM6",
    "COM7",
    "COM8",
    "COM9",
    "LPT1",
    "LPT2",
    "LPT3",
    "LPT4",
    "LPT5",
    "LPT6",
    "LPT7",
    "LPT8",
    "LPT9",
]

ILLEGAL_END_CHARS = [
    '.',
    ' ',
]


def check_path(path, is_dir=False):
    """Check the specified path for unwanted characters and names."""
    type_name = 'directory' if is_dir else 'file'
    file_name = os.path.basename(path.rstrip(os.path.sep))
    name = os.path.splitext(file_name)[0]

    if name.upper() in ILLEGAL_NAMES:
        print("%s: illegal %s name %s" % (path, type_name, name.upper()))

    if file_name[-1] in ILLEGAL_END_CHARS:
        print("%s: illegal %s name end-char '%s'" % (path, type_name, file_name[-1]))

    bfile = to_bytes(file_name, encoding='utf-8')
    for char in ILLEGAL_CHARS:
        if char in bfile:
            bpath = to_bytes(path, encoding='utf-8')
            print("%s: illegal char '%s' in %s name" % (bpath, char, type_name))


def main():
    """Main entry point."""
    for path in sys.argv[1:] or sys.stdin.read().splitlines():
        check_path(path, is_dir=path.endswith(os.path.sep))


if __name__ == '__main__':
    main()