Skip to content

Commit

Permalink
Merge branch '5.4' into 6.3
Browse files Browse the repository at this point in the history
* 5.4:
  fix tests
  Remove full DSNs from exception messages
  [Yaml] Fix uid binary parsing
  [HttpKernel] Preventing error 500 when function putenv is disabled
  [PasswordHasher][Tests] Do not invoke methods with additional arguments in tests
  remove invalid group
  Fix block scalar array parsing
  • Loading branch information
xabbuh committed Nov 6, 2023
2 parents e8ce12a + 5c949c1 commit 01efac5
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ public function testTranslationFileIsValid($filePath)

/**
* @dataProvider provideTranslationFiles
*
* @group Legacy
*/
public function testTranslationFileIsValidWithoutEntityLoader($filePath)
{
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Component/HttpKernel/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,9 @@ private function preBoot(): ContainerInterface
$this->startTime = microtime(true);
}
if ($this->debug && !isset($_ENV['SHELL_VERBOSITY']) && !isset($_SERVER['SHELL_VERBOSITY'])) {
putenv('SHELL_VERBOSITY=3');
if (\function_exists('putenv')) {
putenv('SHELL_VERBOSITY=3');
}
$_ENV['SHELL_VERBOSITY'] = 3;
$_SERVER['SHELL_VERBOSITY'] = 3;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,25 @@ public function testValidation()
{
$hasher = new NativePasswordHasher();
$result = $hasher->hash('password', null);
$this->assertTrue($hasher->verify($result, 'password', null));
$this->assertFalse($hasher->verify($result, 'anotherPassword', null));
$this->assertFalse($hasher->verify($result, '', null));
$this->assertTrue($hasher->verify($result, 'password'));
$this->assertFalse($hasher->verify($result, 'anotherPassword'));
$this->assertFalse($hasher->verify($result, ''));
}

public function testNonArgonValidation()
{
$hasher = new NativePasswordHasher();
$this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password', null));
$this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword', null));
$this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password', null));
$this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword', null));
$this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password'));
$this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword'));
$this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password'));
$this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword'));
}

public function testConfiguredAlgorithm()
{
$hasher = new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT);
$result = $hasher->hash('password', null);
$this->assertTrue($hasher->verify($result, 'password', null));
$result = $hasher->hash('password');
$this->assertTrue($hasher->verify($result, 'password'));
$this->assertStringStartsWith('$2', $result);
}

Expand All @@ -84,8 +84,8 @@ public function testDefaultAlgorithm()
public function testConfiguredAlgorithmWithLegacyConstValue()
{
$hasher = new NativePasswordHasher(null, null, null, '1');
$result = $hasher->hash('password', null);
$this->assertTrue($hasher->verify($result, 'password', null));
$result = $hasher->hash('password');
$this->assertTrue($hasher->verify($result, 'password'));
$this->assertStringStartsWith('$2', $result);
}

Expand All @@ -94,17 +94,17 @@ public function testBcryptWithLongPassword()
$hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT);
$plainPassword = str_repeat('a', 100);

$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt'));
$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword, 'salt'));
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

public function testBcryptWithNulByte()
{
$hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT);
$plainPassword = "a\0b";

$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt'));
$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword, 'salt'));
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

public function testNeedsRehash()
Expand All @@ -113,7 +113,7 @@ public function testNeedsRehash()

$this->assertTrue($hasher->needsRehash('dummyhash'));

$hash = $hasher->hash('foo', 'salt');
$hash = $hasher->hash('foo');
$this->assertFalse($hasher->needsRehash($hash));

$hasher = new NativePasswordHasher(5, 11000, 5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function testGetNamedHasherForHasherAware()
'hasher_name' => new MessageDigestPasswordHasher('sha1'),
]);

