From a80680880b6a80bf23386d8af95503e4adb74ab5 Mon Sep 17 00:00:00 2001 From: webchick <webchick@24967.no-reply.drupal.org> Date: Sat, 8 Dec 2012 15:22:34 -0800 Subject: [PATCH] Issue #1834594 by effulgentsia, Rob Loach: Update dependencies (Symfony and Twig) follow up fixes for Composer. --- core/composer.json | 26 +- core/composer.lock | 233 +++++++-- core/includes/bootstrap.inc | 35 +- core/vendor/autoload.php | 2 +- core/vendor/composer/autoload_namespaces.php | 17 +- core/vendor/composer/autoload_real.php | 6 +- core/vendor/composer/installed.json | 446 ++++++++++++------ .../guzzle/common/Guzzle/Common/composer.json | 2 +- .../Component/HttpFoundation/CHANGELOG.md | 1 + .../Component/HttpFoundation/IpUtils.php | 111 +++++ .../HttpFoundation/RequestMatcher.php | 87 +--- .../HttpFoundation/Tests/IpUtilsTest.php | 71 +++ .../Tests/RequestMatcherTest.php | 73 --- .../DataCollector/LoggerDataCollector.php | 22 +- .../HttpKernel/Debug/ErrorHandler.php | 51 ++ .../HttpKernel/Debug/ExceptionHandler.php | 3 + .../DependencyInjection/Extension.php | 10 +- .../DeprecationLoggerListener.php | 44 ++ .../Exception/FatalErrorException.php | 22 + .../HttpKernel/Exception/FlattenException.php | 36 +- .../DataCollector/LoggerDataCollectorTest.php | 19 +- .../Tests/Debug/ErrorHandlerTest.php | 29 +- .../Tests/Exception/FlattenExceptionTest.php | 4 +- .../Process/Exception/ExceptionInterface.php | 0 .../Exception/ProcessFailedException.php | 0 .../Process/Exception/RuntimeException.php | 0 .../Process/Tests/AbstractProcessTest.php | 300 ++++++++++++ .../Process/Tests/PhpExecutableFinderTest.php | 64 +++ .../Process/Tests/ProcessBuilderTest.php | 108 +++++ .../Tests/ProcessFailedExceptionTest.php | 75 +++ .../Tests/ProcessInSigchildEnvironment.php | 22 + .../Process/Tests/ProcessTestHelper.php | 63 +++ .../Tests/SigchildDisabledProcessTest.php | 99 ++++ .../Tests/SigchildEnabledProcessTest.php | 65 +++ .../Process/Tests/SimpleProcessTest.php | 87 ++++ .../Component/Process/Tests/bootstrap.php | 18 + .../Symfony/Component/Process/composer.json | 7 +- .../Component/Process/phpunit.xml.dist | 28 ++ .../Symfony/Component/Routing/CHANGELOG.md | 33 ++ .../Matcher/Dumper/PhpMatcherDumper.php | 34 +- .../Routing/Matcher/TraceableUrlMatcher.php | 8 - .../Component/Routing/Matcher/UrlMatcher.php | 12 - .../Component/Routing/RouteCollection.php | 185 +++----- .../Matcher/Dumper/PhpMatcherDumperTest.php | 4 +- .../Routing/Tests/RouteCollectionTest.php | 74 +-- 45 files changed, 1998 insertions(+), 638 deletions(-) create mode 100644 core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/IpUtils.php create mode 100644 core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php create mode 100644 core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FatalErrorException.php mode change 100644 => 100755 core/vendor/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.php mode change 100644 => 100755 core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php mode change 100644 => 100755 core/vendor/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessBuilderTest.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTestHelper.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/Tests/bootstrap.php create mode 100644 core/vendor/symfony/process/Symfony/Component/Process/phpunit.xml.dist diff --git a/core/composer.json b/core/composer.json index 1fc8db9199b9..87e60b4647d7 100644 --- a/core/composer.json +++ b/core/composer.json @@ -3,18 +3,18 @@ "description": "Drupal is an open source content management platform powering millions of websites and applications.", "license": "GPL-2.0+", "require": { - "symfony/class-loader": "<2.4@dev", - "symfony/dependency-injection": "<2.4@dev", - "symfony/event-dispatcher": "<2.4@dev", - "symfony/http-foundation": "<2.4@dev", - "symfony/http-kernel": "<2.4@dev", - "symfony/routing": "<2.4@dev", - "symfony/serializer": "<2.4@dev", - "symfony/yaml": "<2.4@dev", - "twig/twig": "1.*", - "doctrine/common": "2.3.*", - "guzzle/http": "3.*", - "kriswallsmith/assetic": "1.1.*" + "symfony/class-loader": "<2.4", + "symfony/dependency-injection": "<2.4", + "symfony/event-dispatcher": "<2.4", + "symfony/http-foundation": "<2.4", + "symfony/http-kernel": "<2.4", + "symfony/routing": "<2.4", + "symfony/serializer": "<2.4", + "symfony/yaml": "<2.4", + "twig/twig": "1.*@stable", + "doctrine/common": "2.3.*@stable", + "guzzle/http": "*", + "kriswallsmith/assetic": "1.1.*@alpha" }, - "minimum-stability": "alpha" + "minimum-stability": "dev" } diff --git a/core/composer.lock b/core/composer.lock index 94dc922f5389..1894ab38cfb0 100644 --- a/core/composer.lock +++ b/core/composer.lock @@ -1,5 +1,5 @@ { - "hash": "1a2c52fedf8d9a23498df41568d82ff4", + "hash": "5d17aee0bd24c24563c2c864600fc5bd", "packages": [ { "name": "doctrine/common", @@ -71,6 +71,182 @@ "persistence" ] }, + { + "name": "guzzle/common", + "version": "dev-master", + "target-dir": "Guzzle/Common", + "source": { + "type": "git", + "url": "git://github.com/guzzle/common.git", + "reference": "23162d56daa85b1ee6f1d73d9b5a5ecda2d70849" + }, + "dist": { + "type": "zip", + "url": "https://github.com/guzzle/common/archive/23162d56daa85b1ee6f1d73d9b5a5ecda2d70849.zip", + "reference": "23162d56daa85b1ee6f1d73d9b5a5ecda2d70849", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" + }, + "time": "2012-12-06 02:26:39", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-0": { + "Guzzle\\Common": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Common libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "event", + "exception", + "common", + "collection" + ] + }, + { + "name": "guzzle/http", + "version": "dev-master", + "target-dir": "Guzzle/Http", + "source": { + "type": "git", + "url": "git://github.com/guzzle/http.git", + "reference": "v3.0.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/guzzle/http/archive/v3.0.5.zip", + "reference": "v3.0.5", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "guzzle/common": "self.version", + "guzzle/parser": "self.version", + "guzzle/stream": "self.version" + }, + "time": "2012-11-18 05:28:55", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-0": { + "Guzzle\\Http": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "HTTP libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "curl", + "http", + "http client", + "client", + "Guzzle" + ] + }, + { + "name": "guzzle/parser", + "version": "dev-master", + "target-dir": "Guzzle/Parser", + "source": { + "type": "git", + "url": "git://github.com/guzzle/parser.git", + "reference": "v3.0.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/guzzle/parser/archive/v3.0.5.zip", + "reference": "v3.0.5", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "time": "2012-11-19 00:07:13", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-0": { + "Guzzle\\Parser": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Interchangeable parsers used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "http", + "url", + "message", + "cookie", + "URI Template" + ] + }, + { + "name": "guzzle/stream", + "version": "dev-master", + "target-dir": "Guzzle/Stream", + "source": { + "type": "git", + "url": "https://github.com/guzzle/stream", + "reference": "v3.0.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/guzzle/stream/archive/v3.0.5.zip", + "reference": "v3.0.5", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "guzzle/common": "self.version" + }, + "time": "2012-11-11 23:54:57", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-0": { + "Guzzle\\Stream": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle stream wrapper component", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "stream", + "Guzzle", + "component" + ] + }, { "name": "kriswallsmith/assetic", "version": "v1.1.0-alpha1", @@ -114,6 +290,7 @@ "Assetic": "src/" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -301,18 +478,18 @@ "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation", - "reference": "c209d2d5b6c99121d4f3144a41e449200f4c1477" + "reference": "067c310fe4d0691a24adc97f39500233a58e42cb" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/HttpFoundation/archive/c209d2d5b6c99121d4f3144a41e449200f4c1477.zip", - "reference": "c209d2d5b6c99121d4f3144a41e449200f4c1477", + "url": "https://github.com/symfony/HttpFoundation/archive/067c310fe4d0691a24adc97f39500233a58e42cb.zip", + "reference": "067c310fe4d0691a24adc97f39500233a58e42cb", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-12-03 13:31:00", + "time": "2012-12-06 15:23:16", "type": "library", "extra": { "branch-alias": { @@ -352,12 +529,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel", - "reference": "b8d175c14bdf4eb9771690eae9718673dcca8408" + "reference": "dbd6b331aab91deb9e97307eac666b77a0879e07" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/HttpKernel/archive/b8d175c14bdf4eb9771690eae9718673dcca8408.zip", - "reference": "b8d175c14bdf4eb9771690eae9718673dcca8408", + "url": "https://github.com/symfony/HttpKernel/archive/dbd6b331aab91deb9e97307eac666b77a0879e07.zip", + "reference": "dbd6b331aab91deb9e97307eac666b77a0879e07", "shasum": "" }, "require": { @@ -384,7 +561,7 @@ "symfony/dependency-injection": "2.2.*", "symfony/finder": "2.2.*" }, - "time": "2012-11-24 12:13:43", + "time": "2012-12-06 13:04:11", "type": "library", "extra": { "branch-alias": { @@ -416,30 +593,25 @@ }, { "name": "symfony/process", - "version": "v2.1.4", + "version": "2.1.x-dev", "target-dir": "Symfony/Component/Process", "source": { "type": "git", "url": "https://github.com/symfony/Process", - "reference": "v2.1.4" + "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Process/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://github.com/symfony/Process/archive/058ae5038a9623fa64b120a2d10ba81f1ade05c7.zip", + "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-11-19 20:53:52", + "time": "2012-12-06 10:00:55", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", + "installation-source": "source", "autoload": { "psr-0": { "Symfony\\Component\\Process": "" @@ -469,12 +641,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Routing", - "reference": "de5f6ded706bf50922c89864693c60793d21e935" + "reference": "17109bfef57e52b35d76db4d35b3b66b1d176701" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Routing/archive/de5f6ded706bf50922c89864693c60793d21e935.zip", - "reference": "de5f6ded706bf50922c89864693c60793d21e935", + "url": "https://github.com/symfony/Routing/archive/17109bfef57e52b35d76db4d35b3b66b1d176701.zip", + "reference": "17109bfef57e52b35d76db4d35b3b66b1d176701", "shasum": "" }, "require": { @@ -491,7 +663,7 @@ "symfony/config": "2.2.*", "symfony/yaml": "2.2.*" }, - "time": "2012-12-03 22:11:37", + "time": "2012-12-05 15:37:03", "type": "library", "extra": { "branch-alias": { @@ -672,15 +844,10 @@ "aliases": [ ], - "minimum-stability": "alpha", + "minimum-stability": "dev", "stability-flags": { - "symfony/class-loader": 20, - "symfony/dependency-injection": 20, - "symfony/event-dispatcher": 20, - "symfony/http-foundation": 20, - "symfony/http-kernel": 20, - "symfony/routing": 20, - "symfony/serializer": 20, - "symfony/yaml": 20 + "twig/twig": 0, + "doctrine/common": 0, + "kriswallsmith/assetic": 15 } } diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 77560459b28d..4ebe881ced72 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -3096,18 +3096,31 @@ function drupal_classloader() { 'Drupal\Component' => DRUPAL_ROOT . '/core/lib', )); - // Register namespaces for vendor libraries managed by Composer. - $namespaces = require DRUPAL_ROOT . '/core/vendor/composer/autoload_namespaces.php'; + // Register namespaces and PEAR-like prefixes for vendor libraries managed + // by Composer. Composer combines libraries that use PHP 5.3 namespaces and + // ones that use PEAR-like class prefixes in a single array, but the Symfony + // class loader requires them to be registered separately. + $prefixes_and_namespaces = require DRUPAL_ROOT . '/core/vendor/composer/autoload_namespaces.php'; $prefixes = array(); - foreach ($namespaces as $namespace => $path) { - // Composer combines libraries that use PHP 5.3 namespaces and ones that - // use PEAR-style class prefixes in a single array, but the Symfony class - // loader requires them to be registered separately. PSR-0 disallows - // underscores in namespace names and requires at least one in a - // PEAR-style class prefix. - if (strpos($namespace, '_') !== FALSE) { - $prefixes[$namespace] = $path; - unset($namespaces[$namespace]); + $namespaces = array(); + foreach ($prefixes_and_namespaces as $key => $path) { + // If the key: + // - Contains a namespace separator, we know it's a namespace. + // - Doesn't contain a namespace separator and ends in an "_" (e.g., + // "Twig_"), it's likely intended as a PEAR-like prefix rather than a + // namespace. + // - Doesn't contain a namespace separator or end in an "_" (e.g., + // "Assetic"), then it could be either a namespace or an incomplete + // PEAR-like prefix, but we assume the former, since the only example of + // that currently in Drupal is Assetic. + // @todo Switch to a class loader that doesn't require this guessing: + // http://drupal.org/node/1658720. + $is_namespace = (strpos($key, '\\') !== FALSE) && (substr($key, -1) !== '_'); + if ($is_namespace) { + $namespaces[rtrim($key, '\\')] = $path; + } + else { + $prefixes[$key] = $path; } } $loader->registerPrefixes($prefixes); diff --git a/core/vendor/autoload.php b/core/vendor/autoload.php index 9cf42c1e7254..daa7ee7447bc 100644 --- a/core/vendor/autoload.php +++ b/core/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInitac017267abab05dbc458e3a320f5ad98::getLoader(); +return ComposerAutoloaderInit295209ab8f7c3b45c210d28fa6db3592::getLoader(); diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php index e21abde93b9d..907240136d62 100644 --- a/core/vendor/composer/autoload_namespaces.php +++ b/core/vendor/composer/autoload_namespaces.php @@ -7,16 +7,15 @@ return array( 'Twig_' => $vendorDir . '/twig/twig/lib/', - 'Symfony\\Component\\Yaml' => $vendorDir . '/symfony/yaml/', - 'Symfony\\Component\\Serializer' => $vendorDir . '/symfony/serializer/', - 'Symfony\\Component\\Routing' => $vendorDir . '/symfony/routing/', + 'Symfony\\Component\\Yaml\\' => $vendorDir . '/symfony/yaml/', + 'Symfony\\Component\\Serializer\\' => $vendorDir . '/symfony/serializer/', + 'Symfony\\Component\\Routing\\' => $vendorDir . '/symfony/routing/', 'Symfony\\Component\\Process' => $vendorDir . '/symfony/process/', - 'Symfony\\Component\\HttpKernel' => $vendorDir . '/symfony/http-kernel/', - 'Symfony\\Component\\HttpFoundation' => $vendorDir . '/symfony/http-foundation/', - 'Symfony\\Component\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/', - 'Symfony\\Component\\DependencyInjection' => $vendorDir . '/symfony/dependency-injection/', - 'Symfony\\Component\\ClassLoader' => $vendorDir . '/symfony/class-loader/', - 'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs', + 'Symfony\\Component\\HttpKernel\\' => $vendorDir . '/symfony/http-kernel/', + 'Symfony\\Component\\HttpFoundation\\' => $vendorDir . '/symfony/http-foundation/', + 'Symfony\\Component\\EventDispatcher\\' => $vendorDir . '/symfony/event-dispatcher/', + 'Symfony\\Component\\DependencyInjection\\' => $vendorDir . '/symfony/dependency-injection/', + 'Symfony\\Component\\ClassLoader\\' => $vendorDir . '/symfony/class-loader/', 'Guzzle\\Stream' => $vendorDir . '/guzzle/stream/', 'Guzzle\\Parser' => $vendorDir . '/guzzle/parser/', 'Guzzle\\Http' => $vendorDir . '/guzzle/http/', diff --git a/core/vendor/composer/autoload_real.php b/core/vendor/composer/autoload_real.php index 72e789fcef24..dbe463c780bc 100644 --- a/core/vendor/composer/autoload_real.php +++ b/core/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php generated by Composer -class ComposerAutoloaderInitac017267abab05dbc458e3a320f5ad98 +class ComposerAutoloaderInit295209ab8f7c3b45c210d28fa6db3592 { private static $loader; @@ -19,9 +19,9 @@ public static function getLoader() return static::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitac017267abab05dbc458e3a320f5ad98', 'loadClassLoader')); + spl_autoload_register(array('ComposerAutoloaderInit295209ab8f7c3b45c210d28fa6db3592', 'loadClassLoader')); static::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitac017267abab05dbc458e3a320f5ad98', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit295209ab8f7c3b45c210d28fa6db3592', 'loadClassLoader')); $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json index 620f56b9882f..aaa926b36ccb 100644 --- a/core/vendor/composer/installed.json +++ b/core/vendor/composer/installed.json @@ -1,4 +1,170 @@ [ + { + "name": "doctrine/common", + "version": "2.3.0", + "version_normalized": "2.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common", + "reference": "2.3.0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/doctrine/common/zipball/2.3.0", + "reference": "2.3.0", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "time": "2012-09-19 22:55:18", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com", + "homepage": "http://www.jwage.com/" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com", + "homepage": "http://www.instaclick.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "http://jmsyst.com", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "collections", + "spl", + "eventmanager", + "annotations", + "persistence" + ] + }, + { + "name": "twig/twig", + "version": "v1.11.1", + "version_normalized": "1.11.1.0", + "source": { + "type": "git", + "url": "git://github.com/fabpot/Twig.git", + "reference": "v1.11.1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/fabpot/Twig/archive/v1.11.1.zip", + "reference": "v1.11.1", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "time": "2012-11-11 17:17:59", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ] + }, + { + "name": "symfony/process", + "version": "2.1.x-dev", + "version_normalized": "2.1.9999999.9999999-dev", + "target-dir": "Symfony/Component/Process", + "source": { + "type": "git", + "url": "https://github.com/symfony/Process", + "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7" + }, + "dist": { + "type": "zip", + "url": "https://github.com/symfony/Process/archive/058ae5038a9623fa64b120a2d10ba81f1ade05c7.zip", + "reference": "058ae5038a9623fa64b120a2d10ba81f1ade05c7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2012-12-06 10:00:55", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-0": { + "Symfony\\Component\\Process": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "http://symfony.com" + }, { "name": "kriswallsmith/assetic", "version": "v1.1.0-alpha1", @@ -43,6 +209,7 @@ "Assetic": "src/" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -171,32 +338,25 @@ "homepage": "http://symfony.com" }, { - "name": "symfony/event-dispatcher", + "name": "symfony/http-foundation", "version": "dev-master", "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/EventDispatcher", + "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", - "url": "https://github.com/symfony/EventDispatcher", - "reference": "eb290a447c0af5bea0d3de5d95d498afd8c82f89" + "url": "https://github.com/symfony/HttpFoundation", + "reference": "067c310fe4d0691a24adc97f39500233a58e42cb" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/EventDispatcher/archive/eb290a447c0af5bea0d3de5d95d498afd8c82f89.zip", - "reference": "eb290a447c0af5bea0d3de5d95d498afd8c82f89", + "url": "https://github.com/symfony/HttpFoundation/archive/067c310fe4d0691a24adc97f39500233a58e42cb.zip", + "reference": "067c310fe4d0691a24adc97f39500233a58e42cb", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "require-dev": { - "symfony/dependency-injection": "2.2.*" - }, - "suggest": { - "symfony/dependency-injection": "2.2.*", - "symfony/http-kernel": "2.2.*" - }, - "time": "2012-11-13 14:08:04", + "time": "2012-12-06 15:23:16", "type": "library", "extra": { "branch-alias": { @@ -206,8 +366,11 @@ "installation-source": "source", "autoload": { "psr-0": { - "Symfony\\Component\\EventDispatcher\\": "" - } + "Symfony\\Component\\HttpFoundation\\": "" + }, + "classmap": [ + "Symfony/Component/HttpFoundation/Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -223,29 +386,36 @@ "homepage": "http://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Symfony HttpFoundation Component", "homepage": "http://symfony.com" }, { - "name": "symfony/http-foundation", + "name": "symfony/event-dispatcher", "version": "dev-master", "version_normalized": "9999999-dev", - "target-dir": "Symfony/Component/HttpFoundation", + "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", - "url": "https://github.com/symfony/HttpFoundation", - "reference": "c209d2d5b6c99121d4f3144a41e449200f4c1477" + "url": "https://github.com/symfony/EventDispatcher", + "reference": "eb290a447c0af5bea0d3de5d95d498afd8c82f89" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/HttpFoundation/archive/c209d2d5b6c99121d4f3144a41e449200f4c1477.zip", - "reference": "c209d2d5b6c99121d4f3144a41e449200f4c1477", + "url": "https://github.com/symfony/EventDispatcher/archive/eb290a447c0af5bea0d3de5d95d498afd8c82f89.zip", + "reference": "eb290a447c0af5bea0d3de5d95d498afd8c82f89", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-12-03 13:31:00", + "require-dev": { + "symfony/dependency-injection": "2.2.*" + }, + "suggest": { + "symfony/dependency-injection": "2.2.*", + "symfony/http-kernel": "2.2.*" + }, + "time": "2012-11-13 14:08:04", "type": "library", "extra": { "branch-alias": { @@ -255,11 +425,8 @@ "installation-source": "source", "autoload": { "psr-0": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Symfony/Component/HttpFoundation/Resources/stubs" - ] + "Symfony\\Component\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -275,7 +442,7 @@ "homepage": "http://symfony.com/contributors" } ], - "description": "Symfony HttpFoundation Component", + "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com" }, { @@ -286,12 +453,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel", - "reference": "b8d175c14bdf4eb9771690eae9718673dcca8408" + "reference": "dbd6b331aab91deb9e97307eac666b77a0879e07" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/HttpKernel/archive/b8d175c14bdf4eb9771690eae9718673dcca8408.zip", - "reference": "b8d175c14bdf4eb9771690eae9718673dcca8408", + "url": "https://github.com/symfony/HttpKernel/archive/dbd6b331aab91deb9e97307eac666b77a0879e07.zip", + "reference": "dbd6b331aab91deb9e97307eac666b77a0879e07", "shasum": "" }, "require": { @@ -318,7 +485,7 @@ "symfony/dependency-injection": "2.2.*", "symfony/finder": "2.2.*" }, - "time": "2012-11-24 12:13:43", + "time": "2012-12-06 13:04:11", "type": "library", "extra": { "branch-alias": { @@ -356,12 +523,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Routing", - "reference": "de5f6ded706bf50922c89864693c60793d21e935" + "reference": "17109bfef57e52b35d76db4d35b3b66b1d176701" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Routing/archive/de5f6ded706bf50922c89864693c60793d21e935.zip", - "reference": "de5f6ded706bf50922c89864693c60793d21e935", + "url": "https://github.com/symfony/Routing/archive/17109bfef57e52b35d76db4d35b3b66b1d176701.zip", + "reference": "17109bfef57e52b35d76db4d35b3b66b1d176701", "shasum": "" }, "require": { @@ -378,7 +545,7 @@ "symfony/config": "2.2.*", "symfony/yaml": "2.2.*" }, - "time": "2012-12-03 22:11:37", + "time": "2012-12-05 15:37:03", "type": "library", "extra": { "branch-alias": { @@ -507,157 +674,162 @@ "homepage": "http://symfony.com" }, { - "name": "twig/twig", - "version": "v1.11.1", - "version_normalized": "1.11.1.0", + "name": "guzzle/common", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Guzzle/Common", "source": { "type": "git", - "url": "git://github.com/fabpot/Twig.git", - "reference": "v1.11.1" + "url": "git://github.com/guzzle/common.git", + "reference": "23162d56daa85b1ee6f1d73d9b5a5ecda2d70849" }, "dist": { "type": "zip", - "url": "https://github.com/fabpot/Twig/archive/v1.11.1.zip", - "reference": "v1.11.1", + "url": "https://github.com/guzzle/common/archive/23162d56daa85b1ee6f1d73d9b5a5ecda2d70849.zip", + "reference": "23162d56daa85b1ee6f1d73d9b5a5ecda2d70849", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" }, - "time": "2012-11-11 17:17:59", + "time": "2012-12-06 02:26:39", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11-dev" + "installation-source": "source", + "autoload": { + "psr-0": { + "Guzzle\\Common": "" } }, - "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Common libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "event", + "exception", + "common", + "collection" + ] + }, + { + "name": "guzzle/stream", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Guzzle/Stream", + "source": { + "type": "git", + "url": "https://github.com/guzzle/stream", + "reference": "v3.0.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/guzzle/stream/archive/v3.0.5.zip", + "reference": "v3.0.5", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "guzzle/common": "self.version" + }, + "time": "2012-11-11 23:54:57", + "type": "library", + "installation-source": "source", "autoload": { "psr-0": { - "Twig_": "lib/" + "Guzzle\\Stream": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3" + "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", + "description": "Guzzle stream wrapper component", + "homepage": "http://guzzlephp.org/", "keywords": [ - "templating" + "stream", + "Guzzle", + "component" ] }, { - "name": "doctrine/common", - "version": "2.3.0", - "version_normalized": "2.3.0.0", + "name": "guzzle/parser", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Guzzle/Parser", "source": { "type": "git", - "url": "https://github.com/doctrine/common", - "reference": "2.3.0" + "url": "git://github.com/guzzle/parser.git", + "reference": "v3.0.5" }, "dist": { "type": "zip", - "url": "https://github.com/doctrine/common/zipball/2.3.0", - "reference": "2.3.0", + "url": "https://github.com/guzzle/parser/archive/v3.0.5.zip", + "reference": "v3.0.5", "shasum": "" }, "require": { "php": ">=5.3.2" }, - "time": "2012-09-19 22:55:18", + "time": "2012-11-19 00:07:13", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "installation-source": "dist", + "installation-source": "source", "autoload": { "psr-0": { - "Doctrine\\Common": "lib/" + "Guzzle\\Parser": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Common Library for Doctrine projects", - "homepage": "http://www.doctrine-project.org", + "description": "Interchangeable parsers used by Guzzle", + "homepage": "http://guzzlephp.org/", "keywords": [ - "collections", - "spl", - "eventmanager", - "annotations", - "persistence" + "http", + "url", + "message", + "cookie", + "URI Template" ] }, { - "name": "symfony/process", - "version": "v2.1.4", - "version_normalized": "2.1.4.0", - "target-dir": "Symfony/Component/Process", + "name": "guzzle/http", + "version": "dev-master", + "version_normalized": "9999999-dev", + "target-dir": "Guzzle/Http", "source": { "type": "git", - "url": "https://github.com/symfony/Process", - "reference": "v2.1.4" + "url": "git://github.com/guzzle/http.git", + "reference": "v3.0.5" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Process/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://github.com/guzzle/http/archive/v3.0.5.zip", + "reference": "v3.0.5", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.2", + "guzzle/common": "self.version", + "guzzle/parser": "self.version", + "guzzle/stream": "self.version" }, - "time": "2012-11-19 20:53:52", + "time": "2012-11-18 05:28:55", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", + "installation-source": "source", "autoload": { "psr-0": { - "Symfony\\Component\\Process": "" + "Guzzle\\Http": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -666,15 +838,19 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } ], - "description": "Symfony Process Component", - "homepage": "http://symfony.com" + "description": "HTTP libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "curl", + "http", + "http client", + "client", + "Guzzle" + ] } ] diff --git a/core/vendor/guzzle/common/Guzzle/Common/composer.json b/core/vendor/guzzle/common/Guzzle/Common/composer.json index 5f379c24276f..62431ccd9727 100644 --- a/core/vendor/guzzle/common/Guzzle/Common/composer.json +++ b/core/vendor/guzzle/common/Guzzle/Common/composer.json @@ -6,7 +6,7 @@ "license": "MIT", "require": { "php": ">=5.3.2", - "symfony/event-dispatcher": "2.1.*" + "symfony/event-dispatcher": ">=2.1" }, "autoload": { "psr-0": { "Guzzle\\Common": "" } diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md index 4b7d0c64ace5..13ed8dd7c96c 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 2.2.0 ----- + * added a IpUtils class to check if an IP belongs to a CIDR * added Request::getRealMethod() to get the "real" HTTP method (getMethod() returns the "intended" HTTP method) * disabled _method request parameter support by default (call Request::enableHttpMethodParameterOverride() to enable it) * Request::splitHttpAcceptHeader() method is deprecated and will be removed in 2.3 diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/IpUtils.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/IpUtils.php new file mode 100644 index 000000000000..2e3e1aa74635 --- /dev/null +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/IpUtils.php @@ -0,0 +1,111 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation; + +/** + * Http utility functions. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class IpUtils +{ + /** + * This class should not be instantiated + */ + private function __construct() {} + + /** + * Validates an IPv4 or IPv6 address. + * + * @param string $requestIp + * @param string $ip + * + * @return boolean Whether the IP is valid + */ + public static function checkIp($requestIp, $ip) + { + if (false !== strpos($requestIp, ':')) { + return self::checkIp6($requestIp, $ip); + } + + return self::checkIp4($requestIp, $ip); + } + + /** + * Validates an IPv4 address. + * + * @param string $requestIp + * @param string $ip + * + * @return boolean Whether the IP is valid + */ + public static function checkIp4($requestIp, $ip) + { + if (false !== strpos($ip, '/')) { + list($address, $netmask) = explode('/', $ip, 2); + + if ($netmask < 1 || $netmask > 32) { + return false; + } + } else { + $address = $ip; + $netmask = 32; + } + + return 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask); + } + + /** + * Validates an IPv6 address. + * + * @author David Soria Parra <dsp at php dot net> + * @see https://github.com/dsp/v6tools + * + * @param string $requestIp + * @param string $ip + * + * @return boolean Whether the IP is valid + * + * @throws \RuntimeException When IPV6 support is not enabled + */ + public static function checkIp6($requestIp, $ip) + { + if (!((extension_loaded('sockets') && defined('AF_INET6')) || @inet_pton('::1'))) { + throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".'); + } + + if (false !== strpos($ip, '/')) { + list($address, $netmask) = explode('/', $ip, 2); + + if ($netmask < 1 || $netmask > 128) { + return false; + } + } else { + $address = $ip; + $netmask = 128; + } + + $bytesAddr = unpack("n*", inet_pton($address)); + $bytesTest = unpack("n*", inet_pton($requestIp)); + + for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; $i++) { + $left = $netmask - 16 * ($i-1); + $left = ($left <= 16) ? $left : 16; + $mask = ~(0xffff >> $left) & 0xffff; + if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) { + return false; + } + } + + return true; + } +} diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcher.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcher.php index 7371d17242ba..536cc7b075f5 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcher.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RequestMatcher.php @@ -143,96 +143,11 @@ public function matches(Request $request) return false; } - if (null !== $this->ip && !$this->checkIp($request->getClientIp(), $this->ip)) { + if (null !== $this->ip && !IpUtils::checkIp($request->getClientIp(), $this->ip)) { return false; } return true; } - - /** - * Validates an IP address. - * - * @param string $requestIp - * @param string $ip - * - * @return boolean True valid, false if not. - */ - protected function checkIp($requestIp, $ip) - { - // IPv6 address - if (false !== strpos($requestIp, ':')) { - return $this->checkIp6($requestIp, $ip); - } else { - return $this->checkIp4($requestIp, $ip); - } - } - - /** - * Validates an IPv4 address. - * - * @param string $requestIp - * @param string $ip - * - * @return boolean True valid, false if not. - */ - protected function checkIp4($requestIp, $ip) - { - if (false !== strpos($ip, '/')) { - list($address, $netmask) = explode('/', $ip, 2); - - if ($netmask < 1 || $netmask > 32) { - return false; - } - } else { - $address = $ip; - $netmask = 32; - } - - return 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask); - } - - /** - * Validates an IPv6 address. - * - * @author David Soria Parra <dsp at php dot net> - * @see https://github.com/dsp/v6tools - * - * @param string $requestIp - * @param string $ip - * - * @return boolean True valid, false if not. - */ - protected function checkIp6($requestIp, $ip) - { - if (!((extension_loaded('sockets') && defined('AF_INET6')) || @inet_pton('::1'))) { - throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".'); - } - - if (false !== strpos($ip, '/')) { - list($address, $netmask) = explode('/', $ip, 2); - - if ($netmask < 1 || $netmask > 128) { - return false; - } - } else { - $address = $ip; - $netmask = 128; - } - - $bytesAddr = unpack("n*", inet_pton($address)); - $bytesTest = unpack("n*", inet_pton($requestIp)); - - for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; $i++) { - $left = $netmask - 16 * ($i-1); - $left = ($left <= 16) ? $left : 16; - $mask = ~(0xffff >> $left) & 0xffff; - if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) { - return false; - } - } - - return true; - } } diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php new file mode 100644 index 000000000000..5b94bd2bd01a --- /dev/null +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php @@ -0,0 +1,71 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Tests; + +use Symfony\Component\HttpFoundation\IpUtils; + +class IpUtilsTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider testIpv4Provider + */ + public function testIpv4($matches, $remoteAddr, $cidr) + { + $this->assertSame($matches, IpUtils::checkIp($remoteAddr, $cidr)); + } + + public function testIpv4Provider() + { + return array( + array(true, '192.168.1.1', '192.168.1.1'), + array(true, '192.168.1.1', '192.168.1.1/1'), + array(true, '192.168.1.1', '192.168.1.0/24'), + array(false, '192.168.1.1', '1.2.3.4/1'), + array(false, '192.168.1.1', '192.168.1/33'), + ); + } + + /** + * @dataProvider testIpv6Provider + */ + public function testIpv6($matches, $remoteAddr, $cidr) + { + if (!defined('AF_INET6')) { + $this->markTestSkipped('Only works when PHP is compiled without the option "disable-ipv6".'); + } + + $this->assertSame($matches, IpUtils::checkIp($remoteAddr, $cidr)); + } + + public function testIpv6Provider() + { + return array( + array(true, '2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'), + array(false, '2a00:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'), + array(false, '2a01:198:603:0:396e:4789:8e99:890f', '::1'), + array(true, '0:0:0:0:0:0:0:1', '::1'), + array(false, '0:0:603:0:396e:4789:8e99:0001', '::1'), + ); + } + + /** + * @expectedException \RuntimeException + */ + public function testAnIpv6WithOptionDisabledIpv6() + { + if (defined('AF_INET6')) { + $this->markTestSkipped('Only works when PHP is compiled with the option "disable-ipv6".'); + } + + IpUtils::checkIp('2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'); + } +} diff --git a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestMatcherTest.php b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestMatcherTest.php index 0e7b9eff662b..0e1a0f5caf36 100644 --- a/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestMatcherTest.php +++ b/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/RequestMatcherTest.php @@ -16,78 +16,6 @@ class RequestMatcherTest extends \PHPUnit_Framework_TestCase { - /** - * @dataProvider testIpv4Provider - */ - public function testIpv4($matches, $remoteAddr, $cidr) - { - $request = Request::create('', 'get', array(), array(), array(), array('REMOTE_ADDR' => $remoteAddr)); - - $matcher = new RequestMatcher(); - $matcher->matchIp($cidr); - - $this->assertEquals($matches, $matcher->matches($request)); - } - - public function testIpv4Provider() - { - return array( - array(true, '192.168.1.1', '192.168.1.1'), - array(true, '192.168.1.1', '192.168.1.1/1'), - array(true, '192.168.1.1', '192.168.1.0/24'), - array(false, '192.168.1.1', '1.2.3.4/1'), - array(false, '192.168.1.1', '192.168.1/33'), - ); - } - - /** - * @dataProvider testIpv6Provider - */ - public function testIpv6($matches, $remoteAddr, $cidr) - { - if (!defined('AF_INET6')) { - $this->markTestSkipped('Only works when PHP is compiled without the option "disable-ipv6".'); - } - - $request = Request::create('', 'get', array(), array(), array(), array('REMOTE_ADDR' => $remoteAddr)); - - $matcher = new RequestMatcher(); - $matcher->matchIp($cidr); - - $this->assertEquals($matches, $matcher->matches($request)); - } - - public function testIpv6Provider() - { - return array( - array(true, '2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'), - array(false, '2a00:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'), - array(false, '2a01:198:603:0:396e:4789:8e99:890f', '::1'), - array(true, '0:0:0:0:0:0:0:1', '::1'), - array(false, '0:0:603:0:396e:4789:8e99:0001', '::1'), - ); - } - - public function testAnIpv6WithOptionDisabledIpv6() - { - if (defined('AF_INET6')) { - $this->markTestSkipped('Only works when PHP is compiled with the option "disable-ipv6".'); - } - - $request = Request::create('', 'get', array(), array(), array(), array('REMOTE_ADDR' => '2a01:198:603:0:396e:4789:8e99:890f')); - - $matcher = new RequestMatcher(); - $matcher->matchIp('2a01:198:603:0::/65'); - - try { - $matcher->matches($request); - - $this->fail('An expected RuntimeException has not been raised.'); - } catch (\Exception $e) { - $this->assertInstanceOf('\RuntimeException', $e); - } - } - /** * @dataProvider testMethodFixtures */ @@ -200,4 +128,3 @@ public function testAttributes() $this->assertFalse($matcher->matches($request)); } } - diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php index 97f716530337..629b451f70db 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php @@ -38,8 +38,9 @@ public function collect(Request $request, Response $response, \Exception $except { if (null !== $this->logger) { $this->data = array( - 'error_count' => $this->logger->countErrors(), - 'logs' => $this->sanitizeLogs($this->logger->getLogs()), + 'error_count' => $this->logger->countErrors(), + 'logs' => $this->sanitizeLogs($this->logger->getLogs()), + 'deprecation_count' => $this->computeDeprecationCount() ); } } @@ -66,6 +67,11 @@ public function getLogs() return isset($this->data['logs']) ? $this->data['logs'] : array(); } + public function countDeprecations() + { + return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0; + } + /** * {@inheritdoc} */ @@ -103,4 +109,16 @@ private function sanitizeContext($context) return $context; } + + private function computeDeprecationCount() + { + $count = 0; + foreach ($this->logger->getLogs() as $log) { + if (isset($log['context']['type']) && 'deprecation' === $log['context']['type']) { + $count++; + } + } + + return $count; + } } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php index 605c08626ce0..f81ea58bf737 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php @@ -11,6 +11,9 @@ namespace Symfony\Component\HttpKernel\Debug; +use Symfony\Component\HttpKernel\Exception\FatalErrorException; +use Symfony\Component\HttpKernel\Log\LoggerInterface; + /** * ErrorHandler. * @@ -28,10 +31,19 @@ class ErrorHandler E_RECOVERABLE_ERROR => 'Catchable Fatal Error', E_DEPRECATED => 'Deprecated', E_USER_DEPRECATED => 'User Deprecated', + E_ERROR => 'Error', + E_CORE_ERROR => 'Core Error', + E_COMPILE_ERROR => 'Compile Error', + E_PARSE => 'Parse', ); private $level; + private $reservedMemory; + + /** @var LoggerInterface */ + private static $logger; + /** * Register the error handler. * @@ -45,6 +57,8 @@ public static function register($level = null) $handler->setLevel($level); set_error_handler(array($handler, 'handle')); + register_shutdown_function(array($handler, 'handleFatal')); + $handler->reservedMemory = str_repeat('x', 10240); return $handler; } @@ -54,6 +68,11 @@ public function setLevel($level) $this->level = null === $level ? error_reporting() : $level; } + public static function setLogger(LoggerInterface $logger) + { + self::$logger = $logger; + } + /** * @throws \ErrorException When error_reporting returns error */ @@ -63,10 +82,42 @@ public function handle($level, $message, $file, $line, $context) return false; } + if ($level & E_USER_DEPRECATED || $level & E_DEPRECATED) { + if (null !== self::$logger) { + self::$logger->warn($message, array('type' => 'deprecation', 'file' => $file, 'line' => $line)); + } + + return true; + } + if (error_reporting() & $level && $this->level & $level) { throw new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line), 0, $level, $file, $line); } return false; } + + public function handleFatal() + { + if (null === $error = error_get_last()) { + return; + } + + unset($this->reservedMemory); + $type = $error['type']; + if (0 === $this->level || !in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE))) { + return; + } + + // get current exception handler + $exceptionHandler = set_exception_handler(function() {}); + restore_exception_handler(); + + if (is_array($exceptionHandler) && $exceptionHandler[0] instanceof ExceptionHandler) { + $level = isset($this->levels[$type]) ? $this->levels[$type] : $type; + $message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']); + $exception = new FatalErrorException($message, 0, $type, $error['file'], $error['line']); + $exceptionHandler[0]->handle($exception); + } + } } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php index 88ef3d7615fc..79d7d66dcca1 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php @@ -234,6 +234,9 @@ private function decorate($content, $css) img { border: 0; } #sf-resetcontent { width:970px; margin:0 auto; } $css + .xdebug-error { + display: none; + } </style> </head> <body> diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.php index 5c8d5e69ad2a..e03ed88b50e6 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.php @@ -12,6 +12,7 @@ namespace Symfony\Component\HttpKernel\DependencyInjection; use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; @@ -84,6 +85,8 @@ public function getNamespace() * This can be overridden in a sub-class to specify the alias manually. * * @return string The alias + * + * @throws \BadMethodCallException When the extension name does not follow conventions */ public function getAlias() { @@ -96,11 +99,11 @@ public function getAlias() return Container::underscore($classBaseName); } - final protected function processConfiguration(ConfigurationInterface $configuration, array $configs) + final protected function processConfiguration(ConfigurationInterface $configuration, array $configs, $normalizeKeys = true) { $processor = new Processor(); - return $processor->processConfiguration($configuration, $configs); + return $processor->processConfiguration($configuration, $configs, $normalizeKeys); } /** @@ -113,6 +116,9 @@ public function getConfiguration(array $config, ContainerBuilder $container) $class = $namespace . '\\Configuration'; if (class_exists($class)) { + $r = new \ReflectionClass($class); + $container->addResource(new FileResource($r->getFileName())); + if (!method_exists($class, '__construct')) { $configuration = new $class(); diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php new file mode 100644 index 000000000000..a40e866155b2 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/DeprecationLoggerListener.php @@ -0,0 +1,44 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\EventListener; + +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Debug\ErrorHandler; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\KernelEvents; + +/** + * Injects the logger into the ErrorHandler, so that it can log deprecation errors. + * + * @author Colin Frei <colin@colinfrei.com> + */ +class DeprecationLoggerListener implements EventSubscriberInterface +{ + private $logger; + + public function __construct(LoggerInterface $logger = null) + { + $this->logger = $logger; + } + + public function injectLogger() + { + if (null !== $this->logger) { + ErrorHandler::setLogger($this->logger); + } + } + + public static function getSubscribedEvents() + { + return array(KernelEvents::REQUEST => 'injectLogger'); + } +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FatalErrorException.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FatalErrorException.php new file mode 100644 index 000000000000..a082f80dc0a0 --- /dev/null +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FatalErrorException.php @@ -0,0 +1,22 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Exception; + +/** + * Fatal Error Exception. + * + * @author Konstanton Myakshin <koc-dp@yandex.ru> + */ +class FatalErrorException extends \ErrorException +{ + +} diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.php index eb5e5715fa80..367b549440d6 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.php @@ -47,7 +47,7 @@ public static function create(\Exception $exception, $statusCode = null, array $ $e->setStatusCode($statusCode); $e->setHeaders($headers); - $e->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine()); + $e->setTraceFromException($exception); $e->setClass(get_class($exception)); $e->setFile($exception->getFile()); $e->setLine($exception->getLine()); @@ -168,6 +168,40 @@ public function getTrace() return $this->trace; } + public function setTraceFromException(\Exception $exception) + { + $trace = $exception->getTrace(); + + if ($exception instanceof FatalErrorException) { + if (function_exists('xdebug_get_function_stack')) { + $trace = array_slice(array_reverse(xdebug_get_function_stack()), 4); + + foreach ($trace as $i => $frame) { + // XDebug pre 2.1.1 doesn't currently set the call type key http://bugs.xdebug.org/view.php?id=695 + if (!isset($frame['type'])) { + $trace[$i]['type'] = '??'; + } + + if ('dynamic' === $trace[$i]['type']) { + $trace[$i]['type'] = '->'; + } elseif ('static' === $trace[$i]['type']) { + $trace[$i]['type'] = '::'; + } + + // XDebug also has a different name for the parameters array + if (isset($frame['params']) && !isset($frame['args'])) { + $trace[$i]['args'] = $frame['params']; + unset($trace[$i]['params']); + } + } + } else { + $trace = array_slice(array_reverse($trace), 1); + } + } + + $this->setTrace($trace, $exception->getFile(), $exception->getLine()); + } + public function setTrace($trace, $file, $line) { $this->trace = array(); diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php index a4b853c3ed28..c4ec7634a486 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php @@ -27,18 +27,19 @@ protected function setUp() /** * @dataProvider getCollectTestData */ - public function testCollect($nb, $logs, $expected) + public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount) { $logger = $this->getMock('Symfony\Component\HttpKernel\Log\DebugLoggerInterface'); $logger->expects($this->once())->method('countErrors')->will($this->returnValue($nb)); - $logger->expects($this->once())->method('getLogs')->will($this->returnValue($logs)); + $logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue($logs)); $c = new LoggerDataCollector($logger); $c->collect(new Request(), new Response()); $this->assertSame('logger', $c->getName()); $this->assertSame($nb, $c->countErrors()); - $this->assertSame($expected ? $expected : $logs, $c->getLogs()); + $this->assertSame($expectedLogs ? $expectedLogs : $logs, $c->getLogs()); + $this->assertSame($expectedDeprecationCount, $c->countDeprecations()); } public function getCollectTestData() @@ -48,16 +49,28 @@ public function getCollectTestData() 1, array(array('message' => 'foo', 'context' => array())), null, + 0 ), array( 1, array(array('message' => 'foo', 'context' => array('foo' => fopen(__FILE__, 'r')))), array(array('message' => 'foo', 'context' => array('foo' => 'Resource(stream)'))), + 0 ), array( 1, array(array('message' => 'foo', 'context' => array('foo' => new \stdClass()))), array(array('message' => 'foo', 'context' => array('foo' => 'Object(stdClass)'))), + 0 + ), + array( + 1, + array( + array('message' => 'foo', 'context' => array('type' => 'deprecation')), + array('message' => 'foo2', 'context' => array('type' => 'deprecation')) + ), + null, + 2 ), ); } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php index 0eb2d79d4c2b..491a0a71067e 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\HttpKernel\Tests\Debug; use Symfony\Component\HttpKernel\Debug\ErrorHandler; -use Symfony\Component\HttpKernel\Debug\ErrorException; /** * ErrorHandlerTest @@ -48,14 +47,36 @@ public function testHandle() $handler = ErrorHandler::register(3); try { - $handler->handle(1, 'foo', 'foo.php', 12, 'foo'); + $handler->handle(111, 'foo', 'foo.php', 12, 'foo'); } catch (\ErrorException $e) { - $this->assertSame('1: foo in foo.php line 12', $e->getMessage()); - $this->assertSame(1, $e->getSeverity()); + $this->assertSame('111: foo in foo.php line 12', $e->getMessage()); + $this->assertSame(111, $e->getSeverity()); $this->assertSame('foo.php', $e->getFile()); $this->assertSame(12, $e->getLine()); } restore_error_handler(); + + $handler = ErrorHandler::register(E_USER_DEPRECATED); + $this->assertTrue($handler->handle(E_USER_DEPRECATED, 'foo', 'foo.php', 12, 'foo')); + + restore_error_handler(); + + $handler = ErrorHandler::register(E_DEPRECATED); + $this->assertTrue($handler->handle(E_DEPRECATED, 'foo', 'foo.php', 12, 'foo')); + + restore_error_handler(); + + $logger = $this->getMock('Symfony\Component\HttpKernel\Log\LoggerInterface'); + $logger->expects($this->once())->method('warn')->with( + $this->equalTo('foo'), + $this->equalTo(array('type' => 'deprecation', 'file' => 'foo.php', 'line' => '12')) + ); + + $handler = ErrorHandler::register(E_USER_DEPRECATED); + $handler->setLogger($logger); + $handler->handle(E_USER_DEPRECATED, 'foo', 'foo.php', 12, 'foo'); + + restore_error_handler(); } } diff --git a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php index 934b44b4613f..d51ab6aa0715 100644 --- a/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php +++ b/core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php @@ -156,14 +156,14 @@ public function testFile(\Exception $exception) public function testToArray(\Exception $exception, $statusCode) { $flattened = FlattenException::create($exception); - $flattened->setTrace(array(),'foo.php',123); + $flattened->setTrace(array(), 'foo.php', 123); $this->assertEquals(array( array( 'message'=> 'test', 'class'=>'Exception', 'trace'=>array(array( - 'namespace' => '', 'short_class' => '', 'class' => '','type' => '','function' => '', 'file' => 'foo.php','line' => 123, + 'namespace' => '', 'short_class' => '', 'class' => '','type' => '','function' => '', 'file' => 'foo.php', 'line' => 123, 'args' => array() )), ) diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.php b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ExceptionInterface.php old mode 100644 new mode 100755 diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php b/core/vendor/symfony/process/Symfony/Component/Process/Exception/ProcessFailedException.php old mode 100644 new mode 100755 diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php b/core/vendor/symfony/process/Symfony/Component/Process/Exception/RuntimeException.php old mode 100644 new mode 100755 diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php new file mode 100644 index 000000000000..d83c1f341973 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -0,0 +1,300 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +/** + * @author Robert Schönthal <seroscho@googlemail.com> + */ +abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase +{ + protected abstract function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()); + + /** + * @expectedException \InvalidArgumentException + */ + public function testNegativeTimeoutFromConstructor() + { + $this->getProcess('', null, null, null, -1); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testNegativeTimeoutFromSetter() + { + $p = $this->getProcess(''); + $p->setTimeout(-1); + } + + public function testNullTimeout() + { + $p = $this->getProcess(''); + $p->setTimeout(10); + $p->setTimeout(null); + + $this->assertNull($p->getTimeout()); + } + + /** + * tests results from sub processes + * + * @dataProvider responsesCodeProvider + */ + public function testProcessResponses($expected, $getter, $code) + { + $p = $this->getProcess(sprintf('php -r %s', escapeshellarg($code))); + $p->run(); + + $this->assertSame($expected, $p->$getter()); + } + + /** + * tests results from sub processes + * + * @dataProvider pipesCodeProvider + */ + public function testProcessPipes($expected, $code) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Test hangs on Windows & PHP due to https://bugs.php.net/bug.php?id=60120 and https://bugs.php.net/bug.php?id=51800'); + } + + $p = $this->getProcess(sprintf('php -r %s', escapeshellarg($code))); + $p->setStdin($expected); + $p->run(); + + $this->assertSame($expected, $p->getOutput()); + $this->assertSame($expected, $p->getErrorOutput()); + } + + public function chainedCommandsOutputProvider() + { + return array( + array("1\n1\n", ';', '1'), + array("2\n2\n", '&&', '2'), + ); + } + + /** + * + * @dataProvider chainedCommandsOutputProvider + */ + public function testChainedCommandsOutput($expected, $operator, $input) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Does it work on windows ?'); + } + + $process = $this->getProcess(sprintf('echo %s %s echo %s', $input, $operator, $input)); + $process->run(); + $this->assertEquals($expected, $process->getOutput()); + } + + public function testCallbackIsExecutedForOutput() + { + $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('echo \'foo\';'))); + + $called = false; + $p->run(function ($type, $buffer) use (&$called) { + $called = $buffer === 'foo'; + }); + + $this->assertTrue($called, 'The callback should be executed with the output'); + } + + public function testExitCodeCommandFailed() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Windows does not support POSIX exit code'); + } + + // such command run in bash return an exitcode 127 + $process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis'); + $process->run(); + + $this->assertGreaterThan(0, $process->getExitCode()); + } + + public function testExitCodeText() + { + $process = $this->getProcess(''); + $r = new \ReflectionObject($process); + $p = $r->getProperty('exitcode'); + $p->setAccessible(true); + + $p->setValue($process, 2); + $this->assertEquals('Misuse of shell builtins', $process->getExitCodeText()); + } + + public function testStartIsNonBlocking() + { + $process = $this->getProcess('php -r "sleep(4);"'); + $start = microtime(true); + $process->start(); + $end = microtime(true); + $this->assertLessThan(1 , $end-$start); + } + + public function testUpdateStatus() + { + $process = $this->getProcess('php -h'); + $process->run(); + $this->assertTrue(strlen($process->getOutput()) > 0); + } + + public function testGetExitCode() + { + $process = $this->getProcess('php -m'); + $process->run(); + $this->assertEquals(0, $process->getExitCode()); + } + + public function testIsRunning() + { + $process = $this->getProcess('php -r "sleep(1);"'); + $this->assertFalse($process->isRunning()); + $process->start(); + $this->assertTrue($process->isRunning()); + $process->wait(); + $this->assertFalse($process->isRunning()); + } + + public function testStop() + { + $process = $this->getProcess('php -r "while (true) {}"'); + $process->start(); + $this->assertTrue($process->isRunning()); + $process->stop(); + $this->assertFalse($process->isRunning()); + } + + public function testIsSuccessful() + { + $process = $this->getProcess('php -m'); + $process->run(); + $this->assertTrue($process->isSuccessful()); + } + + public function testIsNotSuccessful() + { + $process = $this->getProcess('php -r "while (true) {}"'); + $process->start(); + $this->assertTrue($process->isRunning()); + $process->stop(); + $this->assertFalse($process->isSuccessful()); + } + + public function testProcessIsNotSignaled() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Windows does not support POSIX signals'); + } + + $process = $this->getProcess('php -m'); + $process->run(); + $this->assertFalse($process->hasBeenSignaled()); + } + + public function testProcessWithoutTermSignal() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Windows does not support POSIX signals'); + } + + $process = $this->getProcess('php -m'); + $process->run(); + $this->assertEquals(0, $process->getTermSignal()); + } + + public function testProcessIsSignaledIfStopped() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Windows does not support POSIX signals'); + } + + $process = $this->getProcess('php -r "while (true) {}"'); + $process->start(); + $process->stop(); + $this->assertTrue($process->hasBeenSignaled()); + } + + public function testProcessWithTermSignal() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Windows does not support POSIX signals'); + } + + + $process = $this->getProcess('php -r "while (true) {}"'); + $process->start(); + $process->stop(); + $this->assertEquals(SIGTERM, $process->getTermSignal()); + } + + public function testPhpDeadlock() + { + $this->markTestSkipped('Can course php to hang'); + + // Sleep doesn't work as it will allow the process to handle signals and close + // file handles from the other end. + $process = $this->getProcess('php -r "while (true) {}"'); + $process->start(); + + // PHP will deadlock when it tries to cleanup $process + } + + public function responsesCodeProvider() + { + return array( + //expected output / getter / code to execute + //array(1,'getExitCode','exit(1);'), + //array(true,'isSuccessful','exit();'), + array('output', 'getOutput', 'echo \'output\';'), + ); + } + + public function pipesCodeProvider() + { + $variations = array( + 'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);', + 'include \'' . __DIR__ . '/ProcessTestHelper.php\';', + ); + $baseData = str_repeat('*', 1024); + + $codes = array(); + foreach (array(1, 16, 64, 1024, 4096) as $size) { + $data = str_repeat($baseData, $size) . '!'; + foreach ($variations as $code) { + $codes[] = array($data, $code); + } + } + + return $codes; + } + + /** + * provides default method names for simple getter/setter + */ + public function methodProvider() + { + $defaults = array( + array('CommandLine'), + array('Timeout'), + array('WorkingDirectory'), + array('Env'), + array('Stdin'), + array('Options') + ); + + return $defaults; + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php new file mode 100644 index 000000000000..c632e31f7483 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php @@ -0,0 +1,64 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\PhpExecutableFinder; + +/** + * @author Robert Schönthal <seroscho@googlemail.com> + */ +class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase +{ + /** + * tests find() with the env var PHP_PATH + */ + public function testFindWithPHP_PATH() + { + if (defined('PHP_BINARY')) { + $this->markTestSkipped('The PHP binary is easily available as of PHP 5.4'); + } + + $f = new PhpExecutableFinder(); + + $current = $f->find(); + + //not executable PHP_PATH + putenv('PHP_PATH=/not/executable/php'); + $this->assertFalse($f->find(), '::find() returns false for not executable php'); + + //executable PHP_PATH + putenv('PHP_PATH='.$current); + $this->assertEquals($f->find(), $current, '::find() returns the executable php'); + } + + /** + * tests find() with default executable + */ + public function testFindWithSuffix() + { + if (defined('PHP_BINARY')) { + $this->markTestSkipped('The PHP binary is easily available as of PHP 5.4'); + } + + putenv('PHP_PATH='); + putenv('PHP_PEAR_PHP_BIN='); + $f = new PhpExecutableFinder(); + + $current = $f->find(); + + //TODO maybe php executable is custom or even windows + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->assertTrue(is_executable($current)); + $this->assertTrue((bool) preg_match('/'.addSlashes(DIRECTORY_SEPARATOR).'php\.(exe|bat|cmd|com)$/i', $current), '::find() returns the executable php with suffixes'); + } + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessBuilderTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessBuilderTest.php new file mode 100644 index 000000000000..9ca45a80a790 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessBuilderTest.php @@ -0,0 +1,108 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\ProcessBuilder; + +class ProcessBuilderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @test + */ + public function shouldInheritEnvironmentVars() + { + $snapshot = $_ENV; + $_ENV = $expected = array('foo' => 'bar'); + + $pb = new ProcessBuilder(); + $pb->add('foo')->inheritEnvironmentVariables(); + $proc = $pb->getProcess(); + + $this->assertNull($proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } + + /** + * @test + */ + public function shouldInheritAndOverrideEnvironmentVars() + { + $snapshot = $_ENV; + $_ENV = array('foo' => 'bar', 'bar' => 'baz'); + $expected = array('foo' => 'foo', 'bar' => 'baz'); + + $pb = new ProcessBuilder(); + $pb->add('foo')->inheritEnvironmentVariables() + ->setEnv('foo', 'foo'); + $proc = $pb->getProcess(); + + $this->assertEquals($expected, $proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } + + /** + * @test + */ + public function shouldInheritEnvironmentVarsByDefault() + { + $pb = new ProcessBuilder(); + $proc = $pb->add('foo')->getProcess(); + + $this->assertNull($proc->getEnv()); + } + + /** + * @test + */ + public function shouldNotReplaceExplicitlySetVars() + { + $snapshot = $_ENV; + $_ENV = array('foo' => 'bar'); + $expected = array('foo' => 'baz'); + + $pb = new ProcessBuilder(); + $pb + ->setEnv('foo', 'baz') + ->inheritEnvironmentVariables() + ->add('foo') + ; + $proc = $pb->getProcess(); + + $this->assertEquals($expected, $proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testNegativeTimeoutFromSetter() + { + $pb = new ProcessBuilder(); + $pb->setTimeout(-1); + } + + public function testNullTimeout() + { + $pb = new ProcessBuilder(); + $pb->setTimeout(10); + $pb->setTimeout(null); + + $r = new \ReflectionObject($pb); + $p = $r->getProperty('timeout'); + $p->setAccessible(true); + + $this->assertNull($p->getValue($pb)); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php new file mode 100644 index 000000000000..356c7debaa02 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php @@ -0,0 +1,75 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\Process, + Symfony\Component\Process\Exception\ProcessFailedException; + +/** + * @author Sebastian Marek <proofek@gmail.com> + */ +class ProcessFailedExceptionTest extends \PHPUnit_Framework_TestCase +{ + /** + * tests ProcessFailedException throws exception if the process was successful + */ + public function testProcessFailedExceptionThrowsException() + { + $process = $this->getMock( + 'Symfony\Component\Process\Process', + array('isSuccessful'), + array('php') + ); + $process->expects($this->once()) + ->method('isSuccessful') + ->will($this->returnValue(true)); + + $this->setExpectedException( + '\InvalidArgumentException', + 'Expected a failed process, but the given process was successful.' + ); + $exception = new ProcessFailedException($process); + } + + /** + * tests ProcessFailedException uses information from process output + * to generate exception message + */ + public function testProcessFailedExceptionPopulatesInformationFromProcessOutput() + { + $cmd = 'php'; + $output = "Command output"; + $errorOutput = "FATAL: Unexpected error"; + + $process = $this->getMock( + 'Symfony\Component\Process\Process', + array('isSuccessful', 'getOutput', 'getErrorOutput'), + array($cmd) + ); + $process->expects($this->once()) + ->method('isSuccessful') + ->will($this->returnValue(false)); + $process->expects($this->once()) + ->method('getOutput') + ->will($this->returnValue($output)); + $process->expects($this->once()) + ->method('getErrorOutput') + ->will($this->returnValue($errorOutput)); + + $exception = new ProcessFailedException($process); + + $this->assertEquals( + "The command \"$cmd\" failed.\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}", + $exception->getMessage() + ); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php new file mode 100644 index 000000000000..3977bcdcf1e8 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php @@ -0,0 +1,22 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\Process; + +class ProcessInSigchildEnvironment extends Process +{ + protected function isSigchildEnabled() + { + return true; + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTestHelper.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTestHelper.php new file mode 100644 index 000000000000..25cfb41f9335 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/ProcessTestHelper.php @@ -0,0 +1,63 @@ +<?php + +define('ERR_SELECT_FAILED', 1); +define('ERR_TIMEOUT', 2); +define('ERR_READ_FAILED', 3); +define('ERR_WRITE_FAILED', 4); + +$read = array(STDIN); +$write = array(STDOUT, STDERR); + +stream_set_blocking(STDIN, false); +stream_set_blocking(STDOUT, false); +stream_set_blocking(STDERR, false); + +$out = $err = ''; +while ($read || $write) { + $r = $read; + $w = $write; + $e = null; + $n = stream_select($r, $w, $e, 5); + + if (false === $n) { + die(ERR_SELECT_FAILED); + } elseif ($n < 1) { + die(ERR_TIMEOUT); + } + + if (in_array(STDOUT, $w) && strlen($out) > 0) { + $written = fwrite(STDOUT, (binary) $out, 1024); + if (false === $written) { + die(ERR_WRITE_FAILED); + } + $out = (binary) substr($out, $written); + } + if (null === $read && strlen($out) < 1) { + $write = array_diff($write, array(STDOUT)); + } + + if (in_array(STDERR, $w) && strlen($err) > 0) { + $written = fwrite(STDERR, (binary) $err, 1024); + if (false === $written) { + die(ERR_WRITE_FAILED); + } + $err = (binary) substr($err, $written); + } + if (null === $read && strlen($err) < 1) { + $write = array_diff($write, array(STDERR)); + } + + if ($r) { + $str = fread(STDIN, 1024); + if (false !== $str) { + $out .= $str; + $err .= $str; + } + if (false === $str || feof(STDIN)) { + $read = null; + if (!feof(STDIN)) { + die(ERR_READ_FAILED); + } + } + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php new file mode 100644 index 000000000000..4a321adf5501 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php @@ -0,0 +1,99 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +class SigchildDisabledProcessTest extends AbstractProcessTest +{ + + protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) + { + $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $stdin, $timeout, $options); + $process->setEnhanceSigchildCompatibility(false); + + return $process; + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testGetExitCode() + { + parent::testGetExitCode(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testExitCodeCommandFailed() + { + parent::testExitCodeCommandFailed(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessIsSignaledIfStopped() + { + parent::testProcessIsSignaledIfStopped(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessWithTermSignal() + { + parent::testProcessWithTermSignal(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessIsNotSignaled() + { + parent::testProcessIsNotSignaled(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessWithoutTermSignal() + { + parent::testProcessWithoutTermSignal(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testExitCodeText() + { + $process = $this->getProcess('qdfsmfkqsdfmqmsd'); + $process->run(); + + $process->getExitCodeText(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testIsSuccessful() + { + parent::testIsSuccessful(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testIsNotSuccessful() + { + parent::testIsNotSuccessful(); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php new file mode 100644 index 000000000000..4c04ff146b3f --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php @@ -0,0 +1,65 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +class SigchildEnabledProcessTest extends AbstractProcessTest +{ + + protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) + { + $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $stdin, $timeout, $options); + $process->setEnhanceSigchildCompatibility(true); + + return $process; + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessIsSignaledIfStopped() + { + parent::testProcessIsSignaledIfStopped(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessWithTermSignal() + { + parent::testProcessWithTermSignal(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessIsNotSignaled() + { + parent::testProcessIsNotSignaled(); + } + + /** + * @expectedException Symfony\Component\Process\Exception\RuntimeException + */ + public function testProcessWithoutTermSignal() + { + parent::testProcessWithoutTermSignal(); + } + + public function testExitCodeText() + { + $process = $this->getProcess('qdfsmfkqsdfmqmsd'); + $process->run(); + + $this->assertInternalType('string', $process->getExitCodeText()); + } + +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php new file mode 100644 index 000000000000..8742a69e54cf --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/SimpleProcessTest.php @@ -0,0 +1,87 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use Symfony\Component\Process\Process; + +class SimpleProcessTest extends AbstractProcessTest +{ + + protected function skipIfPHPSigchild() + { + ob_start(); + phpinfo(INFO_GENERAL); + + if (false !== strpos(ob_get_clean(), '--enable-sigchild')) { + $this->markTestSkipped('Your PHP has been compiled with --enable-sigchild, this test can not be executed'); + } + } + + protected function getProcess($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) + { + return new Process($commandline, $cwd, $env, $stdin, $timeout, $options); + } + + public function testGetExitCode() + { + $this->skipIfPHPSigchild(); + parent::testGetExitCode(); + } + + public function testExitCodeCommandFailed() + { + $this->skipIfPHPSigchild(); + parent::testExitCodeCommandFailed(); + } + + public function testProcessIsSignaledIfStopped() + { + $this->skipIfPHPSigchild(); + parent::testProcessIsSignaledIfStopped(); + } + + public function testProcessWithTermSignal() + { + $this->skipIfPHPSigchild(); + parent::testProcessWithTermSignal(); + } + + public function testProcessIsNotSignaled() + { + $this->skipIfPHPSigchild(); + parent::testProcessIsNotSignaled(); + } + + public function testProcessWithoutTermSignal() + { + $this->skipIfPHPSigchild(); + parent::testProcessWithoutTermSignal(); + } + + public function testExitCodeText() + { + $this->skipIfPHPSigchild(); + parent::testExitCodeText(); + } + + public function testIsSuccessful() + { + $this->skipIfPHPSigchild(); + parent::testIsSuccessful(); + } + + public function testIsNotSuccessful() + { + $this->skipIfPHPSigchild(); + parent::testIsNotSuccessful(); + } +} diff --git a/core/vendor/symfony/process/Symfony/Component/Process/Tests/bootstrap.php b/core/vendor/symfony/process/Symfony/Component/Process/Tests/bootstrap.php new file mode 100644 index 000000000000..11054b98928f --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/Tests/bootstrap.php @@ -0,0 +1,18 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +spl_autoload_register(function ($class) { + if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\Process')) { + if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\Process')).'.php')) { + require_once $file; + } + } +}); diff --git a/core/vendor/symfony/process/Symfony/Component/Process/composer.json b/core/vendor/symfony/process/Symfony/Component/Process/composer.json index a9f85f1af895..a20a4517bdfa 100644 --- a/core/vendor/symfony/process/Symfony/Component/Process/composer.json +++ b/core/vendor/symfony/process/Symfony/Component/Process/composer.json @@ -22,10 +22,5 @@ "psr-0": { "Symfony\\Component\\Process": "" } }, "target-dir": "Symfony/Component/Process", - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - } + "minimum-stability": "dev" } diff --git a/core/vendor/symfony/process/Symfony/Component/Process/phpunit.xml.dist b/core/vendor/symfony/process/Symfony/Component/Process/phpunit.xml.dist new file mode 100644 index 000000000000..c120a97e9118 --- /dev/null +++ b/core/vendor/symfony/process/Symfony/Component/Process/phpunit.xml.dist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false" + bootstrap="Tests/bootstrap.php" +> + <testsuites> + <testsuite name="Symfony Process Component Test Suite"> + <directory>./Tests/</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>./</directory> + <exclude> + <directory>./Tests</directory> + </exclude> + </whitelist> + </filter> +</phpunit> diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md b/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md index 8c5665b2fca7..e7fec1b0b320 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md @@ -4,6 +4,39 @@ CHANGELOG 2.2.0 ----- + * [BC BREAK] RouteCollection does not behave like a tree structure anymore but as + a flat array of Routes. So when using PHP to build the RouteCollection, you must + make sure to add routes to the sub-collection before adding it to the parent + collection (this is not relevant when using YAML or XML for Route definitions). + + Before: + + ``` + $rootCollection = new RouteCollection(); + $subCollection = new RouteCollection(); + $rootCollection->addCollection($subCollection); + $subCollection->add('foo', new Route('/foo')); + ``` + + After: + + ``` + $rootCollection = new RouteCollection(); + $subCollection = new RouteCollection(); + $subCollection->add('foo', new Route('/foo')); + $rootCollection->addCollection($subCollection); + ``` + + Also one must call `addCollection` from the bottom to the top hierarchy. + So the correct sequence is the following (and not the reverse): + + ``` + $childCollection->->addCollection($grandchildCollection); + $rootCollection->addCollection($childCollection); + ``` + + * The methods `RouteCollection::getParent()` and `RouteCollection::getRoot()` + have been deprecated and will be removed in Symfony 2.3. * added support for the method default argument values when defining a @Route * Adjacent placeholders without separator work now, e.g. `/{x}{y}{z}.{_format}`. * Characters that function as separator between placeholders are now whitelisted diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 454e26ca7bee..2c86761b63e2 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -111,7 +111,6 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections) { $fetchedHostname = false; - $routes = $this->flattenRouteCollection($routes); $groups = $this->groupRoutesByHostnameRegex($routes); $code = ''; @@ -321,31 +320,6 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren return $code; } - /** - * Flattens a tree of routes to a single collection. - * - * @param RouteCollection $routes Collection of routes - * @param DumperCollection|null $to A DumperCollection to add routes to - * - * @return DumperCollection - */ - private function flattenRouteCollection(RouteCollection $routes, DumperCollection $to = null) - { - if (null === $to) { - $to = new DumperCollection(); - } - - foreach ($routes as $name => $route) { - if ($route instanceof RouteCollection) { - $this->flattenRouteCollection($route, $to); - } else { - $to->add(new DumperRoute($name, $route)); - } - } - - return $to; - } - /** * Groups consecutive routes having the same hostname regex. * @@ -355,7 +329,7 @@ private function flattenRouteCollection(RouteCollection $routes, DumperCollectio * * @return DumperCollection A collection with routes grouped by hostname regex in sub-collections */ - private function groupRoutesByHostnameRegex(DumperCollection $routes) + private function groupRoutesByHostnameRegex(RouteCollection $routes) { $groups = new DumperCollection(); @@ -363,14 +337,14 @@ private function groupRoutesByHostnameRegex(DumperCollection $routes) $currentGroup->setAttribute('hostname_regex', null); $groups->add($currentGroup); - foreach ($routes as $route) { - $hostnameRegex = $route->getRoute()->compile()->getHostnameRegex(); + foreach ($routes as $name => $route) { + $hostnameRegex = $route->compile()->getHostnameRegex(); if ($currentGroup->getAttribute('hostname_regex') !== $hostnameRegex) { $currentGroup = new DumperCollection(); $currentGroup->setAttribute('hostname_regex', $hostnameRegex); $groups->add($currentGroup); } - $currentGroup->add($route); + $currentGroup->add(new DumperRoute($name, $route)); } return $groups; diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php index 1e2491c48895..6ef846dd69a2 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php @@ -44,14 +44,6 @@ public function getTraces($pathinfo) protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { - if ($route instanceof RouteCollection) { - if (!$ret = $this->matchCollection($pathinfo, $route)) { - continue; - } - - return true; - } - $compiledRoute = $route->compile(); if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php index 98d7a1fa0816..c0fea2d7e7d5 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -105,18 +105,6 @@ public function match($pathinfo) protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { - if ($route instanceof RouteCollection) { - if (false === strpos($route->getPrefix(), '{') && $route->getPrefix() !== substr($pathinfo, 0, strlen($route->getPrefix()))) { - continue; - } - - if (!$ret = $this->matchCollection($pathinfo, $route)) { - continue; - } - - return $ret; - } - $compiledRoute = $route->compile(); // check the static prefix of the URL first. Only use the more expensive preg_match when it matches diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php index 9e5f4a1d6f98..4716eae381ff 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php @@ -14,10 +14,11 @@ use Symfony\Component\Config\Resource\ResourceInterface; /** - * A RouteCollection represents a set of Route instances as a tree structure. + * A RouteCollection represents a set of Route instances. * - * When adding a route, it overrides existing routes with the - * same name defined in the instance or its children and parents. + * When adding a route at the end of the collection, an existing route + * with the same name is removed first. So there can only be one route + * with a given name. * * @author Fabien Potencier <fabien@symfony.com> * @author Tobias Schultze <http://tobion.de> @@ -27,7 +28,7 @@ class RouteCollection implements \IteratorAggregate, \Countable { /** - * @var (RouteCollection|Route)[] + * @var Route[] */ private $routes = array(); @@ -43,6 +44,7 @@ class RouteCollection implements \IteratorAggregate, \Countable /** * @var RouteCollection|null + * @deprecated since version 2.2, will be removed in 2.3 */ private $parent; @@ -50,9 +52,6 @@ public function __clone() { foreach ($this->routes as $name => $route) { $this->routes[$name] = clone $route; - if ($route instanceof RouteCollection) { - $this->routes[$name]->setParent($this); - } } } @@ -60,6 +59,8 @@ public function __clone() * Gets the parent RouteCollection. * * @return RouteCollection|null The parent RouteCollection or null when it's the root + * + * @deprecated since version 2.2, will be removed in 2.3 */ public function getParent() { @@ -67,9 +68,11 @@ public function getParent() } /** - * Gets the root RouteCollection of the tree. + * Gets the root RouteCollection. * * @return RouteCollection The root RouteCollection + * + * @deprecated since version 2.2, will be removed in 2.3 */ public function getRoot() { @@ -82,9 +85,13 @@ public function getRoot() } /** - * Gets the current RouteCollection as an Iterator that includes all routes and child route collections. + * Gets the current RouteCollection as an Iterator that includes all routes. + * + * It implements \IteratorAggregate. + * + * @see all() * - * @return \ArrayIterator An \ArrayIterator interface + * @return \ArrayIterator An \ArrayIterator object for iterating over routes */ public function getIterator() { @@ -94,16 +101,11 @@ public function getIterator() /** * Gets the number of Routes in this collection. * - * @return int The number of routes in this collection, including nested collections + * @return int The number of routes */ public function count() { - $count = 0; - foreach ($this->routes as $route) { - $count += $route instanceof RouteCollection ? count($route) : 1; - } - - return $count; + return count($this->routes); } /** @@ -116,32 +118,23 @@ public function count() */ public function add($name, Route $route) { - $this->remove($name); + unset($this->routes[$name]); $this->routes[$name] = $route; } /** - * Returns all routes in this collection and its children. + * Returns all routes in this collection. * * @return Route[] An array of routes */ public function all() { - $routes = array(); - foreach ($this->routes as $name => $route) { - if ($route instanceof RouteCollection) { - $routes = array_merge($routes, $route->all()); - } else { - $routes[$name] = $route; - } - } - - return $routes; + return $this->routes; } /** - * Gets a route by name defined in this collection or its children. + * Gets a route by name. * * @param string $name The route name * @@ -149,36 +142,31 @@ public function all() */ public function get($name) { - if (isset($this->routes[$name])) { - return $this->routes[$name] instanceof RouteCollection ? null : $this->routes[$name]; - } - - foreach ($this->routes as $routes) { - if ($routes instanceof RouteCollection && null !== $route = $routes->get($name)) { - return $route; - } - } - - return null; + return isset($this->routes[$name]) ? $this->routes[$name] : null; } /** - * Removes a route or an array of routes by name from all connected - * collections (this instance and all parents and children). + * Removes a route or an array of routes by name from the collection + * + * For BC it's also removed from the root, which will not be the case in 2.3 + * as the RouteCollection won't be a tree structure. * * @param string|array $name The route name or an array of route names */ public function remove($name) { + // just for BC $root = $this->getRoot(); foreach ((array) $name as $n) { - $root->removeRecursively($n); + unset($root->routes[$n]); + unset($this->routes[$n]); } } /** - * Adds a route collection to the current set of routes (at the end of the current set). + * Adds a route collection at the end of the current set by appending all + * routes of the added collection. * * @param RouteCollection $collection A RouteCollection instance * @param string $prefix An optional prefix to add before each pattern of the route collection @@ -187,22 +175,16 @@ public function remove($name) * @param array $options An array of options * @param string $hostnamePattern Hostname pattern * - * @throws \InvalidArgumentException When the RouteCollection already exists in the tree - * * @api */ public function addCollection(RouteCollection $collection, $prefix = '', $defaults = array(), $requirements = array(), $options = array(), $hostnamePattern = '') { - // prevent infinite loops by recursive referencing - $root = $this->getRoot(); - if ($root === $collection || $root->hasCollection($collection)) { - throw new \InvalidArgumentException('The RouteCollection already exists in the tree.'); - } - - // remove all routes with the same names in all existing collections - $this->remove(array_keys($collection->all())); + // This is to keep BC for getParent() and getRoot(). It does not prevent + // infinite loops by recursive referencing. But we don't need that logic + // anymore as the tree logic has been deprecated and we are just widening + // the accepted range. + $collection->parent = $this; - $collection->setParent($this); // the sub-collection must have the prefix of the parent (current instance) prepended because it does not // necessarily already have it applied (depending on the order RouteCollections are added to each other) $collection->addPrefix($this->getPrefix() . $prefix, $defaults, $requirements, $options); @@ -211,7 +193,14 @@ public function addCollection(RouteCollection $collection, $prefix = '', $defaul $collection->setHostnamePattern($hostnamePattern); } - $this->routes[] = $collection; + // we need to remove all routes with the same names first because just replacing them + // would not place the new route at the end of the merged array + foreach ($collection->all() as $name => $route) { + unset($this->routes[$name]); + $this->routes[$name] = $route; + } + + $this->resources = array_merge($this->resources, $collection->getResources()); } /** @@ -238,17 +227,12 @@ public function addPrefix($prefix, $defaults = array(), $requirements = array(), } foreach ($this->routes as $route) { - if ($route instanceof RouteCollection) { - // we add the slashes so the prefix is not lost by trimming in the sub-collection - $route->addPrefix('/' . $prefix . '/', $defaults, $requirements, $options); - } else { - if ('' !== $prefix) { - $route->setPattern('/' . $prefix . $route->getPattern()); - } - $route->addDefaults($defaults); - $route->addRequirements($requirements); - $route->addOptions($options); + if ('' !== $prefix) { + $route->setPattern('/' . $prefix . $route->getPattern()); } + $route->addDefaults($defaults); + $route->addRequirements($requirements); + $route->addOptions($options); } } @@ -263,7 +247,7 @@ public function getPrefix() } /** - * Sets the hostname pattern on all child routes. + * Sets the hostname pattern on all routes. * * @param string $pattern The pattern */ @@ -281,14 +265,7 @@ public function setHostnamePattern($pattern) */ public function getResources() { - $resources = $this->resources; - foreach ($this->routes as $routes) { - if ($routes instanceof RouteCollection) { - $resources = array_merge($resources, $routes->getResources()); - } - } - - return array_unique($resources); + return array_unique($this->resources); } /** @@ -300,60 +277,4 @@ public function addResource(ResourceInterface $resource) { $this->resources[] = $resource; } - - /** - * Sets the parent RouteCollection. It's only used internally from one RouteCollection - * to another. It makes no sense to be available as part of the public API. - * - * @param RouteCollection $parent The parent RouteCollection - */ - private function setParent(RouteCollection $parent) - { - $this->parent = $parent; - } - - /** - * Removes a route by name from this collection and its children recursively. - * - * @param string $name The route name - * - * @return Boolean true when found - */ - private function removeRecursively($name) - { - // It is ensured by the adders (->add and ->addCollection) that there can - // only be one route per name in all connected collections. So we can stop - // iterating recursively on the first hit. - if (isset($this->routes[$name])) { - unset($this->routes[$name]); - - return true; - } - - foreach ($this->routes as $routes) { - if ($routes instanceof RouteCollection && $routes->removeRecursively($name)) { - return true; - } - } - - return false; - } - - /** - * Checks whether the given RouteCollection is already set in any child of the current instance. - * - * @param RouteCollection $collection A RouteCollection instance - * - * @return Boolean - */ - private function hasCollection(RouteCollection $collection) - { - foreach ($this->routes as $routes) { - if ($routes === $collection || $routes instanceof RouteCollection && $routes->hasCollection($collection)) { - return true; - } - } - - return false; - } } diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php index 9c15be5642bf..e04310cc9a70 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php @@ -135,8 +135,8 @@ public function getRouteCollections() $collection3 = new RouteCollection(); $collection3->add('overridden2', new Route('/new')); $collection3->add('hey', new Route('/hey/')); - $collection1->addCollection($collection2); $collection2->addCollection($collection3); + $collection1->addCollection($collection2); $collection->addCollection($collection1, '/multi'); // "dynamic" prefix @@ -216,8 +216,8 @@ public function getRouteCollections() $collection3 = new RouteCollection(); $collection3->add('c', new Route('/{var}')); - $collection1->addCollection($collection2, '/b'); $collection2->addCollection($collection3, '/c'); + $collection1->addCollection($collection2, '/b'); $collection->addCollection($collection1, '/a'); /* test case 2 */ diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php index 08cd7a9a26f2..de1d9b1f39c8 100644 --- a/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php +++ b/core/vendor/symfony/routing/Symfony/Component/Routing/Tests/RouteCollectionTest.php @@ -60,8 +60,8 @@ public function testIteratorWithOverriddenRoutes() $collection->add('foo', new Route('/foo')); $collection1 = new RouteCollection(); - $collection->addCollection($collection1); $collection1->add('foo', new Route('/foo1')); + $collection->addCollection($collection1); $this->assertEquals('/foo1', $this->getFirstNamedRoute($collection, 'foo')->getPattern()); } @@ -72,8 +72,8 @@ public function testCount() $collection->add('foo', new Route('/foo')); $collection1 = new RouteCollection(); - $collection->addCollection($collection1); $collection1->add('foo1', new Route('/foo1')); + $collection->addCollection($collection1); $this->assertCount(2, $collection); } @@ -202,19 +202,12 @@ public function testUniqueRouteWithGivenName() $collection3 = new RouteCollection(); $collection3->add('foo', $new = new Route('/new')); - $collection1->addCollection($collection2); $collection2->addCollection($collection3); - - $collection1->add('stay', new Route('/stay')); - - $iterator = $collection1->getIterator(); + $collection1->addCollection($collection2); $this->assertSame($new, $collection1->get('foo'), '->get() returns new route that overrode previous one'); - // size of 2 because collection1 contains collection2 and /stay but not /old anymore - $this->assertCount(2, $iterator, '->addCollection() removes previous routes when adding new routes with the same name'); - $this->assertInstanceOf('Symfony\Component\Routing\RouteCollection', $iterator->current(), '->getIterator returns both Routes and RouteCollections'); - $iterator->next(); - $this->assertInstanceOf('Symfony\Component\Routing\Route', $iterator->current(), '->getIterator returns both Routes and RouteCollections'); + // size of 1 because collection1 contains /new but not /old anymore + $this->assertCount(1, $collection1->getIterator(), '->addCollection() removes previous routes when adding new routes with the same name'); } public function testGet() @@ -231,63 +224,6 @@ public function testGet() $this->assertNull($collection1->get(0), '->get() does not disclose internal child RouteCollection'); } - /** - * @expectedException \InvalidArgumentException - */ - public function testCannotSelfJoinCollection() - { - $collection = new RouteCollection(); - - $collection->addCollection($collection); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testCannotAddExistingCollectionToTree() - { - $collection1 = new RouteCollection(); - $collection2 = new RouteCollection(); - $collection3 = new RouteCollection(); - - $collection1->addCollection($collection2); - $collection1->addCollection($collection3); - $collection2->addCollection($collection3); - } - - public function testPatternDoesNotChangeWhenDefinitionOrderChanges() - { - $collection1 = new RouteCollection(); - $collection1->add('a', new Route('/a...')); - $collection2 = new RouteCollection(); - $collection2->add('b', new Route('/b...')); - $collection3 = new RouteCollection(); - $collection3->add('c', new Route('/c...')); - - $rootCollection_A = new RouteCollection(); - $collection2->addCollection($collection3, '/c'); - $collection1->addCollection($collection2, '/b'); - $rootCollection_A->addCollection($collection1, '/a'); - - // above should mean the same as below - - $collection1 = new RouteCollection(); - $collection1->add('a', new Route('/a...')); - $collection2 = new RouteCollection(); - $collection2->add('b', new Route('/b...')); - $collection3 = new RouteCollection(); - $collection3->add('c', new Route('/c...')); - - $rootCollection_B = new RouteCollection(); - $collection1->addCollection($collection2, '/b'); - $collection2->addCollection($collection3, '/c'); - $rootCollection_B->addCollection($collection1, '/a'); - - // test it now - - $this->assertEquals($rootCollection_A, $rootCollection_B); - } - public function testSetHostnamePattern() { $collection = new RouteCollection(); -- GitLab