matthiasmullie / minify

CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.
https://matthiasmullie.github.io/minify/
MIT License
1.96k stars 310 forks source link

CSS class extractMath() method has a bug. An example and a solution are provided #371

Closed alexey4453 closed 2 years ago

alexey4453 commented 3 years ago

Consider this part of code is inside a CSS file about to be minified:

.list-courses {
  display: grid;
  grid-template-columns: calc(50% - 20px) calc(25% - 20px) calc(25% - 20px);
}

Here is the minified output: .list-courses{display:grid;grid-template-columns:calc(50% - 20px) calc(25% - 20px)}

We have just lost the third parameter of the grid-template-columns property.

What causes the bug? The code which is responsive for this buggy behavior is in this file: matthiasmullie/minify/src/CSS.php

function extractMath() {
...
$rest = str_replace($function.$expr, '', $match[0]);
...
};

As you can now understand $function.$expr will match not only the processed math expression but all unprocessed maths as well.

What is the solution? I suggest to replace the line of code: $rest = str_replace($function.$expr, '', $match[0]);

To this:

$rest = "";
$pos = strpos($match[0], $function.$expr);
if ($pos !== false) {
   $rest = substr_replace($match[0], '', $pos, strlen($function.$expr));
}

In such case only the first matching occurrence will be replaced. Now the resulting minified CSS code is correct.

simondud commented 2 years ago

Thanks @alexey4453 the fix is applied - we used a function in case we will need it in other situations.