Merge branch '3.3' into 3.4
* 3.3: fix merge fix merge fix merge Fix 7.2 compat layer Fix PHP 7.2 support [HttpFoundation] Add missing session.lazy_write config option [HttpFoundation] Combine Cache-Control headers [Form] fix parsing invalid floating point numbers Escape command usage when displaying it in the text descriptor Use for=ID on radio/checkbox label.
This commit is contained in:
commit
d3bc436cd2
|
@ -25,9 +25,10 @@ matrix:
|
|||
group: edge
|
||||
- php: 5.5
|
||||
- php: 5.6
|
||||
- php: 7.0
|
||||
- php: 7.1
|
||||
env: deps=high
|
||||
- php: 7.0
|
||||
- php: 7.2
|
||||
env: deps=low
|
||||
fast_finish: true
|
||||
|
||||
|
|
|
@ -50,10 +50,14 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block checkbox_label -%}
|
||||
{%- set label_attr = label_attr|merge({'for': id}) -%}
|
||||
|
||||
{{- block('checkbox_radio_label') -}}
|
||||
{%- endblock checkbox_label %}
|
||||
|
||||
{% block radio_label -%}
|
||||
{%- set label_attr = label_attr|merge({'for': id}) -%}
|
||||
|
||||
{{- block('checkbox_radio_label') -}}
|
||||
{%- endblock radio_label %}
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ class AppVariableTest extends TestCase
|
|||
$this->assertEquals('dev', $this->appVariable->getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testGetSession()
|
||||
{
|
||||
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
|
||||
|
@ -166,6 +169,9 @@ class AppVariableTest extends TestCase
|
|||
$this->assertEquals(array(), $this->appVariable->getFlashes());
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testGetFlashesWithNoSessionStarted()
|
||||
{
|
||||
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
|
||||
|
@ -177,6 +183,9 @@ class AppVariableTest extends TestCase
|
|||
$this->assertEquals(array(), $this->appVariable->getFlashes());
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testGetFlashes()
|
||||
{
|
||||
$flashMessages = $this->setFlashMessages();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"symfony/asset": "~2.8|~3.0|~4.0",
|
||||
"symfony/finder": "~2.8|~3.0|~4.0",
|
||||
"symfony/form": "~3.4|~4.0",
|
||||
"symfony/http-foundation": "^3.3.11|~4.0",
|
||||
"symfony/http-kernel": "~3.2|~4.0",
|
||||
"symfony/polyfill-intl-icu": "~1.0",
|
||||
"symfony/routing": "~2.8|~3.0|~4.0",
|
||||
|
|
|
@ -55,7 +55,7 @@ class CacheClearCommandTest extends TestCase
|
|||
$finder = new Finder();
|
||||
$metaFiles = $finder->files()->in($this->kernel->getCacheDir())->name('*.php.meta');
|
||||
// simply check that cache is warmed up
|
||||
$this->assertGreaterThanOrEqual(1, count($metaFiles));
|
||||
$this->assertNotEmpty($metaFiles);
|
||||
$configCacheFactory = new ConfigCacheFactory(true);
|
||||
|
||||
foreach ($metaFiles as $file) {
|
||||
|
|
|
@ -373,6 +373,9 @@ abstract class ControllerTraitTest extends TestCase
|
|||
$this->assertSame(302, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testAddFlash()
|
||||
{
|
||||
$flashBag = new FlashBag();
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation;
|
||||
|
||||
class Article implements NotExistingInterface
|
||||
{
|
||||
public $category;
|
||||
if (!function_exists('__phpunit_run_isolated_test')) {
|
||||
class Article implements NotExistingInterface
|
||||
{
|
||||
public $category;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"symfony/dependency-injection": "~3.4|~4.0",
|
||||
"symfony/config": "~3.4|~4.0",
|
||||
"symfony/event-dispatcher": "^3.3.1|~4.0",
|
||||
"symfony/http-foundation": "~3.3|~4.0",
|
||||
"symfony/http-foundation": "^3.3.11|~4.0",
|
||||
"symfony/http-kernel": "~3.4|~4.0",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/filesystem": "~2.8|~3.0|~4.0",
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Symfony\Component\Config\Tests\Fixtures;
|
||||
|
||||
class BadParent extends MissingParent
|
||||
{
|
||||
if (!function_exists('__phpunit_run_isolated_test')) {
|
||||
class BadParent extends MissingParent
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ class TextDescriptor extends Descriptor
|
|||
$this->writeText('<comment>Usage:</comment>', $options);
|
||||
foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) {
|
||||
$this->writeText("\n");
|
||||
$this->writeText(' '.$usage, $options);
|
||||
$this->writeText(' '.OutputFormatter::escape($usage), $options);
|
||||
}
|
||||
$this->writeText("\n");
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<comment>Usage:</comment>
|
||||
descriptor:command2 [options] [--] <argument_name>
|
||||
descriptor:command2 -o|--option_name <argument_name>
|
||||
descriptor:command2 <argument_name>
|
||||
descriptor:command2 [options] [--] \<argument_name>
|
||||
descriptor:command2 -o|--option_name \<argument_name>
|
||||
descriptor:command2 \<argument_name>
|
||||
|
||||
<comment>Arguments:</comment>
|
||||
<info>argument_name</info>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<comment>Usage:</comment>
|
||||
descriptor:åèä [options] [--] <argument_åèä>
|
||||
descriptor:åèä -o|--option_name <argument_name>
|
||||
descriptor:åèä <argument_name>
|
||||
descriptor:åèä [options] [--] \<argument_åèä>
|
||||
descriptor:åèä -o|--option_name \<argument_name>
|
||||
descriptor:åèä \<argument_name>
|
||||
|
||||
<comment>Arguments:</comment>
|
||||
<info>argument_åèä</info>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<?php
|
||||
|
||||
throw new \Exception('boo');
|
||||
if (!function_exists('__phpunit_run_isolated_test')) {
|
||||
throw new \Exception('boo');
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
|||
|
||||
use Symfony\Bug\NotExistClass;
|
||||
|
||||
class OptionalServiceClass extends NotExistClass
|
||||
{
|
||||
if (!function_exists('__phpunit_run_isolated_test')) {
|
||||
class OptionalServiceClass extends NotExistClass
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -458,6 +458,9 @@ class XmlFileLoaderTest extends TestCase
|
|||
if (extension_loaded('suhosin') && false === strpos(ini_get('suhosin.executor.include.whitelist'), 'phar')) {
|
||||
$this->markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.');
|
||||
}
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM makes this test conflict with those run in separate processes.');
|
||||
}
|
||||
|
||||
require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar';
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
|
|||
return;
|
||||
}
|
||||
|
||||
$position = 0;
|
||||
$formatter = $this->getNumberFormatter();
|
||||
$groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
|
||||
$decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
|
||||
|
@ -129,18 +130,44 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
|
|||
$value = str_replace(',', $decSep, $value);
|
||||
}
|
||||
|
||||
if (false !== strpos($value, $decSep)) {
|
||||
$type = \NumberFormatter::TYPE_DOUBLE;
|
||||
} else {
|
||||
$type = \PHP_INT_SIZE === 8 ? \NumberFormatter::TYPE_INT64 : \NumberFormatter::TYPE_INT32;
|
||||
}
|
||||
|
||||
// replace normal spaces so that the formatter can read them
|
||||
$value = $formatter->parse(str_replace(' ', "\xc2\xa0", $value));
|
||||
$result = $formatter->parse(str_replace(' ', "\xc2\xa0", $value), $type, $position);
|
||||
|
||||
if (intl_is_failure($formatter->getErrorCode())) {
|
||||
throw new TransformationFailedException($formatter->getErrorMessage());
|
||||
}
|
||||
|
||||
if (self::FRACTIONAL == $this->type) {
|
||||
$value /= 100;
|
||||
$result /= 100;
|
||||
}
|
||||
|
||||
return $value;
|
||||
if (\function_exists('mb_detect_encoding') && false !== $encoding = mb_detect_encoding($value, null, true)) {
|
||||
$length = mb_strlen($value, $encoding);
|
||||
$remainder = mb_substr($value, $position, $length, $encoding);
|
||||
} else {
|
||||
$length = \strlen($value);
|
||||
$remainder = substr($value, $position, $length);
|
||||
}
|
||||
|
||||
// After parsing, position holds the index of the character where the
|
||||
// parsing stopped
|
||||
if ($position < $length) {
|
||||
// Check if there are unrecognized characters at the end of the
|
||||
// number (excluding whitespace characters)
|
||||
$remainder = trim($remainder, " \t\n\r\0\x0b\xc2\xa0");
|
||||
|
||||
if ('' !== $remainder) {
|
||||
throw new TransformationFailedException(sprintf('The number contains unrecognized characters: "%s"', $remainder));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -141,10 +141,10 @@ class PercentToLocalizedStringTransformerTest extends TestCase
|
|||
*/
|
||||
public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot()
|
||||
{
|
||||
// Since we test against "de_AT", we need the full implementation
|
||||
// Since we test against "de_DE", we need the full implementation
|
||||
IntlTestHelper::requireFullIntl($this, '4.8.1.1');
|
||||
|
||||
\Locale::setDefault('de_AT');
|
||||
\Locale::setDefault('de_DE');
|
||||
|
||||
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
|
||||
|
||||
|
@ -236,4 +236,70 @@ class PercentToLocalizedStringTransformerTest extends TestCase
|
|||
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
|
||||
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||
*/
|
||||
public function testReverseTransformDisallowsLeadingExtraCharacters()
|
||||
{
|
||||
$transformer = new PercentToLocalizedStringTransformer();
|
||||
|
||||
$transformer->reverseTransform('foo123');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||
* @expectedExceptionMessage The number contains unrecognized characters: "foo3"
|
||||
*/
|
||||
public function testReverseTransformDisallowsCenteredExtraCharacters()
|
||||
{
|
||||
$transformer = new PercentToLocalizedStringTransformer();
|
||||
|
||||
$transformer->reverseTransform('12foo3');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||
* @expectedExceptionMessage The number contains unrecognized characters: "foo8"
|
||||
* @requires extension mbstring
|
||||
*/
|
||||
public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte()
|
||||
{
|
||||
// Since we test against other locales, we need the full implementation
|
||||
IntlTestHelper::requireFullIntl($this, false);
|
||||
|
||||
\Locale::setDefault('ru');
|
||||
|
||||
$transformer = new PercentToLocalizedStringTransformer();
|
||||
|
||||
$transformer->reverseTransform("12\xc2\xa0345,67foo8");
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||
* @expectedExceptionMessage The number contains unrecognized characters: "foo"
|
||||
*/
|
||||
public function testReverseTransformDisallowsTrailingExtraCharacters()
|
||||
{
|
||||
$transformer = new PercentToLocalizedStringTransformer();
|
||||
|
||||
$transformer->reverseTransform('123foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||
* @expectedExceptionMessage The number contains unrecognized characters: "foo"
|
||||
* @requires extension mbstring
|
||||
*/
|
||||
public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte()
|
||||
{
|
||||
// Since we test against other locales, we need the full implementation
|
||||
IntlTestHelper::requireFullIntl($this, false);
|
||||
|
||||
\Locale::setDefault('ru');
|
||||
|
||||
$transformer = new PercentToLocalizedStringTransformer();
|
||||
|
||||
$transformer->reverseTransform("12\xc2\xa0345,678foo");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ class HeaderBag implements \IteratorAggregate, \Countable
|
|||
}
|
||||
|
||||
if ('cache-control' === $key) {
|
||||
$this->cacheControl = $this->parseCacheControl($values[0]);
|
||||
$this->cacheControl = $this->parseCacheControl(implode(', ', $this->headers[$key]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
* gc_probability, "1"
|
||||
* hash_bits_per_character, "4"
|
||||
* hash_function, "0"
|
||||
* lazy_write, "1"
|
||||
* name, "PHPSESSID"
|
||||
* referer_check, ""
|
||||
* serialize_handler, "php"
|
||||
|
@ -98,8 +99,11 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
*/
|
||||
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
|
||||
{
|
||||
session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used)
|
||||
ini_set('session.use_cookies', 1);
|
||||
$options += array(
|
||||
// disable by default because it's managed by HeaderBag (if used)
|
||||
'cache_limiter' => '',
|
||||
'use_cookies' => 1,
|
||||
);
|
||||
|
||||
session_register_shutdown();
|
||||
|
||||
|
@ -187,6 +191,10 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
if (headers_sent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null !== $lifetime) {
|
||||
ini_set('session.cookie_lifetime', $lifetime);
|
||||
}
|
||||
|
@ -324,12 +332,16 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
if (headers_sent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$validOptions = array_flip(array(
|
||||
'cache_limiter', 'cookie_domain', 'cookie_httponly',
|
||||
'cookie_lifetime', 'cookie_path', 'cookie_secure',
|
||||
'entropy_file', 'entropy_length', 'gc_divisor',
|
||||
'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
|
||||
'hash_function', 'name', 'referer_check',
|
||||
'hash_function', 'lazy_write', 'name', 'referer_check',
|
||||
'serialize_handler', 'use_strict_mode', 'use_cookies',
|
||||
'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
|
||||
'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
|
||||
|
@ -381,6 +393,10 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
);
|
||||
}
|
||||
|
||||
if (headers_sent($file, $line)) {
|
||||
throw new \RuntimeException(sprintf('Failed to set the session handler because headers have already been sent by "%s" at line %d.', $file, $line));
|
||||
}
|
||||
|
||||
// Wrap $saveHandler in proxy and prevent double wrapping of proxy
|
||||
if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
|
||||
$saveHandler = new SessionHandlerProxy($saveHandler);
|
||||
|
|
|
@ -86,6 +86,17 @@ class ResponseHeaderBagTest extends TestCase
|
|||
$bag = new ResponseHeaderBag();
|
||||
$bag->set('Last-Modified', 'abcde');
|
||||
$this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
|
||||
|
||||
$bag = new ResponseHeaderBag();
|
||||
$bag->set('Cache-Control', array('public', 'must-revalidate'));
|
||||
$this->assertCount(1, $bag->get('Cache-Control', null, false));
|
||||
$this->assertEquals('must-revalidate, public', $bag->get('Cache-Control'));
|
||||
|
||||
$bag = new ResponseHeaderBag();
|
||||
$bag->set('Cache-Control', 'public');
|
||||
$bag->set('Cache-Control', 'must-revalidate', false);
|
||||
$this->assertCount(1, $bag->get('Cache-Control', null, false));
|
||||
$this->assertEquals('must-revalidate, public', $bag->get('Cache-Control'));
|
||||
}
|
||||
|
||||
public function testCacheControlClone()
|
||||
|
|
|
@ -269,6 +269,9 @@ class PdoSessionHandlerTest extends TestCase
|
|||
$this->assertSame('', $data, 'Destroyed session returns empty string');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testSessionGC()
|
||||
{
|
||||
$previousLifeTime = ini_set('session.gc_maxlifetime', 1000);
|
||||
|
|
|
@ -38,8 +38,7 @@ class LocaleListenerTest extends TestCase
|
|||
public function testLocaleFromRequestAttribute()
|
||||
{
|
||||
$request = Request::create('/');
|
||||
session_name('foo');
|
||||
$request->cookies->set('foo', 'value');
|
||||
$request->cookies->set(session_name(), 'value');
|
||||
|
||||
$request->attributes->set('_locale', 'es');
|
||||
$listener = new LocaleListener($this->requestStack, 'fr');
|
||||
|
|
|
@ -65,8 +65,7 @@ class TestSessionListenerTest extends TestCase
|
|||
{
|
||||
$this->sessionHasBeenStarted();
|
||||
|
||||
$params = session_get_cookie_params();
|
||||
session_set_cookie_params(0, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
|
||||
@ini_set('session.cookie_lifetime', 0);
|
||||
|
||||
$response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST);
|
||||
$cookies = $response->headers->getCookies();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8",
|
||||
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
|
||||
"symfony/http-foundation": "~3.3|~4.0",
|
||||
"symfony/http-foundation": "^3.3.11|~4.0",
|
||||
"symfony/debug": "~2.8|~3.0|~4.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<?php
|
||||
|
||||
if (function_exists('__phpunit_run_isolated_test')) {
|
||||
return;
|
||||
}
|
||||
/** @var $loader \Symfony\Component\Routing\Loader\PhpFileLoader */
|
||||
/** @var \Symfony\Component\Routing\RouteCollection $collection */
|
||||
$collection = $loader->import('validpattern.php');
|
||||
|
|
|
@ -29,14 +29,6 @@ class NativeSessionTokenStorageTest extends TestCase
|
|||
*/
|
||||
private $storage;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
ini_set('session.save_handler', 'files');
|
||||
ini_set('session.save_path', sys_get_temp_dir());
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$_SESSION = array();
|
||||
|
|
Reference in New Issue