Changeset View
Changeset View
Standalone View
Standalone View
src/filesystem/binary/PhutilMercurialBinaryAnalyzer.php
- This file was added.
| <?php | |||||
| final class PhutilMercurialBinaryAnalyzer | |||||
| extends PhutilBinaryAnalyzer { | |||||
| const BINARY = 'hg'; | |||||
| const CAPABILITY_FILES = 'files'; | |||||
| const CAPABILITY_INJECTION = 'injection'; | |||||
| protected function newBinaryVersion() { | |||||
| list($err, $stdout) = exec_manual('hg --version --quiet'); | |||||
| if ($err) { | |||||
| return null; | |||||
| } | |||||
| return self::parseMercurialBinaryVersion($stdout); | |||||
| } | |||||
| public static function parseMercurialBinaryVersion($stdout) { | |||||
| // NOTE: At least on OSX, recent versions of Mercurial report this | |||||
| // string in this format: | |||||
| // | |||||
| // Mercurial Distributed SCM (version 3.1.1+20140916) | |||||
| $matches = null; | |||||
| $pattern = '/^Mercurial Distributed SCM \(version ([\d.]+)/m'; | |||||
| if (preg_match($pattern, $stdout, $matches)) { | |||||
| return $matches[1]; | |||||
| } | |||||
| return null; | |||||
| } | |||||
| /** | |||||
| * The `locate` command is deprecated as of Mercurial 3.2, to be replaced | |||||
| * with `files` command, which supports most of the same arguments. This | |||||
| * determines whether the new `files` command should be used instead of | |||||
| * the `locate` command. | |||||
| * | |||||
| * @return boolean True if the version of Mercurial is new enough to support | |||||
| * the `files` command, or false if otherwise. | |||||
| */ | |||||
| public function isMercurialFilesCommandAvailable() { | |||||
| return self::versionHasCapability( | |||||
| $this->requireBinaryVersion(), | |||||
| self::CAPABILITY_FILES); | |||||
| } | |||||
| public function isMercurialVulnerableToInjection() { | |||||
| return self::versionHasCapability( | |||||
| $this->requireBinaryVersion(), | |||||
| self::CAPABILITY_INJECTION); | |||||
| } | |||||
| public static function versionHasCapability( | |||||
| $mercurial_version, | |||||
| $capability) { | |||||
| switch ($capability) { | |||||
| case self::CAPABILITY_FILES: | |||||
| return version_compare($mercurial_version, '3.2', '>='); | |||||
| case self::CAPABILITY_INJECTION: | |||||
| return version_compare($mercurial_version, '3.2.4', '<'); | |||||
| default: | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Unknown Mercurial capability "%s".', | |||||
| $capability)); | |||||
| } | |||||
| } | |||||
| } | |||||