alikothari / htmlcompressor

Automatically exported from code.google.com/p/htmlcompressor
Apache License 2.0
0 stars 0 forks source link

Event-handler preservation breaks script compression #70

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
The code that finds inline event handlers in the HTML using a couple of regexps 
(eventPattern1 and eventPattern2) is also finding them inside literals in 
script blocks and breaking those scripts because of it.

Example input:
<html><head><script type="text/javascript">
function t() {
 var myvarname = 1;
 return ' onclick="test('+myvarname+')"/>';
}
</script></head><body/></html>

This should compress like this:

<html><head><script type="text/javascript">
function t(){var a=1;return ' onclick="test('+a+')"/>';}
</script></head><body/></html>

but instead becomes:

<html><head><script type="text/javascript">
function t(){var a=1;return ' onclick="test('+myvarname+')"/>';}
</script></head><body/></html>

This breaks the Javascript code, as 'myvarname' doesn't exist after 
compression. It was the HTML event handling code that put it back.

This same regexp can break compression entirely. Example:

<html><head><script type="text/javascript">
var a='a', b='b', x=' onclick="t('+"'"+a+"','"+b+"'"+')"';
</script></head><body/></html>

This is a legitimate javascript statement, setting x to the string 
onclick="t('a','b')"

HtmlCompressor goes ahead and breaks it because it tried to parse HTML with 
regexps.

[ERROR] HtmlCompressor: "missing ; before statement" at line [2:62] during 
JavaScript compression: var a='a', b='b', x=' 
onclick="%%%~COMPRESS~EVENT~0~%%%"'"+a+"','"+b+"'"+')"';
[ERROR] HtmlCompressor: "unterminated string literal" at line [2:78] during 
JavaScript compression: var a='a', b='b', x=' 
onclick="%%%~COMPRESS~EVENT~0~%%%"'"+a+"','"+b+"'"+')"';
[ERROR] HtmlCompressor: "Compilation produced 2 syntax errors." at line [1:0] 
during JavaScript compression

It doesn't even have to be a known event handler, any word beginning "on" will 
do:

<html><head><script type="text/javascript">
var x=' one="'+"'";
</script></head><body/></html>

This is using htmlcompressor 1.5.3 on all platforms, configured to use 
YUICompressor for JS compression.

Original issue reported on code.google.com by stuart.c...@gmail.com on 10 Apr 2012 at 1:25

GoogleCodeExporter commented 9 years ago
The solution I'm using just now is to move the event handler preservation to 
after the script block preservation. I don't know if this might break something 
else.

Original comment by stuart.c...@gmail.com on 10 Apr 2012 at 1:43

Attachments: