Blame SOURCES/squid-4.11-large-acl.patch

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 <>