- {{ loop.index }} |
+ {{ loop.index }} |
{{ trace.name }} |
{{ trace.path }} |
diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php
index 278a767bf0216..9b9e31829694e 100644
--- a/src/Symfony/Component/BrowserKit/Client.php
+++ b/src/Symfony/Component/BrowserKit/Client.php
@@ -468,6 +468,7 @@ public function followRedirect()
if (-1 !== $this->maxRedirects) {
if ($this->redirectCount > $this->maxRedirects) {
+ $this->redirectCount = 0;
throw new \LogicException(sprintf('The maximum number (%d) of redirections was reached.', $this->maxRedirects));
}
}
diff --git a/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php
index 87e38fdb89071..942fdc96226ac 100644
--- a/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php
+++ b/src/Symfony/Component/Console/Descriptor/JsonDescriptor.php
@@ -103,7 +103,7 @@ private function getInputArgumentData(InputArgument $argument)
'is_required' => $argument->isRequired(),
'is_array' => $argument->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
- 'default' => $argument->getDefault(),
+ 'default' => INF === $argument->getDefault() ? 'INF' : $argument->getDefault(),
);
}
@@ -121,7 +121,7 @@ private function getInputOptionData(InputOption $option)
'is_value_required' => $option->isValueRequired(),
'is_multiple' => $option->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
- 'default' => $option->getDefault(),
+ 'default' => INF === $option->getDefault() ? 'INF' : $option->getDefault(),
);
}
diff --git a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php
index c0dd4830c3d2d..5b82b3deefa8e 100644
--- a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php
+++ b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php
@@ -237,6 +237,10 @@ private function writeText($content, array $options = array())
*/
private function formatDefaultValue($default)
{
+ if (INF === $default) {
+ return 'INF';
+ }
+
if (is_string($default)) {
$default = OutputFormatter::escape($default);
} elseif (is_array($default)) {
diff --git a/src/Symfony/Component/Console/Helper/QuestionHelper.php b/src/Symfony/Component/Console/Helper/QuestionHelper.php
index 8998f7b0f3c21..a1e770ab2b2a3 100644
--- a/src/Symfony/Component/Console/Helper/QuestionHelper.php
+++ b/src/Symfony/Component/Console/Helper/QuestionHelper.php
@@ -111,8 +111,7 @@ public function getName()
*
* @return bool|mixed|null|string
*
- * @throws \Exception
- * @throws \RuntimeException
+ * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
*/
public function doAsk(OutputInterface $output, Question $question)
{
@@ -126,7 +125,7 @@ public function doAsk(OutputInterface $output, Question $question)
if ($question->isHidden()) {
try {
$ret = trim($this->getHiddenResponse($output, $inputStream));
- } catch (\RuntimeException $e) {
+ } catch (RuntimeException $e) {
if (!$question->isHiddenFallback()) {
throw $e;
}
diff --git a/src/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php b/src/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
index 8f825ecb68395..b4f34ada19ec6 100644
--- a/src/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
+++ b/src/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
@@ -32,6 +32,7 @@ public static function getInputArguments()
'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
'input_argument_4' => new InputArgument('argument_name', InputArgument::REQUIRED, "multiline\nargument description"),
'input_argument_with_style' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'style>'),
+ 'input_argument_with_default_inf_value' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', INF),
);
}
@@ -46,6 +47,7 @@ public static function getInputOptions()
'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'),
'input_option_with_style' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description', 'style>'),
'input_option_with_style_array' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'option description', array('Hello', 'world')),
+ 'input_option_with_default_inf_value' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', INF),
);
}
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.json b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.json
new file mode 100644
index 0000000000000..b61ecf7b8c23c
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.json
@@ -0,0 +1,7 @@
+{
+ "name": "argument_name",
+ "is_required": false,
+ "is_array": false,
+ "description": "argument description",
+ "default": "INF"
+}
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.md b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.md
new file mode 100644
index 0000000000000..293d816201271
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.md
@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: no
+* Is array: no
+* Description: argument description
+* Default: `INF`
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.txt b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.txt
new file mode 100644
index 0000000000000..c32d768c6f328
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.txt
@@ -0,0 +1 @@
+ argument_name argument description [default: INF]
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.xml b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.xml
new file mode 100644
index 0000000000000..d457260070be0
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_with_default_inf_value.xml
@@ -0,0 +1,7 @@
+
+
+ argument description
+
+ INF
+
+
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.json b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.json
new file mode 100644
index 0000000000000..7c96ad30405c6
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.json
@@ -0,0 +1,9 @@
+{
+ "name": "--option_name",
+ "shortcut": "-o",
+ "accept_value": true,
+ "is_value_required": false,
+ "is_multiple": false,
+ "description": "option description",
+ "default": "INF"
+}
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.md b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.md
new file mode 100644
index 0000000000000..b57bd04bf9993
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: no
+* Is multiple: no
+* Description: option description
+* Default: `INF`
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.txt b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.txt
new file mode 100644
index 0000000000000..d467dcf42327b
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.txt
@@ -0,0 +1 @@
+ -o, --option_name[=OPTION_NAME] option description [default: INF]
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.xml b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.xml
new file mode 100644
index 0000000000000..5d1d21753e9dc
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/input_option_with_default_inf_value.xml
@@ -0,0 +1,7 @@
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
index 21977487a364f..732ce97a17dcc 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
@@ -120,7 +120,7 @@ public function testGet()
$this->assertEquals('Circular reference detected for service "baz", path: "baz".', $e->getMessage(), '->get() throws a LogicException if the service has a circular reference to itself');
}
- $this->assertTrue($builder->get('bar') === $builder->get('bar'), '->get() always returns the same instance if the service is shared');
+ $this->assertSame($builder->get('bar'), $builder->get('bar'), '->get() always returns the same instance if the service is shared');
}
public function testNonSharedServicesReturnsDifferentInstances()
diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php
index ddf10468564b5..cfa6540399dbe 100644
--- a/src/Symfony/Component/Filesystem/Filesystem.php
+++ b/src/Symfony/Component/Filesystem/Filesystem.php
@@ -276,6 +276,13 @@ public function rename($origin, $target, $overwrite = false)
}
if (true !== @rename($origin, $target)) {
+ if (is_dir($origin)) {
+ // See https://bugs.php.net/bug.php?id=54097 & http://php.net/manual/en/function.rename.php#113943
+ $this->mirror($origin, $target, null, array('override' => $overwrite, 'delete' => $overwrite));
+ $this->remove($origin);
+
+ return;
+ }
throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target), 0, null, $target);
}
}
diff --git a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
index 0791cebc694b8..9ed871ea5a2a3 100644
--- a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
+++ b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
@@ -49,7 +49,7 @@ public function testErrorHandlingInLockIfLockPathBecomesUnwritable()
$this->markTestSkipped('This test cannot run on Windows.');
}
- $lockPath = sys_get_temp_dir().'/'.uniqid();
+ $lockPath = sys_get_temp_dir().'/'.uniqid('', true);
$e = null;
$wrongMessage = null;
diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php
index e08c9e51276be..fd24ccbeb11da 100644
--- a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php
+++ b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php
@@ -89,7 +89,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null,
if (!is_callable($preferredChoices) && !empty($preferredChoices)) {
$preferredChoices = function ($choice) use ($preferredChoices) {
- return false !== array_search($choice, $preferredChoices, true);
+ return in_array($choice, $preferredChoices, true);
};
}
diff --git a/src/Symfony/Component/Form/FormBuilderInterface.php b/src/Symfony/Component/Form/FormBuilderInterface.php
index 1145ab26420c0..c19cc903beeba 100644
--- a/src/Symfony/Component/Form/FormBuilderInterface.php
+++ b/src/Symfony/Component/Form/FormBuilderInterface.php
@@ -27,7 +27,7 @@ interface FormBuilderInterface extends \Traversable, \Countable, FormConfigBuild
* @param string|FormTypeInterface $type
* @param array $options
*
- * @return $this
+ * @return self
*/
public function add($child, $type = null, array $options = array());
@@ -58,7 +58,7 @@ public function get($name);
*
* @param string $name
*
- * @return $this
+ * @return self
*/
public function remove($name);
diff --git a/src/Symfony/Component/Form/FormRenderer.php b/src/Symfony/Component/Form/FormRenderer.php
index 15a8d08430cfe..9d1c075bb5fa7 100644
--- a/src/Symfony/Component/Form/FormRenderer.php
+++ b/src/Symfony/Component/Form/FormRenderer.php
@@ -316,6 +316,6 @@ public function searchAndRenderBlock(FormView $view, $blockNameSuffix, array $va
*/
public function humanize($text)
{
- return ucfirst(trim(strtolower(preg_replace(array('/([A-Z])/', '/[_\s]+/'), array('_$1', ' '), $text))));
+ return ucfirst(strtolower(trim(preg_replace(array('/([A-Z])/', '/[_\s]+/'), array('_$1', ' '), $text))));
}
}
diff --git a/src/Symfony/Component/Form/FormView.php b/src/Symfony/Component/Form/FormView.php
index c1da5f8fc9bb1..8655bedf6e135 100644
--- a/src/Symfony/Component/Form/FormView.php
+++ b/src/Symfony/Component/Form/FormView.php
@@ -53,6 +53,8 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable
*/
private $rendered = false;
+ private $methodRendered = false;
+
public function __construct(FormView $parent = null)
{
$this->parent = $parent;
@@ -90,6 +92,19 @@ public function setRendered()
return $this;
}
+ /**
+ * @return bool
+ */
+ public function isMethodRendered()
+ {
+ return $this->methodRendered;
+ }
+
+ public function setMethodRendered()
+ {
+ $this->methodRendered = true;
+ }
+
/**
* Returns a child by name (implements \ArrayAccess).
*
diff --git a/src/Symfony/Component/HttpFoundation/IpUtils.php b/src/Symfony/Component/HttpFoundation/IpUtils.php
index 28093be43403f..eba603b15df01 100644
--- a/src/Symfony/Component/HttpFoundation/IpUtils.php
+++ b/src/Symfony/Component/HttpFoundation/IpUtils.php
@@ -18,6 +18,8 @@
*/
class IpUtils
{
+ private static $checkedIps = array();
+
/**
* This class should not be instantiated.
*/
@@ -61,26 +63,31 @@ public static function checkIp($requestIp, $ips)
*/
public static function checkIp4($requestIp, $ip)
{
+ $cacheKey = $requestIp.'-'.$ip;
+ if (isset(self::$checkedIps[$cacheKey])) {
+ return self::$checkedIps[$cacheKey];
+ }
+
if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
- return false;
+ return self::$checkedIps[$cacheKey] = false;
}
if (false !== strpos($ip, '/')) {
list($address, $netmask) = explode('/', $ip, 2);
if ($netmask === '0') {
- return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
+ return self::$checkedIps[$cacheKey] = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
}
if ($netmask < 0 || $netmask > 32) {
- return false;
+ return self::$checkedIps[$cacheKey] = false;
}
} else {
$address = $ip;
$netmask = 32;
}
- return 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
+ return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
}
/**
@@ -100,6 +107,11 @@ public static function checkIp4($requestIp, $ip)
*/
public static function checkIp6($requestIp, $ip)
{
+ $cacheKey = $requestIp.'-'.$ip;
+ if (isset(self::$checkedIps[$cacheKey])) {
+ return self::$checkedIps[$cacheKey];
+ }
+
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".');
}
@@ -108,7 +120,7 @@ public static function checkIp6($requestIp, $ip)
list($address, $netmask) = explode('/', $ip, 2);
if ($netmask < 1 || $netmask > 128) {
- return false;
+ return self::$checkedIps[$cacheKey] = false;
}
} else {
$address = $ip;
@@ -119,7 +131,7 @@ public static function checkIp6($requestIp, $ip)
$bytesTest = unpack('n*', @inet_pton($requestIp));
if (!$bytesAddr || !$bytesTest) {
- return false;
+ return self::$checkedIps[$cacheKey] = false;
}
for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
@@ -127,10 +139,10 @@ public static function checkIp6($requestIp, $ip)
$left = ($left <= 16) ? $left : 16;
$mask = ~(0xffff >> $left) & 0xffff;
if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
- return false;
+ return self::$checkedIps[$cacheKey] = false;
}
}
- return true;
+ return self::$checkedIps[$cacheKey] = true;
}
}
diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php
index b8acebe6d44c6..481d02f27cf41 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php
@@ -92,6 +92,10 @@ class NativeSessionStorage implements SessionStorageInterface
* upload_progress.freq, "1%"
* upload_progress.min-freq, "1"
* url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
+ * sid_length, "32"
+ * sid_bits_per_character, "5"
+ * trans_sid_hosts, $_SERVER['HTTP_HOST']
+ * trans_sid_tags, "a=href,area=href,frame=src,form="
*
* @param array $options Session configuration options
* @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler
@@ -336,6 +340,7 @@ public function setOptions(array $options)
'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags',
+ 'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags',
));
foreach ($options as $key => $value) {
diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php
index 39a99e6966c22..027b2b1761334 100644
--- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php
+++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php
@@ -39,7 +39,7 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
*/
public function add(Response $response)
{
- if ($response->isValidateable()) {
+ if (!$response->isFresh() || !$response->isCacheable()) {
$this->cacheable = false;
} else {
$maxAge = $response->getMaxAge();
@@ -70,6 +70,9 @@ public function update(Response $response)
if ($response->isValidateable()) {
$response->setEtag(null);
$response->setLastModified(null);
+ }
+
+ if (!$response->isFresh()) {
$this->cacheable = false;
}
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 97e83f8d59c80..48cb62a602cbc 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -59,11 +59,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
- const VERSION = '2.8.22';
- const VERSION_ID = 20822;
+ const VERSION = '2.8.23';
+ const VERSION_ID = 20823;
const MAJOR_VERSION = 2;
const MINOR_VERSION = 8;
- const RELEASE_VERSION = 22;
+ const RELEASE_VERSION = 23;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '11/2018';
diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php
index f30a3b6ad94ab..5e4c322223eb3 100644
--- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php
@@ -75,4 +75,148 @@ public function testSharedMaxAgeNotSetIfNotSetInMasterRequest()
$this->assertFalse($response->headers->hasCacheControlDirective('s-maxage'));
}
+
+ public function testMasterResponseNotCacheableWhenEmbeddedResponseRequiresValidation()
+ {
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ $embeddedResponse = new Response();
+ $embeddedResponse->setLastModified(new \DateTime());
+ $cacheStrategy->add($embeddedResponse);
+
+ $masterResponse = new Response();
+ $masterResponse->setSharedMaxAge(3600);
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertTrue($masterResponse->headers->hasCacheControlDirective('no-cache'));
+ $this->assertTrue($masterResponse->headers->hasCacheControlDirective('must-revalidate'));
+ $this->assertFalse($masterResponse->isFresh());
+ }
+
+ public function testValidationOnMasterResponseIsNotPossibleWhenItContainsEmbeddedResponses()
+ {
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ // This master response uses the "validation" model
+ $masterResponse = new Response();
+ $masterResponse->setLastModified(new \DateTime());
+ $masterResponse->setEtag('foo');
+
+ // Embedded response uses "expiry" model
+ $embeddedResponse = new Response();
+ $masterResponse->setSharedMaxAge(3600);
+ $cacheStrategy->add($embeddedResponse);
+
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertFalse($masterResponse->isValidateable());
+ $this->assertFalse($masterResponse->headers->has('Last-Modified'));
+ $this->assertFalse($masterResponse->headers->has('ETag'));
+ $this->assertTrue($masterResponse->headers->hasCacheControlDirective('no-cache'));
+ $this->assertTrue($masterResponse->headers->hasCacheControlDirective('must-revalidate'));
+ }
+
+ public function testMasterResponseWithValidationIsUnchangedWhenThereIsNoEmbeddedResponse()
+ {
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ $masterResponse = new Response();
+ $masterResponse->setLastModified(new \DateTime());
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertTrue($masterResponse->isValidateable());
+ }
+
+ public function testMasterResponseWithExpirationIsUnchangedWhenThereIsNoEmbeddedResponse()
+ {
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ $masterResponse = new Response();
+ $masterResponse->setSharedMaxAge(3600);
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertTrue($masterResponse->isFresh());
+ }
+
+ public function testMasterResponseIsNotCacheableWhenEmbeddedResponseIsNotCacheable()
+ {
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ $masterResponse = new Response();
+ $masterResponse->setSharedMaxAge(3600); // Public, cacheable
+
+ /* This response has no validation or expiration information.
+ That makes it uncacheable, it is always stale.
+ (It does *not* make this private, though.) */
+ $embeddedResponse = new Response();
+ $this->assertFalse($embeddedResponse->isFresh()); // not fresh, as no lifetime is provided
+
+ $cacheStrategy->add($embeddedResponse);
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertTrue($masterResponse->headers->hasCacheControlDirective('no-cache'));
+ $this->assertTrue($masterResponse->headers->hasCacheControlDirective('must-revalidate'));
+ $this->assertFalse($masterResponse->isFresh());
+ }
+
+ public function testEmbeddingPrivateResponseMakesMainResponsePrivate()
+ {
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ $masterResponse = new Response();
+ $masterResponse->setSharedMaxAge(3600); // public, cacheable
+
+ // The embedded response might for example contain per-user data that remains valid for 60 seconds
+ $embeddedResponse = new Response();
+ $embeddedResponse->setPrivate();
+ $embeddedResponse->setMaxAge(60); // this would implicitly set "private" as well, but let's be explicit
+
+ $cacheStrategy->add($embeddedResponse);
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertTrue($masterResponse->headers->hasCacheControlDirective('private'));
+ // Not sure if we should pass "max-age: 60" in this case, as long as the response is private and
+ // that's the more conservative of both the master and embedded response...?
+ }
+
+ public function testResponseIsExiprableWhenEmbeddedResponseCombinesExpiryAndValidation()
+ {
+ /* When "expiration wins over validation" (https://symfony.com/doc/current/http_cache/validation.html)
+ * and both the main and embedded response provide s-maxage, then the more restricting value of both
+ * should be fine, regardless of whether the embedded response can be validated later on or must be
+ * completely regenerated.
+ */
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ $masterResponse = new Response();
+ $masterResponse->setSharedMaxAge(3600);
+
+ $embeddedResponse = new Response();
+ $embeddedResponse->setSharedMaxAge(60);
+ $embeddedResponse->setEtag('foo');
+
+ $cacheStrategy->add($embeddedResponse);
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertSame('60', $masterResponse->headers->getCacheControlDirective('s-maxage'));
+ }
+
+ public function testResponseIsExpirableButNotValidateableWhenMasterResponseCombinesExpirationAndValidation()
+ {
+ $cacheStrategy = new ResponseCacheStrategy();
+
+ $masterResponse = new Response();
+ $masterResponse->setSharedMaxAge(3600);
+ $masterResponse->setEtag('foo');
+ $masterResponse->setLastModified(new \DateTime());
+
+ $embeddedResponse = new Response();
+ $embeddedResponse->setSharedMaxAge(60);
+
+ $cacheStrategy->add($embeddedResponse);
+ $cacheStrategy->update($masterResponse);
+
+ $this->assertSame('60', $masterResponse->headers->getCacheControlDirective('s-maxage'));
+ $this->assertFalse($masterResponse->isValidateable());
+ }
}
diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php
index a1112b92a7d05..4cb3b03f898a5 100644
--- a/src/Symfony/Component/Process/Tests/ProcessTest.php
+++ b/src/Symfony/Component/Process/Tests/ProcessTest.php
@@ -439,6 +439,9 @@ public function testExitCodeCommandFailed()
$this->assertGreaterThan(0, $process->getExitCode());
}
+ /**
+ * @group tty
+ */
public function testTTYCommand()
{
if ('\\' === DIRECTORY_SEPARATOR) {
@@ -454,6 +457,9 @@ public function testTTYCommand()
$this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
}
+ /**
+ * @group tty
+ */
public function testTTYCommandExitCode()
{
if ('\\' === DIRECTORY_SEPARATOR) {
diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php
index cdb075c84621f..a6615f11e7a5e 100644
--- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php
+++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php
@@ -245,7 +245,7 @@ public static function handleError($type, $message, $file, $line, $context)
private static function throwInvalidArgumentException($message, $trace, $i)
{
- if (isset($trace[$i]['file']) && __FILE__ === $trace[$i]['file']) {
+ if (isset($trace[$i]['file']) && __FILE__ === $trace[$i]['file'] && isset($trace[$i]['args'][0])) {
$pos = strpos($message, $delim = 'must be of the type ') ?: (strpos($message, $delim = 'must be an instance of ') ?: strpos($message, $delim = 'must implement interface '));
$pos += strlen($delim);
$type = $trace[$i]['args'][0];
diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/ReturnTyped.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/ReturnTyped.php
new file mode 100644
index 0000000000000..b6a9852715d79
--- /dev/null
+++ b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/ReturnTyped.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\PropertyAccess\Tests\Fixtures;
+
+/**
+ * @author Kévin Dunglas
+ */
+class ReturnTyped
+{
+ public function getFoos(): array
+ {
+ return 'It doesn\'t respect the return type on purpose';
+ }
+
+ public function addFoo(\DateTime $dateTime)
+ {
+ }
+
+ public function removeFoo(\DateTime $dateTime)
+ {
+ }
+}
diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
index fc434adb45a0e..bff2c728f1ca2 100644
--- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
+++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
@@ -14,6 +14,7 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException;
use Symfony\Component\PropertyAccess\PropertyAccessor;
+use Symfony\Component\PropertyAccess\Tests\Fixtures\ReturnTyped;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClass;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicCall;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicGet;
@@ -566,4 +567,16 @@ public function testThrowTypeErrorWithInterface()
$this->propertyAccessor->setValue($object, 'countable', 'This is a string, \Countable expected.');
}
+
+ /**
+ * @requires PHP 7
+ *
+ * @expectedException \TypeError
+ */
+ public function testDoNotDiscardReturnTypeError()
+ {
+ $object = new ReturnTyped();
+
+ $this->propertyAccessor->setValue($object, 'foos', array(new \DateTime()));
+ }
}
diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php
index 537a81e9a44b1..cdf1973df4158 100644
--- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php
@@ -250,7 +250,7 @@ private function parseConfigs(\DOMElement $node, $path)
$condition = trim($n->textContent);
break;
default:
- throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "default", "requirement" or "option".', $n->localName, $path));
+ throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "default", "requirement", "option" or "condition".', $n->localName, $path));
}
}
diff --git a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
index 463bc0d056809..900c59fa37392 100644
--- a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
+++ b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
@@ -49,7 +49,7 @@ public function match($pathinfo)
protected function handleRouteRequirements($pathinfo, $name, Route $route)
{
// expression condition
- if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) {
+ if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
return array(self::REQUIREMENT_MISMATCH, null);
}
diff --git a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php
index cb1a35f4d3023..9085be0424886 100644
--- a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php
+++ b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php
@@ -105,7 +105,7 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
// check condition
if ($condition = $route->getCondition()) {
- if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request))) {
+ if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
$this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $condition), self::ROUTE_ALMOST_MATCHES, $name, $route);
continue;
diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php
index 9786a9b42cc60..c646723b3ab08 100644
--- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php
+++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php
@@ -207,7 +207,7 @@ protected function getAttributes(Route $route, $name, array $attributes)
protected function handleRouteRequirements($pathinfo, $name, Route $route)
{
// expression condition
- if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) {
+ if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
return array(self::REQUIREMENT_MISMATCH, null);
}
@@ -248,4 +248,19 @@ protected function getExpressionLanguage()
return $this->expressionLanguage;
}
+
+ /**
+ * @internal
+ */
+ protected function createRequest($pathinfo)
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
+ return null;
+ }
+
+ return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array(
+ 'SCRIPT_FILENAME' => $this->context->getBaseUrl(),
+ 'SCRIPT_NAME' => $this->context->getBaseUrl(),
+ ));
+ }
}
diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php
index 6d59855d2d8f3..9fd53e9814496 100644
--- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php
+++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php
@@ -337,6 +337,16 @@ public function testCondition()
$matcher->match('/foo');
}
+ public function testRequestCondition()
+ {
+ $coll = new RouteCollection();
+ $route = new Route('/foo/{bar}');
+ $route->setCondition('request.getBaseUrl() == "/sub/front.php" and request.getPathInfo() == "/foo/bar"');
+ $coll->add('foo', $route);
+ $matcher = new UrlMatcher($coll, new RequestContext('/sub/front.php'));
+ $this->assertEquals(array('bar' => 'bar', '_route' => 'foo'), $matcher->match('/foo/bar'));
+ }
+
public function testDecodeOnce()
{
$coll = new RouteCollection();
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php
index 71d19adc14f2b..7bfc556bdbf25 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php
@@ -27,7 +27,7 @@ class UsernamePasswordToken extends AbstractToken
* Constructor.
*
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
- * @param string $credentials This usually is the password of the user
+ * @param mixed $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param (RoleInterface|string)[] $roles An array of roles
*
diff --git a/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php b/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php
index 2dc7fee49992e..5f4c146cab469 100644
--- a/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php
+++ b/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php
@@ -39,6 +39,10 @@ public function validate($password, Constraint $constraint)
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UserPassword');
}
+ if (null === $password || '' === $password) {
+ return;
+ }
+
$user = $this->tokenStorage->getToken()->getUser();
if (!$user instanceof UserInterface) {
diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
index 7de83d2513369..606392de8a16c 100644
--- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
@@ -158,7 +158,7 @@ private function attemptSwitchUser(Request $request)
*/
private function attemptExitUser(Request $request)
{
- if (false === $original = $this->getOriginalToken($this->tokenStorage->getToken())) {
+ if (null === ($currentToken = $this->tokenStorage->getToken()) || false === $original = $this->getOriginalToken($currentToken)) {
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
}
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
index 43013520c36ba..6b6cb246c985f 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
@@ -65,6 +65,17 @@ public function testEventIsIgnoredIfUsernameIsNotPassedWithTheRequest()
$this->assertNull($this->tokenStorage->getToken());
}
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
+ */
+ public function testExitUserThrowsAuthenticationExceptionIfNoCurrentToken()
+ {
+ $this->tokenStorage->setToken(null);
+ $this->request->query->set('_switch_user', '_exit');
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener->handle($this->event);
+ }
+
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
index 63bfb871e819d..5149d0dbc7d97 100644
--- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
@@ -228,7 +228,7 @@ protected function handleCircularReference($object)
return call_user_func($this->circularReferenceHandler, $object);
}
- throw new CircularReferenceException(sprintf('A circular reference has been detected (configured limit: %d).', $this->circularReferenceLimit));
+ throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', get_class($object), $this->circularReferenceLimit));
}
/**
diff --git a/src/Symfony/Component/Translation/DataCollectorTranslator.php b/src/Symfony/Component/Translation/DataCollectorTranslator.php
index 50e4a2ff93805..0429595a57847 100644
--- a/src/Symfony/Component/Translation/DataCollectorTranslator.php
+++ b/src/Symfony/Component/Translation/DataCollectorTranslator.php
@@ -95,7 +95,7 @@ public function getCatalogue($locale = null)
*/
public function getFallbackLocales()
{
- if ($this->translator instanceof Translator) {
+ if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
return $this->translator->getFallbackLocales();
}
diff --git a/src/Symfony/Component/Translation/Dumper/IcuResFileDumper.php b/src/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
index 049b98c7a73d3..0535fda201046 100644
--- a/src/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
+++ b/src/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
@@ -62,7 +62,7 @@ public function formatCatalogue(MessageCatalogue $messages, $domain, array $opti
$resOffset = $this->getPosition($data);
- $data .= pack('v', count($messages))
+ $data .= pack('v', count($messages->all($domain)))
.$indexes
.$this->writePadding($data)
.$resources
@@ -73,11 +73,11 @@ public function formatCatalogue(MessageCatalogue $messages, $domain, array $opti
$root = pack('V7',
$resOffset + (2 << 28), // Resource Offset + Resource Type
6, // Index length
- $keyTop, // Index keys top
- $bundleTop, // Index resources top
- $bundleTop, // Index bundle top
- count($messages), // Index max table length
- 0 // Index attributes
+ $keyTop, // Index keys top
+ $bundleTop, // Index resources top
+ $bundleTop, // Index bundle top
+ count($messages->all($domain)), // Index max table length
+ 0 // Index attributes
);
$header = pack('vC2v4C12@32',
diff --git a/src/Symfony/Component/Translation/Loader/FileLoader.php b/src/Symfony/Component/Translation/Loader/FileLoader.php
index a7f24f41a6535..1885963a99550 100644
--- a/src/Symfony/Component/Translation/Loader/FileLoader.php
+++ b/src/Symfony/Component/Translation/Loader/FileLoader.php
@@ -54,7 +54,7 @@ public function load($resource, $locale, $domain = 'messages')
return $catalogue;
}
- /*
+ /**
* @param string $resource
*
* @return array
diff --git a/src/Symfony/Component/Translation/LoggingTranslator.php b/src/Symfony/Component/Translation/LoggingTranslator.php
index b259df5e0aa49..85ab3c47f55c8 100644
--- a/src/Symfony/Component/Translation/LoggingTranslator.php
+++ b/src/Symfony/Component/Translation/LoggingTranslator.php
@@ -95,7 +95,7 @@ public function getCatalogue($locale = null)
*/
public function getFallbackLocales()
{
- if ($this->translator instanceof Translator) {
+ if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
return $this->translator->getFallbackLocales();
}
diff --git a/src/Symfony/Component/Validator/Constraints/AbstractComparison.php b/src/Symfony/Component/Validator/Constraints/AbstractComparison.php
index 78db943f74f14..e20a8f3fb7b05 100644
--- a/src/Symfony/Component/Validator/Constraints/AbstractComparison.php
+++ b/src/Symfony/Component/Validator/Constraints/AbstractComparison.php
@@ -30,6 +30,10 @@ abstract class AbstractComparison extends Constraint
*/
public function __construct($options = null)
{
+ if (null === $options) {
+ $options = array();
+ }
+
if (is_array($options) && !isset($options['value'])) {
throw new ConstraintDefinitionException(sprintf(
'The %s constraint requires the "value" option to be set.',
diff --git a/src/Symfony/Component/Validator/Constraints/UrlValidator.php b/src/Symfony/Component/Validator/Constraints/UrlValidator.php
index c84f46c449f06..ded371b04aa1a 100644
--- a/src/Symfony/Component/Validator/Constraints/UrlValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/UrlValidator.php
@@ -48,7 +48,7 @@ public function validate($value, Constraint $constraint)
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Url');
}
- if (null === $value) {
+ if (null === $value || '' === $value) {
return;
}
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf
index 72d4d92973fdc..30a883bbf239d 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf
@@ -76,7 +76,7 @@
This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.
- Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractère.|Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractères.
+ Cette chaîne est trop longue. Elle doit avoir au maximum {{ limit }} caractère.|Cette chaîne est trop longue. Elle doit avoir au maximum {{ limit }} caractères.
This value should be {{ limit }} or more.
@@ -84,7 +84,7 @@
This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.
- Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractère.|Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractères.
+ Cette chaîne est trop courte. Elle doit avoir au minimum {{ limit }} caractère.|Cette chaîne est trop courte. Elle doit avoir au minimum {{ limit }} caractères.
This value should not be blank.
@@ -180,7 +180,7 @@
This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.
- Cette chaine doit avoir exactement {{ limit }} caractère.|Cette chaine doit avoir exactement {{ limit }} caractères.
+ Cette chaîne doit avoir exactement {{ limit }} caractère.|Cette chaîne doit avoir exactement {{ limit }} caractères.
The file was only partially uploaded.
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
index fe0e25e6e3aea..2c1bb5bbcc1fd 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
@@ -68,14 +68,21 @@ protected static function addPhp5Dot5Comparisons(array $comparisons)
return $result;
}
+ public function provideInvalidConstraintOptions()
+ {
+ return array(
+ array(null),
+ array(array()),
+ );
+ }
+
/**
+ * @dataProvider provideInvalidConstraintOptions
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
- public function testThrowsConstraintExceptionIfNoValueOrProperty()
+ public function testThrowsConstraintExceptionIfNoValueOrProperty($options)
{
- $comparison = $this->createConstraint(array());
-
- $this->validator->validate('some value', $comparison);
+ $this->createConstraint($options);
}
/**
@@ -170,11 +177,11 @@ public function provideAllInvalidComparisons()
abstract public function provideInvalidComparisons();
/**
- * @param array $options Options for the constraint
+ * @param array|null $options Options for the constraint
*
* @return Constraint
*/
- abstract protected function createConstraint(array $options);
+ abstract protected function createConstraint(array $options = null);
/**
* @return string|null
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
index 47f1e483fb4b2..32c81c3ae78d5 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new EqualToValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new EqualTo($options);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
index 41899b2ef10da..2a8bcb3b5f13a 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new GreaterThanOrEqualValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new GreaterThanOrEqual($options);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
index 080928c2e6d27..8e763fbe30911 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new GreaterThanValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new GreaterThan($options);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
index a83af3d5c6def..4999919a31a5a 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new IdenticalToValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new IdenticalTo($options);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
index 8b1adef1806c1..84f150bf133e9 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new LessThanOrEqualValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new LessThanOrEqual($options);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
index c3dea687be826..da2885fba3a5c 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new LessThanValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new LessThan($options);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
index 1ee8a54ac35fe..a797762bd3230 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new NotEqualToValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new NotEqualTo($options);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
index 3810a847f4f01..16f518f179149 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
@@ -30,7 +30,7 @@ protected function createValidator()
return new NotIdenticalToValidator();
}
- protected function createConstraint(array $options)
+ protected function createConstraint(array $options = null)
{
return new NotIdenticalTo($options);
}
diff --git a/src/Symfony/Component/VarDumper/Caster/ResourceCaster.php b/src/Symfony/Component/VarDumper/Caster/ResourceCaster.php
index 903641f69c636..d70c09ac4da62 100644
--- a/src/Symfony/Component/VarDumper/Caster/ResourceCaster.php
+++ b/src/Symfony/Component/VarDumper/Caster/ResourceCaster.php
@@ -45,7 +45,7 @@ public static function castStream($stream, array $a, Stub $stub, $isNested)
public static function castStreamContext($stream, array $a, Stub $stub, $isNested)
{
- return stream_context_get_params($stream);
+ return @stream_context_get_params($stream) ?: $a;
}
public static function castGd($gd, array $a, Stub $stub, $isNested)
diff --git a/src/Symfony/Component/VarDumper/Caster/SplCaster.php b/src/Symfony/Component/VarDumper/Caster/SplCaster.php
index e0409788e1ee1..75f01ca7cfa12 100644
--- a/src/Symfony/Component/VarDumper/Caster/SplCaster.php
+++ b/src/Symfony/Component/VarDumper/Caster/SplCaster.php
@@ -180,7 +180,7 @@ public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $s
$storage = array();
unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967
- foreach ($c as $obj) {
+ foreach (clone $c as $obj) {
$storage[spl_object_hash($obj)] = array(
'object' => $obj,
'info' => $c->getInfo(),
diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php
index f444741580af8..1e29573f3d37e 100644
--- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php
+++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php
@@ -123,9 +123,9 @@ public function dumpScalar(Cursor $cursor, $type, $value)
$style = 'num';
switch (true) {
- case INF === $value: $value = 'INF'; break;
+ case INF === $value: $value = 'INF'; break;
case -INF === $value: $value = '-INF'; break;
- case is_nan($value): $value = 'NAN'; break;
+ case is_nan($value): $value = 'NAN'; break;
default:
$value = (string) $value;
if (false === strpos($value, $this->decimalPoint)) {
|