$hasher = $factory->getPasswordHasher(new HasherAwareUser('user', 'pass'));
$hasher = $factory->getPasswordHasher(new HasherAwareUser());
$expectedHasher = new MessageDigestPasswordHasher('sha1');
$this->assertEquals($expectedHasher->hash('foo', ''), $hasher->hash('foo', ''));
}
Expand All @@ -121,7 +121,7 @@ public function testGetNullNamedHasherForHasherAware()
'hasher_name' => new MessageDigestPasswordHasher('sha256'),
]);

$user = new HasherAwareUser('mathilde', 'krogulec');
$user = new HasherAwareUser();
$user->hasherName = null;
$hasher = $factory->getPasswordHasher($user);
$expectedHasher = new MessageDigestPasswordHasher('sha1');
Expand All @@ -136,7 +136,7 @@ public function testGetInvalidNamedHasherForHasherAware()
'hasher_name' => new MessageDigestPasswordHasher('sha256'),
]);

$user = new HasherAwareUser('user', 'pass');
$user = new HasherAwareUser();
$user->hasherName = 'invalid_hasher_name';
$factory->getPasswordHasher($user);
}
Expand Down Expand Up @@ -167,9 +167,9 @@ public function testMigrateFrom()
$hasher = $factory->getPasswordHasher(SomeUser::class);
$this->assertInstanceOf(MigratingPasswordHasher::class, $hasher);

$this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo', null), 'foo', null));
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo', null), 'foo', null));
$this->assertTrue($hasher->verify($digest->hash('foo', null), 'foo', null));
$this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo'), 'foo', null));
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo'), 'foo', null));
$this->assertTrue($hasher->verify($digest->hash('foo'), 'foo', null));
$this->assertStringStartsWith(\SODIUM_CRYPTO_PWHASH_STRPREFIX, $hasher->hash('foo', null));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,65 +28,65 @@ protected function setUp(): void
public function testValidation()
{
$hasher = new SodiumPasswordHasher();
$result = $hasher->hash('password', null);
$this->assertTrue($hasher->verify($result, 'password', null));
$this->assertFalse($hasher->verify($result, 'anotherPassword', null));
$this->assertFalse($hasher->verify($result, '', null));
$result = $hasher->hash('password');
$this->assertTrue($hasher->verify($result, 'password'));
$this->assertFalse($hasher->verify($result, 'anotherPassword'));
$this->assertFalse($hasher->verify($result, ''));
}

public function testBcryptValidation()
{
$hasher = new SodiumPasswordHasher();
$this->assertTrue($hasher->verify('$2y$04$M8GDODMoGQLQRpkYCdoJh.lbiZPee3SZI32RcYK49XYTolDGwoRMm', 'abc', null));
$this->assertTrue($hasher->verify('$2y$04$M8GDODMoGQLQRpkYCdoJh.lbiZPee3SZI32RcYK49XYTolDGwoRMm', 'abc'));
}

public function testNonArgonValidation()
{
$hasher = new SodiumPasswordHasher();
$this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password', null));
$this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword', null));
$this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password', null));
$this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword', null));
$this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password'));
$this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword'));
$this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password'));
$this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword'));
}

public function testHashLength()
{
$this->expectException(InvalidPasswordException::class);
$hasher = new SodiumPasswordHasher();
$hasher->hash(str_repeat('a', 4097), 'salt');
$hasher->hash(str_repeat('a', 4097));
}

public function testCheckPasswordLength()
{
$hasher = new SodiumPasswordHasher();
$result = $hasher->hash(str_repeat('a', 4096), null);
$this->assertFalse($hasher->verify($result, str_repeat('a', 4097), null));
$this->assertTrue($hasher->verify($result, str_repeat('a', 4096), null));
$result = $hasher->hash(str_repeat('a', 4096));
$this->assertFalse($hasher->verify($result, str_repeat('a', 4097)));
$this->assertTrue($hasher->verify($result, str_repeat('a', 4096)));
}

