|
|
3921f5 |
diff --git a/src/acl/RegexData.cc b/src/acl/RegexData.cc
|
|
|
3921f5 |
index 01a4c12..b5c1679 100644
|
|
|
3921f5 |
--- a/src/acl/RegexData.cc
|
|
|
3921f5 |
+++ b/src/acl/RegexData.cc
|
|
|
3921f5 |
@@ -22,6 +22,7 @@
|
|
|
3921f5 |
#include "ConfigParser.h"
|
|
|
3921f5 |
#include "Debug.h"
|
|
|
3921f5 |
#include "sbuf/List.h"
|
|
|
3921f5 |
+#include "sbuf/Algorithms.h"
|
|
|
3921f5 |
|
|
|
3921f5 |
ACLRegexData::~ACLRegexData()
|
|
|
3921f5 |
{
|
|
|
3921f5 |
@@ -129,6 +130,18 @@ compileRE(std::list<RegexPattern> &curlist, const char * RE, int flags)
|
|
|
3921f5 |
return true;
|
|
|
3921f5 |
}
|
|
|
3921f5 |
|
|
|
3921f5 |
+static bool
|
|
|
3921f5 |
+compileRE(std::list<RegexPattern> &curlist, const SBufList &RE, int flags)
|
|
|
3921f5 |
+{
|
|
|
3921f5 |
+ if (RE.empty())
|
|
|
3921f5 |
+ return curlist.empty(); // XXX: old code did this. It looks wrong.
|
|
|
3921f5 |
+ SBuf regexp;
|
|
|
3921f5 |
+ static const SBuf openparen("("), closeparen(")"), separator(")|(");
|
|
|
3921f5 |
+ JoinContainerIntoSBuf(regexp, RE.begin(), RE.end(), separator, openparen,
|
|
|
3921f5 |
+ closeparen);
|
|
|
3921f5 |
+ return compileRE(curlist, regexp.c_str(), flags);
|
|
|
3921f5 |
+}
|
|
|
3921f5 |
+
|
|
|
3921f5 |
/** Compose and compile one large RE from a set of (small) REs.
|
|
|
3921f5 |
* The ultimate goal is to have only one RE per ACL so that match() is
|
|
|
3921f5 |
* called only once per ACL.
|
|
|
3921f5 |
@@ -137,16 +150,11 @@ static int
|
|
|
3921f5 |
compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
|
|
|
3921f5 |
{
|
|
|
3921f5 |
std::list<RegexPattern> newlist;
|
|
|
3921f5 |
- int numREs = 0;
|
|
|
3921f5 |
+ SBufList accumulatedRE;
|
|
|
3921f5 |
+ int numREs = 0, reSize = 0;
|
|
|
3921f5 |
int flags = REG_EXTENDED | REG_NOSUB;
|
|
|
3921f5 |
- int largeREindex = 0;
|
|
|
3921f5 |
- char largeRE[BUFSIZ];
|
|
|
3921f5 |
- *largeRE = 0;
|
|
|
3921f5 |
|
|
|
3921f5 |
for (const SBuf & configurationLineWord : sl) {
|
|
|
3921f5 |
- int RElen;
|
|
|
3921f5 |
- RElen = configurationLineWord.length();
|
|
|
3921f5 |
-
|
|
|
3921f5 |
static const SBuf minus_i("-i");
|
|
|
3921f5 |
static const SBuf plus_i("+i");
|
|
|
3921f5 |
if (configurationLineWord == minus_i) {
|
|
|
3921f5 |
@@ -155,10 +163,11 @@ compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
|
|
|
3921f5 |
debugs(28, 2, "optimisation of -i ... -i" );
|
|
|
3921f5 |
} else {
|
|
|
3921f5 |
debugs(28, 2, "-i" );
|
|
|
3921f5 |
- if (!compileRE(newlist, largeRE, flags))
|
|
|
3921f5 |
+ if (!compileRE(newlist, accumulatedRE, flags))
|
|
|
3921f5 |
return 0;
|
|
|
3921f5 |
flags |= REG_ICASE;
|
|
|
3921f5 |
- largeRE[largeREindex=0] = '\0';
|
|
|
3921f5 |
+ accumulatedRE.clear();
|
|
|
3921f5 |
+ reSize = 0;
|
|
|
3921f5 |
}
|
|
|
3921f5 |
} else if (configurationLineWord == plus_i) {
|
|
|
3921f5 |
if ((flags & REG_ICASE) == 0) {
|
|
|
3921f5 |
@@ -166,37 +175,34 @@ compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
|
|
|
3921f5 |
debugs(28, 2, "optimisation of +i ... +i");
|
|
|
3921f5 |
} else {
|
|
|
3921f5 |
debugs(28, 2, "+i");
|
|
|
3921f5 |
- if (!compileRE(newlist, largeRE, flags))
|
|
|
3921f5 |
+ if (!compileRE(newlist, accumulatedRE, flags))
|
|
|
3921f5 |
return 0;
|
|
|
3921f5 |
flags &= ~REG_ICASE;
|
|
|
3921f5 |
- largeRE[largeREindex=0] = '\0';
|
|
|
3921f5 |
+ accumulatedRE.clear();
|
|
|
3921f5 |
+ reSize = 0;
|
|
|
3921f5 |
}
|
|
|
3921f5 |
- } else if (RElen + largeREindex + 3 < BUFSIZ-1) {
|
|
|
3921f5 |
+ } else if (reSize < 1024) {
|
|
|
3921f5 |
debugs(28, 2, "adding RE '" << configurationLineWord << "'");
|
|
|
3921f5 |
- if (largeREindex > 0) {
|
|
|
3921f5 |
- largeRE[largeREindex] = '|';
|
|
|
3921f5 |
- ++largeREindex;
|
|
|
3921f5 |
- }
|
|
|
3921f5 |
- largeRE[largeREindex] = '(';
|
|
|
3921f5 |
- ++largeREindex;
|
|
|
3921f5 |
- configurationLineWord.copy(largeRE+largeREindex, BUFSIZ-largeREindex);
|
|
|
3921f5 |
- largeREindex += configurationLineWord.length();
|
|
|
3921f5 |
- largeRE[largeREindex] = ')';
|
|
|
3921f5 |
- ++largeREindex;
|
|
|
3921f5 |
- largeRE[largeREindex] = '\0';
|
|
|
3921f5 |
+ accumulatedRE.push_back(configurationLineWord);
|
|
|
3921f5 |
++numREs;
|
|
|
3921f5 |
+ reSize += configurationLineWord.length();
|
|
|
3921f5 |
} else {
|
|
|
3921f5 |
debugs(28, 2, "buffer full, generating new optimised RE..." );
|
|
|
3921f5 |
- if (!compileRE(newlist, largeRE, flags))
|
|
|
3921f5 |
+ accumulatedRE.push_back(configurationLineWord);
|
|
|
3921f5 |
+ if (!compileRE(newlist, accumulatedRE, flags))
|
|
|
3921f5 |
return 0;
|
|
|
3921f5 |
- largeRE[largeREindex=0] = '\0';
|
|
|
3921f5 |
+ accumulatedRE.clear();
|
|
|
3921f5 |
+ reSize = 0;
|
|
|
3921f5 |
continue; /* do the loop again to add the RE to largeRE */
|
|
|
3921f5 |
}
|
|
|
3921f5 |
}
|
|
|
3921f5 |
|
|
|
3921f5 |
- if (!compileRE(newlist, largeRE, flags))
|
|
|
3921f5 |
+ if (!compileRE(newlist, accumulatedRE, flags))
|
|
|
3921f5 |
return 0;
|
|
|
3921f5 |
|
|
|
3921f5 |
+ accumulatedRE.clear();
|
|
|
3921f5 |
+ reSize = 0;
|
|
|
3921f5 |
+
|
|
|
3921f5 |
/* all was successful, so put the new list at the tail */
|
|
|
3921f5 |
curlist.splice(curlist.end(), newlist);
|
|
|
3921f5 |
|
|
|
3921f5 |
diff --git a/src/sbuf/Algorithms.h b/src/sbuf/Algorithms.h
|
|
|
3921f5 |
index 21ee889..338e9c0 100644
|
|
|
3921f5 |
--- a/src/sbuf/Algorithms.h
|
|
|
3921f5 |
+++ b/src/sbuf/Algorithms.h
|
|
|
3921f5 |
@@ -81,6 +81,57 @@ SBufContainerJoin(const Container &items, const SBuf& separator)
|
|
|
3921f5 |
return rv;
|
|
|
3921f5 |
}
|
|
|
3921f5 |
|
|
|
3921f5 |
+/** Join container of SBufs and append to supplied target
|
|
|
3921f5 |
+ *
|
|
|
3921f5 |
+ * append to the target SBuf all elements in the [begin,end) range from
|
|
|
3921f5 |
+ * an iterable container, prefixed by prefix, separated by separator and
|
|
|
3921f5 |
+ * followed by suffix. Prefix and suffix are added also in case of empty
|
|
|
3921f5 |
+ * iterable
|
|
|
3921f5 |
+ *
|
|
|
3921f5 |
+ * \return the modified dest
|
|
|
3921f5 |
+ */
|
|
|
3921f5 |
+template <class ContainerIterator>
|
|
|
3921f5 |
+SBuf&
|
|
|
3921f5 |
+JoinContainerIntoSBuf(SBuf &dest, const ContainerIterator &begin,
|
|
|
3921f5 |
+ const ContainerIterator &end, const SBuf& separator,
|
|
|
3921f5 |
+ const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf())
|
|
|
3921f5 |
+{
|
|
|
3921f5 |
+ if (begin == end) {
|
|
|
3921f5 |
+ dest.append(prefix).append(suffix);
|
|
|
3921f5 |
+ return dest;
|
|
|
3921f5 |
+ }
|
|
|
3921f5 |
+
|
|
|
3921f5 |
+ // optimization: pre-calculate needed storage
|
|
|
3921f5 |
+ const SBuf::size_type totalContainerSize =
|
|
|
3921f5 |
+ std::accumulate(begin, end, 0, SBufAddLength(separator)) +
|
|
|
3921f5 |
+ dest.length() + prefix.length() + suffix.length();
|
|
|
3921f5 |
+ SBufReservationRequirements req;
|
|
|
3921f5 |
+ req.minSpace = totalContainerSize;
|
|
|
3921f5 |
+ dest.reserve(req);
|
|
|
3921f5 |
+
|
|
|
3921f5 |
+ auto i = begin;
|
|
|
3921f5 |
+ dest.append(prefix);
|
|
|
3921f5 |
+ dest.append(*i);
|
|
|
3921f5 |
+ ++i;
|
|
|
3921f5 |
+ for (; i != end; ++i)
|
|
|
3921f5 |
+ dest.append(separator).append(*i);
|
|
|
3921f5 |
+ dest.append(suffix);
|
|
|
3921f5 |
+ return dest;
|
|
|
3921f5 |
+}
|
|
|
3921f5 |
+
|
|
|
3921f5 |
+
|
|
|
3921f5 |
+/// convenience wrapper of JoinContainerIntoSBuf with no caller-supplied SBuf
|
|
|
3921f5 |
+template <class ContainerIterator>
|
|
|
3921f5 |
+SBuf
|
|
|
3921f5 |
+JoinContainerToSBuf(const ContainerIterator &begin,
|
|
|
3921f5 |
+ const ContainerIterator &end, const SBuf& separator,
|
|
|
3921f5 |
+ const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf())
|
|
|
3921f5 |
+{
|
|
|
3921f5 |
+ SBuf rv;
|
|
|
3921f5 |
+ return JoinContainerIntoSBuf(rv, begin, end, separator, prefix, suffix);
|
|
|
3921f5 |
+}
|
|
|
3921f5 |
+
|
|
|
3921f5 |
+
|
|
|
3921f5 |
namespace std {
|
|
|
3921f5 |
/// default hash functor to support std::unordered_map<SBuf,*>
|
|
|
3921f5 |
template <>
|