Search code examples
javascriptgoogle-closure-compilergoogle-closure

Closure Compiler modifying end bracket in string


I try to run the following Javascript code through closure compiler:

var firstRun = eval("<?--#exec cmd_argument='command'-->");

And it comes out as:

var a=eval(" <?--#exec cmd_argument='command'--\x3e")

Since it is an SSI command I need i to not convert > to \x3e. I have tried using --charset=utf-8 and US-ascii as input to Closure Compiler. I have also tried using \u003e in the string. Whatever I do it outputs > as \x3e, which seems very odd, since it does not do the same to <.

The input command to closure compiler I use is:

java -jar compiler.jar --js file.js --js_output_file newfile.js

Solution

  • Even if there is a compiler option to avoid that happening, my view is that this is not a good practice, as you are relying on how precisely the compiler will output something (i.e. your SSI string in this case) that can have many different representations (as you can see the original string is changed).

    The compiler does this to avoid the string --> that will end an HTML comment in case it's embedded in HTML code. It used to be common practice to wrap JavaScript in an HTML comment to avoid error in browsers that didn't support JavaScript.


    Possible solution: can you separately include your SSI string so that it will not go through the compilation process? That way you can guarantee it's not going to be affected by the compiler.

    This could be done either by including the SSI string in another uncompiled JS file or by prepending the uncompiled SSI string in the compiled JS output. Something like this:

    var MY_GLOBAL_SSI_STRING = "<?--#exec cmd_argument='command'-->";
    // compiled code follows...
    

    Then you can refer to MY_GLOBAL_SSI_STRING from your (to be compiled) code like this:

    var firstRun = eval(goog.global['MY_GLOBAL_SSI_STRING']);
    

    Hope that helps.