@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 122 lines 4.4 kB view raw
1<?php 2 3final class DiffusionMercurialCommandEngine 4 extends DiffusionCommandEngine { 5 6 protected function canBuildForRepository( 7 PhabricatorRepository $repository) { 8 return $repository->isHg(); 9 } 10 11 protected function newFormattedCommand($pattern, array $argv) { 12 $args = array(); 13 14 // Crudely blacklist commands which look like they may contain command 15 // injection via "--config" or "--debugger". See T13012. To do this, we 16 // print the whole command, parse it using shell rules, then examine each 17 // argument to see if it looks like "--config" or "--debugger". 18 19 $test_command = call_user_func_array( 20 'csprintf', 21 array_merge(array($pattern), $argv)); 22 $test_args = id(new PhutilShellLexer()) 23 ->splitArguments($test_command); 24 25 foreach ($test_args as $test_arg) { 26 if (preg_match('/^--(config|debugger)/i', $test_arg)) { 27 throw new DiffusionMercurialFlagInjectionException( 28 pht( 29 'Mercurial command appears to contain unsafe injected "--config" '. 30 'or "--debugger": %s', 31 $test_command)); 32 } 33 } 34 35 // NOTE: Here, and in Git and Subversion, we override the SSH command even 36 // if the repository does not use an SSH remote, since our SSH wrapper 37 // defuses an attack against older versions of Mercurial, Git and 38 // Subversion (see T12961) and it's possible to execute this attack 39 // in indirect ways, like by using an SSH subrepo inside an HTTP repo. 40 41 $pattern = "hg --config ui.ssh=%s {$pattern}"; 42 $args[] = $this->getSSHWrapper(); 43 44 return array($pattern, array_merge($args, $argv)); 45 } 46 47 protected function newCustomEnvironment() { 48 $env = array(); 49 50 // NOTE: This overrides certain configuration, extensions, and settings 51 // which make Mercurial commands do random unusual things. 52 $env['HGPLAIN'] = 1; 53 54 return $env; 55 } 56 57 /** 58 * Sanitize output of an `hg` command invoked with the `--debug` flag to make 59 * it usable. 60 * 61 * @param string $stdout Output from `hg --debug ...` 62 * @return string Usable output. 63 */ 64 public static function filterMercurialDebugOutput($stdout) { 65 // When hg commands are run with `--debug` and some config file isn't 66 // trusted, Mercurial prints out a warning to stdout, twice, after Feb 2011. 67 // 68 // http://selenic.com/pipermail/mercurial-devel/2011-February/028541.html 69 // 70 // After Jan 2015, it may also fail to write to a revision branch cache. 71 // 72 // Separately, it may fail to write to a different branch cache, and may 73 // encounter issues reading the branch cache. 74 // 75 // When Mercurial repositories are hosted on external systems with 76 // multi-user environments it's possible that the branch cache is computed 77 // on a revision which does not end up being published. When this happens it 78 // will recompute the cache but also print out "invalid branch cache". 79 // 80 // https://www.mercurial-scm.org/pipermail/mercurial/2014-June/047239.html 81 // 82 // When observing a repository which uses largefiles, the debug output may 83 // also contain extraneous output about largefile changes. 84 // 85 // At some point Mercurial added/improved support for pager used when 86 // command output is large. It includes printing out debug information that 87 // the pager is being started for a command. This seems to happen despite 88 // the output of the command being piped/read from another process. 89 // 90 // When printing color output Mercurial may run into some issue with the 91 // terminal info. This should never happen in Phabricator since color 92 // output should be turned off, however in the event it shows up we should 93 // filter it out anyways. 94 95 $ignore = array( 96 'ignoring untrusted configuration option', 97 "couldn't write revision branch cache:", 98 "couldn't write branch cache:", 99 'invalid branchheads cache', 100 'invalid branch cache', 101 'updated patterns: .hglf', 102 'starting pager for command', 103 'no terminfo entry for', 104 ); 105 106 foreach ($ignore as $key => $pattern) { 107 $ignore[$key] = preg_quote($pattern, '/'); 108 } 109 110 $ignore = '('.implode('|', $ignore).')'; 111 112 $lines = preg_split('/(?<=\n)/', $stdout); 113 $regex = '/'.$ignore.'.*\n$/'; 114 115 foreach ($lines as $key => $line) { 116 $lines[$key] = preg_replace($regex, '', $line); 117 } 118 119 return implode('', $lines); 120 } 121 122}