mirror of
https://github.com/mrclay/minify.git
synced 2025-08-22 13:42:48 +02:00
Fixes #73: Handles regex literals directly following return/typeof
This commit is contained in:
@@ -272,23 +272,33 @@ class JSMin {
|
||||
// we obviously aren't dividing
|
||||
return true;
|
||||
}
|
||||
if ($this->a === ' ' || $this->a === "\n") {
|
||||
$length = strlen($this->output);
|
||||
if ($length < 2) { // weird edge case
|
||||
return true;
|
||||
|
||||
// we have to check for a preceding keyword, and we don't need to pattern
|
||||
// match over the whole output.
|
||||
$recentOutput = substr($this->output, -10);
|
||||
|
||||
// check if return/typeof directly precede a pattern without a space
|
||||
foreach (array('return', 'typeof') as $keyword) {
|
||||
if ($this->a !== substr($keyword, -1)) {
|
||||
// certainly wasn't keyword
|
||||
continue;
|
||||
}
|
||||
// you can't divide a keyword
|
||||
if (preg_match('/(?:case|else|in|return|typeof)$/', $this->output, $m)) {
|
||||
if ($this->output === $m[0]) { // odd but could happen
|
||||
return true;
|
||||
}
|
||||
// make sure it's a keyword, not end of an identifier
|
||||
$charBeforeKeyword = substr($this->output, $length - strlen($m[0]) - 1, 1);
|
||||
if (! $this->isAlphaNum($charBeforeKeyword)) {
|
||||
if (preg_match("~(^|[\\s\\S])" . substr($keyword, 0, -1) . "$~", $recentOutput, $m)) {
|
||||
if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check all keywords
|
||||
if ($this->a === ' ' || $this->a === "\n") {
|
||||
if (preg_match('~(^|[\\s\\S])(?:case|else|in|return|typeof)$~', $recentOutput, $m)) {
|
||||
if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -17,4 +17,8 @@ x = / [/] /;
|
||||
|
||||
(2)
|
||||
|
||||
/ foo;
|
||||
/ foo;
|
||||
|
||||
function(){return/foo/};
|
||||
|
||||
function(){return typeof/foo/};
|
||||
|
2
min_unit_tests/_test_files/js/regexes.min.js
vendored
2
min_unit_tests/_test_files/js/regexes.min.js
vendored
@@ -1,3 +1,3 @@
|
||||
function testIssue74(){return /'/;}
|
||||
!function(s){return /^[£$€?.]/.test(s);}();typeof
|
||||
/ ' /;x=/ [/] /;1/foo;(2)/foo;
|
||||
/ ' /;x=/ [/] /;1/foo;(2)/foo;function(){return/foo/};function(){return typeof/foo/};
|
@@ -55,21 +55,39 @@ function test_JSMin()
|
||||
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
||||
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
||||
echo "---Source: " .countBytes($src). " bytes\n\n{$src}\n\n\n";
|
||||
|
||||
// only test exceptions on this page
|
||||
test_JSMin_exception('"Hello'
|
||||
,'Unterminated String'
|
||||
,'JSMin_UnterminatedStringException'
|
||||
,"JSMin: Unterminated String at byte 6: \"Hello");
|
||||
test_JSMin_exception("return /regexp\n}"
|
||||
,'Unterminated RegExp'
|
||||
,'JSMin_UnterminatedRegExpException'
|
||||
,"JSMin: Unterminated RegExp at byte 15: /regexp\n");
|
||||
test_JSMin_exception("/* Comment "
|
||||
,'Unterminated Comment'
|
||||
,'JSMin_UnterminatedCommentException'
|
||||
,"JSMin: Unterminated comment at byte 11: /* Comment ");
|
||||
}
|
||||
|
||||
test_JSMin_exception('"Hello'
|
||||
,'Unterminated String'
|
||||
,'JSMin_UnterminatedStringException'
|
||||
,"JSMin: Unterminated String at byte 6: \"Hello");
|
||||
|
||||
test_JSMin_exception("return /regexp\n}"
|
||||
,'Unterminated RegExp'
|
||||
,'JSMin_UnterminatedRegExpException'
|
||||
,"JSMin: Unterminated RegExp at byte 15: /regexp\n");
|
||||
test_JSMin_exception("return/regexp\n}"
|
||||
,'Unterminated RegExp'
|
||||
,'JSMin_UnterminatedRegExpException'
|
||||
,"JSMin: Unterminated RegExp at byte 14: /regexp\n");
|
||||
test_JSMin_exception(";return/regexp\n}"
|
||||
,'Unterminated RegExp'
|
||||
,'JSMin_UnterminatedRegExpException'
|
||||
,"JSMin: Unterminated RegExp at byte 15: /regexp\n");
|
||||
test_JSMin_exception(";return /regexp\n}"
|
||||
,'Unterminated RegExp'
|
||||
,'JSMin_UnterminatedRegExpException'
|
||||
,"JSMin: Unterminated RegExp at byte 16: /regexp\n");
|
||||
|
||||
test_JSMin_exception("typeof/regexp\n}"
|
||||
,'Unterminated RegExp'
|
||||
,'JSMin_UnterminatedRegExpException'
|
||||
,"JSMin: Unterminated RegExp at byte 14: /regexp\n");
|
||||
|
||||
test_JSMin_exception("/* Comment "
|
||||
,'Unterminated Comment'
|
||||
,'JSMin_UnterminatedCommentException'
|
||||
,"JSMin: Unterminated comment at byte 11: /* Comment ");
|
||||
}
|
||||
|
||||
function test_JSMin_exception($js, $label, $expClass, $expMessage) {
|
||||
@@ -82,7 +100,7 @@ function test_JSMin_exception($js, $label, $expClass, $expMessage) {
|
||||
}
|
||||
$passed = assertTrue($eClass === $expClass && $eMsg === $expMessage,
|
||||
'JSMin : throw on ' . $label);
|
||||
if (! $passed && __FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||
if (! $passed && isset($e) && (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME']))) {
|
||||
echo "\n ---" , $e, "\n\n";
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user