Skip to content

Incorrect scope alteration of function by redeclaring as 'var' - take 2 #3623

@AshleyScirra

Description

@AshleyScirra

This is related to issue #3622 but is another variant of it.

Tested with Closure compiler v20200614

In some circumstances, Closure Compiler will redeclare a local function in a scope block with var, i.e.:

"use strict";
{
    function foo() { ... }
}

will become:

"use strict";
{
    var foo = function () { ... }
}

In the first example foo is scoped to just that block. This behavior appears to be specific to strict mode (which is in use in this example) - in sloppy mode foo is indeed a global declaration. In the second example the var has global scope even in strict mode. This causes it to conflict with other places a similar transformation has been done.

For example consider these two input scripts:

// simple1.js
"use strict";
{
	function foo(p) { window["external1"](p) }
	const local = window["getThing"]();
	
	console.log(foo(local));
	console.log(foo(local));
}
// simple2.js
"use strict";
{
	function foo(p) { window["external2"](p) }
	const local = window["getThing"]();
	
	console.log(foo(local));
	console.log(foo(local));
}

Command: java -jar ./closure-compiler.jar --js in.js --js_output_file out.js --compilation_level SIMPLE --language_in ECMASCRIPT_2015 --language_out ECMASCRIPT_2015 --strict_mode_input --formatting PRETTY_PRINT (update in.js as necessary)

Note these both use a function named foo, but each calls a different external function. In both cases in simple mode, Closure Compiler replaces the scoped function foo with var foo = .... This means the declaration in simple2.js overwrites the declaration from simple1.js, since they're both global. Then simple1.js ends up calling the wrong foo implementation, breaking code.

This also gets worse in ADVANCED mode since it's then also possible that functions with different names are renamed to the same short name, e.g. functions foo and bar both being redeclared as var a = function () ....

To avoid all this happening, Closure Compiler should not redeclare functions in scope blocks with var in strict mode.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions