From e8cae947580693d8a4d65fc798586da89688c3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Ja=CC=88ger?= Date: Thu, 28 Mar 2013 23:37:30 +0100 Subject: [PATCH 01/17] fix overwriting of request's locale if attribute _locale is missing --- .../HttpKernel/EventListener/LocaleListener.php | 2 +- .../Tests/EventListener/LocaleListenerTest.php | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php b/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php index f3cb804832..dac810abae 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php @@ -50,7 +50,7 @@ class LocaleListener implements EventSubscriberInterface $request = $event->getRequest(); $request->setDefaultLocale($this->defaultLocale); - $this->setLocale($request, $request->attributes->get('_locale', $this->defaultLocale)); + $this->setLocale($request, $request->attributes->get('_locale', $request->getLocale())); array_unshift($this->locales, $request->getLocale()); } diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php index 9ca64321b2..e5e4e3a286 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php @@ -68,6 +68,17 @@ class LocaleListenerTest extends \PHPUnit_Framework_TestCase $listener->onKernelRequest($this->getEvent($request)); } + public function testRequestLocaleIsNotOverridden() + { + $request = Request::create('/'); + $request->setLocale('de'); + $listener = new LocaleListener('fr'); + $event = $this->getEvent($request); + + $listener->onKernelRequest($event); + $this->assertEquals('de', $request->getLocale()); + } + private function getEvent(Request $request) { return new GetResponseEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, HttpKernelInterface::MASTER_REQUEST); From b0ba9fd712335fce1f389eadeda30348b1da3e7d Mon Sep 17 00:00:00 2001 From: Bilal Amarni Date: Tue, 2 Apr 2013 11:25:27 +0300 Subject: [PATCH 02/17] [WebProfilerBundle] removed next pointer class in a template --- .../Resources/views/Collector/request.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index fa43c50201..511a666a2a 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -9,7 +9,7 @@ {{ collector.controller.method }} {% else %} - {{ collector.controller }} + {{ collector.controller }} {% endif %} {% endset %} {% set request_status_code_color = (400 > collector.statuscode) ? ((200 == collector.statuscode) ? 'green' : 'yellow') : 'red'%} From 375ded4227f55b341898446434336fb56a3f11ef Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 5 Apr 2013 08:39:48 +0200 Subject: [PATCH 03/17] [FrameworkBundle] fixed the discovery of the PHPUnit configuration file when using aggregate options like in -vc app/ (closes #7562) --- src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php index ea0c49ecbd..0048f5539c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php @@ -82,19 +82,19 @@ abstract class WebTestCase extends \PHPUnit_Framework_TestCase } /** - * Finds the value of configuration flag from cli + * Finds the value of the CLI configuration option. * * PHPUnit will use the last configuration argument on the command line, so this only returns - * the last configuration argument + * the last configuration argument. * - * @return string The value of the phpunit cli configuration option + * @return string The value of the PHPUnit cli configuration option */ private static function getPhpUnitCliConfigArgument() { $dir = null; $reversedArgs = array_reverse($_SERVER['argv']); foreach ($reversedArgs as $argIndex => $testArg) { - if ($testArg === '-c' || $testArg === '--configuration') { + if (preg_match('/^-[^ \-]*c$/', $testArg) || $testArg === '--configuration') { $dir = realpath($reversedArgs[$argIndex - 1]); break; } elseif (strpos($testArg, '--configuration=') === 0) { From 815eb6144cd284eb292e235e41657ba6d76a631a Mon Sep 17 00:00:00 2001 From: phc Date: Fri, 5 Apr 2013 14:59:25 +0200 Subject: [PATCH 04/17] [HttpFoundation] Fixed copy pasted comment from FlashBag in AttributeBag --- .../Component/HttpFoundation/Session/Attribute/AttributeBag.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php b/src/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php index 2f1a4222e7..e9d0257152 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php +++ b/src/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php @@ -31,7 +31,7 @@ class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Counta /** * Constructor. * - * @param string $storageKey The key used to store flashes in the session. + * @param string $storageKey The key used to store attributes in the session. */ public function __construct($storageKey = '_sf2_attributes') { From 2ea5eaadc6ad5992a00e0e28254251aa18637450 Mon Sep 17 00:00:00 2001 From: Christian Morgan Date: Fri, 5 Apr 2013 22:29:42 +0100 Subject: [PATCH 05/17] Fixed phpdoc blocks to show that $uri can be passed as a string or ControllerReference (rather than just as a string) --- .../Bridge/Twig/Extension/HttpKernelExtension.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php index ecdff56f5c..e11fbcc95c 100644 --- a/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php @@ -45,8 +45,8 @@ class HttpKernelExtension extends \Twig_Extension /** * Renders a fragment. * - * @param string $uri A URI - * @param array $options An array of options + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance + * @param array $options An array of options * * @return string The fragment content * @@ -65,9 +65,9 @@ class HttpKernelExtension extends \Twig_Extension /** * Renders a fragment. * - * @param string $strategy A strategy name - * @param string $uri A URI - * @param array $options An array of options + * @param string $strategy A strategy name + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance + * @param array $options An array of options * * @return string The fragment content * From 3c5ee556fd43318149712253215dce4a7248a1fb Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 6 Apr 2013 12:15:29 +0200 Subject: [PATCH 06/17] updated CHANGELOG for 2.2.1 --- CHANGELOG-2.2.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/CHANGELOG-2.2.md b/CHANGELOG-2.2.md index 74f7e2c303..8abd730929 100644 --- a/CHANGELOG-2.2.md +++ b/CHANGELOG-2.2.md @@ -7,6 +7,62 @@ in 2.2 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.2.0...v2.2.1 +* 2.2.1 (2013-04-06) + + * 751abe1: Doctrine cannot handle bare random non-utf8 strings + * 673fd9b: idAsIndex should be true with a smallint or bigint id field. + * 64a1d39: Fixed long multibyte parameter logging in DbalLogger:startQuery + * 4cf06c1: Keep the file extension in the temporary copy and test that it exists (closes #7482) + * 64ac34d: [Security] fixed wrong interface + * 9875c4b: Added '@@' escaping strategy for YamlFileLoader and YamlDumper + * bbcdfe2: [Yaml] fixed bugs with folded scalar parsing + * 5afea04: [Form] made DefaultCsrfProvider using session_status() when available + * c928ddc: [HttpFoudantion] fixed Request::getPreferredLanguage() + * e6b7515: [DomCrawler] added support for query string with slash + * 633c051: Fixed invalid file path for hiddeninput.exe on Windows. + * 7ef90d2: fix xsd definition for strict-requirements + * 39445c5: [WebProfilerBundle] Fixed the toolbar styles to apply them in IE8 + * 601da45: [ClassLoader] fixed heredocs handling + * 17dc2ff: [HttpRequest] fixes Request::getLanguages() bug + * 67fbbac: [DoctrineBridge] Fixed non-utf-8 recognition + * e51432a: sub-requests are now created with the same class as their parent + * cc3a40e: [FrameworkBundle] changed temp kernel name in cache:clear + * d7a7434: [Routing] fix url generation for optional parameter having a null value + * ef53456: [DoctrineBridge] Avoids blob values to be logged by doctrine + * 6575df6: [Security] use current request attributes to generate redirect url? + * 7216cb0: [Validator] fix showing wrong max file size for upload errors + * c423f16: [2.1][TwigBridge] Fixes Issue #7342 in TwigBridge + * 7d87ecd: [FrameworkBundle] fixed cahe:clear command's warmup + * 5ad4bd1: [TwigBridge] now enter/leave scope on Twig_Node_Module + * fe4cc24: [TwigBridge] fixed fixed scope & trans_default_domain node visitor + * fc47589: [BrowserKit] added ability to ignored malformed set-cookie header + * 602cdee: replace INF to PHP_INT_MAX inside Finder component. + * 5bc30bb: [Translation] added xliff loader/dumper with resname support + * 663c796: Property accessor custom array object fix + * 4f3771d: [2.2][HttpKernel] fixed wrong option name in FragmentHandler::fixOptions + * a735cbd: fix xargs pipe to work with spaces in dir names + * 15bf033: [FrameworkBundle] fix router debug command + * d16d193: [FramworkBundle] removed unused property of trans update command + * 523ef29: Fix warning for buildXml method + * 7241be9: [Finder] fixed a potential issue on Solaris where INF value is wrong (refs #7269) + * 1d3da29: [FrameworkBundle] avoids cache:clear to break if new/old folders already exist + * b9cdb9a: [HttpKernel] Fixed possible profiler token collision (closes #7272, closes #7171) + * d1f5d25: [FrameworkBundle] Fixes invalid serialized objects in cache + * c82c754: RedisProfilerStorage wrong db-number/index-number selected + * e86fefa: Unset loading[$id] in ContainerBuilder on exception + * 709518b: Default validation message translation fix. + * c0687cd: remove() should not use deprecated getParent() so it does not trigger deprecation internally + * 708c0d3: adjust routing tests to not use prefix in addCollection + * acff735: [Routing] trigger deprecation warning for deprecated features that will be removed in 2.3 + * 41ad9d8: [Routing] make xml loader more tolerant + * 73bead7: [ClassLoader] made DebugClassLoader idempotent + * a4ec677: [DomCrawler] Fix relative path handling in links + * 6681df0: [Console] fixed StringInput binding + * 5bf2f71: [Console] added deprecation annotation + * 8d9cd42: Routing issue with installation in a sub-directory ref: https://github.com/symfony/symfony/issues/7129 + * c97ee8d: [Translator] mention that the message id may also be an object that can be cast to string in TranslatorInterface and fix the IdentityTranslator that did not respect this + * 5a36b2d: [Translator] fix MessageCatalogueInterface::getFallbackCatalogue that can return null + * 2.2.0 (2013-03-01) * 5b19c89: [Console] fixed unparsed StringInput tokens From 8d0cb78fbf94979c28c7b043be8387ecba21da5b Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 6 Apr 2013 12:16:33 +0200 Subject: [PATCH 07/17] updated VERSION for 2.2.1 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index e87884bcaa..18950c190b 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -62,12 +62,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $classes; protected $errorReportingLevel; - const VERSION = '2.2.1-DEV'; + const VERSION = '2.2.1'; const VERSION_ID = '20101'; const MAJOR_VERSION = '2'; const MINOR_VERSION = '2'; const RELEASE_VERSION = '1'; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; /** * Constructor. From 6c114ca8c4780bbb1f0863df61e35ad93138b861 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 6 Apr 2013 15:17:40 +0200 Subject: [PATCH 08/17] bumped Symfony version to 2.2.2-DEV --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 18950c190b..6898ea8252 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -62,12 +62,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $classes; protected $errorReportingLevel; - const VERSION = '2.2.1'; - const VERSION_ID = '20101'; + const VERSION = '2.2.2-DEV'; + const VERSION_ID = '20202'; const MAJOR_VERSION = '2'; const MINOR_VERSION = '2'; - const RELEASE_VERSION = '1'; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = '2'; + const EXTRA_VERSION = 'DEV'; /** * Constructor. From 99256e44a08ac84d04bf46bde7c865e4daa3d971 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 7 Apr 2013 13:10:08 +0200 Subject: [PATCH 09/17] [HttpKernel] Remove args from 5.3 stack traces to avoid filling log files, fixes #7259 --- .../Component/HttpKernel/Debug/ErrorHandler.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php b/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php index 3c1cf72d2d..9260f4ad22 100644 --- a/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php +++ b/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php @@ -87,7 +87,17 @@ class ErrorHandler if ($level & (E_USER_DEPRECATED | E_DEPRECATED)) { if (null !== self::$logger) { - $stack = version_compare(PHP_VERSION, '5.4', '<') ? array_slice(debug_backtrace(false), 0, 10) : debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10); + if (version_compare(PHP_VERSION, '5.4', '<')) { + $stack = array_map( + function ($row) { + unset($row['args']); + return $row; + }, + array_slice(debug_backtrace(false), 0, 10) + ); + } else { + $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10); + } self::$logger->warning($message, array('type' => self::TYPE_DEPRECATION, 'stack' => $stack)); } From 3780fdb214ac8c192fb38bac00134a2c5f561453 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Sat, 6 Apr 2013 20:51:55 +0200 Subject: [PATCH 10/17] Fix Process timeout --- src/Symfony/Component/Process/Process.php | 43 +++++++++++++++---- .../Component/Process/ProcessBuilder.php | 6 +-- .../Process/Tests/AbstractProcessTest.php | 42 ++++++++++++++++++ 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index f8a3293b12..a4ee6a760a 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -34,10 +34,14 @@ class Process const STDOUT = 1; const STDERR = 2; + // Timeout Precision in seconds. + CONST TIMEOUT_PRECISION = 0.2; + private $commandline; private $cwd; private $env; private $stdin; + private $starttime; private $timeout; private $options; private $exitcode; @@ -211,6 +215,7 @@ class Process throw new \RuntimeException('Process is already running'); } + $this->starttime = microtime(true); $this->stdout = ''; $this->stderr = ''; $callback = $this->buildCallback($callback); @@ -285,7 +290,7 @@ class Process $w = $writePipes; $e = null; - $n = @stream_select($r, $w, $e, $this->timeout); + $n = @stream_select($r, $w, $e, 0, static::TIMEOUT_PRECISION * 1E6); if (false === $n) { break; @@ -318,6 +323,8 @@ class Process unset($this->pipes[$type]); } } + + $this->checkTimeout(); } $this->updateStatus(); @@ -345,13 +352,15 @@ class Process if (defined('PHP_WINDOWS_VERSION_BUILD') && $this->fileHandles) { $this->processFileHandles($callback, !$this->pipes); } + $this->checkTimeout(); if ($this->pipes) { $r = $this->pipes; $w = null; $e = null; - if (false === $n = @stream_select($r, $w, $e, $this->timeout)) { + // let's have a look if something changed in streams + if (false === $n = @stream_select($r, $w, $e, 0, static::TIMEOUT_PRECISION * 1E6)) { $lastError = error_get_last(); // stream_select returns false when the `select` system call is interrupted by an incoming signal @@ -361,10 +370,11 @@ class Process continue; } - if (0 === $n) { - proc_terminate($this->process); - throw new \RuntimeException('The process timed out.'); + + // nothing has changed + if (0 === $n) { + continue; } foreach ($r as $pipe) { @@ -675,7 +685,7 @@ class Process * * To disable the timeout, set this value to null. * - * @param integer|null $timeout The timeout in seconds + * @param float|null $timeout The timeout in seconds * * @throws \InvalidArgumentException if the timeout is negative */ @@ -687,10 +697,10 @@ class Process return; } - $timeout = (integer) $timeout; + $timeout = (float) $timeout; if ($timeout < 0) { - throw new \InvalidArgumentException('The timeout value must be a valid positive integer.'); + throw new \InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); } $this->timeout = $timeout; @@ -829,6 +839,23 @@ class Process $this->enhanceSigchildCompatibility = (Boolean) $enhance; } + /** + * Performs a check between the timeout definition and the time the process + * started + * + * In case you run a background process (with the start method), you should + * trigger this method regularly to ensure the process timeout + * + * @throws RuntimeException In case the timeout was reached + */ + public function checkTimeout() + { + if (0 < $this->timeout && $this->timeout < (microtime(true) - $this->starttime)) { + $this->stop(0); + throw new RuntimeException('Process timed-out.'); + } + } + /** * Builds up the callback used by wait(). * diff --git a/src/Symfony/Component/Process/ProcessBuilder.php b/src/Symfony/Component/Process/ProcessBuilder.php index 2ffb3af5ff..3d8b687fec 100644 --- a/src/Symfony/Component/Process/ProcessBuilder.php +++ b/src/Symfony/Component/Process/ProcessBuilder.php @@ -86,7 +86,7 @@ class ProcessBuilder * * To disable the timeout, set this value to null. * - * @param integer|null + * @param float|null */ public function setTimeout($timeout) { @@ -96,10 +96,10 @@ class ProcessBuilder return $this; } - $timeout = (integer) $timeout; + $timeout = (float) $timeout; if ($timeout < 0) { - throw new \InvalidArgumentException('The timeout value must be a valid positive integer.'); + throw new \InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); } $this->timeout = $timeout; diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index 51d51f40b8..10dea51098 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Process\Tests; use Symfony\Component\Process\Process; +use Symfony\Component\Process\Exception\RuntimeException; /** * @author Robert Schönthal @@ -255,6 +256,47 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase // PHP will deadlock when it tries to cleanup $process } + public function testRunProcessWithTimeout() + { + $timeout = 0.5; + $process = $this->getProcess('sleep 3'); + $process->setTimeout($timeout); + $start = microtime(true); + try { + $process->run(); + $this->fail('A RuntimeException should have been raised'); + } catch (RuntimeException $e) { + + } + $duration = microtime(true) - $start; + + $this->assertLessThan($timeout + Process::TIMEOUT_PRECISION, $duration); + } + + public function testCheckTimeoutOnStartedProcess() + { + $timeout = 0.5; + $precision = 100000; + $process = $this->getProcess('sleep 3'); + $process->setTimeout($timeout); + $start = microtime(true); + + $process->start(); + + try { + while ($process->isRunning()) { + $process->checkTimeout(); + usleep($precision); + } + $this->fail('A RuntimeException should have been raised'); + } catch (RuntimeException $e) { + + } + $duration = microtime(true) - $start; + + $this->assertLessThan($timeout + $precision, $duration); + } + public function responsesCodeProvider() { return array( From bf4a9b083c0df4d797a0fd5489b9cf8cb9901baf Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Sun, 7 Apr 2013 14:38:17 +0200 Subject: [PATCH 11/17] Round stream_select fifth argument up. - This argument must be an integer - An argument equal to 0 should be avoided as it consumes too much CPU time --- src/Symfony/Component/Process/Process.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index a4ee6a760a..56ff6d1ecc 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -290,7 +290,7 @@ class Process $w = $writePipes; $e = null; - $n = @stream_select($r, $w, $e, 0, static::TIMEOUT_PRECISION * 1E6); + $n = @stream_select($r, $w, $e, 0, ceil(static::TIMEOUT_PRECISION * 1E6)); if (false === $n) { break; @@ -360,7 +360,7 @@ class Process $e = null; // let's have a look if something changed in streams - if (false === $n = @stream_select($r, $w, $e, 0, static::TIMEOUT_PRECISION * 1E6)) { + if (false === $n = @stream_select($r, $w, $e, 0, ceil(static::TIMEOUT_PRECISION * 1E6))) { $lastError = error_get_last(); // stream_select returns false when the `select` system call is interrupted by an incoming signal From 783ae3adffea7d12963156c4d9befb5138886c16 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 7 Apr 2013 16:10:23 +0200 Subject: [PATCH 12/17] fixed CS --- src/Symfony/Component/Process/Process.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 56ff6d1ecc..7cbaf700b5 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -35,7 +35,7 @@ class Process const STDERR = 2; // Timeout Precision in seconds. - CONST TIMEOUT_PRECISION = 0.2; + const TIMEOUT_PRECISION = 0.2; private $commandline; private $cwd; @@ -850,9 +850,10 @@ class Process */ public function checkTimeout() { - if (0 < $this->timeout && $this->timeout < (microtime(true) - $this->starttime)) { + if (0 < $this->timeout && $this->timeout < microtime(true) - $this->starttime) { $this->stop(0); - throw new RuntimeException('Process timed-out.'); + + throw new RuntimeException('The process timed-out.'); } } From bec8ff16e8ec01e344811ec93d95ef0703b9ecfa Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Sat, 6 Apr 2013 19:59:02 +0200 Subject: [PATCH 13/17] Fix timeout in Process::stop method - The timeout is ten times more than set. - The timeout does not occurs, it is actually blocking until the process dies. --- src/Symfony/Component/Process/Process.php | 6 ++- .../Process/Tests/AbstractProcessTest.php | 25 +++++++++++++ .../Process/Tests/NonStopableProcess.php | 37 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Process/Tests/NonStopableProcess.php diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index f8a3293b12..7d2535095e 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -591,7 +591,7 @@ class Process */ public function stop($timeout=10) { - $timeoutMicro = (int) $timeout*10E6; + $timeoutMicro = (int) $timeout*1E6; if ($this->isRunning()) { proc_terminate($this->process); $time = 0; @@ -600,6 +600,10 @@ class Process usleep(1000); } + if (!defined('PHP_WINDOWS_VERSION_BUILD') && $this->isRunning()) { + proc_terminate($this->process, SIGKILL); + } + foreach ($this->pipes as $pipe) { fclose($pipe); } diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index 51d51f40b8..7f622d38ac 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -44,6 +44,31 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertNull($p->getTimeout()); } + public function testStopWithTimeoutIsActuallyWorking() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Stop with timeout does not work on windows, it requires posix signals'); + } + if (!function_exists('pcntl_signal')) { + $this->markTestSkipped('This test require pcntl_signal function'); + } + + // exec is mandatory here since we send a signal to the process + // see https://github.com/symfony/symfony/issues/5030 about prepending + // command with exec + $p = $this->getProcess('exec php '.__DIR__.'/NonStopableProcess.php 3'); + $p->start(); + usleep(100000); + $start = microtime(true); + $p->stop(1.1); + while ($p->isRunning()) { + usleep(1000); + } + $duration = microtime(true) - $start; + + $this->assertLessThan(1.3, $duration); + } + /** * tests results from sub processes * diff --git a/src/Symfony/Component/Process/Tests/NonStopableProcess.php b/src/Symfony/Component/Process/Tests/NonStopableProcess.php new file mode 100644 index 0000000000..a4db838256 --- /dev/null +++ b/src/Symfony/Component/Process/Tests/NonStopableProcess.php @@ -0,0 +1,37 @@ + (microtime(true) - $start)) { + usleep(1000); +} From 9d71ebe8e2e809da93ea4555759846c7676d9d08 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 7 Apr 2013 16:34:20 +0200 Subject: [PATCH 14/17] Fix autocompletion of command names when namespaces conflict --- src/Symfony/Component/Console/Application.php | 42 +++++++++---------- .../Console/Tests/ApplicationTest.php | 10 +++++ 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index af80091613..7f7da75858 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -478,20 +478,24 @@ class Application */ public function findNamespace($namespace) { - $allNamespaces = array(); - foreach ($this->getNamespaces() as $n) { - $allNamespaces[$n] = explode(':', $n); - } - - $found = array(); + $allNamespaces = $this->getNamespaces(); + $found = ''; foreach (explode(':', $namespace) as $i => $part) { - $abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $allNamespaces))))); + // select sub-namespaces matching the current namespace we found + $namespaces = array(); + foreach ($allNamespaces as $n) { + if ('' === $found || 0 === strpos($n, $found)) { + $namespaces[$n] = explode(':', $n); + } + } + + $abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $namespaces))))); if (!isset($abbrevs[$part])) { $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); if (1 <= $i) { - $part = implode(':', $found).':'.$part; + $part = $found.':'.$part; } if ($alternatives = $this->findAlternativeNamespace($part, $abbrevs)) { @@ -507,14 +511,19 @@ class Application throw new \InvalidArgumentException($message); } + // there are multiple matches, but $part is an exact match of one of them so we select it + if (in_array($part, $abbrevs[$part])) { + $abbrevs[$part] = array($part); + } + if (count($abbrevs[$part]) > 1) { throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions($abbrevs[$part]))); } - $found[] = $abbrevs[$part][0]; + $found .= $found ? ':' . $abbrevs[$part][0] : $abbrevs[$part][0]; } - return implode(':', $found); + return $found; } /** @@ -637,21 +646,12 @@ class Application { $abbrevs = array(); foreach ($names as $name) { - for ($len = strlen($name) - 1; $len > 0; --$len) { + for ($len = strlen($name); $len > 0; --$len) { $abbrev = substr($name, 0, $len); - if (!isset($abbrevs[$abbrev])) { - $abbrevs[$abbrev] = array($name); - } else { - $abbrevs[$abbrev][] = $name; - } + $abbrevs[$abbrev][] = $name; } } - // Non-abbreviations always get entered, even if they aren't unique - foreach ($names as $name) { - $abbrevs[$name] = array($name); - } - return $abbrevs; } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 7a0a4895cb..bb4e11e6a2 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -342,6 +342,16 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase } } + public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces() + { + $application = $this->getMock('Symfony\Component\Console\Application', array('getNamespaces')); + $application->expects($this->once()) + ->method('getNamespaces') + ->will($this->returnValue(array('foo:sublong', 'bar:sub'))); + + $this->assertEquals('foo:sublong', $application->findNamespace('f:sub')); + } + public function testSetCatchExceptions() { $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth')); From a3826ab4f4f5660c9e26c830f4bb35b5a0d067c7 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Mon, 1 Apr 2013 13:19:43 +0200 Subject: [PATCH 15/17] #7531: [HttpKernel][Config] FileLocator adds NULL as global resource path --- .../HttpKernel/Config/FileLocator.php | 10 +-- .../Tests/Config/FileLocatorTest.php | 61 +++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) mode change 100644 => 100755 src/Symfony/Component/HttpKernel/Config/FileLocator.php create mode 100755 src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php diff --git a/src/Symfony/Component/HttpKernel/Config/FileLocator.php b/src/Symfony/Component/HttpKernel/Config/FileLocator.php old mode 100644 new mode 100755 index d241b9da19..50c7d07a1c --- a/src/Symfony/Component/HttpKernel/Config/FileLocator.php +++ b/src/Symfony/Component/HttpKernel/Config/FileLocator.php @@ -28,14 +28,16 @@ class FileLocator extends BaseFileLocator * Constructor. * * @param KernelInterface $kernel A KernelInterface instance - * @param string $path The path the global resource directory - * @param string|array $paths A path or an array of paths where to look for resources + * @param null|string $path The path the global resource directory + * @param array $paths An array of paths where to look for resources */ public function __construct(KernelInterface $kernel, $path = null, array $paths = array()) { $this->kernel = $kernel; - $this->path = $path; - $paths[] = $path; + if(null !== $path) { + $this->path = $path; + $paths[] = $path; + } parent::__construct($paths); } diff --git a/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php b/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php new file mode 100755 index 0000000000..336a4bcff2 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Tests\Config; + +use Symfony\Component\HttpKernel\Config\FileLocator; +use Symfony\Component\HttpKernel\KernelInterface; + +class FileLocatorTest extends \PHPUnit_Framework_TestCase +{ + + /** @var KernelInterface */ + private $kernel; + + public function setUp() + { + $this->kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + } + + public function tearDown() + { + $this->kernel = null; + } + + public function testLocate() + { + $this->kernel + ->expects($this->atLeastOnce()) + ->method('locateResource') + ->with('@BundleName/some/path', null, true) + ->will($this->returnValue('/bundle-name/some/path')); + $locator = new FileLocator($this->kernel); + $this->assertEquals('/bundle-name/some/path', $locator->locate('@BundleName/some/path')); + + $this->kernel + ->expects($this->never()) + ->method('locateResource'); + $this->setExpectedException('LogicException'); + $locator->locate('/some/path'); + } + + public function testLocateWithGlobalResourcePath() + { + $this->kernel + ->expects($this->atLeastOnce()) + ->method('locateResource') + ->with('@BundleName/some/path', '/global/resource/path', false); + + $locator = new FileLocator($this->kernel, '/global/resource/path'); + $locator->locate('@BundleName/some/path', null, false); + } + +} From 12b7073607cb413a1e4cf7ee9bc7180f09fe96f7 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 7 Apr 2013 17:51:26 +0200 Subject: [PATCH 16/17] [HttpKernel] tweaked previous merge --- .../HttpKernel/Config/FileLocator.php | 2 +- .../Tests/Config/FileLocatorTest.php | 28 +++++-------------- 2 files changed, 8 insertions(+), 22 deletions(-) mode change 100755 => 100644 src/Symfony/Component/HttpKernel/Config/FileLocator.php diff --git a/src/Symfony/Component/HttpKernel/Config/FileLocator.php b/src/Symfony/Component/HttpKernel/Config/FileLocator.php old mode 100755 new mode 100644 index 50c7d07a1c..47b543c15e --- a/src/Symfony/Component/HttpKernel/Config/FileLocator.php +++ b/src/Symfony/Component/HttpKernel/Config/FileLocator.php @@ -34,7 +34,7 @@ class FileLocator extends BaseFileLocator public function __construct(KernelInterface $kernel, $path = null, array $paths = array()) { $this->kernel = $kernel; - if(null !== $path) { + if (null !== $path) { $this->path = $path; $paths[] = $path; } diff --git a/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php b/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php index 336a4bcff2..be59486269 100755 --- a/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php @@ -12,35 +12,21 @@ namespace Symfony\Component\HttpKernel\Tests\Config; use Symfony\Component\HttpKernel\Config\FileLocator; -use Symfony\Component\HttpKernel\KernelInterface; class FileLocatorTest extends \PHPUnit_Framework_TestCase { - - /** @var KernelInterface */ - private $kernel; - - public function setUp() - { - $this->kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); - } - - public function tearDown() - { - $this->kernel = null; - } - public function testLocate() { - $this->kernel + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel ->expects($this->atLeastOnce()) ->method('locateResource') ->with('@BundleName/some/path', null, true) ->will($this->returnValue('/bundle-name/some/path')); - $locator = new FileLocator($this->kernel); + $locator = new FileLocator($kernel); $this->assertEquals('/bundle-name/some/path', $locator->locate('@BundleName/some/path')); - $this->kernel + $kernel ->expects($this->never()) ->method('locateResource'); $this->setExpectedException('LogicException'); @@ -49,13 +35,13 @@ class FileLocatorTest extends \PHPUnit_Framework_TestCase public function testLocateWithGlobalResourcePath() { - $this->kernel + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel ->expects($this->atLeastOnce()) ->method('locateResource') ->with('@BundleName/some/path', '/global/resource/path', false); - $locator = new FileLocator($this->kernel, '/global/resource/path'); + $locator = new FileLocator($kernel, '/global/resource/path'); $locator->locate('@BundleName/some/path', null, false); } - } From 8a9e898c9a98db391f164782a3f5cbc2d5839108 Mon Sep 17 00:00:00 2001 From: Samuel Gordalina Date: Fri, 5 Apr 2013 13:20:23 +0100 Subject: [PATCH 17/17] Fix finding ACLs from ObjectIdentity's with different types --- .../Component/Security/Acl/Dbal/AclProvider.php | 6 +++++- .../Security/Tests/Acl/Dbal/AclProviderTest.php | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php b/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php index 6f47231ed9..822a16017c 100644 --- a/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php +++ b/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php @@ -263,7 +263,11 @@ SELECTCLAUSE; for ($i = 0; $i < $count; $i++) { if (!isset($types[$batch[$i]->getType()])) { $types[$batch[$i]->getType()] = true; - if ($count > 1) { + + // if there is more than one type we can safely break out of the + // loop, because it is the differentiator factor on whether to + // query for only one or more class types + if (count($types) > 1) { break; } } diff --git a/src/Symfony/Component/Security/Tests/Acl/Dbal/AclProviderTest.php b/src/Symfony/Component/Security/Tests/Acl/Dbal/AclProviderTest.php index 83771eef21..ad58d72ab2 100644 --- a/src/Symfony/Component/Security/Tests/Acl/Dbal/AclProviderTest.php +++ b/src/Symfony/Component/Security/Tests/Acl/Dbal/AclProviderTest.php @@ -72,6 +72,23 @@ class AclProviderTest extends \PHPUnit_Framework_TestCase $this->assertTrue($oids[1]->equals($acl1->getObjectIdentity())); } + public function testFindAclsWithDifferentTypes() + { + $oids = array(); + $oids[] = new ObjectIdentity('123', 'Bundle\SomeVendor\MyBundle\Entity\SomeEntity'); + $oids[] = new ObjectIdentity('123', 'Bundle\MyBundle\Entity\AnotherEntity'); + + $provider = $this->getProvider(); + + $acls = $provider->findAcls($oids); + $this->assertInstanceOf('SplObjectStorage', $acls); + $this->assertCount(2, $acls); + $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl0 = $acls->offsetGet($oids[0])); + $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl1 = $acls->offsetGet($oids[1])); + $this->assertTrue($oids[0]->equals($acl0->getObjectIdentity())); + $this->assertTrue($oids[1]->equals($acl1->getObjectIdentity())); + } + public function testFindAclCachesAclInMemory() { $oid = new ObjectIdentity('1', 'foo');