39 static const Acl::Options MyOptions = { &MyCaseSensitivityOption };
50 debugs(28, 3,
"checking '" << word <<
"'");
53 for (
auto &i :
data) {
55 debugs(28, 2,
'\'' << i <<
"' found in '" << word <<
'\'');
71 for (
const auto &i:
data) {
72 i.
print(os, previous);
82 if (strcmp(t,
".*") == 0)
87 if (strncmp(t,
"^.*", 3) == 0)
93 while (*t ==
'.' && *(t+1) ==
'*') {
99 debugs(28,
DBG_IMPORTANT,
"WARNING: regular expression '" << orig <<
"' has only wildcards and matches all strings. Using '.*' instead.");
104 debugs(28,
DBG_IMPORTANT,
"WARNING: regular expression '" << orig <<
"' has unnecessary wildcard(s). Using '" << t <<
"' instead.");
113 curlist.emplace_back(RE, flags);
121 static const SBuf openparen(
"("), closeparen(
")"), separator(
")|(");
134 std::list<RegexPattern> newlist;
136 int numREs = 0, reSize = 0;
137 auto flags = flagsAtLineStart;
139 for (
const SBuf & configurationLineWord : sl) {
140 static const SBuf minus_i(
"-i");
141 static const SBuf plus_i(
"+i");
142 if (configurationLineWord == minus_i) {
143 if (flags & REG_ICASE) {
145 debugs(28, 2,
"optimisation of -i ... -i" );
148 if (!accumulatedRE.empty()) {
150 accumulatedRE.clear();
156 }
else if (configurationLineWord == plus_i) {
157 if ((flags & REG_ICASE) == 0) {
159 debugs(28, 2,
"optimisation of +i ... +i");
162 if (!accumulatedRE.empty()) {
164 accumulatedRE.clear();
172 debugs(28, 2,
"adding RE '" << configurationLineWord <<
"'");
173 accumulatedRE.push_back(configurationLineWord);
175 reSize += configurationLineWord.length();
178 debugs(28, 2,
"buffer full, generating new optimised RE..." );
180 accumulatedRE.clear();
186 if (!accumulatedRE.empty()) {
188 accumulatedRE.clear();
193 curlist.splice(curlist.end(), newlist);
195 debugs(28, 2, numREs <<
" REs are optimised into one RE.");
199 "Consider using less REs or use rules without expressions like 'dstdomain'.");
206 auto flags = flagsAtLineStart;
208 static const SBuf minus_i(
"-i"), plus_i(
"+i");
209 for (
const auto &configurationLineWord: sl) {
210 if (configurationLineWord == minus_i) {
212 }
else if (configurationLineWord == plus_i) {
215 compileRE(curlist, configurationLineWord, flags);
223 debugs(28, 2,
"new Regex line or file");
225 int flagsAtLineStart = REG_EXTENDED | REG_NOSUB;
227 flagsAtLineStart |= REG_ICASE;
232 debugs(28, 3,
"buffering RE '" << clean <<
"'");
233 sl.emplace_back(clean);
246 debugs(28,
DBG_IMPORTANT,
"WARNING: Failed to optimize a set of regular expressions; will use them as-is instead;" <<
SBuf & JoinContainerIntoSBuf(SBuf &dest, const ContainerIterator &begin, const ContainerIterator &end, const SBuf &separator, const SBuf &prefix=SBuf(), const SBuf &suffix=SBuf())
static void compileOptimisedREs(std::list< RegexPattern > &curlist, const SBufList &sl, const int flagsAtLineStart)
static void compileUnoptimisedREs(std::list< RegexPattern > &curlist, const SBufList &sl, const int flagsAtLineStart)
static void compileREs(std::list< RegexPattern > &curlist, const SBufList &RE, int flags)
static void compileRE(std::list< RegexPattern > &curlist, const SBuf &RE, int flags)
static const char * removeUnnecessaryWildcards(char *t)
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
char config_input_line[BUFSIZ]
const char * cfg_filename
const Acl::Options & lineOptions() override
supported ACL "line" options (e.g., "-i")
std::list< RegexPattern > data
static Acl::BooleanOptionValue CaseInsensitive_
whether parse() is called in a case insensitive context
bool empty() const override
bool match(char const *user) override
SBufList dump() const override
static char * RegexStrtokFile()
static std::ostream & Extra(std::ostream &)
void print(std::ostream &os, const RegexPattern *previous=nullptr) const
SBuf buf()
bytes written so far
const_iterator begin() const
#define debugs(SECTION, LEVEL, CONTENT)
const BooleanOption & CaseSensitivityOption()
std::vector< const Option * > Options
std::list< SBuf > SBufList