Arc browse with default browser doesn't work on windows

Reproduction Instructions

  1. Install arc on windows and configure it against a phabricator installation
  2. arc --trace browse .

The command will fail with output:

PS C:\Users\Yannay\res\repo> arc --trace browse .
 ARGV  "C:\Users\Yannay\src\arcanist\bin\..\scripts\arcanist.php" "--trace" "browse" "."
 LOAD  Loaded "phutil" from "C:\Users\Yannay\src\libphutil\src".
 LOAD  Loaded "arcanist" from "C:\Users\Yannay\src\arcanist\src".
Config: Reading user configuration file "C:\Users\Yannay\AppData\Roaming/.arcrc"...
Config: Did not find system configuration at "C:\ProgramData\Phabricator/Arcanist/config".
Working Copy: Unable to find .arcconfig in any of these locations: C:\Users\Yannay\res\repo/.arcconfig.
Working Copy: Path "C:\Users\Yannay\res\repo" is part of `git` working copy "C:\Users\Yannay\res\repo".
Working Copy: Project root is at "C:\Users\Yannay\res\repo".
Config: Did not find local configuration at "C:\Users\Yannay\res\repo\.git\arc/config".
>>> [0] (+0) <http> http://phabricator.company.local/api/user.whoami
<<< [0] (+60) <http> 60,554 us
>>> [1] (+63) <http> http://phabricator.company.local/api/phid.lookup
<<< [1] (+82) <http> 18,663 us
Opening . as a repository path.
>>> [2] (+90) <exec> $ git symbolic-ref --quiet HEAD
<<< [2] (+125) <exec> 34,119 us
>>> [3] (+125) <exec> $ git rev-parse --symbolic-full-name "master"@{upstream}
<<< [3] (+172) <exec> 47,199 us
>>> [4] (+173) <exec> $ git --version
<<< [4] (+251) <exec> 77,419 us
>>> [5] (+252) <exec> $ git ls-remote --get-url "origin"
<<< [5] (+329) <exec> 76,440 us
>>> [6] (+329) <http> http://phabricator.company.local/api/repository.query
<<< [6] (+367) <http> 37,795 us
>>> [7] (+368) <exec> $ "start" "http://phabricator.company.local/diffusion/REP/browse/master/"

[2019-06-26 12:23:59] EXCEPTION: (Exception) Failed to passthru proc_open(): proc_open(): CreateProcess failed, error code - 2 at [<phutil>\src\future\exec\PhutilExecPassthru.php:103]
arcanist(head=master, ref.master=d92fa96366c0), phutil(head=master, ref.master=340e00f6622d)
  #0 PhutilExecPassthru::execute() called at [<phutil>\src\future\exec\execx.php:50]
  #1 phutil_passthru(string, string, string) called at [<arcanist>\src\workflow\ArcanistWorkflow.php:1974]
  #2 ArcanistWorkflow::openURIsInBrowser(array) called at [<arcanist>\src\workflow\ArcanistBrowseWorkflow.php:209]
  #3 ArcanistBrowseWorkflow::run() called at [<arcanist>\scripts\arcanist.php:394]

Phabricator/Arcanist Version

arcanist d92fa96366c0ed50e4257508148aa75192d4fb1f (20 Jun 2019)
libphutil 340e00f6622d1de36eb5c8b1ca5d602e2a807d97 (26 Jun 2019)

The reason for the bug is libphutil’s escaping and wrapping of shell arguments + windows peculiarity of the start command. The default browser on windows is “start” but this command doesn’t worked when wrapped in quotes, i.e. start . works but "start" . does not. Moreover, even quoting start’s argument, i.e. start "http://google.com" fails.
Therefore when wrapping a command by libphtil’s csprintf, it will not work.

I think it’s related to this issue https://secure.phabricator.com/T9485 and probably a bunch of others.