Merge branch '2.3' into 2.7

* 2.3:
  Windows and Intl fixes
  Add appveyor.yml for C.I. on Windows
  [travis] merge php: nightly and deps=high test-matrix lines
  [Security] Add missing docblock in PreAuthenticatedToken

Conflicts:
	.travis.yml
	src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
	src/Symfony/Component/HttpFoundation/JsonResponse.php
	src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php
This commit is contained in:
Nicolas Grekas 2015-08-26 12:48:03 +02:00
commit e924d567e9
27 changed files with 369 additions and 156 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ phpunit.xml
composer.phar
package.tar
/packages.json
/.phpunit

View File

@ -3,9 +3,9 @@ language: php
sudo: false
addons:
apt_packages:
- parallel
- language-pack-fr-base
apt_packages:
- parallel
- language-pack-fr-base
matrix:
include:
@ -15,9 +15,8 @@ matrix:
- php: 5.5
- php: 5.6
env: deps=low
- php: 5.6
env: deps=high
- php: 7.0
env: deps=high
fast_finish: true
services: mongodb
@ -30,27 +29,24 @@ env:
before_install:
- composer self-update
- if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then echo "memory_limit = -1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi;
- if [[ "$TRAVIS_PHP_VERSION" != "7.0" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi;
- if [[ "$TRAVIS_PHP_VERSION" != "7.0" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
- if [[ "$TRAVIS_PHP_VERSION" != "7.0" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]] && [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
- if [[ "$TRAVIS_PHP_VERSION" != "7.0" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then (pecl install -f memcached-2.1.0 && echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini) || echo "Let's continue without memcache extension"; fi;
- if [[ "$TRAVIS_PHP_VERSION" != "7.0" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo "extension = $(pwd)/modules/symfony_debug.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini); fi;
- if [[ "$TRAVIS_PHP_VERSION" != "7.0" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then php -i; fi;
# Build a standalone phpunit without symfony/yaml and that works around https://github.com/sebastianbergmann/phpunit-mock-objects/issues/223
- (mkdir phpunit && cd phpunit && wget https://github.com/sebastianbergmann/phpunit/archive/4.7.zip && unzip 4.7.zip && cd phpunit-4.7 && composer remove --no-update symfony/yaml && composer require --prefer-source phpunit/phpunit-mock-objects '2.3.0')
- export PHPUNIT="$(readlink -f ./phpunit/phpunit-4.7/phpunit) --colors=always"
# Set the COMPOSER_ROOT_VERSION to the right version according to the branch being built
- if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
- if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then phpenv config-rm xdebug.ini; fi;
- if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
- if [[ "$TRAVIS_PHP_VERSION" =~ 5.[34] ]]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
- if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then (pecl install -f memcached-2.1.0 && echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini) || echo "Let's continue without memcache extension"; fi;
- if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo "extension = $(pwd)/modules/symfony_debug.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini); fi;
- if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then php -i; fi;
- ./phpunit install
- export PHPUNIT="$(readlink -f ./phpunit)"
install:
- if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
- if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi;
- if [ "$deps" = "no" ]; then composer --prefer-source install; fi;
- components=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n')
- if [ "$deps" != "no" ]; then php .travis.php $TRAVIS_COMMIT_RANGE $TRAVIS_BRANCH $components; fi;
- COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n')
- if [ "$deps" != "no" ]; then php .travis.php $TRAVIS_COMMIT_RANGE $TRAVIS_BRANCH $COMPONENTS; fi;
script:
- if [ "$deps" = "no" ]; then echo "$components" | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; $PHPUNIT --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
- if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi;
- if [ "$deps" = "high" ]; then echo "$components" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; $PHPUNIT --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
- if [ "$deps" = "low" ]; then echo "$components" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; $PHPUNIT --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
- if [ "$deps" = "no" ]; then echo "$COMPONENTS" | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; $PHPUNIT --exclude-group tty,benchmark,intl-data {}'; fi;
- if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty; fi;
- if [ "$deps" = "high" ]; then echo "$COMPONENTS" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi;
- if [ "$deps" = "low" ]; then echo "$COMPONENTS" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi;

53
appveyor.yml Normal file
View File

@ -0,0 +1,53 @@
build: false
shallow_clone: true
platform: x86
clone_folder: c:\projects\symfony
environment:
matrix:
- PHP_EXT: 1
- PHP_EXT: 0
cache:
- c:\php -> appveyor.yml
- .phpunit -> phpunit
- vendor -> composer.json
init:
- SET PATH=c:\php;%PATH%
- SET COMPOSER_NO_INTERACTION=1
- SET SYMFONY_DEPRECATIONS_HELPER=weak
- SET PHP=1
install:
- IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php)
- cd c:\php
- IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-5.4.43-nts-Win32-VC9-x86.zip
- IF %PHP%==1 7z x php-5.4.43-nts-Win32-VC9-x86.zip -y > 7z.log
- IF %PHP%==1 appveyor DownloadFile http://nebm.ist.utl.pt/~glopes/misc/intl_win/ICU-51.2-dlls.zip
- IF %PHP%==1 7z x ICU-51.2-dlls.zip -y > 7z.log
- IF %PHP%==1 cd ext
- IF %PHP%==1 appveyor DownloadFile http://nebm.ist.utl.pt/~glopes/misc/intl_win/php_intl-3.0.0-5.4-nts-vc9-x86.zip
- IF %PHP%==1 7z x php_intl-3.0.0-5.4-nts-vc9-x86.zip -y > 7z.log
- IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/apc/3.1.13/php_apc-3.1.13-5.4-nts-vc9-x86.zip
- IF %PHP%==1 7z x php_apc-3.1.13-5.4-nts-vc9-x86.zip -y > 7z.log
- IF %PHP%==1 cd ..
- IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat
- appveyor DownloadFile https://getcomposer.org/composer.phar
- copy php.ini-production php.ini /Y
- echo date.timezone="UTC" >> php.ini
- echo extension_dir=ext >> php.ini
- echo extension=php_openssl.dll >> php.ini
- IF %PHP_EXT%==1 echo extension=php_apc.dll >> php.ini
- IF %PHP_EXT%==1 echo extension=php_intl.dll >> php.ini
- IF %PHP_EXT%==1 echo extension=php_mbstring.dll >> php.ini
- IF %PHP_EXT%==1 echo extension=php_fileinfo.dll >> php.ini
- IF %PHP_EXT%==1 echo extension=php_pdo_sqlite.dll >> php.ini
- cd c:\projects\symfony
- php phpunit install
- IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev)
- composer update --prefer-dist --no-progress --ansi
test_script:
- cd c:\projects\symfony
- php phpunit symfony --exclude-group benchmark,intl-data

116
phpunit Executable file
View File

@ -0,0 +1,116 @@
#!/usr/bin/env php
<?php
error_reporting(-1);
$PHPUNIT_VERSION = 4.8;
$PHPUNIT_DIR = __DIR__.'/.phpunit';
if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit")) {
# Build a standalone phpunit without symfony/yaml
$oldPwd = getcwd();
mkdir($PHPUNIT_DIR);
chdir($PHPUNIT_DIR);
if (extension_loaded('openssl') && ini_get('allow_url_fopen')) {
stream_copy_to_stream(fopen("https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip", 'rb'), fopen("$PHPUNIT_VERSION.zip", 'wb'));
} else {
passthru("wget https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip");
}
$zip = new ZipArchive();
$zip->open("$PHPUNIT_VERSION.zip");
$zip->extractTo(getcwd());
$zip->close();
chdir("phpunit-$PHPUNIT_VERSION");
passthru("composer remove --no-update symfony/yaml");
passthru("composer install --prefer-source --no-progress --ansi");
chdir($oldPwd);
}
$cmd = array_map('escapeshellarg', $argv);
$exit = 0;
if (isset($argv[1]) && 'symfony' === $argv[1]) {
# Find Symfony components in plain php for Windows portability
$finder = new RecursiveDirectoryIterator('src/Symfony', FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::UNIX_PATHS);
$finder = new RecursiveIteratorIterator($finder);
$finder->setMaxDepth(3);
array_shift($cmd);
$cmd[0] = "php $PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit --colors=always";
$procs = array();
foreach ($finder as $file => $fileInfo) {
if ('phpunit.xml.dist' === $file) {
$component = dirname($fileInfo->getPathname());
# Run phpunit tests in parallel
$c = escapeshellarg($component);
if ($proc = proc_open(implode(' ', $cmd)." $c > $c/phpunit.stdout 2> $c/phpunit.stderr", array(), $pipes)) {
$procs[$component] = $proc;
} else {
$exit = 1;
echo "\033[41mKO\033[0m $component\n\n";
}
}
}
foreach ($procs as $component => $proc) {
$procStatus = proc_close($proc);
foreach (array('out', 'err') as $file) {
$file = "$component/phpunit.std$file";
$h = fopen($file, 'rb');
while (false !== $line = fgets($h)) {
echo preg_replace_callback(
'/\033\[[0-9]++(?:;[0-9]++)++m/',
function ($m) {return str_replace(';', "m\033[", $m[0]);},
$line
);
}
fclose($h);
unlink($file);
}
if ($procStatus) {
$exit = 1;
echo "\033[41mKO\033[0m $component\n\n";
} else {
echo "\033[32mOK\033[0m $component\n\n";
}
}
} elseif (!isset($argv[1]) || 'install' !== $argv[1]) {
# Run regular phpunit in a subprocess
$cmd[0] = "php $PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit --colors=always";
$errFile = tempnam(sys_get_temp_dir(), 'phpunit.stderr.');
if ($proc = proc_open(implode(' ', $cmd).' 2> '.escapeshellarg($errFile), array(1 => array('pipe', 'w')), $pipes)) {
while (false !== $line = fgets($pipes[1])) {
echo $line;
}
fclose($pipes[1]);
$exit = proc_close($proc);
$h = fopen($errFile, 'rb');
while (false !== $line = fgets($h)) {
echo $line;
}
fclose($h);
unlink($errFile);
}
if (file_exists($component = array_pop($argv))) {
if ($exit) {
echo "\033[41mKO\033[0m $component\n\n";
} else {
echo "\033[32mOK\033[0m $component\n\n";
}
}
}
exit($exit);

View File

@ -553,6 +553,10 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
public function testRenderExceptionWithDoubleWidthCharacters()
{
if (!function_exists('mb_strwidth')) {
$this->markTestSkipped('The "mb_strwidth" function is not available');
}
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
$application->setAutoExit(false);
$application->expects($this->any())

View File

@ -166,20 +166,43 @@ class Crawler extends \SplObjectStorage
$dom = new \DOMDocument('1.0', $charset);
$dom->validateOnParse = true;
if (function_exists('mb_convert_encoding')) {
$hasError = false;
set_error_handler(function () use (&$hasError) {
$hasError = true;
});
$tmpContent = @mb_convert_encoding($content, 'HTML-ENTITIES', $charset);
set_error_handler(function () {throw new \Exception();});
restore_error_handler();
try {
// Convert charset to HTML-entities to work around bugs in DOMDocument::loadHTML()
if (!$hasError) {
$content = $tmpContent;
if (function_exists('mb_convert_encoding')) {
$content = mb_convert_encoding($content, 'HTML-ENTITIES', $charset);
} elseif (function_exists('iconv')) {
$content = preg_replace_callback(
'/[\x80-\xFF]+/',
function ($m) {
$m = unpack('C*', $m[0]);
$i = 1;
$entities = '';
while (isset($m[$i])) {
if (0xF0 <= $m[$i]) {
$c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} elseif (0xE0 <= $m[$i]) {
$c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} else {
$c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
}
$entities .= '&#'.$c.';';
}
return $entities;
},
iconv($charset, 'UTF-8', $content)
);
}
} catch (\Exception $e) {
}
restore_error_handler();
if ('' !== trim($content)) {
@$dom->loadHTML($content);
}

View File

@ -81,6 +81,7 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
* @requires extension mbstring
*/
public function testAddHtmlContentCharset()
{
@ -115,6 +116,7 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
* @requires extension mbstring
*/
public function testAddHtmlContentCharsetGbk()
{
@ -235,7 +237,7 @@ EOF
$this->assertEquals('中文', $crawler->filterXPath('//span')->text(), '->addContent() guess wrong charset');
$crawler = new Crawler();
$crawler->addContent(mb_convert_encoding('<html><head><meta charset="Shift_JIS"></head><body>日本語</body></html>', 'SJIS', 'UTF-8'));
$crawler->addContent(iconv('UTF-8', 'SJIS', '<html><head><meta charset="Shift_JIS"></head><body>日本語</body></html>'));
$this->assertEquals('日本語', $crawler->filterXPath('//body')->text(), '->addContent() can recognize "Shift_JIS" in html5 meta charset tag');
}

View File

@ -11,24 +11,11 @@
namespace Symfony\Component\Filesystem\Tests;
use Symfony\Component\Filesystem\Filesystem;
/**
* Test class for Filesystem.
*/
class FilesystemTest extends FilesystemTestCase
{
/**
* @var \Symfony\Component\Filesystem\Filesystem
*/
private $filesystem = null;
protected function setUp()
{
parent::setUp();
$this->filesystem = new Filesystem();
}
public function testCopyCreatesNewFile()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';

View File

@ -11,29 +11,33 @@
namespace Symfony\Component\Filesystem\Tests;
use Symfony\Component\Filesystem\Filesystem;
class FilesystemTestCase extends \PHPUnit_Framework_TestCase
{
private $umask;
/**
* @var \Symfony\Component\Filesystem\Filesystem
*/
protected $filesystem = null;
/**
* @var string
*/
protected $workspace = null;
protected static $symlinkOnWindows = null;
private static $symlinkOnWindows = null;
public static function setUpBeforeClass()
{
if ('\\' === DIRECTORY_SEPARATOR) {
static::$symlinkOnWindows = true;
$originDir = tempnam(sys_get_temp_dir(), 'sl');
$targetDir = tempnam(sys_get_temp_dir(), 'sl');
if (true !== @symlink($originDir, $targetDir)) {
$report = error_get_last();
if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
static::$symlinkOnWindows = false;
}
if ('\\' === DIRECTORY_SEPARATOR && null === self::$symlinkOnWindows) {
$target = tempnam(sys_get_temp_dir(), 'sl');
$link = sys_get_temp_dir().'/sl'.microtime(true).mt_rand();
if (self::$symlinkOnWindows = @symlink($target, $link)) {
unlink($link);
}
unlink($target);
}
}
@ -43,31 +47,15 @@ class FilesystemTestCase extends \PHPUnit_Framework_TestCase
$this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().mt_rand(0, 1000);
mkdir($this->workspace, 0777, true);
$this->workspace = realpath($this->workspace);
$this->filesystem = new Filesystem();
}
protected function tearDown()
{
$this->clean($this->workspace);
$this->filesystem->remove($this->workspace);
umask($this->umask);
}
/**
* @param string $file
*/
protected function clean($file)
{
if (is_dir($file) && !is_link($file)) {
$dir = new \FilesystemIterator($file);
foreach ($dir as $childFile) {
$this->clean($childFile);
}
rmdir($file);
} else {
unlink($file);
}
}
/**
* @param int $expectedFilePerms expected file permissions as three digits (i.e. 755)
* @param string $filePath

View File

@ -60,9 +60,6 @@ class RecursiveDirectoryIteratorTest extends IteratorTestCase
$i->seek(1);
$actual[] = $i->getPathname();
$i->seek(2);
$actual[] = $i->getPathname();
$this->assertEquals($contains, $actual);
}
@ -73,7 +70,6 @@ class RecursiveDirectoryIteratorTest extends IteratorTestCase
// ftp
$contains = array(
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'index.html',
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
);
$data[] = array('ftp://ftp.mozilla.org/', false, $contains);

View File

@ -33,7 +33,11 @@ class SortableIteratorTest extends RealIteratorTestCase
if (!is_callable($mode)) {
switch ($mode) {
case SortableIterator::SORT_BY_ACCESSED_TIME :
file_get_contents(self::toAbsolute('.git'));
if ('\\' === DIRECTORY_SEPARATOR) {
touch(self::toAbsolute('.git'));
} else {
file_get_contents(self::toAbsolute('.git'));
}
sleep(1);
file_get_contents(self::toAbsolute('.bar'));
break;
@ -56,7 +60,11 @@ class SortableIteratorTest extends RealIteratorTestCase
if ($mode === SortableIterator::SORT_BY_ACCESSED_TIME
|| $mode === SortableIterator::SORT_BY_CHANGED_TIME
|| $mode === SortableIterator::SORT_BY_MODIFIED_TIME) {
|| $mode === SortableIterator::SORT_BY_MODIFIED_TIME
) {
if ('\\' === DIRECTORY_SEPARATOR && SortableIterator::SORT_BY_MODIFIED_TIME !== $mode) {
$this->markTestSkipped('Sorting by atime or ctime is not supported on Windows');
}
$this->assertOrderedIteratorForGroups($expected, $iterator);
} else {
$this->assertOrderedIterator($expected, $iterator);

View File

@ -86,7 +86,7 @@ class CommandTest extends \PHPUnit_Framework_TestCase
$cmd = Command::create()->add('--force');
$cmd->arg('--run');
$this->assertSame('--force \'--run\'', $cmd->join());
$this->assertSame('--force '.escapeshellarg('--run'), $cmd->join());
}
public function testCmd()

View File

@ -262,7 +262,7 @@ class DateType extends AbstractType
$pattern = $formatter->getPattern();
$timezone = $formatter->getTimezoneId();
if ($setTimeZone = method_exists($formatter, 'setTimeZone')) {
if ($setTimeZone = PHP_VERSION_ID >= 50500 || method_exists($formatter, 'setTimeZone')) {
$formatter->setTimeZone('UTC');
} else {
$formatter->setTimeZoneId('UTC');

View File

@ -1852,9 +1852,9 @@ class Request
return $prefix;
}
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl), '/').'/')) {
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl), '/'.DIRECTORY_SEPARATOR).'/')) {
// directory portion of $baseUrl matches
return rtrim($prefix, '/');
return rtrim($prefix, '/'.DIRECTORY_SEPARATOR);
}
$truncatedRequestUri = $requestUri;
@ -1875,7 +1875,7 @@ class Request
$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
}
return rtrim($baseUrl, '/');
return rtrim($baseUrl, '/'.DIRECTORY_SEPARATOR);
}
/**

View File

@ -54,7 +54,7 @@ class BinaryFileResponseTest extends ResponseTestCase
*/
public function testRequests($requestRange, $offset, $length, $responseRange)
{
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
// do a request to get the ETag
$request = Request::create('/');
@ -96,7 +96,7 @@ class BinaryFileResponseTest extends ResponseTestCase
*/
public function testFullFileRequests($requestRange)
{
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
// prepare a request for a range of the testing file
$request = Request::create('/');
@ -131,7 +131,7 @@ class BinaryFileResponseTest extends ResponseTestCase
*/
public function testInvalidRequests($requestRange)
{
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
// prepare a request for a range of the testing file
$request = Request::create('/');
@ -159,7 +159,7 @@ class BinaryFileResponseTest extends ResponseTestCase
$request->headers->set('X-Sendfile-Type', 'X-Sendfile');
BinaryFileResponse::trustXSendfileTypeHeader();
$response = BinaryFileResponse::create(__DIR__.'/../README.md');
$response = BinaryFileResponse::create(__DIR__.'/../README.md', 200, array('Content-Type' => 'application/octet-stream'));
$response->prepare($request);
$this->expectOutputString('');
@ -180,7 +180,7 @@ class BinaryFileResponseTest extends ResponseTestCase
$file = new FakeFile($realpath, __DIR__.'/File/Fixtures/test');
BinaryFileResponse::trustXSendfileTypeHeader();
$response = new BinaryFileResponse($file);
$response = new BinaryFileResponse($file, 200, array('Content-Type' => 'application/octet-stream'));
$reflection = new \ReflectionObject($response);
$property = $reflection->getProperty('file');
$property->setAccessible(true);
@ -211,7 +211,7 @@ class BinaryFileResponseTest extends ResponseTestCase
public function testAcceptRangeOnUnsafeMethods()
{
$request = Request::create('/', 'POST');
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif');
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
$response->prepare($request);
$this->assertEquals('none', $response->headers->get('Accept-Ranges'));
@ -220,7 +220,7 @@ class BinaryFileResponseTest extends ResponseTestCase
public function testAcceptRangeNotOverriden()
{
$request = Request::create('/', 'POST');
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif');
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
$response->headers->set('Accept-Ranges', 'foo');
$response->prepare($request);
@ -237,7 +237,7 @@ class BinaryFileResponseTest extends ResponseTestCase
protected function provideResponse()
{
return new BinaryFileResponse(__DIR__.'/../README.md');
return new BinaryFileResponse(__DIR__.'/../README.md', 200, array('Content-Type' => 'application/octet-stream'));
}
public static function tearDownAfterClass()

View File

@ -45,6 +45,9 @@ class FileTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('gif', $file->guessExtension());
}
/**
* @requires extension fileinfo
*/
public function testGuessExtensionWithReset()
{
$file = new File(__DIR__.'/Fixtures/other-file.example');

View File

@ -14,17 +14,16 @@ namespace Symfony\Component\HttpFoundation\Tests\File\MimeType;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser;
/**
* @requires extension fileinfo
*/
class MimeTypeTest extends \PHPUnit_Framework_TestCase
{
protected $path;
public function testGuessImageWithoutExtension()
{
if (extension_loaded('fileinfo')) {
$this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
} else {
$this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
}
$this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
}
public function testGuessImageWithDirectory()
@ -38,29 +37,17 @@ class MimeTypeTest extends \PHPUnit_Framework_TestCase
{
$guesser = MimeTypeGuesser::getInstance();
$guesser->register(new FileBinaryMimeTypeGuesser());
if (extension_loaded('fileinfo')) {
$this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
} else {
$this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
}
$this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
}
public function testGuessImageWithKnownExtension()
{
if (extension_loaded('fileinfo')) {
$this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
} else {
$this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
}
$this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
}
public function testGuessFileWithUnknownExtension()
{
if (extension_loaded('fileinfo')) {
$this->assertEquals('application/octet-stream', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
} else {
$this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
}
$this->assertEquals('application/octet-stream', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
}
public function testGuessWithIncorrectPath()
@ -75,7 +62,7 @@ class MimeTypeTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Can not verify chmod operations on Windows');
}
if ('root' === get_current_user()) {
if (!getenv('USER') || 'root' === getenv('USER')) {
$this->markTestSkipped('This test will fail if run under superuser');
}
@ -83,7 +70,7 @@ class MimeTypeTest extends \PHPUnit_Framework_TestCase
touch($path);
@chmod($path, 0333);
if (get_current_user() != 'root' && substr(sprintf('%o', fileperms($path)), -4) == '0333') {
if (substr(sprintf('%o', fileperms($path)), -4) == '0333') {
$this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException');
MimeTypeGuesser::getInstance()->guess($path);
} else {

View File

@ -209,7 +209,7 @@ class IntlDateFormatter
$argumentError = null;
if (!is_int($timestamp) && !$timestamp instanceof \DateTime) {
$argumentError = 'datefmt_format: takes either an array or an integer timestamp value or a DateTime object';
if (PHP_VERSION_ID >= 50500 && !is_int($timestamp)) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$argumentError = sprintf('datefmt_format: string \'%s\' is not numeric, which would be required for it to be a valid date', $timestamp);
}
}
@ -371,7 +371,7 @@ class IntlDateFormatter
}
// In PHP 5.5 default timezone depends on `date_default_timezone_get()` method
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
return date_default_timezone_get();
}
}
@ -536,7 +536,7 @@ class IntlDateFormatter
{
if (null === $timeZoneId) {
// In PHP 5.5 if $timeZoneId is null it fallbacks to `date_default_timezone_get()` method
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$timeZoneId = date_default_timezone_get();
} else {
// TODO: changes were made to ext/intl in PHP 5.4.4 release that need to be investigated since it will
@ -563,8 +563,16 @@ class IntlDateFormatter
try {
$this->dateTimeZone = new \DateTimeZone($timeZoneId);
if ('GMT' !== $timeZoneId && $this->dateTimeZone->getName() !== $timeZoneId) {
$timeZoneId = $timeZone = $this->getTimeZoneId();
}
} catch (\Exception $e) {
$this->dateTimeZone = new \DateTimeZone('UTC');
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$timeZoneId = $timeZone = $this->getTimeZoneId();
} else {
$timeZoneId = 'UTC';
}
$this->dateTimeZone = new \DateTimeZone($timeZoneId);
}
$this->timeZoneId = $timeZone;
@ -630,7 +638,7 @@ class IntlDateFormatter
if (self::NONE !== $this->timetype) {
$patternParts[] = $this->defaultTimeFormats[$this->timetype];
}
$pattern = implode(' ', $patternParts);
$pattern = implode(', ', $patternParts);
return $pattern;
}

View File

@ -538,22 +538,30 @@ class NumberFormatter
return false;
}
preg_match('/^([^0-9\-\.]{0,})(.*)/', $value, $matches);
$groupSep = $this->getAttribute(self::GROUPING_USED) ? ',' : '';
// Any string before the numeric value causes error in the parsing
if (isset($matches[1]) && !empty($matches[1])) {
if (preg_match("/^-?(?:\.\d++|([\d{$groupSep}]++)(?:\.\d++)?)/", $value, $matches)) {
$value = $matches[0];
$position = strlen($value);
if ($error = $groupSep && isset($matches[1]) && !preg_match('/^\d{1,3}+(?:(?:,\d{3})++|\d*+)$/', $matches[1])) {
$position -= strlen(preg_replace('/^\d{1,3}+(?:(?:,\d++)++|\d*+)/', '', $matches[1]));
}
} else {
$error = 1;
$position = 0;
}
if ($error) {
IntlGlobals::setError(IntlGlobals::U_PARSE_ERROR, 'Number parsing failed');
$this->errorCode = IntlGlobals::getErrorCode();
$this->errorMessage = IntlGlobals::getErrorMessage();
$position = 0;
return false;
}
preg_match('/^[0-9\-\.\,]*/', $value, $matches);
$value = preg_replace('/[^0-9\.\-]/', '', $matches[0]);
$value = str_replace(',', '', $value);
$value = $this->convertValueDataType($value, $type);
$position = strlen($matches[0]);
// behave like the intl extension
$this->resetError();

View File

@ -38,11 +38,16 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
$formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT);
// In PHP 5.5 default timezone depends on `date_default_timezone_get()` method
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->assertEquals(date_default_timezone_get(), $formatter->getTimeZoneId());
} else {
$this->assertNull($formatter->getTimeZoneId());
}
$this->assertEquals(
$this->getDateTime(0, $formatter->getTimeZoneId())->format('M j, Y, g:i A'),
$formatter->format(0)
);
}
/**
@ -267,7 +272,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function formatErrorProvider()
{
// With PHP 5.5 IntlDateFormatter accepts empty values ('0')
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
return array(
array('y-M-d', 'foobar', 'datefmt_format: string \'foobar\' is not numeric, which would be required for it to be a valid date: U_ILLEGAL_ARGUMENT_ERROR'),
);
@ -320,7 +325,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
);
// As of PHP 5.5, intl ext no longer fallbacks invalid time zones to UTC
if (PHP_VERSION_ID < 50500) {
if (PHP_VERSION_ID < 50500 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
// When time zone not exists, uses UTC by default
$data[] = array(0, 'Foo/Bar', '1970-01-01 00:00:00');
$data[] = array(0, 'UTC+04:30', '1970-01-01 00:00:00');
@ -334,7 +339,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter('zzzz');
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone('GMT+03:00');
} else {
$formatter->setTimeZoneId('GMT+03:00');
@ -347,7 +352,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter('zzzz');
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone('GMT+00:30');
} else {
$formatter->setTimeZoneId('GMT+00:30');
@ -360,7 +365,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter('zzzz');
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone('Pacific/Fiji');
} else {
$formatter->setTimeZoneId('Pacific/Fiji');
@ -397,7 +402,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormatWithIntlTimeZone()
{
if (PHP_VERSION_ID < 50500) {
if (PHP_VERSION_ID < 50500 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->markTestSkipped('Only in PHP 5.5+ IntlDateFormatter allows to use DateTimeZone objects.');
}
@ -412,7 +417,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormatWithTimezoneFromEnvironmentVariable()
{
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->markTestSkipped('IntlDateFormatter in PHP 5.5 no longer depends on TZ environment.');
}
@ -435,7 +440,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormatWithTimezoneFromPhp()
{
if (PHP_VERSION_ID < 50500) {
if (PHP_VERSION_ID < 50500 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->markTestSkipped('Only in PHP 5.5 IntlDateFormatter depends on default timezone (`date_default_timezone_get()`).');
}
@ -866,7 +871,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter();
if (PHP_VERSION_ID >= 50500) {
if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone($timeZoneId);
} else {
$formatter->setTimeZoneId($timeZoneId);
@ -877,15 +882,17 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function setTimeZoneIdProvider()
{
$isPhp55 = PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'));
return array(
array('UTC', 'UTC'),
array('GMT', 'GMT'),
array('GMT-03:00', 'GMT-03:00'),
array('Europe/Zurich', 'Europe/Zurich'),
array('GMT-0300', 'GMT-0300'),
array('Foo/Bar', 'Foo/Bar'),
array('GMT+00:AA', 'GMT+00:AA'),
array('GMT+00AA', 'GMT+00AA'),
array(null, $isPhp55 ? date_default_timezone_get() : null),
array('Foo/Bar', $isPhp55 ? 'UTC' : 'Foo/Bar'),
array('GMT+00:AA', $isPhp55 ? 'UTC' : 'GMT+00:AA'),
array('GMT+00AA', $isPhp55 ? 'UTC' : 'GMT+00AA'),
);
}
@ -898,7 +905,9 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$dateTime = new \DateTime();
$dateTime->setTimestamp(null === $timestamp ? time() : $timestamp);
$dateTime->setTimezone(new \DateTimeZone($timeZone));
if (null !== $timeZone) {
$dateTime->setTimezone(new \DateTimeZone($timeZone));
}
return $dateTime;
}

View File

@ -45,7 +45,11 @@ class IntlDateFormatterTest extends AbstractIntlDateFormatterTest
protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null)
{
return new \IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern);
if (!$formatter = new \IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern)) {
throw new \InvalidArgumentException(intl_get_error_message());
}
return $formatter;
}
protected function getIntlErrorMessage()

View File

@ -602,10 +602,11 @@ abstract class AbstractNumberFormatterTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider parseProvider
*/
public function testParse($value, $expected, $message, $expectedPosition)
public function testParse($value, $expected, $message, $expectedPosition, $groupingUsed = true)
{
$position = 0;
$formatter = $this->getNumberFormatter('en', NumberFormatter::DECIMAL);
$formatter->setAttribute(NumberFormatter::GROUPING_USED, $groupingUsed);
$parsedValue = $formatter->parse($value, NumberFormatter::TYPE_DOUBLE, $position);
$this->assertSame($expected, $parsedValue, $message);
$this->assertSame($expectedPosition, $position, $message);
@ -631,6 +632,11 @@ abstract class AbstractNumberFormatterTest extends \PHPUnit_Framework_TestCase
return array(
array('prefix1', false, '->parse() does not parse a number with a string prefix.', 0),
array('1.4suffix', (float) 1.4, '->parse() parses a number with a string suffix.', 3),
array('-.4suffix', (float) -0.4, '->parse() parses a negative dot float with suffix.', 3),
array('-123,4', false, '->parse() does not parse when invalid grouping used.', 6),
array('-1234,567', false, '->parse() does not parse when invalid grouping used.', 5),
array('-123,,456', false, '->parse() does not parse when invalid grouping used.', 4),
array('-123,,456', -123.0, '->parse() parses when grouping is disabled.', 4, false),
);
}

View File

@ -637,8 +637,10 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(1);"');
$process->start();
$this->assertFalse($process->isSuccessful());
while ($process->isRunning()) {
$this->assertFalse($process->isSuccessful());
usleep(300000);
}

View File

@ -33,7 +33,7 @@ abstract class AbstractToken implements TokenInterface
/**
* Constructor.
*
* @param RoleInterface[] $roles An array of roles
* @param RoleInterface[]|string[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
use Symfony\Component\Security\Core\Role\RoleInterface;
/**
* PreAuthenticatedToken implements a pre-authenticated token.
*
@ -23,6 +25,11 @@ class PreAuthenticatedToken extends AbstractToken
/**
* Constructor.
*
* @param string|object $user The user
* @param mixed $credentials The user credentials
* @param string $providerKey The provider key
* @param RoleInterface[]|string[] $roles An array of roles
*/
public function __construct($user, $credentials, $providerKey, array $roles = array())
{

View File

@ -45,23 +45,25 @@ class LengthValidator extends ConstraintValidator
$charset = 'UTF-8';
}
if (function_exists('iconv_strlen')) {
$length = @iconv_strlen($stringValue, $constraint->charset);
$invalidCharset = false === $length;
if ('UTF-8' === $charset) {
if (!preg_match('//u', $stringValue)) {
$invalidCharset = true;
} elseif (function_exists('utf8_decode')) {
$length = strlen(utf8_decode($stringValue));
} else {
preg_replace('/./u', '', $stringValue, -1, $length);
}
} elseif (function_exists('mb_strlen')) {
if (mb_check_encoding($stringValue, $constraint->charset)) {
if (@mb_check_encoding($stringValue, $constraint->charset)) {
$length = mb_strlen($stringValue, $constraint->charset);
} else {
$invalidCharset = true;
}
} elseif ('UTF-8' !== $charset) {
$length = strlen($stringValue);
} elseif (!preg_match('//u', $stringValue)) {
$invalidCharset = true;
} elseif (function_exists('utf8_decode')) {
$length = strlen(utf8_decode($stringValue));
} elseif (function_exists('iconv_strlen')) {
$length = @iconv_strlen($stringValue, $constraint->charset);
$invalidCharset = false === $length;
} else {
preg_replace('/./u', '', $stringValue, -1, $length);
$length = strlen($stringValue);
}
if ($invalidCharset) {

View File

@ -15,6 +15,9 @@ use Symfony\Component\Validator\Constraints\Image;
use Symfony\Component\Validator\Constraints\ImageValidator;
use Symfony\Component\Validator\Validation;
/**
* @requires extension fileinfo
*/
class ImageValidatorTest extends AbstractConstraintValidatorTest
{
protected $context;