/** * 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; }
/** * 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; }
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); } }
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)); } } } }