git subrepo pull (merge) mailcow/src/mailcow-dockerized

Among other things, this updates Dovecot to 2.3.13, which is a
critical security update.

subrepo: subdir:   "mailcow/src/mailcow-dockerized"
  merged:   "376574d9"
upstream: origin:   "https://github.com/mailcow/mailcow-dockerized.git"
  branch:   "master"
  commit:   "6f14955b"
git-subrepo: version:  "0.4.3"
  origin:   "???"
  commit:   "???"
Change-Id: Idf4859ddaaebf6997afbb0cebffc8bf3f5b902a0
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/.github/FUNDING.yml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/.github/FUNDING.yml
new file mode 100644
index 0000000..9b98688
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: [matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/Dockerfile b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/Dockerfile
index d17f9d7..fc36a81 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/Dockerfile
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/Dockerfile
@@ -6,7 +6,7 @@
 
 RUN apt-get update
 RUN apt-get install -y zip unzip zlib1g-dev
-RUN docker-php-ext-install zip
+RUN if [[ `php-config --vernum` -ge 73000 ]]; then docker-php-ext-install zip; fi
 RUN docker-php-ext-install pcntl
 RUN curl -sS https://getcomposer.org/installer | php
 RUN mv composer.phar /usr/local/bin/composer
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/docker-compose.yml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/docker-compose.yml
index 5413e24..cb7ace1 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/docker-compose.yml
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/docker-compose.yml
@@ -9,6 +9,21 @@
       - ./data:/var/www/data
       - ./tests:/var/www/tests
       - ./phpunit.xml.dist:/var/www/phpunit.xml.dist
+  '8.0':
+    extends: php
+    build:
+      args:
+        version: 8.0-cli
+  '7.4':
+    extends: php
+    build:
+      args:
+        version: 7.4-cli
+  '7.3':
+    extends: php
+    build:
+      args:
+        version: 7.3-cli
   '7.2':
     extends: php
     build:
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/src/CSS.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/src/CSS.php
index 89fcf1b..ea8e8cd 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/src/CSS.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/matthiasmullie/minify/src/CSS.php
@@ -216,7 +216,7 @@
 
             // grab referenced file & minify it (which may include importing
             // yet other @import statements recursively)
-            $minifier = new static($importPath);
+            $minifier = new self($importPath);
             $minifier->setMaxImportSize($this->maxImportSize);
             $minifier->setImportExtensions($this->importExtensions);
             $importContent = $minifier->execute($source, $parents);
@@ -307,7 +307,8 @@
              */
             $this->extractStrings();
             $this->stripComments();
-            $this->extractCalcs();
+            $this->extractMath();
+            $this->extractCustomProperties();
             $css = $this->replace($css);
 
             $css = $this->stripWhitespace($css);
@@ -678,19 +679,29 @@
     }
 
     /**
-     * Replace all `calc()` occurrences.
+     * Replace all occurrences of functions that may contain math, where
+     * whitespace around operators needs to be preserved (e.g. calc, clamp)
      */
-    protected function extractCalcs()
+    protected function extractMath()
     {
+        $functions = array('calc', 'clamp', 'min', 'max');
+        $pattern = '/('. implode('|', $functions) .')(\(.+?)(?=$|;|})/m';
+
         // PHP only supports $this inside anonymous functions since 5.4
         $minifier = $this;
-        $callback = function ($match) use ($minifier) {
-            $length = strlen($match[1]);
+        $callback = function ($match) use ($minifier, $pattern, &$callback) {
+            $function = $match[1];
+            $length = strlen($match[2]);
             $expr = '';
             $opened = 0;
 
+            // the regular expression for extracting math has 1 significant problem:
+            // it can't determine the correct closing parenthesis...
+            // instead, it'll match a larger portion of code to where it's certain that
+            // the calc() musts have ended, and we'll figure out which is the correct
+            // closing parenthesis here, by counting how many have opened
             for ($i = 0; $i < $length; $i++) {
-                $char = $match[1][$i];
+                $char = $match[2][$i];
                 $expr .= $char;
                 if ($char === '(') {
                     $opened++;
@@ -698,18 +709,41 @@
                     break;
                 }
             }
-            $rest = str_replace($expr, '', $match[1]);
-            $expr = trim(substr($expr, 1, -1));
 
+            // now that we've figured out where the calc() starts and ends, extract it
             $count = count($minifier->extracted);
-            $placeholder = 'calc('.$count.')';
-            $minifier->extracted[$placeholder] = 'calc('.$expr.')';
+            $placeholder = 'math('.$count.')';
+            $minifier->extracted[$placeholder] = $function.'('.trim(substr($expr, 1, -1)).')';
+
+            // and since we've captured more code than required, we may have some leftover
+            // calc() in here too - go recursive on the remaining but of code to go figure
+            // that out and extract what is needed
+            $rest = str_replace($function.$expr, '', $match[0]);
+            $rest = preg_replace_callback($pattern, $callback, $rest);
 
             return $placeholder.$rest;
         };
 
-        $this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/', $callback);
-        $this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/m', $callback);
+        $this->registerPattern($pattern, $callback);
+    }
+
+    /**
+     * Replace custom properties, whose values may be used in scenarios where
+     * we wouldn't want them to be minified (e.g. inside calc)
+     */
+    protected function extractCustomProperties()
+    {
+        // PHP only supports $this inside anonymous functions since 5.4
+        $minifier = $this;
+        $this->registerPattern(
+            '/(?<=^|[;}])(--[^:;{}"\'\s]+)\s*:([^;{}]+)/m',
+            function ($match) use ($minifier) {
+                $placeholder = '--custom-'. count($minifier->extracted) . ':0';
+                $minifier->extracted[$placeholder] = $match[1] .':'. trim($match[2]);
+                return $placeholder;
+
+            }
+        );
     }
 
     /**