Skip to content

Commit c25c368

Browse files
[PasswordHasher] Make bcrypt nul byte hash test tolerant to PHP related failures
1 parent 93fcdb8 commit c25c368

File tree

2 files changed

+44
-18
lines changed

2 files changed

+44
-18
lines changed

src/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.php

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,36 @@ public function testBcryptWithLongPassword()
9999
}
100100

101101
/**
102-
* "password_hash()" does not accept passwords containing NUL bytes prior to PHP 8.2
103-
* and throws a ValueError, thus this test is skipped because `$hasher->verify()` will
104-
* not be executed.
105-
*
106-
* @requires PHP >= 8.2
102+
* @requires PHP < 8.4
107103
*/
108104
public function testBcryptWithNulByte()
109105
{
110106
$hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT);
111107
$plainPassword = "a\0b";
112108

113-
if (\PHP_VERSION_ID < 80218 || \PHP_VERSION_ID >= 80300 && \PHP_VERSION_ID < 80305) {
114-
// password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5
115-
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
109+
try {
110+
$hash = password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]);
111+
} catch (\Throwable $throwable) {
112+
// we skip the test in case the PHP version does not support NUL bytes in passwords
113+
// with bcrypt
114+
//
115+
// @see https://github.com/php/php-src/commit/11f2568767660ffe92fbc6799800e01203aad73a
116+
if (false !== strpos($throwable->getMessage(), 'Bcrypt password must not contain null character')) {
117+
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
118+
}
119+
120+
throw $throwable;
116121
}
117122

118-
$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
123+
if (null === $hash) {
124+
// we also skip the test in case password_hash() returns null as
125+
// implemented in security patches backports
126+
//
127+
// @see https://github.com/shivammathur/php-src-backports/commit/d22d9ebb29dce86edd622205dd1196a2796c08c7
128+
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
129+
}
130+
131+
$this->assertTrue($hasher->verify($hash, $plainPassword));
119132
}
120133

121134
public function testNeedsRehash()

src/Symfony/Component/PasswordHasher/Tests/Hasher/SodiumPasswordHasherTest.php

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,23 +74,36 @@ public function testBcryptWithLongPassword()
7474
}
7575

7676
/**
77-
* "password_hash()" does not accept passwords containing NUL bytes prior to PHP 8.2
78-
* and throws a ValueError, thus this test is skipped because `$hasher->verify()` will
79-
* not be executed.
80-
*
81-
* @requires PHP >= 8.2
77+
* @requires PHP < 8.4
8278
*/
8379
public function testBcryptWithNulByte()
8480
{
8581
$hasher = new SodiumPasswordHasher(null, null);
8682
$plainPassword = "a\0b";
8783

88-
if (\PHP_VERSION_ID < 80218 || \PHP_VERSION_ID >= 80300 && \PHP_VERSION_ID < 80305) {
89-
// password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5
90-
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
84+
try {
85+
$hash = password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]);
86+
} catch (\Throwable $throwable) {
87+
// we skip the test in case the PHP version does not support NUL bytes in passwords
88+
// with bcrypt
89+
//
90+
// @see https://github.com/php/php-src/commit/11f2568767660ffe92fbc6799800e01203aad73a
91+
if (false !== strpos($throwable->getMessage(), 'Bcrypt password must not contain null character')) {
92+
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
93+
}
94+
95+
throw $throwable;
9196
}
9297

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

96109
public function testUserProvidedSaltIsNotUsed()

0 commit comments

Comments
 (0)