PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | vendor/matthiasmullie/minify/src/Minify.php +40 -29 3.4.2 → 4.7.0 View file →
@@ -12,8 +12,9 @@
12 12
13 13 namespace MatthiasMullie\Minify;
14 14
15 15 use MatthiasMullie\Minify\Exceptions\IOException;
16 +use MatthiasMullie\Minify\Exceptions\PatternMatchException;
16 17 use Psr\Cache\CacheItemInterface;
17 18
18 19 /**
19 20 * Abstract minifier class.
@@ -229,9 +230,9 @@
229 230 /**
230 231 * Save to file.
231 232 *
232 233 * @param string $content The minified data
233 - * @param string $path The path to save the minified data to
234 + * @param string $path The path to save the minified data to
234 235 *
235 236 * @throws IOException
236 237 */
237 238 protected function save($content, $path)
@@ -248,9 +249,9 @@
248 249 *
249 250 * If $replacement is a string, it must be plain text. Placeholders like $1 or \2 don't work.
250 251 * If you need that functionality, use a callback instead.
251 252 *
252 - * @param string $pattern PCRE pattern
253 + * @param string $pattern PCRE pattern
253 254 * @param string|callable $replacement Replacement value for matched pattern
254 255 */
255 256 protected function registerPattern($pattern, $replacement = '')
256 257 {
@@ -264,25 +265,11 @@
264 265 * Both JS and CSS use the same form of multi-line comment, so putting the common code here.
265 266 */
266 267 protected function stripMultilineComments()
267 268 {
268 - // First extract comments we want to keep, so they can be restored later
269 - // PHP only supports $this inside anonymous functions since 5.4
270 269 $minifier = $this;
271 - $callback = function ($match) use ($minifier) {
272 - $count = count($minifier->extracted);
273 - $placeholder = '/*' . $count . '*/';
274 - $minifier->extracted[$placeholder] = $match[0];
275 -
276 - return $placeholder;
277 - };
278 - $this->registerPattern('/
279 - # optional newline
280 - \n?
281 -
282 - # start comment
283 - \/\*
284 -
270 + // Pattern for matching comments that we want to preserve
271 + $keepPattern = '/^
285 272 # comment content
286 273 (?:
287 274 # either starts with an !
288 275 !
@@ -292,16 +279,26 @@
292 279
293 280 # there is either a @license or @preserve tag
294 281 @(?:license|preserve)
295 282 )
283 + /ixs';
284 + $callback = function ($match) use ($minifier, $keepPattern) {
285 + if (preg_match($keepPattern, $match[1])) {
286 + // Preserve the comment
287 + $count = count($minifier->extracted);
288 + $placeholder = '/*' . $count . '*/';
289 + $minifier->extracted[$placeholder] = $match[0];
290 + } else {
291 + // Discard the comment but keep any single line feed
292 + $placeholder = strncmp($match[0], "\n", 1) === 0 || substr($match[0], -1) === "\n"
293 + ? "\n"
294 + : '';
295 + }
296 296
297 - # then match to the end of the comment
298 - .*?\*\/\n?
297 + return $placeholder;
298 + };
299 299
300 - /ixs', $callback);
301 -
302 - // Then strip all other comments
303 - $this->registerPattern('/\/\*.*?\*\//s', '');
300 + $this->registerPattern('/\n?\/\*(.*?)\*\/\n?/s', $callback);
304 301 }
305 302
306 303 /**
307 304 * We can't "just" run some regular expressions against JavaScript: it's a
@@ -313,8 +310,10 @@
313 310 *
314 311 * @param string $content The content to replace patterns in
315 312 *
316 313 * @return string The (manipulated) content
314 + *
315 + * @throws PatternMatchException
317 316 */
318 317 protected function replace($content)
319 318 {
320 319 $contentLength = strlen($content);
@@ -340,9 +339,10 @@
340 339 continue;
341 340 }
342 341
343 342 $match = null;
344 - if (preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE, $processedOffset)) {
343 + $matchResult = preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE, $processedOffset);
344 + if ($matchResult) {
345 345 $matches[$i] = $match;
346 346
347 347 // we'll store the match position as well; that way, we
348 348 // don't have to redo all preg_matches after changing only
@@ -348,8 +348,13 @@
348 348 // don't have to redo all preg_matches after changing only
349 349 // the first (we'll still know where those others are)
350 350 $positions[$i] = $match[0][1];
351 351 } else {
352 + if ($matchResult === false) {
353 + throw PatternMatchException::fromLastError(
354 + "Failed to match pattern '$pattern' at $processedOffset"
355 + );
356 + }
352 357 // if the pattern couldn't be matched, there's no point in
353 358 // executing it again in later runs on this same content;
354 359 // ignore this one until we reach end of content
355 360 unset($matches[$i], $positions[$i]);
@@ -389,9 +394,9 @@
389 394 * If $replacement is a callback, execute it, passing in the match data.
390 395 * If it's a string, just pass it through.
391 396 *
392 397 * @param string|callable $replacement Replacement value
393 - * @param array $match Match data, in PREG_OFFSET_CAPTURE form
398 + * @param array $match Match data, in PREG_OFFSET_CAPTURE form
394 399 *
395 400 * @return string
396 401 */
397 402 protected function executeReplacement($replacement, $match)
@@ -444,8 +449,13 @@
444 449 return $placeholder;
445 450 };
446 451
447 452 /*
453 + * Quantifier {0,65535} is used instead of *? to avoid exceeding
454 + * backtrack limit with large strings. 65535 is the maximum allowed
455 + * (see https://www.php.net/manual/en/regexp.reference.repetition.php)
456 + * and should be well sufficient for string representations here.
457 + *
448 458 * The \\ messiness explained:
449 459 * * Don't count ' or " as end-of-string if it's escaped (has backslash
450 460 * in front of it)
451 461 * * Unless... that backslash itself is escaped (another leading slash),
@@ -455,9 +465,10 @@
455 465 * to be done to pass the backslash into the PHP string without it being
456 466 * considered as escape-char (times 2) and to get it in the regex,
457 467 * escaped (times 2)
458 468 */
459 - $this->registerPattern('/([' . $chars . '])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
469 +
470 + $this->registerPattern('/([' . $chars . '])(.{0,65535}?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
460 471 }
461 472
462 473 /**
463 474 * This method will restore all extracted data (strings, regexes) that were
@@ -531,10 +542,10 @@
531 542 /**
532 543 * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions.
533 544 *
534 545 * @param resource $handler The resource to write to
535 - * @param string $content The content to write
536 - * @param string $path The path to the file (for exception printing only)
546 + * @param string $content The content to write
547 + * @param string $path The path to the file (for exception printing only)
537 548 *
538 549 * @throws IOException
539 550 */
540 551 protected function writeToFile($handler, $content, $path = '')