/**
  * Execute this command.
  *
  * @return int  Error code returned by the subprocess.
  *
  * @task command
  */
 public function execute()
 {
     $command = $this->command;
     $profiler = PhutilServiceProfiler::getInstance();
     $call_id = $profiler->beginServiceCall(array('type' => 'exec', 'subtype' => 'passthru', 'command' => $command));
     $spec = array(STDIN, STDOUT, STDERR);
     $pipes = array();
     if ($command instanceof PhutilCommandString) {
         $unmasked_command = $command->getUnmaskedString();
     } else {
         $unmasked_command = $command;
     }
     $env = $this->env;
     $cwd = $this->cwd;
     $options = array();
     if (phutil_is_windows()) {
         // Without 'bypass_shell', things like launching vim don't work properly,
         // and we can't execute commands with spaces in them, and all commands
         // invoked from git bash fail horridly, and everything is a mess in
         // general.
         $options['bypass_shell'] = true;
     }
     $trap = new PhutilErrorTrap();
     $proc = @proc_open($unmasked_command, $spec, $pipes, $cwd, $env, $options);
     $errors = $trap->getErrorsAsString();
     $trap->destroy();
     if (!is_resource($proc)) {
         throw new Exception(pht('Failed to passthru %s: %s', 'proc_open()', $errors));
     }
     $err = proc_close($proc);
     $profiler->endServiceCall($call_id, array('err' => $err));
     return $err;
 }
 /**
  * Removes an error trap. Normally you should not invoke this directly;
  * @{class:PhutilErrorTrap} deregisters itself on destruction.
  *
  * @param PhutilErrorTrap Trap to remove.
  * @return void
  * @task trap
  */
 public static function removeErrorTrap(PhutilErrorTrap $trap)
 {
     $key = $trap->getTrapKey();
     unset(self::$traps[$key]);
 }
 /**
  * Get the GD image resource for the image being transformed.
  *
  * @return resource GD image resource.
  */
 protected function getImage()
 {
     if ($this->image !== null) {
         return $this->image;
     }
     if (!function_exists('imagecreatefromstring')) {
         throw new Exception(pht('Unable to transform image: the imagecreatefromstring() function ' . 'is not available. Install or enable the "gd" extension for PHP.'));
     }
     $data = $this->getData();
     $data = (string) $data;
     // First, we're going to write the file to disk and use getimagesize()
     // to determine its dimensions without actually loading the pixel data
     // into memory. For very large images, we'll bail out.
     // In particular, this defuses a resource exhaustion attack where the
     // attacker uploads a 40,000 x 40,000 pixel PNGs of solid white. These
     // kinds of files compress extremely well, but require a huge amount
     // of memory and CPU to process.
     $tmp = new TempFile();
     Filesystem::writeFile($tmp, $data);
     $tmp_path = (string) $tmp;
     $trap = new PhutilErrorTrap();
     $info = @getimagesize($tmp_path);
     $errors = $trap->getErrorsAsString();
     $trap->destroy();
     unset($tmp);
     if ($info === false) {
         throw new Exception(pht('Unable to get image information with getimagesize(): %s', $errors));
     }
     list($width, $height) = $info;
     if ($width <= 0 || $height <= 0) {
         throw new Exception(pht('Unable to determine image width and height with getimagesize().'));
     }
     $max_pixels = 4096 * 4096;
     $img_pixels = $width * $height;
     if ($img_pixels > $max_pixels) {
         throw new Exception(pht('This image (with dimensions %spx x %spx) is too large to ' . 'transform. The image has %s pixels, but transforms are limited ' . 'to images with %s or fewer pixels.', new PhutilNumber($width), new PhutilNumber($height), new PhutilNumber($img_pixels), new PhutilNumber($max_pixels)));
     }
     $trap = new PhutilErrorTrap();
     $image = @imagecreatefromstring($data);
     $errors = $trap->getErrorsAsString();
     $trap->destroy();
     if ($image === false) {
         throw new Exception(pht('Unable to load image data with imagecreatefromstring(): %s', $errors));
     }
     $this->image = $image;
     return $this->image;
 }
示例#4
0
/**
 * Decode an INI string.
 *
 * @param  string
 * @return mixed
 */
