Merge branch '2.3' into 2.4
* 2.3: [Process] minor fixes Improve performance of getNextEmbedBlock by removing unnecessary preg_match and function calls. Avoid unnecessary line indentation calculation. Optimise Inline::evaluateScalar() for parsing strings. fixed CS fixed parsing Mongo DSN and added Test for it () is also a valid delimiter Adding PHP 5.6 to travis-ci tests Update BCryptPasswordEncoder.php [Validator] Removed PHP <5.3.3 specific code which is not officially supported. Fixed wrong redirect url if path contains some query parameters
This commit is contained in:
commit
81e27d2a3e
@ -5,6 +5,7 @@ php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
|
@ -100,7 +100,11 @@ class RedirectController extends ContainerAware
|
||||
|
||||
$qs = $request->getQueryString();
|
||||
if ($qs) {
|
||||
$qs = '?'.$qs;
|
||||
if (strpos($path, '?') === false) {
|
||||
$qs = '?'.$qs;
|
||||
} else {
|
||||
$qs = '&'.$qs;
|
||||
}
|
||||
}
|
||||
|
||||
$port = '';
|
||||
|
@ -199,7 +199,36 @@ class RedirectControllerTest extends TestCase
|
||||
$this->assertRedirectUrl($returnValue, $expectedUrl);
|
||||
}
|
||||
|
||||
private function createRequestObject($scheme, $host, $port, $baseUrl)
|
||||
public function pathQueryParamsProvider()
|
||||
{
|
||||
return array(
|
||||
array('http://www.example.com/base/redirect-path', '/redirect-path', ''),
|
||||
array('http://www.example.com/base/redirect-path?foo=bar', '/redirect-path?foo=bar', ''),
|
||||
array('http://www.example.com/base/redirect-path?foo=bar', '/redirect-path', 'foo=bar'),
|
||||
array('http://www.example.com/base/redirect-path?foo=bar&abc=example', '/redirect-path?foo=bar', 'abc=example'),
|
||||
array('http://www.example.com/base/redirect-path?foo=bar&abc=example&baz=def', '/redirect-path?foo=bar', 'abc=example&baz=def'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider pathQueryParamsProvider
|
||||
*/
|
||||
public function testPathQueryParams($expectedUrl, $path, $queryString)
|
||||
{
|
||||
$scheme = 'http';
|
||||
$host = 'www.example.com';
|
||||
$baseUrl = '/base';
|
||||
$port = 80;
|
||||
|
||||
$request = $this->createRequestObject($scheme, $host, $port, $baseUrl, $queryString);
|
||||
|
||||
$controller = $this->createRedirectController();
|
||||
|
||||
$returnValue = $controller->urlRedirectAction($request, $path, false, $scheme, $port, null);
|
||||
$this->assertRedirectUrl($returnValue, $expectedUrl);
|
||||
}
|
||||
|
||||
private function createRequestObject($scheme, $host, $port, $baseUrl, $queryString = '')
|
||||
{
|
||||
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
|
||||
$request
|
||||
@ -218,6 +247,10 @@ class RedirectControllerTest extends TestCase
|
||||
->expects($this->any())
|
||||
->method('getBaseUrl')
|
||||
->will($this->returnValue($baseUrl));
|
||||
$request
|
||||
->expects($this->any())
|
||||
->method('getQueryString')
|
||||
->will($this->returnValue($queryString));
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
@ -65,7 +65,11 @@ class Regex implements ValueInterface
|
||||
$start = substr($m[1], 0, 1);
|
||||
$end = substr($m[1], -1);
|
||||
|
||||
if (($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start)) || ($start === '{' && $end === '}')) {
|
||||
if (
|
||||
($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
|
||||
|| ($start === '{' && $end === '}')
|
||||
|| ($start === '(' && $end === ')')
|
||||
) {
|
||||
return new self(substr($m[1], 1, -1), $m[2], $end);
|
||||
}
|
||||
}
|
||||
|
@ -99,21 +99,19 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface
|
||||
*/
|
||||
protected function getMongo()
|
||||
{
|
||||
if ($this->mongo === null) {
|
||||
if (preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $this->dsn, $matches)) {
|
||||
$server = $matches[1].(!empty($matches[2]) ? '/'.$matches[2] : '');
|
||||
$database = $matches[2];
|
||||
$collection = $matches[3];
|
||||
|
||||
$mongoClass = (version_compare(phpversion('mongo'), '1.3.0', '<')) ? '\Mongo' : '\MongoClient';
|
||||
$mongo = new $mongoClass($server);
|
||||
$this->mongo = $mongo->selectCollection($database, $collection);
|
||||
} else {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"', $this->dsn));
|
||||
}
|
||||
if (null !== $this->mongo) {
|
||||
return $this->mongo;
|
||||
}
|
||||
|
||||
return $this->mongo;
|
||||
if (!$parsedDsn = $this->parseDsn($this->dsn)) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"', $this->dsn));
|
||||
}
|
||||
|
||||
list($server, $database, $collection) = $parsedDsn;
|
||||
$mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? '\Mongo' : '\MongoClient';
|
||||
$mongo = new $mongoClass($server);
|
||||
|
||||
return $this->mongo = $mongo->selectCollection($database, $collection);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,4 +231,27 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dsn
|
||||
*
|
||||
* @return null|array Array($server, $database, $collection)
|
||||
*/
|
||||
private function parseDsn($dsn)
|
||||
{
|
||||
if (!preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $dsn, $matches)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$server = $matches[1];
|
||||
$database = $matches[2];
|
||||
$collection = $matches[3];
|
||||
preg_match('#^mongodb://(([^:]+):?(.*)(?=@))?@?([^/]*)(.*)$#', $server, $matchesServer);
|
||||
|
||||
if ('' == $matchesServer[5] && '' != $matches[2]) {
|
||||
$server .= '/'.$matches[2];
|
||||
}
|
||||
|
||||
return array($server, $database, $collection);
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,32 @@ class MongoDbProfilerStorageTest extends AbstractProfilerStorageTest
|
||||
}
|
||||
}
|
||||
|
||||
public function getDsns()
|
||||
{
|
||||
return array(
|
||||
array('mongodb://localhost/symfony_tests/profiler_data', array(
|
||||
'mongodb://localhost/symfony_tests',
|
||||
'symfony_tests',
|
||||
'profiler_data'
|
||||
)),
|
||||
array('mongodb://user:password@localhost/symfony_tests/profiler_data', array(
|
||||
'mongodb://user:password@localhost/symfony_tests',
|
||||
'symfony_tests',
|
||||
'profiler_data'
|
||||
)),
|
||||
array('mongodb://user:password@localhost/admin/symfony_tests/profiler_data', array(
|
||||
'mongodb://user:password@localhost/admin',
|
||||
'symfony_tests',
|
||||
'profiler_data'
|
||||
)),
|
||||
array('mongodb://user:password@localhost:27009,localhost:27010/?replicaSet=rs-name&authSource=admin/symfony_tests/profiler_data', array(
|
||||
'mongodb://user:password@localhost:27009,localhost:27010/?replicaSet=rs-name&authSource=admin',
|
||||
'symfony_tests',
|
||||
'profiler_data'
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
public function testCleanup()
|
||||
{
|
||||
$dt = new \DateTime('-2 day');
|
||||
@ -87,6 +113,17 @@ class MongoDbProfilerStorageTest extends AbstractProfilerStorageTest
|
||||
self::$storage->purge();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getDsns
|
||||
*/
|
||||
public function testDsnParser($dsn, $expected)
|
||||
{
|
||||
$m = new \ReflectionMethod(self::$storage, 'parseDsn');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$this->assertEquals($expected, $m->invoke(self::$storage, $dsn));
|
||||
}
|
||||
|
||||
public function testUtf8()
|
||||
{
|
||||
$profile = new Profile('utf8_test_profile');
|
||||
|
@ -865,7 +865,9 @@ class Process
|
||||
public function setEnv(array $env)
|
||||
{
|
||||
// Process can not handle env values that are arrays
|
||||
$env = array_filter($env, function ($value) { if (!is_array($value)) { return true; } });
|
||||
$env = array_filter($env, function ($value) {
|
||||
return !is_array($value);
|
||||
});
|
||||
|
||||
$this->env = array();
|
||||
foreach ($env as $key => $value) {
|
||||
@ -1117,6 +1119,7 @@ class Process
|
||||
* Reads pipes, executes callback.
|
||||
*
|
||||
* @param Boolean $blocking Whether to use blocking calls or not.
|
||||
* @param Boolean $close Whether to close file handles or not.
|
||||
*/
|
||||
private function readPipes($blocking, $close)
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ class ProcessPipes
|
||||
public function close()
|
||||
{
|
||||
$this->closeUnixPipes();
|
||||
foreach ($this->fileHandles as $offset => $handle) {
|
||||
foreach ($this->fileHandles as $handle) {
|
||||
fclose($handle);
|
||||
}
|
||||
$this->fileHandles = array();
|
||||
@ -218,6 +218,8 @@ class ProcessPipes
|
||||
/**
|
||||
* Reads data in file handles.
|
||||
*
|
||||
* @param Boolean $close Whether to close file handles or not.
|
||||
*
|
||||
* @return array An array of read data indexed by their fd.
|
||||
*/
|
||||
private function readFileHandles($close = false)
|
||||
@ -253,6 +255,7 @@ class ProcessPipes
|
||||
* Reads data in file pipes streams.
|
||||
*
|
||||
* @param Boolean $blocking Whether to use blocking calls or not.
|
||||
* @param Boolean $close Whether to close file handles or not.
|
||||
*
|
||||
* @return array An array of read data indexed by their fd.
|
||||
*/
|
||||
|
@ -29,6 +29,7 @@ class BCryptPasswordEncoder extends BasePasswordEncoder
|
||||
*
|
||||
* @param integer $cost The algorithmic cost that should be used
|
||||
*
|
||||
* @throws \RuntimeException When no BCrypt encoder is available
|
||||
* @throws \InvalidArgumentException if cost is out of range
|
||||
*/
|
||||
public function __construct($cost)
|
||||
|
@ -386,51 +386,55 @@ class Inline
|
||||
private static function evaluateScalar($scalar)
|
||||
{
|
||||
$scalar = trim($scalar);
|
||||
|
||||
$scalarLower = strtolower($scalar);
|
||||
switch (true) {
|
||||
case 'null' == strtolower($scalar):
|
||||
case 'null' == $scalarLower:
|
||||
case '' == $scalar:
|
||||
case '~' == $scalar:
|
||||
return null;
|
||||
case 0 === strpos($scalar, '!str'):
|
||||
return (string) substr($scalar, 5);
|
||||
case 0 === strpos($scalar, '! '):
|
||||
return intval(self::parseScalar(substr($scalar, 2)));
|
||||
case 0 === strpos($scalar, '!!php/object:'):
|
||||
if (self::$objectSupport) {
|
||||
return unserialize(substr($scalar, 13));
|
||||
}
|
||||
|
||||
if (self::$exceptionOnInvalidType) {
|
||||
throw new ParseException('Object support when parsing a YAML file has been disabled.');
|
||||
}
|
||||
|
||||
return null;
|
||||
case ctype_digit($scalar):
|
||||
$raw = $scalar;
|
||||
$cast = intval($scalar);
|
||||
|
||||
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
|
||||
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
|
||||
$raw = $scalar;
|
||||
$cast = intval($scalar);
|
||||
|
||||
return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
|
||||
case 'true' === strtolower($scalar):
|
||||
case 'true' === $scalarLower:
|
||||
return true;
|
||||
case 'false' === strtolower($scalar):
|
||||
case 'false' === $scalarLower:
|
||||
return false;
|
||||
case is_numeric($scalar):
|
||||
return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
|
||||
case 0 == strcasecmp($scalar, '.inf'):
|
||||
case 0 == strcasecmp($scalar, '.NaN'):
|
||||
return -log(0);
|
||||
case 0 == strcasecmp($scalar, '-.inf'):
|
||||
return log(0);
|
||||
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
|
||||
return floatval(str_replace(',', '', $scalar));
|
||||
case preg_match(self::getTimestampRegex(), $scalar):
|
||||
return strtotime($scalar);
|
||||
// Optimise for returning strings.
|
||||
case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
|
||||
switch (true) {
|
||||
case 0 === strpos($scalar, '!str'):
|
||||
return (string) substr($scalar, 5);
|
||||
case 0 === strpos($scalar, '! '):
|
||||
return intval(self::parseScalar(substr($scalar, 2)));
|
||||
case 0 === strpos($scalar, '!!php/object:'):
|
||||
if (self::$objectSupport) {
|
||||
return unserialize(substr($scalar, 13));
|
||||
}
|
||||
|
||||
if (self::$exceptionOnInvalidType) {
|
||||
throw new ParseException('Object support when parsing a YAML file has been disabled.');
|
||||
}
|
||||
|
||||
return null;
|
||||
case ctype_digit($scalar):
|
||||
$raw = $scalar;
|
||||
$cast = intval($scalar);
|
||||
|
||||
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
|
||||
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
|
||||
$raw = $scalar;
|
||||
$cast = intval($scalar);
|
||||
|
||||
return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
|
||||
case is_numeric($scalar):
|
||||
return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
|
||||
case 0 == strcasecmp($scalar, '.inf'):
|
||||
case 0 == strcasecmp($scalar, '.NaN'):
|
||||
return -log(0);
|
||||
case 0 == strcasecmp($scalar, '-.inf'):
|
||||
return log(0);
|
||||
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
|
||||
return floatval(str_replace(',', '', $scalar));
|
||||
case preg_match(self::getTimestampRegex(), $scalar):
|
||||
return strtotime($scalar);
|
||||
}
|
||||
default:
|
||||
return (string) $scalar;
|
||||
}
|
||||
|
@ -312,7 +312,9 @@ class Parser
|
||||
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
|
||||
|
||||
while ($this->moveToNextLine()) {
|
||||
if ($this->getCurrentLineIndentation() === $newIndent) {
|
||||
$indent = $this->getCurrentLineIndentation();
|
||||
|
||||
if ($indent === $newIndent) {
|
||||
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
|
||||
}
|
||||
|
||||
@ -321,20 +323,16 @@ class Parser
|
||||
break;
|
||||
}
|
||||
|
||||
if ($removeComments && $this->isCurrentLineEmpty() || $this->isCurrentLineBlank()) {
|
||||
if ($this->isCurrentLineBlank()) {
|
||||
$data[] = substr($this->currentLine, $newIndent);
|
||||
}
|
||||
|
||||
if ($this->isCurrentLineBlank()) {
|
||||
$data[] = substr($this->currentLine, $newIndent);
|
||||
continue;
|
||||
}
|
||||
|
||||
$indent = $this->getCurrentLineIndentation();
|
||||
if ($removeComments && $this->isCurrentLineComment()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (preg_match('#^(?P<text> *)$#', $this->currentLine, $match)) {
|
||||
// empty line
|
||||
$data[] = $match['text'];
|
||||
} elseif ($indent >= $newIndent) {
|
||||
if ($indent >= $newIndent) {
|
||||
$data[] = substr($this->currentLine, $newIndent);
|
||||
} elseif (0 == $indent) {
|
||||
$this->moveToPreviousLine();
|
||||
|
Reference in New Issue
Block a user