mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-12 18:02:39 +01:00
(stable) Promote 2021 Week 9
This commit is contained in:
commit
b177e489b4
6 changed files with 207 additions and 3 deletions
|
@ -744,6 +744,7 @@ phutil_register_library_map(array(
|
||||||
'PhutilEnglishCanadaLocale' => 'internationalization/locales/PhutilEnglishCanadaLocale.php',
|
'PhutilEnglishCanadaLocale' => 'internationalization/locales/PhutilEnglishCanadaLocale.php',
|
||||||
'PhutilErrorHandler' => 'error/PhutilErrorHandler.php',
|
'PhutilErrorHandler' => 'error/PhutilErrorHandler.php',
|
||||||
'PhutilErrorHandlerTestCase' => 'error/__tests__/PhutilErrorHandlerTestCase.php',
|
'PhutilErrorHandlerTestCase' => 'error/__tests__/PhutilErrorHandlerTestCase.php',
|
||||||
|
'PhutilErrorLog' => 'filesystem/PhutilErrorLog.php',
|
||||||
'PhutilErrorTrap' => 'error/PhutilErrorTrap.php',
|
'PhutilErrorTrap' => 'error/PhutilErrorTrap.php',
|
||||||
'PhutilEvent' => 'events/PhutilEvent.php',
|
'PhutilEvent' => 'events/PhutilEvent.php',
|
||||||
'PhutilEventConstants' => 'events/constant/PhutilEventConstants.php',
|
'PhutilEventConstants' => 'events/constant/PhutilEventConstants.php',
|
||||||
|
@ -849,6 +850,7 @@ phutil_register_library_map(array(
|
||||||
'PhutilRawEnglishLocale' => 'internationalization/locales/PhutilRawEnglishLocale.php',
|
'PhutilRawEnglishLocale' => 'internationalization/locales/PhutilRawEnglishLocale.php',
|
||||||
'PhutilReadableSerializer' => 'readableserializer/PhutilReadableSerializer.php',
|
'PhutilReadableSerializer' => 'readableserializer/PhutilReadableSerializer.php',
|
||||||
'PhutilReadableSerializerTestCase' => 'readableserializer/__tests__/PhutilReadableSerializerTestCase.php',
|
'PhutilReadableSerializerTestCase' => 'readableserializer/__tests__/PhutilReadableSerializerTestCase.php',
|
||||||
|
'PhutilRegexException' => 'exception/PhutilRegexException.php',
|
||||||
'PhutilRope' => 'utils/PhutilRope.php',
|
'PhutilRope' => 'utils/PhutilRope.php',
|
||||||
'PhutilRopeTestCase' => 'utils/__tests__/PhutilRopeTestCase.php',
|
'PhutilRopeTestCase' => 'utils/__tests__/PhutilRopeTestCase.php',
|
||||||
'PhutilServiceProfiler' => 'serviceprofiler/PhutilServiceProfiler.php',
|
'PhutilServiceProfiler' => 'serviceprofiler/PhutilServiceProfiler.php',
|
||||||
|
@ -1009,6 +1011,9 @@ phutil_register_library_map(array(
|
||||||
'phutil_partition' => 'utils/utils.php',
|
'phutil_partition' => 'utils/utils.php',
|
||||||
'phutil_passthru' => 'future/exec/execx.php',
|
'phutil_passthru' => 'future/exec/execx.php',
|
||||||
'phutil_person' => 'internationalization/pht.php',
|
'phutil_person' => 'internationalization/pht.php',
|
||||||
|
'phutil_preg_match' => 'utils/utils.php',
|
||||||
|
'phutil_preg_match_all' => 'utils/utils.php',
|
||||||
|
'phutil_raise_preg_exception' => 'utils/utils.php',
|
||||||
'phutil_register_library' => 'init/lib/core.php',
|
'phutil_register_library' => 'init/lib/core.php',
|
||||||
'phutil_register_library_map' => 'init/lib/core.php',
|
'phutil_register_library_map' => 'init/lib/core.php',
|
||||||
'phutil_set_system_locale' => 'utils/utf8.php',
|
'phutil_set_system_locale' => 'utils/utf8.php',
|
||||||
|
@ -1812,6 +1817,7 @@ phutil_register_library_map(array(
|
||||||
'PhutilEnglishCanadaLocale' => 'PhutilLocale',
|
'PhutilEnglishCanadaLocale' => 'PhutilLocale',
|
||||||
'PhutilErrorHandler' => 'Phobject',
|
'PhutilErrorHandler' => 'Phobject',
|
||||||
'PhutilErrorHandlerTestCase' => 'PhutilTestCase',
|
'PhutilErrorHandlerTestCase' => 'PhutilTestCase',
|
||||||
|
'PhutilErrorLog' => 'Phobject',
|
||||||
'PhutilErrorTrap' => 'Phobject',
|
'PhutilErrorTrap' => 'Phobject',
|
||||||
'PhutilEvent' => 'Phobject',
|
'PhutilEvent' => 'Phobject',
|
||||||
'PhutilEventConstants' => 'Phobject',
|
'PhutilEventConstants' => 'Phobject',
|
||||||
|
@ -1925,6 +1931,7 @@ phutil_register_library_map(array(
|
||||||
'PhutilRawEnglishLocale' => 'PhutilLocale',
|
'PhutilRawEnglishLocale' => 'PhutilLocale',
|
||||||
'PhutilReadableSerializer' => 'Phobject',
|
'PhutilReadableSerializer' => 'Phobject',
|
||||||
'PhutilReadableSerializerTestCase' => 'PhutilTestCase',
|
'PhutilReadableSerializerTestCase' => 'PhutilTestCase',
|
||||||
|
'PhutilRegexException' => 'Exception',
|
||||||
'PhutilRope' => 'Phobject',
|
'PhutilRope' => 'Phobject',
|
||||||
'PhutilRopeTestCase' => 'PhutilTestCase',
|
'PhutilRopeTestCase' => 'PhutilTestCase',
|
||||||
'PhutilServiceProfiler' => 'Phobject',
|
'PhutilServiceProfiler' => 'Phobject',
|
||||||
|
|
3
src/exception/PhutilRegexException.php
Normal file
3
src/exception/PhutilRegexException.php
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhutilRegexException extends Exception {}
|
|
@ -52,7 +52,7 @@ final class Filesystem extends Phobject {
|
||||||
* Make assertions about the state of path in preparation for
|
* Make assertions about the state of path in preparation for
|
||||||
* writeFile() and writeFileIfChanged().
|
* writeFile() and writeFileIfChanged().
|
||||||
*/
|
*/
|
||||||
private static function assertWritableFile($path) {
|
public static function assertWritableFile($path) {
|
||||||
$path = self::resolvePath($path);
|
$path = self::resolvePath($path);
|
||||||
$dir = dirname($path);
|
$dir = dirname($path);
|
||||||
|
|
||||||
|
|
101
src/filesystem/PhutilErrorLog.php
Normal file
101
src/filesystem/PhutilErrorLog.php
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
final class PhutilErrorLog
|
||||||
|
extends Phobject {
|
||||||
|
|
||||||
|
private $logName;
|
||||||
|
private $logPath;
|
||||||
|
|
||||||
|
public function setLogName($log_name) {
|
||||||
|
$this->logName = $log_name;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLogName() {
|
||||||
|
return $this->logName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLogPath($log_path) {
|
||||||
|
$this->logPath = $log_path;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLogPath() {
|
||||||
|
return $this->logPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function activateLog() {
|
||||||
|
$log_path = $this->getLogPath();
|
||||||
|
|
||||||
|
if ($log_path !== null) {
|
||||||
|
// Test that the path is writable.
|
||||||
|
$write_exception = null;
|
||||||
|
try {
|
||||||
|
Filesystem::assertWritableFile($log_path);
|
||||||
|
} catch (FilesystemException $ex) {
|
||||||
|
$write_exception = $ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we hit an exception, try to create the containing directory.
|
||||||
|
if ($write_exception) {
|
||||||
|
$log_dir = dirname($log_path);
|
||||||
|
if (!Filesystem::pathExists($log_dir)) {
|
||||||
|
try {
|
||||||
|
Filesystem::createDirectory($log_dir, 0755, true);
|
||||||
|
} catch (FilesystemException $ex) {
|
||||||
|
throw new PhutilProxyException(
|
||||||
|
pht(
|
||||||
|
'Unable to write log "%s" to path "%s". The containing '.
|
||||||
|
'directory ("%s") does not exist or is not readable, and '.
|
||||||
|
'could not be created.',
|
||||||
|
$this->getLogName(),
|
||||||
|
$log_path,
|
||||||
|
$log_dir),
|
||||||
|
$ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we created the parent directory, test if the path is writable
|
||||||
|
// again.
|
||||||
|
try {
|
||||||
|
Filesystem::assertWritableFile($log_path);
|
||||||
|
$write_exception = null;
|
||||||
|
} catch (FilesystemException $ex) {
|
||||||
|
$write_exception = $ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we ran into a write exception and couldn't resolve it, fail.
|
||||||
|
if ($write_exception) {
|
||||||
|
throw new PhutilProxyException(
|
||||||
|
pht(
|
||||||
|
'Unable to write log "%s" to path "%s" because the path is not '.
|
||||||
|
'writable.',
|
||||||
|
$this->getLogName(),
|
||||||
|
$log_path),
|
||||||
|
$write_exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ini_set('error_log', $log_path);
|
||||||
|
PhutilErrorHandler::setErrorListener(array($this, 'onError'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onError($event, $value, array $metadata) {
|
||||||
|
// If we've set "error_log" to a real file, so messages won't be output to
|
||||||
|
// stderr by default. Copy them to stderr.
|
||||||
|
|
||||||
|
if ($this->logPath === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = idx($metadata, 'default_message');
|
||||||
|
|
||||||
|
if (strlen($message)) {
|
||||||
|
$message = tsprintf("%B\n", $message);
|
||||||
|
@fwrite(STDERR, $message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2008,3 +2008,89 @@ function phutil_partition(array $map) {
|
||||||
|
|
||||||
return $partitions;
|
return $partitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function phutil_preg_match(
|
||||||
|
$pattern,
|
||||||
|
$subject,
|
||||||
|
$flags = 0,
|
||||||
|
$offset = 0) {
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
$result = @preg_match($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
if ($result === false || $result === null) {
|
||||||
|
phutil_raise_preg_exception(
|
||||||
|
'preg_match',
|
||||||
|
array(
|
||||||
|
$pattern,
|
||||||
|
$subject,
|
||||||
|
$matches,
|
||||||
|
$flags,
|
||||||
|
$offset,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
function phutil_preg_match_all(
|
||||||
|
$pattern,
|
||||||
|
$subject,
|
||||||
|
$flags = 0,
|
||||||
|
$offset = 0) {
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
$result = @preg_match_all($pattern, $subject, $matches, $flags, $offset);
|
||||||
|
if ($result === false || $result === null) {
|
||||||
|
phutil_raise_preg_exception(
|
||||||
|
'preg_match_all',
|
||||||
|
array(
|
||||||
|
$pattern,
|
||||||
|
$subject,
|
||||||
|
$matches,
|
||||||
|
$flags,
|
||||||
|
$offset,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
function phutil_raise_preg_exception($function, array $argv) {
|
||||||
|
$trap = new PhutilErrorTrap();
|
||||||
|
|
||||||
|
// NOTE: This ugly construction to avoid issues with reference behavior when
|
||||||
|
// passing values through "call_user_func_array()".
|
||||||
|
|
||||||
|
switch ($function) {
|
||||||
|
case 'preg_match':
|
||||||
|
@preg_match($argv[0], $argv[1], $argv[2], $argv[3], $argv[4]);
|
||||||
|
break;
|
||||||
|
case 'preg_match_all':
|
||||||
|
@preg_match_all($argv[0], $argv[1], $argv[2], $argv[3], $argv[4]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$error_message = $trap->getErrorsAsString();
|
||||||
|
|
||||||
|
$trap->destroy();
|
||||||
|
|
||||||
|
$pattern = $argv[0];
|
||||||
|
$pattern_display = sprintf(
|
||||||
|
'"%s"',
|
||||||
|
addcslashes($pattern, '\\\"'));
|
||||||
|
|
||||||
|
$message = array();
|
||||||
|
$message[] = pht(
|
||||||
|
'Call to %s(%s, ...) failed.',
|
||||||
|
$function,
|
||||||
|
$pattern_display);
|
||||||
|
|
||||||
|
if (strlen($error_message)) {
|
||||||
|
$message[] = pht(
|
||||||
|
'Regular expression engine emitted message: %s',
|
||||||
|
$error_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = implode("\n\n", $message);
|
||||||
|
|
||||||
|
throw new PhutilRegexException($message);
|
||||||
|
}
|
||||||
|
|
|
@ -56,6 +56,15 @@ function __arcanist_init_script__() {
|
||||||
// inspect "args", and this option generally obscures useful debugging
|
// inspect "args", and this option generally obscures useful debugging
|
||||||
// information without any benefit in the context of Phabricator.
|
// information without any benefit in the context of Phabricator.
|
||||||
'zend.exception_ignore_args' => 0,
|
'zend.exception_ignore_args' => 0,
|
||||||
|
|
||||||
|
// See T13100. We'd like the regex engine to fail, rather than segfault,
|
||||||
|
// if handed a pathological regular expression.
|
||||||
|
'pcre.backtrack_limit' => 10000,
|
||||||
|
'pcre.recusion_limit' => 10000,
|
||||||
|
|
||||||
|
// NOTE: Phabricator applies a similar set of startup options for Web
|
||||||
|
// environments in "PhabricatorStartup". Changes here may also be
|
||||||
|
// appropriate to apply there.
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($config_map as $config_key => $config_value) {
|
foreach ($config_map as $config_key => $config_value) {
|
||||||
|
@ -106,8 +115,6 @@ function __arcanist_init_script__() {
|
||||||
|
|
||||||
PhutilErrorHandler::initialize();
|
PhutilErrorHandler::initialize();
|
||||||
|
|
||||||
PhutilErrorHandler::initialize();
|
|
||||||
|
|
||||||
// If "variables_order" excludes "E", silently repair it so that $_ENV has
|
// If "variables_order" excludes "E", silently repair it so that $_ENV has
|
||||||
// the values we expect.
|
// the values we expect.
|
||||||
PhutilExecutionEnvironment::repairMissingVariablesOrder();
|
PhutilExecutionEnvironment::repairMissingVariablesOrder();
|
||||||
|
|
Loading…
Reference in a new issue