Monday, April 2, 2012

How to break javascript compression using eval

Working on some javascript compression (or minification) for a site. Given this javascript:
function callingFunction(arrayVariable){
  var jsEval = 'globalFunction("String parameter " + arrayVariable["lookup"]);';
  return jsEval;
}

// non-global
var arrayVariable = [....];
var actEval = callingFunction(arrayVariable);
eval(actEval);
When the compression is ran, the variable in the function definition for "callingFunction" will be compressed, call it "a" from "arrayVariable" because it is not global. So now when "callingFunction" executes, and generates the "jsEval" to return a string with the non-compressed variable name. The execution of the eval will result in an exception of "arrayVariable" not being defined.

This is how you break javascript compression, or in other words, write javascript badly for compression. The right way? Don't use eval, or:
var jsEval = 'globalFunction("String parameter " + ' + arrayVariable["lookup"] +');';
Code might have an error, but you get the idea right? "arrayVariable["lookup"]" is being evaluated during the setting of variable "jsEval" verses the outer "eval(actEval)" execution.

See the following via the google closure compiler tutorial:
"Compilation with SIMPLE_OPTIMIZATIONS always preserves the functionality of syntactically valid JavaScript, provided that the code does not access local variables using string names (with, for example, eval() statements)."
And again Broken References between Compiled and Uncompiled Code:
'Keep in mind that "uncompiled code" includes any code passed to the eval() function as a string. Closure Compiler never alters string literals in code, so Closure Compiler does not change strings passed to eval() statements.'
You can also try the YUI Compressor.

No comments:

Share on Twitter