# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
"""Check the .fc files for some common errors
@author:NicolasIooss
@license:GPLv2
"""
importargparse
frompathlibimportPath
importre
# Common patterns for ending a file pattern, associated with something to
# replace the pattern with, during the checks.
# Order matters as the first ones are tried before the last ones
#
# Use the infinity symbol to replace "any character", in order to keep a meaning
# of any possible character in the pattern after the reduction operations.
COMMON_FILE_END_PATTERNS=(
('/.+',''),# Match the children of a directory
('/.*',''),# Like /.+, but it could be empty
('(/.*)',''),# Like /.*, but with useless parentheses
('/[^/]+',''),# Match any filename
('/[^/]*',''),# Match any filename, but it could be empty
('(/[^/]*)',''),# Like /[^/]*, but with useless parentheses
('(/[^/]*)?',''),# Match a directory and its direct children
('(/.+)?',''),# Match a directory and its children
('(/.*)?',''),# Match a directory and its children
('/(sbin/)?.*',''),# Weird pattern for postfix, which would better be (/sbin)?(/.*)?
('\\.so(\\.[^/]*)*','\\.so'),# Match a .so extension, which is really weird because [^/] matches a dot too, so the final star can be replaced with '?' # noqa
('\\.db(\\.[^/]*)*','\\.db'),# Match a .db extension, which is really weird because [^/] matches a dot too, so the final star can be replaced with '?' # noqa
('(\\.[^/]+)?',''),# Match a possible file extension
('(\\..+)','\\.∞'),# Match a dot and anything after
('(\\..*)?','\\.∞'),# Match a dot and anything after or nothing, or nothing at all
('\\..*','\\.'),# Match a dot and anything after or nothing
('.*',''),# Match anything after
('.+','∞'),# Match anything after, but at least one character
('[^/]+','∞'),# Match anything after which does not create a new directory level
('[^/]*',''),# Like [^/]+, but may be empty
('[^/-]*',''),# Like [^/]*, but do not match files with dashes in their names
('[a-z]?',''),# Match a possible letter
('[a-z]*',''),# Match some letters
('[0-9]?',''),# Match a possible digit
('[0-9]*',''),# Match some digits
('[0-9]+','0'),# Match at least one digit
('(\\.bin)?',''),# Match an optional extension
('(-.*)?',''),# Match an optional suffix with a minus sign
print(f"{prefix}using ([^/]+/)? without a previous slash could be a bug in {path} as it can match the empty string, please use /([^/]+/)? instead")# noqa
print(f"{prefix}using (.*/)* without a previous slash could be a bug in {path} as it can match the empty string, please use /(.*/)* instead")# noqa
retval=False
ifre.search(r'\(\.\*/\)[^?*+]',path):
print(f"{prefix}using (.*/) without a ?, * or + symbol could be a bug in {path} as it misleads readers into thinking that this part is optional, please use .*/ instead")# noqa
retval=False
reduced_path=path
# Using "index`'(...)" is a way to prevent an error message from m4:
print(f"{prefix}unescaped dot still present {path} after being reduced to {reduced_path} (suggestion: use \\. to match a dot, or a charset like [^/])")# noqa
retval=False
# Check the remaining symbols in the reduced path.
# Only show a warning if no other ones were reported, in order to reduce the probability of false-positive.
print(f"{prefix}unexpected symbols {''.join(sorted(invalid_symbols))} in {path} after being reduced to {reduced_path}. This could be due to an error in the pattern or a missing reduction rule in the checker")# noqa
retval=False
returnretval
defanalyze_all_fc(policy_dirpath):
"""Analyze all .fc files in the specified directory"""