Page MenuHomePhabricator

Implicit semicolon not kept during minification
Closed, ResolvedPublic

Description

This file from SMW has no semicolons after some assignments, which is legal at the end of the line, but minify 2.2.2 (and perhaps earlier versions) put the next line without adding a semicolon: it should and it results on Firefox with a console error Uncaught SyntaxError: unexpected token: identifier (with a link to this documentation).

Below is a minimal self-contained example of this issue.

Before minification:

var change = function () {};

change.prototype.delete = function( key ) {
	delete this.messages[key];
}

change.prototype.informAbout = function() {
}

After minification:

var change=function(name){};change.prototype.delete=function(key){
delete this.messages[key];}change.prototype.informAbout=function(key){}

To highlight the error in the minification, here is a diff:

 var change=function(name){};change.prototype.delete=function(key){
-delete this.messages[key];}change.prototype.informAbout=function(key){}
+delete this.messages[key];};change.prototype.informAbout=function(key){}

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

This bug can be observed on MediaWiki 1.37.0-alpha (a2729f3a56412) with Semantic MediaWiki 4.0.0-alpha (580d9d4e7a) when browsing on [[Special:Ask]] (the user-visible behaviour it that the form is disabled, this is caused by the non-executed script which should normally remove the 'disabled' CSS class). But the root issue relies really in minify.

Krinkle renamed this task from Missing semicolon, not added during minification to Implicit semicolon not kept during minification.May 24 2021, 6:23 PM
Krinkle added a subscriber: Krinkle.

The minifier will not insert new code. However, line breaks that represent implicit semicolons (via ASI: Automatic Semicolon Insertion) must be kept indeed instead of stripped by minification.

Krinkle triaged this task as High priority.May 24 2021, 6:25 PM

It looks like this is not a general issue with line breaks between statements. Consider the below:

var change = function(name){
};

change.prototype.foo=function(key){
  delete this.x[key];
}

A.prototype.bar=function(key){
}
echo -e "var change = function(name){};\n\nchange.prototype.foo=function(key){ delete this.x[key]; }\n\nA.prototype.bar=function(key){}\n" | bin/minify js
var change=function(name){};change.prototype.foo=function(key){delete this.x[key];}
A.prototype.bar=function(key){}

This one works as expected. The line break, and thus its implied semi-colon, is kept.

Where it fails is if the assigned method property is named delete, like so:

var change = function(name){
};

change.prototype.delete=function(key){
  delete this.x[key];
}

A.prototype.bar=function(key){
}
echo -e "var change = function(name){};\n\nchange.prototype.delete=function(key){ delete this.x[key]; }\n\nA.prototype.bar=function(key){}\n" | bin/minify js
var change=function(name){};change.prototype.delete=function(key){delete this.x[key];}A.prototype.bar=function(key){}
$ echo -e "a.foo=function(){ delete x; }\n\nb=1" | bin/minify js
token: "a", state: STATEMENT, type: TYPE_LITERAL
token: ".", state: EXPRESSION_OP, type: TYPE_DOT
token: "foo", state: EXPRESSION_DOT, type: TYPE_LITERAL # Good type (1)
token: "=", state: EXPRESSION_OP, type: TYPE_BIN_OP  # Good state (2)
token: "function", state: EXPRESSION, type: TYPE_FUNC
token: "(", state: FUNC, type: TYPE_PAREN_OPEN
token: ")", state: PAREN_EXPRESSION, type: TYPE_PAREN_CLOSE
token: "{", state: FUNC, type: TYPE_BRACE_OPEN
token: "delete", state: STATEMENT, type: TYPE_UN_OP
token: "x", state: EXPRESSION, type: TYPE_LITERAL
token: ";", state: EXPRESSION_OP, type: TYPE_SEMICOLON
token: "}", state: STATEMENT, type: TYPE_BRACE_CLOSE
token: "b", state: EXPRESSION_OP, type: TYPE_LITERAL  # Good state (3)
token: "=", state: EXPRESSION_OP, type: TYPE_BIN_OP
token: "1", state: EXPRESSION, type: TYPE_LITERAL

a.foo=function(){delete x;}
b=1

$ echo -e "a.delete=function(){ delete x; }\n\nb=1" | bin/minify js
token: "a", state: STATEMENT, type: TYPE_LITERAL
token: ".", state: EXPRESSION_OP, type: TYPE_DOT
token: "delete", state: EXPRESSION_DOT, type: TYPE_UN_OP # Wrong type (1)
token: "=", state: EXPRESSION_DOT, type: TYPE_BIN_OP # Wrong state (2)
token: "function", state: EXPRESSION_DOT, type: TYPE_FUNC
token: "(", state: EXPRESSION_OP, type: TYPE_PAREN_OPEN
token: ")", state: PAREN_EXPRESSION, type: TYPE_PAREN_CLOSE
token: "{", state: EXPRESSION_OP, type: TYPE_BRACE_OPEN
token: "delete", state: EXPRESSION_OP, type: TYPE_UN_OP
token: "x", state: EXPRESSION_OP, type: TYPE_LITERAL
token: ";", state: EXPRESSION_OP, type: TYPE_SEMICOLON
token: "}", state: STATEMENT, type: TYPE_BRACE_CLOSE
token: "b", state: STATEMENT, type: TYPE_LITERAL  # Wrong state (3)
token: "=", state: EXPRESSION_OP, type: TYPE_BIN_OP
token: "1", state: EXPRESSION, type: TYPE_LITERAL

a.delete=function(){delete x;}b=1

Change 693982 had a related patch set uploaded (by Catrope; author: Catrope):

[mediawiki/libs/Minify@master] JavaScriptMinifer: Fix handling of .delete as object property

https://gerrit.wikimedia.org/r/693982

Change 693982 merged by jenkins-bot:

[mediawiki/libs/Minify@master] JavaScriptMinifer: Fix handling of .delete as object property

https://gerrit.wikimedia.org/r/693982

Note to self: Cut a release and update core.

Change 698603 had a related patch set uploaded (by Krinkle; author: Krinkle):

[mediawiki/libs/Minify@master] Tag 2.2.3

https://gerrit.wikimedia.org/r/698603

Change 698603 merged by jenkins-bot:

[mediawiki/libs/Minify@master] Tag 2.2.3

https://gerrit.wikimedia.org/r/698603

Change 698616 had a related patch set uploaded (by Krinkle; author: Krinkle):

[mediawiki/core@master] Update wikimedia/minify to 2.2.3

https://gerrit.wikimedia.org/r/698616

Change 698616 merged by jenkins-bot:

[mediawiki/core@master] Update wikimedia/minify to 2.2.3

https://gerrit.wikimedia.org/r/698616

Change 698894 had a related patch set uploaded (by Krinkle; author: Krinkle):

[mediawiki/core@REL1_36] Update wikimedia/minify to 2.2.3

https://gerrit.wikimedia.org/r/698894

Change 698894 merged by jenkins-bot:

[mediawiki/core@REL1_36] Update wikimedia/minify to 2.2.3

https://gerrit.wikimedia.org/r/698894

Krinkle reassigned this task from Krinkle to Catrope.