From f74773f4520adff6b70a7d445417aa9769f61fa6 Mon Sep 17 00:00:00 2001 From: Taylor Woll Date: Thu, 16 Mar 2017 15:40:08 -0700 Subject: [PATCH] [CVE-2017-0223] Fix right paren location calculation for lambda with assignment expression We don't calculate correct right paren location when a lambda contains an assignment expression where the assignment rhs is wrapped in parens. Due to the incorrect offset, we overwrite the buffer allocated in ScriptFunction::EnsureSourceString when we try to toString the lambda. --- lib/Parser/Parse.cpp | 2 +- test/es6/lambda1.js | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/Parser/Parse.cpp b/lib/Parser/Parse.cpp index 9a5d7b9edde..d29ddfebf47 100644 --- a/lib/Parser/Parse.cpp +++ b/lib/Parser/Parse.cpp @@ -8440,7 +8440,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin, { // Parse the operand, make a new node, and look for more IdentToken token; - pnodeT = ParseExpr(opl, NULL, fAllowIn, FALSE, pNameHint, &hintLength, &hintOffset, &token); + pnodeT = ParseExpr(opl, NULL, fAllowIn, FALSE, pNameHint, &hintLength, &hintOffset, &token, false, nullptr, plastRParen); // Detect nested function escapes of the pattern "o.f = function(){...}" or "o[s] = function(){...}". // Doing so in the parser allows us to disable stack-nested-functions in common cases where an escape diff --git a/test/es6/lambda1.js b/test/es6/lambda1.js index e12376bfbe0..3329f4537b1 100644 --- a/test/es6/lambda1.js +++ b/test/es6/lambda1.js @@ -477,6 +477,29 @@ var tests = [ var l = async() => (async() => ('str')); assert.areEqual("async() => (async() => ('str'))", '' + l, "Nested async lambda should be correct"); } + }, + { + name: "Lambda consisting of assignment expression should have correct source string", + body: function () { + var l = () => a = (123) + assert.areEqual('() => a = (123)', '' + l, "Lambda to string should include the parens wrapping the return expression"); + + var l = () => a = (('๏บบ')) + assert.areEqual("() => a = (('๏บบ'))", '' + l, "Multi-byte characters should not break the string"); + + var s = "() => a = ('\u{20ac}')"; + var l = eval(s); + assert.areEqual(s, '' + l, "Unicode byte sequences should not break the string"); + + var l = async() => a = ({}); + assert.areEqual('async() => a = ({})', '' + l, "Async lambda should also be correct"); + + var l = () => a = (() => b = (123)) + assert.areEqual('() => a = (() => b = (123))', '' + l, "Nested lambda to string should be correct"); + + var l = async() => a = (async() => b = ('str')); + assert.areEqual("async() => a = (async() => b = ('str'))", '' + l, "Nested async lambda should be correct"); + } } ];