WebOptimizer icon indicating copy to clipboard operation
WebOptimizer copied to clipboard

Parsing the "Elvis Operator" (optional chaining like '?.") throws null reference exception

Open torrobinson opened this issue 4 years ago • 0 comments

The optional chaining operator ?. causes a request to a JavaScript file containing it to return a 500, with the exception: NullReferenceException: Object reference not set to an instance of an object.

NUglify.JavaScript.JSParser.ParseExpression(AstNode leftHandSide, bool single, bool bCanAssign, JSToken inToken)
NUglify.JavaScript.JSParser.ParseArrowFunction(AstNode parameters)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseExpressionList(JSToken terminator)
NUglify.JavaScript.JSParser.ParseMemberExpression(AstNode expression, List<SourceContext> newContexts)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseExpressionList(JSToken terminator)
NUglify.JavaScript.JSParser.ParseMemberExpression(AstNode expression, List<SourceContext> newContexts)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseArrayLiteral(bool isBindingPattern)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseVarDecl(JSToken inToken)
NUglify.JavaScript.JSParser.ParseVariableStatement()
NUglify.JavaScript.JSParser.ParseBlock()
NUglify.JavaScript.JSParser.ParseIfStatement()
NUglify.JavaScript.JSParser.ParseBlock()
NUglify.JavaScript.JSParser.ParseArrowFunction(AstNode parameters)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseExpressionList(JSToken terminator)
NUglify.JavaScript.JSParser.ParseMemberExpression(AstNode expression, List<SourceContext> newContexts)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseExpressionStatement(bool fSourceElement)
NUglify.JavaScript.JSParser.ParseStatement(bool fSourceElement, bool skipImportantComment)
NUglify.JavaScript.JSParser.ParseFunctionBody(BlockStatement body)
NUglify.JavaScript.JSParser.ParseFunction(FunctionType functionType, SourceContext fncCtx)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseExpressionList(JSToken terminator)
NUglify.JavaScript.JSParser.ParseMemberExpression(AstNode expression, List<SourceContext> newContexts)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseReturnStatement()
NUglify.JavaScript.JSParser.ParseFunctionBody(BlockStatement body)
NUglify.JavaScript.JSParser.ParseFunction(FunctionType functionType, SourceContext fncCtx)
NUglify.JavaScript.JSParser.ParseLeftHandSideExpression(bool isMinus)
NUglify.JavaScript.JSParser.ParseUnaryExpression(out bool isLeftHandSideExpr, bool isMinus)
NUglify.JavaScript.JSParser.ParseExpression(AstNode leftHandSide, bool single, bool bCanAssign, JSToken inToken)
NUglify.JavaScript.JSParser.ParseExpressionStatement(bool fSourceElement)
NUglify.JavaScript.JSParser.ParseStatement(bool fSourceElement, bool skipImportantComment)
NUglify.JavaScript.JSParser.ParseStatements(BlockStatement block)
NUglify.JavaScript.JSParser.InternalParse()
NUglify.JavaScript.JSParser.Parse(DocumentContext sourceContext)
NUglify.JavaScript.JSParser.Parse(DocumentContext sourceContext, CodeSettings settings)
NUglify.Uglify.Js(string source, string fileName, CodeSettings codeSettings)
WebOptimizer.JavaScriptMinifier.ExecuteAsync(IAssetContext config)
WebOptimizer.Asset.ExecuteAsync(HttpContext context, IWebOptimizerOptions options)
WebOptimizer.AssetBuilder.BuildAsync(IAsset asset, HttpContext context, IWebOptimizerOptions options)
WebOptimizer.AssetMiddleware.HandleAssetAsync(HttpContext context, IAsset asset, WebOptimizerOptions options)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Example line of code which throws the error:

data = uniqueAnswers.sorted('asc').map(answer => question.draftedQueens.filter(dq => (dq.queen?.name || nobody) == answer).length);

When I rewrite to remove optional chaining (which makes it very unreadble) it works:

data = uniqueAnswers.sorted('asc').map(answer => question.draftedQueens.filter(dq => (dq.queen === null ? nobody : (dq.queen.name === null ? nobody : dq.queen.name)) == answer).length);

As this operator is now safe to use across all modern browsers (except IE 11, but that's not modern) I would have assumed this was safe to use. Does the library parsing the JS need to be updated?

Thanks!

torrobinson avatar May 18 '21 02:05 torrobinson