diff --git a/appveyor.yml b/.appveyor.yml similarity index 94% rename from appveyor.yml rename to .appveyor.yml index 5cbbb67386626..1383a1070d320 100644 --- a/appveyor.yml +++ b/.appveyor.yml @@ -1,5 +1,5 @@ build: false -clone_depth: 1 +clone_depth: 2 clone_folder: c:\projects\symfony cache: @@ -10,6 +10,7 @@ init: - SET PATH=c:\php;%PATH% - SET COMPOSER_NO_INTERACTION=1 - SET SYMFONY_DEPRECATIONS_HELPER=strict + - SET "SYMFONY_REQUIRE=>=2.7" - SET ANSICON=121x90 (121x90) - SET SYMFONY_PHPUNIT_VERSION=4.8 - REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v DelayedExpansion /t REG_DWORD /d 1 /f @@ -50,9 +51,10 @@ install: - copy /Y php.ini-min php.ini - echo extension=php_openssl.dll >> php.ini - cd c:\projects\symfony - - IF NOT EXIST composer.phar (appveyor DownloadFile https://getcomposer.org/download/1.3.0/composer.phar) + - IF NOT EXIST composer.phar (appveyor DownloadFile https://github.com/composer/composer/releases/download/1.7.1/composer.phar) - php composer.phar self-update - copy /Y .composer\* %APPDATA%\Composer\ + - php composer.phar global require --no-progress --no-scripts --no-plugins symfony/flex dev-master - php .github/build-packages.php "HEAD^" src\Symfony\Bridge\PhpUnit - IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev) - php composer.phar config platform.php 5.3.9 diff --git a/.github/build-packages.php b/.github/build-packages.php index b67a699609d66..b09cea2fe230a 100644 --- a/.github/build-packages.php +++ b/.github/build-packages.php @@ -6,9 +6,14 @@ } chdir(dirname(__DIR__)); +$json = ltrim(file_get_contents('composer.json')); +if ($json !== $package = preg_replace('/\n "repositories": \[\n.*?\n \],/s', '', $json)) { + file_put_contents('composer.json', $package); +} + $dirs = $_SERVER['argv']; array_shift($dirs); -$mergeBase = trim(shell_exec(sprintf('git merge-base %s HEAD', array_shift($dirs)))); +$mergeBase = trim(shell_exec(sprintf('git merge-base "%s" HEAD', array_shift($dirs)))); $packages = array(); $flags = \PHP_VERSION_ID >= 50400 ? JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE : 0; @@ -49,7 +54,7 @@ $packages[$package->name][$package->version] = $package; - $versions = file_get_contents('https://packagist.org/p/'.$package->name.'.json'); + $versions = @file_get_contents('https://repo.packagist.org/p/'.$package->name.'.json') ?: sprintf('{"packages":{"%s":{"dev-master":%s}}}', $package->name, file_get_contents($dir.'/composer.json')); $versions = json_decode($versions)->packages->{$package->name}; if ($package->version === str_replace('-dev', '.x-dev', $versions->{'dev-master'}->extra->{'branch-alias'}->{'dev-master'})) { @@ -74,8 +79,6 @@ 'type' => 'composer', 'url' => 'file://'.str_replace(DIRECTORY_SEPARATOR, '/', dirname(__DIR__)).'/', )); - if (false === strpos($json, "\n \"repositories\": [\n")) { - $json = rtrim(json_encode(array('repositories' => $package->repositories), $flags), "\n}").','.substr($json, 1); - file_put_contents('composer.json', $json); - } + $json = rtrim(json_encode(array('repositories' => $package->repositories), $flags), "\n}").','.substr($json, 1); + file_put_contents('composer.json', $json); } diff --git a/.github/rm-invalid-lowest-lock-files.php b/.github/rm-invalid-lowest-lock-files.php new file mode 100644 index 0000000000000..c036fd356f045 --- /dev/null +++ b/.github/rm-invalid-lowest-lock-files.php @@ -0,0 +1,158 @@ + array(), 'packages-dev' => array()); + $composerJsons[$composerJson['name']] = array($dir, $composerLock['packages'] + $composerLock['packages-dev'], getRelevantContent($composerJson)); +} + +$referencedCommits = array(); + +foreach ($composerJsons as list($dir, $lockedPackages)) { + foreach ($lockedPackages as $lockedJson) { + if (0 !== strpos($version = $lockedJson['version'], 'dev-') && '-dev' !== substr($version, -4)) { + continue; + } + + if (!isset($composerJsons[$name = $lockedJson['name']])) { + echo "$dir/composer.lock references missing $name.\n"; + @unlink($dir.'/composer.lock'); + continue 2; + } + + if (isset($composerJsons[$name][2]['repositories']) && !isset($lockedJson['repositories'])) { + // the locked package has been patched locally but the lock references a commit, + // which means the referencing package itself is not modified + continue; + } + + foreach (array('minimum-stability', 'prefer-stable') as $key) { + if (array_key_exists($key, $composerJsons[$name][2])) { + $lockedJson[$key] = $composerJsons[$name][2][$key]; + } + } + + // use weak comparison to ignore ordering + if (getRelevantContent($lockedJson) != $composerJsons[$name][2]) { + echo "$dir/composer.lock is not in sync with $name.\n"; + @unlink($dir.'/composer.lock'); + continue 2; + } + + if ($lockedJson['dist']['reference']) { + $referencedCommits[$name][$lockedJson['dist']['reference']][] = $dir; + } + } +} + +if (!$referencedCommits) { + return; +} + +@mkdir($_SERVER['HOME'].'/.cache/composer/repo/https---repo.packagist.org', 0777, true); + +$ch = null; +$mh = curl_multi_init(); +$sh = curl_share_init(); +curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); +curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); +curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); +$chs = array(); + +foreach ($referencedCommits as $name => $dirsByCommit) { + $chs[] = $ch = array(curl_init(), fopen($_SERVER['HOME'].'/.cache/composer/repo/https---repo.packagist.org/provider-'.strtr($name, '/', '$').'.json', 'wb')); + curl_setopt($ch[0], CURLOPT_URL, 'https://repo.packagist.org/p/'.$name.'.json'); + curl_setopt($ch[0], CURLOPT_FILE, $ch[1]); + curl_setopt($ch[0], CURLOPT_SHARE, $sh); + curl_multi_add_handle($mh, $ch[0]); +} + +do { + curl_multi_exec($mh, $active); + curl_multi_select($mh); +} while ($active); + +foreach ($chs as list($ch, $fd)) { + curl_multi_remove_handle($mh, $ch); + curl_close($ch); + fclose($fd); +} + +foreach ($referencedCommits as $name => $dirsByCommit) { + $repo = file_get_contents($_SERVER['HOME'].'/.cache/composer/repo/https---repo.packagist.org/provider-'.strtr($name, '/', '$').'.json'); + $repo = json_decode($repo, true); + + foreach ($repo['packages'][$name] as $version) { + unset($referencedCommits[$name][$version['source']['reference']]); + } +} + +foreach ($referencedCommits as $name => $dirsByCommit) { + foreach ($dirsByCommit as $dirs) { + foreach ($dirs as $dir) { + if (file_exists($dir.'/composer.lock')) { + echo "$dir/composer.lock references old commit for $name.\n"; + @unlink($dir.'/composer.lock'); + } + } + } +} diff --git a/.travis.yml b/.travis.yml index 25ca170da93a5..34ef0b343e0d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,9 @@ language: php dist: trusty -sudo: false git: - depth: 1 + depth: 2 addons: apt_packages: @@ -22,9 +21,7 @@ matrix: sudo: required group: edge - php: 5.4 - - php: 5.5 - - php: 5.6 - - php: 7.0 + env: php_extra="5.5 5.6 7.0" - php: 7.1 env: deps=high - php: 7.2 @@ -42,15 +39,26 @@ services: mongodb before_install: - | # General configuration + set -e stty cols 120 - PHP=$TRAVIS_PHP_VERSION [ -d ~/.composer ] || mkdir ~/.composer cp .composer/* ~/.composer/ export PHPUNIT=$(readlink -f ./phpunit) export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data" export COMPOSER_UP='composer update --no-progress --no-suggest --ansi' + export COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n') + find ~/.phpenv -name xdebug.ini -delete + + if [[ $TRAVIS_PHP_VERSION = 5.* || $TRAVIS_PHP_VERSION = hhvm* ]]; then + composer () { + $HOME/.phpenv/versions/7.1/bin/php $HOME/.phpenv/versions/7.1/bin/composer config platform.php $(echo ' > $INI - echo memory_limit = -1 >> $INI - echo session.gc_probability = 0 >> $INI - echo opcache.enable_cli = 1 >> $INI - echo hhvm.jit = 0 >> $INI - echo apc.enable_cli = 1 >> $INI - [[ $PHP = 5.* ]] && echo extension = memcache.so >> $INI - if [[ $PHP = 5.* ]]; then - echo extension = mongo.so >> $INI - fi - # tpecl is a helper to compile and cache php extensions tpecl () { local ext_name=$1 @@ -114,6 +104,7 @@ before_install: if [[ -e $ext_cache/$ext_so ]]; then echo extension = $ext_cache/$ext_so >> $INI else + rm ~/.pearrc /tmp/pear 2>/dev/null || true mkdir -p $ext_cache echo yes | pecl install -f $ext_name && cp $ext_dir/$ext_so $ext_cache @@ -121,38 +112,62 @@ before_install: } export -f tpecl - # Matrix lines for intermediate PHP versions are skipped for pull requests - if [[ ! $deps && ! $PHP = ${MIN_PHP%.*} && ! $PHP = hhvm* && $TRAVIS_PULL_REQUEST != false ]]; then - deps=skip - skip=1 - else - COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n') - fi - - | # Install sigchild-enabled PHP to test the Process component on the lowest PHP matrix line - if [[ ! $deps && $PHP = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then + if [[ ! $deps && $TRAVIS_PHP_VERSION = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then wget http://museum.php.net/php5/php-$MIN_PHP.tar.bz2 -O - | tar -xj && (cd php-$MIN_PHP && ./configure --enable-sigchild --enable-pcntl && make -j2) fi + - | + # php.ini configuration + for PHP in $TRAVIS_PHP_VERSION $php_extra; do + if [[ $PHP = hhvm* ]]; then + INI=/etc/hhvm/php.ini + else + phpenv global $PHP 2>/dev/null || (cd / && wget https://s3.amazonaws.com/travis-php-archives/binaries/ubuntu/14.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) + INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini + fi + echo date.timezone = Europe/Paris >> $INI + echo memory_limit = -1 >> $INI + echo session.gc_probability = 0 >> $INI + echo opcache.enable_cli = 1 >> $INI + echo hhvm.jit = 0 >> $INI + echo apc.enable_cli = 1 >> $INI + [[ $PHP = 5.* ]] && echo extension = memcache.so >> $INI + if [[ $PHP = 5.* ]]; then + echo extension = mongo.so >> $INI + fi + done + - | # Install extra PHP extensions - if [[ ! $skip && $PHP = 5.* ]]; then - ([[ $deps ]] || tfold ext.symfony_debug 'cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> '"$INI") - tfold ext.memcached tpecl memcached-2.1.0 memcached.so $INI - tfold ext.apcu tpecl apcu-4.0.11 apcu.so $INI - elif [[ ! $skip && $PHP = 7.* ]]; then - tfold ext.apcu tpecl apcu-5.1.6 apcu.so $INI - tfold ext.mongodb tpecl mongodb-1.4.0RC1 mongodb.so $INI - fi + for PHP in $TRAVIS_PHP_VERSION $php_extra; do + if [[ $PHP = hhvm* ]]; then + continue + fi + export PHP=$PHP + phpenv global $PHP + INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini + if [[ $PHP = 5.* ]]; then + tfold ext.memcached tpecl memcached-2.1.0 memcached.so $INI + tfold ext.apcu tpecl apcu-4.0.11 apcu.so $INI + [[ $deps ]] && continue + ext_cache=~/php-ext/$(php -r "echo basename(ini_get('extension_dir'));")/symfony_debug.so + [[ -e $ext_cache ]] || (tfold ext.symfony_debug "cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && mv modules/symfony_debug.so $ext_cache && phpize --clean") + echo extension = $ext_cache >> $INI + elif [[ $PHP = 7.* ]]; then + tfold ext.apcu tpecl apcu-5.1.6 apcu.so $INI + tfold ext.mongodb tpecl mongodb-1.6.0alpha1 mongodb.so $INI + fi + done install: - | # Create local composer packages for each patched components and reference them in composer.json files when cross-testing components if [[ ! $deps ]]; then php .github/build-packages.php HEAD^ src/Symfony/Bridge/PhpUnit - elif [[ ! $skip ]]; then + else export SYMFONY_DEPRECATIONS_HELPER=weak && cp composer.json composer.json.orig && echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json && @@ -168,46 +183,67 @@ install: git fetch origin $SYMFONY_VERSION && git checkout -m FETCH_HEAD && COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n') - elif [[ ! $skip ]]; then + else SYMFONY_VERSION=$(cat composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9.]*') fi + - | + # Install symfony/flex + if [[ $deps = low ]]; then + export SYMFONY_REQUIRE='>=2.3' + else + export SYMFONY_REQUIRE=">=$SYMFONY_VERSION" + fi + composer global require --no-progress --no-scripts --no-plugins symfony/flex dev-master + - | # Legacy tests are skipped when deps=high and when the current branch version has not the same major version number than the next one [[ $deps = high && ${SYMFONY_VERSION%.*} != $(git show $(git ls-remote --heads | grep -FA1 /$SYMFONY_VERSION | tail -n 1):composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9]*' | head -n 1) ]] && LEGACY=,legacy export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev - if [[ ! $skip && $deps ]]; then mv composer.json.phpunit composer.json; fi - - if [[ ! $skip && $PHP = 7.* ]]; then - ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; composer require --dev --no-update mongodb/mongodb) - fi + if [[ $deps ]]; then mv composer.json.phpunit composer.json; fi - - if [[ ! $skip ]]; then $COMPOSER_UP; fi - - if [[ ! $skip ]]; then ./phpunit install; fi - | # phpinfo - if [[ ! $PHP = hhvm* ]]; then php -i; else hhvm --php -r 'print_r($_SERVER);print_r(ini_get_all());'; fi + if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then php -i; else hhvm --php -r 'print_r($_SERVER);print_r(ini_get_all());'; fi - | run_tests () { set -e - if [[ $skip ]]; then + export PHP=$1 + if [[ $PHP != $TRAVIS_PHP_VERSION && $TRAVIS_PULL_REQUEST != false ]]; then echo -e "\\n\\e[1;34mIntermediate PHP version $PHP is skipped for pull requests.\\e[0m" - elif [[ $deps = high ]]; then + break + fi + phpenv global ${PHP/hhvm*/hhvm} + if [[ $PHP = 7.* ]]; then + ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; composer config platform.ext-mongodb 1.6.0; composer require --dev --no-update mongodb/mongodb) + fi + tfold 'composer update' $COMPOSER_UP + if [[ $TRAVIS_PHP_VERSION = 5.* || $TRAVIS_PHP_VERSION = hhvm* ]]; then + tfold 'phpunit install' 'composer global remove symfony/flex && ./phpunit install && composer global require --no-progress --no-scripts --no-plugins symfony/flex dev-master' + else + tfold 'phpunit install' ./phpunit install + fi + if [[ $deps = high ]]; then echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" elif [[ $deps = low ]]; then - echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'" + [[ -e ~/php-ext/composer-lowest.lock.tar ]] && tar -xf ~/php-ext/composer-lowest.lock.tar + tar -cf ~/php-ext/composer-lowest.lock.tar --files-from /dev/null + php .github/rm-invalid-lowest-lock-files.php $COMPONENTS + echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && ([ -e composer.lock ] && ${COMPOSER_UP/update/install} || $COMPOSER_UP --prefer-lowest --prefer-stable) && $PHPUNIT_X'" + echo "$COMPONENTS" | xargs -n1 -I{} tar --append -f ~/php-ext/composer-lowest.lock.tar {}/composer.lock elif [[ $PHP = hhvm* ]]; then $PHPUNIT --exclude-group no-hhvm,benchmark,intl-data else echo "$COMPONENTS" | parallel --gnu "tfold {} $PHPUNIT_X {}" - tfold tty-group $PHPUNIT --group tty + tfold src/Symfony/Component/Console.tty $PHPUNIT src/Symfony/Component/Console --group tty if [[ $PHP = ${MIN_PHP%.*} ]]; then - echo -e "1\\n0" | xargs -I{} bash -c "tfold src/Symfony/Component/Process.sigchild{} ENHANCE_SIGCHLD={} php-$MIN_PHP/sapi/cli/php .phpunit/phpunit-4.8/phpunit --colors=always src/Symfony/Component/Process/" + export PHP=$MIN_PHP + echo -e "1\\n0" | xargs -I{} bash -c "tfold src/Symfony/Component/Process.sigchild{} SYMFONY_DEPRECATIONS_HELPER=weak ENHANCE_SIGCHLD={} php-$MIN_PHP/sapi/cli/php .phpunit/phpunit-4.8/phpunit --colors=always src/Symfony/Component/Process/" fi fi } script: - - (run_tests) + - for PHP in $TRAVIS_PHP_VERSION $php_extra; do (run_tests $PHP); done diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index a209a917388a5..bfe51e96c858a 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,11 @@ in 2.7 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.7.0...v2.7.1 +* 2.7.50 (2018-12-06) + + * security #cve-2018-19790 [Security\Http] detect bad redirect targets using backslashes (xabbuh) + * security #cve-2018-19789 [Form] Filter file uploads out of regular form types (nicolas-grekas) + * 2.7.49 (2018-08-01) * security #cve-2018-14774 [HttpKernel] fix trusted headers management in HttpCache and InlineFragmentRenderer (nicolas-grekas) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index c1dfa2ad36a85..59b453c439886 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -1509,4 +1509,9 @@ public function testSetDataNonEmptyArraySubmitNullMultiple() $this->assertEquals(array(), $form->getNormData()); $this->assertSame(array(), $form->getViewData(), 'View data is always an array'); } + + public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = null) + { + $this->markTestIncomplete('Added in symfony/form 2.8.'); + } } diff --git a/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt b/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt index 7ce7b9dc6f7dd..1de9b29ac0e66 100644 --- a/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt +++ b/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt @@ -38,8 +38,7 @@ Did you forget a "use" statement for another namespace?" ["line":protected]=> int(%d) ["trace":"Exception":private]=> - array(0) { - } + array(%d) {%A} ["previous":"Exception":private]=> NULL ["severity":protected]=> diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index 321cbc03690e5..f7f7fe72db8d4 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -105,6 +105,7 @@ public function configureOptions(OptionsResolver $resolver) 'data_class' => $dataClass, 'empty_data' => $emptyData, 'multiple' => false, + 'allow_file_upload' => true, )); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index 9c5642b11604e..292907165573d 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -213,6 +213,7 @@ public function configureOptions(OptionsResolver $resolver) 'attr' => $defaultAttr, 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'upload_max_size_message' => $uploadMaxSizeMessage, // internal + 'allow_file_upload' => false, )); $resolver->setAllowedTypes('label_attr', 'array'); diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index ec4f96783ce9e..a4c25a8a71719 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -541,6 +541,11 @@ public function submit($submittedData, $clearMissing = true) $submittedData = null; } elseif (is_scalar($submittedData)) { $submittedData = (string) $submittedData; + } elseif ($this->config->getOption('allow_file_upload')) { + // no-op + } elseif ($this->config->getRequestHandler()->isFileUpload($submittedData)) { + $submittedData = null; + $this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.'); } $dispatcher = $this->config->getEventDispatcher(); @@ -550,6 +555,10 @@ public function submit($submittedData, $clearMissing = true) $viewData = null; try { + if (null !== $this->transformationFailure) { + throw $this->transformationFailure; + } + // Hook to change content of the data submitted by the browser if ($dispatcher->hasListeners(FormEvents::PRE_SUBMIT)) { $event = new FormEvent($this, $submittedData); diff --git a/src/Symfony/Component/Form/Tests/CompoundFormTest.php b/src/Symfony/Component/Form/Tests/CompoundFormTest.php index 7975570cccc61..96f2a7cf55937 100644 --- a/src/Symfony/Component/Form/Tests/CompoundFormTest.php +++ b/src/Symfony/Component/Form/Tests/CompoundFormTest.php @@ -712,7 +712,7 @@ public function testSubmitPostOrPutRequestWithSingleChildForm($method) 'REQUEST_METHOD' => $method, )); - $form = $this->getBuilder('image') + $form = $this->getBuilder('image', null, null, array('allow_file_upload' => true)) ->setMethod($method) ->setRequestHandler(new HttpFoundationRequestHandler()) ->getForm(); @@ -1088,6 +1088,21 @@ public function testDisabledButtonIsNotSubmitted() $this->assertFalse($submit->isSubmitted()); } + public function testFileUpload() + { + $reqHandler = new HttpFoundationRequestHandler(); + $this->form->add($this->getBuilder('foo')->setRequestHandler($reqHandler)->getForm()); + $this->form->add($this->getBuilder('bar')->setRequestHandler($reqHandler)->getForm()); + + $this->form->submit(array( + 'foo' => 'Foo', + 'bar' => new UploadedFile(__FILE__, 'upload.png', 'image/png', 123, UPLOAD_ERR_OK), + )); + + $this->assertSame('Submitted data was expected to be text or number, file upload given.', $this->form->get('bar')->getTransformationFailure()->getMessage()); + $this->assertNull($this->form->get('bar')->getData()); + } + protected function createForm() { return $this->getBuilder() diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index 13b85b15d4e81..0feaad28036ef 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -170,7 +170,7 @@ class Response 422 => 'Unprocessable Entity', // RFC4918 423 => 'Locked', // RFC4918 424 => 'Failed Dependency', // RFC4918 - 425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817 + 425 => 'Too Early', // RFC-ietf-httpbis-replay-04 426 => 'Upgrade Required', // RFC2817 428 => 'Precondition Required', // RFC6585 429 => 'Too Many Requests', // RFC6585 diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 6106c9cf703aa..3ce7b5cf470f1 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,11 +58,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.49'; - const VERSION_ID = 20749; + const VERSION = '2.7.50'; + const VERSION_ID = 20750; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 49; + const RELEASE_VERSION = 50; const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index c614b3aa40089..58d86ce3571e2 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -439,9 +439,6 @@ public function testExitCodeCommandFailed() $this->assertGreaterThan(0, $process->getExitCode()); } - /** - * @group tty - */ public function testTTYCommand() { if ('\\' === DIRECTORY_SEPARATOR) { @@ -457,9 +454,6 @@ public function testTTYCommand() $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus()); } - /** - * @group tty - */ public function testTTYCommandExitCode() { if ('\\' === DIRECTORY_SEPARATOR) { diff --git a/src/Symfony/Component/Security/Http/HttpUtils.php b/src/Symfony/Component/Security/Http/HttpUtils.php index 30071b880de16..a16a1489e43fa 100644 --- a/src/Symfony/Component/Security/Http/HttpUtils.php +++ b/src/Symfony/Component/Security/Http/HttpUtils.php @@ -59,7 +59,7 @@ public function __construct(UrlGeneratorInterface $urlGenerator = null, $urlMatc */ public function createRedirectResponse(Request $request, $path, $status = 302) { - if (null !== $this->domainRegexp && preg_match('#^https?://[^/]++#i', $path, $host) && !preg_match(sprintf($this->domainRegexp, preg_quote($request->getHttpHost())), $host[0])) { + if (null !== $this->domainRegexp && preg_match('#^https?:[/\\\\]{2,}+[^/]++#i', $path, $host) && !preg_match(sprintf($this->domainRegexp, preg_quote($request->getHttpHost())), $host[0])) { $path = '/'; } diff --git a/src/Symfony/Component/Security/Http/Tests/HttpUtilsTest.php b/src/Symfony/Component/Security/Http/Tests/HttpUtilsTest.php index 352f8977e777e..2ab000dceb94f 100644 --- a/src/Symfony/Component/Security/Http/Tests/HttpUtilsTest.php +++ b/src/Symfony/Component/Security/Http/Tests/HttpUtilsTest.php @@ -54,14 +54,28 @@ public function testCreateRedirectResponseWithRequestsDomain() $this->assertTrue($response->isRedirect('http://localhost/blog')); } - public function testCreateRedirectResponseWithBadRequestsDomain() + /** + * @dataProvider badRequestDomainUrls + */ + public function testCreateRedirectResponseWithBadRequestsDomain($url) { $utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://%s$#i'); - $response = $utils->createRedirectResponse($this->getRequest(), 'http://pirate.net/foo'); + $response = $utils->createRedirectResponse($this->getRequest(), $url); $this->assertTrue($response->isRedirect('http://localhost/')); } + public function badRequestDomainUrls() + { + return array( + array('http://pirate.net/foo'), + array('http:\\\\pirate.net/foo'), + array('http:/\\pirate.net/foo'), + array('http:\\/pirate.net/foo'), + array('http://////pirate.net/foo'), + ); + } + public function testCreateRedirectResponseWithProtocolRelativeTarget() { $utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://%s$#i');