function phutil_ini_decode($string)
{
    $results = null;
    $trap = new PhutilErrorTrap();
    try {
        if (!function_exists('parse_ini_string')) {
            throw new PhutilMethodNotImplementedException(pht('%s is not compatible with your version of PHP (%s). This function ' . 'is only supported on PHP versions newer than 5.3.0.', __FUNCTION__, phpversion()));
        }
        $results = @parse_ini_string($string, true, INI_SCANNER_RAW);
        if ($results === false) {
            throw new PhutilINIParserException(trim($trap->getErrorsAsString()));
        }
        foreach ($results as $section => $result) {
            if (!is_array($result)) {
                // We JSON decode the value in ordering to perform the following
                // conversions:
                //
                //   - `'true'` => `true`
                //   - `'false'` => `false`
                //   - `'123'` => `123`
                //   - `'1.234'` => `1.234`
                //
                $result = json_decode($result, true);
                if ($result !== null && !is_array($result)) {
                    $results[$section] = $result;
                }
                continue;
            }
            foreach ($result as $key => $value) {
                $value = json_decode($value, true);
                if ($value !== null && !is_array($value)) {
                    $results[$section][$key] = $value;
                }
            }
        }
    } catch (Exception $ex) {
        $trap->destroy();
        throw $ex;
    }
    $trap->destroy();
    return $results;
}
示例#5
0
 public function check($value, $name = null)
 {
     switch ($this->type) {
         case 'int':
             if (!is_int($value)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             break;
         case 'float':
             if (!is_float($value)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             break;
         case 'bool':
             if (!is_bool($value)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             break;
         case 'string':
             if (!is_string($value)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             break;
         case 'regex':
             $trap = new PhutilErrorTrap();
             $ok = @preg_match($value, '');
             $err = $trap->getErrorsAsString();
             $trap->destroy();
             if ($ok === false) {
                 throw new PhutilTypeCheckException($this, $value, $name, $err);
             }
             break;
         case 'null':
             if (!is_null($value)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             break;
         case 'list':
             if (!is_array($value)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             if ($value && array_keys($value) !== range(0, count($value) - 1)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             try {
                 foreach ($value as $v) {
                     $this->subtypes[0]->check($v);
                 }
             } catch (PhutilTypeCheckException $ex) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             break;
         case 'map':
             if (!is_array($value)) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             try {
                 foreach ($value as $k => $v) {
                     $this->subtypes[0]->check($k);
                     $this->subtypes[1]->check($v);
                 }
             } catch (PhutilTypeCheckException $ex) {
                 throw new PhutilTypeCheckException($this, $value, $name);
             }
             break;
         case 'or':
             foreach ($this->subtypes as $subtype) {
                 try {
                     $subtype->check($value);
                     return;
                 } catch (PhutilTypeCheckException $ex) {
                     // Ignore.
                 }
             }
             throw new PhutilTypeCheckException($this, $value, $name);
         case 'wild':
             return;
         default:
             if (class_exists($this->type, false)) {
                 if ($value instanceof $this->type) {
                     return;
                 }
             } else {
                 if (interface_exists($this->type, false)) {
                     if ($value instanceof $this->type) {
                         return;
                     }
                 }
             }
             throw new PhutilTypeCheckException($this, $value, $name);
     }
 }
示例#6
0
 public static function verifySignature($method, array $params, array $meta, $openssl_public_key)
 {
     $auth_type = idx($meta, 'auth.type');
     switch ($auth_type) {
         case self::AUTH_ASYMMETRIC:
             break;
         default:
             throw new Exception(pht('Unable to verify request signature, specified "%s" ' . '("%s") is unknown.', 'auth.type', $auth_type));
     }
     $public_key = idx($meta, 'auth.key');
     if (!strlen($public_key)) {
         throw new Exception(pht('Unable to verify request signature, no "%s" present in ' . 'request protocol information.', 'auth.key'));
     }
     $signature = idx($meta, 'auth.signature');
     if (!strlen($signature)) {
         throw new Exception(pht('Unable to verify request signature, no "%s" present ' . 'in request protocol information.', 'auth.signature'));
     }
     $prefix = self::SIGNATURE_CONSIGN_1;
     if (strncmp($signature, $prefix, strlen($prefix)) !== 0) {
         throw new Exception(pht('Unable to verify request signature, signature format is not ' . 'known.'));
     }
     $signature = substr($signature, strlen($prefix));
     $input = self::encodeRequestDataForSignature($method, $params, $meta);
     $signature = base64_decode($signature);
     $trap = new PhutilErrorTrap();
     $result = @openssl_verify($input, $signature, $openssl_public_key);
     $err = $trap->getErrorsAsString();
     $trap->destroy();
     if ($result === 1) {
         // Signature is good.
         return true;
     } else {
         if ($result === 0) {
             // Signature is bad.
             throw new Exception(pht('Request signature verification failed: signature is not correct.'));
         } else {
             // Some kind of error.
             if (strlen($err)) {
                 throw new Exception(pht('OpenSSL encountered an error verifying the request signature: %s', $err));
             } else {
                 throw new Exception(pht('OpenSSL encountered an unknown error verifying the request: %s', $err));
             }
         }
     }
 }