Skip to content

Commit a9d582d

Browse files
committed
Merge branch '5.2' into 5.x
* 5.2: make fabbot happy use correct spelling when accessing the SMTP php.ini value Fix issue 40507: Tabs as separators between tokens [Cache] phpredis: Added full TLS support for RedisCluster [DependencyInjection][AliasDeprecatedPublicServicesPass] Noop when the service is private
2 parents abeb8e4 + 546f3b6 commit a9d582d

File tree

8 files changed

+121
-33
lines changed

8 files changed

+121
-33
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Traits;
13+
14+
/**
15+
* This file acts as a wrapper to the \RedisCluster implementation so it can accept the same type of calls as
16+
* individual \Redis objects.
17+
*
18+
* Calls are made to individual nodes via: RedisCluster->{method}($host, ...args)'
19+
* according to https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#directed-node-commands
20+
*
21+
* @author Jack Thomas <[email protected]>
22+
*
23+
* @internal
24+
*/
25+
class RedisClusterNodeProxy
26+
{
27+
private $host;
28+
private $redis;
29+
30+
/**
31+
* @param \RedisCluster|RedisClusterProxy $redis
32+
*/
33+
public function __construct(array $host, $redis)
34+
{
35+
$this->host = $host;
36+
$this->redis = $redis;
37+
}
38+
39+
public function __call(string $method, array $args)
40+
{
41+
return $this->redis->{$method}($this->host, ...$args);
42+
}
43+
44+
public function scan(&$iIterator, $strPattern = null, $iCount = null)
45+
{
46+
return $this->redis->scan($iIterator, $this->host, $strPattern, $iCount);
47+
}
48+
}

src/Symfony/Component/Cache/Traits/RedisTrait.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ trait RedisTrait
4242
'redis_sentinel' => null,
4343
'dbindex' => 0,
4444
'failover' => 'none',
45+
'ssl' => null, // see https://php.net/context.ssl
4546
];
4647
private $redis;
4748
private $marshaller;
@@ -202,7 +203,7 @@ public static function createConnection($dsn, array $options = [])
202203
}
203204

204205
try {
205-
@$redis->{$connect}($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout']);
206+
@$redis->{$connect}($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ['stream' => $params['ssl'] ?? null]);
206207

207208
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
208209
$isConnected = $redis->isConnected();
@@ -265,7 +266,7 @@ public static function createConnection($dsn, array $options = [])
265266
}
266267

267268
try {
268-
$redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], (bool) $params['persistent'], $params['auth'] ?? '');
269+
$redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], (bool) $params['persistent'], $params['auth'] ?? '', $params['ssl'] ?? null);
269270
} catch (\RedisClusterException $e) {
270271
throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage());
271272
}
@@ -311,7 +312,7 @@ public static function createConnection($dsn, array $options = [])
311312
}
312313
$params['exceptions'] = false;
313314

314-
$redis = new $class($hosts, array_diff_key($params, self::$defaultConnectionOptions));
315+
$redis = new $class($hosts, array_diff_key($params, array_diff_key(self::$defaultConnectionOptions, ['ssl' => null])));
315316
if (isset($params['redis_sentinel'])) {
316317
$redis->getConnection()->setSentinelTimeout($params['timeout']);
317318
}
@@ -558,8 +559,7 @@ private function getHosts(): array
558559
} elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
559560
$hosts = [];
560561
foreach ($this->redis->_masters() as $host) {
561-
$hosts[] = $h = new \Redis();
562-
$h->connect($host[0], $host[1]);
562+
$hosts[] = new RedisClusterNodeProxy($host, $this->redis);
563563
}
564564
}
565565

src/Symfony/Component/DependencyInjection/Compiler/AliasDeprecatedPublicServicesPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function process(ContainerBuilder $container)
5858

5959
$definition = $container->getDefinition($id);
6060
if (!$definition->isPublic() || $definition->isPrivate()) {
61-
throw new InvalidArgumentException(sprintf('The "%s" service is private: it cannot have the "%s" tag.', $id, $this->tagName));
61+
continue;
6262
}
6363

6464
$container

src/Symfony/Component/DependencyInjection/Tests/Compiler/AliasDeprecatedPublicServicesPassTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,13 @@ public function processWithMissingAttributeProvider()
5959

6060
public function testProcessWithNonPublicService()
6161
{
62-
$this->expectException(InvalidArgumentException::class);
63-
$this->expectExceptionMessage('The "foo" service is private: it cannot have the "container.private" tag.');
64-
6562
$container = new ContainerBuilder();
6663
$container
6764
->register('foo')
6865
->addTag('container.private', ['package' => 'foo/bar', 'version' => '1.2']);
6966

7067
(new AliasDeprecatedPublicServicesPass())->process($container);
68+
69+
$this->assertTrue($container->hasDefinition('foo'));
7170
}
7271
}

