google / closure-compiler

A JavaScript checker and optimizer.
https://developers.google.com/closure/compiler/
Apache License 2.0
7.36k stars 1.14k forks source link

Crash when using variable named `JSCompiler_inline_anon_param_[0-9]*` #3857

Closed jkukucka closed 3 years ago

jkukucka commented 3 years ago

This was found during fuzzing research.

Input for $SIMPLE_OPTIMIZATIONS

throw ((z_0, a_55) => (new (() => (null))((c_ara),(((234) + ((948) * ((() => (! ((JSCompiler_inline_anon_param_3) *= (19))))(((() => { switch((~ (evae))) {case (goog$dom$TagName$aaazkpckd): {  } case ((declare) = (q_53)): { while ((z_0)){  } } case ((-10).s_76): { var w_58 }};var q_53 })[(function(goog$dom$TagName$s_30, goog$dom$TagName$s_12t_08){ var goog$dom$TagName$$superpmmespaceaa })]),(false),(__32),(this))))) != (a_77)))))`

Stracktrace:

java.lang.IllegalStateException: Invalid child for ASSIGN_MUL node. Reference node:
THIS 1:410  [length: 4] [is_parenthesized: 1] [source_file: input0] : Color{id=3eb2df126665c4a3, debugInfo=DebugInfo{compositeTypename=}, prototypes=[], instanceColors=[], invalidating=false, propertiesKeepOriginalName=false, constructor=false, ownProperties=[$jscomp, $jscomp$lookupPolyfilledValue, ActiveXObject, AggregateError, Arguments, Array, ArrayBuffer, ArrayBufferView, AsyncGenerator, AsyncIterable, AsyncIterator, AsyncIteratorIterable, Atomics, BigInt, BigInt64Array, BigUint64Array, Boolean, BufferSource, CanvasPixelArray, DataView, Date, Error, EvalError, FinalizationRegistry, Float32Array, Float64Array, Function, Generator, IArrayLike, IIterableResult, IObject, ITemplateArray, IThenable, Infinity, Int16Array, Int32Array, Int8Array, Iterable, Iterator, IteratorIterable, JSCompiler_renameProperty, JSON, JSONType, Map, Math, NaN, Number, Object, ObjectPropertyDescriptor, Promise, RangeError, ReferenceError, Reflect, RegExp, RegExpResult, Set, SharedArrayBuffer, String, Symbol, SyntaxError, Thenable, Transferable, TrustedScript, TypeError, TypedArray, URIError, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakRef, WeakSet, arguments, decodeURI, decodeURIComponent, encodeURI, encodeURIComponent, escape, eval, global, globalThis, isFinite, isNaN, parseFloat, parseInt, self, undefined, unescape, window, JSCompiler_inline_anon_param_3, __32, a_77, c_ara, declare, evae, goog$dom$TagName$aaazkpckd], boxId=null, closureAssert=false, unionElements=[]}

 Parent node:
ASSIGN_MUL 1:81  [length: 40] [source_file: input0]
    THIS 1:410  [length: 4] [is_parenthesized: 1] [source_file: input0] : Color{id=3eb2df126665c4a3, debugInfo=DebugInfo{compositeTypename=}, prototypes=[], instanceColors=[], invalidating=false, propertiesKeepOriginalName=false, constructor=false, ownProperties=[$jscomp, $jscomp$lookupPolyfilledValue, ActiveXObject, AggregateError, Arguments, Array, ArrayBuffer, ArrayBufferView, AsyncGenerator, AsyncIterable, AsyncIterator, AsyncIteratorIterable, Atomics, BigInt, BigInt64Array, BigUint64Array, Boolean, BufferSource, CanvasPixelArray, DataView, Date, Error, EvalError, FinalizationRegistry, Float32Array, Float64Array, Function, Generator, IArrayLike, IIterableResult, IObject, ITemplateArray, IThenable, Infinity, Int16Array, Int32Array, Int8Array, Iterable, Iterator, IteratorIterable, JSCompiler_renameProperty, JSON, JSONType, Map, Math, NaN, Number, Object, ObjectPropertyDescriptor, Promise, RangeError, ReferenceError, Reflect, RegExp, RegExpResult, Set, SharedArrayBuffer, String, Symbol, SyntaxError, Thenable, Transferable, TrustedScript, TypeError, TypedArray, URIError, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakRef, WeakSet, arguments, decodeURI, decodeURIComponent, encodeURI, encodeURIComponent, escape, eval, global, globalThis, isFinite, isNaN, parseFloat, parseInt, self, undefined, unescape, window, JSCompiler_inline_anon_param_3, __32, a_77, c_ara, declare, evae, goog$dom$TagName$aaazkpckd], boxId=null, closureAssert=false, unionElements=[]}
    NUMBER 19.0 1:118  [length: 2] [is_parenthesized: 1] [source_file: input0] : Color{id=d081722c, debugInfo=DebugInfo{compositeTypename=number}, prototypes=[], instanceColors=[], invalidating=false, propertiesKeepOriginalName=false, constructor=false, ownProperties=[], boxId=34ba2fb1, closureAssert=false, unionElements=[]}

    at com.google.javascript.jscomp.AstValidator$1.handleViolation(AstValidator.java:86)
    at com.google.javascript.jscomp.AstValidator.violation(AstValidator.java:1993)
    at com.google.javascript.jscomp.AstValidator.validateAssignmentOpTarget(AstValidator.java:1620)
    at com.google.javascript.jscomp.AstValidator.validateCompoundAssignmentExpression(AstValidator.java:1597)
    at com.google.javascript.jscomp.AstValidator.validateExpression(AstValidator.java:315)
    at com.google.javascript.jscomp.AstValidator.validateUnaryOp(AstValidator.java:1898)
    at com.google.javascript.jscomp.AstValidator.validateExpression(AstValidator.java:288)
    at com.google.javascript.jscomp.AstValidator.validateBinaryOp(AstValidator.java:1904)
    at com.google.javascript.jscomp.AstValidator.validateExpression(AstValidator.java:378)
    at com.google.javascript.jscomp.AstValidator.validateBinaryOp(AstValidator.java:1904)
    at com.google.javascript.jscomp.AstValidator.validateExpression(AstValidator.java:378)
    at com.google.javascript.jscomp.AstValidator.validateBinaryOp(AstValidator.java:1903)
    at com.google.javascript.jscomp.AstValidator.validateExpression(AstValidator.java:378)
    at com.google.javascript.jscomp.AstValidator.validatePseudoExpression(AstValidator.java:478)
    at com.google.javascript.jscomp.AstValidator.validateNew(AstValidator.java:1217)
    at com.google.javascript.jscomp.AstValidator.validateExpression(AstValidator.java:418)
    at com.google.javascript.jscomp.AstValidator.validateReturn(AstValidator.java:1465)
    at com.google.javascript.jscomp.AstValidator.validateStatement(AstValidator.java:212)
    at com.google.javascript.jscomp.AstValidator.validateStatement(AstValidator.java:153)
    at com.google.javascript.jscomp.AstValidator.validateBlock(AstValidator.java:939)
    at com.google.javascript.jscomp.AstValidator.validateFunctionExpressionHelper(AstValidator.java:1050)
    at com.google.javascript.jscomp.AstValidator.validateFunctionExpression(AstValidator.java:1032)
    at com.google.javascript.jscomp.AstValidator.validateExpression(AstValidator.java:422)
    at com.google.javascript.jscomp.AstValidator.validateThrow(AstValidator.java:1472)
    at com.google.javascript.jscomp.AstValidator.validateStatement(AstValidator.java:215)
    at com.google.javascript.jscomp.AstValidator.validateStatement(AstValidator.java:153)
    at com.google.javascript.jscomp.AstValidator.validateStatements(AstValidator.java:147)
    at com.google.javascript.jscomp.AstValidator.validateScript(AstValidator.java:136)
    at com.google.javascript.jscomp.AstValidator.validateCodeRoot(AstValidator.java:123)
    at com.google.javascript.jscomp.AstValidator.process(AstValidator.java:109)
    at com.google.javascript.jscomp.PhaseOptimizer$NamedPass.process(PhaseOptimizer.java:317)
    at com.google.javascript.jscomp.PhaseOptimizer.process(PhaseOptimizer.java:232)
    at com.google.javascript.jscomp.Compiler.performOptimizations(Compiler.java:2583)
    at com.google.javascript.jscomp.Compiler.lambda$stage2Passes$8(Compiler.java:960)
    at com.google.javascript.jscomp.CompilerExecutor.runInCompilerThread(CompilerExecutor.java:127)
    at com.google.javascript.jscomp.Compiler.runInCompilerThread(Compiler.java:1006)
    at com.google.javascript.jscomp.Compiler.stage2Passes(Compiler.java:957)
    at com.google.javascript.jscomp.Compiler.compileModules(Compiler.java:899)
    at com.google.javascript.jscomp.debugger.CompilationServlet.service(CompilationServlet.java:99)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1459)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
    at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:62)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at com.google.apphosting.runtime.jetty9.ParseBlobUploadHandler.handle(ParseBlobUploadHandler.java:111)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
    at com.google.apphosting.runtime.jetty94.AppEngineWebAppContext.doHandle(AppEngineWebAppContext.java:234)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at com.google.apphosting.runtime.jetty94.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:256)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle(Server.java:516)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
    at com.google.apphosting.runtime.jetty94.RpcConnection.handle(RpcConnection.java:243)
    at com.google.apphosting.runtime.jetty94.RpcConnector.serviceRequest(RpcConnector.java:83)
    at com.google.apphosting.runtime.jetty94.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:158)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest(JavaRuntime.java:794)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest(JavaRuntime.java:757)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:727)
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:261)
    at java.base/java.lang.Thread.run(Thread.java:829)

Reproduce URL:

https://closure-compiler-debugger.appspot.com/#input0%3Dthrow%2520((z_0%252C%2520a_55)%2520%253D%253E%2520(new%2520(()%2520%253D%253E%2520(null))((c_ara)%252C(((234)%2520%252B%2520((948)%2520*%2520((()%2520%253D%253E%2520(!%2520((JSCompiler_inline_anon_param_3)%2520*%253D%2520(19))))(((()%2520%253D%253E%2520%257B%2520switch((~%2520(evae)))%2520%257Bcase%2520(goog%2524dom%2524TagName%2524aaazkpckd)%253A%2520%257B%2520%2520%257D%2520case%2520((declare)%2520%253D%2520(q_53))%253A%2520%257B%2520while%2520((z_0))%257B%2520%2520%257D%2520%257D%2520case%2520((-10).s_76)%253A%2520%257B%2520var%2520w_58%2520%257D%257D%253Bvar%2520q_53%2520%257D)%255B(function(goog%2524dom%2524TagName%2524s_30%252C%2520goog%2524dom%2524TagName%2524s_12t_08)%257B%2520var%2520goog%2524dom%2524TagName%2524%2524superpmmespaceaa%2520%257D)%255D)%252C(false)%252C(__32)%252C(this)))))%2520!%253D%2520(a_77)))))%250A%26input1%26conformanceConfig%26externs%26refasterjs-template%26CHECK_TYPES%3Dtrue%26REWRITE_MODULES_BEFORE_TYPECHECKING%3Dtrue%26ALIAS_ALL_STRINGS%3Dtrue%26AMBIGUATE_PROPERTIES%3Dtrue%26COALESCE_VARIABLE_NAMES%3Dtrue%26COLLAPSE_VARIABLE_DECLARATIONS%3Dtrue%26COLLAPSE_ANONYMOUS_FUNCTIONS%3Dtrue%26COLLAPSE_PROPERTIES%3Dtrue%26COLLAPSE_OBJECT_LITERALS%3Dtrue%26COMPUTE_FUNCTION_SIDE_EFFECTS%3Dtrue%26CONVERT_TO_DOTTED_PROPERTIES%3Dtrue%26CROSS_CHUNK_CODE_MOTION%3Dtrue%26CROSS_CHUNK_METHOD_MOTION%3Dtrue%26DEAD_ASSIGNMENT_ELIMINATION%3Dtrue%26DEVIRTUALIZE_METHODS%3Dtrue%26DISAMBIGUATE_PROPERTIES%3Dtrue%26EXTRACT_PROTOTYPE_MEMBER_DECLARATIONS%3Dtrue%26FOLD_CONSTANTS%3Dtrue%26INLINE_CONSTANTS%3Dtrue%26INLINE_FUNCTIONS%3Dtrue%26INLINE_PROPERTIES%3Dtrue%26INLINE_VARIABLES%3Dtrue%26LABEL_RENAMING%3Dtrue%26OPTIMIZE_CALLS%3Dtrue%26OPTIMIZE_CONSTRUCTORS%3Dtrue%26OPTIMIZE_ARGUMENTS_ARRAY%3Dtrue%26REMOVE_ABSTRACT_METHODS%3Dtrue%26REMOVE_DEAD_CODE%3Dtrue%26REMOVE_UNUSED_CLASS_PROPERTIES%3Dtrue%26REMOVE_UNUSED_PROTOTYPE_PROPERTIES%3Dtrue%26REMOVE_UNUSED_VARIABLES%3Dtrue%26REWRITE_FUNCTION_EXPRESSIONS%3Dtrue%26SMART_NAME_REMOVAL%3Dtrue%26USE_TYPES_FOR_LOCAL_OPTIMIZATION%3Dtrue%26VARIABLE_RENAMING%3Dtrue%26PROPERTY_RENAMING%3Dtrue%26MOVE_FUNCTION_DECLARATIONS%3Dtrue%26SYNTHETIC_BLOCK_MARKER%3Dtrue%26CLOSURE_PASS%3Dtrue%26PRESERVE_TYPE_ANNOTATIONS%3Dtrue%26PRETTY_PRINT%3Dtrue

lauraharker commented 3 years ago

Simplified examples:

(() => JSCompiler_inline_anon_param_0 *= 19)
  (this);

or

(() => JSCompiler_inline_anon_param_1 *= 19)
  (1, this);

It looks like the issue is passing in a variable named JSCompiler_inline_anon_param_[0-9]* to the compiler, which collides with a synthetic variable generated by whatever pass inlines parameters.

(edit - here's the repro link: https://closure-compiler-debugger.appspot.com/#input0%3D(()%2520%253D%253E%2520JSCompiler_inline_anon_param_0%2520*%253D%252019)%250A%2520%2520(this)%253B%26input1%26conformanceConfig%26externs%26refasterjs-template%26CHECK_TYPES%3Dtrue%26REWRITE_MODULES_BEFORE_TYPECHECKING%3Dtrue%26INLINE_FUNCTIONS%3Dtrue%26OPTIMIZE_CALLS%3Dtrue%26CLOSURE_PASS%3Dtrue%26PRESERVE_TYPE_ANNOTATIONS%3Dtrue%26PRETTY_PRINT%3Dtrue)

lauraharker commented 3 years ago

Another example:

var JSCompiler_inline_anon_param_0 = 0;

(() => JSCompiler_inline_anon_param_0)(1); // evaluates to '0'

is compiled to

1

This may be a low priority if only reproducible by passing in a variable named JSCompiler_inline_anon_param_

lauraharker commented 3 years ago

From today's triage meeting: we're closing this since the solution is for user code to not name variables JSCompiler_inline_anon_param_[0-9]