public function testBcryptWithLongPassword()
{
$hasher = new SodiumPasswordHasher(null, null, 4);
$hasher = new SodiumPasswordHasher(null, null);
$plainPassword = str_repeat('a', 100);

$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt'));
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword, 'salt'));
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword));
}

public function testBcryptWithNulByte()
{
$hasher = new SodiumPasswordHasher(null, null, 4);
$hasher = new SodiumPasswordHasher(null, null);
$plainPassword = "a\0b";

$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt'));
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword, 'salt'));
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword));
}

public function testUserProvidedSaltIsNotUsed()
{
$hasher = new SodiumPasswordHasher();
$result = $hasher->hash('password', 'salt');
$this->assertTrue($hasher->verify($result, 'password', 'anotherSalt'));
$result = $hasher->hash('password');
$this->assertTrue($hasher->verify($result, 'password'));
}

public function testNeedsRehash()
Expand All @@ -95,7 +95,7 @@ public function testNeedsRehash()

$this->assertTrue($hasher->needsRehash('dummyhash'));

$hash = $hasher->hash('foo', 'salt');
$hash = $hasher->hash('foo');
$this->assertFalse($hasher->needsRehash($hash));

$hasher = new SodiumPasswordHasher(5, 11000);
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Yaml/Inline.php
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ private static function parseMapping(string $mapping, int $flags, int &$i = 0, a
if ('<<' === $key) {
$output += $value;
} elseif ($allowOverwrite || !isset($output[$key])) {
if (!$isValueQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) {
if (!$isValueQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && !self::isBinaryString($value) && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) {
$references[$matches['ref']] = $matches['value'];
$value = $matches['value'];
}
Expand Down
7 changes: 5 additions & 2 deletions src/Symfony/Component/Yaml/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,8 @@ private function doParse(string $value, int $flags): mixed
|| self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->trimTag($values['value']), $matches)
)
) {
// this is a compact notation element, add to next block and parse
$block = $values['value'];
if ($this->isNextLineIndented()) {
if ($this->isNextLineIndented() || isset($matches['value']) && '>-' === $matches['value']) {
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1);
}

Expand Down Expand Up @@ -932,6 +931,10 @@ private function isNextLineIndented(): bool
} while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));

if ($EOF) {
for ($i = 0; $i < $movements; ++$i) {
$this->moveToPreviousLine();
}

return false;
}

Expand Down
3 changes: 3 additions & 0 deletions src/Symfony/Component/Yaml/Tests/InlineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,9 @@ public static function getTestsForParse()

['[foo, bar: { foo: bar }]', ['foo', '1' => ['bar' => ['foo' => 'bar']]]],
['[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', ['foo', '@foo.baz', ['%foo%' => 'foo is %foo%', 'bar' => '%foo%'], true, '@service_container']],

// Binary string not utf8-compliant but starting with and utf8-equivalent "&" character
['{ uid: !!binary Ju0Yh+uqSXOagJZFTlUt8g== }', ['uid' => hex2bin('26ed1887ebaa49739a8096454e552df2')]],
];
}

Expand Down
38 changes: 38 additions & 0 deletions src/Symfony/Component/Yaml/Tests/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2712,6 +2712,44 @@ public static function circularReferenceProvider()
return $tests;
}

public function testBlockScalarArray()
{
$yaml = <<<'YAML'
anyOf:
- $ref: >-
#/string/bar
anyOfMultiline:
- $ref: >-
#/string/bar
second line
nested:
anyOf:
- $ref: >-
#/string/bar
YAML;
$expected = [
'anyOf' => [
0 => [
'$ref' => '#/string/bar',
],
],
'anyOfMultiline' => [
0 => [
'$ref' => '#/string/bar second line',
],
],
'nested' => [
'anyOf' => [
0 => [
'$ref' => '#/string/bar',
],
],
],
];

$this->assertSame($expected, $this->parser->parse($yaml));
}

/**
* @dataProvider indentedMappingData
*/
Expand Down

0 comments on commit 01efac5

Please sign in to comment.