src/Symfony/Component/Mailer/Tests/Transport/NativeTransportFactoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public function testCreate(string $dsn, string $sendmailPath, string $smtp, stri
111111
{
112112
self::$fakeConfiguration = [
113113
'sendmail_path' => $sendmailPath,
114-
'smtp' => $smtp,
114+
'SMTP' => $smtp,
115115
'smtp_port' => $smtpPort,
116116
];
117117

src/Symfony/Component/Mailer/Transport/NativeTransportFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function create(Dsn $dsn): TransportInterface
3939

4040
// Only for windows hosts; at this point non-windows
4141
// host have already thrown an exception or returned a transport
42-
$host = ini_get('smtp');
42+
$host = ini_get('SMTP');
4343
$port = (int) ini_get('smtp_port');
4444

4545
if (!$host || !$port) {

src/Symfony/Component/Yaml/Parser.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ private function doParse(string $value, int $flags)
212212
array_pop($this->refsBeingParsed);
213213
}
214214
} elseif (
215-
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:( ++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
215+
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(( |\t)++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
216216
&& (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"]))
217217
) {
218218
if ($context && 'sequence' == $context) {
@@ -230,7 +230,7 @@ private function doParse(string $value, int $flags)
230230
}
231231

232232
if (!\is_string($key) && !\is_int($key)) {
233-
throw new ParseException(sprintf('%s keys are not supported. Quote your evaluable mapping keys instead.', is_numeric($key) ? 'Numeric' : 'Non-string'), $this->getRealCurrentLineNb() + 1, $this->currentLine);
233+
throw new ParseException((is_numeric($key) ? 'Numeric' : 'Non-string').' keys are not supported. Quote your evaluable mapping keys instead.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
234234
}
235235

236236
// Convert float keys to strings, to avoid being converted to integers by PHP
@@ -245,7 +245,7 @@ private function doParse(string $value, int $flags)
245245
$refName = substr(rtrim($values['value']), 1);
246246
if (!\array_key_exists($refName, $this->refs)) {
247247
if (false !== $pos = array_search($refName, $this->refsBeingParsed, true)) {
248-
throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $refName, $refName), $this->currentLineNb + 1, $this->currentLine, $this->filename);
248+
throw new ParseException(sprintf('Circular reference [%s] detected for reference "%s".', implode(', ', array_merge(\array_slice($this->refsBeingParsed, $pos), [$refName])), $refName), $this->currentLineNb + 1, $this->currentLine, $this->filename);
249249
}
250250

251251
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
@@ -732,7 +732,7 @@ private function parseValue(string $value, int $flags, string $context)
732732

733733
if (!\array_key_exists($value, $this->refs)) {
734734
if (false !== $pos = array_search($value, $this->refsBeingParsed, true)) {
735-
throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $value, $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
735+
throw new ParseException(sprintf('Circular reference [%s] detected for reference "%s".', implode(', ', array_merge(\array_slice($this->refsBeingParsed, $pos), [$value])), $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
736736
}
737737

738738
throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
@@ -1225,7 +1225,7 @@ private function lexInlineQuotedString(int &$cursor = 0): string
12251225
}
12261226
} while ($this->moveToNextLine());
12271227

1228-
throw new ParseException('Malformed inline YAML string');
1228+
throw new ParseException('Malformed inline YAML string.');
12291229
}
12301230

12311231
private function lexUnquotedString(int &$cursor): string
@@ -1296,7 +1296,7 @@ private function lexInlineStructure(int &$cursor, string $closingTag): string
12961296
}
12971297
} while ($this->moveToNextLine());
12981298

1299-
throw new ParseException('Malformed inline YAML string');
1299+
throw new ParseException('Malformed inline YAML string.');
13001300
}
13011301

13021302
private function consumeWhitespaces(int &$cursor): bool

src/Symfony/Component/Yaml/Tests/ParserTest.php

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,67 @@ public function getNonStringMappingKeysData()
5252
return $this->loadTestsFromFixtureFiles('nonStringKeys.yml');
5353
}
5454

55-
public function testTabsInYaml()
55+
/**
56+
* @dataProvider invalidIndentation
57+
*/
58+
public function testTabsAsIndentationInYaml(string $given, string $expectedMessage)
5659
{
57-
// test tabs in YAML
58-
$yamls = [
59-
"foo:\n bar",
60-
"foo:\n bar",
61-
"foo:\n bar",
62-
"foo:\n bar",
60+
$this->expectException(ParseException::class);
61+
$this->expectExceptionMessage($expectedMessage);
62+
$this->parser->parse($given);
63+
}
64+
65+
public function invalidIndentation(): array
66+
{
67+
return [
68+
[
69+
"foo:\n\tbar",
70+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\tbar\").",
71+
],
72+
[
73+
"foo:\n \tbar",
74+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\tbar\").",
75+
],
76+
[
77+
"foo:\n\t bar",
78+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\t bar\").",
79+
],
80+
[
81+
"foo:\n \t bar",
82+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\t bar\").",
83+
],
6384
];
85+
}
6486

65-
foreach ($yamls as $yaml) {
66-
try {
67-
$this->parser->parse($yaml);
87+
/**
88+
* @dataProvider validTokenSeparators
89+
*/
90+
public function testValidTokenSeparation(string $given, array $expected)
91+
{
92+
$actual = $this->parser->parse($given);
93+
$this->assertEquals($expected, $actual);
94+
}
6895

69-
$this->fail('YAML files must not contain tabs');
70-
} catch (\Exception $e) {
71-
$this->assertInstanceOf(\Exception::class, $e, 'YAML files must not contain tabs');
72-
$this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
73-
}
74-
}
96+
public function validTokenSeparators(): array
97+
{
98+
return [
99+
[
100+
'foo: bar',
101+
['foo' => 'bar'],
102+
],
103+
[
104+
"foo:\tbar",
105+
['foo' => 'bar'],
106+
],
107+
[
108+
"foo: \tbar",
109+
['foo' => 'bar'],
110+
],
111+
[
112+
"foo:\t bar",
113+
['foo' => 'bar'],
114+
],
115+
];
75116
}
76117

77118
public function testEndOfTheDocumentMarker()

0 commit comments

Comments
 (0)