@@ -73,17 +73,45 @@ public function testBcryptWithLongPassword()
73
73
$ this ->assertTrue ($ hasher ->verify ((new NativePasswordHasher (null , null , 4 , \PASSWORD_BCRYPT ))->hash ($ plainPassword ), $ plainPassword ));
74
74
}
75
75
76
- public function testBcryptWithNulByte ()
76
+ /**
77
+ * @requires PHP < 8.4
78
+ */
79
+ public function testBcryptWithNulByteWithNativePasswordHash ()
77
80
{
78
81
$ hasher = new SodiumPasswordHasher (null , null );
79
82
$ plainPassword = "a \0b " ;
80
83
81
- if (\PHP_VERSION_ID < 80218 || \PHP_VERSION_ID >= 80300 && \PHP_VERSION_ID < 80305 ) {
82
- // password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5
83
- $ 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 current 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 (str_contains ($ 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 ;
84
96
}
85
97
86
- $ 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 ));
107
+ }
108
+
109
+ public function testPasswordNulByteGracefullyHandled ()
110
+ {
111
+ $ hasher = new SodiumPasswordHasher (null , null );
112
+ $ plainPassword = "a \0b " ;
113
+
114
+ $ this ->assertTrue ($ hasher ->verify ($ hasher ->hash ($ plainPassword ), $ plainPassword ));
87
115
}
88
116
89
117
public function testUserProvidedSaltIsNotUsed ()
0 commit comments