diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 21bee4a64e13..d57ae149691b 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -17,7 +17,6 @@ #include #endif -#include #include "php_hash.h" #include "ext/standard/info.h" #include "ext/standard/file.h" @@ -1033,10 +1032,10 @@ PHP_FUNCTION(hash_pbkdf2) } digest_length = length; if (!raw_output) { - digest_length = (zend_long) ceil((float) length / 2.0); + digest_length = length / 2 + (length % 2); } - loops = (zend_long) ceil((float) digest_length / (float) ops->digest_size); + loops = (digest_length - 1) / ops->digest_size + 1; result = safe_emalloc(loops, ops->digest_size, 0); diff --git a/ext/hash/tests/hash_pbkdf2_large_length.phpt b/ext/hash/tests/hash_pbkdf2_large_length.phpt new file mode 100644 index 000000000000..527e238a2cc3 --- /dev/null +++ b/ext/hash/tests/hash_pbkdf2_large_length.phpt @@ -0,0 +1,19 @@ +--TEST-- +Hash: hash_pbkdf2() function : large output length +--FILE-- + +--EXPECT-- +int(33554433) +bool(true) diff --git a/ext/hash/tests/hash_pbkdf2_max_length.phpt b/ext/hash/tests/hash_pbkdf2_max_length.phpt new file mode 100644 index 000000000000..eccd8abaa2bf --- /dev/null +++ b/ext/hash/tests/hash_pbkdf2_max_length.phpt @@ -0,0 +1,17 @@ +--TEST-- +Hash: hash_pbkdf2() function : output length of PHP_INT_MAX +--SKIPIF-- + +--INI-- +memory_limit=128M +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of 134217728 bytes exhausted%s(tried to allocate 4611686018427387904 bytes) in %s on line %d diff --git a/ext/hash/tests/hash_pbkdf2_max_length_raw.phpt b/ext/hash/tests/hash_pbkdf2_max_length_raw.phpt new file mode 100644 index 000000000000..b0eceefa356a --- /dev/null +++ b/ext/hash/tests/hash_pbkdf2_max_length_raw.phpt @@ -0,0 +1,17 @@ +--TEST-- +Hash: hash_pbkdf2() function : raw output length of PHP_INT_MAX +--SKIPIF-- + +--INI-- +memory_limit=128M +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of 134217728 bytes exhausted%s(tried to allocate 9223372036854775808 bytes) in %s on line %d