@@ -73,17 +73,45 @@ public function testBcryptWithLongPassword()
7373 $ this ->assertTrue ($ hasher ->verify ((new NativePasswordHasher (null , null , 4 , \PASSWORD_BCRYPT ))->hash ($ plainPassword ), $ plainPassword ));
7474 }
7575
76- public function testBcryptWithNulByte ()
76+ /**
77+ * @requires PHP < 8.4
78+ */
79+ public function testBcryptWithNulByteWithNativePasswordHash ()
7780 {
7881 $ hasher = new SodiumPasswordHasher (null , null );
7982 $ plainPassword = "a \0b " ;
8083
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 ;
8496 }
8597
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 ));
87115 }
88116
89117 public function testUserProvidedSaltIsNotUsed ()
0 commit comments