0

I am using Google Closure Compiler in "SIMPLE_OPTIMIZATIONS" mode. The JavaScript uses an "Eval" statement with the variable "_u" embedded in the string. When Google Closure Compiler obfuscates the code, the variable name is changed to "a" and I get an error that "_u" is not defined in the console. My understanding is that an Extern will solve this problem, but I'm not sure how to write it. Thoughts?

Code Snippet:

var FuncName = (function(){

  var ht=escape(_w.location.href)

  function _fC(_u){
    _aT=_sp+',\\/,\\.,-,_,'+_rp+',%2F,%2E,%2D,%5F';
    _aA=_aT.split(',');
    for(i=0;i<5;i++){
      eval('_u=_u.replace(/'+_aA[i]+'/g,_aA[i+5])')
    }
    return _u
  };

  return {
  O_LC:function(){ 
    _w.open('https://someurl?referer='+_fC(_ht))
  }
};
})();

After Google Closure Compiler modifies the code:

var FuncName = function() {
  function a(a) {
    _aT = _sp + ",\\/,\\.,-,_," + _rp + ",%2F,%2E,%2D,%5F";
    _aA = _aT.split(",");
    for (i = 0;5 > i;i++) {
      eval("_u=_u.replace(/" + _aA[i] + "/g,_aA[i+5])");
    }
    return a;
  }
  escape(_w.location.href);
  return {O_LC:function() {
    _w.open("https://someurl?referer=" + a(_ht));
  }};
}();
satoukum
  • 1,188
  • 1
  • 21
  • 31

2 Answers2

0

It's pretty easy. You just need a separate externs file:

sampleextern.js

/** @externs */

var _u;

Externs are valid javascript. See http://blogs.missouristate.edu/web/2013/09/12/how-to-write-closure-compiler-extern-files-part-1-the-basics/

Chad Killingsworth
  • 14,360
  • 2
  • 34
  • 57
  • 1
    Chad this won't fix their issue though. They won't their parameter "_u" to not be renamed. The compiler doesn't support this directly. – John Oct 15 '15 at 15:54
  • @John I assumed since `_u` was not defined in the scope, the compiler would assume it was global, and therefore fall back to using the extern definition. – Chad Killingsworth Oct 15 '15 at 15:59
  • Yeah, this doesn't appear to work. Other options could be to rewrite the statement without the eval or to change the JavaScript, but this is 3rd party code and I have been discouraged from editing it. For now our team is using "WHITESPACE_ONLY". – satoukum Oct 15 '15 at 16:02
  • _u is the function parameter, it is in scope. – John Oct 15 '15 at 16:03
  • 1
    @satoukum I would modify it and send a patch to the original author. – John Oct 15 '15 at 16:07
0

You can only prevent renaming of global variables or properties with externs. Locals will always be renamed. You can modify the code in a number of ways to fix this, including using a function constructor:

new Function("_u", "... function body ...")

But I would rewrite the code to avoid using eval to construct the regex. This would work:

_u=_u.replace(new RegExp(_aA[i], "g"), _aA[i+5]);

You also may be interested in:

Escape string for use in Javascript regex

General documentation regarding the Closure Compiler limitations are here:

https://developers.google.com/closure/compiler/docs/limitations

Community
  • 1
  • 1
John
  • 5,443
  • 15
  • 21
  • Note, that you could also modify the compiler to special case "_u". There is one such case already: https://github.com/google/closure-compiler/blob/04dd916be73f961f489906231cfb1a1ad0fd583a/src/com/google/javascript/jscomp/CodingConventions.java#L327 Or propose a patch to make this configurable. – John Oct 15 '15 at 16:12
  • I'm using a plugin that uses google closure compiler, so I think I'm restricted to only passing in options such as '--externs=./lib/gcc-externs.js' – satoukum Oct 15 '15 at 16:16