[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class DiffusionMercurialWireProtocol { 4 5 public static function getCommandArgs($command) { 6 // We need to enumerate all of the Mercurial wire commands because the 7 // argument encoding varies based on the command. "Why?", you might ask, 8 // "Why would you do this?". 9 10 $commands = array( 11 'batch' => array('cmds', '*'), 12 'between' => array('pairs'), 13 'branchmap' => array(), 14 'branches' => array('nodes'), 15 'capabilities' => array(), 16 'changegroup' => array('roots'), 17 'changegroupsubset' => array('bases heads'), 18 'debugwireargs' => array('one two *'), 19 'getbundle' => array('*'), 20 'heads' => array(), 21 'hello' => array(), 22 'known' => array('nodes', '*'), 23 'listkeys' => array('namespace'), 24 'lookup' => array('key'), 25 'pushkey' => array('namespace', 'key', 'old', 'new'), 26 'stream_out' => array(''), 27 'unbundle' => array('heads'), 28 ); 29 30 if (!isset($commands[$command])) { 31 throw new Exception("Unknown Mercurial command '{$command}!"); 32 } 33 34 return $commands[$command]; 35 } 36 37 public static function isReadOnlyCommand($command) { 38 $read_only = array( 39 'between' => true, 40 'branchmap' => true, 41 'branches' => true, 42 'capabilities' => true, 43 'changegroup' => true, 44 'changegroupsubset' => true, 45 'debugwireargs' => true, 46 'getbundle' => true, 47 'heads' => true, 48 'hello' => true, 49 'known' => true, 50 'listkeys' => true, 51 'lookup' => true, 52 'stream_out' => true, 53 ); 54 55 // Notably, the write commands are "pushkey" and "unbundle". The 56 // "batch" command is theoretically read only, but we require explicit 57 // analysis of the actual commands. 58 59 return isset($read_only[$command]); 60 } 61 62 public static function isReadOnlyBatchCommand($cmds) { 63 if (!strlen($cmds)) { 64 // We expect a "batch" command to always have a "cmds" string, so err 65 // on the side of caution and throw if we don't get any data here. This 66 // either indicates a mangled command from the client or a programming 67 // error in our code. 68 throw new Exception("Expected nonempty 'cmds' specification!"); 69 } 70 71 // For "batch" we get a "cmds" argument like: 72 // 73 // heads ;known nodes= 74 // 75 // We need to examine the commands (here, "heads" and "known") to make sure 76 // they're all read-only. 77 78 // NOTE: Mercurial has some code to escape semicolons, but it does not 79 // actually function for command separation. For example, these two batch 80 // commands will produce completely different results (the former will run 81 // the lookup; the latter will fail with a parser error): 82 // 83 // lookup key=a:xb;lookup key=z* 0 84 // lookup key=a:;b;lookup key=z* 0 85 // ^ 86 // | 87 // +-- Note semicolon. 88 // 89 // So just split unconditionally. 90 91 $cmds = explode(';', $cmds); 92 foreach ($cmds as $sub_cmd) { 93 $name = head(explode(' ', $sub_cmd, 2)); 94 if (!self::isReadOnlyCommand($name)) { 95 return false; 96 } 97 } 98 99 return true; 100 } 101 102 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |