Skip to content

Commit

Permalink
Merge branch '7.0' into 7.1
Browse files Browse the repository at this point in the history
* 7.0:
  replace wurstmeister Docker images for Kafka and Zookeeper
  [PasswordHasher] Make bcrypt nul byte hash test tolerant to PHP related failures
  [HttpClient] Revert fixing curl default options
  [VarExporter] fix proxy helper when a method returns null
  [Validator] Update Dutch (nl) translation
  Fix exception thrown during `LDAP_MODIFY_BATCH_REMOVE_ALL` batch operations
  Fix various warnings across components test suite
  • Loading branch information
xabbuh committed May 13, 2024
2 parents 5a00a8b + fc5137a commit 5f26022
Show file tree
Hide file tree
Showing 18 changed files with 201 additions and 45 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ jobs:
ports:
- 4566:4566
zookeeper:
image: wurstmeister/zookeeper:3.4.6
image: zookeeper
kafka:
image: wurstmeister/kafka:2.12-2.0.1
image: bitnami/kafka:3.7
ports:
- 9092:9092
env:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function testSupports()
*/
public function testIsFresh(callable $mockContainer, $expected)
{
$mockContainer($this->container);
$mockContainer($this->container, $this);

$this->assertSame($expected, $this->resourceChecker->isFresh($this->resource, time()));
}
Expand Down
4 changes: 4 additions & 0 deletions src/Symfony/Component/HttpClient/Response/CurlResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ public function __construct(
curl_multi_remove_handle($multi->handle, $ch);
curl_setopt_array($ch, [
\CURLOPT_NOPROGRESS => true,
\CURLOPT_PROGRESSFUNCTION => null,
\CURLOPT_HEADERFUNCTION => null,
\CURLOPT_WRITEFUNCTION => null,
\CURLOPT_READFUNCTION => null,
\CURLOPT_INFILE => null,
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,15 @@ public function __construct(int $operationType, string $attribute, ?array $value

public function toArray(): array
{
return [
$op = [
'attrib' => $this->attribute,
'modtype' => $this->operationType,
'values' => $this->values,
];

if (\LDAP_MODIFY_BATCH_REMOVE_ALL !== $this->operationType) {
$op['values'] = $this->values;
}

return $op;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,23 @@ public function testLdapAddAttributeValuesError()
$entryManager->addAttributeValues($entry, 'mail', $entry->getAttribute('mail'));
}

public function testLdapApplyOperationsRemoveAll()
{
$entryManager = $this->adapter->getEntryManager();

$result = $this->executeSearchQuery(1);
$entry = $result[0];

$entryManager->applyOperations($entry->getDn(), [new UpdateOperation(\LDAP_MODIFY_BATCH_REMOVE_ALL, 'mail', null)]);

$result = $this->executeSearchQuery(1);
$entry = $result[0];

$this->assertNull($entry->getAttribute('mail'));

$entryManager->addAttributeValues($entry, 'mail', ['fabpot@symfony.com', 'fabien@potencier.com']);
}

public function testLdapApplyOperationsRemoveAllWithArrayError()
{
$entryManager = $this->adapter->getEntryManager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,44 @@ public function testBcryptWithLongPassword()
$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

public function testBcryptWithNulByte()
/**
* @requires PHP < 8.4
*/
public function testBcryptWithNulByteWithNativePasswordHash()
{
$hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT);
$plainPassword = "a\0b";

if (\PHP_VERSION_ID < 80218 || \PHP_VERSION_ID >= 80300 && \PHP_VERSION_ID < 80305) {
// password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
try {
$hash = password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]);
} catch (\Throwable $throwable) {
// we skip the test in case the current PHP version does not support NUL bytes in passwords
// with bcrypt
//
// @see https://github.com/php/php-src/commit/11f2568767660ffe92fbc6799800e01203aad73a
if (str_contains($throwable->getMessage(), 'Bcrypt password must not contain null character')) {
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

throw $throwable;
}

if (null === $hash) {
// we also skip the test in case password_hash() returns null as
// implemented in security patches backports
//
// @see https://github.com/shivammathur/php-src-backports/commit/d22d9ebb29dce86edd622205dd1196a2796c08c7
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

$this->assertTrue($hasher->verify($hash, $plainPassword));
}

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

$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,45 @@ public function testBcryptWithLongPassword()
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword));
}

public function testBcryptWithNulByte()
/**
* @requires PHP < 8.4
*/
public function testBcryptWithNulByteWithNativePasswordHash()
{
$hasher = new SodiumPasswordHasher(null, null);
$plainPassword = "a\0b";

if (\PHP_VERSION_ID < 80218 || \PHP_VERSION_ID >= 80300 && \PHP_VERSION_ID < 80305) {
// password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
try {
$hash = password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]);
} catch (\Throwable $throwable) {
// we skip the test in case the current PHP version does not support NUL bytes in passwords
// with bcrypt
//
// @see https://github.com/php/php-src/commit/11f2568767660ffe92fbc6799800e01203aad73a
if (str_contains($throwable->getMessage(), 'Bcrypt password must not contain null character')) {
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

throw $throwable;
}

$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword));
if (null === $hash) {
// we also skip the test in case password_hash() returns null as
// implemented in security patches backports
//
// @see https://github.com/shivammathur/php-src-backports/commit/d22d9ebb29dce86edd622205dd1196a2796c08c7
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

$this->assertTrue($hasher->verify($hash, $plainPassword));
}

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

$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

public function testUserProvidedSaltIsNotUsed()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ protected function tearDown(): void
parent::tearDown();

@unlink($this->testTmpFilepath);
@unlink($this->largeTestTmpFilepath);
}

public function testDumpWithRoutes()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ public function testUncallableCallbacks($callbacks)
$normalizer->normalize($obj, null, ['callbacks' => $callbacks]);
}

public function provideNormalizeCallbacks()
public static function provideNormalizeCallbacks()
{
return [
'Change a string' => [
[
'bar' => function ($bar) {
$this->assertEquals('baz', $bar);
static::assertEquals('baz', $bar);

return 'baz';
},
Expand All @@ -143,11 +143,11 @@ public function provideNormalizeCallbacks()
'Null an item' => [
[
'bar' => function ($value, $object, $attributeName, $format, $context) {
$this->assertSame('baz', $value);
$this->assertInstanceOf(CallbacksObject::class, $object);
$this->assertSame('bar', $attributeName);
$this->assertSame('any', $format);
$this->assertArrayHasKey('circular_reference_limit_counters', $context);
static::assertSame('baz', $value);
static::assertInstanceOf(CallbacksObject::class, $object);
static::assertSame('bar', $attributeName);
static::assertSame('any', $format);
static::assertArrayHasKey('circular_reference_limit_counters', $context);
},
],
'baz',
Expand All @@ -156,7 +156,7 @@ public function provideNormalizeCallbacks()
'Format a date' => [
[
'bar' => function ($bar) {
$this->assertInstanceOf(\DateTimeImmutable::class, $bar);
static::assertInstanceOf(\DateTimeImmutable::class, $bar);

return $bar->format('d-m-Y H:i:s');
},
Expand Down Expand Up @@ -188,13 +188,13 @@ public function provideNormalizeCallbacks()
];
}

public function provideDenormalizeCallbacks(): array
public static function provideDenormalizeCallbacks(): array
{
return [
'Change a string' => [
[
'bar' => function ($bar) {
$this->assertEquals('bar', $bar);
static::assertEquals('bar', $bar);

return $bar;
},
Expand All @@ -205,11 +205,11 @@ public function provideDenormalizeCallbacks(): array
'Null an item' => [
[
'bar' => function ($value, $object, $attributeName, $format, $context) {
$this->assertSame('baz', $value);
$this->assertTrue(is_a($object, CallbacksObject::class, true));
$this->assertSame('bar', $attributeName);
$this->assertSame('any', $format);
$this->assertIsArray($context);
static::assertSame('baz', $value);
static::assertTrue(is_a($object, CallbacksObject::class, true));
static::assertSame('bar', $attributeName);
static::assertSame('any', $format);
static::assertIsArray($context);
},
],
'baz',
Expand All @@ -218,7 +218,7 @@ public function provideDenormalizeCallbacks(): array
'Format a date' => [
[
'bar' => function ($bar) {
$this->assertIsString($bar);
static::assertIsString($bar);

return \DateTimeImmutable::createFromFormat('d-m-Y H:i:s', $bar);
},
Expand Down Expand Up @@ -250,13 +250,13 @@ public function provideDenormalizeCallbacks(): array
];
}

public function providerDenormalizeCallbacksWithTypedProperty(): array
public static function providerDenormalizeCallbacksWithTypedProperty(): array
{
return [
'Change a typed string' => [
[
'foo' => function ($foo) {
$this->assertEquals('foo', $foo);
static::assertEquals('foo', $foo);

return $foo;
},
Expand All @@ -267,11 +267,11 @@ public function providerDenormalizeCallbacksWithTypedProperty(): array
'Null an typed item' => [
[
'foo' => function ($value, $object, $attributeName, $format, $context) {
$this->assertSame('fool', $value);
$this->assertTrue(is_a($object, CallbacksObject::class, true));
$this->assertSame('foo', $attributeName);
$this->assertSame('any', $format);
$this->assertIsArray($context);
static::assertSame('fool', $value);
static::assertTrue(is_a($object, CallbacksObject::class, true));
static::assertSame('foo', $attributeName);
static::assertSame('any', $format);
static::assertIsArray($context);
},
],
'fool',
Expand All @@ -280,7 +280,7 @@ public function providerDenormalizeCallbacksWithTypedProperty(): array
];
}

public function provideInvalidCallbacks()
public static function provideInvalidCallbacks()
{
return [
[['bar' => null]],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ abstract protected function getNormalizerForCircularReference(array $defaultCont

abstract protected function getSelfReferencingModel();

public function provideUnableToNormalizeCircularReference(): array
public static function provideUnableToNormalizeCircularReference(): array
{
return [
[[], [], 1],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function testSkipUninitializedValues(array $context)
$this->assertSame('value', $objectToPopulate->getUninitialized());
}

public function skipUninitializedValuesFlagProvider(): iterable
public static function skipUninitializedValuesFlagProvider(): iterable
{
yield 'passed manually' => [['skip_uninitialized_values' => true, 'groups' => ['foo']]];
yield 'using default context value' => [['groups' => ['foo']]];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@
</trans-unit>
<trans-unit id="113">
<source>This URL is missing a top-level domain.</source>
<target state="needs-review-translation">Deze URL mist een top-level domein.</target>
<target>Deze URL mist een top-level domein.</target>
</trans-unit>
</body>
</file>
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra
if (isset($a[$prefix.'returnType'])) {
$v = $a[$prefix.'returnType'];
$v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && 'mixed' !== $v ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && !\in_array($v, ['mixed', 'null'], true) ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
}
if (isset($a[$prefix.'class'])) {
$a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
Expand Down Expand Up @@ -368,7 +368,7 @@ public static function getSignature(array $a): string
if (!$type instanceof \ReflectionNamedType) {
$signature .= $type.' ';
} else {
if ($param->allowsNull() && 'mixed' !== $type->getName()) {
if ($param->allowsNull() && !\in_array($type->getName(), ['mixed', 'null'], true)) {
$signature .= '?';
}
$signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
use Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes;
use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass;
use Symfony\Component\VarDumper\Tests\Fixtures\Php82NullStandaloneReturnType;
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionIntersectionTypeFixture;
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionNamedTypeFixture;
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionUnionTypeFixture;
Expand Down Expand Up @@ -95,7 +96,7 @@ public function testClosureCaster()
$b: & 123
}
file: "%sReflectionCasterTest.php"
line: "88 to 88"
line: "%s"
}
EOTXT
, $var
Expand Down Expand Up @@ -403,6 +404,26 @@ class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
);
}

/**
* @requires PHP 8.2
*/
public function testNullReturnType()
{
$className = Php82NullStandaloneReturnType::class;

$this->assertDumpMatchesFormat(
<<<EOTXT
{$className}::foo(null \$bar): null {
returnType: "null"
this: {$className} { …}
file: "%s"
line: "%s"
}
EOTXT
, (new Php82NullStandaloneReturnType())->foo(...)
);
}

public function testUnionReturnType()
{
$f = function (): int|float {};
Expand Down

0 comments on commit 5f26022

Please sign in to comment.