Skip to content

Commit dfae066

Browse files
committed
Fix issue #385 - for(;;) without body but containig closures inside brackets.
1 parent 37c14b9 commit dfae066

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/JS.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,19 @@ protected function stripWhitespace($content)
415415
* to be the for-loop's body... Same goes for while loops.
416416
* I'm going to double that semicolon (if any) so after the next line,
417417
* which strips semicolons here & there, we're still left with this one.
418+
* Note the special recursive construct in the three inner parts of the for:
419+
* (\{([^\{\}]*(?-2))*[^\{\}]*\})? - it is intended to match inline
420+
* functions bodies, e.g.: i<arr.map(function(e){return e}).length.
421+
* Also note that the construct is applied only once and multiplied
422+
* for each part of the for, otherwise it risks a catastrophic backtracking.
423+
* The limitation is that it will not allow closures in more than one
424+
* of the three parts for a specific for() case.
425+
* REGEX throwing catastrophic backtracking: $content = preg_replace('/(for\([^;\{]*(\{([^\{\}]*(?-2))*[^\{\}]*\})?[^;\{]*;[^;\{]*(\{([^\{\}]*(?-2))*[^\{\}]*\})?[^;\{]*;[^;\{]*(\{([^\{\}]*(?-2))*[^\{\}]*\})?[^;\{]*\));(\}|$)/s', '\\1;;\\8', $content);
418426
*/
419-
$content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
427+
$content = preg_replace('/(for\([^;\{]*(\{([^\{\}]*(?-2))*[^\{\}]*\})?[^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\4', $content);
428+
$content = preg_replace('/(for\([^;\{]*;[^;\{]*(\{([^\{\}]*(?-2))*[^\{\}]*\})?[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\4', $content);
429+
$content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*(\{([^\{\}]*(?-2))*[^\{\}]*\})?[^;\{]*\));(\}|$)/s', '\\1;;\\4', $content);
430+
420431
$content = preg_replace('/(for\([^;\{]+\s+in\s+[^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
421432
/*
422433
* Below will also keep `;` after a `do{}while();` along with `while();`

tests/js/JSTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,20 @@ function someOtherFunction() {
13071307
'/^\[(x| )\](?=\s)/i',
13081308
);
13091309

1310+
// https://github.com/matthiasmullie/minify/issues/385
1311+
$tests[] = array(
1312+
'if (l !== 3) { for (var V = w.map(function(e) { return e }).length; l < V; V++); } else var C = 3;',
1313+
'if(l!==3){for(var V=w.map(function(e){return e}).length;l<V;V++);}else var C=3'
1314+
);
1315+
$tests[] = array(
1316+
'if (l !== 3) { for (var V = w.map(function(e) { if(e > 5) { return e-5; } return e; }).length; l < V; V++); } else var C = 3;',
1317+
'if(l!==3){for(var V=w.map(function(e){if(e>5){return e-5}return e}).length;l<V;V++);}else var C=3'
1318+
);
1319+
$tests[] = array(
1320+
'if (l !== 3) { for (var V = w.length; l < V; V+=w.map(function(e) { if(e > 5) { return e-5; } return e; }).length); } else var C = 3;',
1321+
'if(l!==3){for(var V=w.length;l<V;V+=w.map(function(e){if(e>5){return e-5}return e}).length);}else var C=3'
1322+
);
1323+
13101324
// known minified files to help doublecheck changes in places not yet
13111325
// anticipated in these tests
13121326
$files = glob(__DIR__.'/sample/minified/*.js');

0 commit comments

Comments
 (0)