From 1f5f6fc2048269335a6b7df71ae6cc6f03de97b7 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Fri, 10 Aug 2018 23:23:08 +0100 Subject: [PATCH] JavaScriptMinifier: Fix bad state after '{}' in property value Previously, $push contained: self::PROPERTY_EXPRESSION_OP => [ self::TYPE_PAREN_OPEN => self::PROPERTY_EXPRESSION_OP ], But $pop contained: self::PROPERTY_EXPRESSION_OP => [ self::TYPE_BRACE_CLOSE => true ] This meant that when a closing brace was found inside a property expression, it would wrongly pop the stack, eventhough we are still inside the property expression. The impact is that everything after this is one level higher in the stack than it should be, causing various other types to be misinterpreted. Including in the following contrived example: call( function () { try { } catch (e) { obj = { key: 1 ? 0 : {} // A }; // B } // C return name === 'input'; } ); In the above, the closing brace at A would close the 'obj.key' assignment (PROPERTY_EXPRESSION_OP), instead of waiting for the closing brace at B to decide that. Then the closing brace at B would wrongly close the 'catch' block (instead of the 'obj' assignment). And lastly, the closing brace at C would close the function body (STATEMENT). This resulted in keyword 'return' being interpreted while in state PAREN_EXPRESSION_OP instead of STATEMENT, where PAREN_EXPRESSION_OP is the arguments list to `call()`. In an argument list, TYPE_RETURN is not valid, which means we stay in that state, instead of progressing to EXPRESSION_NO_NL, which then wrongly allows for a line break to be inserted. Bug: T201606 Change-Id: I07b809a7ca56e282ecb48b5c89c217b4b8da6856 --- includes/libs/JavaScriptMinifier.php | 1 + .../phpunit/includes/libs/JavaScriptMinifierTest.php | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/includes/libs/JavaScriptMinifier.php b/includes/libs/JavaScriptMinifier.php index 8541c4f7ed..bf78ce396f 100644 --- a/includes/libs/JavaScriptMinifier.php +++ b/includes/libs/JavaScriptMinifier.php @@ -434,6 +434,7 @@ class JavaScriptMinifier { self::TYPE_PAREN_OPEN => self::PROPERTY_EXPRESSION_OP ], self::PROPERTY_EXPRESSION_OP => [ + self::TYPE_BRACE_OPEN => self::PROPERTY_EXPRESSION_OP, self::TYPE_PAREN_OPEN => self::PROPERTY_EXPRESSION_OP ], self::PROPERTY_EXPRESSION_FUNC => [ diff --git a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php index 70f9c7ca42..3e37f15a9f 100644 --- a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php +++ b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php @@ -257,8 +257,8 @@ class JavaScriptMinifierTest extends PHPUnit\Framework\TestCase { call( function () { try { } catch (e) { - push = { - apply: 1 ? 0 : {} + obj = { + key: 1 ? 0 : {} }; } return name === 'input'; @@ -280,10 +280,10 @@ JAVASCRIPT 'e', ')', '{', - 'push', + 'obj', '=', '{', - 'apply', + 'key', ':', '1', '?', @@ -294,7 +294,9 @@ JAVASCRIPT '}', ';', '}', - 'return', 'name', // FIXME + // The return Statement: + // return [no LineTerminator here] Expression + 'return name', '===', "'input'", ';', -- 2.20.1