Page MenuHomePhabricator

Peast syntax checker seemingly rejects some valid JavaScript that was previously allowed
Closed, ResolvedPublic

Description

@Raymond noticed that the AC/DC gadget (JS code, permalink) is broken – MediaWiki replaces it with a parse error:

$ curl 'https://commons.wikimedia.org/w/load.php?debug=2&lang=en&modules=ext.gadget.ACDC&skin=vector&version=ztntf'
mw.loader.impl(function(){return["ext.gadget.ACDC@",function($,jQuery,require,module){/*
MediaWiki:Gadget-ACDC.js
*/
mw.log.error("Parse error: Unexpected: function on line 20");
}];});

Presumably this is due to the introduction of Peast with this week’s train. Unfortunately, line 20 in the gadget is quite long, so it’s not immediately clear where exactly the syntax checker encounters an error. (The code should be valid, it’s emitted by webpack and was working previously.)


Summary: reduced to (a=1,2); worked around in AC/DC; no other gadget likely to be affected; upstream #65; fixed in Peast 0.16, to be deployed with 1.42.0-wmf.14.

Event Timeline

I’ll try to look into this a bit more, but I figured you’d also want to know about it quickly, hence this somewhat incomplete task.

With a strategically placed var_dump in Peast (and also xdebug.max_nesting_level=1024) I can at least get a column number:

$ curl -s 'https://commons.wikimedia.org/wiki/MediaWiki:Gadget-ACDC.js?action=raw' | php maintenance/run.php jsparse -
/home/lucas/git/wikimedia/mediawiki/vendor/mck89/peast/lib/Peast/Syntax/Exception.php:39:
class Peast\Syntax\Position#56635 (3) {
  protected $line =>
  int(20)
  protected $column =>
  int(78254)
  protected $index =>
  int(78830)
}
- ERROR: Peast\Syntax\Exception: Unexpected: function
Failed.

Which is all the way at the end of the file – just after the comma, apparently:

case"end":return t.stop()}}),t)}))),function(e,r){return t.apply(this,arguments)})(mediaWiki,jQuery)}()}();
//                                  ^

Shortest case:

$ echo '(a=1,2)' | php maintenance/run.php jsparse -
- ERROR: Peast\Syntax\Exception: Unexpected: 2
Failed.

Demo that this is valid (if not exactly idiomatic) JS:

$ echo 'function f(){return 1,(a=2,3);}console.log(f())' | php maintenance/run.php jsparse -
- ERROR: Peast\Syntax\Exception: Unexpected: 3
Failed.
$ echo 'function f(){return 1,(a=2,3);}console.log(f())' | node
3

Impact: not critical IMHO. Based on global search for “webpack”, Portuguese Wikipedia’s Gadget-arquivarPEs.js might also be affected, but probably not much else. (I wouldn’t expect anyone to write this syntax pattern by hand.)

Edit: I forgot I can just check for myself. No, that gadget is not affected. ACDC might be the only one.

$ curl -s 'https://pt.wikipedia.org/wiki/MediaWiki:Gadget-arquivarPEs.js?action=raw' | php maintenance/run.php jsparse -
- OK

I’ve worked around it for now by tweaking the code a bit so that webpack seemingly no longer outputs the problematic syntax construct (gadget diff, though it’s pretty useless, MediaWiki can’t make sense of such a huge diff of minified code ^^). So I guess I should go file a Peast issue next…

Hm, apparently Peast starts being able to parse this in ES8:

> Peast\Peast::ES7('(a=1,2)')->parse()

   Peast\Syntax\Exception  Unexpected: 2.

> Peast\Peast::ES8('(a=1,2)')->parse()
= Peast\Syntax\Node\Program {#6254
    +location: Peast\Syntax\SourceLocation {#6322
      +start: Peast\Syntax\Position {#6366},
      +end: Peast\Syntax\Position {#6359},
    },
  }

Was this actually illegal prior to ES8? (It’s possible I didn’t configure webpack correctly and it just never came up so far.)

Was this actually illegal prior to ES8? (It’s possible I didn’t configure webpack correctly and it just never came up so far.)

As far as I can tell, it should have been valid, so I filed Peast issue #65.

Change 989920 had a related patch set uploaded (by Lucas Werkmeister; author: Lucas Werkmeister):

[mediawiki/vendor@master] Bump mck89/peast to 0.16.0

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

Change 989923 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Bump mck89/peast to 0.16.0

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

Should be fixed with Peast 0.16, rolling out with the train next week.

Change 989920 merged by jenkins-bot:

[mediawiki/vendor@master] Bump mck89/peast to 0.16.0

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

Change 989923 merged by jenkins-bot:

[mediawiki/core@master] Bump mck89/peast to 0.16.0

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