JSMin uses a pretty crude tokenizer-like algorithm based on assumptions of what kind of characters can precede/follow others. In the PHP port I maintain I’ve made numerous fixes to handle most syntax in the wild, but I see no fix for this:
Here’s a very boiled down version of a statement created by another minifier:
if(a)/b/.test(c)?d():e();
Since (a)
follows if
, we know it’s a condition, and, if truthy, the statement /b/.test(c)?d():e()
will be executed.
However, JSMin has no parser and therefore no concept that (a)
is an if condition; it just sees an expression. Since lots of scripts in the wild have expressions like (expression) / divisor
, we’ve told JSMin to see that as division. So when JSMin arrives at )/
, it incorrectly assumes /
is the division operator, then incorrectly treats the following /
as the beginning of a RegExp literal.
Lessons: Don’t run minified code through JSMin*, and don’t use it at all if you have access to a JavaScript/Java runtime.
*Minify already knows to skip JSMin for files ending in -min.js
or .min.js
.